summaryrefslogtreecommitdiff
path: root/covoar/DesiredSymbols.cc
diff options
context:
space:
mode:
Diffstat (limited to 'covoar/DesiredSymbols.cc')
-rw-r--r--covoar/DesiredSymbols.cc692
1 files changed, 0 insertions, 692 deletions
diff --git a/covoar/DesiredSymbols.cc b/covoar/DesiredSymbols.cc
deleted file mode 100644
index 6b780dd..0000000
--- a/covoar/DesiredSymbols.cc
+++ /dev/null
@@ -1,692 +0,0 @@
-/*! @file DesiredSymbols.cc
- * @brief DesiredSymbols Implementation
- *
- * This file contains the implementation of the functions
- * which provide the functionality of the DesiredSymbols.
- */
-
-#include <libgen.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "DesiredSymbols.h"
-#include "app_common.h"
-#include "CoverageMap.h"
-#include "ObjdumpProcessor.h"
-
-namespace Coverage {
-
- DesiredSymbols::DesiredSymbols()
- {
- }
-
- DesiredSymbols::~DesiredSymbols()
- {
- }
-
- void DesiredSymbols::load(
- const char* const symbolsFile
- )
- {
- int cStatus;
- bool done = false;
- FILE* sFile;
- SymbolInformation* symInfo;
- int line = 1;
- std::string symbol;
-
- // Ensure that symbols file name is given.
- if ( !symbolsFile ) {
- fprintf(
- stderr,
- "ERROR: DesiredSymbols::load - no symbols file specified\n"
- );
- exit(-1);
- }
-
- // Open symbols file.
- sFile = fopen( symbolsFile, "r" );
- if ( !sFile ) {
- fprintf(
- stderr,
- "ERROR: DesiredSymbols::load - unable to open symbols file %s\n",
- symbolsFile
- );
- exit(-1);
- }
-
- // Process symbols file.
- while ( !done ) {
-
- symInfo = new SymbolInformation;
-
- // Skip blank lines between symbols
- do {
- inputBuffer[0] = '\0';
- inputBuffer2[0] = '\0';
- cStatus = fscanf( sFile, "%s %s", inputBuffer, inputBuffer2 );
- if ( cStatus == EOF ) {
- done = true;
- }
- else {
- //inputBuffer[ strlen(inputBuffer) - 1] = '\0';
- line++;
- }
- } while ( !done && (inputBuffer[0] == '\0') );
-
- // Have we already seen this one?
- if ( !done ) {
- if (set.find( inputBuffer ) != set.end()) {
- fprintf(
- stderr,
- "File: %s, Line %d: Duplicate symbol: %s\n",
- symbolsFile,
- line,
- inputBuffer
- );
-
- delete symInfo;
- }
-
- // Add this to the set of symbols.
- else
- set[ inputBuffer ] = *symInfo;
- }
- }
- }
-
- void DesiredSymbols::preprocess( void )
- {
- ObjdumpProcessor::objdumpLines_t::iterator fitr;
- ObjdumpProcessor::objdumpLines_t::iterator n, p;
- DesiredSymbols::symbolSet_t::iterator sitr;
- CoverageMapBase* theCoverageMap;
-
- // Look at each symbol.
- for (sitr = SymbolsToAnalyze->set.begin();
- sitr != SymbolsToAnalyze->set.end();
- sitr++) {
-
- // If the unified coverage map does not exist, the symbol was
- // never referenced by any executable. Just skip it.
- theCoverageMap = sitr->second.unifiedCoverageMap;
- if (!theCoverageMap)
- continue;
-
- // Mark any branch and NOP instructions.
- for (fitr = sitr->second.instructions.begin();
- fitr != sitr->second.instructions.end();
- fitr++) {
- if (fitr->isBranch) {
- theCoverageMap->setIsBranch(
- fitr->address - sitr->second.baseAddress
- );
- }
- if (fitr->isNop) {
- theCoverageMap->setIsNop(
- fitr->address - sitr->second.baseAddress
- );
- }
- }
-
- }
- }
-
- void DesiredSymbols::calculateStatistics( void )
- {
- uint32_t a;
- uint32_t endAddress;
- DesiredSymbols::symbolSet_t::iterator sitr;
- CoverageMapBase* theCoverageMap;
-
- // Look at each symbol.
- for (sitr = SymbolsToAnalyze->set.begin();
- sitr != SymbolsToAnalyze->set.end();
- sitr++) {
-
- // If the unified coverage map does not exist, the symbol was
- // never referenced by any executable. Just skip it.
- theCoverageMap = sitr->second.unifiedCoverageMap;
- if (!theCoverageMap)
- continue;
-
- // Increment the total sizeInBytes byt the bytes in the symbol
- stats.sizeInBytes += sitr->second.stats.sizeInBytes;
-
- // Now scan through the coverage map of this symbol.
- endAddress = sitr->second.stats.sizeInBytes - 1;
- a = 0;
- while (a <= endAddress) {
-
- // If we are at the start of instruction increment
- // instruction type counters as needed.
- if ( theCoverageMap->isStartOfInstruction( a ) ) {
-
- stats.sizeInInstructions++;
- sitr->second.stats.sizeInInstructions++;
-
- if (!theCoverageMap->wasExecuted( a ) ) {
- stats.uncoveredInstructions++;
- sitr->second.stats.uncoveredInstructions++;
-
- if ( theCoverageMap->isBranch( a )) {
- stats.branchesNotExecuted++;
- sitr->second.stats.branchesNotExecuted++;
- }
- } else if (theCoverageMap->isBranch( a )) {
- stats.branchesExecuted++;
- sitr->second.stats.branchesExecuted++;
- }
-
- }
-
- if (!theCoverageMap->wasExecuted( a )) {
- stats.uncoveredBytes++;
- sitr->second.stats.uncoveredBytes++;
- }
- a++;
-
- }
- }
- }
-
-
- void DesiredSymbols::computeUncovered( void )
- {
- uint32_t a, la, ha;
- uint32_t endAddress;
- uint32_t count;
- DesiredSymbols::symbolSet_t::iterator sitr;
- CoverageRanges* theBranches;
- CoverageMapBase* theCoverageMap;
- CoverageRanges* theRanges;
-
- // Look at each symbol.
- for (sitr = SymbolsToAnalyze->set.begin();
- sitr != SymbolsToAnalyze->set.end();
- sitr++) {
-
- // If the unified coverage map does not exist, the symbol was
- // never referenced by any executable. Just skip it.
- theCoverageMap = sitr->second.unifiedCoverageMap;
- if (!theCoverageMap)
- continue;
-
- // Create containers for the symbol's uncovered ranges and branches.
- theRanges = new CoverageRanges();
- sitr->second.uncoveredRanges = theRanges;
- theBranches = new CoverageRanges();
- sitr->second.uncoveredBranches = theBranches;
-
- // Mark NOPs as executed
- endAddress = sitr->second.stats.sizeInBytes - 1;
- a = 0;
- while (a < endAddress) {
- if (!theCoverageMap->wasExecuted( a )) {
- a++;
- continue;
- }
-
- for (ha=a+1;
- ha<=endAddress && !theCoverageMap->isStartOfInstruction( ha );
- ha++)
- ;
- if ( ha >= endAddress )
- break;
-
- if (theCoverageMap->isNop( ha ))
- do {
- theCoverageMap->setWasExecuted( ha );
- ha++;
- if ( ha >= endAddress )
- break;
- } while ( !theCoverageMap->isStartOfInstruction( ha ) );
- a = ha;
- }
-
- // Now scan through the coverage map of this symbol.
- endAddress = sitr->second.stats.sizeInBytes - 1;
- a = 0;
- while (a <= endAddress) {
-
- // If an address was NOT executed, find consecutive unexecuted
- // addresses and add them to the uncovered ranges.
- if (!theCoverageMap->wasExecuted( a )) {
-
- la = a;
- count = 1;
- for (ha=a+1;
- ha<=endAddress && !theCoverageMap->wasExecuted( ha );
- ha++)
- {
- if ( theCoverageMap->isStartOfInstruction( ha ) )
- count++;
- }
- ha--;
-
- stats.uncoveredRanges++;
- sitr->second.stats.uncoveredRanges++;
- theRanges->add(
- sitr->second.baseAddress + la,
- sitr->second.baseAddress + ha,
- CoverageRanges::UNCOVERED_REASON_NOT_EXECUTED,
- count
- );
- a = ha + 1;
- }
-
- // If an address is a branch instruction, add any uncovered branches
- // to the uncoverd branches.
- else if (theCoverageMap->isBranch( a )) {
- la = a;
- for (ha=a+1;
- ha<=endAddress && !theCoverageMap->isStartOfInstruction( ha );
- ha++)
- ;
- ha--;
-
- if (theCoverageMap->wasAlwaysTaken( la )) {
- stats.branchesAlwaysTaken++;
- sitr->second.stats.branchesAlwaysTaken++;
- theBranches->add(
- sitr->second.baseAddress + la,
- sitr->second.baseAddress + ha,
- CoverageRanges::UNCOVERED_REASON_BRANCH_ALWAYS_TAKEN,
- 1
- );
- if (Verbose)
- fprintf(
- stderr,
- "Branch always taken found in %s (0x%x - 0x%x)\n",
- (sitr->first).c_str(),
- sitr->second.baseAddress + la,
- sitr->second.baseAddress + ha
- );
- }
-
- else if (theCoverageMap->wasNeverTaken( la )) {
- stats.branchesNeverTaken++;
- sitr->second.stats.branchesNeverTaken++;
- theBranches->add(
- sitr->second.baseAddress + la,
- sitr->second.baseAddress + ha,
- CoverageRanges::UNCOVERED_REASON_BRANCH_NEVER_TAKEN,
- 1
- );
- if (Verbose)
- fprintf(
- stderr,
- "Branch never taken found in %s (0x%x - 0x%x)\n",
- (sitr->first).c_str(),
- sitr->second.baseAddress + la,
- sitr->second.baseAddress + ha
- );
- }
- a = ha + 1;
- }
- else
- a++;
- }
- }
- }
-
-
- void DesiredSymbols::createCoverageMap(
- const std::string& symbolName,
- uint32_t size
- )
- {
- CoverageMapBase* aCoverageMap;
- uint32_t highAddress;
- symbolSet_t::iterator itr;
-
- // Ensure that the symbol is a desired symbol.
- itr = set.find( symbolName );
-
- if (itr == set.end()) {
-
- fprintf(
- stderr,
- "ERROR: DesiredSymbols::createCoverageMap - Unable to create "
- "unified coverage map for %s because it is NOT a desired symbol\n",
- symbolName.c_str()
- );
- exit( -1 );
- }
-
- // If we have already created a coverage map, ...
- if (itr->second.unifiedCoverageMap) {
-
- // ensure that the specified size matches the existing size.
- if (itr->second.stats.sizeInBytes != size) {
-
- fprintf(
- stderr,
- "ERROR: DesiredSymbols::createCoverageMap - Attempt to create "
- "unified coverage maps for %s with different sizes (%d != %d)\n",
- symbolName.c_str(),
- itr->second.stats.sizeInBytes,
- size
- );
- if ( itr->second.stats.sizeInBytes < size )
- itr->second.stats.sizeInBytes = size;
- else
- size = itr->second.stats.sizeInBytes;
- // exit( -1 );
- }
- }
-
- // If we don't already have a coverage map, create one.
- else {
-
- highAddress = size - 1;
-
- aCoverageMap = new CoverageMap( 0, highAddress );
- if (!aCoverageMap) {
-
- fprintf(
- stderr,
- "ERROR: DesiredSymbols::createCoverageMap - Unable to allocate "
- "coverage map for %s\n",
- symbolName.c_str()
- );
- exit( -1 );
- }
-
- if ( Verbose )
- fprintf(
- stderr,
- "Created unified coverage map for %s (0x%x - 0x%x)\n",
- symbolName.c_str(), 0, highAddress
- );
- itr->second.unifiedCoverageMap = aCoverageMap;
- itr->second.stats.sizeInBytes = size;
- }
- }
-
- void DesiredSymbols::determineSourceLines(
- CoverageRanges* const theRanges,
- ExecutableInfo* const theExecutable
-
- )
- {
- 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);
- }
-
- // 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.
- 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(
- const std::string& symbolName
- )
- {
- if (set.find( symbolName ) == set.end())
- return NULL;
- else
- return &set[ symbolName ];
- }
-
- void DesiredSymbols::findSourceForUncovered( void )
- {
- DesiredSymbols::symbolSet_t::iterator ditr;
- CoverageRanges* theBranches;
- CoverageRanges* theRanges;
-
- // Process uncovered ranges and/or branches for each symbol.
- for (ditr = SymbolsToAnalyze->set.begin();
- ditr != SymbolsToAnalyze->set.end();
- ditr++) {
-
- // First the unexecuted ranges, ...
- theRanges = ditr->second.uncoveredRanges;
- if (theRanges == NULL)
- continue;
-
- if (!theRanges->set.empty()) {
- if (Verbose)
- fprintf(
- stderr,
- "Looking up source lines for uncovered ranges in %s\n",
- (ditr->first).c_str()
- );
- determineSourceLines(
- theRanges,
- ditr->second.sourceFile
- );
- }
-
- // then the uncovered branches.
- theBranches = ditr->second.uncoveredBranches;
- if (theBranches == NULL)
- continue;
-
- if (!theBranches->set.empty()) {
- if (Verbose)
- fprintf(
- stderr,
- "Looking up source lines for uncovered branches in %s\n",
- (ditr->first).c_str()
- );
- determineSourceLines(
- theBranches,
- ditr->second.sourceFile
- );
- }
- }
- }
-
- uint32_t DesiredSymbols::getNumberBranchesAlwaysTaken( void ) const {
- return stats.branchesAlwaysTaken;
- };
-
- uint32_t DesiredSymbols::getNumberBranchesFound( void ) const {
- return (stats.branchesNotExecuted + stats.branchesExecuted);
- };
-
- uint32_t DesiredSymbols::getNumberBranchesNeverTaken( void ) const {
- return stats.branchesNeverTaken;
- };
-
- uint32_t DesiredSymbols::getNumberUncoveredRanges( void ) const {
- return stats.uncoveredRanges;
- };
-
- bool DesiredSymbols::isDesired (
- const std::string& symbolName
- ) const
- {
- if (set.find( symbolName ) == set.end()) {
- #if 0
- fprintf( stderr,
- "Warning: Unable to find symbol %s\n",
- symbolName.c_str()
- );
- #endif
- return false;
- }
- return true;
- }
-
- void DesiredSymbols::mergeCoverageMap(
- const std::string& symbolName,
- const CoverageMapBase* const sourceCoverageMap
- )
- {
- uint32_t dAddress;
- CoverageMapBase* destinationCoverageMap;
- uint32_t dMapSize;
- symbolSet_t::iterator itr;
- uint32_t sAddress;
- uint32_t sBaseAddress;
- uint32_t sMapSize;
- uint32_t executionCount;
-
- // Ensure that the symbol is a desired symbol.
- itr = set.find( symbolName );
-
- if (itr == set.end()) {
-
- fprintf(
- stderr,
- "ERROR: DesiredSymbols::mergeCoverageMap - Unable to merge "
- "coverage map for %s because it is NOT a desired symbol\n",
- symbolName.c_str()
- );
- exit( -1 );
- }
-
- // Ensure that the source and destination coverage maps
- // are the same size.
- dMapSize = itr->second.stats.sizeInBytes;
- sBaseAddress = sourceCoverageMap->getFirstLowAddress();
- sMapSize = sourceCoverageMap->getSize();
- if (dMapSize != sMapSize) {
-
- fprintf(
- stderr,
- "ERROR: DesiredSymbols::mergeCoverageMap - Unable to merge "
- "coverage map for %s because the sizes are different\n",
- symbolName.c_str()
- );
- return;
- // exit( -1 );
- }
-
- // Merge the data for each address.
- destinationCoverageMap = itr->second.unifiedCoverageMap;
-
- for (dAddress = 0; dAddress < dMapSize; dAddress++) {
-
- sAddress = dAddress + sBaseAddress;
-
- // Merge start of instruction indication.
- if (sourceCoverageMap->isStartOfInstruction( sAddress ))
- destinationCoverageMap->setIsStartOfInstruction( dAddress );
-
- // Merge the execution data.
- executionCount = sourceCoverageMap->getWasExecuted( sAddress );
- destinationCoverageMap->sumWasExecuted( dAddress, executionCount );
-
- // Merge the branch data.
- executionCount = sourceCoverageMap->getWasTaken( sAddress );
- destinationCoverageMap->sumWasTaken( dAddress, executionCount );
-
- executionCount = sourceCoverageMap->getWasNotTaken( sAddress );
- destinationCoverageMap->sumWasNotTaken( dAddress, executionCount );
- }
- }
-
-}