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:
@ -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")
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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() {}
|
|
||||||
|
|||||||
@ -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__
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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 ®_info = disas.getRegisterInfo();
|
const MCRegisterInfo ®_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) {
|
||||||
|
|||||||
@ -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();
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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();
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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();
|
||||||
|
|||||||
@ -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;
|
||||||
|
|
||||||
|
|||||||
@ -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 ®_info = disas->getRegisterInfo();
|
//const MCRegisterInfo ®_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 == <of.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 == <of.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;
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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(®);
|
registry.add(®);
|
||||||
RandomJumpImporter rjump;
|
RandomJumpImporter rjump;
|
||||||
|
|||||||
Reference in New Issue
Block a user