--- tester/covoar/CoverageMapBase.cc | 41 +++++++------ tester/covoar/DesiredSymbols.cc | 123 ++------------------------------------- tester/covoar/ExecutableInfo.cc | 80 ++++++++++++++++--------- tester/covoar/ExecutableInfo.h | 41 ++++++++++--- tester/covoar/GcovData.cc | 29 +++++---- tester/covoar/covoar.cc | 2 +- tester/covoar/wscript | 2 +- 7 files changed, 127 insertions(+), 191 deletions(-)
diff --git a/tester/covoar/CoverageMapBase.cc b/tester/covoar/CoverageMapBase.cc index ed30603..d2b60d2 100644 --- a/tester/covoar/CoverageMapBase.cc +++ b/tester/covoar/CoverageMapBase.cc @@ -2,11 +2,10 @@ /*! @file CoverageMapBase.cc * @brief CoverageMapBase Implementation * - * This file contains the implementation of the functions + * This file contains the implementation of the functions * which provide a base level of functionality of a CoverageMap. */ -#include <libgen.h> #include <limits.h> #include <stdio.h> #include <stdlib.h> @@ -51,7 +50,7 @@ namespace Coverage { if (Info) delete Info; } - + void CoverageMapBase::Add( uint32_t low, uint32_t high ) { AddressRange_t range; @@ -60,9 +59,9 @@ namespace Coverage { range.highAddress = high; RangeList.push_back( range ); } - - bool CoverageMapBase::determineOffset( - uint32_t address, + + bool CoverageMapBase::determineOffset( + uint32_t address, uint32_t *offset )const { @@ -174,7 +173,7 @@ namespace Coverage { ) { uint32_t offset; - + if (determineOffset( address, &offset ) != true) return; @@ -184,7 +183,7 @@ namespace Coverage { bool CoverageMapBase::isStartOfInstruction( uint32_t address ) const { uint32_t offset; - + if (determineOffset( address, &offset ) != true) return false; @@ -194,7 +193,7 @@ namespace Coverage { void CoverageMapBase::setWasExecuted( uint32_t address ) { uint32_t offset; - + if (determineOffset( address, &offset ) != true) return; @@ -204,7 +203,7 @@ namespace Coverage { void CoverageMapBase::sumWasExecuted( uint32_t address, uint32_t addition) { uint32_t offset; - + if (determineOffset( address, &offset ) != true) return; @@ -215,7 +214,7 @@ namespace Coverage { { uint32_t offset; bool result; - + result = true; if (determineOffset( address, &offset ) != true) @@ -234,7 +233,7 @@ namespace Coverage { if (determineOffset( address, &offset ) != true) return 0; - return Info[ offset ].wasExecuted; + return Info[ offset ].wasExecuted; } void CoverageMapBase::setIsBranch( @@ -242,7 +241,7 @@ namespace Coverage { ) { uint32_t offset; - + if (determineOffset( address, &offset ) != true) return; @@ -252,7 +251,7 @@ namespace Coverage { bool CoverageMapBase::isNop( uint32_t address ) const { uint32_t offset; - + if (determineOffset( address, &offset ) != true) return false; @@ -264,7 +263,7 @@ namespace Coverage { ) { uint32_t offset; - + if (determineOffset( address, &offset ) != true) return; @@ -274,7 +273,7 @@ namespace Coverage { bool CoverageMapBase::isBranch( uint32_t address ) const { uint32_t offset; - + if (determineOffset( address, &offset ) != true) return false; @@ -286,7 +285,7 @@ namespace Coverage { ) { uint32_t offset; - + if (determineOffset( address, &offset ) != true) return; @@ -298,7 +297,7 @@ namespace Coverage { ) { uint32_t offset; - + if (determineOffset( address, &offset ) != true) return; @@ -308,7 +307,7 @@ namespace Coverage { bool CoverageMapBase::wasAlwaysTaken( uint32_t address ) const { uint32_t offset; - + if (determineOffset( address, &offset ) != true) return false; @@ -319,7 +318,7 @@ namespace Coverage { bool CoverageMapBase::wasNeverTaken( uint32_t address ) const { uint32_t offset; - + if (determineOffset( address, &offset ) != true) return false; @@ -369,7 +368,7 @@ namespace Coverage { bool result; result = true; - + if (determineOffset( address, &offset ) != true) result = false; diff --git a/tester/covoar/DesiredSymbols.cc b/tester/covoar/DesiredSymbols.cc index 89f95ea..278498d 100644 --- a/tester/covoar/DesiredSymbols.cc +++ b/tester/covoar/DesiredSymbols.cc @@ -9,7 +9,6 @@ #undef __STRICT_ANSI__ #endif -#include <libgen.h> #include <limits.h> #include <stdio.h> #include <stdlib.h> @@ -445,123 +444,13 @@ namespace Coverage { ) { - char* base; - char* cStatus; - char command[512]; - std::string fileName; - CoverageRanges::ranges_t::iterator ritr; - char rpath[PATH_MAX]; - FILE* tmpfile; - - // Open a temporary file for the uncovered ranges. - tmpfile = fopen( "ranges1.tmp", "w" ); - if ( !tmpfile ) { - fprintf( - stderr, - "ERROR: DesiredSymbols::determineSourceLines - " - "unable to open %s\n", - "ranges1.tmp" - ); - exit(-1); - } - - // Write the range addresses to the temporary file. - for (ritr = theRanges->set.begin(); - ritr != theRanges->set.end(); - ritr++ ) { - fprintf( - tmpfile, - "0x%08x\n0x%08x\n", - ritr->lowAddress - theExecutable->getLoadAddress(), - ritr->highAddress - theExecutable->getLoadAddress() - ); - } - - fclose( tmpfile ); - - // Invoke addr2line to generate the source lines for each address. - if (theExecutable->hasDynamicLibrary()) - fileName = theExecutable->getLibraryName(); - else - fileName = theExecutable->getFileName(); - - sprintf( - command, - "%s -Ce %s <%s | dos2unix >%s", - TargetInfo->getAddr2line(), - fileName.c_str(), - "ranges1.tmp", - "ranges2.tmp" - ); - - if (system( command )) { - fprintf( - stderr, - "ERROR: DesiredSymbols::determineSourceLines - " - "command (%s) failed\n", - command - ); - exit( -1 ); - } - - // Open the addr2line output file. - tmpfile = fopen( "ranges2.tmp", "r" ); - if ( !tmpfile ) { - fprintf( - stderr, - "ERROR: DesiredSymbols::determineSourceLines - " - "unable to open %s\n", - "ranges2.tmp" - ); - exit(-1); + for (auto& r : theRanges->set) { + std::string location; + theExecutable->getSourceAndLine(r.lowAddress, location); + r.lowSourceLine = rld::path::basename (location); + theExecutable->getSourceAndLine(r.highAddress, location); + r.highSourceLine = rld::path::basename (location); } - - // Process the addr2line output. - for (ritr = theRanges->set.begin(); - ritr != theRanges->set.end(); - ritr++ ) { - - cStatus = fgets( inputBuffer, MAX_LINE_LENGTH, tmpfile ); - if ( cStatus == NULL ) { - fprintf( - stderr, - "ERROR: DesiredSymbols::determineSourceLines - " - "Out of sync in addr2line output\n" - ); - exit( -1 ); - } - inputBuffer[ strlen(inputBuffer) - 1] = '\0'; - - // Use only the base filename without directory path. -#ifdef _WIN32 - #define realpath(N,R) _fullpath((R),(N),_MAX_PATH) -#endif - realpath( inputBuffer, rpath ); - base = basename( rpath ); - - ritr->lowSourceLine = std::string( base ); - - cStatus = fgets( inputBuffer, MAX_LINE_LENGTH, tmpfile ); - if ( cStatus == NULL ) { - fprintf( - stderr, - "ERROR: DesiredSymbols::determineSourceLines - " - "Out of sync in addr2line output\n" - ); - exit( -1 ); - } - inputBuffer[ strlen(inputBuffer) - 1] = '\0'; - - // Use only the base filename without directory path. - realpath( inputBuffer, rpath ); - base = basename( rpath ); - - ritr->highSourceLine = std::string( base ); - } - - fclose( tmpfile ); - unlink( "ranges1.tmp" ); - unlink( "ranges2.tmp" ); } SymbolInformation* DesiredSymbols::find( diff --git a/tester/covoar/ExecutableInfo.cc b/tester/covoar/ExecutableInfo.cc index c41d931..1755e93 100644 --- a/tester/covoar/ExecutableInfo.cc +++ b/tester/covoar/ExecutableInfo.cc @@ -7,6 +7,8 @@ #include <stdio.h> +#include <rld.h> + #include "ExecutableInfo.h" #include "app_common.h" #include "CoverageMap.h" @@ -18,24 +20,36 @@ namespace Coverage { ExecutableInfo::ExecutableInfo( const char* const theExecutableName, const char* const theLibraryName - ) + ) : executable(theExecutableName), + loadAddress(0) { - executableName = theExecutableName; - loadAddress = 0; - libraryName = ""; if (theLibraryName) libraryName = theLibraryName; - theSymbolTable = new SymbolTable(); + try { + executable.open(); + executable.begin(); + executable.load_symbols(symbols); + debug.begin(executable.elf()); + debug.load_debug(); + } catch (rld::error re) { + std::cerr << "error: " + << re.where << ": " << re.what + << std::endl; + exit(2); + } catch (...) { + exit(2); + } } ExecutableInfo::~ExecutableInfo() { - if (theSymbolTable) - delete theSymbolTable; + debug.end(); + executable.end(); + executable.close(); } void ExecutableInfo::dumpCoverageMaps( void ) { - ExecutableInfo::coverageMaps_t::iterator itr; + ExecutableInfo::CoverageMaps::iterator itr; for (itr = coverageMaps.begin(); itr != coverageMaps.end(); itr++) { fprintf( stderr, "Coverage Map for %s\n", ((*itr).first).c_str() );; @@ -44,21 +58,22 @@ namespace Coverage { } void ExecutableInfo::dumpExecutableInfo( void ){ - fprintf( stdout, "\n== Executable info ==\n"); - fprintf( stdout, "executableName = %s\n", executableName.c_str()); - fprintf( stdout, "libraryName = %s\n", libraryName.c_str()); - fprintf( stdout, "loadAddress = %u\n", loadAddress); - theSymbolTable->dumpSymbolTable(); + std::cout << std::endl + << "== Executable info ==" << std::endl + << "executable = " << getFileName () << std::endl + << "library = " << libraryName << std::endl + << "loadAddress = " << loadAddress << std::endl; + theSymbolTable.dumpSymbolTable(); } CoverageMapBase* ExecutableInfo::getCoverageMap ( uint32_t address ) { - CoverageMapBase* aCoverageMap = NULL; - coverageMaps_t::iterator it; - std::string itsSymbol; + CoverageMapBase* aCoverageMap = NULL; + CoverageMaps::iterator it; + std::string itsSymbol; // Obtain the coverage map containing the specified address. - itsSymbol = theSymbolTable->getSymbol( address ); + itsSymbol = theSymbolTable.getSymbol( address ); if (itsSymbol != "") { it = coverageMaps.find( itsSymbol ); aCoverageMap = (*it).second; @@ -67,12 +82,12 @@ namespace Coverage { return aCoverageMap; } - const std::string& ExecutableInfo::getFileName ( void ) const + const std::string ExecutableInfo::getFileName ( void ) const { - return executableName; + return executable.name().full(); } - const std::string& ExecutableInfo::getLibraryName( void ) const + const std::string ExecutableInfo::getLibraryName( void ) const { return libraryName; } @@ -83,9 +98,9 @@ namespace Coverage { } - SymbolTable* ExecutableInfo::getSymbolTable ( void ) const + SymbolTable* ExecutableInfo::getSymbolTable ( void ) { - return theSymbolTable; + return &theSymbolTable; } CoverageMapBase* ExecutableInfo::createCoverageMap ( @@ -95,8 +110,8 @@ namespace Coverage { uint32_t highAddress ) { - CoverageMapBase *theMap; - ExecutableInfo::coverageMaps_t::iterator itr; + CoverageMapBase *theMap; + ExecutableInfo::CoverageMaps::iterator itr; itr = coverageMaps.find( symbolName ); if ( itr == coverageMaps.end() ) { @@ -109,13 +124,26 @@ namespace Coverage { return theMap; } + void ExecutableInfo::getSourceAndLine( + const unsigned int address, + std::string& line + ) + { + std::string file; + int lno; + debug.get_source (address, file, lno); + std::ostringstream ss; + ss << file << ':' << lno; + line = ss.str (); + } + bool ExecutableInfo::hasDynamicLibrary( void ) { - return (libraryName != ""); + return !libraryName.empty(); } void ExecutableInfo::mergeCoverage( void ) { - ExecutableInfo::coverageMaps_t::iterator itr; + ExecutableInfo::CoverageMaps::iterator itr; for (itr = coverageMaps.begin(); itr != coverageMaps.end(); itr++) { SymbolsToAnalyze->mergeCoverageMap( (*itr).first, (*itr).second ); diff --git a/tester/covoar/ExecutableInfo.h b/tester/covoar/ExecutableInfo.h index 20ea9bf..9106db3 100644 --- a/tester/covoar/ExecutableInfo.h +++ b/tester/covoar/ExecutableInfo.h @@ -11,6 +11,10 @@ #include <stdint.h> #include <string> +#include <rld-dwarf.h> +#include <rld-files.h> +#include <rld-symbols.h> + #include "CoverageMapBase.h" #include "SymbolTable.h" @@ -67,14 +71,14 @@ namespace Coverage { * * @return Returns the executable's file name */ - const std::string& getFileName( void ) const; + const std::string getFileName( void ) const; /*! * This method returns the library name associated with the executable. * * @return Returns the executable's library name */ - const std::string& getLibraryName( void ) const; + const std::string getLibraryName( void ) const; /*! * This method returns the load address of the dynamic library @@ -88,7 +92,7 @@ namespace Coverage { * * @return Returns a pointer to the symbol table. */ - SymbolTable* getSymbolTable( void ) const; + SymbolTable* getSymbolTable( void ); /*! * This method creates a coverage map for the specified symbol. @@ -107,6 +111,15 @@ namespace Coverage { uint32_t highAddress ); + /*! + * This method gets the source location, the file and line number given an + * address. + */ + void getSourceAndLine( + const unsigned int address, + std::string& location + ); + /*! * This method indicates whether a dynamic library has been * associated with the executable. @@ -132,15 +145,25 @@ namespace Coverage { private: /*! - * This map associates a symbol with its coverage map. + * The ELF executable. */ - typedef std::map<std::string, CoverageMapBase *> coverageMaps_t; - coverageMaps_t coverageMaps; + rld::files::object executable; /*! - * This member variable contains the name of the executable. + * The DWARF data to the ELF executable. + */ + rld::dwarf::file debug; + + /*! + * The executable's symbol table. + */ + rld::symbols::table symbols; + + /*! + * This map associates a symbol with its coverage map. */ - std::string executableName; + typedef std::map<std::string, CoverageMapBase *> CoverageMaps; + CoverageMaps coverageMaps; /*! * This member variable contains the name of a dynamic library @@ -158,7 +181,7 @@ namespace Coverage { * This member variable contains a pointer to the symbol table * of the executable or library. */ - SymbolTable* theSymbolTable; + SymbolTable theSymbolTable; }; } diff --git a/tester/covoar/GcovData.cc b/tester/covoar/GcovData.cc index 6d10337..2c033e5 100644 --- a/tester/covoar/GcovData.cc +++ b/tester/covoar/GcovData.cc @@ -11,7 +11,6 @@ * reading *.gcno and writing *.gcda files for gcov support */ -#include <libgen.h> #include <stdio.h> #include <string.h> #include <stdlib.h> @@ -61,7 +60,7 @@ namespace Gcov { if ( (tempString == NULL) && (tempString2 == NULL) ){ fprintf(stderr, "ERROR: incorrect name of *.gcno file\n"); - } + } else { strcpy( tempString, ".gcda"); // construct gcda file name @@ -238,7 +237,7 @@ namespace Gcov { status = readFrameHeader( &header, gcovFile); if ( status <= 0 ){ - // Not printing error message because this + // Not printing error message because this // happenns at the end of each file return false; } @@ -260,11 +259,11 @@ namespace Gcov { status = fread( &intBuffer, 4, header.length, gcovFile ); if ( status != (int) header.length){ - fprintf( + fprintf( stderr, "Error while reading BLOCKS from gcov file...\n" - "Header lenght is %u instead of %u\n", - header.length, - status + "Header lenght is %u instead of %u\n", + header.length, + status ); return false; } @@ -478,15 +477,13 @@ namespace Gcov { void GcovData::writeGcovFile( ) { - char path[512]; - char command[512]; - - //fprintf (stderr, "Attempting to run gcov for: %s\n", cFileName ); - strcpy( path, cFileName ); - dirname( path ); - sprintf( command, "( cd %s && gcov %s &>> gcov.log)", path, basename( cFileName ) ); - //fprintf (stderr, "> %s\n", command ); - system( command ); + //std::cerr << "Attempting to run gcov for: " << cFileName << std::endl; + std::ostringstream command; + command << "( cd " << rld::path::dirname (cFileName) + << " && gcov " << rld::path::basename (cFileName) + << " &>> gcov.log)"; + //std::cerr << "> " << command << std::endl; + system( command.str ().c_str () ); } bool GcovData::processCounters( ) diff --git a/tester/covoar/covoar.cc b/tester/covoar/covoar.cc index c6b0589..9608bc3 100644 --- a/tester/covoar/covoar.cc +++ b/tester/covoar/covoar.cc @@ -186,7 +186,7 @@ int main( Coverage::ExecutableInfo* executableInfo = NULL; std::string executableExtension = "exe"; std::string coverageExtension = "cov"; - Coverage::CoverageFormats_t coverageFormat; + Coverage::CoverageFormats_t coverageFormat = Coverage::COVERAGE_FORMAT_QEMU; Coverage::CoverageReaderBase* coverageReader = NULL; char* executable = NULL; const char* explanations = NULL; diff --git a/tester/covoar/wscript b/tester/covoar/wscript index c0270d8..55d5ec9 100644 --- a/tester/covoar/wscript +++ b/tester/covoar/wscript @@ -70,7 +70,7 @@ def build(bld): # # The list of modules. # - modules = ['rld', 'elf', 'iberty'] + modules = ['rld', 'dwarf', 'elf', 'iberty'] bld.stlib(target = 'ccovoar', source = ['app_common.cc', -- 2.15.1 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel