mirror of
https://git.rtems.org/rtems-tools/
synced 2025-06-12 12:03:44 +08:00
covoar: Add symbol set reader and ELF data parser to covoar.
Add ability to organize symbol sets of libraries in INI file and then read them with covoar and load the symbols directly from the libraries. rtems-tools/../testing: Add configuration files for coverage analysis. A number of covoar options are not required and are defaulted. Co-author: Krzysztof Miesowicz <krzysztof.miesowicz@gmail.com> Co-author: Vijay Kumar Banerjee <vijaykumar9597@gmail.com> Co-author: Chris Johns <chrisj@rtems.org>
This commit is contained in:
parent
e0a52a4fe4
commit
3e187baeb9
@ -16,6 +16,13 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "rld.h"
|
||||
#include <rld-config.h>
|
||||
#include "rld-symbols.h"
|
||||
#include "rld-files.h"
|
||||
|
||||
#include "DesiredSymbols.h"
|
||||
#include "app_common.h"
|
||||
#include "CoverageMap.h"
|
||||
@ -31,75 +38,90 @@ namespace Coverage {
|
||||
{
|
||||
}
|
||||
|
||||
void DesiredSymbols::load(
|
||||
const char* const symbolsFile
|
||||
bool DesiredSymbols::load(
|
||||
const std::string& symbolsSet,
|
||||
const std::string& buildTarget,
|
||||
const std::string& buildBSP,
|
||||
bool verbose
|
||||
)
|
||||
{
|
||||
int cStatus;
|
||||
bool done = false;
|
||||
FILE* sFile;
|
||||
SymbolInformation* symInfo;
|
||||
int line = 1;
|
||||
std::string symbol;
|
||||
rld::files::cache cache;
|
||||
bool r = true;
|
||||
|
||||
// Ensure that symbols file name is given.
|
||||
if ( !symbolsFile ) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"ERROR: DesiredSymbols::load - no symbols file specified\n"
|
||||
);
|
||||
exit(-1);
|
||||
}
|
||||
//
|
||||
// Load the INI file looking for a top level:
|
||||
//
|
||||
// [symbols-sets]
|
||||
// sets = A, B, C
|
||||
//
|
||||
// For each set read the libraries from the configuration file and load.
|
||||
//
|
||||
// [A]
|
||||
// libraries = @BUILD-PREFIX@/c/@BSP@/A/libA.a
|
||||
//
|
||||
// [B]
|
||||
// libraries = @BUILD-PREFIX@/c/@BSP@/B/libB.a
|
||||
//
|
||||
try {
|
||||
cache.open();
|
||||
|
||||
// Open symbols file.
|
||||
sFile = fopen( symbolsFile, "r" );
|
||||
if ( !sFile ) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"ERROR: DesiredSymbols::load - unable to open symbols file %s\n",
|
||||
symbolsFile
|
||||
);
|
||||
exit(-1);
|
||||
}
|
||||
rld::config::config config;
|
||||
|
||||
// Process symbols file.
|
||||
while ( !done ) {
|
||||
if (verbose)
|
||||
std::cerr << "Loading symbol sets: " << symbolsSet << std::endl;
|
||||
|
||||
symInfo = new SymbolInformation;
|
||||
config.load (symbolsSet);
|
||||
|
||||
// Skip blank lines between symbols
|
||||
do {
|
||||
inputBuffer[0] = '\0';
|
||||
inputBuffer2[0] = '\0';
|
||||
cStatus = fscanf( sFile, "%s %s", inputBuffer, inputBuffer2 );
|
||||
if ( cStatus == EOF ) {
|
||||
done = true;
|
||||
const rld::config::section& sym_section = config.get_section("symbol-sets");
|
||||
|
||||
rld::strings sets;
|
||||
rld::config::parse_items (sym_section, "sets", sets, true);
|
||||
|
||||
for (const std::string set : sets) {
|
||||
if (verbose)
|
||||
std::cerr << " Symbol set: " << set << std::endl;
|
||||
const rld::config::section& set_section = config.get_section(set);
|
||||
rld::strings libs;
|
||||
rld::config::parse_items (set_section, "libraries", libs, true);
|
||||
for (std::string lib : libs) {
|
||||
lib = rld::find_replace(lib, "@BUILD-TARGET@", buildTarget);
|
||||
lib = rld::find_replace(lib, "@BSP@", buildBSP);
|
||||
if (verbose)
|
||||
std::cerr << " Loading library: " << lib << std::endl;
|
||||
cache.add(lib);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
rld::symbols::table symbols;
|
||||
|
||||
cache.load_symbols (symbols, true);
|
||||
|
||||
for (auto& kv : symbols.globals()) {
|
||||
const rld::symbols::symbol& sym = *(kv.second);
|
||||
set[sym.name()] = *(new SymbolInformation);
|
||||
}
|
||||
for (auto& kv : symbols.weaks()) {
|
||||
const rld::symbols::symbol& sym = *(kv.second);
|
||||
set[sym.name()] = *(new SymbolInformation);
|
||||
}
|
||||
for (auto& kv : symbols.locals()) {
|
||||
const rld::symbols::symbol& sym = *(kv.second);
|
||||
set[sym.name()] = *(new SymbolInformation);
|
||||
}
|
||||
|
||||
} catch (rld::error re) {
|
||||
std::cerr << "error: "
|
||||
<< re.where << ": " << re.what
|
||||
<< std::endl;
|
||||
r = false;
|
||||
} catch (...) {
|
||||
cache.close();
|
||||
throw;
|
||||
}
|
||||
|
||||
cache.close();
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void DesiredSymbols::preprocess( void )
|
||||
|
@ -293,9 +293,17 @@ namespace Coverage {
|
||||
/*!
|
||||
* This method creates the set of symbols to analyze from the symbols
|
||||
* listed in the specified file.
|
||||
*
|
||||
* @param[in] symbolsSet An INI format file of the symbols to be loaded.
|
||||
* @param[in] buildTarget The build target
|
||||
* @param[in] buildBSP The BSP
|
||||
* @return Returns false if the load fails.
|
||||
*/
|
||||
void load(
|
||||
const char* const symbolsFile
|
||||
bool load(
|
||||
const std::string& symbolsSet,
|
||||
const std::string& buildTarget,
|
||||
const std::string& buildBSP,
|
||||
bool verbose
|
||||
);
|
||||
|
||||
/*!
|
||||
|
@ -67,12 +67,12 @@ namespace Coverage {
|
||||
return aCoverageMap;
|
||||
}
|
||||
|
||||
std::string ExecutableInfo::getFileName ( void ) const
|
||||
const std::string& ExecutableInfo::getFileName ( void ) const
|
||||
{
|
||||
return executableName;
|
||||
}
|
||||
|
||||
std::string ExecutableInfo::getLibraryName( void ) const
|
||||
const std::string& ExecutableInfo::getLibraryName( void ) const
|
||||
{
|
||||
return libraryName;
|
||||
}
|
||||
|
@ -67,14 +67,14 @@ namespace Coverage {
|
||||
*
|
||||
* @return Returns the executable's file name
|
||||
*/
|
||||
std::string getFileName( void ) const;
|
||||
const std::string& getFileName( void ) const;
|
||||
|
||||
/*!
|
||||
* This method returns the library name associated with the executable.
|
||||
*
|
||||
* @return Returns the executable's library name
|
||||
*/
|
||||
std::string getLibraryName( void ) const;
|
||||
const std::string& getLibraryName( void ) const;
|
||||
|
||||
/*!
|
||||
* This method returns the load address of the dynamic library
|
||||
@ -111,7 +111,7 @@ namespace Coverage {
|
||||
* This method indicates whether a dynamic library has been
|
||||
* associated with the executable.
|
||||
*
|
||||
* @return Returns TRUE if
|
||||
* @return Returns TRUE if
|
||||
*/
|
||||
bool hasDynamicLibrary( void );
|
||||
|
||||
|
@ -247,15 +247,15 @@ namespace Coverage {
|
||||
try
|
||||
{
|
||||
status = rld::process::execute( TargetInfo->getObjdump(),
|
||||
args, objdumpFile.name(), err.name() );
|
||||
args, objdumpFile.name(), err.name() );
|
||||
if ( (status.type != rld::process::status::normal)
|
||||
|| (status.code != 0) ) {
|
||||
throw rld::error( "Objdump error", "generating objdump" );
|
||||
}
|
||||
} catch( rld::error& err )
|
||||
{
|
||||
std::cout << "Error while running" << TargetInfo->getObjdump()
|
||||
<< "for" << fileName << std::endl;
|
||||
std::cout << "Error while running " << TargetInfo->getObjdump()
|
||||
<< " on " << fileName << std::endl;
|
||||
std::cout << err.what << " in " << err.where << std::endl;
|
||||
return;
|
||||
}
|
||||
|
@ -1,6 +1,11 @@
|
||||
#ifndef __APP_COMMON_h
|
||||
#define __APP_COMMON_h
|
||||
|
||||
/*
|
||||
* This file needs to be removed and these globals removed from the
|
||||
* global scope. For example SymbolsToAnalyze is never destructed.
|
||||
*/
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "DesiredSymbols.h"
|
||||
@ -22,8 +27,8 @@ extern char inputBuffer[MAX_LINE_LENGTH];
|
||||
extern char inputBuffer2[MAX_LINE_LENGTH];
|
||||
|
||||
|
||||
bool FileIsNewer( const char *f1, const char *f2 );
|
||||
bool FileIsReadable( const char *f1 );
|
||||
bool FileIsNewer( const char *f1, const char *f2 );
|
||||
bool FileIsReadable( const char *f1 );
|
||||
bool ReadUntilFound( FILE *file, const char *line );
|
||||
|
||||
#endif
|
||||
|
@ -29,34 +29,92 @@
|
||||
#define kill(p,s) raise(s)
|
||||
#endif
|
||||
|
||||
typedef std::list<std::string> CoverageNames;
|
||||
typedef std::list<Coverage::ExecutableInfo*> Executables;
|
||||
|
||||
/*
|
||||
* Variables to control general behavior
|
||||
* Create a build path from the executable paths. Also extract the build prefix
|
||||
* and BSP names.
|
||||
*/
|
||||
const char* coverageFileExtension = NULL;
|
||||
std::list<std::string> coverageFileNames;
|
||||
int coverageExtensionLength = 0;
|
||||
Coverage::CoverageFormats_t coverageFormat;
|
||||
Coverage::CoverageReaderBase* coverageReader = NULL;
|
||||
char* executable = NULL;
|
||||
const char* executableExtension = NULL;
|
||||
int executableExtensionLength = 0;
|
||||
std::list<Coverage::ExecutableInfo*> executablesToAnalyze;
|
||||
const char* explanations = NULL;
|
||||
char* progname;
|
||||
const char* symbolsFile = NULL;
|
||||
const char* gcnosFileName = NULL;
|
||||
char gcnoFileName[FILE_NAME_LENGTH];
|
||||
char gcdaFileName[FILE_NAME_LENGTH];
|
||||
char gcovBashCommand[256];
|
||||
const char* target = NULL;
|
||||
const char* format = NULL;
|
||||
FILE* gcnosFile = NULL;
|
||||
Gcov::GcovData* gcovFile;
|
||||
static void createBuildPath(Executables& executablesToAnalyze,
|
||||
std::string& buildPath,
|
||||
std::string& buildPrefix,
|
||||
std::string& buildBSP)
|
||||
{
|
||||
for (const auto& exe : executablesToAnalyze) {
|
||||
rld::strings eparts;
|
||||
rld::split(eparts, rld::path::path_abs(exe->getFileName()), RLD_PATH_SEPARATOR);
|
||||
std::string fail; // empty means all is OK else an error string
|
||||
for (rld::path::paths::reverse_iterator pri = eparts.rbegin();
|
||||
pri != eparts.rend();
|
||||
++pri) {
|
||||
if (*pri == "testsuites") {
|
||||
++pri;
|
||||
if (pri == eparts.rend()) {
|
||||
fail = "invalid executable path, no BSP";
|
||||
break;
|
||||
}
|
||||
if (buildBSP.empty()) {
|
||||
buildBSP = *pri;
|
||||
} else {
|
||||
if (buildBSP != *pri) {
|
||||
fail = "executable BSP does not match: " + buildBSP;
|
||||
break;
|
||||
}
|
||||
}
|
||||
++pri;
|
||||
if (pri == eparts.rend() || *pri != "c") {
|
||||
fail = "invalid executable path, no 'c'";
|
||||
break;
|
||||
}
|
||||
++pri;
|
||||
if (pri == eparts.rend()) {
|
||||
fail = "invalid executable path, no arch prefix";
|
||||
break;
|
||||
}
|
||||
if (buildPrefix.empty()) {
|
||||
buildPrefix = *pri;
|
||||
} else {
|
||||
if (buildBSP != *pri) {
|
||||
fail = "executable build prefix does not match: " + buildPrefix;
|
||||
break;
|
||||
}
|
||||
}
|
||||
++pri;
|
||||
if (pri == eparts.rend()) {
|
||||
fail = "invalid executable path, no build top";
|
||||
break;
|
||||
}
|
||||
//
|
||||
// The remaining parts of the path is the build path. Iterator over them
|
||||
// and collect into a new paths variable to join to make a path.
|
||||
//
|
||||
rld::path::paths bparts;
|
||||
for (; pri != eparts.rend(); ++pri)
|
||||
bparts.insert(bparts.begin(), *pri);
|
||||
std::string thisBuildPath;
|
||||
rld::path::path_join(thisBuildPath, bparts, thisBuildPath);
|
||||
if (buildPath.empty()) {
|
||||
buildPath = thisBuildPath;
|
||||
} else {
|
||||
if (buildBSP != *pri) {
|
||||
fail = "executable build path does not match: " + buildPath;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!fail.empty()) {
|
||||
std::cerr << "ERROR: " << fail << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Print program usage message
|
||||
*/
|
||||
void usage()
|
||||
void usage(const std::string& progname)
|
||||
{
|
||||
fprintf(
|
||||
stderr,
|
||||
@ -69,17 +127,18 @@ void usage()
|
||||
" -f FORMAT - coverage file format "
|
||||
"(RTEMS, QEMU, TSIM or Skyeye)\n"
|
||||
" -E EXPLANATIONS - name of file with explanations\n"
|
||||
" -s SYMBOLS_FILE - name of file with symbols of interest\n"
|
||||
" -s SYMBOL_SET_FILE - path to the INI format symbol sets\n"
|
||||
" -1 EXECUTABLE - name of executable to get symbols from\n"
|
||||
" -e EXE_EXTENSION - extension of the executables to analyze\n"
|
||||
" -c COVERAGEFILE_EXTENSION - extension of the coverage files to analyze\n"
|
||||
" -g GCNOS_LIST - name of file with list of *.gcno files\n"
|
||||
" -p PROJECT_NAME - name of the project\n"
|
||||
" -C ConfigurationFileName - name of configuration file\n"
|
||||
" -O Output_Directory - name of output directory (default=."
|
||||
" -O Output_Directory - name of output directory (default=.\n"
|
||||
" -d debug - disable cleaning of tempfiles."
|
||||
"\n",
|
||||
progname,
|
||||
progname
|
||||
progname.c_str(),
|
||||
progname.c_str()
|
||||
);
|
||||
}
|
||||
|
||||
@ -125,42 +184,58 @@ int main(
|
||||
char** argv
|
||||
)
|
||||
{
|
||||
std::list<std::string>::iterator citr;
|
||||
std::string coverageFileName;
|
||||
std::list<Coverage::ExecutableInfo*>::iterator eitr;
|
||||
Coverage::ExecutableInfo* executableInfo = NULL;
|
||||
int i;
|
||||
int opt;
|
||||
const char* singleExecutable = NULL;
|
||||
rld::process::tempfile objdumpFile( ".dmp" );
|
||||
rld::process::tempfile err( ".err" );
|
||||
bool debug = false;
|
||||
std::string option;
|
||||
CoverageNames coverageFileNames;
|
||||
std::string coverageFileName;
|
||||
Executables executablesToAnalyze;
|
||||
Coverage::ExecutableInfo* executableInfo = NULL;
|
||||
std::string executableExtension = "exe";
|
||||
std::string coverageExtension = "cov";
|
||||
Coverage::CoverageFormats_t coverageFormat;
|
||||
Coverage::CoverageReaderBase* coverageReader = NULL;
|
||||
char* executable = NULL;
|
||||
const char* explanations = NULL;
|
||||
const char* gcnosFileName = NULL;
|
||||
char gcnoFileName[FILE_NAME_LENGTH];
|
||||
char gcdaFileName[FILE_NAME_LENGTH];
|
||||
char gcovBashCommand[256];
|
||||
std::string target;
|
||||
const char* format = "html";
|
||||
FILE* gcnosFile = NULL;
|
||||
Gcov::GcovData* gcovFile;
|
||||
const char* singleExecutable = NULL;
|
||||
rld::process::tempfile objdumpFile( ".dmp" );
|
||||
rld::process::tempfile err( ".err" );
|
||||
rld::process::tempfile syms( ".syms" );
|
||||
bool debug = false;
|
||||
std::string symbolSet;
|
||||
std::string progname;
|
||||
std::string option;
|
||||
int opt;
|
||||
|
||||
setup_signals();
|
||||
|
||||
//
|
||||
// Process command line options.
|
||||
//
|
||||
progname = argv[0];
|
||||
progname = rld::path::basename(argv[0]);
|
||||
|
||||
while ((opt = getopt(argc, argv, "1:L:e:c:g:E:f:s:T:O:p:v:d")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "1:L:e:c:g:E:f:s:S:T:O:p:vd")) != -1) {
|
||||
switch (opt) {
|
||||
case '1': singleExecutable = optarg; break;
|
||||
case 'L': dynamicLibrary = optarg; break;
|
||||
case 'e': executableExtension = optarg; break;
|
||||
case 'c': coverageFileExtension = optarg; break;
|
||||
case 'g': gcnosFileName = optarg; break;
|
||||
case 'E': explanations = optarg; break;
|
||||
case 'f': format = optarg; break;
|
||||
case 's': symbolsFile = optarg; break;
|
||||
case 'T': target = optarg; break;
|
||||
case 'O': outputDirectory = optarg; break;
|
||||
case 'v': Verbose = true; break;
|
||||
case 'p': projectName = optarg; break;
|
||||
case 'd': debug = true; break;
|
||||
case '1': singleExecutable = optarg; break;
|
||||
case 'L': dynamicLibrary = optarg; break;
|
||||
case 'e': executableExtension = optarg; break;
|
||||
case 'c': coverageExtension = optarg; break;
|
||||
case 'g': gcnosFileName = optarg; break;
|
||||
case 'E': explanations = optarg; break;
|
||||
case 'f': format = optarg; break;
|
||||
case 'S': symbolSet = optarg; break;
|
||||
case 'T': target = optarg; break;
|
||||
case 'O': outputDirectory = optarg; break;
|
||||
case 'v': Verbose = true; break;
|
||||
case 'p': projectName = optarg; break;
|
||||
case 'd': debug = true; break;
|
||||
default: /* '?' */
|
||||
usage();
|
||||
usage(progname);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
@ -171,18 +246,10 @@ int main(
|
||||
*/
|
||||
|
||||
/*
|
||||
* Target name must be set.
|
||||
* Validate that we have a symbols of interest file.
|
||||
*/
|
||||
if ( !target ) {
|
||||
option = "target -T";
|
||||
throw option;
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate simulator format.
|
||||
*/
|
||||
if ( !format ) {
|
||||
option = "format -f";
|
||||
if ( symbolSet.empty() ) {
|
||||
option = "symbol set file -S";
|
||||
throw option;
|
||||
}
|
||||
|
||||
@ -194,22 +261,6 @@ int main(
|
||||
throw option;
|
||||
}
|
||||
|
||||
/*
|
||||
* Has coverage file extension been specified.
|
||||
*/
|
||||
if ( !coverageFileExtension ) {
|
||||
option = "coverage extension -c";
|
||||
throw option;
|
||||
}
|
||||
|
||||
/*
|
||||
* Has executable extension been specified.
|
||||
*/
|
||||
if ( !executableExtension ) {
|
||||
option = "executable extension -e";
|
||||
throw option;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for project name.
|
||||
*/
|
||||
@ -220,8 +271,8 @@ int main(
|
||||
}
|
||||
catch( std::string option )
|
||||
{
|
||||
std::cout << "error missing option: " + option << std::endl;
|
||||
usage();
|
||||
std::cerr << "error missing option: " + option << std::endl;
|
||||
usage(progname);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@ -238,7 +289,7 @@ int main(
|
||||
);
|
||||
} else {
|
||||
|
||||
for (i=optind; i < argc; i++) {
|
||||
for (int i = optind; i < argc; i++) {
|
||||
// Ensure that the coverage file is readable.
|
||||
if (!FileIsReadable( argv[i] )) {
|
||||
fprintf(
|
||||
@ -266,11 +317,10 @@ int main(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If not invoked with a single executable, process the remaining
|
||||
// arguments as executables and derive the coverage file names.
|
||||
else {
|
||||
for (i = optind; i < argc; i++) {
|
||||
// If not invoked with a single executable, process the remaining
|
||||
// arguments as executables and derive the coverage file names.
|
||||
for (int i = optind; i < argc; i++) {
|
||||
|
||||
// Ensure that the executable is readable.
|
||||
if (!FileIsReadable( argv[i] )) {
|
||||
@ -282,9 +332,9 @@ int main(
|
||||
} else {
|
||||
coverageFileName = argv[i];
|
||||
coverageFileName.replace(
|
||||
coverageFileName.length() - executableExtensionLength,
|
||||
executableExtensionLength,
|
||||
coverageFileExtension
|
||||
coverageFileName.length() - executableExtension.size(),
|
||||
executableExtension.size(),
|
||||
coverageExtension
|
||||
);
|
||||
|
||||
if (!FileIsReadable( coverageFileName.c_str() )) {
|
||||
@ -310,6 +360,33 @@ int main(
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// The executablesToAnalyze and coverageFileNames containers need
|
||||
// to be the name size of some of the code below breaks. Lets
|
||||
// check and make sure.
|
||||
if (executablesToAnalyze.size() != coverageFileNames.size()) {
|
||||
std::cerr << "ERROR: executables and coverage name size mismatch" << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
//
|
||||
// Find the top of the BSP's build tree and if we have found the top
|
||||
// check the executable is under the same path and BSP.
|
||||
//
|
||||
std::string buildPath;
|
||||
std::string buildTarget;
|
||||
std::string buildBSP;
|
||||
createBuildPath(executablesToAnalyze,
|
||||
buildPath,
|
||||
buildTarget,
|
||||
buildBSP);
|
||||
|
||||
//
|
||||
// Use a command line target if provided.
|
||||
//
|
||||
if (!target.empty()) {
|
||||
buildTarget = target;
|
||||
}
|
||||
|
||||
if (Verbose) {
|
||||
if (singleExecutable) {
|
||||
fprintf(
|
||||
@ -323,12 +400,12 @@ int main(
|
||||
);
|
||||
}
|
||||
fprintf( stderr, "Coverage Format : %s\n", format );
|
||||
fprintf( stderr, "Target : %s\n", PrintableString(target) );
|
||||
fprintf( stderr, "Target : %s\n", buildTarget.c_str() );
|
||||
fprintf( stderr, "\n" );
|
||||
#if 1
|
||||
|
||||
// Process each executable/coverage file pair.
|
||||
eitr = executablesToAnalyze.begin();
|
||||
for (citr = coverageFileNames.begin();
|
||||
Executables::iterator eitr = executablesToAnalyze.begin();
|
||||
for (CoverageNames::iterator citr = coverageFileNames.begin();
|
||||
citr != coverageFileNames.end();
|
||||
citr++) {
|
||||
|
||||
@ -342,7 +419,6 @@ int main(
|
||||
if (!singleExecutable)
|
||||
eitr++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
@ -350,19 +426,22 @@ int main(
|
||||
//
|
||||
|
||||
// Create data based on target.
|
||||
TargetInfo = Target::TargetFactory( target );
|
||||
TargetInfo = Target::TargetFactory( buildTarget );
|
||||
|
||||
// Create the set of desired symbols.
|
||||
SymbolsToAnalyze = new Coverage::DesiredSymbols();
|
||||
SymbolsToAnalyze->load( symbolsFile );
|
||||
if (Verbose) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"Analyzing %u symbols\n",
|
||||
(unsigned int) SymbolsToAnalyze->set.size()
|
||||
);
|
||||
|
||||
//
|
||||
// Read symbol configuration file and load needed symbols.
|
||||
//
|
||||
if (!SymbolsToAnalyze->load( symbolSet, buildTarget, buildBSP, Verbose )) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if ( Verbose )
|
||||
std::cout << "Analyzing " << SymbolsToAnalyze->set.size()
|
||||
<< " symbols" << std::endl;
|
||||
|
||||
// Create explanations.
|
||||
AllExplanations = new Coverage::Explanations();
|
||||
if ( explanations )
|
||||
@ -379,7 +458,7 @@ int main(
|
||||
objdumpProcessor = new Coverage::ObjdumpProcessor();
|
||||
|
||||
// Prepare each executable for analysis.
|
||||
for (eitr = executablesToAnalyze.begin();
|
||||
for (Executables::iterator eitr = executablesToAnalyze.begin();
|
||||
eitr != executablesToAnalyze.end();
|
||||
eitr++) {
|
||||
|
||||
@ -407,22 +486,19 @@ int main(
|
||||
//
|
||||
|
||||
// Process each executable/coverage file pair.
|
||||
eitr = executablesToAnalyze.begin();
|
||||
for (citr = coverageFileNames.begin();
|
||||
citr != coverageFileNames.end();
|
||||
citr++) {
|
||||
|
||||
Executables::iterator eitr = executablesToAnalyze.begin();
|
||||
for (const auto& cname : coverageFileNames) {
|
||||
if (Verbose) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"Processing coverage file %s for executable %s\n",
|
||||
(*citr).c_str(),
|
||||
cname.c_str(),
|
||||
((*eitr)->getFileName()).c_str()
|
||||
);
|
||||
}
|
||||
|
||||
// Process its coverage file.
|
||||
coverageReader->processFile( (*citr).c_str(), *eitr );
|
||||
coverageReader->processFile( cname.c_str(), *eitr );
|
||||
|
||||
// Merge each symbols coverage map into a unified coverage map.
|
||||
(*eitr)->mergeCoverage();
|
||||
@ -524,6 +600,8 @@ int main(
|
||||
objdumpFile.keep();
|
||||
err.override( "objdump_exec_log" );
|
||||
err.keep();
|
||||
syms.override( "symbols_list" );
|
||||
syms.keep();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -118,10 +118,12 @@ def build(bld):
|
||||
'TraceWriterQEMU.cc'],
|
||||
use = ['ccovoar'] + modules,
|
||||
cflags = ['-O2', '-g'],
|
||||
cxxflags = ['-std=c++11', '-O2', '-g'],
|
||||
includes = ['.'] + rtl_includes)
|
||||
|
||||
bld.program(target = 'covoar',
|
||||
source = ['covoar.cc'],
|
||||
use = ['ccovoar'] + modules,
|
||||
cflags = ['-O2', '-g'],
|
||||
cxxflags = ['-std=c++11', '-O2', '-g'],
|
||||
includes = ['.'] + rtl_includes)
|
||||
|
39
tester/rtems/testing/bsps/leon3-qemu-cov.ini
Normal file
39
tester/rtems/testing/bsps/leon3-qemu-cov.ini
Normal file
@ -0,0 +1,39 @@
|
||||
#
|
||||
# RTEMS Tools Project (http://www.rtems.org/)
|
||||
# Copyright 2010-2018 Chris Johns (chrisj@rtems.org)
|
||||
# All rights reserved.
|
||||
#
|
||||
# This file is part of the RTEMS Tools package in 'rtems-tools'.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
#
|
||||
# The Leon 3 QEMU BSP
|
||||
#
|
||||
[leon3-qemu]
|
||||
bsp = leon3-qemu
|
||||
arch = sparc
|
||||
tester = %{_rtscripts}/qemu.cfg
|
||||
bsp_qemu_opts = %{qemu_opts_base} -M leon3_generic
|
||||
bsp_qemu_cov_opts = -exec-trace %{test_executable}.cov
|
38
tester/rtems/testing/bsps/leon3-qemu.ini
Normal file
38
tester/rtems/testing/bsps/leon3-qemu.ini
Normal file
@ -0,0 +1,38 @@
|
||||
#
|
||||
# RTEMS Tools Project (http://www.rtems.org/)
|
||||
# Copyright 2010-2014 Chris Johns (chrisj@rtems.org)
|
||||
# All rights reserved.
|
||||
#
|
||||
# This file is part of the RTEMS Tools package in 'rtems-tools'.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
#
|
||||
# The Leon 3 QEMU BSP
|
||||
#
|
||||
[leon3-qemu]
|
||||
bsp = leon3-qemu
|
||||
arch = sparc
|
||||
tester = %{_rtscripts}/qemu.cfg
|
||||
bsp_qemu_opts = %{qemu_opts_base} -M leon3_generic
|
19
tester/rtems/testing/coverage/Categories.txt
Normal file
19
tester/rtems/testing/coverage/Categories.txt
Normal file
@ -0,0 +1,19 @@
|
||||
This is the list of Explanation Categories used when analyzing RTEMS
|
||||
Coverage report. By using standard categories, the table filter on
|
||||
the web site works better.
|
||||
|
||||
Simple Test Case
|
||||
|
||||
Hard Test Tase
|
||||
|
||||
Uncalled Routine
|
||||
|
||||
Interrupt Critical Section
|
||||
|
||||
Simple Error Case
|
||||
|
||||
Hard Error Case
|
||||
|
||||
Allocation Error
|
||||
|
||||
Bharath Suri
|
35
tester/rtems/testing/coverage/Explanations.txt
Normal file
35
tester/rtems/testing/coverage/Explanations.txt
Normal file
@ -0,0 +1,35 @@
|
||||
schedulerpriorityyield.c:47
|
||||
Simple Test Case
|
||||
Branch Never Taken
|
||||
New test where there is more than one thread at a priority with the
|
||||
executing thread being non-preemptive. Create a higher priority thread
|
||||
and then yield.
|
||||
|
||||
init task at priority 2, non-preemptive
|
||||
create task at priority 2
|
||||
create task at priority 1
|
||||
yield
|
||||
+++
|
||||
|
||||
schedulerpriorityyield.c:51
|
||||
Simple Test Case
|
||||
Branch Always Taken
|
||||
New test where only one thread at a priority (non-preemptive), create a
|
||||
thread at higher priority, then yield.
|
||||
|
||||
init task at priority 2, non-preemptive
|
||||
create task at priority 1
|
||||
yield
|
||||
+++
|
||||
|
||||
schedulerpriorityyield.c:52
|
||||
Simple Test Case
|
||||
Not Executed
|
||||
Same test case as schedulerpriorityyield.c:51
|
||||
+++
|
||||
|
||||
coremsg.c:86
|
||||
Simple Test Case
|
||||
We need to request enough messages of a certain size that the math
|
||||
overflows to less than a single message.
|
||||
+++
|
@ -0,0 +1,56 @@
|
||||
The SPARC assembly is often hard to understand because a single
|
||||
instruction will show up as not executed. The instructions before
|
||||
and after it will be marked as executed. The instruction before
|
||||
the one not executed should be a "bxx,a" instruction which means
|
||||
that the instruction following the branch instruction is executed
|
||||
ONLY if the branch is taken. Otherwise it is "annulled" or skipped.
|
||||
|
||||
So when you see these cases, it means the branch was NOT taken.
|
||||
|
||||
===================================================================
|
||||
Subject: <offlist> annul slot explanation
|
||||
From: Jiri Gaisler <jiri@gaisler.com>
|
||||
Date: Wed, 3 Jun 2009 14:57:48 -0500
|
||||
To: Joel Sherrill <Joel.Sherrill@OARcorp.com>
|
||||
|
||||
|
||||
Joel Sherrill wrote:
|
||||
> > Hi,
|
||||
> >
|
||||
> > I am trying to look at more coverage cases and
|
||||
> > wanted to make sure I am reading things correctly.
|
||||
> >
|
||||
> > The code in question is:
|
||||
> >
|
||||
> >
|
||||
> > if ( the_thread->current_priority > interested_priority )
|
||||
> > 200fd00: d8 00 e0 14 ld [ %g3 + 0x14 ], %o4
|
||||
> > 200fd04: 80 a3 00 04 cmp %o4, %g4
|
||||
> > 200fd08: 38 80 00 1c bgu,a 200fd78 <killinfo+0x224>
|
||||
> > 200fd0c: 98 10 00 04 mov %g4,
|
||||
> > %o4 <== NOT EXECUTED
|
||||
> >
|
||||
> > /*
|
||||
> > * If this thread is not interested, then go on to the next thread.
|
||||
> > */
|
||||
> >
|
||||
> > api = the_thread->API_Extensions[ THREAD_API_POSIX ];
|
||||
> > 200fd10: d4 00 e1 6c ld [ %g3 + 0x16c ], %o2
|
||||
> >
|
||||
> > Am I correct in interpreting this as meaning 0x200fd0c
|
||||
> > is not executed because the bgu,a is never taken. And it
|
||||
> > is not executed as part of falling through.
|
||||
|
||||
Yes, this is correct. The branch delay slot is only executed
|
||||
when the branch is taken.
|
||||
|
||||
Jiri.
|
||||
|
||||
> >
|
||||
> > So in this case we need a test where the "if" condition
|
||||
> > is true if I am reading things correctly.
|
||||
> >
|
||||
> > Thanks. There are a number of these 4 byte cases which
|
||||
> > are probably easy to hit if I read the code correctly.
|
||||
> >
|
||||
> >
|
35
tester/rtems/testing/coverage/score-symbols.ini
Normal file
35
tester/rtems/testing/coverage/score-symbols.ini
Normal file
@ -0,0 +1,35 @@
|
||||
#
|
||||
# RTEMS Tools Project (http://www.rtems.org/)
|
||||
# Copyright 2018 Chris Johns (chrisj@rtems.org)
|
||||
# All rights reserved.
|
||||
#
|
||||
# This file is part of the RTEMS Tools package in 'rtems-tools'.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
[symbol-sets]
|
||||
sets = score
|
||||
|
||||
[score]
|
||||
libraries=@BUILD-TARGET@/c/@BSP@/cpukit/score/libscore.a
|
197
tester/rtems/testing/coverage/style.css
Normal file
197
tester/rtems/testing/coverage/style.css
Normal file
@ -0,0 +1,197 @@
|
||||
body {
|
||||
background: rgb(253,253,253);
|
||||
color: rgb(0,0,0);
|
||||
font-family: helvetica, sans-serif;
|
||||
font-size: 1em;
|
||||
line-height: 1.4;
|
||||
margin: 5px, 5px, 5px, 5px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
a:link {
|
||||
color: rgb(180, 50, 50);
|
||||
font-family: helvetica, sans-serif;
|
||||
font-size: 1.0em;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
color: purple;
|
||||
font-family: helvetica, sans-serif;
|
||||
font-size: 1.0em;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: rgb(0, 0, 0);
|
||||
font-family: helvetica, sans-serif;
|
||||
font-size: 1.0em;
|
||||
}
|
||||
|
||||
a:active {
|
||||
color: red;
|
||||
font-family: helvetica, sans-serif;
|
||||
font-size: 1.0em;
|
||||
}
|
||||
|
||||
.heading {
|
||||
background: rgb(250,250,250);
|
||||
background-image: url("http://www.rtems.org/logos/rtems_logo.jpg");
|
||||
background-repeat: no-repeat;
|
||||
color: rgb(55,55,55);
|
||||
font-size: 1.5em;
|
||||
height: 140px;
|
||||
padding-top: 20px;
|
||||
padding-left: 300px;
|
||||
}
|
||||
|
||||
.heading-title {
|
||||
text-align: center;
|
||||
color: rgb(0,0,0);
|
||||
font-size: 0.9em;
|
||||
font-weight: bold;
|
||||
padding-top: 5px;
|
||||
padding-left: 0px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.datetime {
|
||||
color: rgb(55,55,55);
|
||||
font-size: 0.8em;
|
||||
padding-top: 5px;
|
||||
padding-left: 0px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.info {
|
||||
color: rgb(55,55,55);
|
||||
font-size: 0.6em;
|
||||
padding-top: 5px;
|
||||
padding-left: 00px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.stats-table {
|
||||
background: rgb(225,225,225);
|
||||
font-size: 0.9em;
|
||||
border: 1px solid rgb(200, 200, 200);
|
||||
padding: 0;
|
||||
margin-top: 3px;
|
||||
margin-left: 10px;
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
.stats-table-target {
|
||||
background: rgb(243,243,243);
|
||||
font-size: 1.2em;
|
||||
padding-left: 10px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.stats-target-results {
|
||||
background: rgb(243,243,243);
|
||||
font-size: 0.9em;
|
||||
text-align: right;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.stats-target-good {
|
||||
background: rgb(30,230,30);
|
||||
font-size: 0.9em;
|
||||
text-align: right;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.stats-target-good {
|
||||
background: rgb(50,180,50);
|
||||
color: rgb(230,230,230);
|
||||
font-size: 0.9em;
|
||||
text-align: center;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.stats-target-bad {
|
||||
background: rgb(180,50,50);
|
||||
color: rgb(230,230,230);
|
||||
font-size: 0.9em;
|
||||
text-align: center;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.stats-table-top {
|
||||
background: rgb(243,243,243);
|
||||
color: rgb(0,0,0);
|
||||
font-size: 0.9em;
|
||||
padding-left: 2px;
|
||||
}
|
||||
|
||||
.stats-table-row {
|
||||
background: rgb(253,253,253);
|
||||
font-size: 0.9em;
|
||||
padding: 1px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.error-table {
|
||||
font-size: 0.9em;
|
||||
border: 1px solid rgb(200, 200, 200);
|
||||
padding: 0;
|
||||
margin-left: 10px;
|
||||
width: 96%;
|
||||
}
|
||||
|
||||
.error-table-top {
|
||||
background: rgb(225,225,225);
|
||||
color: rgb(0,0,0);
|
||||
font-size: 0.9em;
|
||||
padding-left: 2px;
|
||||
}
|
||||
|
||||
.error-table-on {
|
||||
background: rgb(225,225,225);
|
||||
font-size: 0.9em;
|
||||
padding-left: 2px;
|
||||
}
|
||||
|
||||
.error-table-off {
|
||||
background: rgb(253,253,253);
|
||||
font-size: 0.9em;
|
||||
padding-left: 2px;
|
||||
}
|
||||
|
||||
.error-table-dups {
|
||||
text-align: right;
|
||||
padding-right: 2px;
|
||||
}
|
||||
|
||||
.error-table-error {
|
||||
background: rgb(255,150,150);
|
||||
font-size: 0.9em;
|
||||
padding-left: 2px;
|
||||
}
|
||||
|
||||
.error-table-warning {
|
||||
font-size: 0.9em;
|
||||
padding-left: 2px;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-top: 10px;
|
||||
width: 40%;
|
||||
}
|
||||
th.table-sortable {
|
||||
background-image:url("unsorted.gif");
|
||||
cursor: pointer;
|
||||
background-position: center left;
|
||||
background-repeat: no-repeat;
|
||||
padding-left: 15px;
|
||||
}
|
||||
th.table-sorted-asc {
|
||||
background-image:url("descending.gif");
|
||||
}
|
||||
th.table-sorted-desc {
|
||||
background-image:url("ascending.gif");
|
||||
}
|
@ -54,14 +54,23 @@
|
||||
#%define qemu_opts_base -no-reboot -monitor none -serial stdio -nographic
|
||||
%define qemu_opts_base -no-reboot -serial null -serial mon:stdio -nographic
|
||||
%define qemu_opts_no_net -net none
|
||||
|
||||
#
|
||||
# Coverage, some builds of qemu support coverage.
|
||||
#
|
||||
%ifn %{defined bsp_qemu_cov_opts}
|
||||
%define bsp_qemu_cov_opts %{nil}
|
||||
%endif
|
||||
|
||||
#
|
||||
# Qemu executable
|
||||
#
|
||||
%ifn %{defined bsp_qemu_opts}
|
||||
%define bsp_qemu_opts %{nil}
|
||||
%endif
|
||||
|
||||
%define qemu_cmd qemu-system-%{bsp_arch}
|
||||
%define qemu_opts %{bsp_qemu_opts}
|
||||
%define qemu_opts %{bsp_qemu_opts} %{bsp_qemu_cov_opts}
|
||||
|
||||
#
|
||||
# Executable
|
||||
|
@ -55,3 +55,11 @@ timeout: none, none, '180'
|
||||
|
||||
# Tests detected as invalid that are valid
|
||||
invalid_tests: none, none, '''minimum.exe'''
|
||||
|
||||
# Coverage defaults
|
||||
cov_format: none, none, 'QEMU'
|
||||
cov_explanations: none, none, '%{_rtscripts}/coverage/Explanations.txt'
|
||||
cov_extension: none, none, 'cov'
|
||||
cov_gcnos_file: none, none, '%{_rtscripts}/coverage/rtems.gcnos'
|
||||
cov_exe_ext: none, none, 'exe'
|
||||
cov_report_format: none, none, 'html'
|
||||
|
Loading…
x
Reference in New Issue
Block a user