Changeset fb987e8 in rtems-tools


Ignore:
Timestamp:
May 8, 2018, 5:09:39 AM (12 months ago)
Author:
Chris Johns <chrisj@…>
Branches:
master
Children:
efbf8f0
Parents:
558cab8
git-author:
Chris Johns <chrisj@…> (05/08/18 05:09:39)
git-committer:
Chris Johns <chrisj@…> (06/15/18 05:54:25)
Message:

covoar: Use DWARF to map addresses to source files and lines.

Location:
tester/covoar
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • tester/covoar/CoverageMapBase.cc

    r558cab8 rfb987e8  
    33 *  @brief CoverageMapBase Implementation
    44 *
    5  *  This file contains the implementation of the functions 
     5 *  This file contains the implementation of the functions
    66 *  which provide a base level of functionality of a CoverageMap.
    77 */
    88
    9 #include <libgen.h>
    109#include <limits.h>
    1110#include <stdio.h>
     
    5251      delete Info;
    5352  }
    54  
     53
    5554  void  CoverageMapBase::Add( uint32_t low, uint32_t high )
    5655  {
     
    6160    RangeList.push_back( range );
    6261  }
    63  
    64   bool CoverageMapBase::determineOffset( 
    65     uint32_t  address, 
     62
     63  bool CoverageMapBase::determineOffset(
     64    uint32_t  address,
    6665    uint32_t *offset
    6766  )const
     
    175174  {
    176175    uint32_t offset;
    177  
     176
    178177    if (determineOffset( address, &offset ) != true)
    179178      return;
     
    185184  {
    186185    uint32_t offset;
    187  
     186
    188187    if (determineOffset( address, &offset ) != true)
    189188      return false;
     
    195194  {
    196195    uint32_t offset;
    197  
     196
    198197    if (determineOffset( address, &offset ) != true)
    199198      return;
     
    205204  {
    206205    uint32_t offset;
    207  
     206
    208207    if (determineOffset( address, &offset ) != true)
    209208      return;
     
    216215    uint32_t offset;
    217216    bool     result;
    218  
     217
    219218    result = true;
    220219
     
    235234      return 0;
    236235
    237     return Info[ offset ].wasExecuted; 
     236    return Info[ offset ].wasExecuted;
    238237  }
    239238
     
    243242  {
    244243    uint32_t offset;
    245  
     244
    246245    if (determineOffset( address, &offset ) != true)
    247246      return;
     
    253252  {
    254253    uint32_t offset;
    255  
     254
    256255    if (determineOffset( address, &offset ) != true)
    257256      return false;
     
    265264  {
    266265    uint32_t offset;
    267  
     266
    268267    if (determineOffset( address, &offset ) != true)
    269268      return;
     
    275274  {
    276275    uint32_t offset;
    277  
     276
    278277    if (determineOffset( address, &offset ) != true)
    279278      return false;
     
    287286  {
    288287    uint32_t offset;
    289  
     288
    290289    if (determineOffset( address, &offset ) != true)
    291290      return;
     
    299298  {
    300299    uint32_t offset;
    301  
     300
    302301    if (determineOffset( address, &offset ) != true)
    303302      return;
     
    309308  {
    310309    uint32_t offset;
    311  
     310
    312311    if (determineOffset( address, &offset ) != true)
    313312      return false;
     
    320319  {
    321320    uint32_t offset;
    322  
     321
    323322    if (determineOffset( address, &offset ) != true)
    324323      return false;
     
    370369
    371370    result = true;
    372  
     371
    373372    if (determineOffset( address, &offset ) != true)
    374373      result = false;
  • tester/covoar/DesiredSymbols.cc

    r558cab8 rfb987e8  
    1010#endif
    1111
    12 #include <libgen.h>
    1312#include <limits.h>
    1413#include <stdio.h>
     
    446445  )
    447446  {
    448     char*                              base;
    449     char*                              cStatus;
    450     char                               command[512];
    451     std::string                        fileName;
    452     CoverageRanges::ranges_t::iterator ritr;
    453     char                               rpath[PATH_MAX];
    454     FILE*                              tmpfile;
    455 
    456     // Open a temporary file for the uncovered ranges.
    457     tmpfile = fopen( "ranges1.tmp", "w" );
    458     if ( !tmpfile ) {
    459       fprintf(
    460         stderr,
    461         "ERROR: DesiredSymbols::determineSourceLines - "
    462         "unable to open %s\n",
    463         "ranges1.tmp"
    464       );
    465       exit(-1);
    466     }
    467 
    468     // Write the range addresses to the temporary file.
    469     for (ritr =  theRanges->set.begin();
    470          ritr != theRanges->set.end();
    471          ritr++ ) {
    472       fprintf(
    473         tmpfile,
    474         "0x%08x\n0x%08x\n",
    475         ritr->lowAddress - theExecutable->getLoadAddress(),
    476         ritr->highAddress - theExecutable->getLoadAddress()
    477       );
    478     }
    479 
    480     fclose( tmpfile );
    481 
    482     // Invoke addr2line to generate the source lines for each address.
    483     if (theExecutable->hasDynamicLibrary())
    484       fileName = theExecutable->getLibraryName();
    485     else
    486       fileName = theExecutable->getFileName();
    487 
    488     sprintf(
    489       command,
    490       "%s -Ce %s <%s | dos2unix >%s",
    491       TargetInfo->getAddr2line(),
    492       fileName.c_str(),
    493       "ranges1.tmp",
    494       "ranges2.tmp"
    495     );
    496 
    497     if (system( command )) {
    498       fprintf(
    499         stderr,
    500         "ERROR: DesiredSymbols::determineSourceLines - "
    501         "command (%s) failed\n",
    502         command
    503       );
    504       exit( -1 );
    505     }
    506 
    507     // Open the addr2line output file.
    508     tmpfile = fopen( "ranges2.tmp", "r" );
    509     if ( !tmpfile ) {
    510       fprintf(
    511         stderr,
    512         "ERROR: DesiredSymbols::determineSourceLines - "
    513         "unable to open %s\n",
    514         "ranges2.tmp"
    515       );
    516       exit(-1);
    517     }
    518 
    519     // Process the addr2line output.
    520     for (ritr =  theRanges->set.begin();
    521          ritr != theRanges->set.end();
    522          ritr++ ) {
    523 
    524       cStatus = fgets( inputBuffer, MAX_LINE_LENGTH, tmpfile );
    525       if ( cStatus == NULL ) {
    526         fprintf(
    527           stderr,
    528           "ERROR: DesiredSymbols::determineSourceLines - "
    529           "Out of sync in addr2line output\n"
    530         );
    531         exit( -1 );
    532       }
    533       inputBuffer[ strlen(inputBuffer) - 1] = '\0';
    534 
    535       // Use only the base filename without directory path.
    536 #ifdef _WIN32
    537       #define realpath(N,R) _fullpath((R),(N),_MAX_PATH)
    538 #endif
    539       realpath( inputBuffer, rpath );
    540       base = basename( rpath );
    541 
    542       ritr->lowSourceLine = std::string( base );
    543 
    544       cStatus = fgets( inputBuffer, MAX_LINE_LENGTH, tmpfile );
    545       if ( cStatus == NULL ) {
    546         fprintf(
    547           stderr,
    548           "ERROR: DesiredSymbols::determineSourceLines - "
    549           "Out of sync in addr2line output\n"
    550         );
    551         exit( -1 );
    552       }
    553       inputBuffer[ strlen(inputBuffer) - 1] = '\0';
    554 
    555       // Use only the base filename without directory path.
    556       realpath( inputBuffer, rpath );
    557       base = basename( rpath );
    558 
    559       ritr->highSourceLine = std::string( base );
    560     }
    561 
    562     fclose( tmpfile );
    563     unlink( "ranges1.tmp" );
    564     unlink( "ranges2.tmp" );
     447    for (auto& r : theRanges->set) {
     448      std::string location;
     449      theExecutable->getSourceAndLine(r.lowAddress, location);
     450      r.lowSourceLine = rld::path::basename (location);
     451      theExecutable->getSourceAndLine(r.highAddress, location);
     452      r.highSourceLine = rld::path::basename (location);
     453    }
    565454  }
    566455
  • tester/covoar/ExecutableInfo.cc

    r558cab8 rfb987e8  
    77
    88#include <stdio.h>
     9
     10#include <rld.h>
    911
    1012#include "ExecutableInfo.h"
     
    1921    const char* const theExecutableName,
    2022    const char* const theLibraryName
    21   )
     23    ) : executable(theExecutableName),
     24        loadAddress(0)
    2225  {
    23     executableName = theExecutableName;
    24     loadAddress = 0;
    25     libraryName = "";
    2626    if (theLibraryName)
    2727      libraryName = theLibraryName;
    28     theSymbolTable = new SymbolTable();
     28    try {
     29      executable.open();
     30      executable.begin();
     31      executable.load_symbols(symbols);
     32      debug.begin(executable.elf());
     33      debug.load_debug();
     34    } catch (rld::error re) {
     35      std::cerr << "error: "
     36                << re.where << ": " << re.what
     37                << std::endl;
     38      exit(2);
     39    } catch (...) {
     40      exit(2);
     41    }
    2942  }
    3043
    3144  ExecutableInfo::~ExecutableInfo()
    3245  {
    33     if (theSymbolTable)
    34       delete theSymbolTable;
     46    debug.end();
     47    executable.end();
     48    executable.close();
    3549  }
    3650
    3751  void ExecutableInfo::dumpCoverageMaps( void ) {
    38     ExecutableInfo::coverageMaps_t::iterator  itr;
     52    ExecutableInfo::CoverageMaps::iterator  itr;
    3953
    4054    for (itr = coverageMaps.begin(); itr != coverageMaps.end(); itr++) {
     
    4559
    4660  void ExecutableInfo::dumpExecutableInfo( void ){
    47     fprintf( stdout, "\n== Executable info ==\n");
    48     fprintf( stdout, "executableName = %s\n", executableName.c_str());
    49     fprintf( stdout, "libraryName = %s\n", libraryName.c_str());
    50     fprintf( stdout, "loadAddress = %u\n", loadAddress);
    51     theSymbolTable->dumpSymbolTable();
     61    std::cout << std::endl
     62              << "== Executable info ==" << std::endl
     63              << "executable = " << getFileName () << std::endl
     64              << "library = " << libraryName << std::endl
     65              << "loadAddress = " << loadAddress << std::endl;
     66    theSymbolTable.dumpSymbolTable();
    5267  }
    5368
    5469  CoverageMapBase* ExecutableInfo::getCoverageMap ( uint32_t address )
    5570  {
    56     CoverageMapBase*         aCoverageMap = NULL;
    57     coverageMaps_t::iterator it;
    58     std::string              itsSymbol;
     71    CoverageMapBase*       aCoverageMap = NULL;
     72    CoverageMaps::iterator it;
     73    std::string            itsSymbol;
    5974
    6075    // Obtain the coverage map containing the specified address.
    61     itsSymbol = theSymbolTable->getSymbol( address );
     76    itsSymbol = theSymbolTable.getSymbol( address );
    6277    if (itsSymbol != "") {
    6378      it = coverageMaps.find( itsSymbol );
     
    6883  }
    6984
    70   const std::string& ExecutableInfo::getFileName ( void ) const
     85  const std::string ExecutableInfo::getFileName ( void ) const
    7186  {
    72     return executableName;
     87    return executable.name().full();
    7388  }
    7489
    75   const std::string& ExecutableInfo::getLibraryName( void ) const
     90  const std::string ExecutableInfo::getLibraryName( void ) const
    7691  {
    7792    return libraryName;
     
    8499
    85100
    86   SymbolTable* ExecutableInfo::getSymbolTable ( void ) const
     101  SymbolTable* ExecutableInfo::getSymbolTable ( void )
    87102  {
    88     return theSymbolTable;
     103    return &theSymbolTable;
    89104  }
    90105
     
    96111  )
    97112  {
    98     CoverageMapBase                          *theMap;
    99     ExecutableInfo::coverageMaps_t::iterator  itr;
     113    CoverageMapBase                        *theMap;
     114    ExecutableInfo::CoverageMaps::iterator  itr;
    100115
    101116    itr = coverageMaps.find( symbolName );
     
    110125  }
    111126
     127  void ExecutableInfo::getSourceAndLine(
     128    const unsigned int address,
     129    std::string&       line
     130  )
     131  {
     132    std::string file;
     133    int         lno;
     134    debug.get_source (address, file, lno);
     135    std::ostringstream ss;
     136    ss << file << ':' << lno;
     137    line = ss.str ();
     138  }
     139
    112140  bool ExecutableInfo::hasDynamicLibrary( void )
    113141  {
    114      return (libraryName != "");
     142    return !libraryName.empty();
    115143  }
    116144
    117145  void ExecutableInfo::mergeCoverage( void ) {
    118     ExecutableInfo::coverageMaps_t::iterator  itr;
     146    ExecutableInfo::CoverageMaps::iterator  itr;
    119147
    120148    for (itr = coverageMaps.begin(); itr != coverageMaps.end(); itr++) {
  • tester/covoar/ExecutableInfo.h

    r558cab8 rfb987e8  
    1111#include <stdint.h>
    1212#include <string>
     13
     14#include <rld-dwarf.h>
     15#include <rld-files.h>
     16#include <rld-symbols.h>
    1317
    1418#include "CoverageMapBase.h"
     
    6872     *  @return Returns the executable's file name
    6973     */
    70     const std::string& getFileName( void ) const;
     74    const std::string getFileName( void ) const;
    7175
    7276    /*!
     
    7579     *  @return Returns the executable's library name
    7680     */
    77     const std::string& getLibraryName( void ) const;
     81    const std::string getLibraryName( void ) const;
    7882
    7983    /*!
     
    8993     *  @return Returns a pointer to the symbol table.
    9094     */
    91     SymbolTable* getSymbolTable( void ) const;
     95    SymbolTable* getSymbolTable( void );
    9296
    9397    /*!
     
    106110      uint32_t           lowAddress,
    107111      uint32_t           highAddress
     112    );
     113
     114    /*!
     115     *  This method gets the source location, the file and line number given an
     116     *  address.
     117     */
     118    void getSourceAndLine(
     119      const unsigned int address,
     120      std::string&       location
    108121    );
    109122
     
    133146
    134147    /*!
     148     *  The ELF executable.
     149     */
     150    rld::files::object executable;
     151
     152    /*!
     153     *  The DWARF data to the ELF executable.
     154     */
     155    rld::dwarf::file debug;
     156
     157    /*!
     158     *  The executable's symbol table.
     159     */
     160    rld::symbols::table symbols;
     161
     162    /*!
    135163     *  This map associates a symbol with its coverage map.
    136164     */
    137     typedef std::map<std::string, CoverageMapBase *> coverageMaps_t;
    138     coverageMaps_t coverageMaps;
    139 
    140     /*!
    141      *  This member variable contains the name of the executable.
    142      */
    143     std::string executableName;
     165    typedef std::map<std::string, CoverageMapBase *> CoverageMaps;
     166    CoverageMaps coverageMaps;
    144167
    145168    /*!
     
    159182     *  of the executable or library.
    160183     */
    161     SymbolTable* theSymbolTable;
     184    SymbolTable theSymbolTable;
    162185
    163186  };
  • tester/covoar/GcovData.cc

    r558cab8 rfb987e8  
    1212 */
    1313
    14 #include <libgen.h>
    1514#include <stdio.h>
    1615#include <string.h>
     
    6261    if ( (tempString == NULL) && (tempString2 == NULL) ){
    6362      fprintf(stderr, "ERROR: incorrect name of *.gcno file\n");
    64     } 
     63    }
    6564    else
    6665    {
     
    239238
    240239            if ( status <= 0 ){
    241                 // Not printing error message because this 
     240                // Not printing error message because this
    242241                // happenns at the end of each file
    243242                return false;
     
    261260                                status = fread( &intBuffer, 4, header.length, gcovFile );
    262261                                if ( status != (int) header.length){
    263                                         fprintf( 
     262                                        fprintf(
    264263                                                stderr, "Error while reading BLOCKS from gcov file...\n"
    265                                                 "Header lenght is %u instead of %u\n", 
    266                                                 header.length, 
    267                                                 status 
     264                                                "Header lenght is %u instead of %u\n",
     265                                                header.length,
     266                                                status
    268267                                        );
    269268                                        return false;
     
    479478  void GcovData::writeGcovFile( )
    480479  {
    481     char        path[512];
    482     char        command[512];
    483 
    484     //fprintf (stderr, "Attempting to run gcov for: %s\n", cFileName );
    485     strcpy( path, cFileName );
    486     dirname( path );
    487     sprintf( command, "( cd %s && gcov %s &>> gcov.log)", path, basename( cFileName ) );
    488     //fprintf (stderr, "> %s\n", command );
    489     system( command );
     480    //std::cerr << "Attempting to run gcov for: " << cFileName << std::endl;
     481    std::ostringstream command;
     482    command << "( cd " << rld::path::dirname (cFileName)
     483            << " && gcov " << rld::path::basename (cFileName)
     484            << " &>> gcov.log)";
     485    //std::cerr << "> " << command << std::endl;
     486    system( command.str ().c_str () );
    490487  }
    491488
  • tester/covoar/covoar.cc

    r558cab8 rfb987e8  
    187187  std::string                   executableExtension = "exe";
    188188  std::string                   coverageExtension = "cov";
    189   Coverage::CoverageFormats_t   coverageFormat;
     189  Coverage::CoverageFormats_t   coverageFormat = Coverage::COVERAGE_FORMAT_QEMU;
    190190  Coverage::CoverageReaderBase* coverageReader = NULL;
    191191  char*                         executable = NULL;
  • tester/covoar/wscript

    r558cab8 rfb987e8  
    7171    # The list of modules.
    7272    #
    73     modules = ['rld', 'elf', 'iberty']
     73    modules = ['rld', 'dwarf', 'elf', 'iberty']
    7474
    7575    bld.stlib(target = 'ccovoar',
Note: See TracChangeset for help on using the changeset viewer.