Hi,

I am sending patches for rtems-tools repo. These patches are results of my
development during ESA SOCIS 2014. They introduces coverage analysis into
rtems-test command in rtems-tools repo.

Blog post about how to setup the environment and get coverage analysis
working in new way can be found here:
http://kmiesowicz.blogspot.com/2014/08/new-approach-to-coverage-analysis-in.html

There are still some issues - for example symbol set configuration file
which now has to be manually adjusted to RTEMS build path. This is
inconvenient and I will continue work to improve this.

I'm looking forward to your reviews and comments.

Regards
Krzysztof Miesowicz
From 6b7b2937eb25b31d1c1162efd95b6a18365cb277 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Krzysztof=20Mi=C4=99sowicz?= <krzysztof.miesow...@gmail.com>
Date: Wed, 27 Aug 2014 13:16:17 +0200
Subject: [PATCH 01/12] --coverage feature added to rtems-test command + pc386
 BSP support for rtems-test

---
 rtemstoolkit/options.py            |   2 +
 tester/rt/coverage.py              | 264 +++++++++++++++++++++++++++++++++++++
 tester/rt/test.py                  |  20 ++-
 tester/rtems/testing/bsps/pc386.mc |  57 ++++++++
 tester/rtems/testing/coverage.mc   |  48 +++++++
 tester/rtems/testing/gdb.cfg       |   7 +
 tester/rtems/testing/qemu.cfg      |  17 ++-
 7 files changed, 412 insertions(+), 3 deletions(-)
 create mode 100644 tester/rt/coverage.py
 create mode 100644 tester/rtems/testing/bsps/pc386.mc
 create mode 100644 tester/rtems/testing/coverage.mc

diff --git a/rtemstoolkit/options.py b/rtemstoolkit/options.py
index 97b8ba7..5aa1ed3 100644
--- a/rtemstoolkit/options.py
+++ b/rtemstoolkit/options.py
@@ -91,6 +91,7 @@ class command_line(object):
             '--keep-going'     : ('_keep_going',       self._lo_bool,     False, '0',       True),
             '--always-clean'   : ('_always_clean',     self._lo_bool,     False, '0',       True),
             '--no-install'     : ('_no_install',       self._lo_bool,     False, '0',       True),
+            '--coverage'       : ('_coverage',         self._lo_bool,     False, '0',       False),
             '--help'           : (None,                self._lo_help,     False, None,      False)
         }
         self.long_opts_help = {
@@ -105,6 +106,7 @@ class command_line(object):
             '--jobs=[0..n,none,half,full]': 'Run with specified number of jobs, default: num CPUs.',
             '--macros file[,file]':         'Macro format files to load after the defaults',
             '--log file':                   'Log file where all build out is written too',
+            '--coverage':                   'Perform coverage analysis'
         }
         self.opts = { 'params' : [] }
         self.command_path = command_path
