move to LLVM 3.9

This change removes support for earlier LLVM versions; making them
work as well is simply too tedious.

Change-Id: I372a151279ceb2bfd6de101c9e0c15f0a4b18c03
This commit is contained in:
Horst Schirmeier
2018-05-03 18:58:14 +02:00
parent baaa6c3ce8
commit ff3a5fb498
17 changed files with 175 additions and 131 deletions

View File

@ -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 ) if( NOT LLVMCONFIG )
message(FATAL_ERROR "llvm-config not found, try installing llvm-dev llvm") message(FATAL_ERROR "llvm-config not found, try installing llvm-dev llvm")

View File

@ -24,9 +24,7 @@ Required for FAIL*:
"-D__NO_MATH_INLINES -D__STRICT_ANSI__" or "--c_compiler clang++" (the "-D__NO_MATH_INLINES -D__STRICT_ANSI__" or "--c_compiler clang++" (the
latter requires the clang++ compiler). latter requires the clang++ compiler).
- optional: - optional:
* LLVM 3.3 or 3.4 (needed for several importers in tools/import-trace) * LLVM 3.9 (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)
- built with "make REQUIRES_RTTI=1" (the Debian/Ubuntu packages already - built with "make REQUIRES_RTTI=1" (the Debian/Ubuntu packages already
come built this way) come built this way)
- details below - details below
@ -289,12 +287,12 @@ Database backend setup: MySQL / MariaDB
========================================================================================= =========================================================================================
Building LLVM from sources 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 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. 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 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_34) repository http://llvm.org/git/llvm.git and checkout release_39)
2. Configure as needed. On mixed 32/64-bit systems (userland/kernel), 2. Configure as needed. On mixed 32/64-bit systems (userland/kernel),
prefixing with "linux32" may be necessary: prefixing with "linux32" may be necessary:
$ linux32 ./configure --prefix=$(echo ~/localroot/usr) --enable-optimized --disable-assertions --disable-werror $ linux32 ./configure --prefix=$(echo ~/localroot/usr) --enable-optimized --disable-assertions --disable-werror

View File

@ -81,7 +81,7 @@ add_library(fail-util ${SRCS})
add_dependencies(fail-util fail-comm) 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}) 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) if (BUILD_LLVM_DISASSEMBLER)
add_subdirectory(llvmdisassembler) add_subdirectory(llvmdisassembler)
endif (BUILD_LLVM_DISASSEMBLER) endif (BUILD_LLVM_DISASSEMBLER)

View File

