summaryrefslogtreecommitdiff
path: root/covoar/ObjdumpProcessor.cc
diff options
context:
space:
mode:
Diffstat (limited to 'covoar/ObjdumpProcessor.cc')
-rw-r--r--covoar/ObjdumpProcessor.cc465
1 files changed, 0 insertions, 465 deletions
diff --git a/covoar/ObjdumpProcessor.cc b/covoar/ObjdumpProcessor.cc
deleted file mode 100644
index 486c720..0000000
--- a/covoar/ObjdumpProcessor.cc
+++ /dev/null
@@ -1,465 +0,0 @@
-/*! @file ObjdumpProcessor.cc
- * @brief ObjdumpProcessor Implementation
- *
- * This file contains the implementation of the functions supporting
- * the reading of an objdump output file and adding nops to a
- * coverage map.
- */
-
-#include <assert.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <algorithm>
-#include <string>
-
-#include "app_common.h"
-#include "ObjdumpProcessor.h"
-#include "CoverageMap.h"
-#include "ExecutableInfo.h"
-#include "SymbolTable.h"
-#include "TargetFactory.h"
-
-namespace Coverage {
-
- void finalizeSymbol(
- ExecutableInfo* const executableInfo,
- std::string& symbolName,
- uint32_t lowAddress,
- uint32_t highAddress,
- ObjdumpProcessor::objdumpLines_t instructions
- ) {
-
- CoverageMapBase* aCoverageMap = NULL;
- uint32_t endAddress = highAddress;
- ObjdumpProcessor::objdumpLines_t::iterator itr, fnop, lnop;
- ObjdumpProcessor::objdumpLines_t::reverse_iterator ritr;
- SymbolInformation* symbolInfo = NULL;
- SymbolTable* theSymbolTable;
-
- //
- // Remove trailing nop instructions.
- //
-
- // First find the last instruction.
- for (ritr = instructions.rbegin();
- ritr != instructions.rend();
- ritr++) {
- if (ritr->isInstruction)
- break;
- }
-
- // If an instruction was found and it is a nop, ...
- if ((ritr != instructions.rend()) && (ritr->isNop)) {
-
- // save it as the last nop. Note that we must account for
- // the difference between a forward and a reverse iterator.
- lnop = ritr.base();
- lnop--;
- endAddress -= lnop->nopSize;
-
- // Now look for the first nop in the sequence of trailing nops.
- fnop = lnop;
- ritr++;
- for (; ritr != instructions.rend(); ritr++) {
- if (ritr->isNop) {
- fnop = ritr.base();
- fnop--;
- endAddress -= fnop->nopSize;
- }
- else
- break;
- }
-
- // Erase trailing nops. The erase operation wants the first
- // parameter to point to the first item to erase and the second
- // parameter to point to the item beyond the last item to erase.
- if ( fnop == lnop )
- instructions.erase( fnop );
- else
- instructions.erase( fnop, ++lnop );
- }
-
- // If there are NOT already saved instructions, save them.
- symbolInfo = SymbolsToAnalyze->find( symbolName );
- if (symbolInfo->instructions.empty()) {
- symbolInfo->sourceFile = executableInfo;
- symbolInfo->baseAddress = lowAddress;
- symbolInfo->instructions = instructions;
- }
-
- // Add the symbol to this executable's symbol table.
- theSymbolTable = executableInfo->getSymbolTable();
- theSymbolTable->addSymbol(
- symbolName, lowAddress, endAddress - lowAddress + 1
- );
-
- // Create a coverage map for the symbol.
- aCoverageMap = executableInfo->createCoverageMap(
- symbolName, lowAddress, endAddress
- );
-
- if (aCoverageMap) {
-
- // Mark the start of each instruction in the coverage map.
- for (itr = instructions.begin();
- itr != instructions.end();
- itr++ ) {
-
- aCoverageMap->setIsStartOfInstruction( itr->address );
- }
-
- // Create a unified coverage map for the symbol.
- SymbolsToAnalyze->createCoverageMap(
- symbolName, endAddress - lowAddress + 1
- );
- }
- }
-
- ObjdumpProcessor::ObjdumpProcessor()
- {
- }
-
- ObjdumpProcessor::~ObjdumpProcessor()
- {
- }
-
- uint32_t ObjdumpProcessor::determineLoadAddress(
- ExecutableInfo* theExecutable
- )
- {
- #define METHOD "ERROR: ObjdumpProcessor::determineLoadAddress - "
- FILE* loadAddressFile = NULL;
- char* cStatus;
- uint32_t offset;
-
- // This method should only be call for a dynamic library.
- if (!theExecutable->hasDynamicLibrary())
- return 0;
-
- std::string dlinfoName = theExecutable->getFileName();
- uint32_t address;
- char inLibName[128];
- std::string Library = theExecutable->getLibraryName();
-
- dlinfoName += ".dlinfo";
- // Read load address.
- loadAddressFile = fopen( dlinfoName.c_str(), "r" );
- if (!loadAddressFile) {
- fprintf( stderr, METHOD "unable to open %s\n", dlinfoName.c_str() );
- exit( -1 );
- }
-
- // Process the dlinfo file.
- while ( 1 ) {
-
- // Get a line.
- cStatus = fgets( inputBuffer, MAX_LINE_LENGTH, loadAddressFile );
- if (cStatus == NULL) {
- fprintf(
- stderr,
- METHOD "library %s not found in %s\n",
- Library.c_str(),
- dlinfoName.c_str()
- );
- fclose( loadAddressFile );
- exit( -1 );
- }
- sscanf( inputBuffer, "%s %x", inLibName, &offset );
- std::string tmp = inLibName;
- if ( tmp.find( Library ) != tmp.npos ) {
- // fprintf( stderr, "%s - 0x%08x\n", inLibName, offset );
- address = offset;
- break;
- }
- }
-
- fclose( loadAddressFile );
- return address;
-
- #undef METHOD
- }
-
- bool ObjdumpProcessor::IsBranch(
- const char *instruction
- )
- {
- if ( !TargetInfo ) {
- fprintf(
- stderr,
- "ERROR: ObjdumpProcessor::IsBranch - unknown architecture\n"
- );
- assert(0);
- return false;
- }
-
- return TargetInfo->isBranch( instruction );
- }
-
- bool ObjdumpProcessor::isBranchLine(
- const char* const line
- )
- {
- if ( !TargetInfo ) {
- fprintf(
- stderr,
- "ERROR: ObjdumpProcessor::isBranchLine - unknown architecture\n"
- );
- assert(0);
- return false;
- }
-
- return TargetInfo->isBranchLine( line );
- }
-
- bool ObjdumpProcessor::isNop(
- const char* const line,
- int& size
- )
- {
- if ( !TargetInfo ){
- fprintf(
- stderr,
- "ERROR: ObjdumpProcessor::isNop - unknown architecture\n"
- );
- assert(0);
- return false;
- }
-
- return TargetInfo->isNopLine( line, size );
- }
-
- FILE* ObjdumpProcessor::getFile( std::string fileName )
- {
- char dumpFile[128];
- FILE* objdumpFile;
- char buffer[ 512 ];
- int status;
-
- sprintf( dumpFile, "%s.dmp", fileName.c_str() );
-
- // Generate the objdump.
- if (FileIsNewer( fileName.c_str(), dumpFile )) {
- sprintf(
- buffer,
- "%s -Cda --section=.text --source %s | sed -e \'s/ *$//\' >%s",
- TargetInfo->getObjdump(),
- fileName.c_str(),
- dumpFile
- );
-
- status = system( buffer );
- if (status) {
- fprintf(
- stderr,
- "ERROR: ObjdumpProcessor::getFile - command (%s) failed with %d\n",
- buffer,
- status
- );
- exit( -1 );
- }
- }
-
- // Open the objdump file.
- objdumpFile = fopen( dumpFile, "r" );
- if (!objdumpFile) {
- fprintf(
- stderr,
- "ERROR: ObjdumpProcessor::getFile - unable to open %s\n",
- dumpFile
- );
- exit(-1);
- }
-
- return objdumpFile;
- }
-
- uint32_t ObjdumpProcessor::getAddressAfter( uint32_t address )
- {
- objdumpFile_t::iterator itr;
-
- itr = find ( objdumpList.begin(), objdumpList.end(), address );
- if (itr == objdumpList.end()) {
- return 0;
- }
-
- itr++;
- if (itr == objdumpList.end()) {
- return 0;
- }
-
- return (*itr);
-
- }
-
- void ObjdumpProcessor::loadAddressTable (
- ExecutableInfo* const executableInformation
- )
- {
- char* cStatus;
- int items;
- FILE* objdumpFile;
- uint32_t offset;
- char terminator;
-
- // Obtain the objdump file.
- if (!executableInformation->hasDynamicLibrary())
- objdumpFile = getFile( executableInformation->getFileName() );
- else
- objdumpFile = getFile( executableInformation->getLibraryName() );
-
- // Process all lines from the objdump file.
- while ( 1 ) {
-
- // Get the line.
- cStatus = fgets( inputBuffer, MAX_LINE_LENGTH, objdumpFile );
- if (cStatus == NULL) {
- break;
- }
- inputBuffer[ strlen(inputBuffer) - 1] = '\0';
-
- // See if it is the dump of an instruction.
- items = sscanf(
- inputBuffer,
- "%x%c",
- &offset, &terminator
- );
-
- // If it looks like an instruction ...
- if ((items == 2) && (terminator == ':')){
- objdumpList.push_back(
- executableInformation->getLoadAddress() + offset
- );
- }
- }
- }
-
- void ObjdumpProcessor::load(
- ExecutableInfo* const executableInformation
- )
- {
- char* cStatus;
- std::string currentSymbol = "";
- uint32_t endAddress;
- uint32_t instructionOffset;
- int items;
- objdumpLine_t lineInfo;
- FILE* objdumpFile;
- uint32_t offset;
- bool processSymbol = false;
- uint32_t startAddress = 0;
- char symbol[ MAX_LINE_LENGTH ];
- char terminator1;
- char terminator2;
- objdumpLines_t theInstructions;
-
- // Obtain the objdump file.
- if (!executableInformation->hasDynamicLibrary())
- objdumpFile = getFile( executableInformation->getFileName() );
- else
- objdumpFile = getFile( executableInformation->getLibraryName() );
-
- // Process all lines from the objdump file.
- while ( 1 ) {
-
- // Get the line.
- cStatus = fgets( inputBuffer, MAX_LINE_LENGTH, objdumpFile );
- if (cStatus == NULL) {
-
- // If we are currently processing a symbol, finalize it.
- if (processSymbol) {
- finalizeSymbol(
- executableInformation,
- currentSymbol,
- startAddress,
- executableInformation->getLoadAddress() + offset,
- theInstructions
- );
- fprintf(
- stderr,
- "WARNING: ObjdumpProcessor::load - analysis of symbol %s \n"
- " may be incorrect. It was the last symbol in %s\n"
- " and the length of its last instruction is assumed "
- " to be one.\n",
- currentSymbol.c_str(),
- executableInformation->getFileName().c_str()
- );
- }
- break;
- }
-
- inputBuffer[ strlen(inputBuffer) - 1] = '\0';
-
- lineInfo.line = inputBuffer;
- lineInfo.address = 0xffffffff;
- lineInfo.isInstruction = false;
- lineInfo.isNop = false;
- lineInfo.nopSize = 0;
- lineInfo.isBranch = false;
-
- // Look for the start of a symbol's objdump and extract
- // offset and symbol (i.e. offset <symbolname>:).
- items = sscanf(
- inputBuffer,
- "%x <%[^>]>%c",
- &offset, symbol, &terminator1
- );
-
- // If all items found, we are at the beginning of a symbol's objdump.
- if ((items == 3) && (terminator1 == ':')) {
-
- endAddress = executableInformation->getLoadAddress() + offset - 1;
-
- // If we are currently processing a symbol, finalize it.
- if (processSymbol) {
- finalizeSymbol(
- executableInformation,
- currentSymbol,
- startAddress,
- endAddress,
- theInstructions
- );
- }
-
- // Start processing of a new symbol.
- startAddress = 0;
- currentSymbol = "";
- processSymbol = false;
- theInstructions.clear();
-
- // See if the new symbol is one that we care about.
- if (SymbolsToAnalyze->isDesired( symbol )) {
- startAddress = executableInformation->getLoadAddress() + offset;
- currentSymbol = symbol;
- processSymbol = true;
- theInstructions.push_back( lineInfo );
- }
- }
-
- else if (processSymbol) {
-
- // See if it is the dump of an instruction.
- items = sscanf(
- inputBuffer,
- "%x%c\t%*[^\t]%c",
- &instructionOffset, &terminator1, &terminator2
- );
-
- // If it looks like an instruction ...
- if ((items == 3) && (terminator1 == ':') && (terminator2 == '\t')) {
-
- // update the line's information, save it and ...
- lineInfo.address =
- executableInformation->getLoadAddress() + instructionOffset;
- lineInfo.isInstruction = true;
- lineInfo.isNop = isNop( inputBuffer, lineInfo.nopSize );
- lineInfo.isBranch = isBranchLine( inputBuffer );
- }
-
- // Always save the line.
- theInstructions.push_back( lineInfo );
- }
- }
- }
-}