diff --git a/tester/rt/coverage.py b/tester/rt/coverage.py
new file mode 100644
index 0000000..e170607
--- /dev/null
+++ b/tester/rt/coverage.py
@@ -0,0 +1,264 @@
+'''
+Created on Jul 7, 2014
+
+@author: Krzysztof Mięsowicz <krzysztof.miesow...@gmail.com>
+'''
+from rtemstoolkit import path
+from rtemstoolkit import log
+from rtemstoolkit import execute
+from rtemstoolkit import macros
+import os
+from datetime import datetime
+
+class summary:
+    def __init__(self, p_summaryDir):
+        self.summaryFilePath = path.join(p_summaryDir, "summary.txt")
+        self.indexFilePath = path.join(p_summaryDir, "index.html")
+        self.bytes_analyzed = 0
+        self.bytes_notExecuted = 0
+        self.percentage_executed = 0.0
+        self.percentage_notExecuted = 100.0
+        self.ranges_uncovered = 0
+        self.branches_uncovered = 0
+        self.branches_total = 0
+        self.branches_alwaysTaken = 0
+        self.branches_neverTaken = 0
+        self.percentage_branchesCovered = 0.0
+
+    def parse(self):
+        if(not path.exists(self.summaryFilePath)):
+            log.warning("Summary file " + self.summaryFilePath + " does not exist!")
+            return
+
+        summaryFile = open(self.summaryFilePath,'r')
+        self.bytes_analyzed = self._getValueFromNextLineWithColon(summaryFile)
+        self.bytes_notExecuted = self._getValueFromNextLineWithColon(summaryFile)
+        self.percentage_executed = self._getValueFromNextLineWithColon(summaryFile)
+        self.percentage_notExecuted = self._getValueFromNextLineWithColon(summaryFile)
+        self.ranges_uncovered = self._getValueFromNextLineWithColon(summaryFile)
+        self.branches_total = self._getValueFromNextLineWithColon(summaryFile)
+        self.branches_uncovered = self._getValueFromNextLineWithColon(summaryFile)
+        self.branches_alwaysTaken = self._getValueFromNextLineWithoutColon(summaryFile)
+        self.branches_neverTaken = self._getValueFromNextLineWithoutColon(summaryFile)
+        summaryFile.close()
+
+        self.percentage_branchesCovered = 1 - float(self.branches_uncovered) / float(self.branches_total)
+        return
+
+    def _getValueFromNextLineWithColon(self, summaryFile):
+        line = summaryFile.readline()
+        return line.split(':')[1].strip()
+
+    def _getValueFromNextLineWithoutColon(self, summaryFile):
+        line = summaryFile.readline()
+        return line.strip().split(' ')[0]
+
+class reportGen:
+    def __init__(self, p_symbolSetsList, p_targetDir):
+        self.symbolSetsList = p_symbolSetsList
+        self.targetDir = p_targetDir
+        self.partialReportsFiles = list(["index.html", "summary.txt"])
+
+    def _findPartialReports(self):
+        partialReports = {}
+        for symbolSet in self.symbolSetsList:
+            setSummary = summary(path.join(self.targetDir, "test", symbolSet))
+            setSummary.parse()
+            partialReports[symbolSet] = setSummary
+        return partialReports
+
+    def _prepareHeadSection(self):
+        headSection = '''
+        <head>
+        <title>RTEMS coverage report</title>
+        <style type="text/css">
+            progress[value] {
+              -webkit-appearance: none;
+               appearance: none;
+
+              width: 150px;
+              height: 15px;
+            }
+        </style>
+        </head>'''
+        return headSection
+
+    def _prepareIndexContent(self, partialReports):
+        header = "<h1> RTEMS coverage analysis report </h1>"
+        header += "<h3>Coverage reports by symbols sets:</h3>"
+        table = "<table>"
+        table += self._headerRow()
+        for symbolSet in partialReports:
+            table += self._row(symbolSet, partialReports[symbolSet])
+        table += "</table> </br>"
+        timestamp = "Analysis performed on " + datetime.now().ctime()
+        return "<body>\n" + header + table + timestamp + "\n</body>"
+
+    def _row(self, symbolSet, summary):
+        row = "<tr>"
+        row += "<td>" + symbolSet + "</td>"
+        row += " <td>" + self._link(summary.indexFilePath,"Index") + "</td>"
+        row += " <td>" + self._link(summary.summaryFilePath,"Summary") + "</td>"
+        row += " <td>" + summary.bytes_analyzed + "</td>"
+        row += " <td>" + summary.bytes_notExecuted + "</td>"
+        row += " <td>" + summary.ranges_uncovered + "</td>"
+        row += " <td>" + summary.percentage_executed + "%</td>"
+        row += " <td>" + summary.percentage_notExecuted + "%</td>"
+        row += ' <td><progress value="' + summary.percentage_executed + '" max="100"></progress></td>'
+        row += " <td>" + summary.branches_uncovered + "</td>"
+        row += " <td>" + summary.branches_total + "</td>"
+        row += " <td> {:.3%} </td>".format(summary.percentage_branchesCovered)
+        row += ' <td><progress value="{:.3}" max="100"></progress></td>'.format(100*summary.percentage_branchesCovered)
+        row += "</tr>\n"
+        return row
+
+    def _headerRow(self):
+        row = "<tr>"
+        row += "<th> Symbols set name </th>"
+        row += "<th> Index file </th>"
+        row += "<th> Summary file </th>"
+        row += "<th> Bytes analyzed </th>"
+        row += "<th> Bytes not executed </th>"
+        row += "<th> Uncovered ranges </th>"
+        row += "<th> Percentage covered </th>"
+        row += "<th> Percentage uncovered </th>"
+        row += "<th> Instruction coverage </th>"
+        row += "<th> Branches uncovered </th>"
+        row += "<th> Branches total </th>"
+        row += "<th> Branches covered percentage </th>"
+        row += "<th> Branches coverage </th>"
+        row += "</tr>\n"
+        return row
+
+    def _link(self, address, text):
+        return '<a href="' + address + '">' + text + '</a>'
+
+    def _createIndexFile(self, headSection, content):
+        f = open(path.join(self.targetDir, "report.html"),"w")
+        try:
+            f.write(headSection)
+            f.write(content)
+        finally:
+            f.close()
+
+    def generate(self):
+        partialReports = self._findPartialReports()
+        headSection = self._prepareHeadSection()
+        indexContent = self._prepareIndexContent(partialReports)
+        self._createIndexFile(headSection,indexContent)
+#         _createSummaryFile(summaryContent)
+
+class covoar(object):
+    '''
+    Covoar runner
+    '''
+
+    def __init__(self, baseResultDir, configDir, tracesDir):
+        self.baseResultDir = baseResultDir
+        self.configDir = configDir
+        self.tracesDir = tracesDir
+
+    def run(self, setName, covoarConfigFile, symbolFile):
+        covoarResultDir = path.join(self.baseResultDir, setName)
+
+        if (not path.exists(covoarResultDir)):
+            path.mkdir(covoarResultDir)
+        symbolFile = path.join(self.configDir, symbolFile)
+
+        if (not path.exists(symbolFile)):
+            log.stderr("Symbol file: " + symbolFile + " doesn't exists! Covoar can not be run!")
+            log.stderr("Skipping " + setName)
+            return
+
+        command = "covoar -C" + covoarConfigFile + " -s " + symbolFile + " -O " + covoarResultDir + " " + path.join(self.tracesDir, "*.exe")
+        log.notice("Running covoar for " + setName, stdout_only=True)
+        log.notice(command, stdout_only=True)
+        executor = execute.execute(verbose=True, output=output_handler)
+        exit_code = executor.shell(command, cwd=os.getcwd())
+        status = "success"
+        if (exit_code != 0):
+            status = "failure"
+        log.notice("Coverage run for " + setName + " finished " + status)
+        log.notice("-----------------------------------------------")
+
+class coverage_run(object):
+    '''
+    Coverage analysis support for rtems-test
+    '''
+
+    def __init__(self, p_targetDir, p_rtdir):
+        '''
+        Constructor
+        '''
+        self.targetDir = p_targetDir
+        self.testDir = path.join(self.targetDir, "test")
+        self.covoarConfigPath = path.join(p_rtdir, "config")
+        self.rtdir = path.abspath(p_rtdir)
+        self.macros = macros.macros(name=path.join(self.rtdir,'rtems','testing','testing.mc'), rtdir=path.abspath(p_rtdir))
+        self.rtscripts = self.macros.expand(self.macros['_rtscripts'])
+        self.symbolConfigPath = path.join(self.rtscripts, "coverage")
+        self.tracesDir = path.join(self.targetDir, 'coverage')
+        self.executables = None
+        self.symbolSets = []
+
+    def prepareEnvironment(self):
+        if(path.exists(self.tracesDir)):
+            path.removeall(self.tracesDir)
+        path.mkdir(self.tracesDir)
+        log.notice("Coverage environment prepared", stdout_only = True)
+
+
+    def run(self):
+        if self.executables == None:
+            log.stderr("ERROR: Executables for coverage analysis unspecified!")
+            raise Exception('Executable for coverage analysis unspecified')
+
+        covoarConfigFile = path.join(self.symbolConfigPath, 'config')
+        if(not path.exists(covoarConfigFile)):
+            log.stderr("Covoar configuration file: " + path.abspath(covoarConfigFile) + " doesn't exists! Covoar can not be run! ");
+            return -1
+
+        self._linkExecutables()
+
+        symbolSetsFile = open(path.join(self.symbolConfigPath,"symbol_sets"), 'r');
+        for symbolSet in symbolSetsFile:
+            setName = symbolSet.split()[0]
+            symbolFile = symbolSet.split()[1]
+            self.symbolSets.append(setName)
+
+            covoar_run = covoar(self.testDir, self.symbolConfigPath, self.tracesDir)
+            covoar_run.run(setName, covoarConfigFile, symbolFile)
+
+        self._generateReports();
+        self._cleanup();
+        self._summarize();
+
+    def _linkExecutables(self):
+        log.notice("Linking executables to " + self.tracesDir)
+
+        for exe in self.executables:
+            dst = path.join(self.tracesDir, path.basename(exe))
+            log.notice("Making symlink from " + exe + " to " + dst)
+            os.link(exe, dst)
+        log.notice("Symlinks made")
+
+    def _generateReports(self):
+        log.notice("Generating reports")
+        report = reportGen(self.symbolSets, self.targetDir)
+        report.generate()
+
+    def _cleanup(self):
+        log.notice("Cleaning workspace up")
+        path.removeall(self.tracesDir)
+
+    def _summarize(self):
+        log.notice("Coverage analysis finished. You can find results in " + self.targetDir)
+
+def output_handler(text):
+    log.notice(text, stdout_only = True)
+
+if __name__ == "__main__":
+    c = coverage_run("/home/rtems/coverage/test_new","/home/rtems/development/rtems/src/rtems-tools/tester")
+    c.prepareEnvironment()
+    c.executables = ["/home/rtems/development/rtems/src/b-pc386/i386-rtems4.11/c/pc386/testsuites/samples/hello/hello.exe"]
+    c.run()
diff --git a/tester/rt/test.py b/tester/rt/test.py
index b0981b4..2be2dd0 100644
--- a/tester/rt/test.py
+++ b/tester/rt/test.py
@@ -64,6 +64,7 @@ class test(object):
         if not path.isfile(executable):
             raise error.general('cannot find executable: %s' % (executable))
         self.opts.defaults['test_executable'] = executable
+        self.opts.defaults['test_executable_name'] = path.basename(executable)
         if rtems_tools:
             rtems_tools_bin = path.join(rtems_tools, 'bin')
             if not path.isdir(rtems_tools_bin):
@@ -197,7 +198,7 @@ def run(command_path = None):
                     '--debug-trace': 'Debug trace based on specific flags',
                     '--filter':      'Glob that executables must match to run (default: ' +
                               default_exefilter + ')',
-                    '--stacktrace':  'Dump a stack trace on a user termination (^C)' }
+                    '--stacktrace':  'Dump a stack trace on a user termination (^C)'}
         opts = options.load(sys.argv,
                             optargs = optargs,
                             command_path = command_path)
@@ -220,6 +221,18 @@ def run(command_path = None):
         rtems_tools = opts.find_arg('--rtems-tools')
         if rtems_tools:
             rtems_tools = rtems_tools[1]
+#
+        coverage_enabled = opts.opts['coverage']
+        if coverage_enabled:
+            import coverage
+            from rtemstoolkit import check
+            log.notice("Coverage analysis requested")
+            opts.defaults.load('%%{_configdir}/coverage.mc')
+            if not check.check_exe('__covoar', opts.defaults['__covoar']):
+                raise error.general("Covoar not found!")
+            coverage = coverage.coverage_run(opts.defaults['_cwd'], opts.defaults['_rtdir'])
+            coverage.prepareEnvironment();
+
         bsp = opts.find_arg('--rtems-bsp')
         if bsp is None:
             raise error.general('no RTEMS BSP provided')
@@ -298,6 +311,11 @@ def run(command_path = None):
         end_time = datetime.datetime.now()
         log.notice('Average test time: %s' % (str((end_time - start_time) / total)))
         log.notice('Testing time     : %s' % (str(end_time - start_time)))
+
+        if coverage_enabled:
+            coverage.executables = executables
+            coverage.run()
+
     except error.general, gerr:
         print gerr
         sys.exit(1)
