[PATCH 1/2] covoar: Split symbols by symbol set

Alex White alex.white at oarcorp.com
Mon Apr 5 19:25:11 UTC 2021


This changes the way covoar organizes the symbols. Instead of treating
all symbols as one set, covoar is now aware of multiple symbol sets and
tracks statistics for each set. It now also generates reports for each
symbol set.

This change relieves the caller of covoar of the reponsibility of
managing the symbol sets. As a result, covoar can minimize the work
done for each symbol set, yielding a significant speedup.

Updates #4374
---
 tester/covoar/DesiredSymbols.cc | 465 +++++++++++++++++---------------
 tester/covoar/DesiredSymbols.h  |  98 +++++--
 tester/covoar/ReportsBase.cc    | 181 +++++++------
 tester/covoar/ReportsBase.h     |  40 ++-
 tester/covoar/ReportsHtml.cc    |  62 +++--
 tester/covoar/ReportsHtml.h     |  13 +-
 tester/covoar/ReportsText.cc    |  66 ++---
 tester/covoar/ReportsText.h     |  13 +-
 tester/covoar/covoar.cc         |   6 +-
 9 files changed, 542 insertions(+), 402 deletions(-)

diff --git a/tester/covoar/DesiredSymbols.cc b/tester/covoar/DesiredSymbols.cc
index ffc4f86..2866dbe 100644
--- a/tester/covoar/DesiredSymbols.cc
+++ b/tester/covoar/DesiredSymbols.cc
@@ -37,6 +37,11 @@ namespace Coverage {
   {
   }
 
+  const DesiredSymbols::symbolSet_t& DesiredSymbols::allSymbols() const
+  {
+    return set;
+  }
+
   void DesiredSymbols::load(
     const std::string& symbolsSet,
     const std::string& buildTarget,
@@ -44,8 +49,6 @@ namespace Coverage {
     bool               verbose
   )
   {
-    rld::files::cache cache;
-
     //
     // Load the INI file looking for a top level:
     //
@@ -60,61 +63,61 @@ namespace Coverage {
     //  [B]
     //  libraries = @BUILD-PREFIX@/c/@BSP@/B/libB.a
     //
-    try {
-      cache.open();
+    rld::config::config config;
 
-      rld::config::config config;
+    if (verbose)
+      std::cerr << "Loading symbol sets: " << symbolsSet << std::endl;
 
-      if (verbose)
-        std::cerr << "Loading symbol sets: " << symbolsSet << std::endl;
+    config.load (symbolsSet);
 
-      config.load (symbolsSet);
+    const rld::config::section& sym_section = config.get_section("symbol-sets");
 
-      const rld::config::section& sym_section = config.get_section("symbol-sets");
+    rld::strings sets;
+    rld::config::parse_items (sym_section, "sets", sets, true);
 
-      rld::strings sets;
-      rld::config::parse_items (sym_section, "sets", sets, true);
+    // Load the symbols for each set specified in the config file.
+    for (const auto& setName : sets) {
+      rld::files::cache cache;
+      cache.open();
 
-      for (const std::string set : sets) {
+      if (verbose)
+        std::cerr << "Loading symbols for set: " << setName << std::endl;
+      const rld::config::section& set_section = config.get_section(setName);
+      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 << " 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);
-        }
+          std::cerr << " Loading library: " << lib << std::endl;
+        cache.add(lib);
       }
 
       rld::symbols::table symbols;
 
       cache.load_symbols (symbols, true);
 
+      // Populate the symbol maps with all global symbols.
       for (auto& kv : symbols.globals()) {
         const rld::symbols::symbol& sym = *(kv.second);
-        if (sym.type() == sym.st_func)
+        if (sym.type() == sym.st_func) {
           set[sym.name()] = *(new SymbolInformation);
+          setNamesToSymbols[setName].push_back(sym.name());
+        }
       }
+      // Populate the symbol maps with all weak symbols.
       for (auto& kv : symbols.weaks()) {
         const rld::symbols::symbol& sym = *(kv.second);
-        if (sym.type() == sym.st_func)
+        if (sym.type() == sym.st_func) {
           set[sym.name()] = *(new SymbolInformation);
+          setNamesToSymbols[setName].push_back(sym.name());
+        }
       }
-    } catch (...) {
-      cache.close();
-      throw;
     }
-
-    cache.close();
   }
 
   void DesiredSymbols::preprocess( void )
   {
-
     // Look at each symbol.
     for (auto& s : SymbolsToAnalyze->set) {
       // If the unified coverage map does not exist, the symbol was
@@ -135,48 +138,52 @@ namespace Coverage {
 
   void DesiredSymbols::calculateStatistics( void )
   {
-    // Look at each symbol.
-    for (auto& s : SymbolsToAnalyze->set) {
-      // If the unified coverage map does not exist, the symbol was
-      // never referenced by any executable.  Just skip it.
-      CoverageMapBase* theCoverageMap = s.second.unifiedCoverageMap;
-      if (theCoverageMap)
-      {
-        // Increment the total sizeInBytes by the bytes in the symbol
-        stats.sizeInBytes += s.second.stats.sizeInBytes;
-
-        // Now scan through the coverage map of this symbol.
-        uint32_t endAddress = s.second.stats.sizeInBytes - 1;
-
-        for (uint32_t a = 0; a <= endAddress; ++a) {
-          // If we are at the start of instruction increment
-          // instruction type counters as needed.
-          if ( theCoverageMap->isStartOfInstruction( a ) ) {
-
-            stats.sizeInInstructions++;
-            s.second.stats.sizeInInstructions++;
-
-            if (!theCoverageMap->wasExecuted( a ) ) {
-              stats.uncoveredInstructions++;
-              s.second.stats.uncoveredInstructions++;
-
-              if ( theCoverageMap->isBranch( a )) {
-                stats.branchesNotExecuted++;
-                s.second.stats.branchesNotExecuted++;
+    // Look at each symbol set.
+    for (const auto& kv : setNamesToSymbols) {
+      // Look at each symbol.
+      for (const auto& symbol : kv.second) {
+        SymbolInformation& info = set.at(symbol);
+
+        // If the unified coverage map does not exist, the symbol was
+        // never referenced by any executable.  Just skip it.
+        CoverageMapBase* theCoverageMap = info.unifiedCoverageMap;
+        if (theCoverageMap) {
+          // Increment the total sizeInBytes by the bytes in the symbol
+          stats[kv.first].sizeInBytes += info.stats.sizeInBytes;
+
+          // Now scan through the coverage map of this symbol.
+          uint32_t endAddress = info.stats.sizeInBytes - 1;
+
+          for (uint32_t a = 0; a <= endAddress; ++a) {
+            // If we are at the start of instruction increment
+            // instruction type counters as needed.
+            if ( theCoverageMap->isStartOfInstruction( a ) ) {
+
+              stats[kv.first].sizeInInstructions++;
+              info.stats.sizeInInstructions++;
+
+              if (!theCoverageMap->wasExecuted( a ) ) {
+                stats[kv.first].uncoveredInstructions++;
+                info.stats.uncoveredInstructions++;
+
+                if ( theCoverageMap->isBranch( a )) {
+                  stats[kv.first].branchesNotExecuted++;
+                  info.stats.branchesNotExecuted++;
+                }
+              } else if (theCoverageMap->isBranch( a )) {
+                stats[kv.first].branchesExecuted++;
+                info.stats.branchesExecuted++;
               }
-            } else if (theCoverageMap->isBranch( a )) {
-              stats.branchesExecuted++;
-              s.second.stats.branchesExecuted++;
             }
-          }
 
-          if (!theCoverageMap->wasExecuted( a )) {
-            stats.uncoveredBytes++;
-            s.second.stats.uncoveredBytes++;
+            if (!theCoverageMap->wasExecuted( a )) {
+              stats[kv.first].uncoveredBytes++;
+              info.stats.uncoveredBytes++;
+            }
           }
+        } else {
+          stats[kv.first].unreferencedSymbols++;
         }
-      } else {
-        stats.unreferencedSymbols++;
       }
     }
   }
@@ -184,152 +191,155 @@ namespace Coverage {
 
   void DesiredSymbols::computeUncovered( void )
   {
-    // Look at each symbol.
-    for (auto& s : SymbolsToAnalyze->set) {
-      // If the unified coverage map does not exist, the symbol was
-      // never referenced by any executable.  Just skip it.
-      CoverageMapBase* theCoverageMap = s.second.unifiedCoverageMap;
-      if (theCoverageMap)
-      {
-        // Create containers for the symbol's uncovered ranges and branches.
-        CoverageRanges* theRanges = new CoverageRanges();
-        s.second.uncoveredRanges = theRanges;
-        CoverageRanges* theBranches = new CoverageRanges();
-        s.second.uncoveredBranches = theBranches;
-
-        uint32_t a;
-        uint32_t la;
-        uint32_t ha;
-        uint32_t endAddress;
-        uint32_t count;
-
-        // Mark NOPs as executed
-        a = s.second.stats.sizeInBytes - 1;
-        count = 0;
-        while (a > 0) {
-          if (theCoverageMap->isStartOfInstruction( a )) {
-            break;
-          }
-
-          count++;
-
-          if (theCoverageMap->isNop( a )) {
-            for (la = a; la < (a + count); la++) {
-              theCoverageMap->setWasExecuted( la );
+    // Look at each symbol set.
+    for (const auto& kv : setNamesToSymbols) {
+      // Look at each symbol.
+      for (const auto& symbol : kv.second) {
+        SymbolInformation& info = set.at(symbol);
+        // If the unified coverage map does not exist, the symbol was
+        // never referenced by any executable.  Just skip it.
+        CoverageMapBase* theCoverageMap = info.unifiedCoverageMap;
+        if (theCoverageMap) {
+          // Create containers for the symbol's uncovered ranges and branches.
+          CoverageRanges* theRanges = new CoverageRanges();
+          info.uncoveredRanges = theRanges;
+          CoverageRanges* theBranches = new CoverageRanges();
+          info.uncoveredBranches = theBranches;
+
+          uint32_t a;
+          uint32_t la;
+          uint32_t ha;
+          uint32_t endAddress;
+          uint32_t count;
+
+          // Mark NOPs as executed
+          a = info.stats.sizeInBytes - 1;
+          count = 0;
+          while (a > 0) {
+            if (theCoverageMap->isStartOfInstruction( a )) {
+              break;
             }
 
-            count = 0;
-          }
+            count++;
 
-          a--;
-        }
+            if (theCoverageMap->isNop( a )) {
+              for (la = a; la < (a + count); la++) {
+                theCoverageMap->setWasExecuted( la );
+              }
 
-        endAddress = s.second.stats.sizeInBytes - 1;
-        a = 0;
-        while (a < endAddress) {
-          if (!theCoverageMap->wasExecuted( a )) {
-            a++;
-            continue;
-          }
+              count = 0;
+            }
 
-          for (ha=a+1;
-               ha <= endAddress && !theCoverageMap->isStartOfInstruction( ha );
-               ha++)
-            ;
-          if ( ha >= endAddress )
-            break;
-
-          if (theCoverageMap->isNop( ha ))
-            do {
-              theCoverageMap->setWasExecuted( ha );
-              ha++;
-              if ( ha >= endAddress )
-                break;
-            } while ( !theCoverageMap->isStartOfInstruction( ha ) ||
-                      theCoverageMap->isNop( ha ) );
-          a = ha;
-        }
+            a--;
+          }
 
-        // Now scan through the coverage map of this symbol.
-        endAddress = s.second.stats.sizeInBytesWithoutNops - 1;
-        a = 0;
-        while (a <= endAddress) {
-          // If an address was NOT executed, find consecutive unexecuted
-          // addresses and add them to the uncovered ranges.
-          if (!theCoverageMap->wasExecuted( a )) {
-
-            la = a;
-            count = 1;
-            for (ha = a + 1;
-                 ha <= endAddress && !theCoverageMap->wasExecuted( ha );
-                 ha++)
-            {
-              if ( theCoverageMap->isStartOfInstruction( ha ) )
-                count++;
+          endAddress = info.stats.sizeInBytes - 1;
+          a = 0;
+          while (a < endAddress) {
+            if (!theCoverageMap->wasExecuted( a )) {
+              a++;
+              continue;
             }
-            ha--;
-
-            stats.uncoveredRanges++;
-            s.second.stats.uncoveredRanges++;
-            theRanges->add(
-              s.second.baseAddress + la,
-              s.second.baseAddress + ha,
-              CoverageRanges::UNCOVERED_REASON_NOT_EXECUTED,
-              count
-            );
-            a = ha + 1;
-          }
 
-          // If an address is a branch instruction, add any uncovered branches
-          // to the uncoverd branches.
-          else if (theCoverageMap->isBranch( a )) {
-            la = a;
-            for (ha = a + 1;
-               ha <= endAddress && !theCoverageMap->isStartOfInstruction( ha );
-                 ha++)
+            for (ha=a+1;
+                ha <= endAddress && !theCoverageMap->isStartOfInstruction( ha );
+                ha++)
               ;
-            ha--;
-
-            if (theCoverageMap->wasAlwaysTaken( la )) {
-              stats.branchesAlwaysTaken++;
-              s.second.stats.branchesAlwaysTaken++;
-              theBranches->add(
-                s.second.baseAddress + la,
-                s.second.baseAddress + ha,
-                CoverageRanges::UNCOVERED_REASON_BRANCH_ALWAYS_TAKEN,
-                1
+            if ( ha >= endAddress )
+              break;
+
+            if (theCoverageMap->isNop( ha ))
+              do {
+                theCoverageMap->setWasExecuted( ha );
+                ha++;
+                if ( ha >= endAddress )
+                  break;
+              } while ( !theCoverageMap->isStartOfInstruction( ha ) ||
+                        theCoverageMap->isNop( ha ) );
+            a = ha;
+          }
+
+          // Now scan through the coverage map of this symbol.
+          endAddress = info.stats.sizeInBytesWithoutNops - 1;
+          a = 0;
+          while (a <= endAddress) {
+            // If an address was NOT executed, find consecutive unexecuted
+            // addresses and add them to the uncovered ranges.
+            if (!theCoverageMap->wasExecuted( a )) {
+
+              la = a;
+              count = 1;
+              for (ha = a + 1;
+                  ha <= endAddress && !theCoverageMap->wasExecuted( ha );
+                  ha++)
+              {
+                if ( theCoverageMap->isStartOfInstruction( ha ) )
+                  count++;
+              }
+              ha--;
+
+              stats[kv.first].uncoveredRanges++;
+              info.stats.uncoveredRanges++;
+              theRanges->add(
+                info.baseAddress + la,
+                info.baseAddress + ha,
+                CoverageRanges::UNCOVERED_REASON_NOT_EXECUTED,
+                count
               );
-              if (Verbose)
-                std::cerr << "Branch always taken found in" << s.first
-                          << std::hex
-                          << " (0x" << s.second.baseAddress + la
-                          << " - 0x" << s.second.baseAddress + ha
-                          << ")"
-                          << std::dec
-                          << std::endl;
+              a = ha + 1;
             }
-            else if (theCoverageMap->wasNeverTaken( la )) {
-              stats.branchesNeverTaken++;
-              s.second.stats.branchesNeverTaken++;
-              theBranches->add(
-                s.second.baseAddress + la,
-                s.second.baseAddress + ha,
-                CoverageRanges::UNCOVERED_REASON_BRANCH_NEVER_TAKEN,
-                1
+
+            // If an address is a branch instruction, add any uncovered branches
+            // to the uncoverd branches.
+            else if (theCoverageMap->isBranch( a )) {
+              la = a;
+              for (ha = a + 1;
+                ha <= endAddress && !theCoverageMap->isStartOfInstruction( ha );
+                  ha++)
+                ;
+              ha--;
+
+              if (theCoverageMap->wasAlwaysTaken( la )) {
+                stats[kv.first].branchesAlwaysTaken++;
+                info.stats.branchesAlwaysTaken++;
+                theBranches->add(
+                  info.baseAddress + la,
+                  info.baseAddress + ha,
+                  CoverageRanges::UNCOVERED_REASON_BRANCH_ALWAYS_TAKEN,
+                  1
                 );
-              if (Verbose)
-                std::cerr << "Branch never taken found in " << s.first
-                          << std::hex
-                          << " (0x" << s.second.baseAddress + la
-                          << " - 0x" << s.second.baseAddress + ha
-                          << ")"
-                          << std::dec
-                          << std::endl;
+                if (Verbose)
+                  std::cerr << "Branch always taken found in" << symbol
+                            << std::hex
+                            << " (0x" << info.baseAddress + la
+                            << " - 0x" << info.baseAddress + ha
+                            << ")"
+                            << std::dec
+                            << std::endl;
+              }
+              else if (theCoverageMap->wasNeverTaken( la )) {
+                stats[kv.first].branchesNeverTaken++;
+                info.stats.branchesNeverTaken++;
+                theBranches->add(
+                  info.baseAddress + la,
+                  info.baseAddress + ha,
+                  CoverageRanges::UNCOVERED_REASON_BRANCH_NEVER_TAKEN,
+                  1
+                  );
+                if (Verbose)
+                  std::cerr << "Branch never taken found in " << symbol
+                            << std::hex
+                            << " (0x" << info.baseAddress + la
+                            << " - 0x" << info.baseAddress + ha
+                            << ")"
+                            << std::dec
+                            << std::endl;
+              }
+              a = ha + 1;
             }
-            a = ha + 1;
+            else
+              a++;
           }
-          else
-            a++;
         }
       }
     }
@@ -460,30 +470,61 @@ namespace Coverage {
     }
   }
 
-  uint32_t DesiredSymbols::getNumberBranchesAlwaysTaken( void ) const {
-    return stats.branchesAlwaysTaken;
+  uint32_t DesiredSymbols::getNumberBranchesAlwaysTaken(
+    const std::string& symbolSetName
+  ) const {
+    return stats.at(symbolSetName).branchesAlwaysTaken;
   };
 
-  uint32_t DesiredSymbols::getNumberBranchesFound( void ) const {
-    return (stats.branchesNotExecuted + stats.branchesExecuted);
+  uint32_t DesiredSymbols::getNumberBranchesFound(
+    const std::string& symbolSetName
+  ) const {
+    return (
+      stats.at(symbolSetName).branchesNotExecuted +
+      stats.at(symbolSetName).branchesExecuted
+    );
   };
 
-  uint32_t DesiredSymbols::getNumberBranchesNeverTaken( void ) const {
-    return stats.branchesNeverTaken;
+  uint32_t DesiredSymbols::getNumberBranchesNeverTaken(
+    const std::string& symbolSetName
+  ) const {
+    return stats.at(symbolSetName).branchesNeverTaken;
   };
 
-  uint32_t DesiredSymbols::getNumberBranchesNotExecuted( void ) const {
-    return stats.branchesNotExecuted;
+  uint32_t DesiredSymbols::getNumberBranchesNotExecuted(
+    const std::string& symbolSetName
+  ) const {
+    return stats.at(symbolSetName).branchesNotExecuted;
   };
 
-  uint32_t DesiredSymbols::getNumberUncoveredRanges( void ) const {
-    return stats.uncoveredRanges;
+  uint32_t DesiredSymbols::getNumberUncoveredRanges(
+    const std::string& symbolSetName
+  ) const {
+    return stats.at(symbolSetName).uncoveredRanges;
   };
 
-  uint32_t DesiredSymbols::getNumberUnreferencedSymbols( void ) const {
-    return stats.unreferencedSymbols;
+  uint32_t DesiredSymbols::getNumberUnreferencedSymbols(
+    const std::string& symbolSetName
+  ) const {
+    return stats.at(symbolSetName).unreferencedSymbols;
   };
 
+  std::vector<std::string> DesiredSymbols::getSetNames( void ) const {
+    std::vector<std::string> setNames;
+    for (const auto &kv : setNamesToSymbols) {
+      setNames.push_back(kv.first);
+    }
+
+    return setNames;
+  }
+
+  const std::vector<std::string>& DesiredSymbols::getSymbolsForSet(
+    const std::string& symbolSetName
+  ) const
+  {
+    return setNamesToSymbols.at(symbolSetName);
+  }
+
   bool DesiredSymbols::isDesired (
     const std::string& symbolName
   ) const
diff --git a/tester/covoar/DesiredSymbols.h b/tester/covoar/DesiredSymbols.h
index 5cf96e9..5280d50 100644
--- a/tester/covoar/DesiredSymbols.h
+++ b/tester/covoar/DesiredSymbols.h
@@ -197,12 +197,6 @@ namespace Coverage {
      */
     typedef std::map<std::string, SymbolInformation> symbolSet_t;
 
-    /*!
-     *  This variable contains a map of symbol sets for each
-     *  symbol in the system keyed on the symbol name.
-     */
-    symbolSet_t set;
-
     /*!
      *  This method constructs a DesiredSymbols instance.
      */
@@ -213,6 +207,11 @@ namespace Coverage {
      */
     ~DesiredSymbols();
 
+    /*!
+     *  The set of all symbols.
+     */
+    const symbolSet_t& allSymbols() const;
+
     /*!
      *  This method loops through the coverage map and
      *  calculates the statistics that have not already
@@ -262,51 +261,93 @@ namespace Coverage {
 
     /*!
      *  This method returns the total number of branches always taken
-     *  for all analyzed symbols.
+     *  for all analyzed symbols in a given set.
+     * 
+     *  @param[in] symbolSetName specifies the symbol set of interest
      *
      *  @return Returns the total number of branches always taken
      */
-    uint32_t getNumberBranchesAlwaysTaken( void ) const;
+    uint32_t getNumberBranchesAlwaysTaken(
+      const std::string& symbolSetName
+    ) const;
 
     /*!
      *  This method returns the total number of branches found for
-     *  all analyzed symbols.
+     *  all analyzed symbols in a given set.
+     * 
+     *  @param[in] symbolSetName specifies the symbol set of interest
      *
      *  @return Returns the total number of branches found
      */
-    uint32_t getNumberBranchesFound( void ) const;
+    uint32_t getNumberBranchesFound(
+      const std::string& symbolSetName
+    ) const;
 
     /*!
      *  This method returns the total number of branches never taken
-     *  for all analyzed symbols.
+     *  for all analyzed symbols in a given set.
+     * 
+     *  @param[in] symbolSetName specifies the symbol set of interest
      *
      *  @return Returns the total number of branches never taken
      */
-    uint32_t getNumberBranchesNeverTaken( void ) const;
+    uint32_t getNumberBranchesNeverTaken(
+      const std::string& symbolSetName
+    ) const;
 
     /*!
      *  This method returns the total number of branches not executed
-     *  for all analyzed symbols.
+     *  for all analyzed symbols in a given set.
+     * 
+     *  @param[in] symbolSetName specifies the symbol set of interest
      *
      *  @return Returns the total number of branches not executed
      */
-    uint32_t getNumberBranchesNotExecuted( void ) const;
+    uint32_t getNumberBranchesNotExecuted(
+      const std::string& symbolSetName
+    ) const;
 
     /*!
      *  This method returns the total number of uncovered ranges
-     *  for all analyzed symbols.
+     *  for all analyzed symbols in a given set.
+     * 
+     *  @param[in] symbolSetName specifies the symbol set of interest
      *
      *  @return Returns the total number of uncovered ranges
      */
-    uint32_t getNumberUncoveredRanges( void ) const;
+    uint32_t getNumberUncoveredRanges(
+      const std::string& symbolSetName
+    ) const;
 
     /*!
      *  This method returns the total number of unreferenced symbols
-     *  for all analyzed symbols.
+     *  for all analyzed symbols in a given set.
+     * 
+     *  @param[in] symbolSetName specifies the symbol set of interest
      *
      *  @return Returns the total number of unreferenced symbols
      */
-    uint32_t getNumberUnreferencedSymbols( void ) const;
+    uint32_t getNumberUnreferencedSymbols(
+      const std::string& symbolSetName
+    ) const;
+
+    /*!
+     *  This method returns all symbol set names.
+     * 
+     *  @return Returns all symbol set names
+     */
+    std::vector<std::string> getSetNames( void ) const;
+
+    /*!
+     *  This method returns all symbols for a given set.
+     * 
+     *  @param[in] symbolSetName specifies the symbol set of interest
+     * 
+     *  @return Returns all symbols for the given set
+     */
+    const std::vector<std::string>& getSymbolsForSet(
+      const std::string& symbolSetName
+    ) const;
 
     /*!
      *  This method returns an indication of whether or not the specified
@@ -353,11 +394,6 @@ namespace Coverage {
      */
     void preprocess( void );
 
-    /*!
-     *  This member contains the statistics kept on each symbol.
-     */
-    Statistics stats;
-
   private:
 
     /*!
@@ -369,6 +405,22 @@ namespace Coverage {
       ExecutableInfo* const theExecutable
     );
 
+    /*!
+     *  This variable contains a map of symbol sets for each
+     *  symbol in the system keyed on the symbol name.
+     */
+    symbolSet_t set;
+
+    /*!
+     *  This variable contains a map of symbol set names to symbol name lists.
+     */
+    std::map<std::string, std::vector<std::string>> setNamesToSymbols;
+
+    /*!
+     *  This member contains a map of symbol set names to statistics.
+     */
+    std::map<std::string, Statistics> stats;
+
   };
 }
 
diff --git a/tester/covoar/ReportsBase.cc b/tester/covoar/ReportsBase.cc
index 40ed209..fea776c 100644
--- a/tester/covoar/ReportsBase.cc
+++ b/tester/covoar/ReportsBase.cc
@@ -20,8 +20,9 @@
 
 namespace Coverage {
 
-ReportsBase::ReportsBase( time_t timestamp ):
+ReportsBase::ReportsBase( time_t timestamp, std::string symbolSetName ):
   reportExtension_m(""),
+  symbolSetName_m(symbolSetName),
   timestamp_m( timestamp )
 {
 }
@@ -31,27 +32,38 @@ ReportsBase::~ReportsBase()
 }
 
 FILE* ReportsBase::OpenFile(
-  const char* const fileName
+  const char* const fileName,
+  const char* const symbolSetName
 )
 {
   int          sc;
   FILE        *aFile;
   std::string  file;
 
+  std::string symbolSetOutputDirectory;
+  rld::path::path_join(
+    outputDirectory,
+    symbolSetName,
+    symbolSetOutputDirectory
+  );
+
   // Create the output directory if it does not already exist
 #ifdef _WIN32
-  sc = _mkdir( outputDirectory );
+  sc = _mkdir( symbolSetOutputDirectory );
 #else
-  sc = mkdir( outputDirectory,0755 );
+  sc = mkdir( symbolSetOutputDirectory.c_str(),0755 );
 #endif
   if ( (sc == -1) && (errno != EEXIST) ) {
-    fprintf(stderr, "Unable to create output directory %s\n", outputDirectory);
+    fprintf(
+      stderr,
+      "Unable to create output directory %s\n",
+      symbolSetOutputDirectory.c_str()
+    );
     return NULL;
   }
 
-  file = outputDirectory;
-  file += "/";
-  file += fileName;
+  file = symbolSetOutputDirectory;
+  rld::path::path_join(file, fileName, file);
 
   // Open the file.
   aFile = fopen( file.c_str(), "w" );
@@ -71,7 +83,7 @@ FILE* ReportsBase::OpenAnnotatedFile(
   const char* const fileName
 )
 {
-  return OpenFile(fileName);
+  return OpenFile(fileName, symbolSetName_m.c_str());
 }
 
 FILE* ReportsBase::OpenBranchFile(
@@ -79,21 +91,21 @@ FILE* ReportsBase::OpenBranchFile(
   bool              hasBranches
 )
 {
-  return OpenFile(fileName);
+  return OpenFile(fileName, symbolSetName_m.c_str());
 }
 
 FILE* ReportsBase::OpenCoverageFile(
   const char* const fileName
 )
 {
-  return OpenFile(fileName);
+  return OpenFile(fileName, symbolSetName_m.c_str());
 }
 
 FILE* ReportsBase::OpenNoRangeFile(
   const char* const fileName
 )
 {
-  return OpenFile(fileName);
+  return OpenFile(fileName, symbolSetName_m.c_str());
 }
 
 
@@ -101,14 +113,14 @@ FILE* ReportsBase::OpenSizeFile(
   const char* const fileName
 )
 {
-  return OpenFile(fileName);
+  return OpenFile(fileName, symbolSetName_m.c_str());
 }
 
 FILE* ReportsBase::OpenSymbolSummaryFile(
   const char* const fileName
 )
 {
-  return OpenFile(fileName);
+  return OpenFile(fileName, symbolSetName_m.c_str());
 }
 
 void ReportsBase::CloseFile(
@@ -186,41 +198,42 @@ void ReportsBase::WriteAnnotatedReport(
   const char* const fileName
 ) {
   FILE*                                                          aFile = NULL;
-  Coverage::DesiredSymbols::symbolSet_t::iterator                ditr;
   Coverage::CoverageRanges*                                      theBranches;
   Coverage::CoverageRanges*                                      theRanges;
   Coverage::CoverageMapBase*                                     theCoverageMap = NULL;
   uint32_t                                                       bAddress = 0;
   AnnotatedLineState_t                                           state;
-  std::list<Coverage::ObjdumpProcessor::objdumpLine_t>*          theInstructions;
-  std::list<Coverage::ObjdumpProcessor::objdumpLine_t>::iterator itr;
+  const std::list<Coverage::ObjdumpProcessor::objdumpLine_t>*    theInstructions;
+  std::list<
+    Coverage::ObjdumpProcessor::objdumpLine_t>::const_iterator   itr;
 
   aFile = OpenAnnotatedFile(fileName);
   if (!aFile)
     return;
 
   // Process uncovered branches for each symbol.
-  for (ditr = SymbolsToAnalyze->set.begin();
-       ditr != SymbolsToAnalyze->set.end();
-       ditr++) {
+  const std::vector<std::string>& symbols = SymbolsToAnalyze->getSymbolsForSet(symbolSetName_m);
+
+  for (const auto& symbol : symbols) {
+    const SymbolInformation& info = SymbolsToAnalyze->allSymbols().at(symbol);
 
     // If uncoveredRanges and uncoveredBranches don't exist, then the
     // symbol was never referenced by any executable.  Just skip it.
-    if ((ditr->second.uncoveredRanges == NULL) &&
-        (ditr->second.uncoveredBranches == NULL))
+    if ((info.uncoveredRanges == NULL) &&
+        (info.uncoveredBranches == NULL))
       continue;
 
     // If uncoveredRanges and uncoveredBranches are empty, then everything
     // must have been covered for this symbol.  Just skip it.
-    if ((ditr->second.uncoveredRanges->set.empty()) &&
-        (ditr->second.uncoveredBranches->set.empty()))
+    if ((info.uncoveredRanges->set.empty()) &&
+        (info.uncoveredBranches->set.empty()))
       continue;
 
-    theCoverageMap = ditr->second.unifiedCoverageMap;
-    bAddress = ditr->second.baseAddress;
-    theInstructions = &(ditr->second.instructions);
-    theRanges = ditr->second.uncoveredRanges;
-    theBranches = ditr->second.uncoveredBranches;
+    theCoverageMap = info.unifiedCoverageMap;
+    bAddress = info.baseAddress;
+    theInstructions = &(info.instructions);
+    theRanges = info.uncoveredRanges;
+    theBranches = info.uncoveredBranches;
 
     // Add annotations to each line where necessary
     AnnotatedStart( aFile );
@@ -274,14 +287,13 @@ void ReportsBase::WriteAnnotatedReport(
 void ReportsBase::WriteBranchReport(
   const char* const fileName
 ) {
-  Coverage::DesiredSymbols::symbolSet_t::iterator ditr;
   FILE*                                           report = NULL;
   Coverage::CoverageRanges::ranges_t::iterator    ritr;
   Coverage::CoverageRanges*                       theBranches;
   unsigned int                                    count;
   bool                                            hasBranches = true;
 
-  if ((SymbolsToAnalyze->getNumberBranchesFound() == 0) ||
+  if ((SymbolsToAnalyze->getNumberBranchesFound(symbolSetName_m) == 0) ||
       (BranchInfoAvailable == false) )
      hasBranches = false;
 
@@ -291,15 +303,16 @@ void ReportsBase::WriteBranchReport(
     return;
 
   // If no branches were found then branch coverage is not supported
-  if ((SymbolsToAnalyze->getNumberBranchesFound() != 0) &&
+  if ((SymbolsToAnalyze->getNumberBranchesFound(symbolSetName_m) != 0) &&
       (BranchInfoAvailable == true) ) {
-    // Process uncovered branches for each symbol.
+    // Process uncovered branches for each symbol in the set.
+    const std::vector<std::string>& symbols = SymbolsToAnalyze->getSymbolsForSet(symbolSetName_m);
+
     count = 0;
-    for (ditr = SymbolsToAnalyze->set.begin();
-         ditr != SymbolsToAnalyze->set.end();
-         ditr++) {
+    for (const auto& symbol : symbols) {
+      const SymbolInformation& info = SymbolsToAnalyze->allSymbols().at(symbol);
 
-      theBranches = ditr->second.uncoveredBranches;
+      theBranches = info.uncoveredBranches;
 
       if (theBranches && !theBranches->set.empty()) {
 
@@ -307,7 +320,7 @@ void ReportsBase::WriteBranchReport(
              ritr != theBranches->set.end() ;
              ritr++ ) {
           count++;
-          PutBranchEntry( report, count, ditr, ritr );
+          PutBranchEntry( report, count, symbol, info, ritr );
         }
       }
     }
@@ -323,7 +336,6 @@ void ReportsBase::WriteCoverageReport(
   const char* const fileName
 )
 {
-  Coverage::DesiredSymbols::symbolSet_t::iterator ditr;
   FILE*                                           report;
   Coverage::CoverageRanges::ranges_t::iterator    ritr;
   Coverage::CoverageRanges*                       theRanges;
@@ -346,26 +358,27 @@ void ReportsBase::WriteCoverageReport(
   }
 
   // Process uncovered ranges for each symbol.
+  const std::vector<std::string>& symbols = SymbolsToAnalyze->getSymbolsForSet(symbolSetName_m);
+
   count = 0;
-  for (ditr = SymbolsToAnalyze->set.begin();
-       ditr != SymbolsToAnalyze->set.end();
-       ditr++) {
+  for (const auto& symbol : symbols) {
+    const SymbolInformation& info = SymbolsToAnalyze->allSymbols().at(symbol);
 
-    theRanges = ditr->second.uncoveredRanges;
+    theRanges = info.uncoveredRanges;
 
     // If uncoveredRanges doesn't exist, then the symbol was never
     // referenced by any executable.  There may be a problem with the
     // desired symbols list or with the executables so put something
     // in the report.
     if (theRanges == NULL) {
-      putCoverageNoRange( report, NoRangeFile, count, ditr->first );
+      putCoverageNoRange( report, NoRangeFile, count, symbol );
       count++;
     }  else if (!theRanges->set.empty()) {
 
       for (ritr =  theRanges->set.begin() ;
            ritr != theRanges->set.end() ;
            ritr++ ) {
-        PutCoverageLine( report, count, ditr, ritr );
+        PutCoverageLine( report, count, symbol, info, ritr );
         count++;
       }
     }
@@ -383,7 +396,6 @@ void ReportsBase::WriteSizeReport(
   const char* const fileName
 )
 {
-  Coverage::DesiredSymbols::symbolSet_t::iterator ditr;
   FILE*                                           report;
   Coverage::CoverageRanges::ranges_t::iterator    ritr;
   Coverage::CoverageRanges*                       theRanges;
@@ -396,19 +408,20 @@ void ReportsBase::WriteSizeReport(
   }
 
   // Process uncovered ranges for each symbol.
+  const std::vector<std::string>& symbols = SymbolsToAnalyze->getSymbolsForSet(symbolSetName_m);
+
   count = 0;
-  for (ditr = SymbolsToAnalyze->set.begin();
-       ditr != SymbolsToAnalyze->set.end();
-       ditr++) {
+  for (const auto& symbol : symbols) {
+    const SymbolInformation& info = SymbolsToAnalyze->allSymbols().at(symbol);
 
-    theRanges = ditr->second.uncoveredRanges;
+    theRanges = info.uncoveredRanges;
 
     if (theRanges && !theRanges->set.empty()) {
 
       for (ritr =  theRanges->set.begin() ;
            ritr != theRanges->set.end() ;
            ritr++ ) {
-        PutSizeLine( report, count, ditr, ritr );
+        PutSizeLine( report, count, symbol, ritr );
         count++;
       }
     }
@@ -421,7 +434,6 @@ void ReportsBase::WriteSymbolSummaryReport(
   const char* const fileName
 )
 {
-  Coverage::DesiredSymbols::symbolSet_t::iterator ditr;
   FILE*                                           report;
   unsigned int                                    count;
 
@@ -432,12 +444,13 @@ void ReportsBase::WriteSymbolSummaryReport(
   }
 
   // Process each symbol.
+  const std::vector<std::string>& symbols = SymbolsToAnalyze->getSymbolsForSet(symbolSetName_m);
+
   count = 0;
-  for (ditr = SymbolsToAnalyze->set.begin();
-       ditr != SymbolsToAnalyze->set.end();
-       ditr++) {
+  for (const auto& symbol : symbols) {
+    const SymbolInformation& info = SymbolsToAnalyze->allSymbols().at(symbol);
 
-    PutSymbolSummaryLine( report, count, ditr );
+    PutSymbolSummaryLine( report, count, symbol, info );
     count++;
   }
 
@@ -445,13 +458,13 @@ void ReportsBase::WriteSymbolSummaryReport(
 }
 
 void  ReportsBase::WriteSummaryReport(
-  const char* const fileName
+  const char* const fileName,
+  const char* const symbolSetName
 )
 {
     // Calculate coverage statistics and output results.
   uint32_t                                        a;
   uint32_t                                        endAddress;
-  Coverage::DesiredSymbols::symbolSet_t::iterator itr;
   uint32_t                                        notExecuted = 0;
   double                                          percentage;
   double                                          percentageBranches;
@@ -460,22 +473,23 @@ void  ReportsBase::WriteSummaryReport(
   FILE*                                           report;
 
   // Open the report file.
-  report = OpenFile( fileName );
+  report = OpenFile( fileName, symbolSetName );
   if ( !report ) {
     return;
   }
 
   // Look at each symbol.
-  for (itr = SymbolsToAnalyze->set.begin();
-       itr != SymbolsToAnalyze->set.end();
-       itr++) {
+  const std::vector<std::string>& symbols = SymbolsToAnalyze->getSymbolsForSet(symbolSetName);
+
+  for (const auto& symbol : symbols) {
+    SymbolInformation info = SymbolsToAnalyze->allSymbols().at(symbol);
 
     // If the symbol's unified coverage map exists, scan through it
     // and count bytes.
-    theCoverageMap = itr->second.unifiedCoverageMap;
+    theCoverageMap = info.unifiedCoverageMap;
     if (theCoverageMap) {
 
-      endAddress = itr->second.stats.sizeInBytes - 1;
+      endAddress = info.stats.sizeInBytes - 1;
 
       for (a = 0; a <= endAddress; a++) {
         totalBytes++;
@@ -490,11 +504,12 @@ void  ReportsBase::WriteSummaryReport(
   percentage *= 100.0;
 
   percentageBranches = (double) (
-    SymbolsToAnalyze->getNumberBranchesAlwaysTaken() +
-      SymbolsToAnalyze->getNumberBranchesNeverTaken() +
-      (SymbolsToAnalyze->getNumberBranchesNotExecuted() * 2)
+    SymbolsToAnalyze->getNumberBranchesAlwaysTaken(symbolSetName) +
+      SymbolsToAnalyze->getNumberBranchesNeverTaken(symbolSetName) +
+      (SymbolsToAnalyze->getNumberBranchesNotExecuted(symbolSetName) * 2)
   );
-  percentageBranches /= (double) SymbolsToAnalyze->getNumberBranchesFound() * 2;
+  percentageBranches /=
+    (double) SymbolsToAnalyze->getNumberBranchesFound(symbolSetName) * 2;
   percentageBranches *= 100.0;
 
   fprintf( report, "Bytes Analyzed                   : %d\n", totalBytes );
@@ -504,48 +519,48 @@ void  ReportsBase::WriteSummaryReport(
   fprintf(
     report,
     "Unreferenced Symbols             : %d\n",
-    SymbolsToAnalyze->getNumberUnreferencedSymbols()
+    SymbolsToAnalyze->getNumberUnreferencedSymbols(symbolSetName)
   );
   fprintf(
     report,
     "Uncovered ranges found           : %d\n\n",
-    SymbolsToAnalyze->getNumberUncoveredRanges()
+    SymbolsToAnalyze->getNumberUncoveredRanges(symbolSetName)
   );
-  if ((SymbolsToAnalyze->getNumberBranchesFound() == 0) ||
+  if ((SymbolsToAnalyze->getNumberBranchesFound(symbolSetName) == 0) ||
       (BranchInfoAvailable == false) ) {
     fprintf( report, "No branch information available\n" );
   } else {
     fprintf(
       report,
       "Total conditional branches found : %d\n",
-      SymbolsToAnalyze->getNumberBranchesFound()
+      SymbolsToAnalyze->getNumberBranchesFound(symbolSetName)
     );
     fprintf(
       report,
       "Total branch paths found         : %d\n",
-      SymbolsToAnalyze->getNumberBranchesFound() * 2
+      SymbolsToAnalyze->getNumberBranchesFound(symbolSetName) * 2
     );
     fprintf(
       report,
       "Uncovered branch paths found     : %d\n",
-      SymbolsToAnalyze->getNumberBranchesAlwaysTaken() +
-       SymbolsToAnalyze->getNumberBranchesNeverTaken() +
-       (SymbolsToAnalyze->getNumberBranchesNotExecuted() * 2)
+      SymbolsToAnalyze->getNumberBranchesAlwaysTaken(symbolSetName) +
+       SymbolsToAnalyze->getNumberBranchesNeverTaken(symbolSetName) +
+       (SymbolsToAnalyze->getNumberBranchesNotExecuted(symbolSetName) * 2)
     );
     fprintf(
       report,
       "   %d branches always taken\n",
-      SymbolsToAnalyze->getNumberBranchesAlwaysTaken()
+      SymbolsToAnalyze->getNumberBranchesAlwaysTaken(symbolSetName)
     );
     fprintf(
       report,
       "   %d branches never taken\n",
-      SymbolsToAnalyze->getNumberBranchesNeverTaken()
+      SymbolsToAnalyze->getNumberBranchesNeverTaken(symbolSetName)
     );
     fprintf(
       report,
       "   %d branch paths not executed\n",
-      SymbolsToAnalyze->getNumberBranchesNotExecuted() * 2
+      SymbolsToAnalyze->getNumberBranchesNotExecuted(symbolSetName) * 2
     );
     fprintf(
       report,
@@ -555,7 +570,7 @@ void  ReportsBase::WriteSummaryReport(
   }
 }
 
-void GenerateReports()
+void GenerateReports(const std::string& symbolSetName)
 {
   typedef std::list<ReportsBase *> reportList_t;
 
@@ -568,9 +583,9 @@ void GenerateReports()
 
 
   timestamp = time(NULL); /* get current cal time */
-  reports = new ReportsText(timestamp);
+  reports = new ReportsText(timestamp, symbolSetName);
   reportList.push_back(reports);
-  reports = new ReportsHtml(timestamp);
+  reports = new ReportsHtml(timestamp, symbolSetName);
   reportList.push_back(reports);
 
   for (ritr = reportList.begin(); ritr != reportList.end(); ritr++ ) {
@@ -624,7 +639,7 @@ void GenerateReports()
     delete reports;
   }
 
-  ReportsBase::WriteSummaryReport( "summary.txt" );
+  ReportsBase::WriteSummaryReport( "summary.txt", symbolSetName.c_str() );
 }
 
 }
diff --git a/tester/covoar/ReportsBase.h b/tester/covoar/ReportsBase.h
index 7e28fd8..e7b1fb3 100644
--- a/tester/covoar/ReportsBase.h
+++ b/tester/covoar/ReportsBase.h
@@ -24,7 +24,7 @@ namespace Coverage {
 class ReportsBase {
 
   public:
-    ReportsBase( time_t timestamp );
+    ReportsBase( time_t timestamp, std::string symbolSetName );
     virtual ~ReportsBase();
 
     /*!
@@ -90,7 +90,8 @@ class ReportsBase {
      *  This method produces a sumary report for the overall test run.
      */
     static void  WriteSummaryReport(
-      const char* const fileName
+      const char* const fileName,
+      const char* const symbolSetName
     );
 
     /*!
@@ -118,6 +119,11 @@ class ReportsBase {
      */
     std::string reportExtension_m;
 
+    /*!
+     *  This member variable contains the name of the symbol set for the report.
+     */
+    std::string symbolSetName_m;
+
     /*!
      *  This member variable contains the timestamp for the report.
      */
@@ -128,9 +134,11 @@ class ReportsBase {
      *  correctly.  Upon failure NULL is returned.
      *
      *  @param[in] fileName identifies the report file name
+     *  @param[in] symbolSetName identifies the name of the report's symbol set
      */
      static FILE* OpenFile(
-      const char* const fileName
+      const char* const fileName,
+      const char* const symbolSetName
     );
 
     /*!
@@ -318,13 +326,15 @@ class ReportsBase {
      *
      *  @param[in] report identifies the report file name
      *  @param[in] number identifies the line number.
-     *  @param[in] symbolPtr is a pointer to the symbol information
+     *  @param[in] symbolName is the symbol's name.
+     *  @param[in] symbolInfo is the symbol's information.
      *  @param[in] rangePtr is a pointer to the range information.
      */
     virtual bool PutBranchEntry(
       FILE*                                            report,
       unsigned int                                     number,
-      Coverage::DesiredSymbols::symbolSet_t::iterator  symbolPtr,
+      const std::string&                               symbolName,
+      const SymbolInformation&                         symbolInfo,
       Coverage::CoverageRanges::ranges_t::iterator     rangePtr
     )=0;
 
@@ -348,13 +358,15 @@ class ReportsBase {
      *
      *  @param[in] report identifies the report file name
      *  @param[in] number identifies the line number.
-     *  @param[in] ditr is a iterator to the symbol information
+     *  @param[in] symbolName is the symbol's name.
+     *  @param[in] symbolInfo is the symbol's information.
      *  @param[in] ritr is a iterator to the range information.
      */
     virtual bool PutCoverageLine(
       FILE*                                           report,
       unsigned int                                    number,
-      Coverage::DesiredSymbols::symbolSet_t::iterator ditr,
+      const std::string&                              symbolName,
+      const SymbolInformation&                        symbolInfo,
       Coverage::CoverageRanges::ranges_t::iterator    ritr
     )=0;
 
@@ -363,13 +375,13 @@ class ReportsBase {
      *
      *  @param[in] report identifies the size report file name
      *  @param[in] number identifies the line number.
-     *  @param[in] symbol is a pointer to the symbol information
+     *  @param[in] symbolName is the symbol's name.
      *  @param[in] range is a iterator to the range information.
      */
     virtual bool PutSizeLine(
       FILE*                                           report,
       unsigned int                                    number,
-      Coverage::DesiredSymbols::symbolSet_t::iterator symbol,
+      const std::string&                              symbolName,
       Coverage::CoverageRanges::ranges_t::iterator    range
     )=0;
 
@@ -378,20 +390,24 @@ class ReportsBase {
      *
      *  @param[in] report identifies the report file name
      *  @param[in] number identifies the line number.
-     *  @param[in] symbol is a pointer to the symbol information
+     *  @param[in] symbolName is the symbol's name.
+     *  @param[in] symbolInfo is the symbol's information.
      */
     virtual bool PutSymbolSummaryLine(
       FILE*                                           report,
       unsigned int                                    number,
-      Coverage::DesiredSymbols::symbolSet_t::iterator symbol
+      const std::string&                              symbolName,
+      const SymbolInformation&                        symbolInfo
     )=0;
 };
 
 /*!
  *  This method iterates over all report set types and generates
  *  all reports.
+ * 
+ *  @param[in] symbolSetName is the name of the symbol set to report on.
  */
-void GenerateReports();
+void GenerateReports(const std::string& symbolSetName);
 
 }
 
diff --git a/tester/covoar/ReportsHtml.cc b/tester/covoar/ReportsHtml.cc
index 6406a48..7137016 100644
--- a/tester/covoar/ReportsHtml.cc
+++ b/tester/covoar/ReportsHtml.cc
@@ -31,8 +31,8 @@
 
 namespace Coverage {
 
-  ReportsHtml::ReportsHtml( time_t timestamp ):
-    ReportsBase( timestamp )
+  ReportsHtml::ReportsHtml( time_t timestamp, std::string symbolSetName ):
+    ReportsBase( timestamp, symbolSetName )
   {
     reportExtension_m = ".html";
   }
@@ -113,7 +113,7 @@ namespace Coverage {
     FILE*  aFile;
 
     // Open the file
-    aFile = ReportsBase::OpenFile( fileName );
+    aFile = ReportsBase::OpenFile( fileName, symbolSetName_m.c_str() );
 
     // Put Header information on the file
     fprintf(
@@ -488,7 +488,8 @@ namespace Coverage {
     FILE* report
   )
   {
-    if (BranchInfoAvailable && SymbolsToAnalyze->getNumberBranchesFound() != 0)
+    if (BranchInfoAvailable &&
+      SymbolsToAnalyze->getNumberBranchesFound(symbolSetName_m) != 0)
       fprintf( report, "All branch paths taken.\n" );
     else
       fprintf( report, "No branch information found.\n" );
@@ -498,7 +499,8 @@ namespace Coverage {
   bool ReportsHtml::PutBranchEntry(
     FILE*                                            report,
     unsigned int                                     count,
-    Coverage::DesiredSymbols::symbolSet_t::iterator  symbolPtr,
+    const std::string&                               symbolName,
+    const SymbolInformation&                         symbolInfo,
     Coverage::CoverageRanges::ranges_t::iterator     rangePtr
   )
   {
@@ -519,7 +521,7 @@ namespace Coverage {
     fprintf(
       report,
       "<td class=\"covoar-td\" align=\"center\">%s</td>\n",
-      symbolPtr->first.c_str()
+      symbolName.c_str()
     );
 
     // line
@@ -562,8 +564,8 @@ namespace Coverage {
 
     // Taken / Not taken counts
     lowAddress = rangePtr->lowAddress;
-    bAddress = symbolPtr->second.baseAddress;
-    theCoverageMap = symbolPtr->second.unifiedCoverageMap;
+    bAddress = symbolInfo.baseAddress;
+    theCoverageMap = symbolInfo.unifiedCoverageMap;
     fprintf(
       report,
       "<td class=\"covoar-td\" align=\"center\">%d</td>\n",
@@ -703,7 +705,8 @@ namespace Coverage {
   bool ReportsHtml::PutCoverageLine(
     FILE*                                            report,
     unsigned int                                     count,
-    Coverage::DesiredSymbols::symbolSet_t::iterator  symbolPtr,
+    const std::string&                               symbolName,
+    const SymbolInformation&                         symbolInfo,
     Coverage::CoverageRanges::ranges_t::iterator     rangePtr
   )
   {
@@ -721,7 +724,7 @@ namespace Coverage {
     fprintf(
       report,
       "<td class=\"covoar-td\" align=\"center\">%s</td>\n",
-      symbolPtr->first.c_str()
+      symbolName.c_str()
     );
 
     // Range
@@ -790,7 +793,7 @@ namespace Coverage {
   bool  ReportsHtml::PutSizeLine(
     FILE*                                           report,
     unsigned int                                    count,
-    Coverage::DesiredSymbols::symbolSet_t::iterator symbol,
+    const std::string&                              symbolName,
     Coverage::CoverageRanges::ranges_t::iterator    range
   )
   {
@@ -814,7 +817,7 @@ namespace Coverage {
     fprintf(
       report,
       "<td class=\"covoar-td\" align=\"center\">%s</td>\n",
-      symbol->first.c_str()
+      symbolName.c_str()
     );
 
     // line
@@ -842,7 +845,8 @@ namespace Coverage {
   bool  ReportsHtml::PutSymbolSummaryLine(
     FILE*                                           report,
     unsigned int                                    count,
-    Coverage::DesiredSymbols::symbolSet_t::iterator symbol
+    const std::string&                              symbolName,
+    const SymbolInformation&                        symbolInfo
   )
   {
 
@@ -856,10 +860,10 @@ namespace Coverage {
     fprintf(
       report,
       "<td class=\"covoar-td\" align=\"center\">%s</td>\n",
-      symbol->first.c_str()
+      symbolName.c_str()
     );
 
-    if (symbol->second.stats.sizeInBytes == 0) {
+    if (symbolInfo.stats.sizeInBytes == 0) {
       // The symbol has never been seen. Write "unknown" for all columns.
       fprintf(
         report,
@@ -879,60 +883,60 @@ namespace Coverage {
       fprintf(
         report,
         "<td class=\"covoar-td\" align=\"center\">%d</td>\n",
-        symbol->second.stats.sizeInBytes
+        symbolInfo.stats.sizeInBytes
       );
 
       // Total Size in Instructions
       fprintf(
         report,
         "<td class=\"covoar-td\" align=\"center\">%d</td>\n",
-        symbol->second.stats.sizeInInstructions
+        symbolInfo.stats.sizeInInstructions
       );
 
       // Total Uncovered Ranges
       fprintf(
         report,
         "<td class=\"covoar-td\" align=\"center\">%d</td>\n",
-        symbol->second.stats.uncoveredRanges
+        symbolInfo.stats.uncoveredRanges
       );
 
       // Uncovered Size in Bytes
       fprintf(
         report,
         "<td class=\"covoar-td\" align=\"center\">%d</td>\n",
-        symbol->second.stats.uncoveredBytes
+        symbolInfo.stats.uncoveredBytes
       );
 
       // Uncovered Size in Instructions
       fprintf(
         report,
         "<td class=\"covoar-td\" align=\"center\">%d</td>\n",
-        symbol->second.stats.uncoveredInstructions
+        symbolInfo.stats.uncoveredInstructions
       );
 
       // Total number of branches
       fprintf(
         report,
         "<td class=\"covoar-td\" align=\"center\">%d</td>\n",
-        symbol->second.stats.branchesNotExecuted +  symbol->second.stats.branchesExecuted
+        symbolInfo.stats.branchesNotExecuted + symbolInfo.stats.branchesExecuted
       );
 
       // Total Always Taken
       fprintf(
         report,
         "<td class=\"covoar-td\" align=\"center\">%d</td>\n",
-        symbol->second.stats.branchesAlwaysTaken
+        symbolInfo.stats.branchesAlwaysTaken
       );
 
       // Total Never Taken
       fprintf(
         report,
         "<td class=\"covoar-td\" align=\"center\">%d</td>\n",
-        symbol->second.stats.branchesNeverTaken
+        symbolInfo.stats.branchesNeverTaken
       );
 
       // % Uncovered Instructions
-      if ( symbol->second.stats.sizeInInstructions == 0 )
+      if ( symbolInfo.stats.sizeInInstructions == 0 )
         fprintf(
           report,
           "<td class=\"covoar-td\" align=\"center\">100.00</td>\n"
@@ -941,12 +945,12 @@ namespace Coverage {
         fprintf(
           report,
           "<td class=\"covoar-td\" align=\"center\">%.2f</td>\n",
-          (symbol->second.stats.uncoveredInstructions*100.0)/
-           symbol->second.stats.sizeInInstructions
+          (symbolInfo.stats.uncoveredInstructions*100.0)/
+           symbolInfo.stats.sizeInInstructions
         );
 
       // % Uncovered Bytes
-      if ( symbol->second.stats.sizeInBytes == 0 )
+      if ( symbolInfo.stats.sizeInBytes == 0 )
         fprintf(
           report,
           "<td class=\"covoar-td\" align=\"center\">100.00</td>\n"
@@ -955,8 +959,8 @@ namespace Coverage {
         fprintf(
           report,
           "<td class=\"covoar-td\" align=\"center\">%.2f</td>\n",
-          (symbol->second.stats.uncoveredBytes*100.0)/
-           symbol->second.stats.sizeInBytes
+          (symbolInfo.stats.uncoveredBytes*100.0)/
+           symbolInfo.stats.sizeInBytes
         );
     }
 
diff --git a/tester/covoar/ReportsHtml.h b/tester/covoar/ReportsHtml.h
index 34193da..7972ce1 100644
--- a/tester/covoar/ReportsHtml.h
+++ b/tester/covoar/ReportsHtml.h
@@ -22,7 +22,7 @@ namespace Coverage {
 class ReportsHtml: public ReportsBase {
 
   public:
-    ReportsHtml( time_t timestamp );
+    ReportsHtml( time_t timestamp, std::string symbolSetName );
    ~ReportsHtml();
 
    /*!
@@ -163,7 +163,8 @@ class ReportsHtml: public ReportsBase {
     virtual bool PutBranchEntry(
       FILE*                                            report,
       unsigned int                                     number,
-      Coverage::DesiredSymbols::symbolSet_t::iterator  symbolPtr,
+      const std::string&                               symbolName,
+      const SymbolInformation&                         symbolInfo,
       Coverage::CoverageRanges::ranges_t::iterator     rangePtr
     );
 
@@ -179,7 +180,8 @@ class ReportsHtml: public ReportsBase {
     virtual bool PutCoverageLine(
       FILE*                                           report,
       unsigned int                                    number,
-      Coverage::DesiredSymbols::symbolSet_t::iterator ditr,
+      const std::string&                              symbolName,
+      const SymbolInformation&                        symbolInfo,
       Coverage::CoverageRanges::ranges_t::iterator    ritr
     );
 
@@ -187,7 +189,7 @@ class ReportsHtml: public ReportsBase {
     virtual bool PutSizeLine(
       FILE*                                           report,
       unsigned int                                    number,
-      Coverage::DesiredSymbols::symbolSet_t::iterator symbol,
+      const std::string&                              symbolName,
       Coverage::CoverageRanges::ranges_t::iterator    range
     );
 
@@ -195,7 +197,8 @@ class ReportsHtml: public ReportsBase {
     virtual bool PutSymbolSummaryLine(
       FILE*                                           report,
       unsigned int                                    number,
-      Coverage::DesiredSymbols::symbolSet_t::iterator symbol
+      const std::string&                              symbolName,
+      const SymbolInformation&                        symbolInfo
     );
 
     /* Inherit documentation from base class. */ 
diff --git a/tester/covoar/ReportsText.cc b/tester/covoar/ReportsText.cc
index a3923e6..f552cdd 100644
--- a/tester/covoar/ReportsText.cc
+++ b/tester/covoar/ReportsText.cc
@@ -11,8 +11,8 @@
 
 namespace Coverage {
 
-ReportsText::ReportsText( time_t timestamp ):
-  ReportsBase( timestamp )
+ReportsText::ReportsText( time_t timestamp, std::string symbolSetName ):
+  ReportsBase( timestamp, symbolSetName )
 {
   reportExtension_m = ".txt";
 }
@@ -52,7 +52,8 @@ bool ReportsText::PutNoBranchInfo(
   FILE*           report
 )
 {
-  if ( BranchInfoAvailable && SymbolsToAnalyze->getNumberBranchesFound() != 0 )
+  if ( BranchInfoAvailable &&
+    SymbolsToAnalyze->getNumberBranchesFound(symbolSetName_m) != 0 )
     fprintf( report, "All branch paths taken.\n" );
   else
     fprintf( report, "No branch information found.\n" );
@@ -61,9 +62,10 @@ bool ReportsText::PutNoBranchInfo(
 
 
 bool ReportsText::PutBranchEntry(
-  FILE*   report,
+  FILE*                                            report,
   unsigned int                                     number,
-  Coverage::DesiredSymbols::symbolSet_t::iterator  symbolPtr,
+  const std::string&                               symbolName,
+  const SymbolInformation&                         symbolInfo,
   Coverage::CoverageRanges::ranges_t::iterator     rangePtr
 )
 {
@@ -76,8 +78,8 @@ bool ReportsText::PutBranchEntry(
     "Symbol        : %s (0x%x)\n"
     "Line          : %s (0x%x)\n"
     "Size in Bytes : %d\n",
-    symbolPtr->first.c_str(),
-    symbolPtr->second.baseAddress,
+    symbolName.c_str(),
+    symbolInfo.baseAddress,
     rangePtr->lowSourceLine.c_str(),
     rangePtr->lowAddress,
     rangePtr->highAddress - rangePtr->lowAddress + 1
@@ -153,9 +155,10 @@ void ReportsText::putCoverageNoRange(
 }
 
 bool ReportsText::PutCoverageLine(
-  FILE*                                       report,
-  unsigned int                                     number,
-  Coverage::DesiredSymbols::symbolSet_t::iterator ditr,
+  FILE*                                           report,
+  unsigned int                                    number,
+  const std::string&                              symbolName,
+  const SymbolInformation&                        symbolInfo,
   Coverage::CoverageRanges::ranges_t::iterator    ritr
 )
 {
@@ -171,8 +174,8 @@ bool ReportsText::PutCoverageLine(
     "Size in Bytes        : %d\n"
     "Size in Instructions : %d\n\n",
     ritr->id,
-    ditr->first.c_str(),
-    ditr->second.baseAddress,
+    symbolName.c_str(),
+    symbolInfo.baseAddress,
     ritr->lowSourceLine.c_str(),
     ritr->lowAddress,
     ritr->highSourceLine.c_str(),
@@ -210,9 +213,9 @@ bool ReportsText::PutCoverageLine(
 }
 
 bool  ReportsText::PutSizeLine(
-  FILE*                                      report,
-  unsigned int                                     number,
-  Coverage::DesiredSymbols::symbolSet_t::iterator symbol,
+  FILE*                                           report,
+  unsigned int                                    number,
+  const std::string&                              symbolName,
   Coverage::CoverageRanges::ranges_t::iterator    range
 )
 {
@@ -220,7 +223,7 @@ bool  ReportsText::PutSizeLine(
     report,
     "%d\t%s\t%s\n",
     range->highAddress - range->lowAddress + 1,
-    symbol->first.c_str(),
+    symbolName.c_str(),
     range->lowSourceLine.c_str()
   );
   return true;
@@ -229,13 +232,14 @@ bool  ReportsText::PutSizeLine(
 bool  ReportsText::PutSymbolSummaryLine(
   FILE*                                           report,
   unsigned int                                    number,
-  Coverage::DesiredSymbols::symbolSet_t::iterator symbol
+  const std::string&                              symbolName,
+  const SymbolInformation&                        symbolInfo
 )
 {
   float uncoveredBytes;
   float uncoveredInstructions;
 
-  if (symbol->second.stats.sizeInBytes == 0) {
+  if (symbolInfo.stats.sizeInBytes == 0) {
     fprintf(
       report,
       "============================================\n"
@@ -245,20 +249,20 @@ bool  ReportsText::PutSymbolSummaryLine(
       "Therefore there is no size or disassembly for this symbol.\n"
       "This could be due to symbol misspelling or lack of a test for\n"
       "this symbol.\n",
-      symbol->first.c_str()
+      symbolName.c_str()
     );
   } else {
-    if ( symbol->second.stats.sizeInInstructions == 0 )
+    if ( symbolInfo.stats.sizeInInstructions == 0 )
       uncoveredInstructions = 0;
     else
-      uncoveredInstructions = (symbol->second.stats.uncoveredInstructions*100.0)/
-                              symbol->second.stats.sizeInInstructions;
+      uncoveredInstructions = (symbolInfo.stats.uncoveredInstructions*100.0)/
+                              symbolInfo.stats.sizeInInstructions;
 
-    if ( symbol->second.stats.sizeInBytes == 0 )
+    if ( symbolInfo.stats.sizeInBytes == 0 )
       uncoveredBytes = 0;
     else
-      uncoveredBytes = (symbol->second.stats.uncoveredBytes*100.0)/
-                       symbol->second.stats.sizeInBytes;
+      uncoveredBytes = (symbolInfo.stats.uncoveredBytes*100.0)/
+                       symbolInfo.stats.sizeInBytes;
 
     fprintf(
       report,
@@ -271,12 +275,12 @@ bool  ReportsText::PutSymbolSummaryLine(
       "Total Never Taken                 : %d\n"
       "Percentage Uncovered Instructions : %.2f\n"
       "Percentage Uncovered Bytes        : %.2f\n",
-      symbol->first.c_str(),
-      symbol->second.stats.sizeInBytes,
-      symbol->second.stats.sizeInInstructions,
-      symbol->second.stats.branchesNotExecuted +  symbol->second.stats.branchesExecuted,
-      symbol->second.stats.branchesAlwaysTaken,
-      symbol->second.stats.branchesNeverTaken,
+      symbolName.c_str(),
+      symbolInfo.stats.sizeInBytes,
+      symbolInfo.stats.sizeInInstructions,
+      symbolInfo.stats.branchesNotExecuted +  symbolInfo.stats.branchesExecuted,
+      symbolInfo.stats.branchesAlwaysTaken,
+      symbolInfo.stats.branchesNeverTaken,
       uncoveredInstructions,
       uncoveredBytes
     );
diff --git a/tester/covoar/ReportsText.h b/tester/covoar/ReportsText.h
index 9ae87d4..cf8a813 100644
--- a/tester/covoar/ReportsText.h
+++ b/tester/covoar/ReportsText.h
@@ -21,7 +21,7 @@ namespace Coverage {
 class ReportsText: public ReportsBase {
 
   public:
-    ReportsText( time_t timestamp );
+    ReportsText( time_t timestamp, std::string symbolSetName );
     virtual ~ReportsText();
 
   /*!
@@ -83,7 +83,8 @@ class ReportsText: public ReportsBase {
     virtual bool PutBranchEntry(
       FILE*                                            report,
       unsigned int                                     number,
-      Coverage::DesiredSymbols::symbolSet_t::iterator  symbolPtr,
+      const std::string&                               symbolName,
+      const SymbolInformation&                         symbolInfo,
       Coverage::CoverageRanges::ranges_t::iterator     rangePtr
     );
 
@@ -99,7 +100,8 @@ class ReportsText: public ReportsBase {
     virtual bool PutCoverageLine(
       FILE*                                           report,
       unsigned int                                    number,
-      Coverage::DesiredSymbols::symbolSet_t::iterator ditr,
+      const std::string&                              symbolName,
+      const SymbolInformation&                        symbolInfo,
       Coverage::CoverageRanges::ranges_t::iterator    ritr
     );
 
@@ -107,7 +109,7 @@ class ReportsText: public ReportsBase {
     virtual bool PutSizeLine(
       FILE*                                           report,
       unsigned int                                    number,
-      Coverage::DesiredSymbols::symbolSet_t::iterator symbol,
+      const std::string&                              symbolName,
       Coverage::CoverageRanges::ranges_t::iterator    range
     );
 
@@ -115,7 +117,8 @@ class ReportsText: public ReportsBase {
     virtual bool PutSymbolSummaryLine(
       FILE*                                           report,
       unsigned int                                    number,
-      Coverage::DesiredSymbols::symbolSet_t::iterator symbol
+      const std::string&                              symbolName,
+      const SymbolInformation&                        symbolInfo
     );
 };
 
diff --git a/tester/covoar/covoar.cc b/tester/covoar/covoar.cc
index 84d883a..8d63132 100644
--- a/tester/covoar/covoar.cc
+++ b/tester/covoar/covoar.cc
@@ -350,7 +350,7 @@ int covoar(
     throw rld::error( "executables and coverage name size mismatch", "covoar" );
 
   if ( Verbose )
-    std::cerr << "Analyzing " << SymbolsToAnalyze->set.size()
+    std::cerr << "Analyzing " << SymbolsToAnalyze->allSymbols().size()
               << " symbols" << std::endl;
 
   // Create explanations.
@@ -473,7 +473,9 @@ int covoar(
   if (Verbose)
     std::cerr << "Generate Reports" << std::endl;
 
-  Coverage::GenerateReports();
+  for (const auto& setName : SymbolsToAnalyze->getSetNames()) {
+    Coverage::GenerateReports(setName);
+  }
 
   // Write explanations that were not found.
   if ( explanations ) {
-- 
2.27.0



More information about the devel mailing list