diff --git a/src/core/util/llvmdisassembler/LLVMtoFailBochs.cpp b/src/core/util/llvmdisassembler/LLVMtoFailBochs.cpp index c7493bfe..22f8d38c 100644 --- a/src/core/util/llvmdisassembler/LLVMtoFailBochs.cpp +++ b/src/core/util/llvmdisassembler/LLVMtoFailBochs.cpp @@ -18,12 +18,12 @@ LLVMtoFailBochs::LLVMtoFailBochs() { llvm_to_fail_map[45] = reginfo_t(RID_CBX, 32, 0); // EBX llvm_to_fail_map[9] = reginfo_t(RID_CCX, 8, 8); // CH - llvm_to_fail_map[10] = reginfo_t(RID_CCX, 0xff); // CL + llvm_to_fail_map[10] = reginfo_t(RID_CCX, 8, 0); // CL llvm_to_fail_map[28] = reginfo_t(RID_CCX, 16, 0); // CX llvm_to_fail_map[46] = reginfo_t(RID_CCX); // ECX llvm_to_fail_map[29] = reginfo_t(RID_CDX, 8, 8); // DH - llvm_to_fail_map[32] = reginfo_t(RID_CDX, 0xff); // DL + llvm_to_fail_map[32] = reginfo_t(RID_CDX, 8, 0); // DL llvm_to_fail_map[42] = reginfo_t(RID_CDX, 16, 0); // DX llvm_to_fail_map[48] = reginfo_t(RID_CDX); // EDX diff --git a/src/core/util/llvmdisassembler/LLVMtoFailTranslator.cpp b/src/core/util/llvmdisassembler/LLVMtoFailTranslator.cpp index 82f88304..ea8d6a43 100644 --- a/src/core/util/llvmdisassembler/LLVMtoFailTranslator.cpp +++ b/src/core/util/llvmdisassembler/LLVMtoFailTranslator.cpp @@ -8,7 +8,7 @@ const LLVMtoFailTranslator::reginfo_t & LLVMtoFailTranslator::getFailRegisterID if( it != llvm_to_fail_map.end() ) {// found return (*it).second; } else { // not found - std::cout << "Fail ID for LLVM Register id " << regid << " not found :(" << std::endl; + std::cout << "Fail ID for LLVM Register id " << std::dec << regid << " not found :(" << std::endl; //exit(EXIT_FAILURE); return notfound; } diff --git a/src/core/util/llvmdisassembler/LLVMtoFailTranslator.hpp b/src/core/util/llvmdisassembler/LLVMtoFailTranslator.hpp index c6ae698f..54be9e84 100644 --- a/src/core/util/llvmdisassembler/LLVMtoFailTranslator.hpp +++ b/src/core/util/llvmdisassembler/LLVMtoFailTranslator.hpp @@ -13,6 +13,12 @@ namespace fail { */ class LLVMtoFailTranslator { public: + /** + * Maps registers to/from linear addresses usable for def/use-pruning + * purposes and storage in the database. Takes care that the linear + * addresses of x86 subregisters (e.g., AX represents the lower 16 bits of + * EAX) overlap with their siblings. + */ struct reginfo_t { int id; regwidth_t width; @@ -20,18 +26,17 @@ public: byte_t offset; int toDataAddress() const { - // .. 5 4 | 7 6 5 4 | 3 2 1 0 - // | | - return (id << 8) | ((width/8) << 4) | (offset / 8); + // .. 5 4 | 3 2 1 0 + // | + return (id << 4) | (offset / 8); } + // does not recreate width or mask static reginfo_t fromDataAddress(int addr) { - int id = addr >> 8; - regwidth_t width = ((addr >> 4) & 0xf) * 8; - byte_t offset = (addr & 0xf) * 8; - return reginfo_t(id, width, offset); + int id = addr >> 4; + byte_t offset = (addr & 0xf) * 8; + return reginfo_t(id, 0, offset); } - reginfo_t(int id=-1, regwidth_t width = 32, byte_t offs = 0) : id(id), width(width), mask((regwidth_t)((((long long)1 << width) - 1) << offs)), offset(offs) {}; }; @@ -43,6 +48,12 @@ protected: ltof_map_t llvm_to_fail_map; public: + /** + * Translates a backend-specific register ID to a Fail register ID. + * @param regid A backend-specific register ID. + * @return A Fail* register ID, or LLVMtoFailTranslator::notfound if no + * mapping was found. + */ const reginfo_t & getFailRegisterID(unsigned int regid); regdata_t getRegisterContent(ConcreteCPU & cpu, const reginfo_t & reg); @@ -55,7 +66,7 @@ public: } int getFailRegisterId(unsigned int regid) { return this->getFailRegisterID(regid).id; }; -private: + reginfo_t notfound; }; diff --git a/tools/import-trace/RegisterImporter.cc b/tools/import-trace/RegisterImporter.cc index 982c0d44..a2b4a410 100644 --- a/tools/import-trace/RegisterImporter.cc +++ b/tools/import-trace/RegisterImporter.cc @@ -32,9 +32,8 @@ bool RegisterImporter::addRegisterTrace(simtime_t curtime, instruction_count_t i const Trace_Event &ev, const LLVMtoFailTranslator::reginfo_t &info, char access_type) { - LLVMtoFailTranslator::reginfo_t one_byte_window = info; - one_byte_window.width = 8; - address_t from = one_byte_window.toDataAddress(), to = one_byte_window.toDataAddress() + (info.width) / 8; + address_t from = info.toDataAddress(); + address_t to = from + info.width / 8; // Iterate over all accessed bytes for (address_t data_address = from; data_address < to; ++data_address) { @@ -130,6 +129,12 @@ bool RegisterImporter::handle_ip_event(fail::simtime_t curtime, instruction_coun for (std::vector::const_iterator it = opcode.reg_uses.begin(); it != opcode.reg_uses.end(); ++it) { const LLVMtoFailTranslator::reginfo_t &info = ltof.getFailRegisterID(*it); + if (&info == <of.notfound) { + LOG << "Could not find a mapping for LLVM input register #" << std::dec << *it + << " at IP " << std::hex << ev.ip() + << ", skipping" << std::endl; + continue; + } /* if not tracing flags, but flags register -> ignore it if not tracing gp, but ! flags -> ignore it*/ @@ -146,6 +151,13 @@ bool RegisterImporter::handle_ip_event(fail::simtime_t curtime, instruction_coun for (std::vector::const_iterator it = opcode.reg_defs.begin(); it != opcode.reg_defs.end(); ++it) { const LLVMtoFailTranslator::reginfo_t &info = ltof.getFailRegisterID(*it); + if (&info == <of.notfound) { + LOG << "Could not find a mapping for LLVM output register #" << std::dec << *it + << " at IP " << std::hex << ev.ip() + << ", skipping" << std::endl; + continue; + } + /* if not tracing flags, but flags register -> ignore it if not tracing gp, but ! flags -> ignore it*/ if (info.id == RID_FLAGS && !do_flags)