diff --git a/tester/rtems/testing/bsps/pc386.mc b/tester/rtems/testing/bsps/pc386.mc
new file mode 100644
index 0000000..3a35ebd
--- /dev/null
+++ b/tester/rtems/testing/bsps/pc386.mc
@@ -0,0 +1,57 @@
+#
+# RTEMS Tools Project (http://www.rtems.org/)
+# Copyright 2010-2014 Chris Johns (chr...@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.
+#
+
+#
+# All paths in defaults must be Unix format. Do not store any Windows format
+# paths in the defaults.
+#
+# Every entry must describe the type of checking a host must pass.
+#
+# Records:
+#  key: type, attribute, value
+#   type     : none, dir, exe, triplet
+#   attribute: none, required, optional
+#   value    : 'single line', '''multi line'''
+#
+
+#
+# The i386/pc386 QEMU BSP
+#
+
+hda:	none,	dir,	'/home/rtems/qemu/hdtest/rtems-boot.img'
+
+[global]
+bsp:                      none,    none,     'pc386'
+coverage_supported:	  none,	   none,	'1'
+
+[pc386]
+pc386:      none,    none,  '%{_rtscripts}/qemu.cfg'
+pc386_arch: none,    none,  'i386'
+pc386_opts: none,    none,  '-m 128 -boot b -hda %{hda} %{qemu_opts_base} -append "--console=com1;boot;"'
diff --git a/tester/rtems/testing/coverage.mc b/tester/rtems/testing/coverage.mc
new file mode 100644
index 0000000..a336cc0
--- /dev/null
+++ b/tester/rtems/testing/coverage.mc
@@ -0,0 +1,48 @@
+#
+# RTEMS Tools Project (http://www.rtems.org/)
+# Copyright 2010-2014 Chris Johns (chr...@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.
+#
+
+#
+# All paths in defaults must be Unix format. Do not store any Windows format
+# paths in the defaults.
+#
+# Every entry must describe the type of checking a host must pass.
+#
+# Records:
+#  key: type, attribute, value
+#   type     : none, dir, exe, triplet
+#   attribute: none, required, optional
+#   value    : 'single line', '''multi line'''
+#
+
+#
+# Global defaults
+#
+[global]
+__covoar:			exe,	required, 'covoar'
diff --git a/tester/rtems/testing/gdb.cfg b/tester/rtems/testing/gdb.cfg
index b680dba..5ca344a 100644
--- a/tester/rtems/testing/gdb.cfg
+++ b/tester/rtems/testing/gdb.cfg
@@ -54,6 +54,13 @@
 %define gdb_cmd %{rtems_tools}/%{bsp_arch}-rtems%{rtems_version}-gdb
 
 #
+# Coverage analysis
+#
+%if %{_coverage}
+ %error "Coverage analysis unsupported"
+%endif
+
+#
 # GDB, pass the GDB command, the text executable and the macro label
 # for the script.
 #
diff --git a/tester/rtems/testing/qemu.cfg b/tester/rtems/testing/qemu.cfg
index a3310bc..2254aef 100644
--- a/tester/rtems/testing/qemu.cfg
+++ b/tester/rtems/testing/qemu.cfg
@@ -51,7 +51,7 @@
 #
 # Qemu common option patterns.
 #
-%define qemu_opts_base   -no-reboot -monitor none -serial stdio -nographic
+%define qemu_opts_base   -no-reboot -monitor null -serial stdio -nographic
 %define qemu_opts_no_net -net none
 #
 # Qemu executable
@@ -60,6 +60,19 @@
 %define qemu_opts %{bsp_opts}
 
 #
+# Coverage analysis
+#
+%if %{_coverage}
+
+ %if %{coverage_supported}
+   %define coverage_arg -exec-trace coverage/%{test_executable_name}.cov
+ %else
+  %error "Coverage analysis unsupported for %{bsp}"
+ %endif
+
+%endif
+
+#
 # Executable
 #
-%execute %{qemu_cmd} %{qemu_opts} -kernel %{test_executable}
+%execute %{qemu_cmd} %{qemu_opts} -kernel %{test_executable} %{coverage_arg}
-- 
1.9.1

From 58e79f9d2a3216c4799ac9b8dd4ad34b1ddf5e41 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Krzysztof=20Mi=C4=99sowicz?= <krzysztof.miesow...@gmail.com>
Date: Wed, 27 Aug 2014 13:18:14 +0200
Subject: [PATCH 02/12] Coverage enabled check fix

---
 tester/rt/test.py | 25 +++++++++++++------------
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/tester/rt/test.py b/tester/rt/test.py
index 2be2dd0..a0f98de 100644
--- a/tester/rt/test.py
+++ b/tester/rt/test.py
@@ -221,18 +221,6 @@ def run(command_path = None):
         rtems_tools = opts.find_arg('--rtems-tools')
         if rtems_tools:
             rtems_tools = rtems_tools[1]
-#
-        coverage_enabled = opts.opts['coverage']
-        if coverage_enabled:
-            import coverage
-            from rtemstoolkit import check
-            log.notice("Coverage analysis requested")
-            opts.defaults.load('%%{_configdir}/coverage.mc')
-            if not check.check_exe('__covoar', opts.defaults['__covoar']):
-                raise error.general("Covoar not found!")
-            coverage = coverage.coverage_run(opts.defaults['_cwd'], opts.defaults['_rtdir'])
-            coverage.prepareEnvironment();
-
         bsp = opts.find_arg('--rtems-bsp')
         if bsp is None:
             raise error.general('no RTEMS BSP provided')
@@ -247,6 +235,18 @@ def run(command_path = None):
         if not bsp_script:
             raise error.general('BSP script not found: %s' % (bsp))
         bsp_config = opts.defaults.expand(opts.defaults[bsp])
+
+        coverage_enabled = opts.coverage()
+        if coverage_enabled:
+            import coverage
+            from rtemstoolkit import check
+            log.notice("Coverage analysis requested")
+            opts.defaults.load('%%{_configdir}/coverage.mc')
+            if not check.check_exe('__covoar', opts.defaults['__covoar']):
+                raise error.general("Covoar not found!")
+            coverage = coverage.coverage_run(opts.defaults)
+            coverage.prepareEnvironment();
+
         report_mode = opts.find_arg('--report-mode')
         if report_mode:
             if report_mode[1] != 'failures' and \
@@ -313,6 +313,7 @@ def run(command_path = None):
         log.notice('Testing time     : %s' % (str(end_time - start_time)))
 
         if coverage_enabled:
+            coverage.config_map = opts.defaults.macros['coverage']
             coverage.executables = executables
             coverage.run()
 
-- 
1.9.1

From 48496cf896034cb404ad6edb53c264aa489803bb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Krzysztof=20Mi=C4=99sowicz?= <krzysztof.miesow...@gmail.com>
Date: Wed, 27 Aug 2014 13:20:15 +0200
Subject: [PATCH 03/12] Files moved from rtems-testing/rtems-coverage

---
 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/style.css            | 197 +++++++++++++++++++++
 4 files changed, 307 insertions(+)
 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/style.css

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 <j...@gaisler.com>
+Date: Wed, 3 Jun 2009 14:57:48 -0500
+To: Joel Sherrill <joel.sherr...@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/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
-- 
1.9.1

From 94cc111ad1c61982c8333d743fb940b7c1eb242c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Krzysztof=20Mi=C4=99sowicz?= <krzysztof.miesow...@gmail.com>
Date: Wed, 27 Aug 2014 13:21:21 +0200
Subject: [PATCH 04/12] Qemu rtems-boot.img binary for pc386 booting added

---
 tester/rtems/testing/coverage/rtems-boot.img | Bin 0 -> 5242880 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 tester/rtems/testing/coverage/rtems-boot.img

