#ifndef __IMPORTER_H__ #define __IMPORTER_H__ #include #include #include "util/ProtoStream.hpp" #include "util/ElfReader.hpp" #include "sal/SALConfig.hpp" #include "util/Database.hpp" #include "util/MemoryMap.hpp" #include "comm/TracePlugin.pb.h" class Importer { public: typedef unsigned instruction_count_t; //!< not big enough for some benchmarks struct margin_info_t { instruction_count_t dyninstr; fail::guest_address_t ip; fail::simtime_t time; }; struct access_info_t { char access_type; fail::guest_address_t data_address; int data_width; }; protected: int m_variant_id; fail::ElfReader *m_elf; fail::MemoryMap *m_mm; char m_faultspace_rightmargin; bool m_sanitychecks; fail::Database *db; /* How many rows were inserted into the database */ unsigned m_row_count; // time the trace started/ended fail::simtime_t m_time_trace_start; /* map for keeping one "open" EC for every address (maps injection data address => dyn. instruction count / time information for equivalence class left margin) */ typedef std::map AddrLastaccessMap; AddrLastaccessMap m_open_ecs; margin_info_t getOpenEC(fail::address_t data_address) { margin_info_t ec = m_open_ecs[data_address]; // defaulting to 0 is not such a good idea, memory reads at the // beginning of the trace would get an unnaturally high weight: if (ec.time == 0) { ec.time = m_time_trace_start; } return ec; } void newOpenEC(fail::address_t data_address, fail::simtime_t time, instruction_count_t dyninstr, fail::guest_address_t ip) { m_open_ecs[data_address].dyninstr = dyninstr; m_open_ecs[data_address].time = time; // FIXME: This should be the next IP, not the current, or? m_open_ecs[data_address].ip = ip; } fail::guest_address_t m_last_ip; instruction_count_t m_last_instr; fail::simtime_t m_last_time; 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(); virtual bool add_trace_event(margin_info_t &begin, margin_info_t &end, access_info_t &event, bool is_fake = false); virtual void open_unused_ec_intervals(); virtual bool close_ec_intervals(); virtual bool handle_ip_event(fail::simtime_t curtime, instruction_count_t instr, const Trace_Event &ev) = 0; virtual bool handle_mem_event(fail::simtime_t curtime, instruction_count_t instr, const Trace_Event &ev) = 0; 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; } }; #endif