diff --git a/src/core/util/AliasedRegisterable.hpp b/src/core/util/AliasedRegisterable.hpp new file mode 100644 index 00000000..f6e9787c --- /dev/null +++ b/src/core/util/AliasedRegisterable.hpp @@ -0,0 +1,16 @@ +#ifndef __UTIL_ALIASEDREGISTERABLE_H__ +#define __UTIL_ALIASEDREGISTERABLE_H__ + +#include +#include + +namespace fail { + +class AliasedRegisterable { +public: + virtual void getAliases(std::deque *aliases) = 0; +}; + +}; // end of namespace fail + +#endif // __UTIL_ALIASEDREGISTERABLE_H__ diff --git a/src/core/util/AliasedRegistry.cc b/src/core/util/AliasedRegistry.cc new file mode 100644 index 00000000..46e3eb76 --- /dev/null +++ b/src/core/util/AliasedRegistry.cc @@ -0,0 +1,68 @@ +#include +#include +#include + +#include "util/AliasedRegistry.hpp" +#include "util/AliasedRegisterable.hpp" + +namespace fail { + +bool AliasedRegistry::add(AliasedRegisterable *obj) { + std::deque aliases; + obj->getAliases(&aliases); + + bool inserted = false; + for (std::deque::iterator it = aliases.begin(); it != aliases.end(); ++it) { + if (m_registry.find(*it) == m_registry.end()) { + if (!inserted) { + m_primes[obj] = *it; + } + m_registry[*it] = obj; + inserted = true; + } else { +#ifndef __puma + std::cerr << "AliasedRegistry: alias '" << *it << "' already exists!" << std::endl; +#endif + } + } + return inserted; +} + +AliasedRegisterable *AliasedRegistry::get(std::string key) { + std::map::iterator it = m_registry.find(key); + if (it != m_registry.end()) { + return it->second; + } else { + return 0; + } +} + +bool AliasedRegistry::getPrimeAlias(AliasedRegisterable *obj, std::string& alias) { + std::map::iterator it = m_primes.find(obj); + if (it != m_primes.end()) { + alias = it->second; + return true; + } else { + return false; + } +} + +void AliasedRegistry::getPrimeAliases(std::deque& aliases) { + std::map::iterator it = m_primes.begin(); + for (;it != m_primes.end(); ++it) { + aliases.push_back(it->second); + } +} + +std::string AliasedRegistry::getPrimeAliasesCSV(){ + std::string csv = ""; + std::deque primes; + getPrimeAliases(primes); + for (std::deque::iterator it = primes.begin(); it != primes.end(); ++it) { + csv += *it + ", "; + } + csv.resize(csv.size()-2); + return csv; +} + +}; // end of namespace fail diff --git a/src/core/util/AliasedRegistry.hpp b/src/core/util/AliasedRegistry.hpp new file mode 100644 index 00000000..0007789d --- /dev/null +++ b/src/core/util/AliasedRegistry.hpp @@ -0,0 +1,43 @@ +#ifndef __UTIL_ALIASEDREGISTRY_H__ +#define __UTIL_ALIASEDREGISTRY_H__ + +#include "util/AliasedRegisterable.hpp" +#include + +namespace fail { + +class AliasedRegistry { +private: + std::map m_registry; + std::map m_primes; + +public: + /** + * Register given AliasedRegisterable by it's aliases + */ + bool add(AliasedRegisterable* obj); + + /** + * Get an AliasedRegisterable by an arbitrary alias + */ + AliasedRegisterable *get(std::string alias); + + /** + * Get the prime (i.e. first to be specified) alias for given object + */ + bool getPrimeAlias(AliasedRegisterable* target, std::string& alias); + + /** + * Get all registered prime aliases + */ + void getPrimeAliases(std::deque& prime_aliases); + + /** + * Get prime aliases' names as CSV + */ + std::string getPrimeAliasesCSV(); +}; + +}; // end of namespace fail + +#endif // __UTIL_ALIASEDREGISTRY_H__ diff --git a/src/core/util/CMakeLists.txt b/src/core/util/CMakeLists.txt index 19a8ff72..91f9e1b5 100644 --- a/src/core/util/CMakeLists.txt +++ b/src/core/util/CMakeLists.txt @@ -29,6 +29,9 @@ set(SRCS SynchronizedQueue.hpp WallclockTimer.cc WallclockTimer.hpp + AliasedRegistry.hpp + AliasedRegistry.cc + AliasedRegisterable.hpp ) diff --git a/tools/import-trace/AdvancedMemoryImporter.hpp b/tools/import-trace/AdvancedMemoryImporter.hpp index a78f50be..504efcf1 100644 --- a/tools/import-trace/AdvancedMemoryImporter.hpp +++ b/tools/import-trace/AdvancedMemoryImporter.hpp @@ -55,6 +55,10 @@ protected: virtual bool handle_mem_event(fail::simtime_t curtime, instruction_count_t instr, Trace_Event &ev); virtual bool trace_end_reached(); + + void getAliases(std::deque *aliases) { + aliases->push_back("AdvancedMemoryImporter"); + } }; #endif diff --git a/tools/import-trace/ElfImporter.hpp b/tools/import-trace/ElfImporter.hpp index f1a77189..9c39e351 100644 --- a/tools/import-trace/ElfImporter.hpp +++ b/tools/import-trace/ElfImporter.hpp @@ -71,6 +71,12 @@ public: virtual bool create_database(); virtual bool copy_to_database(fail::ProtoIStream &ps); virtual bool clear_database(); + + void getAliases(std::deque *aliases) { + aliases->push_back("ElfImporter"); + aliases->push_back("ObjdumpImporter"); + aliases->push_back("objdump"); + } }; #endif diff --git a/tools/import-trace/FullTraceImporter.hpp b/tools/import-trace/FullTraceImporter.hpp index 2db2b193..e6abefaf 100644 --- a/tools/import-trace/FullTraceImporter.hpp +++ b/tools/import-trace/FullTraceImporter.hpp @@ -20,6 +20,11 @@ protected: virtual bool add_trace_event(margin_info_t &begin, margin_info_t &end, Trace_Event &event, bool is_fake = false); virtual bool trace_end_reached(); + +public: + void getAliases(std::deque *aliases) { + aliases->push_back("FullTraceImporter"); + } }; #endif diff --git a/tools/import-trace/Importer.hpp b/tools/import-trace/Importer.hpp index f2f97bc9..ce051245 100644 --- a/tools/import-trace/Importer.hpp +++ b/tools/import-trace/Importer.hpp @@ -11,8 +11,9 @@ #include "util/Database.hpp" #include "util/MemoryMap.hpp" #include "comm/TracePlugin.pb.h" +#include "util/AliasedRegisterable.hpp" -class Importer { +class Importer : public fail::AliasedRegisterable { 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; }; diff --git a/tools/import-trace/InstructionImporter.hpp b/tools/import-trace/InstructionImporter.hpp index 53fc9af7..39696e08 100644 --- a/tools/import-trace/InstructionImporter.hpp +++ b/tools/import-trace/InstructionImporter.hpp @@ -17,6 +17,11 @@ protected: /* ignore on purpose */ return true; } + + void getAliases(std::deque *aliases) { + aliases->push_back("InstructionImporter"); + aliases->push_back("code"); + } }; #endif diff --git a/tools/import-trace/MemoryImporter.hpp b/tools/import-trace/MemoryImporter.hpp index 33b24436..ba7e03e9 100644 --- a/tools/import-trace/MemoryImporter.hpp +++ b/tools/import-trace/MemoryImporter.hpp @@ -11,6 +11,13 @@ protected: Trace_Event &ev); virtual bool handle_mem_event(fail::simtime_t curtime, instruction_count_t instr, Trace_Event &ev); +public: + void getAliases(std::deque *aliases) { + aliases->push_back("MemoryImporter"); + aliases->push_back("BasicImporter"); + aliases->push_back("memory"); + aliases->push_back("mem"); + } }; #endif diff --git a/tools/import-trace/RandomJumpImporter.hpp b/tools/import-trace/RandomJumpImporter.hpp index b18105a0..4181bae6 100644 --- a/tools/import-trace/RandomJumpImporter.hpp +++ b/tools/import-trace/RandomJumpImporter.hpp @@ -35,6 +35,10 @@ protected: virtual void open_unused_ec_intervals() { /* empty, Memory Map has a different meaning in this importer */ } + + void getAliases(std::deque *aliases) { + aliases->push_back("RandomJumpImporter"); + } }; #endif diff --git a/tools/import-trace/RegisterImporter.hpp b/tools/import-trace/RegisterImporter.hpp index 5576ba05..42c45cce 100644 --- a/tools/import-trace/RegisterImporter.hpp +++ b/tools/import-trace/RegisterImporter.hpp @@ -44,6 +44,12 @@ protected: virtual void open_unused_ec_intervals() { /* empty, Memory Map has a different meaning in this importer */ } + + void getAliases(std::deque *aliases) { + aliases->push_back("RegisterImporter"); + aliases->push_back("regs"); + } + }; #endif diff --git a/tools/import-trace/main.cc b/tools/import-trace/main.cc index eb2e71cb..903009b7 100644 --- a/tools/import-trace/main.cc +++ b/tools/import-trace/main.cc @@ -8,6 +8,7 @@ #include #include "MemoryImporter.hpp" #include "FullTraceImporter.hpp" +#include "util/AliasedRegistry.hpp" #ifdef BUILD_LLVM_DISASSEMBLER #include "InstructionImporter.hpp" @@ -57,6 +58,28 @@ int main(int argc, char *argv[]) { ElfReader *elf_file = 0; MemoryMap *memorymap = 0; + AliasedRegistry registry; + Importer *importer; + + MemoryImporter mem; + registry.add(&mem); + FullTraceImporter fti; + registry.add(&fti); + +#ifdef BUILD_LLVM_DISASSEMBLER + RegisterImporter reg; + registry.add(®); + RandomJumpImporter rjump; + registry.add(&rjump); + AdvancedMemoryImporter adv; + registry.add(&adv); + ElfImporter elf; + registry.add(&elf); + InstructionImporter instr; + registry.add(&instr); +#endif + std::string importers = registry.getPrimeAliasesCSV(); + // Manually fill the command line option parser CommandLine &cmd = CommandLine::Inst(); for (int i = 1; i < argc; ++i) @@ -123,42 +146,24 @@ int main(int argc, char *argv[]) { exit(-1); } - Importer *importer; - + // get the desired importer from the commandline; default to MemoryImporter + std::string imp("MemoryImporter"); if (cmd[IMPORTER]) { - std::string imp(cmd[IMPORTER].first()->arg); - if (imp == "BasicImporter" || imp == "MemoryImporter" || imp == "memory" || imp == "mem") { - imp = "MemoryImporter"; - importer = new MemoryImporter(); - } else if (imp == "FullTraceImporter") { - importer = new FullTraceImporter(); -#ifdef BUILD_LLVM_DISASSEMBLER - } else if (imp == "InstructionImporter" || imp == "code") { - imp = "InstructionImporter"; - importer = new InstructionImporter(); - - } else if (imp == "RegisterImporter" || imp == "regs") { - imp = "RegisterImporter"; - importer = new RegisterImporter(); - - } else if (imp == "RandomJumpImporter") { - importer = new RandomJumpImporter(); - } else if (imp == "AdvancedMemoryImporter") { - importer = new AdvancedMemoryImporter(); - } else if (imp == "ObjdumpImporter" || imp == "objdump" || imp == "ElfImporter") { - importer = new ElfImporter(); -#endif - } else { - LOG << "Unknown import method: " << imp << endl; - exit(-1); - } - LOG << "Using " << imp << endl; - - } else { - LOG << "Using MemoryImporter" << endl; - importer = new MemoryImporter(); + imp = cmd[IMPORTER].first()->arg; } + // try and get the according importer object ; die on failure + if ((importer = (Importer *)registry.get(imp)) == 0) { + LOG << "Unknown import method: " << imp << endl; + exit(-1); + } + + std::string prime; + if (registry.getPrimeAlias(importer, prime)) { + imp = prime; + } + LOG << "Using " << imp << endl; + if (importer && !(importer->cb_commandline_init())) { std::cerr << "Cannot call importers command line initialization!" << std::endl; exit(-1);