(capstone) feat: add capstone disassembler to tools/import-trace/

This commit is contained in:
Robin Thunig
2019-11-01 01:24:28 +01:00
committed by Robin Thunig
parent d04afaac54
commit f7f982fec5
14 changed files with 407 additions and 14 deletions

View File

@ -2,8 +2,10 @@
#include <sstream>
#include "AdvancedMemoryImporter.hpp"
#ifdef BUILD_LLVM_DISASSEMBLER
using namespace llvm;
using namespace llvm::object;
#endif
using namespace fail;
static fail::Logger LOG("AdvancedMemoryImporter");
@ -98,6 +100,35 @@ bool AdvancedMemoryImporter::handle_ip_event(fail::simtime_t curtime, instructio
// (delayed) trace entries
insert_delayed_entries(false);
#if defined(BUILD_CAPSTONE_DISASSEMBLER)
if (!isDisassembled) {
if (!m_elf) {
LOG << "Please give an ELF binary as parameter (-e/--elf)." << std::endl;
return false;
}
disas.reset(new CapstoneDisassembler(m_elf));
disas->disassemble();
CapstoneDisassembler::InstrMap &instr_map = disas->getInstrMap();
LOG << "instructions disassembled: " << std::dec << instr_map.size() << std::endl;
#if 0
for (CapstoneDisassembler::InstrMap::const_iterator it = instr_map.begin();
it != instr_map.end(); ++it) {
LOG << "DIS " << std::hex << it->second.address << " " << (int) it->second.length << std::endl;
}
#endif
}
const CapstoneDisassembler::InstrMap &instr_map = disas->getInstrMap();
const CapstoneDisassembler::InstrMap::const_iterator it = instr_map.find(ev.ip());
if (it == instr_map.end()) {
LOG << "WARNING: CapstoneDisassembler hasn't disassembled instruction at 0x"
<< ev.ip() << " -- are you using Capstone < 4.0?" << std::endl;
return true; // probably weird things will happen now
}
const CapstoneDisassembler::Instr &opcode = it->second;
#elif defined(BUILD_LLVM_DISASSEMBLER)
if (!binary) {
/* Disassemble the binary if necessary */
llvm::InitializeAllTargetInfos();
@ -144,6 +175,7 @@ bool AdvancedMemoryImporter::handle_ip_event(fail::simtime_t curtime, instructio
return true; // probably weird things will happen now
}
const LLVMDisassembler::Instr &opcode = it->second;
#endif
/* Now we've got the opcode and know whether it's a conditional branch. If
* it is, the next IP event will tell us whether it was taken or not. */
@ -161,8 +193,13 @@ bool AdvancedMemoryImporter::handle_ip_event(fail::simtime_t curtime, instructio
bool AdvancedMemoryImporter::handle_mem_event(fail::simtime_t curtime, instruction_count_t instr,
Trace_Event &ev)
{
#if defined(BUILD_CAPSTONE_DISASSEMBLER)
const CapstoneDisassembler::InstrMap &instr_map = disas->getInstrMap();
const CapstoneDisassembler::Instr &opcode = instr_map.at(ev.ip());
#elif defined(BUILD_LLVM_DISASSEMBLER)
const LLVMDisassembler::InstrMap &instr_map = disas->getInstrMap();
const LLVMDisassembler::Instr &opcode = instr_map.at(ev.ip());
#endif
DelayedTraceEntry entry = { curtime, instr, ev, opcode.opcode, (unsigned) branches_taken.size() };
delayed_entries.push_back(entry);

View File

@ -5,7 +5,11 @@
#include <deque>
#include "MemoryImporter.hpp"
#if defined(BUILD_CAPSTONE_DISASSEMBLER)
#include "util/capstonedisassembler/CapstoneDisassembler.hpp"
#elif defined(BUILD_LLVM_DISASSEMBLER)
#include "util/llvmdisassembler/LLVMDisassembler.hpp"
#endif
/**
* A MemoryImporter that additionally imports Relyzer-style conditional branch
@ -24,8 +28,13 @@
* operations with a set of new virtual functions that are called downwards.
*/
class AdvancedMemoryImporter : public MemoryImporter {
#if defined(BUILD_CAPSTONE_DISASSEMBLER)
bool isDisassembled = false;
std::unique_ptr<fail::CapstoneDisassembler> disas;
#elif defined(BUILD_LLVM_DISASSEMBLER)
llvm::object::Binary *binary = 0;
std::unique_ptr<fail::LLVMDisassembler> disas;
#endif
bool m_last_was_conditional_branch;
fail::guest_address_t m_ip_jump_not_taken;
std::vector<bool> branches_taken;

View File

@ -28,9 +28,26 @@ if (BUILD_LLVM_DISASSEMBLER)
find_package(LibDwarf REQUIRED)
include_directories(${LIBELF_INCLUDE_DIRS})
include_directories(${LIBDWARF_INCLUDE_DIRS})
endif(BUILD_LLVM_DISASSEMBLER)
if (BUILD_CAPSTONE_DISASSEMBLER)
set(SRCS ${SRCS}
InstructionImporter.cc
RegisterImporter.cc
RandomJumpImporter.cc
AdvancedMemoryImporter.cc
ElfImporter.cc
)
include(FindCapstone)
# libelf and libdwarf required by ElfImporter
find_package(LibElf REQUIRED)
find_package(LibDwarf REQUIRED)
include_directories(${LIBELF_INCLUDE_DIRS})
include_directories(${LIBDWARF_INCLUDE_DIRS})
endif(BUILD_CAPSTONE_DISASSEMBLER)
find_package(MySQL REQUIRED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MYSQL_CFLAGS}")
@ -48,5 +65,9 @@ if (BUILD_LLVM_DISASSEMBLER)
target_link_libraries(import-trace fail-llvmdisassembler fail-sal ${LLVM_LIBS} ${LLVM_LDFLAGS} ${Boost_LIBRARIES})
endif (BUILD_LLVM_DISASSEMBLER)
if (BUILD_CAPSTONE_DISASSEMBLER)
target_link_libraries(import-trace fail-capstonedisassembler fail-sal)
endif (BUILD_CAPSTONE_DISASSEMBLER)
install(TARGETS import-trace RUNTIME DESTINATION bin)
install(PROGRAMS import-symbols.sh DESTINATION bin)

View File

@ -9,9 +9,10 @@
#include <boost/algorithm/string.hpp>
#endif
#ifdef BUILD_LLVM_DISASSEMBLER
using namespace llvm;
using namespace llvm::object;
#endif
using namespace fail;
using namespace std;

View File

@ -7,7 +7,13 @@
#include "libelf.h"
#include "Importer.hpp"
#if defined(BUILD_CAPSTONE_DISASSEMBLER)
#include "util/capstonedisassembler/CapstoneDisassembler.hpp"
#elif defined(BUILD_LLVM_DISASSEMBLER)
#include "util/llvmdisassembler/LLVMDisassembler.hpp"
#endif
#include "util/CommandLine.hpp"
#include "util/DwarfReader.hpp"
@ -27,8 +33,11 @@
into the database.
*/
class ElfImporter : public Importer {
std::unique_ptr<llvm::object::Binary> binary;
#if defined(BUILD_CAPSTONE_DISASSEMBLER)
std::unique_ptr<fail::CapstoneDisassembler> disas;
#elif defined(BUILD_LLVM_DISASSEMBLER)
std::unique_ptr<fail::LLVMDisassembler> disas;
#endif
fail::CommandLine::option_handle OBJDUMP;
fail::CommandLine::option_handle SOURCECODE;

View File

@ -3,8 +3,10 @@
#include "InstructionImporter.hpp"
#include "util/Logger.hpp"
#ifdef BUILD_LLVM_DISASSEMBLER
using namespace llvm;
using namespace llvm::object;
#endif
using namespace fail;
@ -12,6 +14,28 @@ static Logger LOG("InstructionImporter");
bool InstructionImporter::handle_ip_event(fail::simtime_t curtime, instruction_count_t instr,
Trace_Event &ev) {
#if defined(BUILD_CAPSTONE_DISASSEMBLER)
if (!isDisassembled) {
if (!m_elf) {
LOG << "Please give an ELF binary as parameter (-e/--elf)." << std::endl;
return false;
}
disas.reset(new CapstoneDisassembler(m_elf));
disas->disassemble();
CapstoneDisassembler::InstrMap &instr_map = disas->getInstrMap();
LOG << "instructions disassembled: " << instr_map.size() << std::endl;
isDisassembled = true;
}
const CapstoneDisassembler::InstrMap &instr_map = disas->getInstrMap();
if (instr_map.find(ev.ip()) == instr_map.end()) {
LOG << "Could not find instruction for IP " << std::hex << ev.ip()
<< ", skipping" << std::endl;
return true;
}
const CapstoneDisassembler::Instr &opcode = instr_map.at(ev.ip());
#elif defined(BUILD_LLVM_DISASSEMBLER)
if (!binary) {
/* Disassemble the binary if necessary */
llvm::InitializeAllTargetInfos();
@ -46,6 +70,7 @@ bool InstructionImporter::handle_ip_event(fail::simtime_t curtime, instruction_c
const LLVMDisassembler::InstrMap &instr_map = disas->getInstrMap();
const LLVMDisassembler::Instr &opcode = instr_map.at(ev.ip());
#endif
address_t from = ev.ip(), to = ev.ip() + opcode.length;

View File

@ -3,11 +3,20 @@
#include "Importer.hpp"
#if defined(BUILD_CAPSTONE_DISASSEMBLER)
#include "util/capstonedisassembler/CapstoneDisassembler.hpp"
#elif defined(BUILD_LLVM_DISASSEMBLER)
#include "util/llvmdisassembler/LLVMDisassembler.hpp"
#endif
class InstructionImporter : public Importer {
#if defined(BUILD_CAPSTONE_DISASSEMBLER)
bool isDisassembled = false;
std::unique_ptr<fail::CapstoneDisassembler> disas;
#elif defined(BUILD_LLVM_DISASSEMBLER)
llvm::object::Binary *binary = 0;
std::unique_ptr<fail::LLVMDisassembler> disas;
#endif
protected:
virtual bool handle_ip_event(fail::simtime_t curtime, instruction_count_t instr,

View File

@ -3,8 +3,10 @@
#include "util/Logger.hpp"
#include "RandomJumpImporter.hpp"
#ifdef BUILD_LLVM_DISASSEMBLER
using namespace llvm;
using namespace llvm::object;
#endif
using namespace fail;
using namespace std;
@ -60,6 +62,22 @@ bool RandomJumpImporter::handle_ip_event(fail::simtime_t curtime, instruction_co
return false;
}
#if defined(BUILD_CAPSTONE_DISASSEMBLER)
disas.reset(new CapstoneDisassembler(m_elf));
disas->disassemble();
CapstoneDisassembler::InstrMap &instr_map = disas->getInstrMap();
LOG << "instructions disassembled: " << instr_map.size() << std::endl;
/* Collect all addresses we want to jump to */
for (CapstoneDisassembler::InstrMap::const_iterator instr = instr_map.begin();
instr != instr_map.end(); ++instr) {
if (m_mm_to && m_mm_to->isMatching(instr->first)) {
m_jump_to_addresses.push_back(instr->first);
}
}
binary = true;
#elif defined(BUILD_LLVM_DISASSEMBLER)
/* Disassemble the binary if necessary */
llvm::InitializeAllTargetInfos();
llvm::InitializeAllTargetMCs();
@ -92,6 +110,7 @@ bool RandomJumpImporter::handle_ip_event(fail::simtime_t curtime, instruction_co
m_jump_to_addresses.push_back(instr->first);
}
}
#endif
LOG << "we will jump to " << m_jump_to_addresses.size() << " addresses" << endl;
}

View File

@ -5,11 +5,20 @@
#include "util/CommandLine.hpp"
#include "Importer.hpp"
#if defined(BUILD_CAPSTONE_DISASSEMBLER)
#include "util/capstonedisassembler/CapstoneDisassembler.hpp"
#elif defined(BUILD_LLVM_DISASSEMBLER)
#include "util/llvmdisassembler/LLVMDisassembler.hpp"
#endif
class RandomJumpImporter : public Importer {
#if defined(BUILD_CAPSTONE_DISASSEMBLER)
bool binary = false;
std::unique_ptr<fail::CapstoneDisassembler> disas;
#elif defined(BUILD_LLVM_DISASSEMBLER)
llvm::object::Binary *binary = 0;
std::unique_ptr<fail::LLVMDisassembler> disas;
#endif
fail::CommandLine::option_handle FROM, TO;

View File

@ -3,8 +3,11 @@
#include "RegisterImporter.hpp"
#include "util/Logger.hpp"
#ifdef BUILD_LLVM_DISASSEMBLER
using namespace llvm;
using namespace llvm::object;
#endif
using namespace fail;
@ -29,7 +32,214 @@ bool RegisterImporter::cb_commandline_init() {
return true;
}
#if defined(BUILD_CAPSTONE_DISASSEMBLER)
bool RegisterImporter::addRegisterTrace(simtime_t curtime, instruction_count_t instr,
Trace_Event &ev,
const CapstoneToFailTranslator::reginfo_t &info,
char access_type) {
address_t from, to;
int chunk_width;
if (do_split_registers) {
/* If we want to split the registers into one byte chunks (to
enable proper pruning, we use a one byte window register,
to determine beginning and end address */
CapstoneToFailTranslator::reginfo_t one_byte_window = info;
one_byte_window.width = 8;
from = one_byte_window.toDataAddress();
to = one_byte_window.toDataAddress() + info.width / 8;
chunk_width = 1; // One byte chunks
} else {
/* We trace whole registers */
from = info.toDataAddress();
to = from + 1; /* exactly one trace event per register access*/
chunk_width = (info.width / 8);
}
// Iterate over all accessed bytes
for (address_t data_address = from; data_address < to; ++data_address) {
// skip events outside a possibly supplied memory map
if (m_mm && !m_mm->isMatching(ev.ip())) {
continue;
}
margin_info_t left_margin = getOpenEC(data_address);
margin_info_t right_margin;
right_margin.time = curtime;
right_margin.dyninstr = instr; // !< The current instruction
right_margin.ip = ev.ip();
// skip zero-sized intervals: these can occur when an instruction
// accesses a memory location more than once (e.g., INC, CMPXCHG)
if (left_margin.dyninstr > right_margin.dyninstr) {
continue;
}
// we now have an interval-terminating R/W event to the memaddr
// we're currently looking at; the EC is defined by
// data_address, dynamic instruction start/end, the absolute PC at
// the end, and time start/end
// pass through potentially available extended trace information
ev.set_width(chunk_width);
ev.set_memaddr(data_address);
ev.set_accesstype(access_type == 'R' ? ev.READ : ev.WRITE);
if (!add_trace_event(left_margin, right_margin, ev)) {
LOG << "add_trace_event failed" << std::endl;
return false;
}
// next interval must start at next instruction; the aforementioned
// skipping mechanism wouldn't work otherwise
newOpenEC(data_address, curtime + 1, instr + 1, ev.ip());
}
return true;
}
bool RegisterImporter::handle_ip_event(fail::simtime_t curtime, instruction_count_t instr,
Trace_Event &ev) {
if (!isDisassembled) {
// Parse command line again, for jump-from and jump-to
// operations
CommandLine &cmd = CommandLine::Inst();
if (!cmd.parse()) {
std::cerr << "Error parsing arguments." << std::endl;
return false;
}
do_gp = !cmd[NO_GP];
do_flags = cmd[FLAGS];
do_ip = cmd[IP];
do_split_registers = !cmd[NO_SPLIT];
// retrieve register IDs for general-purpose and flags register(s) for
// the configured architecture
fail::Architecture arch;
m_ip_register_id =
(*arch.getRegisterSetOfType(RT_IP)->begin())->getId();
fail::UniformRegisterSet *regset;
if (do_gp) {
regset = arch.getRegisterSetOfType(RT_GP);
for (fail::UniformRegisterSet::iterator it = regset->begin();
it != regset->end(); ++it) {
m_register_ids.insert((*it)->getId());
}
}
if (do_flags) {
regset = arch.getRegisterSetOfType(RT_ST);
for (fail::UniformRegisterSet::iterator it = regset->begin();
it != regset->end(); ++it) {
m_register_ids.insert((*it)->getId());
}
}
if (!m_elf) {
LOG << "Please give an ELF binary as parameter (-e/--elf)." << std::endl;
return false;
}
disas.reset(new CapstoneDisassembler(m_elf));
LOG << "Start to dissamble" << std::endl;
disas->disassemble();
LOG << "Get instr map" << std::endl;
CapstoneDisassembler::InstrMap &instr_map = disas->getInstrMap();
LOG << "instructions disassembled: " << std::dec << instr_map.size() << std::endl;
m_ctof = disas->getTranslator();
isDisassembled = true;
}
// instruction pointer is read + written at each instruction
const CapstoneToFailTranslator::reginfo_t info_pc(m_ip_register_id);
if (do_ip &&
(!addRegisterTrace(curtime, instr, ev, info_pc, 'R') ||
!addRegisterTrace(curtime, instr, ev, info_pc, 'W'))) {
return false;
}
const CapstoneDisassembler::InstrMap &instr_map = disas->getInstrMap();
if (instr_map.find(ev.ip()) == instr_map.end()) {
LOG << "Could not find instruction for IP " << std::hex << ev.ip()
<< ", skipping" << std::endl;
return true;
}
const CapstoneDisassembler::Instr &opcode = instr_map.at(ev.ip());
//const MCRegisterInfo &reg_info = disas->getRegisterInfo();
// LOG << std::hex << "Address: " << opcode.address << " Opcode: " << opcode.opcode << std::endl;
// std::string log_regs = "Uses: ";
for (std::vector<CapstoneDisassembler::register_t>::const_iterator it = opcode.reg_uses.begin();
it != opcode.reg_uses.end(); ++it) {
// log_regs += std::to_string(*it) + " ";
const CapstoneToFailTranslator::reginfo_t &info = m_ctof->getFailRegisterInfo(*it);
if (&info == &m_ctof->notfound) {
// record failed translation, report later
m_regnotfound[*it].count++;
m_regnotfound[*it].address.insert(ev.ip());
continue;
}
/* only proceed if we want to inject into this register */
if (m_register_ids.find(info.id) == m_register_ids.end()) {
// log_regs += "n ";
continue;
}
if (!addRegisterTrace(curtime, instr, ev, info, 'R')) {
return false;
}
}
// log_regs += "Defs: ";
for (std::vector<CapstoneDisassembler::register_t>::const_iterator it = opcode.reg_defs.begin();
it != opcode.reg_defs.end(); ++it) {
// log_regs += std::to_string(*it) + " ";
const CapstoneToFailTranslator::reginfo_t &info = m_ctof->getFailRegisterInfo(*it);
if (&info == &m_ctof->notfound) {
// record failed translation, report later
m_regnotfound[*it].count++;
m_regnotfound[*it].address.insert(ev.ip());
continue;
}
/* only proceed if we want to inject into this register */
if (m_register_ids.find(info.id) == m_register_ids.end()) {
// log_regs += "n ";
continue;
}
if (!addRegisterTrace(curtime, instr, ev, info, 'W'))
return false;
}
// LOG << log_regs.c_str() << std::endl;
return true;
}
bool RegisterImporter::trace_end_reached()
{
// report failed LLVM -> FAIL* register mappings, if any
if (m_regnotfound.empty()) {
return true;
}
LOG << "WARNING: Some LLVM -> FAIL* register mappings failed during import, these will not be injected into:" << std::endl;
for (auto it = m_regnotfound.cbegin(); it != m_regnotfound.cend(); ++it) {
const CapstoneDisassembler::register_t id = it->first;
const RegNotFound& rnf = it->second;
LOG << "Capstone register " << std::dec << id
/* << " \"" << disas->getRegisterInfo().getName(id) << "\": " */
<< "seen " << rnf.count << " times in the trace" << std::endl;
std::ostream& o = LOG << " corresponding instruction addresses in ELF binary: " << std::hex;
for (auto addr_it = rnf.address.cbegin(); addr_it != rnf.address.cend(); ++addr_it) {
if (addr_it != rnf.address.cbegin()) {
o << ", ";
}
o << "0x" << *addr_it;
}
o << std::endl;
}
return true;
}
#elif defined(BUILD_LLVM_DISASSEMBLER)
bool RegisterImporter::addRegisterTrace(simtime_t curtime, instruction_count_t instr,
Trace_Event &ev,
const LLVMtoFailTranslator::reginfo_t &info,
@ -177,9 +387,12 @@ bool RegisterImporter::handle_ip_event(fail::simtime_t curtime, instruction_coun
}
const LLVMDisassembler::Instr &opcode = instr_map.at(ev.ip());
//const MCRegisterInfo &reg_info = disas->getRegisterInfo();
// LOG << std::hex << "Address: " << opcode.address << " Opcode: " << opcode.opcode << std::endl;
// std::string log_regs = "Uses: ";
for (std::vector<LLVMDisassembler::register_t>::const_iterator it = opcode.reg_uses.begin();
it != opcode.reg_uses.end(); ++it) {
// log_regs += std::to_string(*it) + " ";
const LLVMtoFailTranslator::reginfo_t &info = m_ltof->getFailRegisterInfo(*it);
if (&info == &m_ltof->notfound) {
// record failed translation, report later
@ -198,8 +411,10 @@ bool RegisterImporter::handle_ip_event(fail::simtime_t curtime, instruction_coun
}
}
// log_regs += "Defs: ";
for (std::vector<LLVMDisassembler::register_t>::const_iterator it = opcode.reg_defs.begin();
it != opcode.reg_defs.end(); ++it) {
// log_regs += std::to_string(*it) + " ";
const LLVMtoFailTranslator::reginfo_t &info = m_ltof->getFailRegisterInfo(*it);
if (&info == &m_ltof->notfound) {
// record failed translation, report later
@ -210,12 +425,14 @@ bool RegisterImporter::handle_ip_event(fail::simtime_t curtime, instruction_coun
/* only proceed if we want to inject into this register */
if (m_register_ids.find(info.id) == m_register_ids.end()) {
// log_regs += "n ";
continue;
}
if (!addRegisterTrace(curtime, instr, ev, info, 'W'))
return false;
}
// LOG << log_regs.c_str() << std::endl;
return true;
}
@ -246,3 +463,4 @@ bool RegisterImporter::trace_end_reached()
return true;
}
#endif

View File

@ -5,10 +5,38 @@
#include "util/CommandLine.hpp"
#include "Importer.hpp"
#if defined(BUILD_CAPSTONE_DISASSEMBLER)
#include "util/capstonedisassembler/CapstoneDisassembler.hpp"
#elif defined(BUILD_LLVM_DISASSEMBLER)
#include "util/llvmdisassembler/LLVMDisassembler.hpp"
#endif
class RegisterImporter : public Importer {
#if defined(BUILD_CAPSTONE_DISASSEMBLER)
bool isDisassembled = false;
std::unique_ptr<fail::CapstoneDisassembler> disas;
fail::CapstoneToFailTranslator *m_ctof = 0;
bool addRegisterTrace(fail::simtime_t curtime, instruction_count_t instr,
Trace_Event &ev,
const fail::CapstoneToFailTranslator::reginfo_t &info,
char access_type);
fail::CommandLine::option_handle NO_GP, FLAGS, IP, NO_SPLIT;
bool do_gp, do_flags, do_ip, do_split_registers;
std::set<unsigned> m_register_ids;
unsigned m_ip_register_id;
// Data structures for recording failed LLVM -> FAIL* register mappings,
// including occurrence counts in the trace (to give an estimate on the
// impact) and instruction addresses (for debugging purposes).
struct RegNotFound {
uint64_t count = 0;
std::set<fail::guest_address_t> address;
};
std::map<fail::CapstoneDisassembler::register_t, RegNotFound> m_regnotfound;
#elif defined(BUILD_LLVM_DISASSEMBLER)
llvm::object::Binary *binary = 0;
std::unique_ptr<fail::LLVMDisassembler> disas;
fail::LLVMtoFailTranslator *m_ltof = 0;
@ -32,6 +60,8 @@ class RegisterImporter : public Importer {
std::set<fail::guest_address_t> address;
};
std::map<fail::LLVMDisassembler::register_t, RegNotFound> m_regnotfound;
#endif
public:
RegisterImporter() : Importer(), do_gp(true), do_flags(false), do_ip(false),

View File

@ -10,12 +10,14 @@
#include "FullTraceImporter.hpp"
#include "util/AliasedRegistry.hpp"
#if defined(BUILD_LLVM_DISASSEMBLER) || defined(BUILD_CAPSTONE_DISASSEMBLER)
#ifdef BUILD_LLVM_DISASSEMBLER
#include "llvm/Support/ManagedStatic.h"
#include "InstructionImporter.hpp"
#include "RegisterImporter.hpp"
#endif
#include "RandomJumpImporter.hpp"
#include "AdvancedMemoryImporter.hpp"
#include "InstructionImporter.hpp"
#include "RegisterImporter.hpp"
#include "ElfImporter.hpp"
#endif
@ -67,18 +69,20 @@ int main(int argc, char *argv[]) {
FullTraceImporter fti;
registry.add(&fti);
#if defined(BUILD_LLVM_DISASSEMBLER) || defined(BUILD_CAPSTONE_DISASSEMBLER)
#ifdef BUILD_LLVM_DISASSEMBLER
llvm::llvm_shutdown_obj Y;
RegisterImporter reg;
registry.add(&reg);
RandomJumpImporter rjump;
registry.add(&rjump);
#endif
AdvancedMemoryImporter adv;
registry.add(&adv);
ElfImporter elf;
registry.add(&elf);
RandomJumpImporter rjump;
registry.add(&rjump);
InstructionImporter instr;
registry.add(&instr);
RegisterImporter reg;
registry.add(&reg);
ElfImporter elf;
registry.add(&elf);
#endif
std::string importers = registry.getPrimeAliasesCSV();