diff --git a/tester/rtems/testing/coverage/rtems-boot.img b/tester/rtems/testing/coverage/rtems-boot.img
new file mode 100644
index 0000000000000000000000000000000000000000..3995316735a53542acdf0d92e0b725fe296c0b49
GIT binary patch
literal 5242880
zcmeFtfdBvi0Dz$VsTV1P3IhfV7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjxE(qc00000802p~h`oi7
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
S0|pEjFkrxd0RsjMoPhuYumAx7

literal 0
HcmV?d00001

-- 
1.9.1

From 261d1c2bc502754d35bd4153ee3157f537816f69 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Krzysztof=20Mi=C4=99sowicz?= <krzysztof.miesow...@gmail.com>
Date: Wed, 27 Aug 2014 13:26:18 +0200
Subject: [PATCH 05/12] Symbol generation added to covoar

---
 tester/covoar/SymbolSet.cpp       | 111 ++++++++++++++++++++++++++++++++++++++
 tester/covoar/SymbolSet.h         |  51 ++++++++++++++++++
 tester/covoar/SymbolSetReader.cpp |  82 ++++++++++++++++++++++++++++
 tester/covoar/SymbolSetReader.h   |  34 ++++++++++++
 tester/covoar/covoar.cc           |  32 +++++++++--
 tester/covoar/wscript             |  25 +++++++--
 6 files changed, 327 insertions(+), 8 deletions(-)
 create mode 100644 tester/covoar/SymbolSet.cpp
 create mode 100644 tester/covoar/SymbolSet.h
 create mode 100644 tester/covoar/SymbolSetReader.cpp
 create mode 100644 tester/covoar/SymbolSetReader.h

diff --git a/tester/covoar/SymbolSet.cpp b/tester/covoar/SymbolSet.cpp
new file mode 100644
index 0000000..c8f83e5
--- /dev/null
+++ b/tester/covoar/SymbolSet.cpp
@@ -0,0 +1,111 @@
+/*
+ * SymbolSet.cpp
+ *
+ *  Created on: Aug 5, 2014
+ *      Author: Krzysztof Mięsowicz <krzysztof.miesow...@gmail.com>
+ */
+
+#include "SymbolSet.h"
+#include "rld-process.h"
+#include "rld.h"
+#include <iostream>
+#include <fstream>
+#include <cstdio>
+
+namespace Symbols {
+
+SymbolSet::SymbolSet() {
+	// TODO Auto-generated constructor stub
+
+}
+
+SymbolSet::~SymbolSet() {
+	// TODO Auto-generated destructor stub
+}
+
+std::string SymbolSet::parseNmOutputLine(std::string line) {
+	std::cout << "Read: " << std::endl;
+	std::cout << line << std::endl;
+	std::cout << "--------" << std::endl;
+	std::string symbol = "";
+	if (line.find("FUNC|") != std::string::npos) {
+		std::cout << "Function:" << std::endl;
+		symbol = line.substr(0, line.find('|'));
+		std::cout << symbol << std::endl;
+	} else {
+		std::cout << "Not a function" << std::endl;
+	}
+	return symbol;
+}
+
+std::string SymbolSet::getLibname(std::string libPath) {
+	std::string libname = "", base = "", temp;
+	size_t pos = libPath.find_last_of('/');
+	if (pos != std::string::npos) {
+		temp = libPath.substr(0, pos);
+		libname = libPath.substr(pos + 1);
+	}
+	pos = temp.find_last_of('/');
+	if (pos != std::string::npos) {
+		base = temp.substr(pos + 1);
+	}
+
+	return base + "/" + libname;
+}
+
+void SymbolSet::parseNmOutput(std::ifstream& nm_out, const std::string& lib) {
+	std::string line, symbol;
+	while (getline(nm_out, line)) {
+		symbol = parseNmOutputLine(line);
+		if (symbol.length() > 0) {
+			symbols.push_back(symbol + " " + getLibname(lib));
+		}
+	}
+}
+
+void SymbolSet::generateSymbolFile(std::string filePath, std::string target) {
+	std::cout << __FUNCTION__ << "(): arguments: " << filePath << ", " << target << std::endl;
+	std::string nm_output = "nm.out";
+	std::string nm_error = "nm.err";
+	std::string libFiles;
+
+	for (std::string lib : libraries) {
+		try {
+			auto status = rld::process::execute(target + "-nm",
+					std::vector<std::string> { target + "-nm", "--format=sysv",
+							lib }, nm_output, nm_error);
+			if (status.type != rld::process::status::normal
+					or
+					status.code != 0) {
+				std::cout << "ERROR: nm returned " << status.code << std::endl;
+				std::cout << "For details see " << nm_error << " file." << std::endl;
+				std::remove(nm_output.c_str());
+				return;
+			}
+
+		} catch (rld::error& err) {
+			std::cout << "Error while running nm for " + lib << std::endl;
+			std::cout << err.what << " in " << err.where << std::endl;
+			return;
+		}
+
+		std::ifstream nm_out(nm_output);
+		try {
+			parseNmOutput(nm_out, lib);
+		} catch(std::exception& e) {
+			std::cout << "ERROR while parsing nm output: " << e.what() << std::endl;
+		}
+		nm_out.close();
+	}
+
+	std::remove(nm_output.c_str());
+	std::remove(nm_error.c_str());
+
+	std::ofstream outputFile(filePath);
+	for (std::string symbol : symbols) {
+		outputFile << symbol << std::endl;
+	}
+	outputFile.close();
+}
+
+} /* namespace Symbols */
diff --git a/tester/covoar/SymbolSet.h b/tester/covoar/SymbolSet.h
new file mode 100644
index 0000000..54e925d
--- /dev/null
+++ b/tester/covoar/SymbolSet.h
@@ -0,0 +1,51 @@
+/*
+ * SymbolSet.h
+ *
+ *  Created on: Aug 5, 2014
+ *      Author: Krzysztof Mięsowicz <krzysztof.miesow...@gmail.com>
+ */
+
+#ifndef SYMBOLSET_H_
+#define SYMBOLSET_H_
+
+#include <string>
+#include <vector>
+
+namespace Symbols {
+
+class SymbolSet {
+public:
+	SymbolSet();
+	virtual ~SymbolSet();
+
+	const std::string getName() const {
+		return name;
+	}
+
+	void setName(const std::string& name) {
+		this->name = name;
+	}
+
+	const std::vector<std::string> getLibraries() const {
+		return libraries;
+	}
+
+	void addLibrary(std::string libraryPath) {
+		libraries.push_back(libraryPath);
+	}
+
+	void generateSymbolFile(std::string filePath, std::string target);
+
+private:
+	std::string name;
+	std::vector<std::string> libraries;
+	std::vector<std::string> symbols;
+
+	std::string parseNmOutputLine(std::string line);
+	std::string getLibname(std::string libPath);
+	void parseNmOutput(std::ifstream& nm_out, const std::string& lib);
+};
+
+} /* namespace Symbols */
+
+#endif /* SYMBOLSET_H_ */
diff --git a/tester/covoar/SymbolSetReader.cpp b/tester/covoar/SymbolSetReader.cpp
new file mode 100644
index 0000000..886e256
--- /dev/null
+++ b/tester/covoar/SymbolSetReader.cpp
@@ -0,0 +1,82 @@
+/*
+ * SymbolSetReader.cpp
+ *
+ *  Created on: Aug 5, 2014
+ *      Author: Krzysztof Mięsowicz <krzysztof.miesow...@gmail.com>
+ */
+
+#include "SymbolSetReader.h"
+#include "iostream"
+#include "fstream"
+
+namespace Symbols {
+
+SymbolSetReader::SymbolSetReader() {
+	// TODO Auto-generated constructor stub
+
+}
+
+SymbolSetReader::~SymbolSetReader() {
+	// TODO Auto-generated destructor stub
+}
+
+std::vector<SymbolSet> SymbolSetReader::readSetFile(string filepath) {
+	std::vector<SymbolSet> setList { };
+	ifstream file(filepath);
+	string line;
+	while (getline(file, line)) {
+		if (line.find("symbolset:") != std::string::npos) {
+			setList.emplace_back();
+		} else if (line.length() > 0) {
+
+			auto pair = parseLine(line);
+
+			if(pair.first == "name") {
+				if (setList.empty()) {
+					setList.emplace_back();
+				}
+				setList.rbegin()->setName(pair.second);
+				continue;
+			}
+			if(pair.first == "lib") {
+				setList.rbegin()->addLibrary(pair.second);
+				continue;
+			}
+
+			std::cout << "Invalid entry in configuration file : " << line << endl;
+			break;
+		}
+	}
+	file.close();
+	return setList;
+}
+
+std::pair<string, string> SymbolSetReader::parseLine(string line) {
+	size_t delimeterPosition = line.find('=');
+
+	if (delimeterPosition != std::string::npos) {
+		string key = line.substr(0, delimeterPosition);
+		string value = line.substr(delimeterPosition + 1);
+		return {trim(key), trim(value)};
+	}
+
+	return {"",""};
+}
+
+string& SymbolSetReader::trim(string& str) {
+	// trim trailing spaces
+	size_t endpos = str.find_last_not_of(" \t\n\r");
+	if (string::npos != endpos) {
+		str = str.substr(0, endpos + 1);
+	}
+
+	// trim leading spaces
+	size_t startpos = str.find_first_not_of(" \t\n\r");
+	if (string::npos != startpos) {
+		str = str.substr(startpos);
+	}
+
+	return str;
+}
+
+} /* namespace Symbols */
diff --git a/tester/covoar/SymbolSetReader.h b/tester/covoar/SymbolSetReader.h
new file mode 100644
index 0000000..24e83cf
--- /dev/null
+++ b/tester/covoar/SymbolSetReader.h
@@ -0,0 +1,34 @@
+/*
+ * SymbolSetReader.h
+ *
+ *  Created on: Aug 5, 2014
+ *      Author: Krzysztof Mięsowicz <krzysztof.miesow...@gmail.com>
+ */
+
+#ifndef SYMBOLSETREADER_H_
+#define SYMBOLSETREADER_H_
+
+#include <string>
+#include <vector>
+#include <utility>
+#include "SymbolSet.h"
+
+using namespace std;
+
+namespace Symbols {
+
+class SymbolSetReader {
+public:
+	SymbolSetReader();
+	virtual ~SymbolSetReader();
+
+	vector<SymbolSet> readSetFile(string filepath);
+protected:
+	pair<string, string> parseLine(string line);
+private:
+	string& trim(string& str);
+};
+
+} /* namespace Symbols */
+
+#endif /* SYMBOLSETREADER_H_ */
diff --git a/tester/covoar/covoar.cc b/tester/covoar/covoar.cc
index 78954fd..868f40d 100644
--- a/tester/covoar/covoar.cc
+++ b/tester/covoar/covoar.cc
@@ -23,6 +23,9 @@
 #include "TargetFactory.h"
 #include "GcovData.h"
 
+#include "SymbolSetReader.h"
+#include "SymbolSet.h"
+
 /*
  *  Variables to control general behavior
  */
@@ -38,6 +41,7 @@ std::list<Coverage::ExecutableInfo*> executablesToAnalyze;
 const char*                          explanations = NULL;
 char*                                progname;
 const char*                          symbolsFile = NULL;
+const char*							 symbolSetFile = NULL;
 const char*		             gcnosFileName = NULL;
 char				     gcnoFileName[FILE_NAME_LENGTH];
 char				     gcdaFileName[FILE_NAME_LENGTH];
@@ -64,6 +68,7 @@ void usage()
            "(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        - name of file specifying symbol set of interest\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"
@@ -89,6 +94,7 @@ Configuration::Options_t Options[] = {
   { "explanations",         NULL },
   { "format",               NULL },
   { "symbolsFile",          NULL },
+  { "symbolSetFile",		NULL },
   { "outputDirectory",      NULL },
   { "executableExtension",  NULL },
   { "coverageExtension",    NULL },
@@ -166,7 +172,7 @@ int main(
   //
   progname = argv[0];
 
-  while ((opt = getopt(argc, argv, "C:1:L:e:c:g:E:f:s:T:O:p:v")) != -1) {
+  while ((opt = getopt(argc, argv, "C:1:L:e:c:g:E:f:s:S:T:O:p:v")) != -1) {
     switch (opt) {
       case 'C': CoverageConfiguration->processFile( optarg ); break;
       case '1': singleExecutable      = optarg; break;
@@ -177,6 +183,7 @@ int main(
       case 'E': explanations          = optarg; break;
       case 'f': format                = optarg; break;
       case 's': symbolsFile           = optarg; break;
+      case 'S': symbolSetFile		  = optarg; break;
       case 'T': target                = optarg; break;
       case 'O': outputDirectory       = optarg; break;
       case 'v': Verbose               = true;   break;
@@ -337,8 +344,8 @@ int main(
   }
 
   // Validate that we have a symbols of interest file.
-  if (!symbolsFile) {
-    fprintf( stderr, "ERROR: symbols of interest file not specified\n" );
+  if (!symbolsFile && !symbolSetFile) {
+    fprintf( stderr, "ERROR: neither symbols of interest file nor symbol set file not specified\n" );
     usage();
     exit(-1);
   }
@@ -352,7 +359,24 @@ int main(
 
   // Create the set of desired symbols.
   SymbolsToAnalyze = new Coverage::DesiredSymbols();
-  SymbolsToAnalyze->load( symbolsFile );
+
+  //Load symbols from specified symbolsFile
+  if(symbolsFile) {
+	  SymbolsToAnalyze->load( symbolsFile );
+  }
+
+  //Read symbol configuration file and load needed symbols
+  if(symbolSetFile) {
+	  cout << "Reading symbols sets configuration for symbol set file: " << symbolSetFile << endl;
+	  Symbols::SymbolSetReader ssr;
+	  std::vector<Symbols::SymbolSet> symbolSets = ssr.readSetFile(symbolSetFile);
+
+	  Symbols::SymbolSet& set = symbolSets[0];
+	  cout << "Generating symbol file for " << set.getName() << endl;
+	  set.generateSymbolFile(set.getName() + ".syms", target);
+	  SymbolsToAnalyze->load((set.getName() + ".syms").c_str());
+  }
+
   if (Verbose)
     fprintf(
       stderr,
diff --git a/tester/covoar/wscript b/tester/covoar/wscript
index 88add6e..5b72c34 100644
--- a/tester/covoar/wscript
+++ b/tester/covoar/wscript
@@ -46,6 +46,16 @@ APPNAME='covoar'
 top = '.'
 out = 'build'
 
+#
+# Paths to rtl-host
+#
+rtl_host_build_dir = "./../../rtl-host/build-linux2"
+rtl_host_dir = "./../../rtl-host"
+rtl_includes = ['../../rtl-host',
+				'../../rtl-host/elftoolchain/common',
+				'../../rtl-host/elftoolchain/libelf',
+				'../../rtl-host/libiberty']
+
 def options(opt):
     opt.load('compiler_cxx')
 
@@ -54,8 +64,11 @@ def configure(conf):
     conf.check_cc(function_name='open64', header_name="stdlib.h", mandatory = False)
     conf.check_cc(function_name='stat64', header_name="stdlib.h", mandatory = False)
     conf.write_config_header('covoar-config.h')
+    conf.env.STLIBPATH_RLD = conf.path.abspath() + rtl_host_build_dir
+    conf.env.STLIB_RLD = ['rld','iberty','elf']
 
 def build(bld):
+
     bld.stlib(target = 'ccovoar',
               source = ['app_common.cc',
                         'ConfigFile.cc',
@@ -89,9 +102,13 @@ def build(bld):
                         'Target_lm32.cc',
                         'Target_m68k.cc',
                         'Target_powerpc.cc',
-                        'Target_sparc.cc'],
+                        'Target_sparc.cc',
+                        'SymbolSet.cpp',
+                        'SymbolSetReader.cpp'],
               cflags = ['-O2', '-g'],
-              includes = ['.'])
+              cxxflags = ['-std=c++11', '-O2', '-g'],
+              includes = ['.',
+              './symbolGen'] + rtl_includes)
 
     bld.program(target = 'trace-converter',
                 source = ['TraceConverter.cc',
@@ -106,12 +123,12 @@ def build(bld):
 
     bld.program(target = 'covoar',
                 source = ['covoar.cc'],
-                use = 'ccovoar',
+                use = ['ccovoar','RLD'],
                 cflags = ['-O2', '-g'],
                 includes = ['.'])
 
     bld.program(target = 'covoar',
                 source = ['covoar.cc'],
-                use = 'ccovoar',
+                use = ['ccovoar','RLD'],
                 cflags = ['-O2', '-g'],
                 includes = ['.'])
-- 
1.9.1

From 27ce4052970cf86b97f7bd1d266be02324ee82d1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Krzysztof=20Mi=C4=99sowicz?= <krzysztof.miesow...@gmail.com>
Date: Wed, 27 Aug 2014 14:09:08 +0200
Subject: [PATCH 06/12] Creating covoar config file from coverage module,
 interface with symbol generation in covoar, covoar exit status check fix

---
 tester/rt/coverage.py              | 146 +++++++++++++++++++++++++++++++------
 tester/rtems/testing/bsps/pc386.mc |  11 ++-
 2 files changed, 132 insertions(+), 25 deletions(-)

diff --git a/tester/rt/coverage.py b/tester/rt/coverage.py
index e170607..cb5ea33 100644
--- a/tester/rt/coverage.py
+++ b/tester/rt/coverage.py
@@ -7,6 +7,7 @@ from rtemstoolkit import path
 from rtemstoolkit import log
 from rtemstoolkit import execute
 from rtemstoolkit import macros
+import shutil
 import os
 from datetime import datetime
 
@@ -148,36 +149,114 @@ class reportGen:
         self._createIndexFile(headSection,indexContent)
 #         _createSummaryFile(summaryContent)
 
+class symbolsConfiguration(object):
+    '''
+    Manages symbols configuration - reading from symbol file
+    '''
+    def __init__(self):
+        self.symbolSets = []
+
+    def _log_invalid_format(self):
+        log.stderr("Invalid symbol configuration file")
+        log.stderr(''' Configuration file format:
+                symbolset:
+                   name=SYMBOLSET_NAME
+                   lib=PATH_TO_LIBRARY_1
+                   lib=PATH_TO_LIBRARY_2
+                symbolset:
+                    name=SYMBOLSET_NAME_N
+                    lib=PATH_TO_LIBRARY        ''')
+
+    def load(self, symbolSetConfigFile):
+        scf = open(symbolSetConfigFile, 'r')
+        for line in scf:
+            try:
+                if line.strip().startswith("symbolset"):
+                    self.symbolSets.append(symbolSet("",[]))
+                else:
+                    splitted = line.split('=')
+                    if(len(splitted) == 2):
+                        key = splitted[0].strip()
+                        value = splitted[1].strip()
+                        if key == 'name':
+                            self.symbolSets[-1].name = value
+                        elif key == 'lib':
+                            self.symbolSets[-1].libs.append(value)
+                        else:
+                            log.stderr("Invalid key : " + key + " in symbol set configuration file " + symbolSetConfigFile)
+                    else:
+                        self._log_invalid_format()
+            except:
+                self._log_invalid_format()
+        scf.close()
+
+    def save(self, path):
+        scf = open(path, 'w')
+        for sset in self.symbolSets:
+            sset.writeSetFile(path)
+        scf.close()
+
+class symbolSet(object):
+    def __init__(self, name, libs):
+        self.name = name
+        self.libs = libs
+
+    def isValid(self):
+        if len(self.name) == 0:
+            log.stderr("Invalid symbol set. Symbol set must have name! ")
+            return False
+        if len(self.libs) == 0:
+            log.stderr("Invalid symbol set. Symbol set must have specified libraries!")
+            return False
+        for lib in self.libs:
+            if not path.exists(lib):
+                log.stderr("Invalid library path: " + lib)
+                return False
+        return True
+
+    def writeSetFile(self, path):
+        f = open(path, 'w')
+        f.write("symbolset:\n")
+        f.write("\t name=" + self.name + '\n')
+        for lib in self.libs:
+            f.write("\t lib=" + lib + '\n')
+        f.close()
+
 class covoar(object):
     '''
     Covoar runner
     '''
 
-    def __init__(self, baseResultDir, configDir, tracesDir):
+    def __init__(self, baseResultDir, configDir, tracesDir, covoarSrcDir):
         self.baseResultDir = baseResultDir
         self.configDir = configDir
         self.tracesDir = tracesDir
+        self.covoarSrcDir = covoarSrcDir
 
     def run(self, setName, covoarConfigFile, symbolFile):
         covoarResultDir = path.join(self.baseResultDir, setName)
 
         if (not path.exists(covoarResultDir)):
             path.mkdir(covoarResultDir)
-        symbolFile = path.join(self.configDir, symbolFile)
 
         if (not path.exists(symbolFile)):
-            log.stderr("Symbol file: " + symbolFile + " doesn't exists! Covoar can not be run!")
+            log.stderr("Symbol set file: " + symbolFile + " doesn't exists! Covoar can not be run!")
             log.stderr("Skipping " + setName)
             return
 
-        command = "covoar -C" + covoarConfigFile + " -s " + symbolFile + " -O " + covoarResultDir + " " + path.join(self.tracesDir, "*.exe")
+        command = "covoar -C" + covoarConfigFile + " -S " + symbolFile + " -O " + covoarResultDir + " " + path.join(self.tracesDir, "*.exe")
         log.notice("Running covoar for " + setName, stdout_only=True)
         log.notice(command, stdout_only=True)
         executor = execute.execute(verbose=True, output=output_handler)
         exit_code = executor.shell(command, cwd=os.getcwd())
+         
+        shutil.copy2(path.join(self.covoarSrcDir, 'table.js'), path.join(covoarResultDir, 'table.js'))
+        shutil.copy2(path.join(self.covoarSrcDir, 'covoar.css'), path.join(covoarResultDir, 'covoar.css'))
+         
+        log.notice("Coverage run for " + setName + " finished ")
         status = "success"
-        if (exit_code != 0):
-            status = "failure"
+        if (exit_code[0] != 0):
+            status = "failure. Error code: " + str(exit_code[0])
         log.notice("Coverage run for " + setName + " finished " + status)
         log.notice("-----------------------------------------------")
 
@@ -186,18 +265,19 @@ class coverage_run(object):
     Coverage analysis support for rtems-test
     '''
 
-    def __init__(self, p_targetDir, p_rtdir):
+    def __init__(self, p_macros):
         '''
         Constructor
         '''
-        self.targetDir = p_targetDir
+        self.macros = p_macros
+        self.targetDir = self.macros['_cwd']
         self.testDir = path.join(self.targetDir, "test")
-        self.covoarConfigPath = path.join(p_rtdir, "config")
-        self.rtdir = path.abspath(p_rtdir)
-        self.macros = macros.macros(name=path.join(self.rtdir,'rtems','testing','testing.mc'), rtdir=path.abspath(p_rtdir))
+        self.rtdir = path.abspath(self.macros['_rtdir'])
         self.rtscripts = self.macros.expand(self.macros['_rtscripts'])
-        self.symbolConfigPath = path.join(self.rtscripts, "coverage")
+        self.coverageConfigPath = path.join(self.rtscripts, "coverage")
+        self.symbolConfigPath = path.join(self.coverageConfigPath, "symbolSets.config")
         self.tracesDir = path.join(self.targetDir, 'coverage')
+        self.config_map = self.macros.macros['coverage']
         self.executables = None
         self.symbolSets = []
 
@@ -207,27 +287,46 @@ class coverage_run(object):
         path.mkdir(self.tracesDir)
         log.notice("Coverage environment prepared", stdout_only = True)
 
+    def writeCovoarConfig(self, covoarConfigFile):
+        ccf = open(covoarConfigFile, 'w')
+        ccf.write("format = " + self.config_map['format'][2] + '\n')
+        ccf.write("target = " + self.config_map['target'][2] + '\n')
+        ccf.write("explanations = " + self.macros.expand(self.config_map['explanations'][2]) + '\n')
+        ccf.write("coverageExtension = " + self.config_map['coverageextension'][2] + '\n')
+        ccf.write("gcnosFile = " + self.macros.expand(self.config_map['gcnosfile'][2]) + '\n')
+        ccf.write("executableExtension = " + self.config_map['executableextension'][2] + '\n')
+        ccf.write("projectName = " + self.config_map['projectname'][2] + '\n')
+        ccf.close()
 
     def run(self):
         if self.executables == None:
             log.stderr("ERROR: Executables for coverage analysis unspecified!")
             raise Exception('Executable for coverage analysis unspecified')
+        if self.config_map == None:
+            log.stderr("ERROR: Configuration map for coverage analysis unspecified!")
+            raise Exception("ERROR: Configuration map for coverage analysis unspecified!")
 
-        covoarConfigFile = path.join(self.symbolConfigPath, 'config')
+        covoarConfigFile = path.join(self.tracesDir, 'config')
+        self.writeCovoarConfig(covoarConfigFile)
         if(not path.exists(covoarConfigFile)):
             log.stderr("Covoar configuration file: " + path.abspath(covoarConfigFile) + " doesn't exists! Covoar can not be run! ");
             return -1
 
         self._linkExecutables()
 
-        symbolSetsFile = open(path.join(self.symbolConfigPath,"symbol_sets"), 'r');
-        for symbolSet in symbolSetsFile:
-            setName = symbolSet.split()[0]
-            symbolFile = symbolSet.split()[1]
-            self.symbolSets.append(setName)
+        symbolConfig = symbolsConfiguration()
+        symbolConfig.load(self.symbolConfigPath)
+
+        for sset in symbolConfig.symbolSets:
+            if sset.isValid():
+                symbolSetFile = path.join(self.tracesDir, sset.name + ".symcfg")
+                sset.writeSetFile(symbolSetFile)
+                self.symbolSets.append(sset.name)
 
-            covoar_run = covoar(self.testDir, self.symbolConfigPath, self.tracesDir)
-            covoar_run.run(setName, covoarConfigFile, symbolFile)
+                covoar_run = covoar(self.testDir, self.symbolConfigPath, self.tracesDir, path.join(self.rtdir, 'covoar'))
+                covoar_run.run(sset.name, covoarConfigFile, symbolSetFile)
+            else:
+                log.stderr("Invalid symbol set " + sset.name + ". Skipping covoar run.")
 
         self._generateReports();
         self._cleanup();
@@ -238,7 +337,6 @@ class coverage_run(object):
 
         for exe in self.executables:
             dst = path.join(self.tracesDir, path.basename(exe))
-            log.notice("Making symlink from " + exe + " to " + dst)
             os.link(exe, dst)
         log.notice("Symlinks made")
 
@@ -255,10 +353,10 @@ class coverage_run(object):
         log.notice("Coverage analysis finished. You can find results in " + self.targetDir)
 
 def output_handler(text):
-    log.notice(text, stdout_only = True)
+    log.notice(text, stdout_only = False)
 
 if __name__ == "__main__":
-    c = coverage_run("/home/rtems/coverage/test_new","/home/rtems/development/rtems/src/rtems-tools/tester")
+    c = coverage_run("/home/krzysztof/coverage/kmtest","/home/krzysztof/development/rtems/src/rtems-tools/tester")
     c.prepareEnvironment()
-    c.executables = ["/home/rtems/development/rtems/src/b-pc386/i386-rtems4.11/c/pc386/testsuites/samples/hello/hello.exe"]
+    c.executables = ["/home/krzysztof/development/rtems/src/b-pc386/i386-rtems4.11/c/pc386/testsuites/samples/hello/hello.exe"]
     c.run()
diff --git a/tester/rtems/testing/bsps/pc386.mc b/tester/rtems/testing/bsps/pc386.mc
index 3a35ebd..9418c00 100644
--- a/tester/rtems/testing/bsps/pc386.mc
+++ b/tester/rtems/testing/bsps/pc386.mc
@@ -45,7 +45,7 @@
 # The i386/pc386 QEMU BSP
 #
 
-hda:	none,	dir,	'/home/rtems/qemu/hdtest/rtems-boot.img'
+hda:	none,	dir,	'%{_rtscripts}/coverage/rtems-boot.img'
 
 [global]
 bsp:                      none,    none,     'pc386'
@@ -55,3 +55,12 @@ coverage_supported:	  none,	   none,	'1'
 pc386:      none,    none,  '%{_rtscripts}/qemu.cfg'
 pc386_arch: none,    none,  'i386'
 pc386_opts: none,    none,  '-m 128 -boot b -hda %{hda} %{qemu_opts_base} -append "--console=com1;boot;"'
+
+[coverage]
+format:		none, none, 'QEMU'
+target:		none, none, 'i386-rtems4.11'
+explanations:	none, none, '%{_rtscripts}/coverage/Explanations.txt'
+coverageExtension:	none, none, 'exe.cov'
+gcnosFile:	none, none, '%{_rtscripts}/coverage/rtems.gcnos'
+executableExtension:	none, none, 'exe'
+projectName:	none, none, 'RTEMS 4.11'
-- 
1.9.1

From aa83acdf4d205278caa9f3a8ba7774cb274bae85 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Krzysztof=20Mi=C4=99sowicz?= <krzysztof.miesow...@gmail.com>
Date: Wed, 27 Aug 2014 14:11:16 +0200
Subject: [PATCH 07/12] Fix in qemu.cfg for runs without coverage

---
 tester/rtems/testing/qemu.cfg | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tester/rtems/testing/qemu.cfg b/tester/rtems/testing/qemu.cfg
index 2254aef..9ff9014 100644
--- a/tester/rtems/testing/qemu.cfg
+++ b/tester/rtems/testing/qemu.cfg
@@ -62,7 +62,8 @@
 #
 # Coverage analysis
 #
-%if %{_coverage}
+%define coverage_arg
+%if %{defined _coverage}
 
  %if %{coverage_supported}
    %define coverage_arg -exec-trace coverage/%{test_executable_name}.cov
-- 
1.9.1

From 60b4d352e9355e4f0aef3a85447a2cf4baf14859 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Krzysztof=20Mi=C4=99sowicz?= <krzysztof.miesow...@gmail.com>
Date: Wed, 27 Aug 2014 14:11:52 +0200
Subject: [PATCH 08/12] Coverage option getter added

---
 rtemstoolkit/options.py | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/rtemstoolkit/options.py b/rtemstoolkit/options.py
index 5aa1ed3..5ddd3c8 100644
--- a/rtemstoolkit/options.py
+++ b/rtemstoolkit/options.py
@@ -406,6 +406,9 @@ class command_line(object):
     def no_install(self):
         return self.opts['no-install'] != '0'
 
+    def coverage(self):
+        return self.opts['coverage'] != '0'
+
     def user_macros(self):
         #
         # Return something even if it does not exist.
-- 
1.9.1

From 3f2821dc17a944be009c3afdc5e42b787eb073e3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Krzysztof=20Mi=C4=99sowicz?= <krzysztof.miesow...@gmail.com>
Date: Wed, 27 Aug 2014 14:12:50 +0200
Subject: [PATCH 09/12] Buffer overflow during writing annotated report fixed

---
 tester/covoar/ReportsBase.cc | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/tester/covoar/ReportsBase.cc b/tester/covoar/ReportsBase.cc
index d401bdd..2b6b8c9 100644
--- a/tester/covoar/ReportsBase.cc
+++ b/tester/covoar/ReportsBase.cc
@@ -205,7 +205,8 @@ void ReportsBase::WriteAnnotatedReport(
       uint32_t     id = 0;
       std::string  annotation = "";
       std::string  line;
-      char         textLine[150];
+      const std::size_t LINE_LENGTH = 150;
+      char         textLine[LINE_LENGTH];
 
       state = A_SOURCE;
 
@@ -228,7 +229,7 @@ void ReportsBase::WriteAnnotatedReport(
         }
       }
 
-      sprintf( textLine, "%-70s", itr->line.c_str() );
+      snprintf( textLine, LINE_LENGTH, "%-70s", itr->line.c_str() );
       line = textLine + annotation;
       
       PutAnnotatedLine( aFile, state, line, id); 
-- 
1.9.1

From 464b01755734ca17be10d354ff6a4edacbfd4d27 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Krzysztof=20Mi=C4=99sowicz?= <krzysztof.miesow...@gmail.com>
Date: Wed, 27 Aug 2014 14:28:48 +0200
Subject: [PATCH 10/12] Failure handling added to report generation

---
 tester/rt/coverage.py | 33 ++++++++++++++++++++-------------
 1 file changed, 20 insertions(+), 13 deletions(-)

diff --git a/tester/rt/coverage.py b/tester/rt/coverage.py
index cb5ea33..971d3cf 100644
--- a/tester/rt/coverage.py
+++ b/tester/rt/coverage.py
@@ -25,10 +25,12 @@ class summary:
         self.branches_alwaysTaken = 0
         self.branches_neverTaken = 0
         self.percentage_branchesCovered = 0.0
+        self.isFailure = False
 
     def parse(self):
         if(not path.exists(self.summaryFilePath)):
             log.warning("Summary file " + self.summaryFilePath + " does not exist!")
+            self.isFailure = True
             return
 
         summaryFile = open(self.summaryFilePath,'r')
@@ -59,6 +61,7 @@ class reportGen:
         self.symbolSetsList = p_symbolSetsList
         self.targetDir = p_targetDir
         self.partialReportsFiles = list(["index.html", "summary.txt"])
+        self.numberOfColumns = 1
 
     def _findPartialReports(self):
         partialReports = {}
@@ -98,19 +101,22 @@ class reportGen:
     def _row(self, symbolSet, summary):
         row = "<tr>"
         row += "<td>" + symbolSet + "</td>"
-        row += " <td>" + self._link(summary.indexFilePath,"Index") + "</td>"
-        row += " <td>" + self._link(summary.summaryFilePath,"Summary") + "</td>"
-        row += " <td>" + summary.bytes_analyzed + "</td>"
-        row += " <td>" + summary.bytes_notExecuted + "</td>"
-        row += " <td>" + summary.ranges_uncovered + "</td>"
-        row += " <td>" + summary.percentage_executed + "%</td>"
-        row += " <td>" + summary.percentage_notExecuted + "%</td>"
-        row += ' <td><progress value="' + summary.percentage_executed + '" max="100"></progress></td>'
-        row += " <td>" + summary.branches_uncovered + "</td>"
-        row += " <td>" + summary.branches_total + "</td>"
-        row += " <td> {:.3%} </td>".format(summary.percentage_branchesCovered)
-        row += ' <td><progress value="{:.3}" max="100"></progress></td>'.format(100*summary.percentage_branchesCovered)
-        row += "</tr>\n"
+        if summary.isFailure:
+            row += ' <td colspan="' + str(self.numberOfColumns-1) + '" style="background-color:red">FAILURE</td>'
+        else:
+            row += " <td>" + self._link(summary.indexFilePath,"Index") + "</td>"
+            row += " <td>" + self._link(summary.summaryFilePath,"Summary") + "</td>"
+            row += " <td>" + summary.bytes_analyzed + "</td>"
+            row += " <td>" + summary.bytes_notExecuted + "</td>"
+            row += " <td>" + summary.ranges_uncovered + "</td>"
+            row += " <td>" + summary.percentage_executed + "%</td>"
+            row += " <td>" + summary.percentage_notExecuted + "%</td>"
+            row += ' <td><progress value="' + summary.percentage_executed + '" max="100"></progress></td>'
+            row += " <td>" + summary.branches_uncovered + "</td>"
+            row += " <td>" + summary.branches_total + "</td>"
+            row += " <td> {:.3%} </td>".format(summary.percentage_branchesCovered)
+            row += ' <td><progress value="{:.3}" max="100"></progress></td>'.format(100*summary.percentage_branchesCovered)
+            row += "</tr>\n"
         return row
 
     def _headerRow(self):
@@ -129,6 +135,7 @@ class reportGen:
         row += "<th> Branches covered percentage </th>"
         row += "<th> Branches coverage </th>"
         row += "</tr>\n"
+        self.numberOfColumns = row.count('<th>')
         return row
 
     def _link(self, address, text):
-- 
1.9.1

From ccb283f513dfc122d515ec054a40e250a58735d5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Krzysztof=20Mi=C4=99sowicz?= <krzysztof.miesow...@gmail.com>
Date: Wed, 27 Aug 2014 14:29:47 +0200
Subject: [PATCH 11/12] Debug logging statement removed

---
 tester/covoar/SymbolSet.cpp | 8 --------
 tester/covoar/covoar.cc     | 4 ++--
 2 files changed, 2 insertions(+), 10 deletions(-)

diff --git a/tester/covoar/SymbolSet.cpp b/tester/covoar/SymbolSet.cpp
index c8f83e5..8290949 100644
--- a/tester/covoar/SymbolSet.cpp
+++ b/tester/covoar/SymbolSet.cpp
@@ -24,16 +24,9 @@ SymbolSet::~SymbolSet() {
 }
 
 std::string SymbolSet::parseNmOutputLine(std::string line) {
-	std::cout << "Read: " << std::endl;
-	std::cout << line << std::endl;
-	std::cout << "--------" << std::endl;
 	std::string symbol = "";
 	if (line.find("FUNC|") != std::string::npos) {
-		std::cout << "Function:" << std::endl;
 		symbol = line.substr(0, line.find('|'));
-		std::cout << symbol << std::endl;
-	} else {
-		std::cout << "Not a function" << std::endl;
 	}
 	return symbol;
 }
@@ -64,7 +57,6 @@ void SymbolSet::parseNmOutput(std::ifstream& nm_out, const std::string& lib) {
 }
 
 void SymbolSet::generateSymbolFile(std::string filePath, std::string target) {
-	std::cout << __FUNCTION__ << "(): arguments: " << filePath << ", " << target << std::endl;
 	std::string nm_output = "nm.out";
 	std::string nm_error = "nm.err";
 	std::string libFiles;
diff --git a/tester/covoar/covoar.cc b/tester/covoar/covoar.cc
index 868f40d..cbef875 100644
--- a/tester/covoar/covoar.cc
+++ b/tester/covoar/covoar.cc
@@ -367,12 +367,12 @@ int main(
 
   //Read symbol configuration file and load needed symbols
   if(symbolSetFile) {
-	  cout << "Reading symbols sets configuration for symbol set file: " << symbolSetFile << endl;
+	  fprintf(stderr,"Reading symbols sets configuration for symbol set file: %s\n", symbolSetFile);
 	  Symbols::SymbolSetReader ssr;
 	  std::vector<Symbols::SymbolSet> symbolSets = ssr.readSetFile(symbolSetFile);
 
 	  Symbols::SymbolSet& set = symbolSets[0];
-	  cout << "Generating symbol file for " << set.getName() << endl;
+	  fprintf(stderr,"Generating symbol file for %s\n", set.getName().c_str());
 	  set.generateSymbolFile(set.getName() + ".syms", target);
 	  SymbolsToAnalyze->load((set.getName() + ".syms").c_str());
   }
-- 
1.9.1

From 01600e07070f40a21f1131a33119bbd76aeae1d0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Krzysztof=20Mi=C4=99sowicz?= <krzysztof.miesow...@gmail.com>
Date: Wed, 27 Aug 2014 15:11:53 +0200
Subject: [PATCH 12/12] Exemplary symbolSets.config file added

---
 tester/rtems/testing/coverage/symbolSets.config | 11 +++++++++++
 1 file changed, 11 insertions(+)
 create mode 100644 tester/rtems/testing/coverage/symbolSets.config

diff --git a/tester/rtems/testing/coverage/symbolSets.config b/tester/rtems/testing/coverage/symbolSets.config
new file mode 100644
index 0000000..24e5040
--- /dev/null
+++ b/tester/rtems/testing/coverage/symbolSets.config
@@ -0,0 +1,11 @@
+symbolset:
+	name=score
+	lib=/home/krzysztof/development/rtems/src/b-pc386/i386-rtems4.11/c/pc386/cpukit/score/libscore.a
+symbolset:
+	name=filesystems
+	lib=/home/krzysztof/development/rtems/src/b-pc386/i386-rtems4.11/c/pc386/cpukit/libfs/libdevfs.a
+	lib=/home/krzysztof/development/rtems/src/b-pc386/i386-rtems4.11/c/pc386/cpukit/libfs/libdosfs.a
+	lib=/home/krzysztof/development/rtems/src/b-pc386/i386-rtems4.11/c/pc386/cpukit/libfs/libimfs.a
+	lib=/home/krzysztof/development/rtems/src/b-pc386/i386-rtems4.11/c/pc386/cpukit/libfs/librfs.a
+	lib=/home/krzysztof/development/rtems/src/b-pc386/i386-rtems4.11/c/pc386/cpukit/libfs/libjffs2.a
+	lib=/home/krzysztof/development/rtems/src/b-pc386/i386-rtems4.11/c/pc386/cpukit/libfs/libdefaultfs.a
\ No newline at end of file
-- 
1.9.1

_______________________________________________
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

Reply via email to