mirror of
https://git.rtems.org/rtems-tools/
synced 2025-06-11 22:19:50 +08:00
276 lines
6.9 KiB
C++
276 lines
6.9 KiB
C++
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include "ReportsText.h"
|
|
#include "app_common.h"
|
|
#include "CoverageRanges.h"
|
|
#include "DesiredSymbols.h"
|
|
#include "Explanations.h"
|
|
#include "ObjdumpProcessor.h"
|
|
|
|
|
|
namespace Coverage {
|
|
|
|
ReportsText::ReportsText( time_t timestamp ):
|
|
ReportsBase( timestamp )
|
|
{
|
|
reportExtension_m = ".txt";
|
|
}
|
|
|
|
ReportsText::~ReportsText()
|
|
{
|
|
}
|
|
|
|
void ReportsText::AnnotatedStart(
|
|
FILE* aFile
|
|
)
|
|
{
|
|
fprintf(
|
|
aFile,
|
|
"========================================"
|
|
"=======================================\n"
|
|
);
|
|
}
|
|
|
|
void ReportsText::AnnotatedEnd(
|
|
FILE* aFile
|
|
)
|
|
{
|
|
}
|
|
|
|
void ReportsText::PutAnnotatedLine(
|
|
FILE* aFile,
|
|
AnnotatedLineState_t state,
|
|
std::string line,
|
|
uint32_t id
|
|
)
|
|
{
|
|
fprintf( aFile, "%s\n", line.c_str());
|
|
}
|
|
|
|
bool ReportsText::PutNoBranchInfo(
|
|
FILE* report
|
|
)
|
|
{
|
|
if ( BranchInfoAvailable )
|
|
fprintf( report, "All branch paths taken.\n" );
|
|
else
|
|
fprintf( report, "No branch information found.\n" );
|
|
return true;
|
|
}
|
|
|
|
|
|
bool ReportsText::PutBranchEntry(
|
|
FILE* report,
|
|
unsigned int number,
|
|
Coverage::DesiredSymbols::symbolSet_t::iterator symbolPtr,
|
|
Coverage::CoverageRanges::ranges_t::iterator rangePtr
|
|
)
|
|
{
|
|
const Coverage::Explanation* explanation;
|
|
|
|
// Add an entry to the report
|
|
fprintf(
|
|
report,
|
|
"============================================\n"
|
|
"Symbol : %s (0x%x)\n"
|
|
"Line : %s (0x%x)\n"
|
|
"Size in Bytes : %d\n",
|
|
symbolPtr->first.c_str(),
|
|
symbolPtr->second.baseAddress,
|
|
rangePtr->lowSourceLine.c_str(),
|
|
rangePtr->lowAddress,
|
|
rangePtr->highAddress - rangePtr->lowAddress + 1
|
|
);
|
|
|
|
if (rangePtr->reason ==
|
|
Coverage::CoverageRanges::UNCOVERED_REASON_BRANCH_ALWAYS_TAKEN)
|
|
fprintf(
|
|
report, "Reason : %s\n\n", "ALWAYS TAKEN"
|
|
);
|
|
else if (rangePtr->reason ==
|
|
Coverage::CoverageRanges::UNCOVERED_REASON_BRANCH_NEVER_TAKEN)
|
|
fprintf( report, "Reason : %s\n\n", "NEVER TAKEN" );
|
|
|
|
// See if an explanation is available
|
|
explanation = AllExplanations->lookupExplanation( rangePtr->lowSourceLine );
|
|
|
|
if ( !explanation ) {
|
|
fprintf(
|
|
report,
|
|
"Classification: NONE\n"
|
|
"\n"
|
|
"Explanation:\n"
|
|
"No Explanation\n"
|
|
);
|
|
} else {
|
|
fprintf(
|
|
report,
|
|
"Classification: %s\n"
|
|
"\n"
|
|
"Explanation:\n",
|
|
explanation->classification.c_str()
|
|
);
|
|
|
|
for ( unsigned int i=0 ;
|
|
i < explanation->explanation.size();
|
|
i++) {
|
|
fprintf(
|
|
report,
|
|
"%s\n",
|
|
explanation->explanation[i].c_str()
|
|
);
|
|
}
|
|
}
|
|
|
|
fprintf(
|
|
report, "============================================\n"
|
|
);
|
|
|
|
return true;
|
|
}
|
|
|
|
void ReportsText::putCoverageNoRange(
|
|
FILE* report,
|
|
FILE* noRangeFile,
|
|
unsigned int number,
|
|
std::string symbol
|
|
)
|
|
{
|
|
fprintf(
|
|
report,
|
|
"============================================\n"
|
|
"Symbol : %s\n\n"
|
|
" *** NEVER REFERENCED ***\n\n"
|
|
"This symbol was never referenced by an analyzed executable.\n"
|
|
"Therefore there is no size or disassembly for this symbol.\n"
|
|
"This could be due to symbol misspelling or lack of a test for\n"
|
|
"this symbol.\n"
|
|
"============================================\n",
|
|
symbol.c_str()
|
|
);
|
|
fprintf( noRangeFile, "%s\n", symbol.c_str() );
|
|
}
|
|
|
|
bool ReportsText::PutCoverageLine(
|
|
FILE* report,
|
|
unsigned int number,
|
|
Coverage::DesiredSymbols::symbolSet_t::iterator ditr,
|
|
Coverage::CoverageRanges::ranges_t::iterator ritr
|
|
)
|
|
{
|
|
const Coverage::Explanation* explanation;
|
|
|
|
fprintf(
|
|
report,
|
|
"============================================\n"
|
|
"Index : %d\n"
|
|
"Symbol : %s (0x%x)\n"
|
|
"Starting Line : %s (0x%x)\n"
|
|
"Ending Line : %s (0x%x)\n"
|
|
"Size in Bytes : %d\n"
|
|
"Size in Instructions : %d\n\n",
|
|
ritr->id,
|
|
ditr->first.c_str(),
|
|
ditr->second.baseAddress,
|
|
ritr->lowSourceLine.c_str(),
|
|
ritr->lowAddress,
|
|
ritr->highSourceLine.c_str(),
|
|
ritr->highAddress,
|
|
ritr->highAddress - ritr->lowAddress + 1,
|
|
ritr->instructionCount
|
|
);
|
|
|
|
explanation = AllExplanations->lookupExplanation( ritr->lowSourceLine );
|
|
|
|
if ( !explanation ) {
|
|
fprintf(
|
|
report,
|
|
"Classification: NONE\n"
|
|
"\n"
|
|
"Explanation:\n"
|
|
"No Explanation\n"
|
|
);
|
|
} else {
|
|
fprintf(
|
|
report,
|
|
"Classification: %s\n"
|
|
"\n"
|
|
"Explanation:\n",
|
|
explanation->classification.c_str()
|
|
);
|
|
|
|
for ( unsigned int i=0; i < explanation->explanation.size(); i++) {
|
|
fprintf( report,"%s\n", explanation->explanation[i].c_str() );
|
|
}
|
|
}
|
|
|
|
fprintf(report, "============================================\n");
|
|
return true;
|
|
}
|
|
|
|
bool ReportsText::PutSizeLine(
|
|
FILE* report,
|
|
unsigned int number,
|
|
Coverage::DesiredSymbols::symbolSet_t::iterator symbol,
|
|
Coverage::CoverageRanges::ranges_t::iterator range
|
|
)
|
|
{
|
|
fprintf(
|
|
report,
|
|
"%d\t%s\t%s\n",
|
|
range->highAddress - range->lowAddress + 1,
|
|
symbol->first.c_str(),
|
|
range->lowSourceLine.c_str()
|
|
);
|
|
return true;
|
|
}
|
|
|
|
bool ReportsText::PutSymbolSummaryLine(
|
|
FILE* report,
|
|
unsigned int number,
|
|
Coverage::DesiredSymbols::symbolSet_t::iterator symbol
|
|
)
|
|
{
|
|
float uncoveredBytes;
|
|
float uncoveredInstructions;
|
|
|
|
if ( symbol->second.stats.sizeInInstructions == 0 )
|
|
uncoveredInstructions = 0;
|
|
else
|
|
uncoveredInstructions = (symbol->second.stats.uncoveredInstructions*100.0)/
|
|
symbol->second.stats.sizeInInstructions;
|
|
|
|
if ( symbol->second.stats.sizeInBytes == 0 )
|
|
uncoveredBytes = 0;
|
|
else
|
|
uncoveredBytes = (symbol->second.stats.uncoveredBytes*100.0)/
|
|
symbol->second.stats.sizeInBytes;
|
|
|
|
fprintf(
|
|
report,
|
|
"============================================\n"
|
|
"Symbol : %s\n"
|
|
"Total Size in Bytes : %d\n"
|
|
"Total Size in Instructions : %d\n"
|
|
"Total number Branches : %d\n"
|
|
"Total Always Taken : %d\n"
|
|
"Total Never Taken : %d\n"
|
|
"Percentage Uncovered Instructions : %.2f\n"
|
|
"Percentage Uncovered Bytes : %.2f\n",
|
|
symbol->first.c_str(),
|
|
symbol->second.stats.sizeInBytes,
|
|
symbol->second.stats.sizeInInstructions,
|
|
symbol->second.stats.branchesNotExecuted + symbol->second.stats.branchesExecuted,
|
|
symbol->second.stats.branchesAlwaysTaken,
|
|
symbol->second.stats.branchesNeverTaken,
|
|
uncoveredInstructions,
|
|
uncoveredBytes
|
|
);
|
|
|
|
fprintf(report, "============================================\n");
|
|
return true;
|
|
}
|
|
|
|
}
|