diff --git a/src/core/util/Demangler.cc b/src/core/util/Demangler.cc index e469d4d5..7ed34574 100644 --- a/src/core/util/Demangler.cc +++ b/src/core/util/Demangler.cc @@ -5,7 +5,7 @@ #include namespace fail { - + const std::string Demangler::DEMANGLE_FAILED = "[Demangler] Demangle failed."; std::string Demangler::demangle(const std::string& name){ @@ -13,7 +13,7 @@ namespace fail { if(res != NULL){ return std::string(res); }else{ - return DEMANGLE_FAILED; + return Demangler::DEMANGLE_FAILED; } } diff --git a/src/core/util/Demangler.hpp b/src/core/util/Demangler.hpp index e5644df8..b8d7299a 100644 --- a/src/core/util/Demangler.hpp +++ b/src/core/util/Demangler.hpp @@ -1,10 +1,10 @@ #ifndef __DEMANGLER_HPP -#define __DEMANGLER_HPP +#define __DEMANGLER_HPP #include namespace fail { - + class Demangler { public: diff --git a/src/core/util/ElfReader.cc b/src/core/util/ElfReader.cc index ca34e68b..1d6c85ca 100644 --- a/src/core/util/ElfReader.cc +++ b/src/core/util/ElfReader.cc @@ -2,12 +2,21 @@ #include "sal/SALConfig.hpp" #include #include - +#include #include "Demangler.hpp" namespace fail { -const std::string ElfReader::NOTFOUND = "[ELFReader] Function not found."; +const std::string ELF::NOTFOUND = "[ELFReader] Function not found."; +static const ElfSymbol g_SymbolNotFound; + +bool operator==(const std::string & str, const ElfSymbol & sym) { + return sym.getName() == str; +} + +bool operator==(guest_address_t address, const ElfSymbol & sym) { + return sym.getAddress() == address; +} ElfReader::ElfReader() : m_log("Fail*Elfinfo", false){ @@ -91,13 +100,17 @@ void ElfReader::setup(const char* path) { free(buff); fclose(fp); + + // printDemangled(); + // printSections(); } int ElfReader::process_section(Elf32_Shdr *sect_hdr, char* sect_name_buff){ // Add section name, start address and size to list int idx=sect_hdr->sh_name; - m_sections_map.push_back( sect_hdr->sh_addr, sect_hdr->sh_size, sect_name_buff+idx ); +// m_sections_map.push_back( sect_hdr->sh_addr, sect_hdr->sh_size, sect_name_buff+idx ); + m_sectiontable.push_back( ElfSymbol(sect_name_buff+idx, sect_hdr->sh_addr, sect_hdr->sh_size, ElfSymbol::SECTION) ); return 0; } @@ -144,103 +157,89 @@ int ElfReader::process_symboltable(int sect_num, FILE* fp){ int type = ELF32_ST_TYPE(mysym.st_info); if((type != STT_SECTION) && (type != STT_FILE)){ -#ifndef __puma - m_bimap_mangled.insert( entry(name_buf+idx, mysym.st_value) ); - m_bimap_demangled.insert( entry ( Demangler::demangle(name_buf+idx), mysym.st_value) ); - -#endif + m_symboltable.push_back( ElfSymbol(name_buf+idx, mysym.st_value, mysym.st_size, ElfSymbol::SYMBOL) ); } } free (name_buf); return 0; } -guest_address_t ElfReader::getAddressByName(const std::string& name) { -#ifndef __puma - guest_address_t res = getAddress(m_bimap_demangled, name); - if(res == ADDR_INV){ - res = getAddress(m_bimap_mangled, name); +const ElfSymbol& ElfReader::getSymbol(guest_address_t address){ + for(container_t::const_iterator it = m_symboltable.begin(); it !=m_symboltable.end(); ++it){ + if(it->contains(address)){ + return *it; + } } - return res; -#endif + + return g_SymbolNotFound; } -#ifndef __puma -guest_address_t ElfReader::getAddress(const bimap_t& map, const std::string& name){ - typedef bimap_t::left_map::const_iterator const_iterator_t; - - const_iterator_t iterator = map.left.find(name); - if(iterator == map.left.end()){ - return ADDR_INV; - }else{ - return iterator->second; +// Symbol search +const ElfSymbol& ElfReader::getSymbol( const std::string& name ){ + container_t::const_iterator it; + // Fist, try to find as mangled symbol + it = std::find(m_symboltable.begin(), m_symboltable.end(), name); + if(it != m_symboltable.end()){ + return *it; } -} -#endif -#ifndef __puma -std::string ElfReader::getName(const bimap_t& map, guest_address_t address){ - // .right switches key/value - typedef bimap_t::right_map::const_iterator const_iterator_t; - - const_iterator_t iterator = map.right.find(address); - if(iterator != map.right.end()){ - return iterator->second; + // Then, try to find as demangled symbol + std::string dname = Demangler::demangle(name); + if(dname == Demangler::DEMANGLE_FAILED){ + return g_SymbolNotFound; } - return NOTFOUND; -} -std::string ElfReader::getNameByAddress(guest_address_t address) { - std::string res = getName(m_bimap_demangled, address); - if(res == NOTFOUND){ - return getName(m_bimap_mangled, address); + it = std::find(m_symboltable.begin(), m_symboltable.end(), dname); + if(it != m_symboltable.end()){ + return *it; } - return res; + + return g_SymbolNotFound; } -std::string ElfReader::getMangledNameByAddress(guest_address_t address) { - return getName(m_bimap_mangled, address); +// Section search +const ElfSymbol& ElfReader::getSection(guest_address_t address){ + for(container_t::const_iterator it = m_sectiontable.begin(); it != m_sectiontable.end(); ++it){ + if(it->contains(address)){ + return *it; + } + } + return g_SymbolNotFound; } -std::string ElfReader::getDemangledNameByAddress(guest_address_t address) { - return getName(m_bimap_demangled, address); +const ElfSymbol& ElfReader::getSection( const std::string& name ){ + for(container_t::const_iterator it = m_sectiontable.begin(); it !=m_sectiontable.end(); ++it){ + if(it->getName() == name){ + return *it; + } + } + return g_SymbolNotFound; } +// "Pretty" Print void ElfReader::printDemangled(){ - print_map(m_bimap_demangled.right); // print Address as first element + m_log << "Demangled: " << std::endl; + for(container_t::const_iterator it = m_symboltable.begin(); it !=m_symboltable.end(); ++it){ + std::string str = Demangler::demangle(it->getName()); + if(str == Demangler::DEMANGLE_FAILED){ + str = it->getName(); + } + m_log << "0x" << std::hex << it->getAddress() << "\t" << str.c_str() << "\t" << it->getSize() << std::endl; + } } void ElfReader::printMangled(){ - print_map(m_bimap_mangled.right); // print Address as first element -} -#endif - -#ifndef __puma -std::string ElfReader::getSection(guest_address_t address) { - return m_sections_map.find_name_by(address); -} - -guest_address_t ElfReader::getSectionStart(const std::string& sectionname) { - SectionsMap::address_pair_t pair; - pair = m_sections_map.find_range_by(sectionname); - - return pair.first; -} - -guest_address_t ElfReader::getSectionEnd(const std::string& sectionname) { - SectionsMap::address_pair_t pair = m_sections_map.find_range_by(sectionname); - if ( pair.first == ADDR_INV ) { - return ADDR_INV; + for(container_t::const_iterator it = m_symboltable.begin(); it !=m_symboltable.end(); ++it){ + m_log << "0x" << it->getAddress() << "\t" << it->getName().c_str() << "\t" << it->getSize() << std::endl; } - return pair.first + pair.second; } -guest_address_t ElfReader::getSectionSize(const std::string& sectionname) { - SectionsMap::address_pair_t pair = m_sections_map.find_range_by(sectionname); - return pair.second; +void ElfReader::printSections() { + for(container_t::const_iterator it = m_sectiontable.begin(); it !=m_sectiontable.end(); ++it){ + m_log << "0x" << it->getAddress() << "\t" << it->getName().c_str() << "\t" << it->getSize() << std::endl; + } } -#endif } // end-of-namespace fail diff --git a/src/core/util/ElfReader.hpp b/src/core/util/ElfReader.hpp index dfb27d6d..82facc11 100644 --- a/src/core/util/ElfReader.hpp +++ b/src/core/util/ElfReader.hpp @@ -2,58 +2,59 @@ #define __ELFREADER_HPP__ #include - -#ifndef __puma -#include -#endif - #include #include "sal/SALConfig.hpp" // for ADDR_INV #include "Logger.hpp" #include "elfinfo/elfinfo.h" #include #include +#include "Demangler.hpp" namespace fail { - /* - * Helper struct for section information - */ - struct SectionsMap { - typedef std::pair address_pair_t; - typedef std::vector< std::pair< address_pair_t, std::string> > container ; - container section_to_name; + struct ELF { + static const std::string NOTFOUND; + }; - void push_back(guest_address_t start, size_t size, std::string name) - { - section_to_name.push_back(std::make_pair(std::make_pair(start, size), name)); - } + class ElfSymbol { + std::string name; + guest_address_t address; + size_t size; + int m_type; - address_pair_t find_range_by(std::string name){ - for(container::iterator it = section_to_name.begin(), end = section_to_name.end(); it != end; ++it){ - container::value_type pair_pair_string = *it; - typedef container::value_type::first_type section_type; + public: + enum { SECTION = 1, SYMBOL = 2, UNDEFINED = 3, }; - if(pair_pair_string.second == name){ - return pair_pair_string.first; - } + ElfSymbol(const std::string & name = ELF::NOTFOUND, guest_address_t addr = ADDR_INV, size_t size = -1, int type = UNDEFINED) + : name(name), address(addr), size(size), m_type(type) {}; + + const std::string& getName() const { return name; }; + guest_address_t getAddress() const { return address; }; + size_t getSize() const { return size; }; + guest_address_t getStart() const { return getAddress(); }; // alias + guest_address_t getEnd() const { return address + size; }; + + bool isSection() const { return m_type == SECTION; }; + bool isSymbol() const { return m_type == SYMBOL; }; + + bool operator==(const std::string& rhs) const { + if(rhs == name){ + return true; } - return std::make_pair(ADDR_INV, 0); - } - - std::string find_name_by(guest_address_t address){ - for(container::iterator it = section_to_name.begin(), end = section_to_name.end(); it != end; ++it){ - container::value_type pair_pair_string = *it; - typedef container::value_type::first_type section_type; - section_type section = pair_pair_string.first; - if(address >= section.first && address < section.first + section.second){ - return pair_pair_string.second; - } + if( rhs == Demangler::demangle(name) ){ + return true; } - return std::string("SECTION_NOT_FOUND"); + + return false; } + bool operator==(const guest_address_t rhs) const { + return rhs == address; + } + bool contains(guest_address_t ad) const { + return (ad >= address) && (ad < address+size); + } }; @@ -79,38 +80,6 @@ namespace fail { */ ElfReader(); - /** - * Get guest address by symbol name. - * Both mangled an demangled symbols are searched. - * @param name The symbol name as string - * @return The according address if found, else ADDR_INV - */ - guest_address_t getAddressByName(const std::string& name) ; - - /** - * Get demangled symbol name associated to an address - * This is interesting when checking instruction pointers. - * @param name The address of a symbol (or around a symbol -> instruction pointer) - * @return The according address if found, else ElfReader::NOTFOUND - */ - std::string getNameByAddress(guest_address_t address) ; - - /** - * Get the mangled symbol name associated to an address - - * @param name The address of a symbol (or around a symbol -> instruction pointer) - * @return The according address if found, else ElfReader::NOTFOUND - */ - std::string getMangledNameByAddress(guest_address_t address) ; - - /** - * Get the demangled symbol name associated to an address - * Note the the demangled name is simplified, not showing any types! - * @param name The address of a symbol (or around a symbol -> instruction pointer) - * @return The according address if found, else ElfReader::NOTFOUND - */ - std::string getDemangledNameByAddress(guest_address_t address) ; - /** * Print the list of available mangled symbols * @note This includes both C and C++ symbols @@ -118,41 +87,42 @@ namespace fail { void printMangled(); /** - * Print the list of all available demangled symbols - * @note These are only C++ symbols. + * Print a list of demangled symbols. */ void printDemangled(); - //! Default string, if symbol is not found - static const std::string NOTFOUND; - /** - * Get the name of a section - * @param address The address of the section - * @return The according section name if section was found, else SECTION_NOT_FOUND + * Print the list of all available sections. */ - std::string getSection(guest_address_t address); + void printSections(); /** - * Get the start address of a section + * Get symbol by address + * @param address Address within range of the symbol + * @return The according symbol name if symbol.address <= address < symbol.address + symbol.size , else g_SymbolNotFound + */ + const ElfSymbol& getSymbol(guest_address_t address); + + /** + * Get symbol by name + * @param address Name of the symbol + * @return The according symbol name if section was found, else g_SymbolNotFound + */ + const ElfSymbol& getSymbol( const std::string& name ); + + /** + * Get section by address + * @param address An address to search for a section containing that address. + * @return The according section name if section was found, else g_SymbolNotFound + */ + const ElfSymbol& getSection(guest_address_t address); + + /** + * Get section by name * @param name The name of the section - * @return The according section start if section was found, else ADDR_INV + * @return The according section if section was found, else g_SymbolNotFound */ - guest_address_t getSectionStart(const std::string& name); - - /** - * Get the end address of a section - * @param name The name of the section - * @return The according section end if section was found, else ADDR_INV - */ - guest_address_t getSectionEnd(const std::string& name); - - /** - * Get the size of a section - * @param name The name of the section - * @return The according section sizh if section was found, else ADDR_INV - */ - guest_address_t getSectionSize(const std::string& name); + const ElfSymbol& getSection( const std::string& name ); private: Logger m_log; @@ -161,27 +131,14 @@ namespace fail { int process_symboltable(int sect_num, FILE* fp); int process_section(Elf32_Shdr *sect_hdr, char* sect_name_buff); - fail::SectionsMap m_sections_map; + typedef ElfSymbol entry_t; + typedef std::vector container_t; -#ifndef __puma - typedef boost::bimap< std::string, guest_address_t > bimap_t; - typedef bimap_t::value_type entry; + container_t m_symboltable; + container_t m_sectiontable; - bimap_t m_bimap_mangled; - bimap_t m_bimap_demangled; - - template < typename MapType > - void print_map(const MapType & m){ - typedef typename MapType::const_iterator const_iterator; - for( const_iterator iter = m.begin(), iend = m.end(); iter != iend; ++iter ) - { - m_log << std::hex << iter->first << " \t "<< std::hex << iter->second << std::endl; - } - } - - guest_address_t getAddress(const bimap_t& map, const std::string& name); - std::string getName(const bimap_t& map, guest_address_t address); -#endif + guest_address_t getAddress(const std::string& name); + std::string getName(guest_address_t address); }; } // end-of-namespace fail diff --git a/src/core/util/Logger.hpp b/src/core/util/Logger.hpp index 052886ff..092273d2 100644 --- a/src/core/util/Logger.hpp +++ b/src/core/util/Logger.hpp @@ -25,7 +25,7 @@ public: * @param dest Stream to log into. */ Logger(const std::string& description = "Fail*", bool show_time = true, - std::ostream& dest = std::cout) + std::ostream& dest = std::cout) : m_pDest(&dest), m_description(description), m_showTime(show_time) { } /** * Change the default description which is shown alongside each log diff --git a/src/experiments/ecos_kernel_test/experiment.cc b/src/experiments/ecos_kernel_test/experiment.cc index 040a79a0..dfead205 100644 --- a/src/experiments/ecos_kernel_test/experiment.cc +++ b/src/experiments/ecos_kernel_test/experiment.cc @@ -593,13 +593,13 @@ bool EcosKernelTestExperiment::readELFSymbols( fail::guest_address_t& text_end) { ElfReader elfreader(EcosKernelTestCampaign::filename_elf(m_variant, m_benchmark).c_str()); - entry = elfreader.getAddressByName("cyg_start"); - finish = elfreader.getAddressByName("cyg_test_exit"); - test_output = elfreader.getAddressByName("cyg_test_output"); - errors_corrected = elfreader.getAddressByName("errors_corrected"); - panic = elfreader.getAddressByName("_Z9ecc_panicv"); - text_start = elfreader.getAddressByName("_stext"); - text_end = elfreader.getAddressByName("_etext"); + entry = elfreader.getSymbol("cyg_start").getAddress(); + finish = elfreader.getSymbol("cyg_test_exit").getAddress(); + test_output = elfreader.getSymbol("cyg_test_output").getAddress(); + errors_corrected = elfreader.getSymbol("errors_corrected").getAddress(); + panic = elfreader.getSymbol("_Z9ecc_panicv").getAddress(); + text_start = elfreader.getSymbol("_stext").getAddress(); + text_end = elfreader.getSymbol("_etext").getAddress(); // it's OK if errors_corrected or ecc_panic are missing if (entry == ADDR_INV || finish == ADDR_INV || test_output == ADDR_INV || diff --git a/src/experiments/kesorefs/campaign.cc b/src/experiments/kesorefs/campaign.cc index c7e82618..a656d2cd 100644 --- a/src/experiments/kesorefs/campaign.cc +++ b/src/experiments/kesorefs/campaign.cc @@ -35,9 +35,9 @@ bool KesoRefCampaign::run() return false; } - address_t injip = elf.getAddressByName("c23_PersistentDetectorScopeEntry_m5_run"); + address_t injip = elf.getSymbol("c23_PersistentDetectorScopeEntry_m5_run").getAddress(); - address_t rambase = elf.getAddressByName("__CIAO_APPDATA_cdx_det__heap"); + address_t rambase = elf.getSymbol("__CIAO_APPDATA_cdx_det__heap").getAddress(); // address_t ramend = rambase + 0x80000; address_t ramend = rambase + 4; cout << "ramend: " << hex << ramend << endl; diff --git a/src/experiments/kesorefs/experiment.cc b/src/experiments/kesorefs/experiment.cc index 307e3c8c..352fa2b8 100644 --- a/src/experiments/kesorefs/experiment.cc +++ b/src/experiments/kesorefs/experiment.cc @@ -24,7 +24,7 @@ using namespace std; using namespace fail; -#define SAFESTATE (0) +#define SAFESTATE (1) // Check if configuration dependencies are satisfied: #if !defined(CONFIG_EVENT_BREAKPOINTS) || !defined(CONFIG_SR_RESTORE) || \ @@ -77,18 +77,20 @@ void handleMemoryAccessEvent(KesoRefExperimentData& param, const fail::MemAccess handleEvent(param, param.msg.MEMACCESS, sstr.str()); } - bool KESOrefs::run() { //******* Boot, and store state *******// m_log << "STARTING EXPERIMENT" << endl; - ElfReader m_elf; #if SAFESTATE // define SS (SafeState) when building: make -DSS #warning "Building safe state variant" - m_log << "Booting, and saving state at main"; + m_log << "Booting, and saving state at main" << std::endl; + // m_elf.printSections(); + // m_elf.printDemangled(); + + simulator.terminate(); BPSingleListener bp; // STEP 1: run until interesting function starts, and save state - bp.setWatchInstructionPointer(m_elf.getAddressByName("main")); + bp.setWatchInstructionPointer(m_elf.getSymbol("main").getAddress()); if(simulator.addListenerAndResume(&bp) == &bp){ m_log << "main function entry reached, saving state" << endl; } @@ -117,7 +119,7 @@ bool KESOrefs::run() simulator.restore("keso.state"); // Goto injection point BPSingleListener injBP; - m_log << "Trying to inject @ " << hex << m_elf.getNameByAddress(injectionPC) << endl; + m_log << "Trying to inject @ " << hex << m_elf.getSymbol(injectionPC).getAddress() << endl; injBP.setWatchInstructionPointer(injectionPC); @@ -126,15 +128,22 @@ bool KESOrefs::run() param.msg.set_original_value(injectBitFlip(data_address, bitpos)); // Setup exit points - BPSingleListener l_error(m_elf.getAddressByName("keso_throw_error")); - BPSingleListener l_nullp(m_elf.getAddressByName("keso_throw_nullpointer")); - BPSingleListener l_parity(m_elf.getAddressByName("keso_throw_parity")); - BPSingleListener l_oobounds(m_elf.getAddressByName("keso_throw_index_out_of_bounds")); - BPSingleListener l_dump(m_elf.getAddressByName("c17_Main_m4_dumpResults_console")); - MemAccessListener l_mem_text(m_elf.getSectionStart(".text"), MemAccessEvent::MEM_WRITE); l_mem_text.setWatchWidth(m_elf.getSectionSize(".text")); - MemAccessListener l_mem_textcdx_det( m_elf.getSectionStart(".text.cdx_det"), MemAccessEvent::MEM_WRITE ); l_mem_textcdx_det.setWatchWidth(m_elf.getSectionSize(".text.cdx_det")); - MemAccessListener l_mem_outerspace( m_elf.getSectionStart(".copy_sec") ); l_mem_outerspace.setWatchWidth(0xfffffff0); + BPSingleListener l_error(m_elf.getSymbol("keso_throw_error").getAddress()); + BPSingleListener l_nullp(m_elf.getSymbol("keso_throw_nullpointer").getAddress()); + BPSingleListener l_parity(m_elf.getSymbol("keso_throw_parity").getAddress()); + BPSingleListener l_oobounds(m_elf.getSymbol("keso_throw_index_out_of_bounds").getAddress()); + BPSingleListener l_dump(m_elf.getSymbol("c17_Main_m4_dumpResults_console").getAddress()); + + ElfSymbol sym = m_elf.getSection(".text"); + MemAccessListener l_mem_text(sym.getStart(), , AccessEvent::MEM_WRITE); l_mem_text.setWatchWidth(sym.getSize()); + + sym = m_elf.getSection(".text.cdx_det"); + MemAccessListener l_mem_textcdx_det(sym.getStart(), MemAccessEvent::MEM_WRITE ); l_mem_textcdx_det.setWatchWidth(sym.getSize()); + + sym = m_elf.getSection(".copy_sec"); + MemAccessListener l_mem_outerspace( sym.getStart() ); l_mem_outerspace.setWatchWidth(0xfffffff0); TrapListener l_trap(ANY_TRAP); + cout << " outerspace : " << l_mem_outerspace.getWatchWidth() << " --- @ :" << l_mem_outerspace.getWatchAddress() << endl; simulator.addListener(&l_trap); simulator.addListener(&l_error); diff --git a/src/experiments/kesorefs/experiment.hpp b/src/experiments/kesorefs/experiment.hpp index 016e708e..88b306b6 100644 --- a/src/experiments/kesorefs/experiment.hpp +++ b/src/experiments/kesorefs/experiment.hpp @@ -13,6 +13,7 @@ class KESOrefs : public fail::ExperimentFlow { fail::JobClient m_jc; fail::Logger m_log; fail::MemoryManager& m_mm; + fail::ElfReader m_elf; void printEIP(); void setupExitBPs(const std::string&); @@ -23,7 +24,8 @@ class KESOrefs : public fail::ExperimentFlow { unsigned injectBitFlip(fail::address_t data_address, unsigned bitpos); public: - KESOrefs() : m_log("KESOrefs", false), m_mm(fail::simulator.getMemoryManager()) {}; + KESOrefs() : m_log("KESOrefs", false), m_mm(fail::simulator.getMemoryManager()) { + }; bool run(); }; diff --git a/src/experiments/nanojpeg/experiment.cc b/src/experiments/nanojpeg/experiment.cc index 146ddde6..17c313df 100644 --- a/src/experiments/nanojpeg/experiment.cc +++ b/src/experiments/nanojpeg/experiment.cc @@ -80,17 +80,17 @@ bool NanoJPEGExperiment::run() ElfReader elfreader(NANOJPEG_ELF); guest_address_t addr_text_start = - elfreader.getAddressByName("___TEXT_START__"); + elfreader.getSymbol("___TEXT_START__").getAddress(); guest_address_t addr_text_end = - elfreader.getAddressByName("___TEXT_END__"); + elfreader.getSymbol("___TEXT_END__").getAddress(); guest_address_t addr_rodata_start = - elfreader.getAddressByName("___RODATA_START__"); + elfreader.getSymbol("___RODATA_START__").getAddress(); guest_address_t addr_bss_end = - elfreader.getAddressByName("___BSS_END__"); + elfreader.getSymbol("___BSS_END__").getAddress(); guest_address_t addr_output_image_ptr = - elfreader.getAddressByName("output_image"); + elfreader.getSymbol("output_image").getAddress(); guest_address_t addr_output_image_size = - elfreader.getAddressByName("output_image_size"); + elfreader.getSymbol("output_image_size").getAddress(); log << "ELF symbols: text " << hex << addr_text_start << "-" << addr_text_end << " rodata/data/bss " << addr_rodata_start << "-" << addr_bss_end << " output_image ptr @ " << addr_output_image_ptr << ", size @ " << addr_output_image_size << endl;