[PATCH] covoar: Add symbol set reader and ELF data parser to covoar.

Vijay Kumar Banerjee vijaykumar9597 at gmail.com
Sat Apr 28 19:02:30 UTC 2018


On 29 April 2018 at 00:04, Cillian O'Donnell <cpodonnell8 at gmail.com> wrote:

>
>
> On 28 April 2018 at 17:29, Vijay Kumar Banerjee <vijaykumar9597 at gmail.com>
> wrote:
>
>> I'm getting the following error after applying the patch:
>>
>
> Did you apply it to the current rtems-tools master? It's building fine for
> me.
>
>>
>> oh , it wasn't the current master.
Yes it's building fine  now .

> -----
>> ./waf build install
>> Waf: Entering directory `/home/lunatic/development/rte
>> ms/test/rtems-tools/build'
>> Traceback (most recent call last):
>>   File "/home/lunatic/development/rtems/test/rtems-tools/.waf-1.9.
>> 9-75529a659e4f06cb4254801e52405e0a/waflib/Scripting.py", line 120, in
>> waf_entry_point
>>     run_commands()
>>   File "/home/lunatic/development/rtems/test/rtems-tools/.waf-1.9.
>> 9-75529a659e4f06cb4254801e52405e0a/waflib/Scripting.py", line 181, in
>> run_commands
>>     ctx=run_command(cmd_name)
>>   File "/home/lunatic/development/rtems/test/rtems-tools/.waf-1.9.
>> 9-75529a659e4f06cb4254801e52405e0a/waflib/Scripting.py", line 172, in
>> run_command
>>     ctx.execute()
>>   File "/home/lunatic/development/rtems/test/rtems-tools/.waf-1.9.
>> 9-75529a659e4f06cb4254801e52405e0a/waflib/Scripting.py", line 362, in
>> execute
>>     return execute_method(self)
>>   File "/home/lunatic/development/rtems/test/rtems-tools/.waf-1.9.
>> 9-75529a659e4f06cb4254801e52405e0a/waflib/Build.py", line 99, in execute
>>     self.execute_build()
>>   File "/home/lunatic/development/rtems/test/rtems-tools/.waf-1.9.
>> 9-75529a659e4f06cb4254801e52405e0a/waflib/Build.py", line 102, in
>> execute_build
>>     self.recurse([self.run_dir])
>>   File "/home/lunatic/development/rtems/test/rtems-tools/.waf-1.9.
>> 9-75529a659e4f06cb4254801e52405e0a/waflib/Context.py", line 129, in
>> recurse
>>     user_function(self)
>>   File "/home/lunatic/development/rtems/test/rtems-tools/wscript", line
>> 134, in build
>>     recurse(ctx)
>>   File "/home/lunatic/development/rtems/test/rtems-tools/wscript", line
>> 81, in recurse
>>     ctx.recurse(sd)
>>   File "/home/lunatic/development/rtems/test/rtems-tools/.waf-1.9.
>> 9-75529a659e4f06cb4254801e52405e0a/waflib/Context.py", line 129, in
>> recurse
>>     user_function(self)
>>   File "/home/lunatic/development/rtems/test/rtems-tools/tester/wscript",
>> line 48, in build
>>     recurse(bld)
>>   File "/home/lunatic/development/rtems/test/rtems-tools/tester/wscript",
>> line 35, in recurse
>>     ctx.recurse(sd)
>>   File "/home/lunatic/development/rtems/test/rtems-tools/.waf-1.9.
>> 9-75529a659e4f06cb4254801e52405e0a/waflib/Context.py", line 129, in
>> recurse
>>     user_function(self)
>>   File "/home/lunatic/development/rtems/test/rtems-tools/tester/covoar/wscript",
>> line 115, in build
>>     use = ['ccovoar'] + modules,
>> NameError: global name 'modules' is not defined
>>
>>
>> -- vijay
>>
>> On 28 April 2018 at 21:54, Cillian O'Donnell <cpodonnell8 at gmail.com>
>> wrote:
>>
>>>
>>>
>>> On 28 April 2018 at 08:08, Chris Johns <chrisj at rtems.org> wrote:
>>>
>>>> From: Cillian O'Donnell <cpodonnell8 at gmail.com>
>>>>
>>>> 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 at gmail.com>
>>>> Co-author: Vijay Kumar Banerjee <vijaykumar9597 at gmail.com>
>>>> Cp-author: Chris Johns <chrisj at rtems.org>
>>>> ---
>>>>  tester/covoar/DesiredSymbols.cc                    | 144 +++++-----
>>>>  tester/covoar/DesiredSymbols.h                     |  14 +-
>>>>  tester/covoar/ExecutableInfo.cc                    |   4 +-
>>>>  tester/covoar/ExecutableInfo.h                     |   6 +-
>>>>  tester/covoar/ObjdumpProcessor.cc                  |   6 +-
>>>>  tester/covoar/app_common.h                         |   9 +-
>>>>  tester/covoar/covoar.cc                            | 300
>>>> +++++++++++++--------
>>>>  tester/covoar/wscript                              |   2 +
>>>>  tester/rtems/testing/bsps/leon3-qemu-cov.ini       |  39 +++
>>>>  tester/rtems/testing/bsps/leon3-qemu.ini           |  38 +++
>>>>  tester/rtems/testing/coverage/Categories.txt       |  19 ++
>>>>  tester/rtems/testing/coverage/Explanations.txt     |  35 +++
>>>>  .../coverage/SPARC-Annul-Slot-Explanation.txt      |  56 ++++
>>>>  tester/rtems/testing/coverage/score-symbols.ini    |  35 +++
>>>>  tester/rtems/testing/coverage/style.css            | 197
>>>> ++++++++++++++
>>>>  tester/rtems/testing/qemu.cfg                      |  11 +-
>>>>  tester/rtems/testing/testing.mc                    |   8 +
>>>>  17 files changed, 737 insertions(+), 186 deletions(-)
>>>>  create mode 100644 tester/rtems/testing/bsps/leon3-qemu-cov.ini
>>>>  create mode 100644 tester/rtems/testing/bsps/leon3-qemu.ini
>>>>  create mode 100644 tester/rtems/testing/coverage/Categories.txt
>>>>  create mode 100644 tester/rtems/testing/coverage/Explanations.txt
>>>>  create mode 100644 tester/rtems/testing/coverage/
>>>> SPARC-Annul-Slot-Explanation.txt
>>>>  create mode 100644 tester/rtems/testing/coverage/score-symbols.ini
>>>>  create mode 100644 tester/rtems/testing/coverage/style.css
>>>>
>>>> diff --git a/tester/covoar/DesiredSymbols.cc
>>>> b/tester/covoar/DesiredSymbols.cc
>>>> index 00d1984..9957b28 100644
>>>> --- a/tester/covoar/DesiredSymbols.cc
>>>> +++ b/tester/covoar/DesiredSymbols.cc
>>>> @@ -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;
>>>> -
>>>> -    // 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;
>>>> +    rld::files::cache cache;
>>>> +    bool              r = true;
>>>> +
>>>> +    //
>>>> +    // 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();
>>>> +
>>>> +      rld::config::config config;
>>>> +
>>>> +      if (verbose)
>>>> +        std::cerr << "Loading symbol sets: " << symbolsSet <<
>>>> std::endl;
>>>> +
>>>> +      config.load (symbolsSet);
>>>> +
>>>> +      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
>>>> -          );
>>>> +      rld::symbols::table symbols;
>>>>
>>>> -          delete symInfo;
>>>> -        }
>>>> +      cache.load_symbols (symbols, true);
>>>>
>>>> -        // Add this to the set of symbols.
>>>> -        else
>>>> -          set[ inputBuffer ] = *symInfo;
>>>> +      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 )
>>>> diff --git a/tester/covoar/DesiredSymbols.h
>>>> b/tester/covoar/DesiredSymbols.h
>>>> index 9524c64..21c5602 100644
>>>> --- a/tester/covoar/DesiredSymbols.h
>>>> +++ b/tester/covoar/DesiredSymbols.h
>>>> @@ -293,9 +293,17 @@ namespace Coverage {
>>>>      /*!
>>>>       *  This method creates the set of symbols to analyze from the
>>>> symbols
>>>>       *  listed in the specified file.
>>>> -     */
>>>> -    void load(
>>>> -      const char* const symbolsFile
>>>> +     *
>>>> +     *  @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.
>>>> +     */
>>>> +    bool load(
>>>> +      const std::string& symbolsSet,
>>>> +      const std::string& buildTarget,
>>>> +      const std::string& buildBSP,
>>>> +      bool               verbose
>>>>      );
>>>>
>>>>      /*!
>>>> diff --git a/tester/covoar/ExecutableInfo.cc
>>>> b/tester/covoar/ExecutableInfo.cc
>>>> index d71c435..c41d931 100644
>>>> --- a/tester/covoar/ExecutableInfo.cc
>>>> +++ b/tester/covoar/ExecutableInfo.cc
>>>> @@ -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;
>>>>    }
>>>> diff --git a/tester/covoar/ExecutableInfo.h
>>>> b/tester/covoar/ExecutableInfo.h
>>>> index 7242715..20ea9bf 100644
>>>> --- a/tester/covoar/ExecutableInfo.h
>>>> +++ b/tester/covoar/ExecutableInfo.h
>>>> @@ -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 );
>>>>
>>>> diff --git a/tester/covoar/ObjdumpProcessor.cc
>>>> b/tester/covoar/ObjdumpProcessor.cc
>>>> index b916984..d41906c 100644
>>>> --- a/tester/covoar/ObjdumpProcessor.cc
>>>> +++ b/tester/covoar/ObjdumpProcessor.cc
>>>> @@ -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;
>>>>        }
>>>> diff --git a/tester/covoar/app_common.h b/tester/covoar/app_common.h
>>>> index d28bfd0..ac32bbd 100644
>>>> --- a/tester/covoar/app_common.h
>>>> +++ b/tester/covoar/app_common.h
>>>> @@ -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
>>>> diff --git a/tester/covoar/covoar.cc b/tester/covoar/covoar.cc
>>>> index c36b00a..81c90d2 100644
>>>> --- a/tester/covoar/covoar.cc
>>>> +++ b/tester/covoar/covoar.cc
>>>> @@ -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;
>>>>  }
>>>> diff --git a/tester/covoar/wscript b/tester/covoar/wscript
>>>> index 9db4815..c0270d8 100644
>>>> --- a/tester/covoar/wscript
>>>> +++ b/tester/covoar/wscript
>>>> @@ -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)
>>>> diff --git a/tester/rtems/testing/bsps/leon3-qemu-cov.ini
>>>> b/tester/rtems/testing/bsps/leon3-qemu-cov.ini
>>>> new file mode 100644
>>>> index 0000000..6b5e7e6
>>>> --- /dev/null
>>>> +++ b/tester/rtems/testing/bsps/leon3-qemu-cov.ini
>>>> @@ -0,0 +1,39 @@
>>>> +#
>>>> +# RTEMS Tools Project (http://www.rtems.org/)
>>>> +# Copyright 2010-2018 Chris Johns (chrisj at 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
>>>> diff --git a/tester/rtems/testing/bsps/leon3-qemu.ini
>>>> b/tester/rtems/testing/bsps/leon3-qemu.ini
>>>> new file mode 100644
>>>> index 0000000..9e8854c
>>>> --- /dev/null
>>>> +++ b/tester/rtems/testing/bsps/leon3-qemu.ini
>>>> @@ -0,0 +1,38 @@
>>>> +#
>>>> +# RTEMS Tools Project (http://www.rtems.org/)
>>>> +# Copyright 2010-2014 Chris Johns (chrisj at 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
>>>> diff --git a/tester/rtems/testing/coverage/Categories.txt
>>>> b/tester/rtems/testing/coverage/Categories.txt
>>>> new file mode 100644
>>>> index 0000000..e19a456
>>>> --- /dev/null
>>>> +++ b/tester/rtems/testing/coverage/Categories.txt
>>>> @@ -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
>>>> diff --git a/tester/rtems/testing/coverage/Explanations.txt
>>>> b/tester/rtems/testing/coverage/Explanations.txt
>>>> new file mode 100644
>>>> index 0000000..a5917f6
>>>> --- /dev/null
>>>> +++ b/tester/rtems/testing/coverage/Explanations.txt
>>>> @@ -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.
>>>> ++++
>>>> diff --git a/tester/rtems/testing/coverage/SPARC-Annul-Slot-Explanation.txt
>>>> b/tester/rtems/testing/coverage/SPARC-Annul-Slot-Explanation.txt
>>>> new file mode 100644
>>>> index 0000000..ef740d3
>>>> --- /dev/null
>>>> +++ b/tester/rtems/testing/coverage/SPARC-Annul-Slot-Explanation.txt
>>>> @@ -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 at gaisler.com>
>>>> +Date: Wed, 3 Jun 2009 14:57:48 -0500
>>>> +To: Joel Sherrill <Joel.Sherrill at 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.
>>>> +> >
>>>> +> >
>>>> diff --git a/tester/rtems/testing/coverage/score-symbols.ini
>>>> b/tester/rtems/testing/coverage/score-symbols.ini
>>>> new file mode 100644
>>>> index 0000000..b3c8b18
>>>> --- /dev/null
>>>> +++ b/tester/rtems/testing/coverage/score-symbols.ini
>>>> @@ -0,0 +1,35 @@
>>>> +#
>>>> +# RTEMS Tools Project (http://www.rtems.org/)
>>>> +# Copyright 2018 Chris Johns (chrisj at 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
>>>> diff --git a/tester/rtems/testing/coverage/style.css
>>>> b/tester/rtems/testing/coverage/style.css
>>>> new file mode 100644
>>>> index 0000000..c715518
>>>> --- /dev/null
>>>> +++ b/tester/rtems/testing/coverage/style.css
>>>> @@ -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");
>>>> +}
>>>> \ No newline at end of file
>>>> diff --git a/tester/rtems/testing/qemu.cfg b/tester/rtems/testing/
>>>> qemu.cfg
>>>> index db5b6b2..858cac8 100644
>>>> --- a/tester/rtems/testing/qemu.cfg
>>>> +++ b/tester/rtems/testing/qemu.cfg
>>>> @@ -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
>>>> +
>>>> +#
>>>> +# Converage, some builds of qemu support coverage.
>>>>
>>>
>>> Typo Converage. That's the only mistake I can see from reading through.
>>> Still have to apply the patches and test.
>>> I'll let you know how that goes.
>>>
>>>
>>>> +#
>>>> +%ifn %{defined bsp_qemu_ocv_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
>>>> diff --git a/tester/rtems/testing/testing.mc b/tester/rtems/testing/
>>>> testing.mc
>>>> index 77f8419..662b352 100644
>>>> --- a/tester/rtems/testing/testing.mc
>>>> +++ b/tester/rtems/testing/testing.mc
>>>> @@ -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/Expla
>>>> nations.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'
>>>> --
>>>> 2.15.1
>>>>
>>>>
>>>
>>> _______________________________________________
>>> devel mailing list
>>> devel at rtems.org
>>> http://lists.rtems.org/mailman/listinfo/devel
>>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/devel/attachments/20180429/e6758c9c/attachment-0001.html>


More information about the devel mailing list