diff --git a/cmake/FindLLVM.cmake b/cmake/FindLLVM.cmake index 45924911..ee45accb 100644 --- a/cmake/FindLLVM.cmake +++ b/cmake/FindLLVM.cmake @@ -1,4 +1,4 @@ -find_program(LLVMCONFIG NAMES llvm-config-3.4 llvm-config-3.3 llvm-config-3.2 llvm-config-3.1 llvm-config) +find_program(LLVMCONFIG NAMES llvm-config-3.9 llvm-config) if( NOT LLVMCONFIG ) message(FATAL_ERROR "llvm-config not found, try installing llvm-dev llvm") diff --git a/doc/how-to-build.txt b/doc/how-to-build.txt index 723be58c..f86b727b 100644 --- a/doc/how-to-build.txt +++ b/doc/how-to-build.txt @@ -24,9 +24,7 @@ Required for FAIL*: "-D__NO_MATH_INLINES -D__STRICT_ANSI__" or "--c_compiler clang++" (the latter requires the clang++ compiler). - optional: - * LLVM 3.3 or 3.4 (needed for several importers in tools/import-trace) - (compiles/links with 3.1 or 3.2, but fails to properly import information - from ELF binaries not compiled with -ffunction-sections) + * LLVM 3.9 (needed for several importers in tools/import-trace) - built with "make REQUIRES_RTTI=1" (the Debian/Ubuntu packages already come built this way) - details below @@ -289,12 +287,12 @@ Database backend setup: MySQL / MariaDB ========================================================================================= Building LLVM from sources ========================================================================================= -If your Linux distribution does not provide a library package for LLVM 3.3 or +If your Linux distribution does not provide a library package for LLVM 3.9 or newer, and you need LLVM support in FAIL*, you may need to build LLVM from the sources and install it, e.g., locally in your home. - 1. Download the source tarball of LLVM 3.4 from http://llvm.org (or use the git - repository http://llvm.org/git/llvm.git and checkout release_34) + 1. Download the source tarball of LLVM 3.9 from http://llvm.org (or use the git + repository http://llvm.org/git/llvm.git and checkout release_39) 2. Configure as needed. On mixed 32/64-bit systems (userland/kernel), prefixing with "linux32" may be necessary: $ linux32 ./configure --prefix=$(echo ~/localroot/usr) --enable-optimized --disable-assertions --disable-werror diff --git a/src/core/util/CMakeLists.txt b/src/core/util/CMakeLists.txt index e08caa0e..53479a8e 100644 --- a/src/core/util/CMakeLists.txt +++ b/src/core/util/CMakeLists.txt @@ -81,7 +81,7 @@ add_library(fail-util ${SRCS}) add_dependencies(fail-util fail-comm) target_link_libraries(fail-util fail-comm ${ADDITIONAL_LIBS} ${PROTOBUF_LIBRARY} ${Boost_LIBRARIES} ${LibIberty_LIBRARIES} ${ZLIB_LIBRARIES} ${LIBDWARF_LIBRARIES} ${LIBELF_LIBRARIES}) -option(BUILD_LLVM_DISASSEMBLER "Build the LLVM-based disassembler (LLVM 3.3 preferred, for 3.1 and 3.2 read doc/how-to-build.txt)" OFF) +option(BUILD_LLVM_DISASSEMBLER "Build the LLVM-based disassembler (LLVM 3.9 preferred, other versions may not work)" OFF) if (BUILD_LLVM_DISASSEMBLER) add_subdirectory(llvmdisassembler) endif (BUILD_LLVM_DISASSEMBLER) diff --git a/src/core/util/llvmdisassembler/LLVMDisassembler.cpp b/src/core/util/llvmdisassembler/LLVMDisassembler.cpp index cca58e5a..093db2a7 100644 --- a/src/core/util/llvmdisassembler/LLVMDisassembler.cpp +++ b/src/core/util/llvmdisassembler/LLVMDisassembler.cpp @@ -5,8 +5,8 @@ using namespace llvm; using namespace llvm::object; -LLVMtoFailTranslator & LLVMDisassembler::getTranslator() { - if ( ltofail == 0 ) { +LLVMtoFailTranslator *LLVMDisassembler::getTranslator() { + if (ltofail == 0) { std::cout << "ArchType: " << llvm::Triple::getArchTypeName( llvm::Triple::ArchType(object->getArch()) ) << std::endl; switch ( llvm::Triple::ArchType(object->getArch()) ) { @@ -22,42 +22,44 @@ LLVMtoFailTranslator & LLVMDisassembler::getTranslator() { exit(1); } } - return *ltofail; + return ltofail; } void LLVMDisassembler::disassemble() { - llvm::error_code ec; - for (section_iterator i = object->begin_sections(), - e = object->end_sections(); - i != e; i.increment(ec)) { - if (error(ec)) break; - bool text; - if (error(i->isText(text))) break; + std::error_code ec; + for (section_iterator i = object->section_begin(), + e = object->section_end(); i != e; ++i) { + bool text = i->isText(); if (!text) continue; - uint64_t SectionAddr; - if (error(i->getAddress(SectionAddr))) break; - - uint64_t SectionLength; - if (error(i->getSize(SectionLength))) break; + uint64_t SectionAddr = i->getAddress(); + // FIXME uint64_t SectionLength = i->getSize(); // Make a list of all the symbols in this section. std::vector > Symbols; - for (symbol_iterator si = object->begin_symbols(), - se = object->end_symbols(); - si != se; si.increment(ec)) { - bool contains; + for (const SymbolRef &symbol : object->symbols()) { StringRef Name; - if (!error(i->containsSymbol(*si, contains)) && contains) { - uint64_t Address; - if (error(si->getAddress(Address))) break; - Address -= SectionAddr; - - if (error(si->getName(Name))) break; - Symbols.push_back(std::make_pair(Address, Name)); + if (!i->containsSymbol(symbol)) { + continue; } + + uint64_t Address; + Expected AddrOrErr = symbol.getAddress(); + if (!AddrOrErr) { + // FIXME fail + continue; + } + Address = *AddrOrErr - SectionAddr; + + Expected NameOrErr = symbol.getName(); + if (!NameOrErr) { + // FIXME fail + continue; + } + + Symbols.push_back(std::make_pair(Address, *NameOrErr)); } // Sort the symbols by address, just in case they didn't come in that way. @@ -71,13 +73,14 @@ void LLVMDisassembler::disassemble() if (Symbols.empty()) Symbols.push_back(std::make_pair(0, name)); - StringRef Bytes; - if (error(i->getContents(Bytes))) break; - StringRefMemoryObject memoryObject(Bytes); + StringRef BytesStr; + if (error(i->getContents(BytesStr))) break; + ArrayRef Bytes(reinterpret_cast(BytesStr.data()), + BytesStr.size()); + uint64_t Size; uint64_t Index; - uint64_t SectSize; - if (error(i->getSize(SectSize))) break; + uint64_t SectSize = i->getSize(); // Disassemble symbol by symbol. for (unsigned si = 0, se = Symbols.size(); si != se; ++si) { @@ -100,7 +103,7 @@ void LLVMDisassembler::disassemble() for (Index = Start; Index < End; Index += Size) { MCInst Inst; - if (disas->getInstruction(Inst, Size, memoryObject, Index, + if (disas->getInstruction(Inst, Size, Bytes.slice(Index), Index, nulls(), nulls()) == MCDisassembler::Success) { const MCInstrDesc &desc = this->instr_info->get(Inst.getOpcode()); // Inst.dump(); @@ -148,7 +151,4 @@ void LLVMDisassembler::disassemble() } } } - } - -void LLVMDisassembler::StringRefMemoryObject::anchor() {} diff --git a/src/core/util/llvmdisassembler/LLVMDisassembler.hpp b/src/core/util/llvmdisassembler/LLVMDisassembler.hpp index 48f442a4..e0623106 100644 --- a/src/core/util/llvmdisassembler/LLVMDisassembler.hpp +++ b/src/core/util/llvmdisassembler/LLVMDisassembler.hpp @@ -5,13 +5,17 @@ #include #include #include +#include // unique_ptr #include "llvm/Object/ObjectFile.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/MC/MCDisassembler.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" @@ -25,8 +29,6 @@ #include "llvm/Support/Casting.h" -#include "llvm/ADT/OwningPtr.h" - #include "LLVMtoFailTranslator.hpp" #include "LLVMtoFailBochs.hpp" #include "LLVMtoFailGem5.hpp" @@ -55,13 +57,13 @@ private: std::string triple; std::string MCPU; std::string FeaturesStr; - llvm::OwningPtr subtargetinfo; - llvm::OwningPtr disas; - llvm::OwningPtr instr_info; - llvm::OwningPtr register_info; - llvm::OwningPtr instrs; + std::unique_ptr subtargetinfo; + std::unique_ptr disas; + std::unique_ptr instr_info; + std::unique_ptr register_info; + std::unique_ptr instrs; - fail::LLVMtoFailTranslator * ltofail; + fail::LLVMtoFailTranslator *ltofail; static std::string GetTriple(const llvm::object::ObjectFile *Obj) { @@ -84,41 +86,56 @@ private: return 0; } - static bool error(llvm::error_code ec) { + static bool error(std::error_code ec) { if (!ec) return false; - std::cerr << "DIS" << ": error reading file: " << ec.message() << ".\n"; + std::cerr << "DIS error: " << ec.message() << ".\n"; return true; } - class StringRefMemoryObject : public llvm::MemoryObject { - virtual void anchor(); - llvm::StringRef Bytes; - public: - StringRefMemoryObject(llvm::StringRef bytes) : Bytes(bytes) {} - - uint64_t getBase() const { return 0; } - uint64_t getExtent() const { return Bytes.size(); } - - int readByte(uint64_t Addr, uint8_t *Byte) const { - if (Addr >= getExtent()) - return -1; - *Byte = Bytes[Addr]; - return 0; - } - }; - - - public: LLVMDisassembler(const llvm::object::ObjectFile *object) : ltofail(0) { this->object = object; this->triple = GetTriple(object); this->target = GetTarget(triple); - this->subtargetinfo.reset(target->createMCSubtargetInfo(triple, MCPU, FeaturesStr)); - this->disas.reset(target->createMCDisassembler(*subtargetinfo)); - this->instr_info.reset(target->createMCInstrInfo()); - this->register_info.reset(target->createMCRegInfo(triple)); + + std::unique_ptr MRI(target->createMCRegInfo(triple)); + if (!MRI) { + std::cerr << "DIS error: no register info for target " << triple << "\n"; + return; + } + + std::unique_ptr MAI(target->createMCAsmInfo(*MRI, triple)); + if (!MAI) { + std::cerr << "DIS error: no assembly info for target " << triple << "\n"; + return; + } + + std::unique_ptr STI( + target->createMCSubtargetInfo(triple, MCPU, FeaturesStr)); + if (!STI) { + std::cerr << "DIS error: no subtarget info for target " << triple << "\n"; + return; + } + std::unique_ptr MII(target->createMCInstrInfo()); + if (!MII) { + std::cerr << "DIS error: no instruction info for target " << triple << "\n"; + return; + } + std::unique_ptr MOFI(new llvm::MCObjectFileInfo); + // Set up the MCContext for creating symbols and MCExpr's. + llvm::MCContext Ctx(MAI.get(), MRI.get(), MOFI.get()); + + this->subtargetinfo = std::move(STI); + std::unique_ptr DisAsm( + target->createMCDisassembler(*subtargetinfo, Ctx)); + if (!DisAsm) { + std::cerr << "DIS error: no disassembler for target " << triple << "\n"; + return; + } + this->disas = std::move(DisAsm); + this->instr_info = std::move(MII); + this->register_info = std::move(MRI); this->instrs.reset(new InstrMap()); } @@ -126,14 +143,13 @@ public: ~LLVMDisassembler() { delete ltofail; }; InstrMap &getInstrMap() { return *instrs; }; - const llvm::MCRegisterInfo &getRegisterInfo() { return *register_info;} - fail::LLVMtoFailTranslator & getTranslator() ; + const llvm::MCRegisterInfo& getRegisterInfo() { return *register_info; } + fail::LLVMtoFailTranslator *getTranslator() ; - const std::string & GetTriple() const { return triple; }; + const std::string& GetTriple() const { return triple; }; void disassemble(); }; - } #endif // __LLVMDISASSEMBLER_HPP__ diff --git a/src/core/util/llvmdisassembler/LLVMtoFailTranslator.cpp b/src/core/util/llvmdisassembler/LLVMtoFailTranslator.cpp index 75aa444f..14fed60c 100644 --- a/src/core/util/llvmdisassembler/LLVMtoFailTranslator.cpp +++ b/src/core/util/llvmdisassembler/LLVMtoFailTranslator.cpp @@ -43,20 +43,18 @@ void LLVMtoFailTranslator::setRegisterContent(ConcreteCPU & cpu, const reginfo_t } LLVMtoFailTranslator* LLVMtoFailTranslator::createFromBinary(const std::string elf_path) { - llvm_shutdown_obj Y; + //llvm_shutdown_obj Y; llvm::InitializeAllTargetInfos(); llvm::InitializeAllTargetMCs(); llvm::InitializeAllDisassemblers(); - OwningPtr binary; - llvm::error_code ret = createBinary(elf_path, binary); - assert (ret == 0); - (void) ret; // unused in release builds - assert (binary.get() != NULL); + Expected> BinaryOrErr = createBinary(elf_path); + assert (BinaryOrErr); + Binary *binary = BinaryOrErr.get().getBinary(); #ifndef __puma - LLVMDisassembler disas(dyn_cast(binary.get())); - return &disas.getTranslator(); + LLVMDisassembler disas(dyn_cast(binary)); + return disas.getTranslator(); #else return 0; #endif diff --git a/src/core/util/llvmdisassembler/testing/llvmDisTest.cc b/src/core/util/llvmdisassembler/testing/llvmDisTest.cc index 4a359e22..c987a9a4 100644 --- a/src/core/util/llvmdisassembler/testing/llvmDisTest.cc +++ b/src/core/util/llvmdisassembler/testing/llvmDisTest.cc @@ -1,3 +1,4 @@ +#include "llvm/Support/raw_os_ostream.h" #include "../LLVMDisassembler.hpp" using namespace llvm; @@ -22,13 +23,16 @@ int main(int argc, char* argv[]) { return -1; } - OwningPtr binary; - if (llvm::error_code ec = createBinary(file, binary)) { - std::cerr << "Dis" << ": '" << file << "': " << ec.message() << ".\n"; + Expected> BinaryOrErr = createBinary(file); + if (!BinaryOrErr) { + std::cerr << "Dis: '" << file << "': "; + raw_os_ostream OS(std::cerr); + logAllUnhandledErrors(BinaryOrErr.takeError(), OS, ""); return -1; } + Binary *binary = BinaryOrErr.get().getBinary(); - ObjectFile *obj = dyn_cast(binary.get()); + ObjectFile *obj = dyn_cast(binary); LLVMDisassembler disas(obj); disas.disassemble(); @@ -40,26 +44,27 @@ int main(int argc, char* argv[]) { const MCRegisterInfo ®_info = disas.getRegisterInfo(); std::cout << std::endl << "Number of Registers: " << reg_info.getNumRegs() << std::endl; - // for(unsigned int i = 0; i < reg_info.getNumRegs(); ++i){ - // std::cout << i << " - " << reg_info.getName(i) << std::endl; - // } - fail::LLVMtoFailTranslator & ltof = disas.getTranslator() ; + for (unsigned int i = 0; i < reg_info.getNumRegs(); ++i) { + std::cout << i << "=" << reg_info.getName(i) << " "; + } + std::cout << std::endl; + fail::LLVMtoFailTranslator *ltof = disas.getTranslator(); - for(itr = instr_map.begin(); itr != instr_map.end(); ++itr){ + for (itr = instr_map.begin(); itr != instr_map.end(); ++itr){ const LLVMDisassembler::Instr &instr = (*itr).second; std::cout << std::hex << (*itr).first << " | " << instr.opcode << std::endl; std::cout << std::dec << "USES: "; for (std::vector::const_iterator it = instr.reg_uses.begin(); it != instr.reg_uses.end(); ++it) { - std::cout << reg_info.getName(*it) <<"(" << *it << ") "; - std::cout << "Fail: " << ltof.getFailRegisterId(*it) << " "; + std::cout << reg_info.getName(*it) + << "(" << *it << "->" << ltof->getFailRegisterId(*it) << ") "; } - std::cout << std::endl; - std::cout << "DEFS: "; + std::cout << " | DEFS: "; for (std::vector::const_iterator it = instr.reg_defs.begin(); it != instr.reg_defs.end(); ++it) { - std::cout << reg_info.getName(*it) << "(" << *it << ") "; + std::cout << reg_info.getName(*it) + << "(" << *it << "->" << ltof->getFailRegisterId(*it) << ") "; } if (instr.conditional_branch) { diff --git a/tools/import-trace/AdvancedMemoryImporter.cc b/tools/import-trace/AdvancedMemoryImporter.cc index dd0cca5a..34209d12 100644 --- a/tools/import-trace/AdvancedMemoryImporter.cc +++ b/tools/import-trace/AdvancedMemoryImporter.cc @@ -104,14 +104,20 @@ bool AdvancedMemoryImporter::handle_ip_event(fail::simtime_t curtime, instructio llvm::InitializeAllTargetMCs(); llvm::InitializeAllDisassemblers(); - if (llvm::error_code ec = createBinary(m_elf->getFilename(), binary)) { - LOG << m_elf->getFilename() << "': " << ec.message() << ".\n"; + Expected> BinaryOrErr = createBinary(m_elf->getFilename()); + if (!BinaryOrErr) { + std::string Buf; + raw_string_ostream OS(Buf); + logAllUnhandledErrors(std::move(BinaryOrErr.takeError()), OS, ""); + OS.flush(); + LOG << m_elf->getFilename() << "': " << Buf << ".\n"; return false; } + binary = &(*BinaryOrErr.get().getBinary()); // necessary due to an AspectC++ bug triggered by LLVM 3.3's dyn_cast() #ifndef __puma - ObjectFile *obj = dyn_cast(binary.get()); + ObjectFile *obj = dyn_cast(binary); disas.reset(new LLVMDisassembler(obj)); #endif disas->disassemble(); diff --git a/tools/import-trace/AdvancedMemoryImporter.hpp b/tools/import-trace/AdvancedMemoryImporter.hpp index 9584de5f..183418b0 100644 --- a/tools/import-trace/AdvancedMemoryImporter.hpp +++ b/tools/import-trace/AdvancedMemoryImporter.hpp @@ -24,8 +24,8 @@ * operations with a set of new virtual functions that are called downwards. */ class AdvancedMemoryImporter : public MemoryImporter { - llvm::OwningPtr binary; - llvm::OwningPtr disas; + llvm::object::Binary *binary = 0; + std::unique_ptr disas; bool m_last_was_conditional_branch; fail::guest_address_t m_ip_jump_not_taken; std::vector branches_taken; diff --git a/tools/import-trace/ElfImporter.hpp b/tools/import-trace/ElfImporter.hpp index 9c668622..13c8106b 100644 --- a/tools/import-trace/ElfImporter.hpp +++ b/tools/import-trace/ElfImporter.hpp @@ -27,8 +27,8 @@ into the database. */ class ElfImporter : public Importer { - llvm::OwningPtr binary; - llvm::OwningPtr disas; + std::unique_ptr binary; + std::unique_ptr disas; fail::CommandLine::option_handle OBJDUMP; fail::CommandLine::option_handle SOURCECODE; diff --git a/tools/import-trace/InstructionImporter.cc b/tools/import-trace/InstructionImporter.cc index 9ec80d68..de3cd91b 100644 --- a/tools/import-trace/InstructionImporter.cc +++ b/tools/import-trace/InstructionImporter.cc @@ -18,14 +18,20 @@ bool InstructionImporter::handle_ip_event(fail::simtime_t curtime, instruction_c llvm::InitializeAllTargetMCs(); llvm::InitializeAllDisassemblers(); - if (llvm::error_code ec = createBinary(m_elf->getFilename(), binary)) { - LOG << m_elf->getFilename() << "': " << ec.message() << ".\n"; + Expected> BinaryOrErr = createBinary(m_elf->getFilename()); + if (!BinaryOrErr) { + std::string Buf; + raw_string_ostream OS(Buf); + logAllUnhandledErrors(std::move(BinaryOrErr.takeError()), OS, ""); + OS.flush(); + LOG << m_elf->getFilename() << "': " << Buf << ".\n"; return false; } + binary = &(*BinaryOrErr.get().getBinary()); // necessary due to an AspectC++ bug triggered by LLVM 3.3's dyn_cast() #ifndef __puma - ObjectFile *obj = llvm::dyn_cast(binary.get()); + ObjectFile *obj = llvm::dyn_cast(binary); disas.reset(new LLVMDisassembler(obj)); #endif disas->disassemble(); diff --git a/tools/import-trace/InstructionImporter.hpp b/tools/import-trace/InstructionImporter.hpp index 39696e08..27391a30 100644 --- a/tools/import-trace/InstructionImporter.hpp +++ b/tools/import-trace/InstructionImporter.hpp @@ -6,8 +6,8 @@ #include "util/llvmdisassembler/LLVMDisassembler.hpp" class InstructionImporter : public Importer { - llvm::OwningPtr binary; - llvm::OwningPtr disas; + llvm::object::Binary *binary = 0; + std::unique_ptr disas; protected: virtual bool handle_ip_event(fail::simtime_t curtime, instruction_count_t instr, diff --git a/tools/import-trace/RandomJumpImporter.cc b/tools/import-trace/RandomJumpImporter.cc index 44ab597d..0f2a788f 100644 --- a/tools/import-trace/RandomJumpImporter.cc +++ b/tools/import-trace/RandomJumpImporter.cc @@ -65,14 +65,20 @@ bool RandomJumpImporter::handle_ip_event(fail::simtime_t curtime, instruction_co llvm::InitializeAllTargetMCs(); llvm::InitializeAllDisassemblers(); - if (llvm::error_code ec = createBinary(m_elf->getFilename(), binary)) { - LOG << m_elf->getFilename() << "': " << ec.message() << ".\n"; + Expected> BinaryOrErr = createBinary(m_elf->getFilename()); + if (!BinaryOrErr) { + std::string Buf; + raw_string_ostream OS(Buf); + logAllUnhandledErrors(std::move(BinaryOrErr.takeError()), OS, ""); + OS.flush(); + LOG << m_elf->getFilename() << "': " << Buf << ".\n"; return false; } + binary = &(*BinaryOrErr.get().getBinary()); // necessary due to an AspectC++ bug triggered by LLVM 3.3's dyn_cast() #ifndef __puma - ObjectFile *obj = dyn_cast(binary.get()); + ObjectFile *obj = dyn_cast(binary); disas.reset(new LLVMDisassembler(obj)); #endif disas->disassemble(); diff --git a/tools/import-trace/RandomJumpImporter.hpp b/tools/import-trace/RandomJumpImporter.hpp index 4181bae6..c48c7b38 100644 --- a/tools/import-trace/RandomJumpImporter.hpp +++ b/tools/import-trace/RandomJumpImporter.hpp @@ -8,8 +8,8 @@ #include "util/llvmdisassembler/LLVMDisassembler.hpp" class RandomJumpImporter : public Importer { - llvm::OwningPtr binary; - llvm::OwningPtr disas; + llvm::object::Binary *binary = 0; + std::unique_ptr disas; fail::CommandLine::option_handle FROM, TO; diff --git a/tools/import-trace/RegisterImporter.cc b/tools/import-trace/RegisterImporter.cc index 71585366..8422b214 100644 --- a/tools/import-trace/RegisterImporter.cc +++ b/tools/import-trace/RegisterImporter.cc @@ -133,19 +133,27 @@ bool RegisterImporter::handle_ip_event(fail::simtime_t curtime, instruction_coun llvm::InitializeAllTargetMCs(); llvm::InitializeAllDisassemblers(); - if (llvm::error_code ec = createBinary(m_elf->getFilename(), binary)) { - LOG << m_elf->getFilename() << "': " << ec.message() << ".\n"; + Expected> BinaryOrErr = createBinary(m_elf->getFilename()); + if (!BinaryOrErr) { + std::string Buf; + raw_string_ostream OS(Buf); + logAllUnhandledErrors(std::move(BinaryOrErr.takeError()), OS, ""); + OS.flush(); + LOG << m_elf->getFilename() << "': " << Buf << ".\n"; return false; } + binary = BinaryOrErr.get().getBinary(); // necessary due to an AspectC++ bug triggered by LLVM 3.3's dyn_cast() #ifndef __puma - ObjectFile *obj = dyn_cast(binary.get()); + ObjectFile *obj = dyn_cast(binary); disas.reset(new LLVMDisassembler(obj)); #endif disas->disassemble(); LLVMDisassembler::InstrMap &instr_map = disas->getInstrMap(); LOG << "instructions disassembled: " << instr_map.size() << " Triple: " << disas->GetTriple() << std::endl; + + m_ltof = disas->getTranslator() ; } // instruction pointer is read + written at each instruction @@ -165,12 +173,10 @@ bool RegisterImporter::handle_ip_event(fail::simtime_t curtime, instruction_coun const LLVMDisassembler::Instr &opcode = instr_map.at(ev.ip()); //const MCRegisterInfo ®_info = disas->getRegisterInfo(); - fail::LLVMtoFailTranslator & ltof = disas->getTranslator() ; - 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) { + const LLVMtoFailTranslator::reginfo_t &info = m_ltof->getFailRegisterID(*it); + if (&info == &m_ltof->notfound) { LOG << "Could not find a mapping for LLVM input register #" << std::dec << *it << " at IP " << std::hex << ev.ip() << ", skipping" << std::endl; @@ -189,8 +195,8 @@ 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) { + const LLVMtoFailTranslator::reginfo_t &info = m_ltof->getFailRegisterID(*it); + if (&info == &m_ltof->notfound) { LOG << "Could not find a mapping for LLVM output register #" << std::dec << *it << " at IP " << std::hex << ev.ip() << ", skipping" << std::endl; diff --git a/tools/import-trace/RegisterImporter.hpp b/tools/import-trace/RegisterImporter.hpp index 87fc1f14..377c9a82 100644 --- a/tools/import-trace/RegisterImporter.hpp +++ b/tools/import-trace/RegisterImporter.hpp @@ -9,8 +9,9 @@ class RegisterImporter : public Importer { - llvm::OwningPtr binary; - llvm::OwningPtr disas; + llvm::object::Binary *binary = 0; + std::unique_ptr disas; + fail::LLVMtoFailTranslator *m_ltof = 0; bool addRegisterTrace(fail::simtime_t curtime, instruction_count_t instr, Trace_Event &ev, diff --git a/tools/import-trace/main.cc b/tools/import-trace/main.cc index 9611c3a9..c3be1237 100644 --- a/tools/import-trace/main.cc +++ b/tools/import-trace/main.cc @@ -11,6 +11,7 @@ #include "util/AliasedRegistry.hpp" #ifdef BUILD_LLVM_DISASSEMBLER +#include "llvm/Support/ManagedStatic.h" #include "InstructionImporter.hpp" #include "RegisterImporter.hpp" #include "RandomJumpImporter.hpp" @@ -67,6 +68,7 @@ int main(int argc, char *argv[]) { registry.add(&fti); #ifdef BUILD_LLVM_DISASSEMBLER + llvm::llvm_shutdown_obj Y; RegisterImporter reg; registry.add(®); RandomJumpImporter rjump;