blob: 0a629b7a878a986c55d32675fb01ac03068418a8 (
plain) (
tree)
|
|
/*! @file ExecutableInfo.cc
* @brief ExecutableInfo Implementation
*
* This file contains the implementation of the functionality
* of the ExecutableInfo class.
*/
#include <stdio.h>
#include <rld.h>
#include "ExecutableInfo.h"
#include "app_common.h"
#include "CoverageMap.h"
#include "DesiredSymbols.h"
#include "SymbolTable.h"
namespace Coverage {
ExecutableInfo::ExecutableInfo(
const char* const theExecutableName,
const char* const theLibraryName,
bool verbose
) : executable(theExecutableName),
loadAddress(0)
{
if (theLibraryName != nullptr)
libraryName = theLibraryName;
if (verbose) {
std::cerr << "Loading executable " << theExecutableName;
if (theLibraryName != nullptr)
std::cerr << " (" << theLibraryName << ')';
std::cerr << std::endl;
}
executable.open();
executable.begin();
executable.load_symbols(symbols);
debug.begin(executable.elf());
debug.load_debug();
debug.load_functions();
for (auto& cu : debug.get_cus()) {
for (auto& func : cu.get_functions()) {
if (func.has_machine_code() && (!func.is_inlined() || func.is_external())) {
createCoverageMap (cu.name(), func.name(),
func.pc_low(), func.pc_high());
}
}
}
}
ExecutableInfo::~ExecutableInfo()
{
debug.end();
executable.end();
executable.close();
}
void ExecutableInfo::dumpCoverageMaps( void ) {
ExecutableInfo::CoverageMaps::iterator itr;
for (auto& cm : coverageMaps) {
std::cerr << "Coverage Map for " << cm.first << std::endl;
cm.second->dump();
}
}
void ExecutableInfo::dumpExecutableInfo( void ){
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::iterator it;
std::string itsSymbol;
// Obtain the coverage map containing the specified address.
itsSymbol = theSymbolTable.getSymbol( address );
if (itsSymbol != "") {
it = coverageMaps.find( itsSymbol );
aCoverageMap = (*it).second;
}
return aCoverageMap;
}
const std::string ExecutableInfo::getFileName ( void ) const
{
return executable.name().full();
}
const std::string ExecutableInfo::getLibraryName( void ) const
{
return libraryName;
}
uint32_t ExecutableInfo::getLoadAddress( void ) const
{
return loadAddress;
}
SymbolTable* ExecutableInfo::getSymbolTable ( void )
{
return &theSymbolTable;
}
CoverageMapBase& ExecutableInfo::findCoverageMap(
const std::string& symbolName
)
{
CoverageMaps::iterator cmi = coverageMaps.find( symbolName );
if ( cmi == coverageMaps.end() )
throw rld::error (symbolName, "ExecutableInfo::findCoverageMap");
return *(cmi->second);
}
void ExecutableInfo::createCoverageMap (
const std::string& fileName,
const std::string& symbolName,
uint32_t lowAddress,
uint32_t highAddress
)
{
CoverageMapBase *theMap;
CoverageMaps::iterator itr;
itr = coverageMaps.find( symbolName );
if ( itr == coverageMaps.end() ) {
theMap = new CoverageMap( fileName, lowAddress, highAddress );
coverageMaps[ symbolName ] = theMap;
} else {
theMap = itr->second;
theMap->Add( lowAddress, highAddress );
}
}
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.empty();
}
void ExecutableInfo::mergeCoverage( void ) {
for (auto& cm : coverageMaps) {
if (SymbolsToAnalyze->isDesired( cm.first ))
SymbolsToAnalyze->mergeCoverageMap( cm.first, cm.second );
}
}
void ExecutableInfo::setLoadAddress( uint32_t address )
{
loadAddress = address;
}
}
|