diff options
author | Chris Johns <chrisj@rtems.org> | 2018-08-06 09:41:08 +1000 |
---|---|---|
committer | Chris Johns <chrisj@rtems.org> | 2018-08-07 09:11:29 +1000 |
commit | 99c90b3353bf5b638dcfd87803e4aaf02adf3219 (patch) | |
tree | 06261fff19936db1f0db82383d02ba9eb2e75ed8 /tester/covoar/CoverageMapBase.cc | |
parent | linkers/exeinfo: Add an inlines report and DWARF data dump. (diff) | |
download | rtems-tools-99c90b3353bf5b638dcfd87803e4aaf02adf3219.tar.bz2 |
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.
Diffstat (limited to 'tester/covoar/CoverageMapBase.cc')
-rw-r--r-- | tester/covoar/CoverageMapBase.cc | 372 |
1 files changed, 171 insertions, 201 deletions
diff --git a/tester/covoar/CoverageMapBase.cc b/tester/covoar/CoverageMapBase.cc index 87c8e8f..ad0080d 100644 --- a/tester/covoar/CoverageMapBase.cc +++ b/tester/covoar/CoverageMapBase.cc @@ -11,98 +11,135 @@ #include <iostream> #include <iomanip> +#include <rld.h> + #include "CoverageMapBase.h" namespace Coverage { - CoverageMapBase::CoverageMapBase( - const std::string& exefileName, - uint32_t low, - uint32_t high - ) + AddressInfo::AddressInfo () + : isStartOfInstruction (false), + wasExecuted (false), + isBranch (false), + isNop (false), + wasTaken (false), + wasNotTaken (false) { - uint32_t a; - AddressRange range; + } - range.fileName = exefileName; - range.lowAddress = low; - range.highAddress = high; - Ranges.push_back( range ); + AddressRange::AddressRange () + : lowAddress(0), + highAddress(0) + { + } - Size = high - low + 1; + AddressRange::AddressRange (const std::string& name, + uint32_t lowAddress, + uint32_t highAddress) + : fileName (name), + lowAddress (lowAddress), + highAddress (highAddress) + { + info.resize( size( ) ); + } - Info = new perAddressInfo[ Size ]; + size_t AddressRange::size () const + { + return highAddress - lowAddress + 1; + } - for (a = 0; a < Size; a++) { + bool AddressRange::inside (uint32_t address) const + { + return address >= lowAddress && address <= highAddress; + } - perAddressInfo *i = &Info[ a ]; + AddressInfo& AddressRange::get (uint32_t address) + { + if ( !inside( address ) ) + throw rld::error( "address outside range", "AddressRange::get" ); + size_t slot = address - lowAddress; + if (slot >= info.size ()) + throw rld::error( "address slot not found", "AddressRange::get" ); + return info[slot]; + } - i->isStartOfInstruction = false; - i->wasExecuted = 0; - i->isBranch = false; - i->isNop = false; - i->wasTaken = 0; - i->wasNotTaken = 0; - } + const AddressInfo& AddressRange::get (uint32_t address) const + { + if ( !inside( address ) ) + throw rld::error( "address outside range", "AddressRange::get" ); + size_t slot = address - lowAddress; + if (slot >= info.size ()) + throw rld::error( "address slot not found", "AddressRange::get" ); + return info[slot]; } - CoverageMapBase::~CoverageMapBase() + void AddressRange::dump (std::ostream& out, bool show_slots) const { - if (Info) - delete Info; + out << std::hex << std::setfill('0') + << "Address range: low = " << std::setw(8) << lowAddress + << " high = " << std::setw(8) << highAddress + << std::endl; + if (show_slots) { + size_t slot = 0; + for (auto& i : info) { + out << std::hex << std::setfill('0') + << "0x" << std::setw(8) << slot++ + lowAddress + << "- isStartOfInstruction:" + << (char*) (i.isStartOfInstruction ? "yes" : "no") + << " wasExecuted:" + << (char*) (i.wasExecuted ? "yes" : "no") + << std::endl + << " isBranch:" + << (char*) (i.isBranch ? "yes" : "no") + << " wasTaken:" + << (char*) (i.wasTaken ? "yes" : "no") + << " wasNotTaken:" + << (char*) (i.wasNotTaken ? "yes" : "no") + << std::dec << std::setfill(' ') + << std::endl; + } + } } - void CoverageMapBase::Add( uint32_t low, uint32_t high ) + CoverageMapBase::CoverageMapBase( + const std::string& exefileName, + uint32_t low, + uint32_t high + ) : exefileName (exefileName) { - AddressRange range; + Ranges.push_back( AddressRange( exefileName, low, high ) ); + } - range.lowAddress = low; - range.highAddress = high; - Ranges.push_back( range ); + CoverageMapBase::~CoverageMapBase() + { } - bool CoverageMapBase::determineOffset( - uint32_t address, - uint32_t *offset - )const + void CoverageMapBase::Add( uint32_t low, uint32_t high ) { - AddressRanges::const_iterator itr; + Ranges.push_back( AddressRange( exefileName, low, high ) ); + } - for ( auto& r : Ranges ) { - if ((address >= r.lowAddress) && (address <= r.highAddress)){ - *offset = address - r.lowAddress; + bool CoverageMapBase::validAddress( const uint32_t address ) const + { + for ( auto r : Ranges ) + if (r.inside( address )) return true; - } - } - *offset = 0; return false; } - void CoverageMapBase::dump( void ) const { - fprintf( stderr, "Coverage Map Contents:\n" ); - /* - * XXX - Dump is only marking the first Address Range. - */ - for (uint32_t a = 0; a < Size; a++) { - perAddressInfo* entry = &Info[ a ]; - std::cerr << std::hex << std::setfill('0') - << "0x" << a + Ranges.front().lowAddress - << "- isStartOfInstruction:" - << (char*) (entry->isStartOfInstruction ? "yes" : "no") - << " wasExecuted:" - << (char*) (entry->wasExecuted ? "yes" : "no") - << std::endl - << " isBranch:" - << (char*) (entry->isBranch ? "yes" : "no") - << " wasTaken:" - << (char*) (entry->wasTaken ? "yes" : "no") - << " wasNotTaken:" - << (char*) (entry->wasNotTaken ? "yes" : "no") - << std::dec << std::setfill(' ') - << std::endl; - } + std::cerr << "Coverage Map Contents:" << std::endl; + for (auto& r : Ranges) + r.dump( std::cerr ); + } + + uint32_t CoverageMapBase::getSize() const + { + size_t size = 0; + for (auto& r : Ranges) + size += r.size (); + return size; } bool CoverageMapBase::getBeginningOfInstruction( @@ -114,15 +151,14 @@ namespace Coverage { uint32_t start; AddressRange range; - - status = getRange( address, &range ); + status = getRange( address, range ); if ( status != true ) return status; start = address; while (start >= range.lowAddress ) { - if (Info[ start - range.lowAddress ].isStartOfInstruction) { + if (isStartOfInstruction( start - range.lowAddress )) { *beginning = start; status = true; break; @@ -136,258 +172,192 @@ namespace Coverage { int32_t CoverageMapBase::getFirstLowAddress() const { + /* + * This is broken, do not trust it. + */ return Ranges.front().lowAddress; } - bool CoverageMapBase::getRange( uint32_t address, AddressRange *range ) const + bool CoverageMapBase::getRange( uint32_t address, AddressRange& range ) const { for ( auto r : Ranges ) { - if ((address >= r.lowAddress) && (address <= r.highAddress)){ - range->lowAddress = r.lowAddress; - range->highAddress = r.highAddress; + if (r.inside( address )) { + range.lowAddress = r.lowAddress; + range.highAddress = r.highAddress; + range.info = r.info; return true; } } - - range->lowAddress = 0; - range->highAddress = 0; - return false; + } + AddressInfo& CoverageMapBase::getInfo( uint32_t address ) + { + for ( auto& r : Ranges ) + if (r.inside( address )) + return r.get( address ); + throw rld::error( "address out of bounds", "CoverageMapBase::getInfo" ); } - uint32_t CoverageMapBase::getSize() const + const AddressInfo& CoverageMapBase::getInfo( uint32_t address ) const { - return Size; + for ( auto& r : Ranges ) + if (r.inside( address )) + return r.get( address ); + throw rld::error( "address out of bounds", "CoverageMapBase::getInfo" ); } void CoverageMapBase::setIsStartOfInstruction( uint32_t address ) { - uint32_t offset; - - if (determineOffset( address, &offset ) != true) - return; - - Info[ offset ].isStartOfInstruction = true; + if ( validAddress( address ) ) + getInfo( address ).isStartOfInstruction = true; } bool CoverageMapBase::isStartOfInstruction( uint32_t address ) const { - uint32_t offset; - - if (determineOffset( address, &offset ) != true) + if ( !validAddress( address ) ) return false; - - return Info[ offset ].isStartOfInstruction; + return getInfo( address ).isStartOfInstruction; } void CoverageMapBase::setWasExecuted( uint32_t address ) { - uint32_t offset; - - if (determineOffset( address, &offset ) != true) - return; - - Info[ offset ].wasExecuted += 1; + if ( validAddress( address ) ) + getInfo( address ).wasExecuted += 1; } void CoverageMapBase::sumWasExecuted( uint32_t address, uint32_t addition) { - uint32_t offset; - - if (determineOffset( address, &offset ) != true) - return; - - Info[ offset ].wasExecuted += addition; + if ( validAddress( address ) ) + getInfo( address ).wasExecuted += addition; } bool CoverageMapBase::wasExecuted( uint32_t address ) const { - uint32_t offset; - bool result; - - result = true; - - if (determineOffset( address, &offset ) != true) - result = false; - - if (Info[ offset ].wasExecuted <= 0) - result = false; - + bool result = false; + if ( validAddress( address ) && (getInfo( address ).wasExecuted > 0)) + result = true; return result; } uint32_t CoverageMapBase::getWasExecuted( uint32_t address ) const { - uint32_t offset; - - if (determineOffset( address, &offset ) != true) + if ( !validAddress( address ) ) return 0; - - return Info[ offset ].wasExecuted; + return getInfo( address ).wasExecuted; } void CoverageMapBase::setIsBranch( uint32_t address ) { - uint32_t offset; - - if (determineOffset( address, &offset ) != true) - return; - - Info[ offset ].isBranch = true; + if ( validAddress( address ) ) + getInfo( address ).isBranch = true; } bool CoverageMapBase::isNop( uint32_t address ) const { - uint32_t offset; - - if (determineOffset( address, &offset ) != true) + if ( !validAddress( address ) ) return false; - - return Info[ offset ].isNop; + return getInfo( address ).isNop; } void CoverageMapBase::setIsNop( uint32_t address ) { - uint32_t offset; - - if (determineOffset( address, &offset ) != true) + if ( !validAddress( address ) ) return; - - Info[ offset ].isNop = true; + getInfo( address ).isNop = true; } bool CoverageMapBase::isBranch( uint32_t address ) const { - uint32_t offset; - - if (determineOffset( address, &offset ) != true) + if ( !validAddress( address ) ) return false; - - return Info[ offset ].isBranch; + return getInfo( address ).isBranch; } void CoverageMapBase::setWasTaken( uint32_t address ) { - uint32_t offset; - - if (determineOffset( address, &offset ) != true) + if ( !validAddress( address ) ) return; - - Info[ offset ].wasTaken += 1; + getInfo( address ).wasTaken += 1; } void CoverageMapBase::setWasNotTaken( uint32_t address ) { - uint32_t offset; - - if (determineOffset( address, &offset ) != true) + if ( !validAddress( address ) ) return; - - Info[ offset ].wasNotTaken += 1; + getInfo( address ).wasNotTaken += 1; } bool CoverageMapBase::wasAlwaysTaken( uint32_t address ) const { - uint32_t offset; - - if (determineOffset( address, &offset ) != true) + if ( !validAddress( address ) ) return false; - - return (Info[ offset ].wasTaken && - !Info[ offset ].wasNotTaken); + const AddressInfo& info = getInfo( address ); + return info.wasTaken && !info.wasNotTaken; } bool CoverageMapBase::wasNeverTaken( uint32_t address ) const { - uint32_t offset; - - if (determineOffset( address, &offset ) != true) + if ( !validAddress( address ) ) return false; - - return (!Info[ offset ].wasTaken && - Info[ offset ].wasNotTaken); + const AddressInfo& info = getInfo( address ); + return !info.wasTaken && info.wasNotTaken; } bool CoverageMapBase::wasNotTaken( uint32_t address ) const { - uint32_t offset; - bool result; - - result = true; - - if (determineOffset( address, &offset ) != true) - result = false; - - if (Info[ offset ].wasNotTaken <= 0) - result = false; - - return result; + bool result = true; + if ( !validAddress( address ) ) + result = false; + else if ( getInfo( address ).wasNotTaken <= 0 ) + result = false; + return result; } void CoverageMapBase::sumWasNotTaken( uint32_t address, uint32_t addition) { - uint32_t offset; - - if (determineOffset( address, &offset ) != true) - return; - - Info[ offset ].wasNotTaken += addition; + if ( validAddress( address ) ) + getInfo( address ).wasNotTaken += addition; } uint32_t CoverageMapBase::getWasNotTaken( uint32_t address ) const { - uint32_t offset; - - if (determineOffset( address, &offset ) != true) + if ( !validAddress( address ) ) return 0; - - return Info[ offset ].wasNotTaken; + return getInfo( address ).wasNotTaken; } bool CoverageMapBase::wasTaken( uint32_t address ) const { - uint32_t offset; - bool result; - - result = true; - - if (determineOffset( address, &offset ) != true) + bool result = true; + if ( !validAddress( address ) ) result = false; - - if (Info[ offset ].wasTaken <= 0) + else if ( getInfo( address ).wasTaken <= 0 ) result = false; - return result; } void CoverageMapBase::sumWasTaken( uint32_t address, uint32_t addition) { - uint32_t offset; - - if (determineOffset( address, &offset ) != true) + if ( !validAddress( address ) ) return; - - Info[ offset ].wasTaken += addition; + getInfo( address ).wasTaken += addition; } uint32_t CoverageMapBase::getWasTaken( uint32_t address ) const { - uint32_t offset; - - if (determineOffset( address, &offset ) != true) + if ( !validAddress( address ) ) return 0; - - return Info[ offset ].wasTaken; + return getInfo( address ).wasTaken; } } |