Changeset 99c90b3 in rtems-tools


Ignore:
Timestamp:
Aug 5, 2018, 11:41:08 PM (16 months ago)
Author:
Chris Johns <chrisj@…>
Branches:
master
Children:
317d85d
Parents:
f450227
git-author:
Chris Johns <chrisj@…> (08/05/18 23:41:08)
git-committer:
Chris Johns <chrisj@…> (08/06/18 23:11:29)
Message:

tester/covoar: Integrate DWARF function data.

Use DAWRF function data to create the executable coverage
maps. Integrate the existing objdump processing with this
data.

  • Refactor CoverageMapBase? to have the address ranges and address info as separate objects. Move the to address info into a vector. Add support for multiple address ranges.
  • DesiredSymbols? is only interested in function symbols.
  • ExecutableInfo? creates coverage maps from DWARF function data.
  • Add warning flags to the covoar build.
  • Varous C++11 refactoring.
Location:
tester/covoar
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • tester/covoar/CoverageMapBase.cc

    rf450227 r99c90b3  
    1212#include <iomanip>
    1313
     14#include <rld.h>
     15
    1416#include "CoverageMapBase.h"
    1517
    1618namespace Coverage {
     19
     20  AddressInfo::AddressInfo ()
     21    : isStartOfInstruction (false),
     22      wasExecuted (false),
     23      isBranch (false),
     24      isNop (false),
     25      wasTaken (false),
     26      wasNotTaken (false)
     27  {
     28  }
     29
     30  AddressRange::AddressRange ()
     31    : lowAddress(0),
     32      highAddress(0)
     33  {
     34  }
     35
     36  AddressRange::AddressRange (const std::string& name,
     37                              uint32_t           lowAddress,
     38                              uint32_t           highAddress)
     39    : fileName (name),
     40      lowAddress (lowAddress),
     41      highAddress (highAddress)
     42  {
     43    info.resize( size( ) );
     44  }
     45
     46  size_t AddressRange::size () const
     47  {
     48    return highAddress - lowAddress + 1;
     49  }
     50
     51  bool AddressRange::inside (uint32_t address) const
     52  {
     53    return address >= lowAddress && address <= highAddress;
     54  }
     55
     56  AddressInfo& AddressRange::get (uint32_t address)
     57  {
     58    if ( !inside( address ) )
     59      throw rld::error( "address outside range", "AddressRange::get" );
     60    size_t slot = address - lowAddress;
     61    if (slot >= info.size ())
     62      throw rld::error( "address slot not found", "AddressRange::get" );
     63    return info[slot];
     64  }
     65
     66  const AddressInfo& AddressRange::get (uint32_t address) const
     67  {
     68    if ( !inside( address ) )
     69      throw rld::error( "address outside range", "AddressRange::get" );
     70    size_t slot = address - lowAddress;
     71    if (slot >= info.size ())
     72      throw rld::error( "address slot not found", "AddressRange::get" );
     73    return info[slot];
     74  }
     75
     76  void AddressRange::dump (std::ostream& out, bool show_slots) const
     77  {
     78    out << std::hex << std::setfill('0')
     79        << "Address range: low = " << std::setw(8) << lowAddress
     80        << " high = " << std::setw(8) << highAddress
     81        << std::endl;
     82    if (show_slots) {
     83      size_t slot = 0;
     84      for (auto& i : info) {
     85        out << std::hex << std::setfill('0')
     86            << "0x" << std::setw(8) << slot++ + lowAddress
     87            << "- isStartOfInstruction:"
     88            << (char*) (i.isStartOfInstruction ? "yes" : "no")
     89            << " wasExecuted:"
     90            << (char*) (i.wasExecuted ? "yes" : "no")
     91            << std::endl
     92            << "           isBranch:"
     93            << (char*) (i.isBranch ? "yes" : "no")
     94            << " wasTaken:"
     95            << (char*) (i.wasTaken ? "yes" : "no")
     96            << " wasNotTaken:"
     97            << (char*) (i.wasNotTaken ? "yes" : "no")
     98            << std::dec << std::setfill(' ')
     99            << std::endl;
     100      }
     101    }
     102  }
    17103
    18104  CoverageMapBase::CoverageMapBase(
     
    20106    uint32_t           low,
    21107    uint32_t           high
    22   )
    23   {
    24     uint32_t     a;
    25     AddressRange range;
    26 
    27     range.fileName    = exefileName;
    28     range.lowAddress  = low;
    29     range.highAddress = high;
    30     Ranges.push_back( range );
    31 
    32     Size = high - low + 1;
    33 
    34     Info = new perAddressInfo[ Size ];
    35 
    36     for (a = 0; a < Size; a++) {
    37 
    38       perAddressInfo *i = &Info[ a ];
    39 
    40       i->isStartOfInstruction = false;
    41       i->wasExecuted          = 0;
    42       i->isBranch             = false;
    43       i->isNop                = false;
    44       i->wasTaken             = 0;
    45       i->wasNotTaken          = 0;
    46     }
     108    ) : exefileName (exefileName)
     109  {
     110    Ranges.push_back( AddressRange( exefileName, low, high ) );
    47111  }
    48112
    49113  CoverageMapBase::~CoverageMapBase()
    50114  {
    51     if (Info)
    52       delete Info;
    53   }
    54 
    55   void  CoverageMapBase::Add( uint32_t low, uint32_t high )
    56   {
    57     AddressRange range;
    58 
    59     range.lowAddress  = low;
    60     range.highAddress = high;
    61     Ranges.push_back( range );
    62   }
    63 
    64   bool CoverageMapBase::determineOffset(
    65     uint32_t  address,
    66     uint32_t *offset
    67   )const
    68   {
    69     AddressRanges::const_iterator  itr;
    70 
    71     for ( auto& r : Ranges ) {
    72       if ((address >= r.lowAddress) && (address <= r.highAddress)){
    73         *offset = address - r.lowAddress;
     115  }
     116
     117  void CoverageMapBase::Add( uint32_t low, uint32_t high )
     118  {
     119    Ranges.push_back( AddressRange( exefileName, low, high ) );
     120  }
     121
     122  bool CoverageMapBase::validAddress( const uint32_t address ) const
     123  {
     124    for ( auto r : Ranges )
     125      if (r.inside( address ))
    74126        return true;
    75       }
    76     }
    77     *offset = 0;
    78127    return false;
    79128  }
    80129
    81 
    82130  void CoverageMapBase::dump( void ) const
    83131  {
    84     fprintf( stderr, "Coverage Map Contents:\n" );
    85     /*
    86      * XXX - Dump is only marking the first Address Range.
    87      */
    88     for (uint32_t a = 0; a < Size; a++) {
    89       perAddressInfo* entry = &Info[ a ];
    90       std::cerr << std::hex << std::setfill('0')
    91                 << "0x" << a + Ranges.front().lowAddress
    92                 << "- isStartOfInstruction:"
    93                 << (char*) (entry->isStartOfInstruction ? "yes" : "no")
    94                 << " wasExecuted:"
    95                 << (char*) (entry->wasExecuted ? "yes" : "no")
    96                 << std::endl
    97                 << "           isBranch:"
    98                 << (char*) (entry->isBranch ? "yes" : "no")
    99                 << " wasTaken:"
    100                 << (char*) (entry->wasTaken ? "yes" : "no")
    101                 << " wasNotTaken:"
    102                 << (char*) (entry->wasNotTaken ? "yes" : "no")
    103                 << std::dec << std::setfill(' ')
    104                 << std::endl;
    105     }
     132    std::cerr << "Coverage Map Contents:" << std::endl;
     133    for (auto& r : Ranges)
     134      r.dump( std::cerr );
     135  }
     136
     137  uint32_t CoverageMapBase::getSize() const
     138  {
     139    size_t size = 0;
     140    for (auto& r : Ranges)
     141      size += r.size ();
     142    return size;
    106143  }
    107144
     
    115152    AddressRange range;
    116153
    117 
    118     status = getRange( address, &range );
     154    status = getRange( address, range );
    119155    if ( status != true )
    120156      return status;
     
    123159
    124160    while (start >= range.lowAddress ) {
    125       if (Info[ start - range.lowAddress ].isStartOfInstruction) {
     161      if (isStartOfInstruction( start - range.lowAddress )) {
    126162        *beginning = start;
    127163        status = true;
     
    137173  int32_t CoverageMapBase::getFirstLowAddress() const
    138174  {
     175    /*
     176     * This is broken, do not trust it.
     177     */
    139178    return Ranges.front().lowAddress;
    140179  }
    141180
    142   bool CoverageMapBase::getRange( uint32_t address, AddressRange *range ) const
     181  bool CoverageMapBase::getRange( uint32_t address, AddressRange& range ) const
    143182  {
    144183    for ( auto r : Ranges ) {
    145       if ((address >= r.lowAddress) && (address <= r.highAddress)){
    146         range->lowAddress = r.lowAddress;
    147         range->highAddress = r.highAddress;
     184      if (r.inside( address )) {
     185        range.lowAddress = r.lowAddress;
     186        range.highAddress = r.highAddress;
     187        range.info = r.info;
    148188        return true;
    149189      }
    150190    }
    151 
    152     range->lowAddress  = 0;
    153     range->highAddress = 0;
    154 
    155191    return false;
    156 
    157   }
    158 
    159   uint32_t CoverageMapBase::getSize() const
    160   {
    161     return Size;
     192  }
     193
     194  AddressInfo& CoverageMapBase::getInfo( uint32_t address )
     195  {
     196    for ( auto& r : Ranges )
     197      if (r.inside( address ))
     198        return r.get( address );
     199    throw rld::error( "address out of bounds", "CoverageMapBase::getInfo" );
     200  }
     201
     202  const AddressInfo& CoverageMapBase::getInfo( uint32_t address ) const
     203  {
     204    for ( auto& r : Ranges )
     205      if (r.inside( address ))
     206        return r.get( address );
     207    throw rld::error( "address out of bounds", "CoverageMapBase::getInfo" );
    162208  }
    163209
     
    166212  )
    167213  {
    168     uint32_t offset;
    169 
    170     if (determineOffset( address, &offset ) != true)
     214    if ( validAddress( address ) )
     215      getInfo( address ).isStartOfInstruction = true;
     216  }
     217
     218  bool CoverageMapBase::isStartOfInstruction( uint32_t address ) const
     219  {
     220    if ( !validAddress( address ) )
     221      return false;
     222    return getInfo( address ).isStartOfInstruction;
     223  }
     224
     225  void CoverageMapBase::setWasExecuted( uint32_t address )
     226  {
     227    if ( validAddress( address ) )
     228      getInfo( address ).wasExecuted += 1;
     229  }
     230
     231  void CoverageMapBase::sumWasExecuted( uint32_t address, uint32_t addition)
     232  {
     233    if ( validAddress( address ) )
     234      getInfo( address ).wasExecuted += addition;
     235  }
     236
     237  bool CoverageMapBase::wasExecuted( uint32_t address ) const
     238  {
     239    bool result = false;
     240    if ( validAddress( address ) && (getInfo( address ).wasExecuted > 0))
     241      result = true;
     242    return result;
     243  }
     244
     245  uint32_t CoverageMapBase::getWasExecuted( uint32_t address ) const
     246  {
     247    if ( !validAddress( address ) )
     248      return 0;
     249    return getInfo( address ).wasExecuted;
     250  }
     251
     252  void CoverageMapBase::setIsBranch(
     253    uint32_t    address
     254  )
     255  {
     256    if ( validAddress( address ) )
     257      getInfo( address ).isBranch = true;
     258  }
     259
     260  bool CoverageMapBase::isNop( uint32_t address ) const
     261  {
     262    if ( !validAddress( address ) )
     263      return false;
     264    return getInfo( address ).isNop;
     265  }
     266
     267  void CoverageMapBase::setIsNop(
     268    uint32_t    address
     269  )
     270  {
     271    if ( !validAddress( address ) )
    171272      return;
    172 
    173     Info[ offset ].isStartOfInstruction = true;
    174   }
    175 
    176   bool CoverageMapBase::isStartOfInstruction( uint32_t address ) const
    177   {
    178     uint32_t offset;
    179 
    180     if (determineOffset( address, &offset ) != true)
    181       return false;
    182 
    183     return Info[ offset ].isStartOfInstruction;
    184   }
    185 
    186   void CoverageMapBase::setWasExecuted( uint32_t address )
    187   {
    188     uint32_t offset;
    189 
    190     if (determineOffset( address, &offset ) != true)
     273    getInfo( address ).isNop = true;
     274  }
     275
     276  bool CoverageMapBase::isBranch( uint32_t address ) const
     277  {
     278    if ( !validAddress( address ) )
     279      return false;
     280    return getInfo( address ).isBranch;
     281  }
     282
     283  void CoverageMapBase::setWasTaken(
     284    uint32_t    address
     285  )
     286  {
     287    if ( !validAddress( address ) )
    191288      return;
    192 
    193     Info[ offset ].wasExecuted += 1;
    194   }
    195 
    196   void CoverageMapBase::sumWasExecuted( uint32_t address, uint32_t addition)
    197   {
    198     uint32_t offset;
    199 
    200     if (determineOffset( address, &offset ) != true)
     289    getInfo( address ).wasTaken += 1;
     290  }
     291
     292  void CoverageMapBase::setWasNotTaken(
     293    uint32_t    address
     294  )
     295  {
     296    if ( !validAddress( address ) )
    201297      return;
    202 
    203     Info[ offset ].wasExecuted += addition;
    204   }
    205 
    206   bool CoverageMapBase::wasExecuted( uint32_t address ) const
    207   {
    208     uint32_t offset;
    209     bool     result;
    210 
    211     result = true;
    212 
    213     if (determineOffset( address, &offset ) != true)
     298    getInfo( address ).wasNotTaken += 1;
     299  }
     300
     301  bool CoverageMapBase::wasAlwaysTaken( uint32_t address ) const
     302  {
     303    if ( !validAddress( address ) )
     304      return false;
     305    const AddressInfo& info = getInfo( address );
     306    return info.wasTaken && !info.wasNotTaken;
     307  }
     308
     309  bool CoverageMapBase::wasNeverTaken( uint32_t address ) const
     310  {
     311    if ( !validAddress( address ) )
     312      return false;
     313    const AddressInfo& info = getInfo( address );
     314    return !info.wasTaken && info.wasNotTaken;
     315  }
     316
     317  bool CoverageMapBase::wasNotTaken( uint32_t address ) const
     318  {
     319    bool result = true;
     320    if ( !validAddress( address ) )
    214321      result = false;
    215 
    216     if (Info[ offset ].wasExecuted <= 0)
     322    else if ( getInfo( address ).wasNotTaken <= 0 )
    217323      result = false;
    218 
    219324    return result;
    220325  }
    221326
    222   uint32_t CoverageMapBase::getWasExecuted( uint32_t address ) const
    223   {
    224     uint32_t offset;
    225 
    226     if (determineOffset( address, &offset ) != true)
     327  void CoverageMapBase::sumWasNotTaken( uint32_t address, uint32_t addition)
     328  {
     329    if ( validAddress( address ) )
     330      getInfo( address ).wasNotTaken += addition;
     331  }
     332
     333  uint32_t CoverageMapBase::getWasNotTaken( uint32_t address ) const
     334  {
     335    if ( !validAddress( address ) )
    227336      return 0;
    228 
    229     return Info[ offset ].wasExecuted;
    230   }
    231 
    232   void CoverageMapBase::setIsBranch(
    233     uint32_t    address
    234   )
    235   {
    236     uint32_t offset;
    237 
    238     if (determineOffset( address, &offset ) != true)
     337    return getInfo( address ).wasNotTaken;
     338  }
     339
     340  bool CoverageMapBase::wasTaken( uint32_t address ) const
     341  {
     342    bool result = true;
     343    if ( !validAddress( address ) )
     344      result = false;
     345    else if ( getInfo( address ).wasTaken <= 0 )
     346      result = false;
     347    return result;
     348  }
     349
     350  void CoverageMapBase::sumWasTaken( uint32_t address, uint32_t addition)
     351  {
     352    if ( !validAddress( address ) )
    239353      return;
    240 
    241     Info[ offset ].isBranch = true;
    242   }
    243 
    244   bool CoverageMapBase::isNop( uint32_t address ) const
    245   {
    246     uint32_t offset;
    247 
    248     if (determineOffset( address, &offset ) != true)
    249       return false;
    250 
    251     return Info[ offset ].isNop;
    252   }
    253 
    254   void CoverageMapBase::setIsNop(
    255     uint32_t    address
    256   )
    257   {
    258     uint32_t offset;
    259 
    260     if (determineOffset( address, &offset ) != true)
    261       return;
    262 
    263     Info[ offset ].isNop = true;
    264   }
    265 
    266   bool CoverageMapBase::isBranch( uint32_t address ) const
    267   {
    268     uint32_t offset;
    269 
    270     if (determineOffset( address, &offset ) != true)
    271       return false;
    272 
    273     return Info[ offset ].isBranch;
    274   }
    275 
    276   void CoverageMapBase::setWasTaken(
    277     uint32_t    address
    278   )
    279   {
    280     uint32_t offset;
    281 
    282     if (determineOffset( address, &offset ) != true)
    283       return;
    284 
    285     Info[ offset ].wasTaken += 1;
    286   }
    287 
    288   void CoverageMapBase::setWasNotTaken(
    289     uint32_t    address
    290   )
    291   {
    292     uint32_t offset;
    293 
    294     if (determineOffset( address, &offset ) != true)
    295       return;
    296 
    297     Info[ offset ].wasNotTaken += 1;
    298   }
    299 
    300   bool CoverageMapBase::wasAlwaysTaken( uint32_t address ) const
    301   {
    302     uint32_t offset;
    303 
    304     if (determineOffset( address, &offset ) != true)
    305       return false;
    306 
    307     return (Info[ offset ].wasTaken &&
    308             !Info[ offset ].wasNotTaken);
    309   }
    310 
    311   bool CoverageMapBase::wasNeverTaken( uint32_t address ) const
    312   {
    313     uint32_t offset;
    314 
    315     if (determineOffset( address, &offset ) != true)
    316       return false;
    317 
    318     return (!Info[ offset ].wasTaken &&
    319             Info[ offset ].wasNotTaken);
    320   }
    321 
    322   bool CoverageMapBase::wasNotTaken( uint32_t address ) const
    323   {
    324             uint32_t offset;
    325             bool     result;
    326 
    327             result = true;
    328 
    329             if (determineOffset( address, &offset ) != true)
    330               result = false;
    331 
    332             if (Info[ offset ].wasNotTaken <= 0)
    333               result = false;
    334 
    335             return result;
    336   }
    337 
    338   void CoverageMapBase::sumWasNotTaken( uint32_t address, uint32_t addition)
    339   {
    340     uint32_t offset;
    341 
    342     if (determineOffset( address, &offset ) != true)
    343       return;
    344 
    345     Info[ offset ].wasNotTaken += addition;
    346   }
    347 
    348   uint32_t CoverageMapBase::getWasNotTaken( uint32_t address ) const
    349   {
    350     uint32_t offset;
    351 
    352     if (determineOffset( address, &offset ) != true)
     354    getInfo( address ).wasTaken += addition;
     355  }
     356
     357  uint32_t CoverageMapBase::getWasTaken( uint32_t address ) const
     358  {
     359    if ( !validAddress( address ) )
    353360      return 0;
    354 
    355     return Info[ offset ].wasNotTaken;
    356   }
    357 
    358   bool CoverageMapBase::wasTaken( uint32_t address ) const
    359   {
    360     uint32_t offset;
    361     bool     result;
    362 
    363     result = true;
    364 
    365     if (determineOffset( address, &offset ) != true)
    366       result = false;
    367 
    368     if (Info[ offset ].wasTaken <= 0)
    369       result = false;
    370 
    371     return result;
    372   }
    373 
    374   void CoverageMapBase::sumWasTaken( uint32_t address, uint32_t addition)
    375   {
    376     uint32_t offset;
    377 
    378     if (determineOffset( address, &offset ) != true)
    379       return;
    380 
    381     Info[ offset ].wasTaken += addition;
    382   }
    383 
    384   uint32_t CoverageMapBase::getWasTaken( uint32_t address ) const
    385   {
    386     uint32_t offset;
    387 
    388     if (determineOffset( address, &offset ) != true)
    389       return 0;
    390 
    391     return Info[ offset ].wasTaken;
     361    return getInfo( address ).wasTaken;
    392362  }
    393363}
  • tester/covoar/CoverageMapBase.h

    rf450227 r99c90b3  
    1010#include <stdint.h>
    1111#include <string>
     12#include <vector>
    1213#include <list>
    1314
    1415namespace Coverage {
     16
     17  /*!
     18   *  This structure defines the information that is gathered and
     19   *  tracked per address.
     20   */
     21  struct AddressInfo {
     22
     23    AddressInfo ();
     24
     25    /*!
     26     *  This member indicates that the address is the start of
     27     *  an instruction.
     28     */
     29    bool isStartOfInstruction;
     30    /*!
     31     *  This member indicates how many times the address was executed.
     32     */
     33    uint32_t wasExecuted;
     34    /*!
     35     *  This member indicates that the address is a branch instruction.
     36     */
     37    bool isBranch;
     38    /*!
     39     *  This member indicates that the address is a NOP instruction.
     40     */
     41    bool isNop;
     42    /*!
     43     *  When isBranch is TRUE, this member indicates that the branch
     44     *  instruction at the address was taken.
     45     */
     46    uint32_t wasTaken;
     47    /*!
     48     *  When isBranch is TRUE, this member indicates that the branch
     49     *  instruction at the address was NOT taken.
     50     */
     51    uint32_t wasNotTaken;
     52
     53  };
     54
     55  typedef std::vector < AddressInfo > AddressInfos;
     56
     57  /*!
     58   *  This structure identifies the low and high addresses
     59   *  of one range.  Note:: There may be more than one address
     60   *  range per symbol.
     61   */
     62  struct AddressRange {
     63
     64    AddressRange ();
     65    AddressRange (const std::string& name,
     66                  uint32_t           lowAddress,
     67                  uint32_t           highAddress);
     68
     69    size_t size () const;
     70
     71    bool inside (uint32_t address) const;
     72
     73    AddressInfo& get (uint32_t address);
     74    const AddressInfo& get (uint32_t address) const;
     75
     76    void dump (std::ostream& out, bool show_slots = false) const;
     77
     78    /*!
     79     *  This is the file from which this originated.
     80     */
     81    std::string fileName;
     82
     83    /*!
     84     *  This is the low address of the address map range.
     85     */
     86    uint32_t lowAddress;
     87
     88    /*!
     89     *  This is the high address of the address map range.
     90     */
     91    uint32_t highAddress;
     92
     93    /*!
     94     *  The address info for this range.
     95     */
     96    AddressInfos info;
     97
     98  };
     99
     100  /*
     101   *  This type identifies a list of ranges.
     102   */
     103  typedef std::vector< AddressRange >  AddressRanges;
    15104
    16105  /*! @class CoverageMapBase
     
    23112
    24113    /*!
    25      *  This structure identifies the low and high addresses
    26      *  of one range.  Note:: There may be more than one address
    27      *  range per symbol.
    28      */
    29     struct AddressRange {
    30       /*!
    31        *  This is the file from which this originated.
    32        */
    33       std::string fileName;
    34 
    35       /*!
    36        *  This is the low address of the address map range.
    37        */
    38       uint32_t lowAddress;
    39 
    40       /*!
    41        *  This is the high address of the address map range.
    42        */
    43       uint32_t highAddress;
    44 
    45     };
    46 
    47     /*
    48      *  This type identifies a list of ranges.
    49      */
    50     typedef std::list< AddressRange >  AddressRanges;
    51 
    52     /*!
    53114     *  This method constructs a CoverageMapBase instance.
    54115     *
     
    78139
    79140    /*!
    80      *  This method returns true and sets the offset if
    81      *  the address falls with the bounds of an address range
    82      *  in the RangeList.
    83      *
    84      *  @param[in]  address specifies the address to find
    85      *  @param[out] offset contains the offset from the low
    86      *              address of the address range.
    87      *
    88      *  @return Returns TRUE if the address range can be found
    89      *   and FALSE if it was not.
    90       */
    91     bool determineOffset( uint32_t address, uint32_t *offset ) const;
    92 
    93     /*!
    94141     *  This method prints the contents of the coverage map to stdout.
    95142     */
    96143    void dump( void ) const;
     144
     145    /*!
     146     *  Address valid?
     147     */
     148    bool validAddress( const uint32_t address ) const;
    97149
    98150    /*!
     
    117169     *   and FALSE if it was not.
    118170     */
    119     bool getRange( uint32_t address, AddressRange *range ) const;
     171    bool getRange( uint32_t address, AddressRange& range ) const;
    120172
    121173    /*!
     
    125177     */
    126178    uint32_t getSize() const;
    127 
    128179
    129180    /*!
     
    359410    bool wasTaken( uint32_t address ) const;
    360411
    361   protected:
    362 
    363     /*!
    364      *  This structure defines the information that is gathered and
    365      *  tracked per address.
    366      */
    367     struct perAddressInfo {
    368       /*!
    369        *  This member indicates that the address is the start of
    370        *  an instruction.
    371        */
    372       bool isStartOfInstruction;
    373       /*!
    374        *  This member indicates how many times the address was executed.
    375        */
    376       uint32_t wasExecuted;
    377       /*!
    378        *  This member indicates that the address is a branch instruction.
    379        */
    380       bool isBranch;
    381       /*!
    382        *  This member indicates that the address is a NOP instruction.
    383        */
    384       bool isNop;
    385       /*!
    386        *  When isBranch is TRUE, this member indicates that the branch
    387        *  instruction at the address was taken.
    388        */
    389       uint32_t wasTaken;
    390       /*!
    391        *  When isBranch is TRUE, this member indicates that the branch
    392        *  instruction at the address was NOT taken.
    393        */
    394       uint32_t wasNotTaken;
    395     };
     412  private:
     413
     414    /*!
     415     * The executable file name.
     416     */
     417    std::string exefileName;
    396418
    397419    /*!
     
    402424
    403425    /*!
    404      *
    405      *  This variable contains the size of the code block.
    406      */
    407     uint32_t Size;
    408 
    409     /*!
    410      *  This is a dynamically allocated array of data that is
    411      *  kept for each address.
    412      */
    413     perAddressInfo* Info;
     426     * Range checked access to the info.
     427     */
     428    AddressInfo& getInfo(uint32_t offset);
     429
     430    /*!
     431     * Constant range checked access to the info.
     432     */
     433    const AddressInfo& getInfo(uint32_t offset) const;
     434
    414435  };
    415436
  • tester/covoar/DesiredSymbols.cc

    rf450227 r99c90b3  
    9797      for (auto& kv : symbols.globals()) {
    9898        const rld::symbols::symbol& sym = *(kv.second);
    99         set[sym.name()] = *(new SymbolInformation);
     99        if (sym.type() == sym.st_func)
     100          set[sym.name()] = *(new SymbolInformation);
    100101      }
    101102      for (auto& kv : symbols.weaks()) {
    102103        const rld::symbols::symbol& sym = *(kv.second);
    103         set[sym.name()] = *(new SymbolInformation);
     104        if (sym.type() == sym.st_func)
     105          set[sym.name()] = *(new SymbolInformation);
    104106      }
    105107    } catch (...) {
     
    346348                  << symbolName
    347349                  << " with different sizes ("
    348                   << exefileName << '/' << itr->second.stats.sizeInBytes
    349                   << "!= "
    350                   << itr->second.sourceFile->getFileName() << '/' << size << ')'
     350                  << rld::path::basename(exefileName) << '/' << itr->second.stats.sizeInBytes
     351                  << " != "
     352                  << rld::path::basename(itr->second.sourceFile->getFileName())
     353                  << '/' << size << ')'
    351354                  << std::endl;
    352355
     
    451454  ) const
    452455  {
    453     if (set.find( symbolName ) == set.end()) {
    454       #if 0
    455         std::cerr << "Warning: Unable to find symbol " << symbolName
    456                   << std::endl;
    457       #endif
    458       return false;
    459     }
    460     return true;
     456    return set.find( symbolName ) == set.end() ? false : true;
    461457  }
    462458
     
    477473    }
    478474
     475    SymbolInformation& sinfo = itr->second;
     476
    479477    // Ensure that the source and destination coverage maps
    480478    // are the same size.
    481479    // Changed from ERROR msg to INFO, because size mismatch is not
    482480    // treated as error anymore. 2015-07-20
    483     uint32_t dMapSize = itr->second.stats.sizeInBytes;
     481    uint32_t dMapSize = sinfo.stats.sizeInBytes;
    484482    uint32_t sBaseAddress = sourceCoverageMap->getFirstLowAddress();
    485483    uint32_t sMapSize = sourceCoverageMap->getSize();
    486     if (dMapSize != sMapSize) {
     484    if (dMapSize != 0 && dMapSize != sMapSize) {
    487485      std::cerr << "INFO: DesiredSymbols::mergeCoverageMap - Unable to merge "
    488486                << "coverage map for " << symbolName
    489                 << " because the sizes are different"
     487                << " because the sizes are different ("
     488                << "size: " << dMapSize << ", source: " << sMapSize << ')'
    490489                << std::endl;
    491490      return;
     
    493492
    494493    // Merge the data for each address.
    495     CoverageMapBase* destinationCoverageMap = itr->second.unifiedCoverageMap;
     494    CoverageMapBase* destinationCoverageMap = sinfo.unifiedCoverageMap;
    496495
    497496    for (uint32_t dAddress = 0; dAddress < dMapSize; dAddress++) {
  • tester/covoar/ExecutableInfo.cc

    rf450227 r99c90b3  
    2020  ExecutableInfo::ExecutableInfo(
    2121    const char* const theExecutableName,
    22     const char* const theLibraryName
     22    const char* const theLibraryName,
     23    bool              verbose
    2324    ) : executable(theExecutableName),
    2425        loadAddress(0)
    2526  {
    26     if (theLibraryName)
     27    if (theLibraryName != nullptr)
    2728      libraryName = theLibraryName;
     29
     30    if (verbose) {
     31      std::cerr << "Loading executable " << theExecutableName;
     32      if (theLibraryName != nullptr)
     33        std::cerr << " (" << theLibraryName << ')';
     34      std::cerr << std::endl;
     35    }
    2836
    2937    executable.open();
     
    3341    debug.load_debug();
    3442    debug.load_functions();
     43
     44    for (auto& cu : debug.get_cus()) {
     45      for (auto& func : cu.get_functions()) {
     46        if (func.has_machine_code() && (!func.is_inlined() || func.is_external())) {
     47          createCoverageMap (cu.name(), func.name(),
     48                             func.pc_low(), func.pc_high());
     49        }
     50      }
     51    }
    3552  }
    3653
     
    96113  }
    97114
    98   CoverageMapBase* ExecutableInfo::createCoverageMap (
     115  CoverageMapBase& ExecutableInfo::findCoverageMap(
     116    const std::string& symbolName
     117  )
     118  {
     119    CoverageMaps::iterator cmi = coverageMaps.find( symbolName );
     120    if ( cmi == coverageMaps.end() )
     121      throw rld::error (symbolName, "ExecutableInfo::findCoverageMap");
     122    return *(cmi->second);
     123  }
     124
     125  void ExecutableInfo::createCoverageMap (
    99126    const std::string& fileName,
    100127    const std::string& symbolName,
     
    114141      theMap->Add( lowAddress, highAddress );
    115142    }
    116     return theMap;
    117143  }
    118144
     
    136162
    137163  void ExecutableInfo::mergeCoverage( void ) {
    138     ExecutableInfo::CoverageMaps::iterator  itr;
    139 
    140     for (itr = coverageMaps.begin(); itr != coverageMaps.end(); itr++) {
    141       SymbolsToAnalyze->mergeCoverageMap( (*itr).first, (*itr).second );
     164    for (auto& cm : coverageMaps) {
     165      if (SymbolsToAnalyze->isDesired( cm.first ))
     166        SymbolsToAnalyze->mergeCoverageMap( cm.first, cm.second );
    142167    }
    143168  }
  • tester/covoar/ExecutableInfo.h

    rf450227 r99c90b3  
    3838    ExecutableInfo(
    3939      const char* const theExecutableName,
    40       const char* const theLibraryName = NULL
     40      const char* const theLibraryName = NULL,
     41      bool              verbose = false
    4142    );
    4243
     
    9697
    9798    /*!
    98      *  This method creates a coverage map for the specified symbol.
     99     *  This method finds a coverage map for the specified symbol.
    99100     *
    100      *  @param[in] exefileName specifies the source of the information
    101101     *  @param[in] symbolName specifies the name of the symbol
    102      *  @param[in] lowAddress specifies the low address of the coverage map
    103      *  @param[in] highAddress specifies the high address of the coverage map
    104102     *
    105      *  @return Returns a pointer to the coverage map
     103     *  @return Returns a reference to the coverage map
    106104     */
    107     CoverageMapBase* createCoverageMap (
    108       const std::string& exefileName,
    109       const std::string& symbolName,
    110       uint32_t           lowAddress,
    111       uint32_t           highAddress
    112     );
     105    CoverageMapBase& findCoverageMap( const std::string& symbolName );
    113106
    114107    /*!
     
    144137
    145138  private:
     139
     140    /*!
     141     *  This method creates a coverage map for the specified symbol.
     142     *
     143     *  @param[in] exefileName specifies the source of the information
     144     *  @param[in] symbolName specifies the name of the symbol
     145     *  @param[in] lowAddress specifies the low address of the coverage map
     146     *  @param[in] highAddress specifies the high address of the coverage map
     147     */
     148    void createCoverageMap (
     149      const std::string& exefileName,
     150      const std::string& symbolName,
     151      uint32_t           lowAddress,
     152      uint32_t           highAddress
     153    );
    146154
    147155    /*!
  • tester/covoar/ObjdumpProcessor.cc

    rf450227 r99c90b3  
    3030    ExecutableInfo* const            executableInfo,
    3131    std::string&                     symbolName,
    32     uint32_t                         lowAddress,
    33     uint32_t                         highAddress,
    3432    ObjdumpProcessor::objdumpLines_t instructions
    3533  ) {
    36 
    37     CoverageMapBase*                                   aCoverageMap = NULL;
    38     uint32_t                                           endAddress = highAddress;
    39     ObjdumpProcessor::objdumpLines_t::iterator         itr, fnop, lnop;
    40     ObjdumpProcessor::objdumpLines_t::reverse_iterator ritr;
    41     SymbolInformation*                                 symbolInfo = NULL;
    42     SymbolTable*                                       theSymbolTable;
    43 
    44     //
    45     // Remove trailing nop instructions.
    46     //
    47 
    48     // First find the last instruction.
    49     for (ritr = instructions.rbegin();
    50          ritr != instructions.rend();
    51          ritr++) {
    52       if (ritr->isInstruction)
    53         break;
    54     }
    55 
    56     // If an instruction was found and it is a nop, ...
    57     if ((ritr != instructions.rend()) && (ritr->isNop)) {
    58 
    59       // save it as the last nop.  Note that we must account for
    60       // the difference between a forward and a reverse iterator.
    61       lnop = ritr.base();
    62       lnop--;
    63       endAddress -= lnop->nopSize;
    64 
    65       // Now look for the first nop in the sequence of trailing nops.
    66       fnop = lnop;
    67       ritr++;
    68       for (; ritr != instructions.rend(); ritr++) {
    69         if (ritr->isNop) {
    70           fnop = ritr.base();
    71           fnop--;
    72           endAddress -= fnop->nopSize;
    73         }
    74         else
    75           break;
    76       }
    77 
    78       // Erase trailing nops.  The erase operation wants the first
    79       // parameter to point to the first item to erase and the second
    80       // parameter to point to the item beyond the last item to erase.
    81       if ( fnop == lnop )
    82         instructions.erase( fnop );
    83       else
    84         instructions.erase( fnop, ++lnop );
    85     }
     34    // Find the symbol's coverage map.
     35    CoverageMapBase& coverageMap = executableInfo->findCoverageMap( symbolName );
     36
     37    uint32_t lowAddress = coverageMap.getFirstLowAddress();
     38    uint32_t size = coverageMap.getSize();
     39    uint32_t highAddress = lowAddress + size;
    8640
    8741    // If there are NOT already saved instructions, save them.
    88     symbolInfo = SymbolsToAnalyze->find( symbolName );
     42    SymbolInformation* symbolInfo = SymbolsToAnalyze->find( symbolName );
    8943    if (symbolInfo->instructions.empty()) {
    9044      symbolInfo->sourceFile = executableInfo;
     
    9448
    9549    // Add the symbol to this executable's symbol table.
    96     theSymbolTable = executableInfo->getSymbolTable();
     50    SymbolTable* theSymbolTable = executableInfo->getSymbolTable();
    9751    theSymbolTable->addSymbol(
    98       symbolName, lowAddress, endAddress - lowAddress + 1
     52      symbolName, lowAddress, highAddress - lowAddress + 1
    9953    );
    10054
    101     // Create a coverage map for the symbol.
    102     aCoverageMap = executableInfo->createCoverageMap(
    103       executableInfo->getFileName().c_str(), symbolName, lowAddress, endAddress
     55    // Mark the start of each instruction in the coverage map.
     56    for (auto& instruction : instructions) {
     57      coverageMap.setIsStartOfInstruction( instruction.address );
     58    }
     59
     60    // Create a unified coverage map for the symbol.
     61    SymbolsToAnalyze->createCoverageMap(
     62      executableInfo->getFileName().c_str(), symbolName, size
    10463    );
    105 
    106     if (aCoverageMap) {
    107 
    108       // Mark the start of each instruction in the coverage map.
    109       for (itr = instructions.begin();
    110            itr != instructions.end();
    111            itr++ ) {
    112 
    113         aCoverageMap->setIsStartOfInstruction( itr->address );
    114       }
    115 
    116       // Create a unified coverage map for the symbol.
    117       SymbolsToAnalyze->createCoverageMap(
    118         executableInfo->getFileName().c_str(), symbolName,
    119         endAddress - lowAddress + 1
    120       );
    121     }
    12264  }
    12365
     
    354296
    355297    while ( true ) {
    356 
    357298      // Get the line.
    358299      objdumpFile.read_line( line );
    359300      if ( line.empty() ) {
    360 
    361301        // If we are currently processing a symbol, finalize it.
    362302        if (processSymbol) {
     
    364304            executableInformation,
    365305            currentSymbol,
    366             startAddress,
    367             executableInformation->getLoadAddress() + offset,
    368306            theInstructions
    369307          );
     
    389327      lineInfo.isBranch      = false;
    390328
     329      instruction[0] = '\0';
     330      ID[0] = '\0';
     331
    391332      // Look for the start of a symbol's objdump and extract
    392333      // offset and symbol (i.e. offset <symbolname>:).
     
    408349      // If all items found, we are at the beginning of a symbol's objdump.
    409350      if ((items == 3) && (terminator1 == ':')) {
    410 
    411351        endAddress = executableInformation->getLoadAddress() + offset - 1;
    412352
     
    416356            executableInformation,
    417357            currentSymbol,
    418             startAddress,
    419             endAddress,
    420358            theInstructions
    421359          );
     
    442380               && processSymbol )
    443381      {
    444 
    445           endAddress = executableInformation->getLoadAddress() + offset - 1;
    446 
    447           // If we are currently processing a symbol, finalize it.
    448           if ( processSymbol ) {
    449             finalizeSymbol(
    450               executableInformation,
    451               currentSymbol,
    452               startAddress,
    453               endAddress,
    454               theInstructions
     382        endAddress = executableInformation->getLoadAddress() + offset - 1;
     383
     384        // If we are currently processing a symbol, finalize it.
     385        if ( processSymbol ) {
     386          finalizeSymbol(
     387            executableInformation,
     388            currentSymbol,
     389            theInstructions
    455390            );
    456           }
    457           processSymbol = false;
     391        }
     392        processSymbol = false;
    458393      }
    459394      else if (processSymbol) {
     
    468403        // If it looks like an instruction ...
    469404        if ((items == 3) && (terminator1 == ':') && (terminator2 == '\t')) {
    470 
    471405          // update the line's information, save it and ...
    472406          lineInfo.address =
  • tester/covoar/covoar.cc

    rf450227 r99c90b3  
    248248        if (dynamicLibrary) {
    249249          executableInfo = new Coverage::ExecutableInfo(
    250             singleExecutable, dynamicLibrary
     250            singleExecutable, dynamicLibrary, Verbose
    251251          );
    252252        } else {
    253           executableInfo = new Coverage::ExecutableInfo( singleExecutable );
     253          executableInfo = new Coverage::ExecutableInfo(
     254            singleExecutable, nullptr, Verbose
     255          );
    254256        }
    255257
     
    273275                    << std::endl;
    274276        } else {
    275           executableInfo = new Coverage::ExecutableInfo( argv[i] );
     277          executableInfo = new Coverage::ExecutableInfo(
     278            argv[i], nullptr, Verbose
     279          );
    276280          executablesToAnalyze.push_back( executableInfo );
    277281          coverageFileNames.push_back( coverageFileName );
     
    574578  catch (std::exception e)
    575579  {
    576     int   status;
    577     char* realname;
    578     realname = abi::__cxa_demangle (e.what(), 0, 0, &status);
    579     std::cerr << "error: exception: " << realname << " [";
    580     ::free (realname);
    581     const std::type_info &ti = typeid (e);
    582     realname = abi::__cxa_demangle (ti.name(), 0, 0, &status);
    583     std::cerr << realname << "] " << e.what () << std::endl << std::flush;
    584     ::free (realname);
     580    rld::output_std_exception(e, std::cerr);
    585581    ec = 11;
    586582  }
  • tester/covoar/wscript

    rf450227 r99c90b3  
    107107                        'Target_powerpc.cc',
    108108                        'Target_sparc.cc'],
    109               cflags = ['-O2', '-g'],
    110               cxxflags = ['-std=c++11', '-O2', '-g'],
     109              cflags = ['-O2', '-g', '-Wall'],
     110              cxxflags = ['-std=c++11', '-O2', '-g', '-Wall'],
    111111              includes = ['.'] + rtl_includes)
    112112
Note: See TracChangeset for help on using the changeset viewer.