From 9843b520c1ed06f2233eefa10d4de8073fb33c24 Mon Sep 17 00:00:00 2001 From: Christian Dietrich Date: Wed, 3 Jul 2013 22:10:18 +0200 Subject: [PATCH 1/9] dbcampaign: select multiple variants/benchmark pairs The variant/benchmark selection now can use SQL LIKE syntax, all unfinished pilots from all selected variants are sent to the clients. E.g.: ./cored-voter-server -v x86-cored-voter -b simple-% -p basic Will select the fsppilots in the variants: - x86-cored-voter/simple-ip/basic - x86-cored-voter/simple-instr/basic The variant and benchmark information is now sent within the fsppilot. Change-Id: I287bfcddc478d0b79d89e156d6f5bf8188674532 --- src/core/comm/DatabaseCampaignMessage.proto | 2 + src/core/cpn/DatabaseCampaign.cc | 109 +++++++++++--------- src/core/cpn/DatabaseCampaign.hpp | 15 ++- src/core/util/Database.cc | 44 +++++--- src/core/util/Database.hpp | 14 +++ 5 files changed, 124 insertions(+), 60 deletions(-) diff --git a/src/core/comm/DatabaseCampaignMessage.proto b/src/core/comm/DatabaseCampaignMessage.proto index ae1e3d09..e66266cc 100644 --- a/src/core/comm/DatabaseCampaignMessage.proto +++ b/src/core/comm/DatabaseCampaignMessage.proto @@ -11,4 +11,6 @@ message DatabaseCampaignMessage { required int32 injection_instr = 4 [(sql_ignore) = true]; optional int32 injection_instr_absolute = 5 [(sql_ignore) = true]; required int32 data_address = 6 [(sql_ignore) = true]; + required string variant = 7 [(sql_ignore) = true]; + required string benchmark = 8 [(sql_ignore) = true]; } \ No newline at end of file diff --git a/src/core/cpn/DatabaseCampaign.cc b/src/core/cpn/DatabaseCampaign.cc index 2acf6326..cb8bf998 100644 --- a/src/core/cpn/DatabaseCampaign.cc +++ b/src/core/cpn/DatabaseCampaign.cc @@ -63,8 +63,7 @@ bool DatabaseCampaign::run() { pruner = "basic"; db = Database::cmdline_connect(); - variant_id = db->get_variant_id(variant, benchmark); - log_send << "Variant to use " << variant << "/" << benchmark << " (ID: " << variant_id << ")" << std::endl; + log_send << "Variant to use " << variant << "/" << benchmark << std::endl; fspmethod_id = db->get_fspmethod_id(pruner); log_send << "Pruner to use " << pruner << " (ID: " << fspmethod_id << ")" << std::endl; @@ -80,56 +79,17 @@ bool DatabaseCampaign::run() { boost::thread collect_thread(&DatabaseCampaign::collect_result_thread, this); #endif - /* Gather all unfinished jobs */ - int experiment_count; - std::string sql_select = "SELECT pilot_id, g.fspmethod_id, g.variant_id, p.injection_instr, p.injection_instr_absolute, g.data_address"; - std::stringstream ss; - ss << " FROM fspgroup g" - << " INNER JOIN fsppilot p ON p.id = g.pilot_id " - << " WHERE p.known_outcome = 0 " - << " AND g.fspmethod_id = " << fspmethod_id - << " AND g.variant_id = " << variant_id - << " AND (SELECT COUNT(*) FROM " + db_connect.result_table() + " as r WHERE r.pilot_id = g.pilot_id) < 8" - << " ORDER BY p.injection_instr"; - std::string sql_body = ss.str(); - - /* Get the number of unfinished experiments */ - MYSQL_RES *count = db->query(("SELECT COUNT(*) " + sql_body).c_str(), true); - MYSQL_ROW row = mysql_fetch_row(count); - experiment_count = atoi(row[0]); - - - MYSQL_RES *pilots = db->query_stream ((sql_select + sql_body).c_str()); - - log_send << "Found " << experiment_count << " unfinished experiments in database." << std::endl; - - sent_pilots = 0; - while ((row = mysql_fetch_row(pilots)) != 0) { - unsigned pilot_id = atoi(row[0]); - unsigned injection_instr = atoi(row[3]); - unsigned data_address = atoi(row[5]); - - DatabaseCampaignMessage pilot; - pilot.set_pilot_id(pilot_id); - pilot.set_fspmethod_id(fspmethod_id); - pilot.set_variant_id(variant_id); - pilot.set_injection_instr(injection_instr); - if (row[4]) { - unsigned injection_instr_absolute = atoi(row[4]); - pilot.set_injection_instr_absolute(injection_instr_absolute); - } - pilot.set_data_address(data_address); - - this->cb_send_pilot(pilot); - - if ((++sent_pilots) % 1000 == 0) { - log_send << "pushed " << sent_pilots << " pilots into the queue" << std::endl; + std::vector variants = db->get_variants(variant, benchmark); + for (std::vector::const_iterator it = variants.begin(); + it != variants.end(); ++it) { + if(!run_variant(*it)) { + log_send << "run_variant failed for " << it->variant << "/" << it->benchmark <query(("SELECT COUNT(*) " + sql_body).c_str(), true); + MYSQL_ROW row = mysql_fetch_row(count); + experiment_count = atoi(row[0]); + + + MYSQL_RES *pilots = db->query_stream ((sql_select + sql_body).c_str()); + + log_send << "Found " << experiment_count << " unfinished experiments in database. (" + << variant.variant << "/" << variant.benchmark << ")" << std::endl; + + sent_pilots = 0; + while ((row = mysql_fetch_row(pilots)) != 0) { + unsigned pilot_id = atoi(row[0]); + unsigned injection_instr = atoi(row[3]); + unsigned data_address = atoi(row[5]); + + + DatabaseCampaignMessage pilot; + pilot.set_pilot_id(pilot_id); + pilot.set_fspmethod_id(fspmethod_id); + pilot.set_variant_id(variant.id); + pilot.set_injection_instr(injection_instr); + pilot.set_variant(variant.variant); + pilot.set_benchmark(variant.benchmark); + if (row[4]) { + unsigned injection_instr_absolute = atoi(row[4]); + pilot.set_injection_instr_absolute(injection_instr_absolute); + } + pilot.set_data_address(data_address); + + this->cb_send_pilot(pilot); + + if ((++sent_pilots) % 1000 == 0) { + log_send << "pushed " << sent_pilots << " pilots into the queue" << std::endl; + } + } + return true; + +} diff --git a/src/core/cpn/DatabaseCampaign.hpp b/src/core/cpn/DatabaseCampaign.hpp index b4f40e2e..f81815d1 100644 --- a/src/core/cpn/DatabaseCampaign.hpp +++ b/src/core/cpn/DatabaseCampaign.hpp @@ -24,7 +24,6 @@ class DatabaseCampaign : public Campaign { Database *db; // !< The database connection object DatabaseProtobufAdapter db_connect; - int variant_id; // !< Which variant do we work on (from CMDLINE) int fspmethod_id; // !< Which fspmethod should be put out to the clients void collect_result_thread(); @@ -41,6 +40,20 @@ public: */ virtual bool run(); + /** + * Is called by run() for every variant, returned by the variant + * filter (SQL LIKE). + * @return \c true if the campaign was successful, \c false otherwise + */ + virtual bool run_variant(fail::Database::Variant); + + /** + * How many results have to are expected from each fsppilot. If + * there are less result rows, the pilot will be again sent to the clients + * @return \c exptected number of results + */ + virtual int expected_number_of_results(std::string variant, std::string benchmark) { return 8;} + /** * Callback function that can be used to add command line options * to the campaign diff --git a/src/core/util/Database.cc b/src/core/util/Database.cc index f567882d..bf18560d 100644 --- a/src/core/util/Database.cc +++ b/src/core/util/Database.cc @@ -74,36 +74,56 @@ my_ulonglong Database::affected_rows() } -int Database::get_variant_id(const std::string &variant, const std::string &benchmark) -{ +std::vector Database::get_variants(const std::string &variant, const std::string &benchmark) { + std::vector result; + if (!query("CREATE TABLE IF NOT EXISTS variant (" " id int(11) NOT NULL AUTO_INCREMENT," " variant varchar(255) NOT NULL," " benchmark varchar(255) NOT NULL," " PRIMARY KEY (id)," "UNIQUE KEY variant (variant,benchmark))")) { - return 0; + return result; } - int variant_id; std::stringstream ss; // FIXME SQL injection possible - ss << "SELECT id FROM variant WHERE variant LIKE '" << variant << "' AND benchmark LIKE '" << benchmark << "'"; + ss << "SELECT id, variant, benchmark FROM variant WHERE variant LIKE '" << variant << "' AND benchmark LIKE '" << benchmark << "'"; MYSQL_RES *variant_id_res = query(ss.str().c_str(), true); + if (!variant_id_res) { - return 0; + return result; } else if (mysql_num_rows(variant_id_res)) { - MYSQL_ROW row = mysql_fetch_row(variant_id_res); - variant_id = atoi(row[0]); - } else { - ss.str(""); + for (unsigned int i = 0; i < mysql_num_rows(variant_id_res); ++i) { + MYSQL_ROW row = mysql_fetch_row(variant_id_res); + Variant var; + var.id = atoi(row[0]); + var.variant = std::string(row[1]); + var.benchmark = std::string(row[2]); + result.push_back(var); + } + } + + return result; +} + +int Database::get_variant_id(const std::string &variant, const std::string &benchmark) +{ + std::vector variants = get_variants(variant, benchmark); + if (variants.size() == 0) { + // Insert a new variant + std::stringstream ss; ss << "INSERT INTO variant (variant, benchmark) VALUES ('" << variant << "', '" << benchmark << "')"; if (!query(ss.str().c_str())) { return 0; } - variant_id = mysql_insert_id(handle); + return mysql_insert_id(handle); + } else if (variants.size() == 1) { + return variants[0].id; + } else { + LOG << "Variant identifier " << variant << "/" << benchmark << " is ambigious!" << std::endl; + return 0; } - return variant_id; } int Database::get_fspmethod_id(const std::string &method) diff --git a/src/core/util/Database.hpp b/src/core/util/Database.hpp index 96a99f58..0a520022 100644 --- a/src/core/util/Database.hpp +++ b/src/core/util/Database.hpp @@ -5,6 +5,7 @@ #include #endif +#include #include #include #include @@ -31,6 +32,12 @@ namespace fail { Database(const std::string &username, const std::string &host, const std::string &database); ~Database() { mysql_close(handle); } + struct Variant { + int id; + std::string variant; + std::string benchmark; + }; + /** * Get the variant id for a specific variant/benchmark pair, * if it isn't defined in the database (variant table), it is @@ -38,6 +45,13 @@ namespace fail { */ int get_variant_id(const std::string &variant, const std::string &benchmark); + /** + * Get all variants that fit the given patterns (will be + * queried with SQL LIKE). + */ + std::vector get_variants(const std::string &variant, const std::string &benchmark); + + /** * Get the fault space pruning method id for a specific * pruning method, if it isn't defined in the database From bedb9c2eb2e7abd88fe1d756f8ebe6d1b83ff0f5 Mon Sep 17 00:00:00 2001 From: Christian Dietrich Date: Fri, 31 May 2013 15:35:07 +0200 Subject: [PATCH 2/9] import-trace: introduce InstructionImporter The InstructionImporter does disassemble the binary and generate read traces for every instruction byte executed. Change-Id: I6b8697c711c009e106ed733c74c6ff8f9bbf8ac5 --- src/core/util/ElfReader.cc | 2 + src/core/util/ElfReader.hpp | 3 +- tools/import-trace/CMakeLists.txt | 28 +++++++- tools/import-trace/Importer.hpp | 3 +- tools/import-trace/InstructionImporter.cc | 80 ++++++++++++++++++++++ tools/import-trace/InstructionImporter.hpp | 27 ++++++++ tools/import-trace/main.cc | 16 +++-- 7 files changed, 151 insertions(+), 8 deletions(-) create mode 100644 tools/import-trace/InstructionImporter.cc create mode 100644 tools/import-trace/InstructionImporter.hpp diff --git a/src/core/util/ElfReader.cc b/src/core/util/ElfReader.cc index cd5f391c..16ceabe8 100644 --- a/src/core/util/ElfReader.cc +++ b/src/core/util/ElfReader.cc @@ -48,6 +48,8 @@ void ElfReader::setup(const char* path) { return; } + m_filename = std::string(path); + // Evaluate headers Elf32_Ehdr ehdr; Elf32_Shdr sec_hdr; diff --git a/src/core/util/ElfReader.hpp b/src/core/util/ElfReader.hpp index 2d12ec10..8cf12093 100644 --- a/src/core/util/ElfReader.hpp +++ b/src/core/util/ElfReader.hpp @@ -75,7 +75,6 @@ namespace fail { */ class ElfReader { - public: typedef ElfSymbol entry_t; typedef std::vector container_t; @@ -153,9 +152,11 @@ namespace fail { container_t::const_iterator sec_begin() { return m_sectiontable.begin(); } container_t::const_iterator sec_end() { return m_sectiontable.end(); } + const std::string & getFilename() { return m_filename; } private: Logger m_log; + std::string m_filename; void setup(const char*); int process_symboltable(int sect_num, FILE* fp); diff --git a/tools/import-trace/CMakeLists.txt b/tools/import-trace/CMakeLists.txt index 5e5a3260..870a0321 100644 --- a/tools/import-trace/CMakeLists.txt +++ b/tools/import-trace/CMakeLists.txt @@ -3,6 +3,32 @@ set(SRCS MemoryImporter.cc ) +if (BUILD_LLVM_DISASSEMBLER) + set(SRCS ${SRCS} + InstructionImporter.cc + ) + + include(FindLLVM) + + # llvm-config does add -fno-exception to the command line. But this + # breaks some boost libraries. + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LLVM_CXX_FLAGS} -fexceptions") +endif(BUILD_LLVM_DISASSEMBLER) + + + add_executable(import-trace main.cc ${SRCS}) -target_link_libraries(import-trace ${PROTOBUF_LIBRARY} -lmysqlclient fail-util fail-sal fail-comm) + +target_link_libraries(import-trace + ${PROTOBUF_LIBRARY} + -lmysqlclient + fail-util + fail-comm + fail-sal) + +if (BUILD_LLVM_DISASSEMBLER) + target_link_libraries(import-trace fail-llvmdisassembler fail-sal ${LLVM_LIBS} ${LLVM_LDFLAGS}) +endif (BUILD_LLVM_DISASSEMBLER) + + install(TARGETS import-trace RUNTIME DESTINATION bin) diff --git a/tools/import-trace/Importer.hpp b/tools/import-trace/Importer.hpp index bbdc4203..96f6c336 100644 --- a/tools/import-trace/Importer.hpp +++ b/tools/import-trace/Importer.hpp @@ -78,7 +78,8 @@ public: const Trace_Event &ev) = 0; - void set_elf_file(fail::ElfReader *elf) { m_elf = elf; } + void set_elf(fail::ElfReader *elf) { m_elf = elf; } + void set_memorymap(fail::MemoryMap *mm) { m_mm = mm; } void set_faultspace_rightmargin(char accesstype) { m_faultspace_rightmargin = accesstype; } void set_sanitychecks(bool enabled) { m_sanitychecks = enabled; } diff --git a/tools/import-trace/InstructionImporter.cc b/tools/import-trace/InstructionImporter.cc new file mode 100644 index 00000000..c88034ca --- /dev/null +++ b/tools/import-trace/InstructionImporter.cc @@ -0,0 +1,80 @@ +#ifndef __puma +#include +#include +#include "InstructionImporter.hpp" +#include "util/Logger.hpp" + +using namespace llvm; +using namespace llvm::object; +using namespace fail; + + +static Logger LOG("InstructionImporter"); + +bool InstructionImporter::handle_ip_event(fail::simtime_t curtime, instruction_count_t instr, + const Trace_Event &ev) { + if (!binary) { + /* Disassemble the binary if necessary */ + llvm::InitializeAllTargetInfos(); + llvm::InitializeAllTargetMCs(); + llvm::InitializeAllDisassemblers(); + + if (error_code ec = createBinary(m_elf->getFilename(), binary)) { + LOG << m_elf->getFilename() << "': " << ec.message() << ".\n"; + return false; + } + + ObjectFile *obj = dyn_cast(binary.get()); + + disas.reset(new LLVMDisassembler(obj)); + disas->disassemble(); + LLVMDisassembler::InstrMap &instr_map = disas->getInstrMap(); + LOG << "instructions disassembled: " << instr_map.size() << " Triple: " << disas->GetTriple() << std::endl; + } + + const LLVMDisassembler::InstrMap &instr_map = disas->getInstrMap(); + const LLVMDisassembler::Instr &opcode = instr_map.at(ev.ip()); + + address_t from = ev.ip(), to = ev.ip() + opcode.length; + + // 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(data_address)) { + 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 + access_info_t access; + access.access_type = 'R'; // instruction fetch is always a read + access.data_address = data_address; + access.data_width = 1; // exactly one byte + if (!add_trace_event(left_margin, right_margin, access)) { + 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; +} + + +#endif // !__puma diff --git a/tools/import-trace/InstructionImporter.hpp b/tools/import-trace/InstructionImporter.hpp new file mode 100644 index 00000000..a60f5f57 --- /dev/null +++ b/tools/import-trace/InstructionImporter.hpp @@ -0,0 +1,27 @@ +#ifndef __INSTRUCTION_IMPORTER_H__ +#define __INSTRUCTION_IMPORTER_H__ + +#include "Importer.hpp" + +#ifndef __puma +#include "util/llvmdisassembler/LLVMDisassembler.hpp" +#endif + + +class InstructionImporter : public Importer { +#ifndef __puma + llvm::OwningPtr binary; + llvm::OwningPtr disas; +#endif + +public: + virtual bool handle_ip_event(fail::simtime_t curtime, instruction_count_t instr, + const Trace_Event &ev); + virtual bool handle_mem_event(fail::simtime_t curtime, instruction_count_t instr, + const Trace_Event &ev) { + /* ignore on purpose */ + return true; + } +}; + +#endif diff --git a/tools/import-trace/main.cc b/tools/import-trace/main.cc index 0c1af3e7..e76c9b7f 100644 --- a/tools/import-trace/main.cc +++ b/tools/import-trace/main.cc @@ -1,5 +1,3 @@ -#include "util/optionparser/optionparser.h" -#include "util/optionparser/optionparser_ext.hpp" #include "util/CommandLine.hpp" #include "util/Database.hpp" #include "util/ElfReader.hpp" @@ -8,9 +6,12 @@ #include "util/Logger.hpp" #include #include - #include "MemoryImporter.hpp" +#ifdef BUILD_LLVM_DISASSEMBLER +#include "InstructionImporter.hpp" +#endif + using namespace fail; using std::cerr; @@ -118,9 +119,14 @@ int main(int argc, char *argv[]) { if (cmd[IMPORTER].count() > 0) { std::string imp(cmd[IMPORTER].first()->arg); - if (imp == "BasicImporter" || imp == "MemoryImporter") { + if (imp == "BasicImporter" || imp == "MemoryImporter" || imp == "memory" || imp == "mem") { LOG << "Using MemoryImporter" << endl; importer = new MemoryImporter(); +#ifdef BUILD_LLVM_DISASSEMBLER + } else if (imp == "InstructionImporter" || imp == "code") { + LOG << "Using InstructionImporter" << endl; + importer = new InstructionImporter(); +#endif } else { LOG << "Unkown import method: " << imp << endl; exit(-1); @@ -160,7 +166,7 @@ int main(int argc, char *argv[]) { if (cmd[ELF_FILE].count() > 0) { elf_file = new ElfReader(cmd[ELF_FILE].first()->arg); } - importer->set_elf_file(elf_file); + importer->set_elf(elf_file); if (cmd[MEMORYMAP].count() > 0) { memorymap = new MemoryMap(); From f47d50b1821779ca4f0b8a64871d6c8e8997772a Mon Sep 17 00:00:00 2001 From: Christian Dietrich Date: Thu, 4 Jul 2013 13:38:32 +0200 Subject: [PATCH 3/9] import-trace: introduce RegisterImporter The RegisterImporter disassembles the binary and adds a trace event for each byte read or written from register. The register number (Fail Register Numbers are used) and the offset within the register are encoded within the trace event. Change-Id: I2d2fd720841fedeeff5f28b64f24ec5f6d2ea0c3 --- tools/import-trace/CMakeLists.txt | 2 +- tools/import-trace/Importer.hpp | 6 + tools/import-trace/RegisterImporter.cc | 171 ++++++++++++++++++++++++ tools/import-trace/RegisterImporter.hpp | 49 +++++++ tools/import-trace/main.cc | 4 + 5 files changed, 231 insertions(+), 1 deletion(-) create mode 100644 tools/import-trace/RegisterImporter.cc create mode 100644 tools/import-trace/RegisterImporter.hpp diff --git a/tools/import-trace/CMakeLists.txt b/tools/import-trace/CMakeLists.txt index 870a0321..43db2759 100644 --- a/tools/import-trace/CMakeLists.txt +++ b/tools/import-trace/CMakeLists.txt @@ -6,6 +6,7 @@ set(SRCS if (BUILD_LLVM_DISASSEMBLER) set(SRCS ${SRCS} InstructionImporter.cc + RegisterImporter.cc ) include(FindLLVM) @@ -30,5 +31,4 @@ if (BUILD_LLVM_DISASSEMBLER) target_link_libraries(import-trace fail-llvmdisassembler fail-sal ${LLVM_LIBS} ${LLVM_LDFLAGS}) endif (BUILD_LLVM_DISASSEMBLER) - install(TARGETS import-trace RUNTIME DESTINATION bin) diff --git a/tools/import-trace/Importer.hpp b/tools/import-trace/Importer.hpp index 96f6c336..e7492860 100644 --- a/tools/import-trace/Importer.hpp +++ b/tools/import-trace/Importer.hpp @@ -64,6 +64,12 @@ public: Importer() : m_sanitychecks(false), m_row_count(0), m_time_trace_start(0) {} bool init(const std::string &variant, const std::string &benchmark, fail::Database *db); + /** + * Callback function that can be used to add command line options + * to the cmd interface + */ + virtual bool cb_commandline_init() { return true; } + virtual bool create_database(); virtual bool copy_to_database(fail::ProtoIStream &ps); virtual bool clear_database(); diff --git a/tools/import-trace/RegisterImporter.cc b/tools/import-trace/RegisterImporter.cc new file mode 100644 index 00000000..ae46200d --- /dev/null +++ b/tools/import-trace/RegisterImporter.cc @@ -0,0 +1,171 @@ +#ifndef __puma +#include +#include +#include "RegisterImporter.hpp" +#include "util/Logger.hpp" + +using namespace llvm; +using namespace llvm::object; +using namespace fail; + + +static Logger LOG("RegisterImporter"); + +/** + * Callback function that can be used to add command line options + * to the campaign + */ +bool RegisterImporter::cb_commandline_init() { + CommandLine &cmd = CommandLine::Inst(); + + NO_GP = cmd.addOption("", "no-gp", Arg::None, + "--no-gp\t RegisterImporter: do not inject general purpose registers\n"); + FLAGS = cmd.addOption("", "flags", Arg::None, + "--flags: RegisterImporter: trace flags register\n"); + IP = cmd.addOption("", "ip", Arg::None, + "--ip: RegisterImporter: trace instruction pointer\n"); + + return true; +} + + +bool RegisterImporter::addRegisterTrace(simtime_t curtime, instruction_count_t instr, + const Trace_Event &ev, + const LLVMtoFailTranslator::reginfo_t &info, + char access_type) { + LLVMtoFailTranslator::reginfo_t one_byte_window = info; + one_byte_window.width = 8; + address_t from = one_byte_window.toDataAddress(), to = one_byte_window.toDataAddress() + (info.width) / 8; + + // 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 + access_info_t access; + access.access_type = access_type; // instruction fetch is always a read + access.data_address = data_address; + access.data_width = 1; // exactly one byte + if (!add_trace_event(left_margin, right_margin, access)) { + 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, + const Trace_Event &ev) { + if (!binary) { + // 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; + } + + // Read FROM memory file + if (cmd[NO_GP].count() > 0) { + do_gp = false; + } + if (cmd[FLAGS].count() > 0) { + do_flags = true; + } + if (cmd[IP].count() > 0) { + do_ip = true; + } + + /* Disassemble the binary if necessary */ + llvm::InitializeAllTargetInfos(); + llvm::InitializeAllTargetMCs(); + llvm::InitializeAllDisassemblers(); + + if (error_code ec = createBinary(m_elf->getFilename(), binary)) { + LOG << m_elf->getFilename() << "': " << ec.message() << ".\n"; + return false; + } + + ObjectFile *obj = dyn_cast(binary.get()); + + disas.reset(new LLVMDisassembler(obj)); + disas->disassemble(); + LLVMDisassembler::InstrMap &instr_map = disas->getInstrMap(); + LOG << "instructions disassembled: " << instr_map.size() << " Triple: " << disas->GetTriple() << std::endl; + } + + const LLVMDisassembler::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() << std::endl; + return false; + } + 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 not tracing flags, but flags register -> ignore it + if not tracing gp, but ! flags -> ignore it*/ + if (info.id == RID_FLAGS && !do_flags) + continue; + else if (!do_gp) + continue; + + if (!addRegisterTrace(curtime, instr, ev, info, 'R')) { + return false; + } + } + + 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 not tracing flags, but flags register -> ignore it + if not tracing gp, but ! flags -> ignore it*/ + if (info.id == RID_FLAGS && !do_flags) + continue; + else if (!do_gp) + continue; + + if (!addRegisterTrace(curtime, instr, ev, info, 'W')) + return false; + } + + const LLVMtoFailTranslator::reginfo_t info_pc(RID_PC); + if (do_ip) { + if (!addRegisterTrace(curtime, instr, ev, info_pc, 'R')) + return false; + if (!addRegisterTrace(curtime, instr, ev, info_pc, 'W')) + return false; + } + + return true; +} + + +#endif // !__puma diff --git a/tools/import-trace/RegisterImporter.hpp b/tools/import-trace/RegisterImporter.hpp new file mode 100644 index 00000000..94c51ead --- /dev/null +++ b/tools/import-trace/RegisterImporter.hpp @@ -0,0 +1,49 @@ +#ifndef __REGISTER_IMPORTER_H__ +#define __REGISTER_IMPORTER_H__ + + +#include "util/CommandLine.hpp" +#include "Importer.hpp" + +#ifndef __puma +#include "util/llvmdisassembler/LLVMDisassembler.hpp" +#endif + + +class RegisterImporter : public Importer { +#ifndef __puma + llvm::OwningPtr binary; + llvm::OwningPtr disas; + + bool addRegisterTrace(fail::simtime_t curtime, instruction_count_t instr, + const Trace_Event &ev, + const fail::LLVMtoFailTranslator::reginfo_t &info, + char access_type); +#endif + + + fail::CommandLine::option_handle NO_GP, FLAGS, IP; + bool do_gp, do_flags, do_ip; + +public: + RegisterImporter() : Importer(), do_gp(true), do_flags(false), do_ip(false) {} + /** + * Callback function that can be used to add command line options + * to the cmd interface + */ + virtual bool cb_commandline_init(); + + virtual bool handle_ip_event(fail::simtime_t curtime, instruction_count_t instr, + const Trace_Event &ev); + virtual bool handle_mem_event(fail::simtime_t curtime, instruction_count_t instr, + const Trace_Event &ev) { + /* ignore on purpose */ + return true; + } + + virtual void open_unused_ec_intervals() { + /* empty, Memory Map has a different meaning in this importer */ + } +}; + +#endif diff --git a/tools/import-trace/main.cc b/tools/import-trace/main.cc index e76c9b7f..0f034326 100644 --- a/tools/import-trace/main.cc +++ b/tools/import-trace/main.cc @@ -10,6 +10,7 @@ #ifdef BUILD_LLVM_DISASSEMBLER #include "InstructionImporter.hpp" +#include "RegisterImporter.hpp" #endif @@ -126,6 +127,9 @@ int main(int argc, char *argv[]) { } else if (imp == "InstructionImporter" || imp == "code") { LOG << "Using InstructionImporter" << endl; importer = new InstructionImporter(); + } else if (imp == "RegisterImporter" || imp == "regs") { + LOG << "Using RegisterImporter" << endl; + importer = new RegisterImporter(); #endif } else { LOG << "Unkown import method: " << imp << endl; From 6c9bb21ab391daeaf2731c4ecc7bb332c0850c27 Mon Sep 17 00:00:00 2001 From: Christian Dietrich Date: Thu, 4 Jul 2013 13:39:02 +0200 Subject: [PATCH 4/9] import-trace: introduce RandomJumpImporter The random jump importer defines trace events, that indicate all possible jumps into a specific instruction range. The region where jumps should start can be defined by a memory map given with --jump-from. For each instruction declared in that memory range, all possible jumps to a memory region specified by with --jump-to are inserted. The target of the jump is saved in the data_address field. So all database tools work as expected. for each event E \in region(--jump-from): foreach Instruction in region(--jump-to): insert_trace(injection_instr = E.IP(), data_address = Instruction.addr) Change-Id: Ie163968acae47fc6c946fc77774c47ee07950bab --- tools/import-trace/CMakeLists.txt | 1 + tools/import-trace/RandomJumpImporter.cc | 132 ++++++++++++++++++++++ tools/import-trace/RandomJumpImporter.hpp | 43 +++++++ tools/import-trace/main.cc | 15 +++ 4 files changed, 191 insertions(+) create mode 100644 tools/import-trace/RandomJumpImporter.cc create mode 100644 tools/import-trace/RandomJumpImporter.hpp diff --git a/tools/import-trace/CMakeLists.txt b/tools/import-trace/CMakeLists.txt index 43db2759..80fce373 100644 --- a/tools/import-trace/CMakeLists.txt +++ b/tools/import-trace/CMakeLists.txt @@ -7,6 +7,7 @@ if (BUILD_LLVM_DISASSEMBLER) set(SRCS ${SRCS} InstructionImporter.cc RegisterImporter.cc + RandomJumpImporter.cc ) include(FindLLVM) diff --git a/tools/import-trace/RandomJumpImporter.cc b/tools/import-trace/RandomJumpImporter.cc new file mode 100644 index 00000000..a7c05262 --- /dev/null +++ b/tools/import-trace/RandomJumpImporter.cc @@ -0,0 +1,132 @@ +#ifndef __puma +#include +#include +#include "util/Logger.hpp" +#include "RandomJumpImporter.hpp" + +using namespace llvm; +using namespace llvm::object; +using namespace fail; +using namespace std; + +static Logger LOG("RandomJumpImporter"); + +/** + * Callback function that can be used to add command line options + * to the campaign + */ +bool RandomJumpImporter::cb_commandline_init() { + CommandLine &cmd = CommandLine::Inst(); + + FROM = cmd.addOption("", "jump-from", Arg::Required, + "--jump-from\t RandomJump: Which addresses should be jumped from\n"); + TO = cmd.addOption("", "jump-to", Arg::Required, + "--jump-to\t RandomJump: Where to jump (a memory map>\n"); + return true; +} + +bool RandomJumpImporter::handle_ip_event(fail::simtime_t curtime, instruction_count_t instr, + const Trace_Event &ev) { + if (!binary) { + // 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; + } + + // Read FROM memory file + if (cmd[FROM].count() > 0) { + m_mm_from = new MemoryMap(); + for (option::Option *o = cmd[FROM]; o; o = o->next()) { + if (!m_mm_from->readFromFile(o->arg)) { + LOG << "failed to load memorymap " << o->arg << endl; + return false; + } + } + } + + if (cmd[TO].count() > 0) { + m_mm_to = new MemoryMap(); + for (option::Option *o = cmd[TO]; o; o = o->next()) { + if (!m_mm_to->readFromFile(o->arg)) { + LOG << "failed to load memorymap " << o->arg << endl; + return false; + } + } + } else { + LOG << "Please give at least one --jump-to memory map" << endl; + return false; + } + + /* Disassemble the binary if necessary */ + llvm::InitializeAllTargetInfos(); + llvm::InitializeAllTargetMCs(); + llvm::InitializeAllDisassemblers(); + + if (error_code ec = createBinary(m_elf->getFilename(), binary)) { + LOG << m_elf->getFilename() << "': " << ec.message() << ".\n"; + return false; + } + + ObjectFile *obj = dyn_cast(binary.get()); + + disas.reset(new LLVMDisassembler(obj)); + disas->disassemble(); + LLVMDisassembler::InstrMap &instr_map = disas->getInstrMap(); + LOG << "instructions disassembled: " << instr_map.size() << " Triple: " << disas->GetTriple() << std::endl; + + /* Collect all addresses we want to jump to */ + for (LLVMDisassembler::InstrMap::const_iterator instr = instr_map.begin(); + instr != instr_map.end(); ++instr) { + if (m_mm_to->isMatching(instr->first)) { + m_jump_to_addresses.push_back(instr->first); + } + } + LOG << "we will jump to " << m_jump_to_addresses.size() << " addresses" << endl; + } + + + // skip events that are outside the memory map. -m instruction map + if (m_mm && !m_mm->isMatching(ev.ip())) { + return true; + } + + // skip events that are outside the --jump-from memory map. + if (!m_mm_from->isMatching(ev.ip())) { + return true; + } + + + for (std::vector::const_iterator it = m_jump_to_addresses.begin(); + it != m_jump_to_addresses.end(); ++it) { + guest_address_t to_addr = *it; + /* Do not add a jump to the same instruction */ + if (to_addr == ev.ip()) + continue; + + margin_info_t margin; + margin.time = curtime; + margin.dyninstr = instr; // !< The current instruction + margin.ip = ev.ip(); + + // 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 + access_info_t access; + access.access_type = 'R'; // instruction fetch is always a read + access.data_address = to_addr; + access.data_width = 4; // exactly one byte + if (!add_trace_event(margin, margin, access)) { + LOG << "add_trace_event failed" << std::endl; + return false; + } + } + + return true; +} + + +#endif // !__puma diff --git a/tools/import-trace/RandomJumpImporter.hpp b/tools/import-trace/RandomJumpImporter.hpp new file mode 100644 index 00000000..088f58ca --- /dev/null +++ b/tools/import-trace/RandomJumpImporter.hpp @@ -0,0 +1,43 @@ +#ifndef __RANDOM_JUMP_IMPORTER_H__ +#define __RANDOM_JUMP_IMPORTER_H__ + +#include +#include "util/CommandLine.hpp" +#include "Importer.hpp" + +#ifndef __puma +#include "util/llvmdisassembler/LLVMDisassembler.hpp" +#endif + + +class RandomJumpImporter : public Importer { +#ifndef __puma + llvm::OwningPtr binary; + llvm::OwningPtr disas; +#endif + + fail::CommandLine::option_handle FROM, TO; + + fail::MemoryMap *m_mm_from, *m_mm_to; + std::vector m_jump_to_addresses; +public: + /** + * Callback function that can be used to add command line options + * to the campaign + */ + virtual bool cb_commandline_init(); + + virtual bool handle_ip_event(fail::simtime_t curtime, instruction_count_t instr, + const Trace_Event &ev); + virtual bool handle_mem_event(fail::simtime_t curtime, instruction_count_t instr, + const Trace_Event &ev) { + /* ignore on purpose */ + return true; + } + + virtual void open_unused_ec_intervals() { + /* empty, Memory Map has a different meaning in this importer */ + } +}; + +#endif diff --git a/tools/import-trace/main.cc b/tools/import-trace/main.cc index 0f034326..877e85d2 100644 --- a/tools/import-trace/main.cc +++ b/tools/import-trace/main.cc @@ -11,6 +11,7 @@ #ifdef BUILD_LLVM_DISASSEMBLER #include "InstructionImporter.hpp" #include "RegisterImporter.hpp" +#include "RandomJumpImporter.hpp" #endif @@ -127,9 +128,14 @@ int main(int argc, char *argv[]) { } else if (imp == "InstructionImporter" || imp == "code") { LOG << "Using InstructionImporter" << endl; importer = new InstructionImporter(); + } else if (imp == "RegisterImporter" || imp == "regs") { LOG << "Using RegisterImporter" << endl; importer = new RegisterImporter(); + + } else if (imp == "RandomJumpImporter") { + LOG << "Using RandomJumpImporter" << endl; + importer = new RandomJumpImporter(); #endif } else { LOG << "Unkown import method: " << imp << endl; @@ -141,7 +147,16 @@ int main(int argc, char *argv[]) { importer = new MemoryImporter(); } + if (importer && !(importer->cb_commandline_init())) { + std::cerr << "Cannot call importers command line initialization!" << std::endl; + exit(-1); + } + if (cmd[HELP]) { + // Since the importer might have added command line options, + // we need to reparse all arguments in order to prevent a + // segfault within optionparser + cmd.parse(); cmd.printUsage(); exit(0); } From 8622c1de12d78141d92616826c69f847507171f3 Mon Sep 17 00:00:00 2001 From: Horst Schirmeier Date: Thu, 11 Jul 2013 09:57:01 +0200 Subject: [PATCH 5/9] db: explicitly use MyISAM engine InnoDB is the default on some setups. Change-Id: I5cc59854cb88cbec0e7bb7f6aab946252d0bd8e5 --- src/core/util/Database.cc | 4 ++-- src/experiments/ecos_kernel_test/campaign.cc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/util/Database.cc b/src/core/util/Database.cc index bf18560d..3ca32ed6 100644 --- a/src/core/util/Database.cc +++ b/src/core/util/Database.cc @@ -82,7 +82,7 @@ std::vector Database::get_variants(const std::string &variant " variant varchar(255) NOT NULL," " benchmark varchar(255) NOT NULL," " PRIMARY KEY (id)," - "UNIQUE KEY variant (variant,benchmark))")) { + "UNIQUE KEY variant (variant,benchmark)) ENGINE=MyISAM")) { return result; } @@ -131,7 +131,7 @@ int Database::get_fspmethod_id(const std::string &method) if (!query("CREATE TABLE IF NOT EXISTS fspmethod (" " id int(11) NOT NULL AUTO_INCREMENT," " method varchar(255) NOT NULL," - " PRIMARY KEY (id), UNIQUE KEY method (method))")) { + " PRIMARY KEY (id), UNIQUE KEY method (method)) ENGINE=MyISAM")) { return 0; } diff --git a/src/experiments/ecos_kernel_test/campaign.cc b/src/experiments/ecos_kernel_test/campaign.cc index 79a96c61..ac665de9 100644 --- a/src/experiments/ecos_kernel_test/campaign.cc +++ b/src/experiments/ecos_kernel_test/campaign.cc @@ -265,7 +265,7 @@ bool EcosKernelTestCampaign::run() << " AND p.fspmethod_id = " << fspmethod_id << " " << " AND (" << sql_variants << ") "; #elif 1 - if (!db->query("CREATE TEMPORARY TABLE done_pilots (id INT UNSIGNED NOT NULL PRIMARY KEY)")) return false; + if (!db->query("CREATE TEMPORARY TABLE done_pilots (id INT UNSIGNED NOT NULL PRIMARY KEY) ENGINE=MyISAM")) return false; ss << "INSERT INTO done_pilots SELECT pilot_id FROM " << m_result_table << " GROUP BY pilot_id HAVING SUM(bit_width) = 8"; if (!db->query(ss.str().c_str())) return false; unsigned finished_jobs = db->affected_rows(); From 760353fb974fa8f7cb386227b05acca0bfdcd4f1 Mon Sep 17 00:00:00 2001 From: Horst Schirmeier Date: Mon, 8 Jul 2013 18:45:26 +0200 Subject: [PATCH 6/9] util: LLVM disassembler bugfix Start/End is both inclusive; otherwise we may miss a trailing single-byte instruction. Change-Id: Ifb25593886864f7f92b08f13875a12e0a5a0d345 --- src/core/util/llvmdisassembler/LLVMDisassembler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/util/llvmdisassembler/LLVMDisassembler.cpp b/src/core/util/llvmdisassembler/LLVMDisassembler.cpp index 356a2612..f1154e44 100644 --- a/src/core/util/llvmdisassembler/LLVMDisassembler.cpp +++ b/src/core/util/llvmdisassembler/LLVMDisassembler.cpp @@ -95,7 +95,7 @@ void LLVMDisassembler::disassemble() // This symbol has the same address as the next symbol. Skip it. continue; - for (Index = Start; Index < End; Index += Size) { + for (Index = Start; Index <= End; Index += Size) { MCInst Inst; if (disas->getInstruction(Inst, Size, memoryObject, Index, From 52322ac7b97f49a3b5726d54d3762d9f6857b07c Mon Sep 17 00:00:00 2001 From: Horst Schirmeier Date: Mon, 8 Jul 2013 18:49:47 +0200 Subject: [PATCH 7/9] import-trace: compile with LLVM 3.3 This was necessary because LLVM 3.1's ELFObjectFile::sectionContainsSymbolsectionContainsSymbol() (needed for proper functioning of our LLVM disassembler, unless you're using -ffunction-sections) is "unimplemented". Change-Id: I81112627ebd1c92b718ac6f4ed58d7f188aedf0c --- tools/import-trace/InstructionImporter.cc | 2 +- tools/import-trace/RandomJumpImporter.cc | 2 +- tools/import-trace/RegisterImporter.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/import-trace/InstructionImporter.cc b/tools/import-trace/InstructionImporter.cc index c88034ca..f62abbca 100644 --- a/tools/import-trace/InstructionImporter.cc +++ b/tools/import-trace/InstructionImporter.cc @@ -24,7 +24,7 @@ bool InstructionImporter::handle_ip_event(fail::simtime_t curtime, instruction_c return false; } - ObjectFile *obj = dyn_cast(binary.get()); + ObjectFile *obj = dyn_cast(binary.get()); disas.reset(new LLVMDisassembler(obj)); disas->disassemble(); diff --git a/tools/import-trace/RandomJumpImporter.cc b/tools/import-trace/RandomJumpImporter.cc index a7c05262..38fa961f 100644 --- a/tools/import-trace/RandomJumpImporter.cc +++ b/tools/import-trace/RandomJumpImporter.cc @@ -70,7 +70,7 @@ bool RandomJumpImporter::handle_ip_event(fail::simtime_t curtime, instruction_co return false; } - ObjectFile *obj = dyn_cast(binary.get()); + ObjectFile *obj = dyn_cast(binary.get()); disas.reset(new LLVMDisassembler(obj)); disas->disassemble(); diff --git a/tools/import-trace/RegisterImporter.cc b/tools/import-trace/RegisterImporter.cc index ae46200d..36cbf509 100644 --- a/tools/import-trace/RegisterImporter.cc +++ b/tools/import-trace/RegisterImporter.cc @@ -108,7 +108,7 @@ bool RegisterImporter::handle_ip_event(fail::simtime_t curtime, instruction_coun return false; } - ObjectFile *obj = dyn_cast(binary.get()); + ObjectFile *obj = dyn_cast(binary.get()); disas.reset(new LLVMDisassembler(obj)); disas->disassemble(); From bc7ad2414270d1cb631db40dfec9f6491fb9d784 Mon Sep 17 00:00:00 2001 From: Horst Schirmeier Date: Mon, 8 Jul 2013 09:39:37 +0200 Subject: [PATCH 8/9] dump-trace: extended trace information dump configurable This adds the same --extended-trace commandline switch as import-trace has. Change-Id: I9c13df7b1df0f48ceeb7d1ebfa1a3ad45684c6a8 --- tools/dump-trace/DumpTrace.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tools/dump-trace/DumpTrace.cc b/tools/dump-trace/DumpTrace.cc index 48c3826c..b99952af 100644 --- a/tools/dump-trace/DumpTrace.cc +++ b/tools/dump-trace/DumpTrace.cc @@ -55,6 +55,9 @@ int main(int argc, char *argv[]) CommandLine::option_handle STATS = cmd.addOption("s", "stats", Arg::None, "-s/--stats \tShow trace stats"); + CommandLine::option_handle EXTENDED_TRACE = + cmd.addOption("", "extended-trace", Arg::None, + "--extended-trace \tDump extended trace information if available"); for (int i = 1; i < argc; ++i) { cmd.add_args(argv[i]); @@ -73,10 +76,8 @@ int main(int argc, char *argv[]) } } - bool stats_only = false; - if (cmd[STATS]) { - stats_only = true; - } + bool stats_only = cmd[STATS]; + bool extended = cmd[EXTENDED_TRACE]; std::ifstream normal_stream; igzstream gz_stream; @@ -99,7 +100,7 @@ int main(int argc, char *argv[]) } } else { stringstream ext; - if (ev.has_trace_ext() && !stats_only) { + if (ev.has_trace_ext() && !stats_only && extended) { const Trace_Event_Extended& temp_ext = ev.trace_ext(); ext << " DATA " << std::hex; ext << (uint64_t) temp_ext.data(); From 32e041543c402d7b5d4423b7ee997a9da3175e39 Mon Sep 17 00:00:00 2001 From: Horst Schirmeier Date: Tue, 9 Jul 2013 18:53:35 +0200 Subject: [PATCH 9/9] import-trace: remove --importer-args parameter The parameter has no effect and has been superseded by Importer::cb_commandline_init(). Change-Id: I8c2f26c878a1ff409a6b5e3ee35d93dea775b583 --- tools/import-trace/main.cc | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/tools/import-trace/main.cc b/tools/import-trace/main.cc index 877e85d2..a3946915 100644 --- a/tools/import-trace/main.cc +++ b/tools/import-trace/main.cc @@ -50,7 +50,7 @@ ProtoIStream openProtoStream(std::string input_file) { int main(int argc, char *argv[]) { std::string trace_file, username, hostname, database, benchmark; - std::string variant, importer_args; + std::string variant; ElfReader *elf_file = 0; MemoryMap *memorymap = 0; @@ -78,9 +78,6 @@ int main(int argc, char *argv[]) { CommandLine::option_handle IMPORTER = cmd.addOption("i", "importer", Arg::Required, "-i/--importer \tWhich import method to use (default: MemoryImporter)"); - CommandLine::option_handle IMPORTER_ARGS = - cmd.addOption("I", "importer-args", Arg::Required, - "-I/--importer-args \tWhich import method to use (default: "")"); CommandLine::option_handle ELF_FILE = cmd.addOption("e", "elf-file", Arg::Required, "-e/--elf-file \tELF File (default: UNSET)"); @@ -179,9 +176,6 @@ int main(int argc, char *argv[]) { else benchmark = "none"; - if (cmd[IMPORTER_ARGS].count() > 0) - importer_args = std::string(cmd[IMPORTER_ARGS].first()->arg); - if (cmd[ELF_FILE].count() > 0) { elf_file = new ElfReader(cmd[ELF_FILE].first()->arg); }