@ -5,8 +5,8 @@ using namespace llvm;
using namespace llvm::object; using namespace llvm::object;
LLVMtoFailTranslator & LLVMDisassembler::getTranslator() { LLVMtoFailTranslator *LLVMDisassembler::getTranslator() {
if ( ltofail == 0 ) { if (ltofail == 0) {
std::cout << "ArchType: " << llvm::Triple::getArchTypeName( llvm::Triple::ArchType(object->getArch()) ) << std::endl; std::cout << "ArchType: " << llvm::Triple::getArchTypeName( llvm::Triple::ArchType(object->getArch()) ) << std::endl;
switch ( llvm::Triple::ArchType(object->getArch()) ) { switch ( llvm::Triple::ArchType(object->getArch()) ) {
@ -22,42 +22,44 @@ LLVMtoFailTranslator & LLVMDisassembler::getTranslator() {
exit(1); exit(1);
} }
} }
return *ltofail; return ltofail;
} }
void LLVMDisassembler::disassemble() void LLVMDisassembler::disassemble()
{ {
llvm::error_code ec; std::error_code ec;
for (section_iterator i = object->begin_sections(), for (section_iterator i = object->section_begin(),
e = object->end_sections(); e = object->section_end(); i != e; ++i) {
i != e; i.increment(ec)) { bool text = i->isText();
if (error(ec)) break;
bool text;
if (error(i->isText(text))) break;
if (!text) continue; if (!text) continue;
uint64_t SectionAddr; uint64_t SectionAddr = i->getAddress();
if (error(i->getAddress(SectionAddr))) break; // FIXME uint64_t SectionLength = i->getSize();
uint64_t SectionLength;
if (error(i->getSize(SectionLength))) break;
// Make a list of all the symbols in this section. // Make a list of all the symbols in this section.
std::vector<std::pair<uint64_t, StringRef> > Symbols; std::vector<std::pair<uint64_t, StringRef> > Symbols;
for (symbol_iterator si = object->begin_symbols(), for (const SymbolRef &symbol : object->symbols()) {
se = object->end_symbols();
si != se; si.increment(ec)) {
bool contains;
StringRef Name; StringRef Name;
if (!error(i->containsSymbol(*si, contains)) && contains) { if (!i->containsSymbol(symbol)) {
uint64_t Address; continue;
if (error(si->getAddress(Address))) break;
Address -= SectionAddr;
if (error(si->getName(Name))) break;
Symbols.push_back(std::make_pair(Address, Name));
} }
uint64_t Address;
Expected<uint64_t> AddrOrErr = symbol.getAddress();
if (!AddrOrErr) {
// FIXME fail
continue;
}
Address = *AddrOrErr - SectionAddr;
Expected<StringRef> 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. // 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()) if (Symbols.empty())
Symbols.push_back(std::make_pair(0, name)); Symbols.push_back(std::make_pair(0, name));
StringRef Bytes; StringRef BytesStr;
if (error(i->getContents(Bytes))) break; if (error(i->getContents(BytesStr))) break;
StringRefMemoryObject memoryObject(Bytes); ArrayRef<uint8_t> Bytes(reinterpret_cast<const uint8_t *>(BytesStr.data()),
BytesStr.size());
uint64_t Size; uint64_t Size;
uint64_t Index; uint64_t Index;
uint64_t SectSize; uint64_t SectSize = i->getSize();
if (error(i->getSize(SectSize))) break;
// Disassemble symbol by symbol. // Disassemble symbol by symbol.
for (unsigned si = 0, se = Symbols.size(); si != se; ++si) { for (unsigned si = 0, se = Symbols.size(); si != se; ++si) {
@ -100,7 +103,7 @@ void LLVMDisassembler::disassemble()
for (Index = Start; Index < End; Index += Size) { for (Index = Start; Index < End; Index += Size) {
MCInst Inst; MCInst Inst;
if (disas->getInstruction(Inst, Size, memoryObject, Index, if (disas->getInstruction(Inst, Size, Bytes.slice(Index), Index,
nulls(), nulls()) == MCDisassembler::Success) { nulls(), nulls()) == MCDisassembler::Success) {
const MCInstrDesc &desc = this->instr_info->get(Inst.getOpcode()); const MCInstrDesc &desc = this->instr_info->get(Inst.getOpcode());
// Inst.dump(); // Inst.dump();
@ -148,7 +151,4 @@ void LLVMDisassembler::disassemble()
} }
} }
} }
} }
void LLVMDisassembler::StringRefMemoryObject::anchor() {}

View File

@ -5,13 +5,17 @@
#include <vector> #include <vector>
#include <map> #include <map>
#include <limits.h> #include <limits.h>
#include <memory> // unique_ptr
#include "llvm/Object/ObjectFile.h" #include "llvm/Object/ObjectFile.h"
#include "llvm/ADT/STLExtras.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/MCInst.h"
#include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCSubtargetInfo.h"
@ -25,8 +29,6 @@
#include "llvm/Support/Casting.h" #include "llvm/Support/Casting.h"
#include "llvm/ADT/OwningPtr.h"
#include "LLVMtoFailTranslator.hpp" #include "LLVMtoFailTranslator.hpp"
#include "LLVMtoFailBochs.hpp" #include "LLVMtoFailBochs.hpp"
#include "LLVMtoFailGem5.hpp" #include "LLVMtoFailGem5.hpp"
@ -55,13 +57,13 @@ private:
std::string triple; std::string triple;
std::string MCPU; std::string MCPU;
std::string FeaturesStr; std::string FeaturesStr;
llvm::OwningPtr<llvm::MCSubtargetInfo> subtargetinfo; std::unique_ptr<const llvm::MCSubtargetInfo> subtargetinfo;
llvm::OwningPtr<const llvm::MCDisassembler> disas; std::unique_ptr<const llvm::MCDisassembler> disas;
llvm::OwningPtr<const llvm::MCInstrInfo> instr_info; std::unique_ptr<const llvm::MCInstrInfo> instr_info;
llvm::OwningPtr<const llvm::MCRegisterInfo> register_info; std::unique_ptr<const llvm::MCRegisterInfo> register_info;
llvm::OwningPtr<InstrMap> instrs; std::unique_ptr<InstrMap> instrs;
fail::LLVMtoFailTranslator * ltofail; fail::LLVMtoFailTranslator *ltofail;
static std::string GetTriple(const llvm::object::ObjectFile *Obj) { static std::string GetTriple(const llvm::object::ObjectFile *Obj) {
@ -84,41 +86,56 @@ private:
return 0; return 0;
} }
static bool error(llvm::error_code ec) { static bool error(std::error_code ec) {
if (!ec) return false; if (!ec) return false;
std::cerr << "DIS" << ": error reading file: " << ec.message() << ".\n"; std::cerr << "DIS error: " << ec.message() << ".\n";
return true; 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: public:
LLVMDisassembler(const llvm::object::ObjectFile *object) : ltofail(0) { LLVMDisassembler(const llvm::object::ObjectFile *object) : ltofail(0) {
this->object = object; this->object = object;
this->triple = GetTriple(object); this->triple = GetTriple(object);
this->target = GetTarget(triple); this->target = GetTarget(triple);
this->subtargetinfo.reset(target->createMCSubtargetInfo(triple, MCPU, FeaturesStr));
this->disas.reset(target->createMCDisassembler(*subtargetinfo)); std::unique_ptr<const llvm::MCRegisterInfo> MRI(target->createMCRegInfo(triple));
this->instr_info.reset(target->createMCInstrInfo()); if (!MRI) {
this->register_info.reset(target->createMCRegInfo(triple)); std::cerr << "DIS error: no register info for target " << triple << "\n";
return;
}
std::unique_ptr<const llvm::MCAsmInfo> MAI(target->createMCAsmInfo(*MRI, triple));
if (!MAI) {
std::cerr << "DIS error: no assembly info for target " << triple << "\n";
return;
}
std::unique_ptr<const llvm::MCSubtargetInfo> STI(
target->createMCSubtargetInfo(triple, MCPU, FeaturesStr));
if (!STI) {
std::cerr << "DIS error: no subtarget info for target " << triple << "\n";
return;
}
std::unique_ptr<const llvm::MCInstrInfo> MII(target->createMCInstrInfo());
if (!MII) {
std::cerr << "DIS error: no instruction info for target " << triple << "\n";
return;
}
std::unique_ptr<const llvm::MCObjectFileInfo> 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<llvm::MCDisassembler> 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()); this->instrs.reset(new InstrMap());
} }
@ -126,14 +143,13 @@ public:
~LLVMDisassembler() { delete ltofail; }; ~LLVMDisassembler() { delete ltofail; };
InstrMap &getInstrMap() { return *instrs; }; InstrMap &getInstrMap() { return *instrs; };
const llvm::MCRegisterInfo &getRegisterInfo() { return *register_info;} const llvm::MCRegisterInfo& getRegisterInfo() { return *register_info; }
fail::LLVMtoFailTranslator & getTranslator() ; fail::LLVMtoFailTranslator *getTranslator() ;
const std::string & GetTriple() const { return triple; }; const std::string& GetTriple() const { return triple; };
void disassemble(); void disassemble();
}; };
} }
#endif // __LLVMDISASSEMBLER_HPP__ #endif // __LLVMDISASSEMBLER_HPP__

View File

@ -43,20 +43,18 @@ void LLVMtoFailTranslator::setRegisterContent(ConcreteCPU & cpu, const reginfo_t
} }
LLVMtoFailTranslator* LLVMtoFailTranslator::createFromBinary(const std::string elf_path) { LLVMtoFailTranslator* LLVMtoFailTranslator::createFromBinary(const std::string elf_path) {
llvm_shutdown_obj Y; //llvm_shutdown_obj Y;
llvm::InitializeAllTargetInfos(); llvm::InitializeAllTargetInfos();
llvm::InitializeAllTargetMCs(); llvm::InitializeAllTargetMCs();
llvm::InitializeAllDisassemblers(); llvm::InitializeAllDisassemblers();
OwningPtr<Binary> binary; Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(elf_path);
llvm::error_code ret = createBinary(elf_path, binary); assert (BinaryOrErr);
assert (ret == 0); Binary *binary = BinaryOrErr.get().getBinary();
(void) ret; // unused in release builds
assert (binary.get() != NULL);
#ifndef __puma #ifndef __puma
LLVMDisassembler disas(dyn_cast<ObjectFile>(binary.get())); LLVMDisassembler disas(dyn_cast<ObjectFile>(binary));
return &disas.getTranslator(); return disas.getTranslator();
#else #else
return 0; return 0;
#endif #endif

View File

@ -1,3 +1,4 @@
#include "llvm/Support/raw_os_ostream.h"
#include "../LLVMDisassembler.hpp" #include "../LLVMDisassembler.hpp"
using namespace llvm; using namespace llvm;
@ -22,13 +23,16 @@ int main(int argc, char* argv[]) {
return -1; return -1;
} }
OwningPtr<Binary> binary; Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(file);
if (llvm::error_code ec = createBinary(file, binary)) { if (!BinaryOrErr) {
std::cerr << "Dis" << ": '" << file << "': " << ec.message() << ".\n"; std::cerr << "Dis: '" << file << "': ";
raw_os_ostream OS(std::cerr);
logAllUnhandledErrors(BinaryOrErr.takeError(), OS, "");
return -1; return -1;
} }
Binary *binary = BinaryOrErr.get().getBinary();
ObjectFile *obj = dyn_cast<ObjectFile>(binary.get()); ObjectFile *obj = dyn_cast<ObjectFile>(binary);
LLVMDisassembler disas(obj); LLVMDisassembler disas(obj);
disas.disassemble(); disas.disassemble();
@ -40,26 +44,27 @@ int main(int argc, char* argv[]) {
const MCRegisterInfo &reg_info = disas.getRegisterInfo(); const MCRegisterInfo &reg_info = disas.getRegisterInfo();
std::cout << std::endl << "Number of Registers: " << reg_info.getNumRegs() << std::endl; std::cout << std::endl << "Number of Registers: " << reg_info.getNumRegs() << std::endl;
// for(unsigned int i = 0; i < reg_info.getNumRegs(); ++i){ for (unsigned int i = 0; i < reg_info.getNumRegs(); ++i) {
// std::cout << i << " - " << reg_info.getName(i) << std::endl; std::cout << i << "=" << reg_info.getName(i) << " ";
// } }
fail::LLVMtoFailTranslator & ltof = disas.getTranslator() ; 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; const LLVMDisassembler::Instr &instr = (*itr).second;
std::cout << std::hex << (*itr).first << " | " << instr.opcode << std::endl; std::cout << std::hex << (*itr).first << " | " << instr.opcode << std::endl;
std::cout << std::dec << "USES: "; std::cout << std::dec << "USES: ";
for (std::vector<uint16_t>::const_iterator it = instr.reg_uses.begin(); for (std::vector<uint16_t>::const_iterator it = instr.reg_uses.begin();
it != instr.reg_uses.end(); ++it) { it != instr.reg_uses.end(); ++it) {
std::cout << reg_info.getName(*it) <<"(" << *it << ") "; std::cout << reg_info.getName(*it)
std::cout << "Fail: " << ltof.getFailRegisterId(*it) << " "; << "(" << *it << "->" << ltof->getFailRegisterId(*it) << ") ";
} }
std::cout << std::endl;
std::cout << "DEFS: "; std::cout << " | DEFS: ";
for (std::vector<uint16_t>::const_iterator it = instr.reg_defs.begin(); for (std::vector<uint16_t>::const_iterator it = instr.reg_defs.begin();
it != instr.reg_defs.end(); ++it) { 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) { if (instr.conditional_branch) {

View File

@ -104,14 +104,20 @@ bool AdvancedMemoryImporter::handle_ip_event(fail::simtime_t curtime, instructio
llvm::InitializeAllTargetMCs(); llvm::InitializeAllTargetMCs();
llvm::InitializeAllDisassemblers(); llvm::InitializeAllDisassemblers();
if (llvm::error_code ec = createBinary(m_elf->getFilename(), binary)) { Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(m_elf->getFilename());
LOG << m_elf->getFilename() << "': " << ec.message() << ".\n"; 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; return false;
} }
binary = &(*BinaryOrErr.get().getBinary());
// necessary due to an AspectC++ bug triggered by LLVM 3.3's dyn_cast() // necessary due to an AspectC++ bug triggered by LLVM 3.3's dyn_cast()
#ifndef __puma #ifndef __puma
ObjectFile *obj = dyn_cast<ObjectFile>(binary.get()); ObjectFile *obj = dyn_cast<ObjectFile>(binary);
disas.reset(new LLVMDisassembler(obj)); disas.reset(new LLVMDisassembler(obj));
#endif #endif
disas->disassemble(); disas->disassemble();

View File

@ -24,8 +24,8 @@
* operations with a set of new virtual functions that are called downwards. * operations with a set of new virtual functions that are called downwards.
*/ */
class AdvancedMemoryImporter : public MemoryImporter { class AdvancedMemoryImporter : public MemoryImporter {
llvm::OwningPtr<llvm::object::Binary> binary; llvm::object::Binary *binary = 0;
llvm::OwningPtr<fail::LLVMDisassembler> disas; std::unique_ptr<fail::LLVMDisassembler> disas;
bool m_last_was_conditional_branch; bool m_last_was_conditional_branch;
fail::guest_address_t m_ip_jump_not_taken; fail::guest_address_t m_ip_jump_not_taken;
std::vector<bool> branches_taken; std::vector<bool> branches_taken;

View File

@ -27,8 +27,8 @@
into the database. into the database.
*/ */
class ElfImporter : public Importer { class ElfImporter : public Importer {
llvm::OwningPtr<llvm::object::Binary> binary; std::unique_ptr<llvm::object::Binary> binary;
llvm::OwningPtr<fail::LLVMDisassembler> disas; std::unique_ptr<fail::LLVMDisassembler> disas;
fail::CommandLine::option_handle OBJDUMP; fail::CommandLine::option_handle OBJDUMP;
fail::CommandLine::option_handle SOURCECODE; fail::CommandLine::option_handle SOURCECODE;

View File

@ -18,14 +18,20 @@ bool InstructionImporter::handle_ip_event(fail::simtime_t curtime, instruction_c
llvm::InitializeAllTargetMCs(); llvm::InitializeAllTargetMCs();
llvm::InitializeAllDisassemblers(); llvm::InitializeAllDisassemblers();
if (llvm::error_code ec = createBinary(m_elf->getFilename(), binary)) { Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(m_elf->getFilename());
LOG << m_elf->getFilename() << "': " << ec.message() << ".\n"; 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; return false;
} }
binary = &(*BinaryOrErr.get().getBinary());
// necessary due to an AspectC++ bug triggered by LLVM 3.3's dyn_cast() // necessary due to an AspectC++ bug triggered by LLVM 3.3's dyn_cast()
#ifndef __puma #ifndef __puma
ObjectFile *obj = llvm::dyn_cast<ObjectFile>(binary.get()); ObjectFile *obj = llvm::dyn_cast<ObjectFile>(binary);
disas.reset(new LLVMDisassembler(obj)); disas.reset(new LLVMDisassembler(obj));
#endif #endif
disas->disassemble(); disas->disassemble();

View File

@ -6,8 +6,8 @@
#include "util/llvmdisassembler/LLVMDisassembler.hpp" #include "util/llvmdisassembler/LLVMDisassembler.hpp"
class InstructionImporter : public Importer { class InstructionImporter : public Importer {
llvm::OwningPtr<llvm::object::Binary> binary; llvm::object::Binary *binary = 0;
llvm::OwningPtr<fail::LLVMDisassembler> disas; std::unique_ptr<fail::LLVMDisassembler> disas;
protected: protected:
virtual bool handle_ip_event(fail::simtime_t curtime, instruction_count_t instr, virtual bool handle_ip_event(fail::simtime_t curtime, instruction_count_t instr,

View File

@ -65,14 +65,20 @@ bool RandomJumpImporter::handle_ip_event(fail::simtime_t curtime, instruction_co
llvm::InitializeAllTargetMCs(); llvm::InitializeAllTargetMCs();
llvm::InitializeAllDisassemblers(); llvm::InitializeAllDisassemblers();
if (llvm::error_code ec = createBinary(m_elf->getFilename(), binary)) { Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(m_elf->getFilename());
LOG << m_elf->getFilename() << "': " << ec.message() << ".\n"; 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; return false;
} }
binary = &(*BinaryOrErr.get().getBinary());
// necessary due to an AspectC++ bug triggered by LLVM 3.3's dyn_cast() // necessary due to an AspectC++ bug triggered by LLVM 3.3's dyn_cast()
#ifndef __puma #ifndef __puma
ObjectFile *obj = dyn_cast<ObjectFile>(binary.get()); ObjectFile *obj = dyn_cast<ObjectFile>(binary);
disas.reset(new LLVMDisassembler(obj)); disas.reset(new LLVMDisassembler(obj));
#endif #endif
disas->disassemble(); disas->disassemble();

View File

@ -8,8 +8,8 @@
#include "util/llvmdisassembler/LLVMDisassembler.hpp" #include "util/llvmdisassembler/LLVMDisassembler.hpp"
class RandomJumpImporter : public Importer { class RandomJumpImporter : public Importer {
llvm::OwningPtr<llvm::object::Binary> binary; llvm::object::Binary *binary = 0;
llvm::OwningPtr<fail::LLVMDisassembler> disas; std::unique_ptr<fail::LLVMDisassembler> disas;
fail::CommandLine::option_handle FROM, TO; fail::CommandLine::option_handle FROM, TO;

View File

@ -133,19 +133,27 @@ bool RegisterImporter::handle_ip_event(fail::simtime_t curtime, instruction_coun
llvm::InitializeAllTargetMCs(); llvm::InitializeAllTargetMCs();
llvm::InitializeAllDisassemblers(); llvm::InitializeAllDisassemblers();
if (llvm::error_code ec = createBinary(m_elf->getFilename(), binary)) { Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(m_elf->getFilename());
LOG << m_elf->getFilename() << "': " << ec.message() << ".\n"; 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; return false;
} }
binary = BinaryOrErr.get().getBinary();
// necessary due to an AspectC++ bug triggered by LLVM 3.3's dyn_cast() // necessary due to an AspectC++ bug triggered by LLVM 3.3's dyn_cast()
#ifndef __puma #ifndef __puma
ObjectFile *obj = dyn_cast<ObjectFile>(binary.get()); ObjectFile *obj = dyn_cast<ObjectFile>(binary);
disas.reset(new LLVMDisassembler(obj)); disas.reset(new LLVMDisassembler(obj));
#endif #endif
disas->disassemble(); disas->disassemble();
LLVMDisassembler::InstrMap &instr_map = disas->getInstrMap(); LLVMDisassembler::InstrMap &instr_map = disas->getInstrMap();
LOG << "instructions disassembled: " << instr_map.size() << " Triple: " << disas->GetTriple() << std::endl; LOG << "instructions disassembled: " << instr_map.size() << " Triple: " << disas->GetTriple() << std::endl;
m_ltof = disas->getTranslator() ;
} }
// instruction pointer is read + written at each instruction // 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 LLVMDisassembler::Instr &opcode = instr_map.at(ev.ip());
//const MCRegisterInfo &reg_info = disas->getRegisterInfo(); //const MCRegisterInfo &reg_info = disas->getRegisterInfo();
fail::LLVMtoFailTranslator & ltof = disas->getTranslator() ;
for (std::vector<LLVMDisassembler::register_t>::const_iterator it = opcode.reg_uses.begin(); for (std::vector<LLVMDisassembler::register_t>::const_iterator it = opcode.reg_uses.begin();
it != opcode.reg_uses.end(); ++it) { it != opcode.reg_uses.end(); ++it) {
const LLVMtoFailTranslator::reginfo_t &info = ltof.getFailRegisterID(*it); const LLVMtoFailTranslator::reginfo_t &info = m_ltof->getFailRegisterID(*it);
if (&info == &ltof.notfound) { if (&info == &m_ltof->notfound) {
LOG << "Could not find a mapping for LLVM input register #" << std::dec << *it LOG << "Could not find a mapping for LLVM input register #" << std::dec << *it
<< " at IP " << std::hex << ev.ip() << " at IP " << std::hex << ev.ip()
<< ", skipping" << std::endl; << ", skipping" << std::endl;
@ -189,8 +195,8 @@ bool RegisterImporter::handle_ip_event(fail::simtime_t curtime, instruction_coun
for (std::vector<LLVMDisassembler::register_t>::const_iterator it = opcode.reg_defs.begin(); for (std::vector<LLVMDisassembler::register_t>::const_iterator it = opcode.reg_defs.begin();
it != opcode.reg_defs.end(); ++it) { it != opcode.reg_defs.end(); ++it) {
const LLVMtoFailTranslator::reginfo_t &info = ltof.getFailRegisterID(*it); const LLVMtoFailTranslator::reginfo_t &info = m_ltof->getFailRegisterID(*it);
if (&info == &ltof.notfound) { if (&info == &m_ltof->notfound) {
LOG << "Could not find a mapping for LLVM output register #" << std::dec << *it LOG << "Could not find a mapping for LLVM output register #" << std::dec << *it
<< " at IP " << std::hex << ev.ip() << " at IP " << std::hex << ev.ip()
<< ", skipping" << std::endl; << ", skipping" << std::endl;

View File

@ -9,8 +9,9 @@
class RegisterImporter : public Importer { class RegisterImporter : public Importer {
llvm::OwningPtr<llvm::object::Binary> binary; llvm::object::Binary *binary = 0;
llvm::OwningPtr<fail::LLVMDisassembler> disas; std::unique_ptr<fail::LLVMDisassembler> disas;
fail::LLVMtoFailTranslator *m_ltof = 0;
bool addRegisterTrace(fail::simtime_t curtime, instruction_count_t instr, bool addRegisterTrace(fail::simtime_t curtime, instruction_count_t instr,
Trace_Event &ev, Trace_Event &ev,

View File

@ -11,6 +11,7 @@
#include "util/AliasedRegistry.hpp" #include "util/AliasedRegistry.hpp"
#ifdef BUILD_LLVM_DISASSEMBLER #ifdef BUILD_LLVM_DISASSEMBLER
#include "llvm/Support/ManagedStatic.h"
#include "InstructionImporter.hpp" #include "InstructionImporter.hpp"
#include "RegisterImporter.hpp" #include "RegisterImporter.hpp"
#include "RandomJumpImporter.hpp" #include "RandomJumpImporter.hpp"
@ -67,6 +68,7 @@ int main(int argc, char *argv[]) {
registry.add(&fti); registry.add(&fti);
#ifdef BUILD_LLVM_DISASSEMBLER #ifdef BUILD_LLVM_DISASSEMBLER
llvm::llvm_shutdown_obj Y;
RegisterImporter reg; RegisterImporter reg;
registry.add(&reg); registry.add(&reg);
RandomJumpImporter rjump; RandomJumpImporter rjump;