diff options
Diffstat (limited to 'covoar/GcovData.cc')
-rw-r--r-- | covoar/GcovData.cc | 508 |
1 files changed, 0 insertions, 508 deletions
diff --git a/covoar/GcovData.cc b/covoar/GcovData.cc deleted file mode 100644 index 6d10337..0000000 --- a/covoar/GcovData.cc +++ /dev/null @@ -1,508 +0,0 @@ -/* - * TODO: use strings instead of cstrings for reliability and saving memory - * TODO: use global buffers - * - */ - -/*! @file GcovData.cc - * @brief GcovData Implementation - * - * This file contains the implementation of the functions supporting - * reading *.gcno and writing *.gcda files for gcov support - */ - -#include <libgen.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -//#include <sys/stat.h> - -//#include "app_common.h" -#include "GcovData.h" -//#include "ExecutableInfo.h" -//#include "CoverageMap.h" -//#include "qemu-traces.h" - - -namespace Gcov { - - GcovData::GcovData() - { - numberOfFunctions = 0; - } - - GcovData::~GcovData() - { - } - - bool GcovData::readGcnoFile( const char* const fileName ) - { - int status; - FILE* gcovFile; - char* tempString; - char* tempString2; - char* tempString3; - - if ( strlen(fileName) >= FILE_NAME_LENGTH ){ - fprintf( - stderr, - "ERROR: File name is too long to be correctly stored: %u\n", - (unsigned int) strlen(fileName) - ); - return false; - } - strcpy( gcnoFileName, fileName ); - strcpy( gcdaFileName, fileName ); - strcpy( textFileName, fileName ); - strcpy( cFileName, fileName ); - tempString = strstr( gcdaFileName,".gcno" ); - tempString2 = strstr( textFileName,".gcno" ); - tempString3 = strstr( cFileName,".gcno" ); - - if ( (tempString == NULL) && (tempString2 == NULL) ){ - fprintf(stderr, "ERROR: incorrect name of *.gcno file\n"); - } - else - { - strcpy( tempString, ".gcda"); // construct gcda file name - strcpy( tempString2, ".txt"); // construct report file name - strcpy( tempString3, ".c"); // construct source file name - } - - // Debug message - // fprintf( stderr, "Readning file: %s\n", gcnoFileName); - - // Open the notes file. - gcovFile = fopen( gcnoFileName, "r" ); - if ( !gcovFile ) { - fprintf( stderr, "Unable to open %s\n", gcnoFileName ); - return false; - } - - // Read and validate the gcnoPreamble (magic, version, timestamp) from the file - status = readFilePreamble( &gcnoPreamble, gcovFile, GCNO_MAGIC ); - if ( status <= 0 ){ - fprintf( stderr, "Unable to read %s\n", gcnoFileName ); - fclose( gcovFile ); - return false; - } - - //Read all remaining frames from file - while( readFrame(gcovFile) ){} - - fclose( gcovFile ); - return true; - } - - - bool GcovData::writeGcdaFile () - { - gcov_preamble preamble; - gcov_frame_header header; - FILE* gcdaFile; - functions_iterator_t currentFunction; - arcs_iterator_t currentArc; - uint32_t buffer; - uint32_t countersFound; - uint32_t countersFoundSum; - uint64_t countersSum; - uint64_t countersMax; - uint64_t llBuffer[4096]; // TODO: Use common buffer - gcov_statistics objectStats; - gcov_statistics programStats; - size_t status; - - // Debug message - // fprintf( stderr, "Writing file: %s\n", gcdaFileName); - - // Lets clear counters sumators - countersSum = 0; - countersMax = 0; - countersFoundSum = 0; - - // Open the data file. - gcdaFile = fopen( gcdaFileName, "w" ); - if ( !gcdaFile ) { - fprintf( stderr, "Unable to create %s\n", gcdaFileName ); - return false; - } - - //Form preamble - preamble.magic = GCDA_MAGIC; - preamble.version = gcnoPreamble.version; - preamble.timestamp = gcnoPreamble.timestamp; - - //Write preamble - status = fwrite (&preamble , sizeof( preamble ), 1 , gcdaFile ); - if ( status != 1 ) - fprintf( stderr, "Error while writing gcda preamble to a file %s\n", gcdaFileName ); - - //Write function info and counter counts - for ( - currentFunction = functions.begin(); - currentFunction != functions.end(); - currentFunction++ - ) - { - //Write function announcement frame header (length always equals 2) - header.tag = GCOV_TAG_FUNCTION; - header.length = 2; - status = fwrite (&header, sizeof(header), 1, gcdaFile ); - if ( status != 1 ) - fprintf( stderr, "Error while writing function announcement to a file %s\n", gcdaFileName ); - - //Write function id - buffer = (*currentFunction)->getId(); - status = fwrite (&buffer, sizeof( buffer ), 1, gcdaFile ); - if ( status != 1 ) - fprintf( stderr, "Error while writing function id to a file %s\n", gcdaFileName ); - - //Write function checksum - buffer = (*currentFunction)->getChecksum(); - status = fwrite (&buffer, sizeof( buffer ), 1, gcdaFile ); - if ( status != 1 ) - fprintf( stderr, "Error while writing function checksum to a file %s\n", gcdaFileName ); - - // Determine how many counters there are - // and store their counts in buffer - countersFound = 0; - (*currentFunction)->getCounters( llBuffer, countersFound, countersSum, countersMax ); - countersFoundSum += countersFound; - - //Write info about counters - header.tag = GCOV_TAG_COUNTER; - header.length = countersFound * 2; - status = fwrite (&header, sizeof( header ), 1, gcdaFile ); - if ( status != 1 ) - fprintf( stderr, "Error while writing counter header to a file %s\n", gcdaFileName ); - - status = fwrite (llBuffer, sizeof( uint64_t ), countersFound , gcdaFile ); - if ( status != countersFound ) - fprintf( stderr, "Error while writing counter data to a file %s\n", gcdaFileName ); - } - - // Prepare frame with object file statistics - header.tag = GCOV_TAG_OBJECT_SUMMARY; - header.length = 9; - objectStats.checksum = 0; // TODO: have no idea hov to calculates it :) - objectStats.counters = countersFoundSum; - objectStats.runs = 1; // We are lying for now, we have no means of figuring this out - objectStats.sum = countersSum; // Sum of all counters - objectStats.max = countersMax; // max value for counter on last run, we have no clue - objectStats.sumMax = countersMax; // we have no clue - - // Write data - status = fwrite (&header, sizeof( header ), 1, gcdaFile ); - if ( status != 1 ) - fprintf( stderr, "Error while writing stats header to a file %s\n", gcdaFileName ); - status = fwrite (&objectStats, sizeof( objectStats ), 1, gcdaFile ); - if ( status != 1 ) - fprintf( stderr, "Error while writing object stats to a file %s\n", gcdaFileName ); - - - // Prepare frame with program statistics - header.tag = GCOV_TAG_PROGRAM_SUMMARY; - header.length = 9; - programStats.checksum = 0; // TODO: have no idea hov to calculate it :) - programStats.counters = countersFoundSum; - programStats.runs = 1; // We are lying for now, we have no clue - programStats.sum = countersSum; // Sum of all counters - programStats.max = countersMax; // max value for counter on last run, we have no clue - programStats.sumMax = countersMax; // we have no clue - - // Write data - status = fwrite (&header, sizeof( header ), 1, gcdaFile ); - if ( status != 1 ) - fprintf( stderr, "Error while writing stats header to a file %s\n", gcdaFileName ); - status = fwrite (&programStats, sizeof( programStats ), 1, gcdaFile ); - if ( status != 1 ) - fprintf( stderr, "Error while writing program stats to a file %s\n", gcdaFileName ); - - fclose( gcdaFile ); - - return true; - } - - bool GcovData::readFrame( - FILE* gcovFile - ) - { - gcov_frame_header header; - char buffer[512]; - uint32_t intBuffer[4096]; - uint32_t tempBlockId; - blocks_iterator_t tempBlockIterator; - int status; - GcovFunctionData* newFunction; - - status = readFrameHeader( &header, gcovFile); - - if ( status <= 0 ){ - // Not printing error message because this - // happenns at the end of each file - return false; - } - - switch (header.tag){ - - case GCOV_TAG_FUNCTION: - - numberOfFunctions++; - newFunction = new GcovFunctionData; - if ( !readFunctionFrame(header, gcovFile, newFunction) ){ - fprintf( stderr, "Error while reading FUNCTION from gcov file...\n" ); - return false; - } - functions.push_back(newFunction); - break; - - case GCOV_TAG_BLOCKS: - - status = fread( &intBuffer, 4, header.length, gcovFile ); - if ( status != (int) header.length){ - fprintf( - stderr, "Error while reading BLOCKS from gcov file...\n" - "Header lenght is %u instead of %u\n", - header.length, - status - ); - return false; - } - - for( uint32_t i = 0; i < header.length; i++ ) - functions.back()->addBlock(i, intBuffer[i], ""); - - break; - - case GCOV_TAG_ARCS: - - status = fread( &intBuffer, 4, header.length, gcovFile ); - if (status != (int) header.length){ - return false; - } - - for ( int i = 1; i < (int) header.length; i += 2 ) - functions.back()->addArc(intBuffer[0], intBuffer[i], intBuffer[i+1]); - - break; - - case GCOV_TAG_LINES: - - status = fread( &intBuffer, 4, 2, gcovFile ); - if (status != 2 || intBuffer[1] != 0){ - fprintf( - stderr, - "Error while reading block id for LINES from gcov file..." - ); - return false; - } - tempBlockId = intBuffer[0]; - header.length -= 2; - - // Find the right block - tempBlockIterator =functions.back()->findBlockById(tempBlockId); - - header.length -= readString(buffer, gcovFile); - functions.back()->setBlockFileName( tempBlockIterator, buffer ); - - status = fread( &intBuffer, 4, header.length, gcovFile ); - if (status != (int) header.length){ - fprintf( stderr, "Error while reading LINES from gcov file..." ); - return false; - } - - else - for (int i = 0; i < (int) (header.length - 2); i++) - functions.back()->addBlockLine( tempBlockIterator, intBuffer[i] ); - - break; - - default: - - fprintf( stderr, "\n\nERROR - encountered unknown *.gcno tag : 0x%x\n", header.tag ); - break; - } - - return true; - } - - int GcovData::readString( - char* buffer, //TODO: use global buffer here - FILE* gcovFile - ) - { - int status; - int length; - - status = fread( &length, sizeof(int), 1, gcovFile ); - if (status != 1){ - fprintf( stderr, "ERROR: Unable to read string length from gcov file\n" ); - return -1; - } - - status = fread( buffer, length * 4 , 1, gcovFile ); - if (status != 1){ - fprintf( stderr, "ERROR: Unable to read string from gcov file\n" ); - return -1; - } - - buffer[length * 4] = '\0'; - - return length +1; - } - - int GcovData::readFrameHeader( - gcov_frame_header* header, - FILE* gcovFile - ) - { - int status; - int length; - - length = sizeof(gcov_frame_header); - status = fread( header, length, 1, gcovFile ); - if (status != 1){ - //fprintf( stderr, "ERROR: Unable to read frame header from gcov file\n" ); - return -1; - } - - return length / 4; - } - - int GcovData::readFilePreamble( - gcov_preamble* preamble, - FILE* gcovFile, - uint32_t desiredMagic - ) - { - int status; - int length; - - length = sizeof( gcov_preamble ); - status = fread( preamble, sizeof( gcov_preamble), 1, gcovFile ); - if (status <= 0) { - fprintf( stderr, "Error while reading file preamble\n" ); - return -1; - } - - if ( preamble->magic != GCNO_MAGIC ) { - fprintf( stderr, "File is not a valid *.gcno output (magic: 0x%4x)\n", preamble->magic ); - return -1; - } - - return length / 4; - } - - bool GcovData::readFunctionFrame( - gcov_frame_header header, - FILE* gcovFile, - GcovFunctionData* function - ) - { - char buffer[512]; //TODO: use common buffers - uint32_t intBuffer[4096]; - int status; - - status = fread( &intBuffer, 8, 1, gcovFile ); - if (status != 1){ - fprintf( stderr, "ERROR: Unable to read Function ID & checksum\n" ); - return false; - } - header.length -= 2; - function->setId( intBuffer[0] ); - function->setChecksum( intBuffer[1] ); - - header.length -= readString( buffer, gcovFile ); - function->setFunctionName( buffer ); - header.length -= readString( buffer, gcovFile ); - function->setFileName( buffer ); - status = fread( &intBuffer, 4, header.length, gcovFile ); - if (status <= 0){ - fprintf( stderr, "ERROR: Unable to read Function starting line number\n" ); - return false; - } - function->setFirstLineNumber( intBuffer[0] ); - - return true; - } - - bool GcovData::writeReportFile() - { - functions_iterator_t currentFunction; - uint32_t i = 1; //iterator - FILE* textFile; - - // Debug message - // fprintf( stderr, "Writing file: %s\n", textFileName); - - // Open the data file. - textFile = fopen( textFileName, "w" ); - if ( !textFile ) { - fprintf( stderr, "Unable to create %s\n", textFileName ); - return false; - } - - printGcnoFileInfo( textFile ); - - for ( - currentFunction = functions.begin(); - currentFunction != functions.end(); - currentFunction++ - ) - { - (*currentFunction)->printFunctionInfo( textFile, i ); - (*currentFunction)->printCoverageInfo( textFile, i ); - i++; - } - - fclose ( textFile ); - return true; - } - - void GcovData::printGcnoFileInfo( FILE * textFile ) - { - fprintf( - textFile, - "\nFILE:\t\t\t%s\n" - "magic:\t\t\t%x\n" - "version:\t\t%x\n" - "timestamp:\t\t%x\n" - "functions found: \t%u\n\n", - gcnoFileName, - gcnoPreamble.magic, - gcnoPreamble.version, - gcnoPreamble.timestamp, - numberOfFunctions - ); - } - - void GcovData::writeGcovFile( ) - { - char path[512]; - char command[512]; - - //fprintf (stderr, "Attempting to run gcov for: %s\n", cFileName ); - strcpy( path, cFileName ); - dirname( path ); - sprintf( command, "( cd %s && gcov %s &>> gcov.log)", path, basename( cFileName ) ); - //fprintf (stderr, "> %s\n", command ); - system( command ); - } - - bool GcovData::processCounters( ) - { - functions_iterator_t currentFunction; - bool status = true; - for ( - currentFunction = functions.begin(); - currentFunction != functions.end(); - currentFunction++ - ) - { - if ( !(*currentFunction)->processFunctionCounters( ) ) - status = false; - } - - return status; - } -} |