<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>change log for gcc-testing (2010-05-24)</title>
</head>
<body text='#000000' bgcolor='#ffffff'>
<a name='cs1'></a>
<table border='0' cellspacing='0' cellpadding='5' width='100%' bgcolor='#eeeeee'>
<tr><td colspan='3' bgcolor='#dddddd'>
<font color='#bb2222'><strong>jennifer</strong></font>
</td></tr>
<tr><td colspan='3' bgcolor='#dddddd'><pre>2010-05-24 Jennifer Averett <Jennifer.Averett@OARcorp.com>
* VERSIONS-COVERAGE, do_coverage: Created covoar directory with source
that will be moved from rtems-coverage.
</pre></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/rtems-coverage/ChangeLog.diff?r1=text&tr1=1.272&r2=text&tr2=1.273&diff_format=h">M</a></td><td width='1%'>1.273</td><td width='100%'>rtems-coverage/ChangeLog</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/rtems-coverage/VERSIONS-COVERAGE.diff?r1=text&tr1=1.21&r2=text&tr2=1.22&diff_format=h">M</a></td><td width='1%'>1.22</td><td width='100%'>rtems-coverage/VERSIONS-COVERAGE</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/rtems-coverage/do_coverage.diff?r1=text&tr1=1.63&r2=text&tr2=1.64&diff_format=h">M</a></td><td width='1%'>1.64</td><td width='100%'>rtems-coverage/do_coverage</td></tr>
</table>
<pre>
<font color='#006600'>diff -u gcc-testing/rtems-coverage/ChangeLog:1.272 gcc-testing/rtems-coverage/ChangeLog:1.273
--- gcc-testing/rtems-coverage/ChangeLog:1.272 Mon May 24 09:47:05 2010
+++ gcc-testing/rtems-coverage/ChangeLog Mon May 24 15:07:02 2010
</font><font color='#997700'>@@ -1,3 +1,8 @@
</font><font color='#000088'>+2010-05-24 Jennifer Averett <Jennifer.Averett@OARcorp.com>
+
+ * VERSIONS-COVERAGE, do_coverage: Created covoar directory with source
+ that will be moved from rtems-coverage.
+
</font> 2010-05-24 Jennifer Averett <Jennifer,.Averett@OARcorp.com>
* ReportsHtml.cc: Added link to size report. Added a filterable File
<font color='#006600'>diff -u gcc-testing/rtems-coverage/VERSIONS-COVERAGE:1.21 gcc-testing/rtems-coverage/VERSIONS-COVERAGE:1.22
--- gcc-testing/rtems-coverage/VERSIONS-COVERAGE:1.21 Wed Mar 31 14:41:44 2010
+++ gcc-testing/rtems-coverage/VERSIONS-COVERAGE Mon May 24 15:07:02 2010
</font><font color='#997700'>@@ -39,20 +39,9 @@
</font> # for publishing results
FTPDIR=/home/ftp/pub/rtems/people/joel/coverage/
<font color='#880000'>-
-# These symbols mark the range of the code block we are analyzing.
-# If the structure of the linked executable changes, then we need
-# to change these. This COULD change if you switch BSPs. We don't
-# know yet.
-#
-# NOTE: The highsym is still in libposix so needs to be analyzed
-# as well. :( We really need the first symbol AFTER it but
-# things are not setup to make that reliable.
-lowsym=start_coverage
-highsym=end_coverage
-
</font> # Calculated
SCRIPTDIR=${BASEDIR}/gcc-testing
COVBASE=${SCRIPTDIR}/rtems-coverage
<font color='#000088'>+COVOARBASE=${SCRIPTDIR}/covoar
</font>
<font color='#006600'>diff -u gcc-testing/rtems-coverage/do_coverage:1.63 gcc-testing/rtems-coverage/do_coverage:1.64
--- gcc-testing/rtems-coverage/do_coverage:1.63 Fri May 21 15:14:30 2010
+++ gcc-testing/rtems-coverage/do_coverage Mon May 24 15:07:02 2010
</font><font color='#997700'>@@ -406,7 +406,7 @@
</font> sort -n -r >${results_dir}/sizes_all.txt
# Now create the archive of information
<font color='#880000'>- cp ${COVBASE}/covoar.css ${COVBASE}/*gif ${COVBASE}/table.js ${results_dir}
</font><font color='#000088'>+ cp ${COVOARBASE}/covoar.css ${COVOARBASE}/*gif ${COVOARBASE}/table.js ${results_dir}
</font> echo "Results saved in ${results_dir}.tar.bz2"
tar cjf ${results_dir}.tar.bz2 ${results_dir}
}
</pre>
<p> </p>
<a name='cs2'></a>
<table border='0' cellspacing='0' cellpadding='5' width='100%' bgcolor='#eeeeee'>
<tr><td colspan='3' bgcolor='#dddddd'>
<font color='#bb2222'><strong>jennifer</strong></font>
</td></tr>
<tr><td colspan='3' bgcolor='#dddddd'><pre>2010-05-24 Jennifer Averett <Jennifer.Averett@OARcorp.com>
* covoar/05_ascending.gif, covoar/05_descending.gif,
covoar/05_unsorted.gif, covoar/ConfigFile.cc, covoar/ConfigFile.h,
covoar/CoverageFactory.cc, covoar/CoverageFactory.h,
covoar/CoverageMap.cc, covoar/CoverageMap.h,
covoar/CoverageMapBase.cc, covoar/CoverageMapBase.h,
covoar/CoverageRanges.cc, covoar/CoverageRanges.h,
covoar/CoverageReaderBase.cc, covoar/CoverageReaderBase.h,
covoar/CoverageReaderQEMU.cc, covoar/CoverageReaderQEMU.h,
covoar/CoverageReaderRTEMS.cc, covoar/CoverageReaderRTEMS.h,
covoar/CoverageReaderSkyeye.cc, covoar/CoverageReaderSkyeye.h,
covoar/CoverageReaderTSIM.cc, covoar/CoverageReaderTSIM.h,
covoar/CoverageWriterBase.cc, covoar/CoverageWriterBase.h,
covoar/CoverageWriterRTEMS.cc, covoar/CoverageWriterRTEMS.h,
covoar/CoverageWriterSkyeye.cc, covoar/CoverageWriterSkyeye.h,
covoar/CoverageWriterTSIM.cc, covoar/CoverageWriterTSIM.h,
covoar/DesiredSymbols.cc, covoar/DesiredSymbols.h,
covoar/ExecutableInfo.cc, covoar/ExecutableInfo.h,
covoar/Explanations.cc, covoar/Explanations.h, covoar/Makefile,
covoar/ObjdumpProcessor.cc, covoar/ObjdumpProcessor.h,
covoar/ReportsBase.cc, covoar/ReportsBase.h, covoar/ReportsHtml.cc,
covoar/ReportsHtml.h, covoar/ReportsText.cc, covoar/ReportsText.h,
covoar/SymbolTable.cc, covoar/SymbolTable.h, covoar/TargetBase.cc,
covoar/TargetBase.h, covoar/TargetFactory.cc, covoar/TargetFactory.h,
covoar/Target_arm.cc, covoar/Target_arm.h, covoar/Target_i386.cc,
covoar/Target_i386.h, covoar/Target_lm32.cc, covoar/Target_lm32.h,
covoar/Target_m68k.cc, covoar/Target_m68k.h,
covoar/Target_powerpc.cc, covoar/Target_powerpc.h,
covoar/Target_sparc.cc, covoar/Target_sparc.h,
covoar/TraceConverter.cc, covoar/TraceList.cc, covoar/TraceList.h,
covoar/TraceReaderBase.cc, covoar/TraceReaderBase.h,
covoar/TraceReaderLogQEMU.cc, covoar/TraceReaderLogQEMU.h,
covoar/TraceWriterBase.cc, covoar/TraceWriterBase.h,
covoar/TraceWriterQEMU.cc, covoar/TraceWriterQEMU.h,
covoar/app_common.cc, covoar/app_common.h, covoar/configfile_test.cc,
covoar/coverage_converter.cc, covoar/covmerge.cc, covoar/covoar.cc,
covoar/covoar.css, covoar/filter.gif, covoar/qemu-dump-trace.c,
covoar/qemu-log.h, covoar/qemu-traces.h, covoar/rtemscov_header.h,
covoar/skyeye_header.h, covoar/table.js: New files.
</pre></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/ChangeLog.diff?r1=text&tr1=1.55&r2=text&tr2=1.56&diff_format=h">M</a></td><td width='1%'>1.56</td><td width='100%'>ChangeLog</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/05_ascending.gif?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/05_ascending.gif</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/05_descending.gif?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/05_descending.gif</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/05_unsorted.gif?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/05_unsorted.gif</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/ConfigFile.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/ConfigFile.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/ConfigFile.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/ConfigFile.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/CoverageFactory.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/CoverageFactory.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/CoverageFactory.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/CoverageFactory.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/CoverageMap.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/CoverageMap.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/CoverageMap.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/CoverageMap.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/CoverageMapBase.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/CoverageMapBase.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/CoverageMapBase.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/CoverageMapBase.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/CoverageRanges.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/CoverageRanges.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/CoverageRanges.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/CoverageRanges.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/CoverageReaderBase.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/CoverageReaderBase.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/CoverageReaderBase.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/CoverageReaderBase.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/CoverageReaderQEMU.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/CoverageReaderQEMU.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/CoverageReaderQEMU.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/CoverageReaderQEMU.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/CoverageReaderRTEMS.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/CoverageReaderRTEMS.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/CoverageReaderRTEMS.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/CoverageReaderRTEMS.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/CoverageReaderSkyeye.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/CoverageReaderSkyeye.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/CoverageReaderSkyeye.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/CoverageReaderSkyeye.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/CoverageReaderTSIM.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/CoverageReaderTSIM.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/CoverageReaderTSIM.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/CoverageReaderTSIM.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/CoverageWriterBase.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/CoverageWriterBase.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/CoverageWriterBase.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/CoverageWriterBase.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/CoverageWriterRTEMS.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/CoverageWriterRTEMS.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/CoverageWriterRTEMS.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/CoverageWriterRTEMS.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/CoverageWriterSkyeye.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/CoverageWriterSkyeye.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/CoverageWriterSkyeye.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/CoverageWriterSkyeye.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/CoverageWriterTSIM.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/CoverageWriterTSIM.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/CoverageWriterTSIM.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/CoverageWriterTSIM.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/DesiredSymbols.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/DesiredSymbols.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/DesiredSymbols.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/DesiredSymbols.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/ExecutableInfo.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/ExecutableInfo.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/ExecutableInfo.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/ExecutableInfo.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/Explanations.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/Explanations.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/Explanations.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/Explanations.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/Makefile?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/Makefile</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/ObjdumpProcessor.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/ObjdumpProcessor.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/ObjdumpProcessor.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/ObjdumpProcessor.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/ReportsBase.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/ReportsBase.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/ReportsBase.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/ReportsBase.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/ReportsHtml.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/ReportsHtml.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/ReportsHtml.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/ReportsHtml.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/ReportsText.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/ReportsText.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/ReportsText.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/ReportsText.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/SymbolTable.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/SymbolTable.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/SymbolTable.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/SymbolTable.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/TargetBase.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/TargetBase.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/TargetBase.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/TargetBase.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/TargetFactory.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/TargetFactory.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/TargetFactory.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/TargetFactory.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/Target_arm.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/Target_arm.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/Target_arm.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/Target_arm.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/Target_i386.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/Target_i386.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/Target_i386.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/Target_i386.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/Target_lm32.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/Target_lm32.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/Target_lm32.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/Target_lm32.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/Target_m68k.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/Target_m68k.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/Target_m68k.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/Target_m68k.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/Target_powerpc.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/Target_powerpc.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/Target_powerpc.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/Target_powerpc.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/Target_sparc.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/Target_sparc.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/Target_sparc.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/Target_sparc.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/TraceConverter.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/TraceConverter.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/TraceList.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/TraceList.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/TraceList.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/TraceList.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/TraceReaderBase.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/TraceReaderBase.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/TraceReaderBase.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/TraceReaderBase.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/TraceReaderLogQEMU.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/TraceReaderLogQEMU.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/TraceReaderLogQEMU.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/TraceReaderLogQEMU.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/TraceWriterBase.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/TraceWriterBase.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/TraceWriterBase.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/TraceWriterBase.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/TraceWriterQEMU.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/TraceWriterQEMU.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/TraceWriterQEMU.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/TraceWriterQEMU.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/app_common.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/app_common.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/app_common.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/app_common.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/configfile_test.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/configfile_test.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/coverage_converter.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/coverage_converter.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/covmerge.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/covmerge.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/covoar.cc?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/covoar.cc</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/covoar.css?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/covoar.css</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/filter.gif?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/filter.gif</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/qemu-dump-trace.c?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/qemu-dump-trace.c</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/qemu-log.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/qemu-log.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/qemu-traces.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/qemu-traces.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/rtemscov_header.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/rtemscov_header.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/skyeye_header.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/skyeye_header.h</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//gcc-testing/covoar/table.js?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">covoar/table.js</font></td></tr>
</table>
<pre>
<font color='#006600'>diff -u gcc-testing/ChangeLog:1.55 gcc-testing/ChangeLog:1.56
--- gcc-testing/ChangeLog:1.55 Thu Mar 25 13:20:18 2010
+++ gcc-testing/ChangeLog Mon May 24 15:07:07 2010
</font><font color='#997700'>@@ -1,3 +1,44 @@
</font><font color='#000088'>+2010-05-24 Jennifer Averett <Jennifer.Averett@OARcorp.com>
+
+ * covoar/05_ascending.gif, covoar/05_descending.gif,
+ covoar/05_unsorted.gif, covoar/ConfigFile.cc, covoar/ConfigFile.h,
+ covoar/CoverageFactory.cc, covoar/CoverageFactory.h,
+ covoar/CoverageMap.cc, covoar/CoverageMap.h,
+ covoar/CoverageMapBase.cc, covoar/CoverageMapBase.h,
+ covoar/CoverageRanges.cc, covoar/CoverageRanges.h,
+ covoar/CoverageReaderBase.cc, covoar/CoverageReaderBase.h,
+ covoar/CoverageReaderQEMU.cc, covoar/CoverageReaderQEMU.h,
+ covoar/CoverageReaderRTEMS.cc, covoar/CoverageReaderRTEMS.h,
+ covoar/CoverageReaderSkyeye.cc, covoar/CoverageReaderSkyeye.h,
+ covoar/CoverageReaderTSIM.cc, covoar/CoverageReaderTSIM.h,
+ covoar/CoverageWriterBase.cc, covoar/CoverageWriterBase.h,
+ covoar/CoverageWriterRTEMS.cc, covoar/CoverageWriterRTEMS.h,
+ covoar/CoverageWriterSkyeye.cc, covoar/CoverageWriterSkyeye.h,
+ covoar/CoverageWriterTSIM.cc, covoar/CoverageWriterTSIM.h,
+ covoar/DesiredSymbols.cc, covoar/DesiredSymbols.h,
+ covoar/ExecutableInfo.cc, covoar/ExecutableInfo.h,
+ covoar/Explanations.cc, covoar/Explanations.h, covoar/Makefile,
+ covoar/ObjdumpProcessor.cc, covoar/ObjdumpProcessor.h,
+ covoar/ReportsBase.cc, covoar/ReportsBase.h, covoar/ReportsHtml.cc,
+ covoar/ReportsHtml.h, covoar/ReportsText.cc, covoar/ReportsText.h,
+ covoar/SymbolTable.cc, covoar/SymbolTable.h, covoar/TargetBase.cc,
+ covoar/TargetBase.h, covoar/TargetFactory.cc, covoar/TargetFactory.h,
+ covoar/Target_arm.cc, covoar/Target_arm.h, covoar/Target_i386.cc,
+ covoar/Target_i386.h, covoar/Target_lm32.cc, covoar/Target_lm32.h,
+ covoar/Target_m68k.cc, covoar/Target_m68k.h,
+ covoar/Target_powerpc.cc, covoar/Target_powerpc.h,
+ covoar/Target_sparc.cc, covoar/Target_sparc.h,
+ covoar/TraceConverter.cc, covoar/TraceList.cc, covoar/TraceList.h,
+ covoar/TraceReaderBase.cc, covoar/TraceReaderBase.h,
+ covoar/TraceReaderLogQEMU.cc, covoar/TraceReaderLogQEMU.h,
+ covoar/TraceWriterBase.cc, covoar/TraceWriterBase.h,
+ covoar/TraceWriterQEMU.cc, covoar/TraceWriterQEMU.h,
+ covoar/app_common.cc, covoar/app_common.h, covoar/configfile_test.cc,
+ covoar/coverage_converter.cc, covoar/covmerge.cc, covoar/covoar.cc,
+ covoar/covoar.css, covoar/filter.gif, covoar/qemu-dump-trace.c,
+ covoar/qemu-log.h, covoar/qemu-traces.h, covoar/rtemscov_header.h,
+ covoar/skyeye_header.h, covoar/table.js: New files.
+
</font> 2010-03-25 Joel Sherrill <joel.sherrill@oarcorp.com>
* VERSIONS: Update.
<font color='#FF0000'>*** DIFF FAILED: ***
*** DIFF FAILED: ***
*** DIFF FAILED: ***
</font><font color='#006600'>diff -u /dev/null gcc-testing/covoar/ConfigFile.h:1.1
--- /dev/null Mon May 24 15:10:03 2010
+++ gcc-testing/covoar/ConfigFile.h Mon May 24 15:07:07 2010
</font><font color='#997700'>@@ -0,0 +1,90 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+
+
+/*! @file ConfigFile.h
+ * @brief Configuration File Reader Specification
+ *
+ * This file contains the specification of the FileReader class.
+ */
+
+#ifndef __CONFIGURATION_FILE_H__
+#define __CONFIGURATION_FILE_H__
+
+namespace Configuration {
+
+ /*!
+ *<span style="background-color: #FF0000"> </span>
+ * This structure contains the configuration parameter
+ * name and value pair.
+ */<span style="background-color: #FF0000"> </span>
+ typedef struct {
+ const char *option;
+ const char *value;
+ } Options_t;
+
+
+ /*! @class FileReader
+ *
+ * This is the specification of the FileReader base class.
+ * All FileReader implementations inherit from this class.
+ */
+ class FileReader {
+
+ public:
+
+ /*!<span style="background-color: #FF0000"> </span>
+ * This method constructs a FileReader instance.
+ *
+ * @param[in] options is the set of options
+ */
+ FileReader(
+ Options_t *options
+ );
+
+ /*!<span style="background-color: #FF0000"> </span>
+ * This method destructs a FileReader instance.
+ */
+ virtual ~FileReader();
+
+ /*!
+ * This method processes the configuratino information from the input
+ * @a file.
+ *
+ * @param[in] file is the coverage file to process
+ *
+ * @return Returns TRUE if the method succeeded and FALSE if it failed.
+ */
+ virtual bool processFile(
+ const char* const file
+ );
+
+ bool setOption(
+ const char* const option,
+ const char* const value
+ );
+
+ const char *getOption(
+ const char* const option
+ );
+
+ void printOptions(void);
+
+ private:
+ /*!
+ * This method processes the configuratino information from the input
+ * @a file.
+ *
+ * @param[in] option is the name of the option
+ * @param[in] value is the associated value
+ *
+ * @return Returns TRUE if the method succeeded and FALSE if it failed.
+ */
+ Options_t *options_m;
+
+ };
+
+}
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/ConfigFile.cc:1.1
--- /dev/null Mon May 24 15:10:03 2010
+++ gcc-testing/covoar/ConfigFile.cc Mon May 24 15:07:07 2010
</font><font color='#997700'>@@ -0,0 +1,200 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+
+/*! @file ConfigFile.cc
+ * @brief ConfigFile Implementation
+ *
+ * This file contains the implementation of the FileReader class.
+ */
+
+#include "ConfigFile.h"
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+
+namespace Configuration {
+
+ FileReader::FileReader(
+ Options_t *options
+ )
+ {
+ options_m = options;
+ }
+
+ FileReader::~FileReader()
+ {
+ }
+
+ bool FileReader::processFile(
+ const char* const file
+ )
+ {
+ #define METHOD "FileReader::processFile - "
+ FILE * in;
+ char line[256];
+ char option[256];
+ char value[256];
+ int line_no;
+ int i;
+ int j;
+
+ if ( file == NULL ) {
+ fprintf( stderr, METHOD "NULL filename\n" );
+ return false;
+ }
+
+ in = fopen( file, "r" );
+ if ( !in ) {
+ fprintf( stderr, METHOD "unable to open %s\n", file );
+ return false;
+ }
+
+ line_no = 0;
+ while (fgets(line, sizeof(line), in) != NULL) {
+ size_t length;
+
+ line_no++;
+
+ length = strlen( line );
+ if ( line[length - 1] != '\n' ) {
+ fprintf(
+ stderr,
+ "%s: line %d is too long",
+ file,
+ line_no
+ );
+ continue;
+ }
+
+ line[length - 1] = '\0';
+ length--;
+
+ /*
+ * Strip off comments at end of line
+ *
+ * LHS = RHS # comment
+ */
+ for (i=0 ; i<length ; i++ ) {
+ if ( line[i] == '#' ) {
+ line[i] = '\0';
+ length = i;
+ break;
+ }
+ }
+
+ /*
+ * Strip off trailing white space
+ */
+ for (i=length-1 ; i>=0 && isspace(line[i]) ; i-- )
+ ;
+
+ line[i+1] = '\0';
+ length = i+1;
+
+ /* Ignore empty lines. We have stripped
+ * all comments and blanks therefore, only
+ * an empty string needs to be checked.
+ */
+ if (line[0] == '\0')<span style="background-color: #FF0000"> </span>
+ continue;
+
+ if (sscanf(line, "%s", option) != 1) {
+ fprintf(
+ stderr,
+ "%s: line %d is invalid: %s\n",
+ file,
+ line_no,
+ line
+ );
+ continue;
+ }
+
+ for (i=0; ((line[i] != '=') && (i<length)); i++)
+ ;
+
+ if (i == length) {
+ fprintf(
+ stderr,
+ "%s: line %d is invalid: %s\n",
+ file,
+ line_no,
+ line
+ );
+ continue;
+ }
+
+ i++;
+ value[0] = '\0';
+ while ( isspace(line[i]) )
+ i++;
+ for (j=0; line[i] != '\0'; i++, j++ )
+ value[j] = line[i];
+ value[j] = '\0';<span style="background-color: #FF0000"> </span>
+ if (value[0] == '\0') {
+ fprintf(
+ stderr,
+ "%s: line %d is invalid: %s\n",
+ file,
+ line_no,
+ line
+ );
+ continue;
+ }
+
+ if ( !setOption(option, value) ) {
+ fprintf(
+ stderr,
+ "%s: line %d: option %s is unknown\n",
+ file,
+ line_no,
+ option
+ );
+ continue;
+ }
+
+ }
+
+ return false;
+ }
+
+ bool FileReader::setOption(
+ const char* const option,
+ const char* const value
+ )
+ {
+ Options_t *o;
+
+ for ( o=options_m ; o->option ; o++ ) {
+ if ( !strcmp( o->option, option ) ) {
+ o->value = strdup( value );
+ return true;
+ }
+ }
+ return false;
+ }
+
+ const char *FileReader::getOption(
+ const char* const option
+ )
+ {
+ Options_t *o;
+
+ for ( o=options_m ; o->option ; o++ ) {
+ if ( !strcmp( o->option, option ) ) {
+ return o->value;
+ }
+ }
+ return NULL;
+ }
+
+ void FileReader::printOptions(void)
+ {
+ Options_t *o;
+
+ for ( o=options_m ; o->option ; o++ ) {
+ fprintf( stderr, "(%s)=(%s)\n", o->option, o->value );
+ }
+ }
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/CoverageFactory.h:1.1
--- /dev/null Mon May 24 15:10:03 2010
+++ gcc-testing/covoar/CoverageFactory.h Mon May 24 15:07:07 2010
</font><font color='#997700'>@@ -0,0 +1,68 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file CoverageFactory.h
+ * @brief CoverageFactory Specification
+ *
+ * This file contains the specification of the CoverageFactory methods.
+ * This collection of methods is used to create CoverageReader and/or
+ * CoverageWriter instances for a particular coverage file format.
+ */
+
+#ifndef __COVERAGE_FACTORY_H__
+#define __COVERAGE_FACTORY_H__
+
+#include "CoverageReaderBase.h"
+#include "CoverageWriterBase.h"
+
+namespace Coverage {
+
+ /*!
+ * This type defines the coverage file formats that are supported.
+ */
+ typedef enum {
+ COVERAGE_FORMAT_QEMU,
+ COVERAGE_FORMAT_RTEMS,
+ COVERAGE_FORMAT_SKYEYE,
+ COVERAGE_FORMAT_TSIM
+ } CoverageFormats_t;
+
+ /*!
+ * This method returns the coverage file format that corresponds
+ * to the specified string.
+ *
+ * @param[in] format is a string specifying the coverage file format
+ *
+ * @return Returns a coverage file format.
+ */
+ CoverageFormats_t CoverageFormatToEnum(
+ const char* const format
+ );
+
+ /*!
+ * This method returns an instance of a Coverage File Reader class
+ * that corresponds to the specified coverage file format.
+ *
+ * @param[in] format specifies the coverage file format
+ *
+ * @return Returns a Coverage File Reader class instance.
+ */
+ CoverageReaderBase* CreateCoverageReader(
+ CoverageFormats_t format
+ );
+
+ /*!
+ * This method returns an instance of a Coverage File Writer class
+ * that corresponds to the specified coverage file format.
+ *
+ * @param[in] format specifies the coverage file format
+ *
+ * @return Returns a Coverage File Writer class instance.
+ */
+ CoverageWriterBase* CreateCoverageWriter(
+ CoverageFormats_t format
+ );
+}
+
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/CoverageFactory.cc:1.1
--- /dev/null Mon May 24 15:10:03 2010
+++ gcc-testing/covoar/CoverageFactory.cc Mon May 24 15:07:07 2010
</font><font color='#997700'>@@ -0,0 +1,85 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file CoverageFactory.cc
+ * @brief CoverageFactory Implementation
+ *
+ * This file contains the implementation of the functions supporting
+ * creating a CoverageReader or CoverageWriter of a specific type
+ * based upon user configuration.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "CoverageFactory.h"
+#include "CoverageReaderQEMU.h"
+#include "CoverageReaderRTEMS.h"
+#include "CoverageWriterRTEMS.h"
+#include "CoverageReaderSkyeye.h"
+#include "CoverageWriterSkyeye.h"
+#include "CoverageReaderTSIM.h"
+#include "CoverageWriterTSIM.h"
+
+Coverage::CoverageFormats_t Coverage::CoverageFormatToEnum(
+ const char* const format
+)
+{
+ if (!strcmp( format, "QEMU" ))
+ return COVERAGE_FORMAT_QEMU;
+
+ if (!strcmp( format, "RTEMS" ))
+ return COVERAGE_FORMAT_RTEMS;
+
+ if (!strcmp( format, "Skyeye" ))
+ return COVERAGE_FORMAT_SKYEYE;
+
+ if (!strcmp( format, "TSIM" ))
+ return COVERAGE_FORMAT_TSIM;
+
+ fprintf(
+ stderr,
+ "ERROR: %s is an unknown coverage format "
+ "(supported formats - QEMU, RTEMS, Skyeye and TSIM)\n",
+ format
+ );
+ exit( 1 );
+}
+
+Coverage::CoverageReaderBase* Coverage::CreateCoverageReader(
+ CoverageFormats_t format
+)
+{
+ switch (format) {
+ case COVERAGE_FORMAT_QEMU:
+ return new Coverage::CoverageReaderQEMU();
+ case COVERAGE_FORMAT_RTEMS:
+ return new Coverage::CoverageReaderRTEMS();
+ case COVERAGE_FORMAT_SKYEYE:
+ return new Coverage::CoverageReaderSkyeye();
+ case COVERAGE_FORMAT_TSIM:
+ return new Coverage::CoverageReaderTSIM();
+ default:
+ break;
+ }
+ return NULL;
+}
+
+Coverage::CoverageWriterBase* Coverage::CreateCoverageWriter(
+ CoverageFormats_t format
+)
+{
+ switch (format) {
+ case COVERAGE_FORMAT_RTEMS:
+ return new Coverage::CoverageWriterRTEMS();
+ case COVERAGE_FORMAT_SKYEYE:
+ return new Coverage::CoverageWriterSkyeye();
+ case COVERAGE_FORMAT_TSIM:
+ return new Coverage::CoverageWriterTSIM();
+ default:
+ break;
+ }
+ return NULL;
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/CoverageMap.h:1.1
--- /dev/null Mon May 24 15:10:03 2010
+++ gcc-testing/covoar/CoverageMap.h Mon May 24 15:07:07 2010
</font><font color='#997700'>@@ -0,0 +1,44 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file CoverageMap.h
+ * @brief CoverageMap Specification
+ *
+ * This file contains the specification of the CoverageMap class.
+ */
+
+#ifndef __COVERAGE_MAP_H__
+#define __COVERAGE_MAP_H__
+
+#include "CoverageMapBase.h"
+
+namespace Coverage {
+
+ /*! @class CoverageMap
+ *
+ * This class implements a coverage map which supports a single
+ * range of addresses from low to high.<span style="background-color: #FF0000"> </span>
+ */
+ class CoverageMap : public CoverageMapBase {
+
+ public:
+
+ /*!<span style="background-color: #FF0000"> </span>
+ * This method constructs a CoverageMap instance.
+ *
+ * @param[in] low specifies the lowest address of the coverage map.
+ * @param[in] high specifies the highest address of the coverage map.
+ */
+ CoverageMap(
+ uint32_t low,
+ uint32_t high
+ );
+
+ /* Inherit documentation from base class. */
+ virtual ~CoverageMap();
+
+ };
+
+}
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/CoverageMap.cc:1.1
--- /dev/null Mon May 24 15:10:03 2010
+++ gcc-testing/covoar/CoverageMap.cc Mon May 24 15:07:07 2010
</font><font color='#997700'>@@ -0,0 +1,27 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file CoverageMap.cc
+ * @brief CoverageMap Implementation
+ *
+ * This file contains the implementation of the functions supporting
+ * a CoverageMap. Currently, it adds no functionality to CoverageMapBase.
+ */
+
+#include "CoverageMap.h"
+
+namespace Coverage {
+
+ CoverageMap::CoverageMap(
+ uint32_t low,
+ uint32_t high
+ ) : CoverageMapBase(low, high)
+ {
+ }
+
+ CoverageMap::~CoverageMap()
+ {
+ }
+
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/CoverageMapBase.h:1.1
--- /dev/null Mon May 24 15:10:03 2010
+++ gcc-testing/covoar/CoverageMapBase.h Mon May 24 15:07:07 2010
</font><font color='#997700'>@@ -0,0 +1,248 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file CoverageMapBase.h
+ * @brief CoverageMapBase Specification
+ *
+ * This file contains the specification of the CoverageMapBase class.
+ */
+
+#ifndef __COVERAGE_MAP_BASE_H__
+#define __COVERAGE_MAP_BASE_H__
+
+#include <stdint.h>
+#include <string>
+
+namespace Coverage {
+
+ /*! @class CoverageMapBase
+ *
+ * This is the base class for Coverage Map implementations.
+ */
+ class CoverageMapBase {
+
+ public:
+
+ /*!<span style="background-color: #FF0000"> </span>
+ * This method constructs a CoverageMapBase instance.
+ *
+ * @param[in] low specifies the lowest address of the coverage map
+ * @param[in] high specifies the highest address of the coverage map
+ */
+ CoverageMapBase(
+ uint32_t low,
+ uint32_t high
+ );
+
+ /*!<span style="background-color: #FF0000"> </span>
+ * This method destructs a CoverageMapBase instance.
+ */
+ virtual ~CoverageMapBase();
+
+ /*!
+ * This method prints the contents of the coverage map to stdout.
+ */
+ void dump( void ) const;
+
+ /*!
+ * This method returns the address of the beginning of the
+ * instruction that contains the specified address.
+ *
+ * @param[in] address specifies the address to search from
+ * @param[out] beginning contains the address of the beginning of
+ * the instruction.
+ *<span style="background-color: #FF0000"> </span>
+ * @return Returns TRUE if the beginning of the instruction was
+ * found and FALSE if it was not.
+ */
+ bool getBeginningOfInstruction(
+ uint32_t address,
+ uint32_t* beginning
+ ) const;
+
+ /*!
+ * This method returns the high address of the coverage map.
+ *
+ * @return Returns the high address of the coverage map.
+ */
+ uint32_t getHighAddress( void ) const;
+
+ /*!
+ * This method returns the low address of the coverage map.
+ *
+ * @return Returns the low address of the coverage map.
+ */
+ uint32_t getLowAddress( void ) const;
+
+ /*!
+ * This method sets the boolean which indicates if this
+ * is the starting address for an instruction.
+ *
+ * @param[in] address specifies the address of the start of an instruction
+ */
+ void setIsStartOfInstruction(
+ uint32_t address
+ );
+
+ /*!
+ * This method returns a boolean which indicates if this
+ * is the starting address of an instruction.
+ *
+ * @param[in] address specifies the address to check
+ *
+ * @return Returns TRUE if the specified address is the start
+ * of an instruction and FALSE otherwise.
+ */
+ bool isStartOfInstruction( uint32_t address ) const;
+
+ /*!
+ * This method sets the boolean which indicates that the instruction
+ * at the specified address was executed.
+ *
+ * @param[in] address specifies the address which was executed
+ */
+ virtual void setWasExecuted( uint32_t address );
+
+ /*!
+ * This method returns a boolean which indicates if the instruction
+ * at the specified address was executed.
+ *
+ * @param[in] address specifies the address to check
+ *<span style="background-color: #FF0000"> </span>
+ * @return Returns TRUE if the instruction at the specified
+ * address was executed and FALSE otherwise.
+ */
+ bool wasExecuted( uint32_t address ) const;
+
+ /*!
+ * This method sets the boolean which indicates if the specified
+ * address is the starting address of a branch instruction.
+ *
+ * @param[in] address specifies the address of the branch instruction
+ */
+ void setIsBranch( uint32_t address );
+
+ /*!
+ * This method returns a boolean which indicates if the specified
+ * address is the starting address of a branch instruction.
+ *
+ * @param[in] address specifies the address to check
+ *
+ * @return Returns TRUE if a branch instruction is at the
+ * specified address and FALSE otherwise.
+ */
+ bool isBranch( uint32_t address ) const;
+
+ /*!
+ * This method sets the boolean which indicates if the branch
+ * at the specified address was taken.
+ *
+ * @param[in] address specifies the address of the branch instruction
+ */
+ void setWasTaken( uint32_t address );
+
+ /*!
+ * This method sets the boolean which indicates if the branch
+ * at the specified address was NOT taken.
+ *
+ * @param[in] address specifies the address of the branch instruction
+ */
+ void setWasNotTaken( uint32_t address );
+
+ /*!
+ * This method returns a boolean which indicates if the branch
+ * instruction at the specified address is ALWAYS taken.
+ *
+ * @param[in] address specifies the address to check
+ *
+ * @return Returns TRUE if the branch instruction at the
+ * specified address is ALWAYS taken and FALSE otherwise.
+ */
+ bool wasAlwaysTaken( uint32_t address ) const;
+
+ /*!
+ * This method returns a boolean which indicates if the branch
+ * instruction at the specified address is NEVER taken.
+ *
+ * @param[in] address specifies the address to check
+ *
+ * @return Returns TRUE if the branch instruction at the
+ * specified address is NEVER taken and FALSE otherwise.
+ */
+ bool wasNeverTaken( uint32_t address ) const;
+
+ /*!
+ * This method returns a boolean which indicates if the branch
+ * instruction at the specified address was NOT taken.
+ *
+ * @param[in] address specifies the address to check
+ *
+ * @return Returns TRUE if the branch instruction at the
+ * specified address was NOT taken and FALSE otherwise.
+ */
+ bool wasNotTaken( uint32_t address ) const;
+
+ /*!
+ * This method returns a boolean which indicates if the branch
+ * instruction at the specified address was taken.
+ *
+ * @param[in] address specifies the address to check
+ *
+ * @return Returns TRUE if the branch instruction at the
+ * specified address was taken and FALSE otherwise.
+ */
+ bool wasTaken( uint32_t address ) const;
+
+ protected:
+
+ /*!
+ * This structure defines the information that is gathered and
+ * tracked per address.
+ */
+ typedef struct {
+ /*!
+ * This member indicates that the address is the start of
+ * an instruction.
+ */
+ bool isStartOfInstruction;
+ /*!
+ * This member indicates that the address was executed.
+ */
+ bool wasExecuted;
+ /*!
+ * This member indicates that the address is a branch instruction.
+ */
+ bool isBranch;
+ /*!
+ * When isBranch is TRUE, this member indicates that the branch
+ * instruction at the address was taken.
+ */
+ bool wasTaken;
+ /*!
+ * When isBranch is TRUE, this member indicates that the branch
+ * instruction at the address was NOT taken.
+ */
+ bool wasNotTaken;
+ } perAddressInfo_t;
+
+ /*!
+ * This is a dynamically allocated array of data that is
+ * kept for each address.
+ */
+ perAddressInfo_t* Info;
+
+ /*!
+ * This is the low address of the address map range.
+ */
+ uint32_t lowAddress;
+
+ /*!
+ * This is the high address of the address map range.
+ */
+ uint32_t highAddress;
+
+ };
+
+}
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/CoverageMapBase.cc:1.1
--- /dev/null Mon May 24 15:10:03 2010
+++ gcc-testing/covoar/CoverageMapBase.cc Mon May 24 15:07:07 2010
</font><font color='#997700'>@@ -0,0 +1,202 @@
</font><font color='#000088'>+
+/*
+ * $Id$
+ */
+
+/*! @file CoverageMapBase.cc
+ * @brief CoverageMapBase Implementation
+ *
+ * This file contains the implementation of the functions<span style="background-color: #FF0000"> </span>
+ * which provide a base level of functionality of a CoverageMap.
+ */
+
+#include <libgen.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "CoverageMapBase.h"
+
+namespace Coverage {
+
+ CoverageMapBase::CoverageMapBase(
+ uint32_t low,
+ uint32_t high
+ ) : lowAddress(low), highAddress(high)
+ {
+ uint32_t a;
+
+ Info = new perAddressInfo_t[ high - low + 1 ];
+
+ for (a=low; a<=high; a++) {
+
+ perAddressInfo_t *i = &Info[ a-low ];
+
+ i->isStartOfInstruction = false;
+ i->wasExecuted = false;
+ i->isBranch = false;
+ i->wasTaken = false;
+ i->wasNotTaken = false;
+ }
+ }
+
+ CoverageMapBase::~CoverageMapBase()
+ {
+ if (Info)
+ delete Info;
+ }
+
+ void CoverageMapBase::dump( void ) const {
+
+ uint32_t a;
+ perAddressInfo_t* entry;
+
+ fprintf( stderr, "Coverage Map Contents:\n" );
+
+ for (a = lowAddress; a <= highAddress; a++) {
+
+ entry = &Info[ a - lowAddress ];
+
+ fprintf(
+ stderr,
+ "0x%x - isStartOfInstruction = %s, wasExecuted = %s\n",
+ a,
+ entry->isStartOfInstruction ? "TRUE" : "FALSE",
+ entry->wasExecuted ? "TRUE" : "FALSE"
+ );
+ fprintf(
+ stderr,
+ " isBranch = %s, wasTaken = %s, wasNotTaken = %s\n",
+ entry->isBranch ? "TRUE" : "FALSE",
+ entry->wasTaken ? "TRUE" : "FALSE",
+ entry->wasNotTaken ? "TRUE" : "FALSE"
+ );
+ }
+ }
+
+ bool CoverageMapBase::getBeginningOfInstruction(
+ uint32_t address,
+ uint32_t* beginning
+ ) const
+ {
+ bool status = false;
+ uint32_t start;
+
+ if ((address < lowAddress) || (address > highAddress))
+ return status;
+
+ start = address;
+
+ while (start >= lowAddress ) {
+ if (Info[ start - lowAddress ].isStartOfInstruction) {
+ *beginning = start;
+ status = true;
+ break;
+ }
+ else
+ start--;
+ }
+
+ return status;
+ }
+
+ uint32_t CoverageMapBase::getHighAddress( void ) const
+ {
+ return highAddress;
+ }
+
+ uint32_t CoverageMapBase::getLowAddress( void ) const
+ {
+ return lowAddress;
+ }
+
+ void CoverageMapBase::setIsStartOfInstruction(
+ uint32_t address
+ )
+ {
+ if ((address < lowAddress) || (address > highAddress))
+ return;
+ Info[ address - lowAddress ].isStartOfInstruction = true;
+ }
+
+ bool CoverageMapBase::isStartOfInstruction( uint32_t address ) const
+ {
+ if ((address < lowAddress) || (address > highAddress))
+ return false;
+ return Info[ address - lowAddress ].isStartOfInstruction;
+ }
+
+ void CoverageMapBase::setWasExecuted( uint32_t address )
+ {
+ if ((address < lowAddress) || (address > highAddress))
+ return;
+ Info[ address - lowAddress ].wasExecuted = true;
+ }
+
+ bool CoverageMapBase::wasExecuted( uint32_t address ) const
+ {
+ if ((address < lowAddress) || (address > highAddress))
+ return false;
+ return Info[ address - lowAddress ].wasExecuted;
+ }
+
+ void CoverageMapBase::setIsBranch(
+ uint32_t address
+ )
+ {
+ if ((address < lowAddress) || (address > highAddress))
+ return;
+ Info[ address - lowAddress ].isBranch = true;
+ }
+
+ bool CoverageMapBase::isBranch( uint32_t address ) const
+ {
+ if ((address < lowAddress) || (address > highAddress))
+ return false;
+ return Info[ address - lowAddress ].isBranch;
+ }
+
+ void CoverageMapBase::setWasTaken(
+ uint32_t address
+ )
+ {
+ if ((address < lowAddress) || (address > highAddress))
+ return;
+ Info[ address - lowAddress ].wasTaken = true;
+ }
+
+ void CoverageMapBase::setWasNotTaken(
+ uint32_t address
+ )
+ {
+ if ((address < lowAddress) || (address > highAddress))
+ return;
+ Info[ address - lowAddress ].wasNotTaken = true;
+ }
+
+ bool CoverageMapBase::wasAlwaysTaken( uint32_t address ) const
+ {
+ if ((address < lowAddress) || (address > highAddress))
+ return false;
+ return (Info[ address - lowAddress ].wasTaken &&
+ !Info[ address - lowAddress ].wasNotTaken);
+ }
+
+ bool CoverageMapBase::wasNeverTaken( uint32_t address ) const
+ {
+ if ((address < lowAddress) || (address > highAddress))
+ return false;
+ return (!Info[ address - lowAddress ].wasTaken &&
+ Info[ address - lowAddress ].wasNotTaken);
+ }
+
+ bool CoverageMapBase::wasNotTaken( uint32_t address ) const
+ {
+ return (Info[ address - lowAddress ].wasNotTaken);
+ }
+
+ bool CoverageMapBase::wasTaken( uint32_t address ) const
+ {
+ return (Info[ address - lowAddress ].wasTaken);
+ }
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/CoverageRanges.h:1.1
--- /dev/null Mon May 24 15:10:03 2010
+++ gcc-testing/covoar/CoverageRanges.h Mon May 24 15:07:07 2010
</font><font color='#997700'>@@ -0,0 +1,133 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file CoverageRanges.h
+ * @brief CoverageRanges Specification
+ *
+ * This file contains the specification of the CoverageRanges class.
+ */
+
+#ifndef __COVERAGE_RANGES_H__
+#define __COVERAGE_RANGES_H__
+
+#include <stdint.h>
+#include <list>
+#include <string>
+
+namespace Coverage {
+
+ /*! @class CoverageRanges
+ *
+ * This class defines a set of address ranges for which coverage
+ * did not occur. Each address range can either define a range of
+ * bytes that was not executed or a range of bytes for a branch
+ * instruction that was not completely covered (i.e. taken and NOT
+ * taken).
+ */
+ class CoverageRanges {
+
+ public:
+
+ /*!
+ * This type defines the reasons to associate with a range.
+ */
+ typedef enum {
+ UNCOVERED_REASON_NOT_EXECUTED,
+ UNCOVERED_REASON_BRANCH_ALWAYS_TAKEN,
+ UNCOVERED_REASON_BRANCH_NEVER_TAKEN
+ } uncoveredReason_t;
+
+ /*!
+ * This type defines the information kept for each range.
+ */
+ typedef struct {
+ /*!
+ * This member contains an identification number for this<span style="background-color: #FF0000"> </span>
+ * coverage range.
+ */
+ uint32_t id;
+
+ /*!
+ * This member contains the low address of this coverage<span style="background-color: #FF0000"> </span>
+ * range.
+ */
+ uint32_t lowAddress;
+
+ /*!
+ * This member contains the source line associated with the<span style="background-color: #FF0000"> </span>
+ * low address for this coverage range.
+ */
+ std::string lowSourceLine;
+
+ /*!
+ * This member contains the high address for this coverage range.
+ */
+ uint32_t highAddress;
+
+ /*!
+ * This member contains the high source line for this coverage range.
+ */
+ std::string highSourceLine;
+
+ /*!
+ * This member contains an instruction count for this coverage<span style="background-color: #FF0000"> </span>
+ * address range.
+ */
+ uint32_t instructionCount;
+
+ /*!
+ * This member contains the reason that this area was uncovered.
+ */
+ uncoveredReason_t reason;
+ } coverageRange_t;
+
+ /*!
+ * This type contains a list of CoverageRange instances.
+ */
+ typedef std::list<coverageRange_t> ranges_t;
+
+ /*!
+ * This member contains a list of the CoverageRange instances.
+ */
+ ranges_t set;
+
+ /*!<span style="background-color: #FF0000"> </span>
+ * This method constructs a CoverageRanges instance.
+ */
+ CoverageRanges();
+
+ /*!<span style="background-color: #FF0000"> </span>
+ * This method destructs a CoverageRanges instance.
+ */
+ ~CoverageRanges();
+
+ /*!
+ * This method adds a range entry to the set of ranges.
+ *
+ * @param[in] lowAddressArg specifies the lowest address of the range
+ * @param[in] highAddressArg specifies the highest address of the range
+ * @param[in] why specifies the reason that the range was added
+ *
+ */
+ void add(
+ uint32_t lowAddressArg,
+ uint32_t highAddressArg,
+ uncoveredReason_t why,
+ uint32_t numInstructions
+ );
+<span style="background-color: #FF0000"> </span>
+
+ /*!
+ * This method returns the index of a range given the low address.
+ * Upon failure on finding the adress 0 is returned.
+ */
+ uint32_t getId( uint32_t lowAddress );
+<span style="background-color: #FF0000"> </span>
+ protected:
+
+
+ };
+
+}
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/CoverageRanges.cc:1.1
--- /dev/null Mon May 24 15:10:04 2010
+++ gcc-testing/covoar/CoverageRanges.cc Mon May 24 15:07:07 2010
</font><font color='#997700'>@@ -0,0 +1,65 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file CoverageRanges.cc
+ * @brief CoverageRanges Implementation
+ *
+ * This file contains the implementation of the functions<span style="background-color: #FF0000"> </span>
+ * which provide a base level of functionality of a CoverageRanges.
+ */
+
+#include "CoverageRanges.h"
+#include <stdio.h>
+
+namespace Coverage {
+
+ /*!
+ * This member variable tracks a unique index for the ranges_t block.
+ */
+ uint32_t id_m = 0;
+
+ CoverageRanges::CoverageRanges()
+ {
+ }
+
+ CoverageRanges::~CoverageRanges()
+ {
+ }
+
+ void CoverageRanges::add(
+ uint32_t lowAddressArg,
+ uint32_t highAddressArg,
+ uncoveredReason_t why,
+ uint32_t numInstructions
+ )
+ {
+ coverageRange_t c;
+
+ id_m++;
+ c.id = id_m;
+ c.lowAddress = lowAddressArg;
+ c.highAddress = highAddressArg;
+ c.reason = why;
+ c.instructionCount = numInstructions;
+ set.push_back(c);
+ }
+
+ uint32_t CoverageRanges::getId( uint32_t lowAddress )
+ {
+ Coverage::CoverageRanges::ranges_t::iterator ritr;
+ uint32_t result = 0;
+
+ for (ritr = set.begin() ;
+ ritr != set.end() ;
+ ritr++ ) {
+ if ( ritr->lowAddress == lowAddress ) {
+ result = ritr->id;
+ break;
+ }
+ }
+
+ return result;
+ }
+
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/CoverageReaderBase.h:1.1
--- /dev/null Mon May 24 15:10:04 2010
+++ gcc-testing/covoar/CoverageReaderBase.h Mon May 24 15:07:07 2010
</font><font color='#997700'>@@ -0,0 +1,52 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file CoverageReaderBase.h
+ * @brief CoverageReaderBase Specification
+ *
+ * This file contains the specification of the CoverageReaderBase class.
+ */
+
+#ifndef __COVERAGE_READER_BASE_H__
+#define __COVERAGE_READER_BASE_H__
+
+#include "ExecutableInfo.h"
+
+namespace Coverage {
+
+ /*! @class CoverageReaderBase
+ *
+ * This is the specification of the CoverageReader base class.
+ * All CoverageReader implementations inherit from this class.
+ */
+ class CoverageReaderBase {
+
+ public:
+
+ /*!<span style="background-color: #FF0000"> </span>
+ * This method constructs a CoverageReaderBase instance.
+ */
+ CoverageReaderBase();
+
+ /*!<span style="background-color: #FF0000"> </span>
+ * This method destructs a CoverageReaderBase instance.
+ */
+ virtual ~CoverageReaderBase();
+
+ /*!
+ * This method processes the coverage information from the input
+ * @a file and adds it to the specified @a executableInformation.
+ *
+ * @param[in] file is the coverage file to process
+ * @param[in] executableInformation is the information for an
+ * associated executable
+ */
+ virtual void processFile(
+ const char* const file,
+ ExecutableInfo* const executableInformation
+ ) = 0;
+ };
+
+}
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/CoverageReaderBase.cc:1.1
--- /dev/null Mon May 24 15:10:04 2010
+++ gcc-testing/covoar/CoverageReaderBase.cc Mon May 24 15:07:07 2010
</font><font color='#997700'>@@ -0,0 +1,23 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file CoverageReaderBase.cc
+ * @brief CoverageReaderBase Implementation
+ *
+ * This file contains the implementation of the CoverageReader base class.
+ * All CoverageReader implementations inherit from this.
+ */
+
+#include "CoverageReaderBase.h"
+
+namespace Coverage {
+
+ CoverageReaderBase::CoverageReaderBase()
+ {
+ }
+
+ CoverageReaderBase::~CoverageReaderBase()
+ {
+ }
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/CoverageReaderQEMU.h:1.1
--- /dev/null Mon May 24 15:10:04 2010
+++ gcc-testing/covoar/CoverageReaderQEMU.h Mon May 24 15:07:07 2010
</font><font color='#997700'>@@ -0,0 +1,50 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file CoverageReaderQEMU.h
+ * @brief CoverageReaderQEMU Specification
+ *
+ * This file contains the specification of the CoverageReaderQEMU class.
+ */
+
+#ifndef __COVERAGE_READER_QEMU_H__
+#define __COVERAGE_READER_QEMU_H__
+
+#include "CoverageReaderBase.h"
+#include "ExecutableInfo.h"
+
+namespace Coverage {
+
+ /*! @class CoverageReaderQEMU
+ *
+ * This class implements the functionality which reads a coverage map
+ * file produced by QEMU. Since the SPARC has 32-bit instructions,
+ * QEMU produces a file with an integer for each 32-bit word. The
+ * integer will have the least significant bit set if the address
+ * was executed. QEMU also supports reporting branch information.
+ * Several bits are set to indicate whether a branch was taken and
+ * NOT taken.
+@verbatim
+TBD
+@endverbatim
+ */
+ class CoverageReaderQEMU : public CoverageReaderBase {
+
+ public:
+
+ /* Inherit documentation from base class. */
+ CoverageReaderQEMU();
+
+ /* Inherit documentation from base class. */
+ virtual ~CoverageReaderQEMU();
+
+ /* Inherit documentation from base class. */
+ void processFile(
+ const char* const file,
+ ExecutableInfo* const executableInformation
+ );
+ };
+
+}
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/CoverageReaderQEMU.cc:1.1
--- /dev/null Mon May 24 15:10:04 2010
+++ gcc-testing/covoar/CoverageReaderQEMU.cc Mon May 24 15:07:07 2010
</font><font color='#997700'>@@ -0,0 +1,158 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file CoverageReaderQEMU.cc
+ * @brief CoverageReaderQEMU Implementation
+ *
+ * This file contains the implementation of the functions supporting
+ * reading the QEMU coverage data files.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#include "app_common.h"
+#include "CoverageReaderQEMU.h"
+#include "CoverageMap.h"
+#include "ExecutableInfo.h"
+
+#include "qemu-traces.h"
+
+/* hack so this can compile on the RH7 RTEMS 4.5 host */
+#if (__GNUC__ <= 2)
+#define OPEN fopen
+#else
+#define OPEN fopen64
+#endif
+
+namespace Coverage {
+
+ CoverageReaderQEMU::CoverageReaderQEMU()
+ {
+ BranchInfoAvailable = true;
+ }
+
+ CoverageReaderQEMU::~CoverageReaderQEMU()
+ {
+ }
+
+ void CoverageReaderQEMU::processFile(
+ const char* const file,
+ ExecutableInfo* const executableInformation
+ )
+ {
+ struct trace_header header;
+ uintptr_t i;
+ int status;
+ FILE* traceFile;
+ uint8_t taken;
+ uint8_t notTaken;
+ uint8_t branchInfo;
+
+ taken = TargetInfo->qemuTakenBit();
+ notTaken = TargetInfo->qemuNotTakenBit();
+ branchInfo = taken | notTaken;
+
+ //
+ // Open the coverage file and read the header.
+ //
+ traceFile = OPEN( file, "r" );
+ if (!traceFile) {
+ fprintf(
+ stderr,
+ "ERROR: CoverageReaderQEMU::processFile - Unable to open %s\n",
+ file
+ );
+ exit( -1 );
+ }
+
+ status = fread( &header, sizeof(trace_header), 1, traceFile );
+ if (status != 1) {
+ fprintf(
+ stderr,
+ "ERROR: CoverageReaderQEMU::processFile - "
+ "Unable to read header from %s\n",
+ file
+ );
+ exit( -1 );
+ }
+
+ #if 0
+ fprintf(
+ stderr,
+ "magic = %s\n"
+ "version = %d\n"
+ "kind = %d\n"
+ "sizeof_target_pc = %d\n"
+ "big_endian = %d\n"
+ "machine = %02x:%02x\n",
+ header.magic,
+ header.version,
+ header.kind,
+ header.sizeof_target_pc,
+ header.big_endian,
+ header.machine[0], header.machine[1]
+ );
+ #endif
+
+ //
+ // Read ENTRIES number of trace entries.
+ //
+#define ENTRIES 1024
+ while (1) {
+ CoverageMapBase *aCoverageMap = NULL;
+ struct trace_entry entries[ENTRIES];
+ struct trace_entry *entry;
+ int num_entries;
+
+
+ // Read and process each line of the coverage file.
+ num_entries = fread(<span style="background-color: #FF0000"> </span>
+ entries,<span style="background-color: #FF0000"> </span>
+ sizeof(struct trace_entry),<span style="background-color: #FF0000"> </span>
+ ENTRIES,<span style="background-color: #FF0000"> </span>
+ traceFile<span style="background-color: #FF0000"> </span>
+ );
+ if (num_entries == 0)
+ break;
+
+ // Get the coverage map for each entry. Note that the map is
+ // the same for each entry in the coverage map
+ for (int count=0; count<num_entries; count++) {
+
+ entry = &entries[count];
+<span style="background-color: #FF0000"> </span>
+ // Mark block as fully executed.
+ // Obtain the coverage map containing the specified address.
+ aCoverageMap = executableInformation->getCoverageMap( entry->pc );
+
+ // Ensure that coverage map exists.
+ if (!aCoverageMap)
+ continue;
+
+ // Set was executed for each TRACE_OP_BLOCK
+ if (entry->op & TRACE_OP_BLOCK) {
+ for (i=0; i<entry->size; i++) {
+ aCoverageMap->setWasExecuted( entry->pc + i );
+ }
+ }
+
+ // Determine if additional branch information is available.
+ if ( (entry->op & branchInfo) != 0 ) {
+ unsigned int a = entry->pc + entry->size - 1;
+ while (!aCoverageMap->isStartOfInstruction(a))
+ a--;
+ if (entry->op & taken) {
+ aCoverageMap->setWasTaken( a );
+ } else if (entry->op & notTaken) {
+ aCoverageMap->setWasNotTaken( a );
+ }
+ }
+ }
+ }
+
+ fclose( traceFile );
+ }
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/CoverageReaderRTEMS.h:1.1
--- /dev/null Mon May 24 15:10:04 2010
+++ gcc-testing/covoar/CoverageReaderRTEMS.h Mon May 24 15:07:07 2010
</font><font color='#997700'>@@ -0,0 +1,48 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file CoverageReaderRTEMS.h
+ * @brief CoverageReaderRTEMS Specification
+ *
+ * This file contains the specification of the CoverageReaderRTEMS class.
+ */
+
+#ifndef __COVERAGE_READER_RTEMS_H__
+#define __COVERAGE_READER_RTEMS_H__
+
+#include "CoverageReaderBase.h"
+#include "ExecutableInfo.h"
+
+namespace Coverage {
+
+ /*! @class CoverageReaderRTEMS
+ *
+ * This class implements the functionality which reads a coverage map
+ * file produced by RTEMS. Since the SPARC has 32-bit instructions,
+ * RTEMS produces a file with an integer for each 32-bit word. The
+ * integer will have the least significant bit set if the address
+ * was executed.
+@verbatim
+TBD
+@endverbatim
+ */
+ class CoverageReaderRTEMS : public CoverageReaderBase {
+
+ public:
+
+ /* Inherit documentation from base class. */
+ CoverageReaderRTEMS();
+
+ /* Inherit documentation from base class. */
+ virtual ~CoverageReaderRTEMS();
+
+ /* Inherit documentation from base class. */
+ void processFile(
+ const char* const file,
+ ExecutableInfo* const executableInformation
+ );
+ };
+
+}
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/CoverageReaderRTEMS.cc:1.1
--- /dev/null Mon May 24 15:10:04 2010
+++ gcc-testing/covoar/CoverageReaderRTEMS.cc Mon May 24 15:07:07 2010
</font><font color='#997700'>@@ -0,0 +1,112 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file CoverageReaderRTEMS.cc
+ * @brief CoverageReaderRTEMS Implementation
+ *
+ * This file contains the implementation of the functions supporting
+ * reading the RTEMS coverage data files.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#include "CoverageReaderRTEMS.h"
+#include "CoverageMap.h"
+#include "ExecutableInfo.h"
+#include "rtemscov_header.h"
+
+namespace Coverage {
+
+ CoverageReaderRTEMS::CoverageReaderRTEMS()
+ {
+ }
+
+ CoverageReaderRTEMS::~CoverageReaderRTEMS()
+ {
+ }
+
+ void CoverageReaderRTEMS::processFile(
+ const char* const file,
+ ExecutableInfo* const executableInformation
+ )
+ {
+ CoverageMapBase* aCoverageMap = NULL;
+ uintptr_t baseAddress;
+ uint8_t cover;
+ FILE* coverageFile;
+ rtems_coverage_map_header_t header;
+ uintptr_t i;
+ uintptr_t length;
+ int status;
+
+ //
+ // Open the coverage file and read the header.
+ //
+ coverageFile = fopen( file, "r" );
+ if (!coverageFile) {
+ fprintf(
+ stderr,
+ "ERROR: CoverageReaderRTEMS::processFile - Unable to open %s\n",
+ file
+ );
+ exit( -1 );
+ }
+
+ status = fread( &header, sizeof(header), 1, coverageFile );
+ if (status != 1) {
+ fprintf(
+ stderr,
+ "ERROR: CoverageReaderRTEMS::processFile - "
+ "Unable to read header from %s\n",
+ file
+ );
+ exit( -1 );
+ }
+
+ baseAddress = header.start;
+ length = header.end - header.start;
+<span style="background-color: #FF0000"> </span>
+ #if 0
+ fprintf(<span style="background-color: #FF0000"> </span>
+ stderr,
+ "%s: 0x%08x 0x%08x 0x%08lx/%ld\n",<span style="background-color: #FF0000"> </span>
+ file,
+ header.start,
+ header.end,
+ (unsigned long) length,
+ (unsigned long) length
+ );
+ #endif
+
+ //
+ // Read and process each line of the coverage file.
+ //
+ for (i=0; i<length; i++) {
+ status = fread( &cover, sizeof(uint8_t), 1, coverageFile );
+ if (status != 1) {
+ fprintf(
+ stderr,
+ "CoverageReaderRTEMS::ProcessFile - breaking after 0x%08x in %s\n",
+ (unsigned int) i,
+ file
+ );
+ break;
+ }
+
+ //
+ // Obtain the coverage map containing the address and
+ // mark the address as executed.
+ //
+ if (cover) {
+ aCoverageMap = executableInformation->getCoverageMap( baseAddress + i );
+ if (aCoverageMap)
+ aCoverageMap->setWasExecuted( baseAddress + i );
+ }
+ }
+
+ fclose( coverageFile );
+ }
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/CoverageReaderSkyeye.h:1.1
--- /dev/null Mon May 24 15:10:04 2010
+++ gcc-testing/covoar/CoverageReaderSkyeye.h Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,48 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file CoverageReaderSkyeye.h
+ * @brief CoverageReaderSkyeye Specification
+ *
+ * This file contains the specification of the CoverageReaderSkyeye class.
+ */
+
+#ifndef __COVERAGE_READER_Skyeye_H__
+#define __COVERAGE_READER_Skyeye_H__
+
+#include "CoverageReaderBase.h"
+#include "ExecutableInfo.h"
+
+namespace Coverage {
+
+ /*! @class CoverageReaderSkyeye
+ *
+ * This class implements the functionality which reads a coverage map
+ * file produced by Skyeye. Since the SPARC has 32-bit instructions,
+ * Skyeye produces a file with an integer for each 32-bit word. The
+ * integer will have the least significant bit set if the address
+ * was executed.
+@verbatim
+TBD
+@endverbatim
+ */
+ class CoverageReaderSkyeye : public CoverageReaderBase {
+
+ public:
+
+ /* Inherit documentation from base class. */
+ CoverageReaderSkyeye();
+
+ /* Inherit documentation from base class. */
+ virtual ~CoverageReaderSkyeye();
+
+ /* Inherit documentation from base class. */
+ void processFile(
+ const char* const file,
+ ExecutableInfo* const executableInformation
+ );
+ };
+
+}
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/CoverageReaderSkyeye.cc:1.1
--- /dev/null Mon May 24 15:10:04 2010
+++ gcc-testing/covoar/CoverageReaderSkyeye.cc Mon May 24 15:07:07 2010
</font><font color='#997700'>@@ -0,0 +1,130 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file CoverageReaderSkyeye.cc
+ * @brief CoverageReaderSkyeye Implementation
+ *
+ * This file contains the implementation of the functions supporting
+ * reading the Skyeye coverage data files.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#include "CoverageReaderSkyeye.h"
+#include "CoverageMap.h"
+#include "ExecutableInfo.h"
+#include "skyeye_header.h"
+
+namespace Coverage {
+
+ CoverageReaderSkyeye::CoverageReaderSkyeye()
+ {
+ }
+
+ CoverageReaderSkyeye::~CoverageReaderSkyeye()
+ {
+ }
+
+ void CoverageReaderSkyeye::processFile(
+ const char* const file,
+ ExecutableInfo* const executableInformation
+ )
+ {
+ CoverageMapBase* aCoverageMap = NULL;
+ uintptr_t baseAddress;
+ uint8_t cover;
+ FILE* coverageFile;
+ prof_header_t header;
+ uintptr_t i;
+ uintptr_t length;
+ int status;
+
+ //
+ // Open the coverage file and read the header.
+ //
+ coverageFile = fopen( file, "r" );
+ if (!coverageFile) {
+ fprintf(
+ stderr,
+ "ERROR: CoverageReaderSkyeye::processFile - Unable to open %s\n",
+ file
+ );
+ exit( -1 );
+ }
+
+ status = fread( &header, sizeof(header), 1, coverageFile );
+ if (status != 1) {
+ fprintf(
+ stderr,
+ "ERROR: CoverageReaderSkyeye::processFile - "
+ "Unable to read header from %s\n",
+ file
+ );
+ exit( -1 );
+ }
+
+ baseAddress = header.prof_start;
+ length = header.prof_end - header.prof_start;
+<span style="background-color: #FF0000"> </span>
+ #if 0
+ fprintf(<span style="background-color: #FF0000"> </span>
+ stderr,
+ "%s: 0x%08x 0x%08x 0x%08lx/%ld\n",<span style="background-color: #FF0000"> </span>
+ file,
+ header.prof_start,
+ header.prof_end,
+ (unsigned long) length,
+ (unsigned long) length
+ );
+ #endif
+
+ //
+ // Read and process each line of the coverage file.
+ //
+ for (i=0; i<length; i+=8) {
+ status = fread( &cover, sizeof(uint8_t), 1, coverageFile );
+ if (status != 1) {
+ fprintf(
+ stderr,
+ "CoverageReaderSkyeye::ProcessFile - breaking after 0x%08x in %s\n",
+ (unsigned int) i,
+ file
+ );
+ break;
+ }
+
+ //
+ // Obtain the coverage map containing the address and
+ // mark the address as executed.
+ //
+ // NOTE: This method ONLY works for Skyeye in 32-bit mode.
+ //
+ if (cover & 0x01) {
+ aCoverageMap = executableInformation->getCoverageMap( baseAddress + i );
+ if (aCoverageMap) {
+ aCoverageMap->setWasExecuted( baseAddress + i );
+ aCoverageMap->setWasExecuted( baseAddress + i + 1 );
+ aCoverageMap->setWasExecuted( baseAddress + i + 2 );
+ aCoverageMap->setWasExecuted( baseAddress + i + 3 );
+ }
+ }
+
+ if (cover & 0x10) {
+ aCoverageMap = executableInformation->getCoverageMap(
+ baseAddress + i + 4
+ );
+ if (aCoverageMap) {
+ aCoverageMap->setWasExecuted( baseAddress + i + 4 );
+ aCoverageMap->setWasExecuted( baseAddress + i + 5 );
+ aCoverageMap->setWasExecuted( baseAddress + i + 6 );
+ aCoverageMap->setWasExecuted( baseAddress + i + 7 );
+ }
+ }
+ }
+
+ fclose( coverageFile );
+ }
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/CoverageReaderTSIM.h:1.1
--- /dev/null Mon May 24 15:10:04 2010
+++ gcc-testing/covoar/CoverageReaderTSIM.h Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,49 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file CoverageReaderTSIM.h
+ * @brief CoverageReaderTSIM Specification
+ *
+ * This file contains the specification of the CoverageReaderTSIM class.
+ */
+
+#ifndef __COVERAGE_READER_TSIM_H__
+#define __COVERAGE_READER_TSIM_H__
+
+#include "CoverageReaderBase.h"
+#include "ExecutableInfo.h"
+
+namespace Coverage {
+
+ /*! @class CoverageReaderTSIM
+ *
+ * This class implements the functionality which reads a coverage map
+ * file produced by TSIM. Since the SPARC has 32-bit instructions,
+ * TSIM produces a file with an integer for each 32-bit word. The
+ * integer will have the least significant bit if the address
+ * was executed.
+@verbatim
+40000000 : 1 0 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 1<span style="background-color: #FF0000"> </span>
+40000080 : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0<span style="background-color: #FF0000"> </span>
+@endverbatim
+ */
+ class CoverageReaderTSIM : public CoverageReaderBase {
+
+ public:
+
+ /* Inherit documentation from base class. */
+ CoverageReaderTSIM();
+
+ /* Inherit documentation from base class. */
+ virtual ~CoverageReaderTSIM();
+
+ /* Inherit documentation from base class. */
+ void processFile(
+ const char* const file,
+ ExecutableInfo* const executableInformation
+ );
+ };
+
+}
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/CoverageReaderTSIM.cc:1.1
--- /dev/null Mon May 24 15:10:04 2010
+++ gcc-testing/covoar/CoverageReaderTSIM.cc Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,96 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file CoverageReaderTSIM.cc
+ * @brief CoverageReaderTSIM Implementation
+ *
+ * This file contains the implementation of the CoverageReader class
+ * for the coverage files written by the SPARC simulator TSIM.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#include "CoverageReaderTSIM.h"
+#include "CoverageMap.h"
+#include "ExecutableInfo.h"
+
+namespace Coverage {
+
+ CoverageReaderTSIM::CoverageReaderTSIM()
+ {
+ }
+
+ CoverageReaderTSIM::~CoverageReaderTSIM()
+ {
+ }
+
+ void CoverageReaderTSIM::processFile(
+ const char* const file,
+ ExecutableInfo* const executableInformation
+ )
+ {
+ CoverageMapBase* aCoverageMap = NULL;
+ int baseAddress;
+ int cover;
+ FILE* coverageFile;
+ int i;
+ int status;
+
+ //
+ // Open the coverage file.
+ //
+ coverageFile = fopen( file, "r" );
+ if (!coverageFile) {
+ fprintf(
+ stderr,
+ "ERROR: CoverageReaderTSIM::processFile - Unable to open %s\n",
+ file
+ );
+ exit( -1 );
+ }
+
+ //
+ // Read and process each line of the coverage file.
+ //
+ while ( 1 ) {
+ status = fscanf( coverageFile, "%x : ", &baseAddress );
+ if (status == EOF || status == 0) {
+ break;
+ }
+
+ for (i=0; i < 0x80; i+=4) {
+ status = fscanf( coverageFile, "%d", &cover );
+ if (status == EOF || status == 0) {
+ fprintf(
+ stderr,
+ "CoverageReaderTSIM: WARNING! Short line in %s at address 0x%08x\n",
+ file,
+ baseAddress
+ );
+ break;
+ }
+
+ //
+ // Obtain the coverage map containing the address and
+ // mark the address as executed.
+ //
+ if (cover & 1) {
+ aCoverageMap = executableInformation->getCoverageMap(
+ baseAddress + i
+ );
+ if (aCoverageMap) {
+ aCoverageMap->setWasExecuted( baseAddress + i );
+ aCoverageMap->setWasExecuted( baseAddress + i + 1 );
+ aCoverageMap->setWasExecuted( baseAddress + i + 2 );
+ aCoverageMap->setWasExecuted( baseAddress + i + 3 );
+ }
+ }
+ }
+ }
+
+ fclose( coverageFile );
+ }
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/CoverageWriterBase.h:1.1
--- /dev/null Mon May 24 15:10:04 2010
+++ gcc-testing/covoar/CoverageWriterBase.h Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,61 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file CoverageWriterBase.h
+ * @brief CoverageWriterBase Specification
+ *
+ * This file contains the specification of the CoverageWriterBase class.
+ */
+
+#ifndef __COVERAGE_WRITER_BASE_H__
+#define __COVERAGE_WRITER_BASE_H__
+
+#include <stdint.h>
+
+#include "CoverageMapBase.h"
+
+namespace Coverage {
+
+ /*! @class CoverageWriterBase
+ *
+ * This is the specification of the CoverageWriter base class.
+ * All CoverageWriter implementations inherit from this class.
+ */
+ class CoverageWriterBase {
+
+ public:
+
+ /*!<span style="background-color: #FF0000"> </span>
+ * This method constructs a CoverageWriterBase instance.
+ */
+ CoverageWriterBase();
+
+ /*!<span style="background-color: #FF0000"> </span>
+ * This method destructs a CoverageWriterBase instance.
+ */
+ virtual ~CoverageWriterBase();
+
+ /*!
+ * This method writes the @a coverage map for the specified
+ * address range and writes it to @file.
+ *
+ * @param[in] file specifies the name of the file to write
+ * @param[in] coverage specifies the coverage map to output
+ * @param[in] lowAddress specifies the lowest address in the
+ * coverage map to process
+ * @param[in] highAddress specifies the highest address in the
+ * coverage map to process
+ *
+ * @return Returns TRUE if the method succeeded and FALSE if it failed.
+ */
+ virtual void writeFile(
+ const char* const file,
+ CoverageMapBase* coverage,
+ uint32_t lowAddress,
+ uint32_t highAddress
+ ) = 0;
+ };
+
+}
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/CoverageWriterBase.cc:1.1
--- /dev/null Mon May 24 15:10:04 2010
+++ gcc-testing/covoar/CoverageWriterBase.cc Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,24 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file CoverageWriterBase.cc
+ * @brief CoverageWriterBase Implementation
+ *
+ * This file contains the implementation of the CoverageWriter base class.
+ * All CoverageWriter implementations inherit from this.
+ */
+
+#include "CoverageWriterBase.h"
+
+namespace Coverage {
+
+ CoverageWriterBase::CoverageWriterBase()
+ {
+ }
+
+ CoverageWriterBase::~CoverageWriterBase()
+ {
+ }
+
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/CoverageWriterRTEMS.h:1.1
--- /dev/null Mon May 24 15:10:05 2010
+++ gcc-testing/covoar/CoverageWriterRTEMS.h Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,48 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file CoverageWriterRTEMS.h
+ * @brief CoverageWriterRTEMS Specification
+ *
+ * This file contains the specification of the CoverageWriterRTEMS class.
+ */
+
+#ifndef __COVERAGE_WRITER_RTEMS_H__
+#define __COVERAGE_WRITER_RTEMS_H__
+
+#include "CoverageMapBase.h"
+#include "CoverageWriterBase.h"
+
+namespace Coverage {
+
+ /*! @class CoverageWriterRTEMS
+ *
+ * This class writes a coverage map in RTEMS format. The format is<span style="background-color: #FF0000"> </span>
+ * documented in CoverageReaderRTEMS.
+ */
+ class CoverageWriterRTEMS : public CoverageWriterBase {
+
+ public:
+
+ /*!<span style="background-color: #FF0000"> </span>
+ * This method constructs a CoverageWriterRTEMS instance.
+ */
+ CoverageWriterRTEMS();
+
+ /*!<span style="background-color: #FF0000"> </span>
+ * This method destructs a CoverageWriterRTEMS instance.
+ */
+ virtual ~CoverageWriterRTEMS();
+
+ /* Inherit documentation from base class. */
+ void writeFile(
+ const char* const file,
+ CoverageMapBase* coverage,
+ uint32_t lowAddress,
+ uint32_t highAddress
+ );
+ };
+
+}
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/CoverageWriterRTEMS.cc:1.1
--- /dev/null Mon May 24 15:10:05 2010
+++ gcc-testing/covoar/CoverageWriterRTEMS.cc Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,92 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file CoverageWriterRTEMS.cc
+ * @brief CoverageWriterRTEMS Implementation
+ *
+ * This file contains the implementation of the functions supporting
+ * the unified overage file format.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "CoverageWriterRTEMS.h"
+#include "rtemscov_header.h"
+
+namespace Coverage {
+<span style="background-color: #FF0000"> </span>
+ CoverageWriterRTEMS::CoverageWriterRTEMS()
+ {
+ }
+
+ CoverageWriterRTEMS::~CoverageWriterRTEMS()
+ {
+ }
+
+ void CoverageWriterRTEMS::writeFile(
+ const char* const file,
+ CoverageMapBase* coverage,
+ uint32_t lowAddress,
+ uint32_t highAddress
+ )
+ {
+ FILE* coverageFile;
+ uint32_t a;
+ int status;
+ uint8_t cover;
+ rtems_coverage_map_header_t header;
+
+ /*
+ * read the file and update the coverage map passed in
+ */
+ coverageFile = fopen( file, "w" );
+ if ( !coverageFile ) {
+ fprintf(
+ stderr,
+ "ERROR: CoverageWriterRTEMS::writeFile - unable to open %s\n",
+ file
+ );
+ exit(-1);
+ }
+
+ /* clear out the header and fill it in */
+ memset( &header, 0, sizeof(header) );
+ header.ver = 0x1;
+ header.header_length = sizeof(header);
+ header.start = lowAddress;
+ header.end = highAddress;
+ strcpy( header.desc, "RTEMS Coverage Data" );
+
+ status = fwrite(&header, 1, sizeof(header), coverageFile);
+ if (status != sizeof(header)) {
+ fprintf(
+ stderr,
+ "ERROR: CoverageWriterRTEMS::writeFile - unable to write header "
+ "to %s\n",
+ file
+ );
+ exit(-1);
+ }
+
+ for ( a=lowAddress ; a < highAddress ; a++ ) {
+ cover = ((coverage->wasExecuted( a )) ? 0x01 : 0);
+ status = fwrite(&cover, 1, sizeof(cover), coverageFile);
+ if (status != sizeof(cover)) {
+ fprintf(
+ stderr,
+ "ERROR: CoverageWriterRTEMS::writeFile - write to %s "
+ "at address 0x%08x failed\n",
+ file,
+ a
+ );
+ exit( -1 );
+ }
+ // fprintf( stderr, "0x%x %d\n", a, cover );
+ }
+
+ fclose( coverageFile );
+ }
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/CoverageWriterSkyeye.h:1.1
--- /dev/null Mon May 24 15:10:05 2010
+++ gcc-testing/covoar/CoverageWriterSkyeye.h Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,48 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file CoverageWriterSkyeye.h
+ * @brief CoverageWriterSkyeye Specification
+ *
+ * This file contains the specification of the CoverageWriterSkyeye class.
+ */
+
+#ifndef __COVERAGE_WRITER_Skyeye_H__
+#define __COVERAGE_WRITER_Skyeye_H__
+
+#include "CoverageMapBase.h"
+#include "CoverageWriterBase.h"
+
+namespace Coverage {
+
+ /*! @class CoverageWriterSkyeye
+ *
+ * This class writes a coverage map in Skyeye format. The format is<span style="background-color: #FF0000"> </span>
+ * documented in CoverageReaderSkyeye.
+ */
+ class CoverageWriterSkyeye : public CoverageWriterBase {
+
+ public:
+
+ /*!<span style="background-color: #FF0000"> </span>
+ * This method constructs a CoverageWriterSkyeye instance.
+ */
+ CoverageWriterSkyeye();
+
+ /*!<span style="background-color: #FF0000"> </span>
+ * This method destructs a CoverageWriterSkyeye instance.
+ */
+ virtual ~CoverageWriterSkyeye();
+
+ /* Inherit documentation from base class. */
+ void writeFile(
+ const char* const file,
+ CoverageMapBase* coverage,
+ uint32_t lowAddress,
+ uint32_t highAddress
+ );
+ };
+
+}
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/CoverageWriterSkyeye.cc:1.1
--- /dev/null Mon May 24 15:10:05 2010
+++ gcc-testing/covoar/CoverageWriterSkyeye.cc Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,94 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file CoverageWriterSkyeye.cc
+ * @brief CoverageWriterSkyeye Implementation
+ *
+ * This file contains the implementation of the CoverageWriter class
+ * for the coverage files written by the multi-architecture simulator
+ * Skyeye (http://www.skyeye.org).
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "CoverageWriterSkyeye.h"
+#include "skyeye_header.h"
+
+namespace Coverage {
+<span style="background-color: #FF0000"> </span>
+ CoverageWriterSkyeye::CoverageWriterSkyeye()
+ {
+ }
+
+ CoverageWriterSkyeye::~CoverageWriterSkyeye()
+ {
+ }
+
+ void CoverageWriterSkyeye::writeFile(
+ const char* const file,
+ CoverageMapBase* coverage,
+ uint32_t lowAddress,
+ uint32_t highAddress
+ )
+ {
+ uint32_t a;
+ uint8_t cover;
+ FILE* coverageFile;
+ prof_header_t header;
+ int status;
+
+ /*
+ * read the file and update the coverage map passed in
+ */
+ coverageFile = fopen( file, "w" );
+ if ( !coverageFile ) {
+ fprintf(
+ stderr,
+ "ERROR: CoverageWriterSkyeye::writeFile - unable to open %s\n",
+ file
+ );
+ exit(-1);
+ }
+
+ /* clear out the header and fill it in */
+ memset( &header, 0, sizeof(header) );
+ header.ver = 0x1;
+ header.header_length = sizeof(header);
+ header.prof_start = lowAddress;
+ header.prof_end = highAddress;
+ strcpy( header.desc, "Skyeye Coverage Data" );
+
+ status = fwrite(&header, 1, sizeof(header), coverageFile);
+ if (status != sizeof(header)) {
+ fprintf(
+ stderr,
+ "ERROR: CoverageWriterSkyeye::writeFile - unable to write header "
+ "to %s\n",
+ file
+ );
+ exit(-1);
+ }
+
+ for ( a=lowAddress ; a < highAddress ; a+= 8 ) {
+ cover = ((coverage->wasExecuted( a )) ? 0x01 : 0);
+ cover |= ((coverage->wasExecuted( a + 4 )) ? 0x10 : 0);
+ status = fwrite(&cover, 1, sizeof(cover), coverageFile);
+ if (status != sizeof(cover)) {
+ fprintf(
+ stderr,
+ "ERROR: CoverageWriterSkyeye::writeFile - write to %s "
+ "at address 0x%08x failed\n",
+ file,
+ a
+ );
+ exit( -1 );
+ }
+ // fprintf( stderr, "0x%x %d\n", a, cover );
+ }
+
+ fclose( coverageFile );
+ }
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/CoverageWriterTSIM.h:1.1
--- /dev/null Mon May 24 15:10:05 2010
+++ gcc-testing/covoar/CoverageWriterTSIM.h Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,48 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file CoverageWriterTSIM.h
+ * @brief CoverageWriterTSIM Specification
+ *
+ * This file contains the specification of the CoverageWriterTSIM class.
+ */
+
+#ifndef __COVERAGE_WRITER_TSIM_H__
+#define __COVERAGE_WRITER_TSIM_H__
+
+#include "CoverageMapBase.h"
+#include "CoverageWriterBase.h"
+
+namespace Coverage {
+
+ /*! @class CoverageWriterTSIM
+ *
+ * This class writes a coverage map in TSIM format. The format is<span style="background-color: #FF0000"> </span>
+ * documented in CoverageReaderTSIM.
+ */
+ class CoverageWriterTSIM : public CoverageWriterBase {
+
+ public:
+
+ /*!<span style="background-color: #FF0000"> </span>
+ * This method constructs a CoverageWriterTSIM instance.
+ */
+ CoverageWriterTSIM();
+
+ /*!<span style="background-color: #FF0000"> </span>
+ * This method destructs a CoverageWriterTSIM instance.
+ */
+ virtual ~CoverageWriterTSIM();
+
+ /* Inherit documentation from base class. */
+ void writeFile(
+ const char* const file,
+ CoverageMapBase* coverage,
+ uint32_t lowAddress,
+ uint32_t highAddress
+ );
+ };
+
+}
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/CoverageWriterTSIM.cc:1.1
--- /dev/null Mon May 24 15:10:05 2010
+++ gcc-testing/covoar/CoverageWriterTSIM.cc Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,82 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file CoverageWriterTSIM.cc
+ * @brief CoverageWriterTSIM Implementation
+ *
+ * This file contains the implementation of the CoverageWriter class
+ * for the coverage files written by the SPARC simulator TSIM.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "CoverageWriterTSIM.h"
+
+namespace Coverage {
+<span style="background-color: #FF0000"> </span>
+ CoverageWriterTSIM::CoverageWriterTSIM()
+ {
+ }
+
+ CoverageWriterTSIM::~CoverageWriterTSIM()
+ {
+ }
+
+<span style="background-color: #FF0000"> </span>
+ void CoverageWriterTSIM::writeFile(
+ const char* const file,
+ CoverageMapBase* coverage,
+ uint32_t lowAddress,
+ uint32_t highAddress
+ )
+ {
+ uint32_t a;
+ int cover;
+ FILE* coverageFile;
+ int i;
+ int status;
+
+ /*
+ * read the file and update the coverage map passed in
+ */
+ coverageFile = fopen( file, "w" );
+ if ( !coverageFile ) {
+ fprintf(
+ stderr,
+ "ERROR: CoverageWriterTSIM::writeFile - unable to open %s\n",
+ file
+ );
+ exit(-1);
+ }
+
+ for ( a=lowAddress ; a < highAddress ; a+= 0x80 ) {
+ status = fprintf( coverageFile, "%x : ", a );
+ if ( status == EOF || status == 0 ) {
+ break;
+ }
+ // fprintf( stderr, "%08x : ", baseAddress );
+ for ( i=0 ; i < 0x80 ; i+=4 ) {
+ cover = ((coverage->wasExecuted( a + i )) ? 1 : 0);
+ status = fprintf( coverageFile, "%d ", cover );
+ if ( status == EOF || status == 0 ) {
+ fprintf(
+ stderr,
+ "ERROR: CoverageWriterTSIM:writeFile - write to %s "
+ "at address 0x%08x failed\n",
+ file,
+ a
+ );
+ exit( -1 );
+ }
+ // fprintf( stderr, "%d ", cover );
+ }
+ fprintf( coverageFile, "\n" );
+ // fprintf( stderr, "\n" );
+<span style="background-color: #FF0000"> </span>
+ }
+
+ fclose( coverageFile );
+ }
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/DesiredSymbols.h:1.1
--- /dev/null Mon May 24 15:10:05 2010
+++ gcc-testing/covoar/DesiredSymbols.h Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,340 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file DesiredSymbols.h
+ * @brief DesiredSymbols Specification
+ *
+ * This file contains the specification of the DesiredSymbols class.
+ */
+
+#ifndef __DESIRED_SYMBOLS_H__
+#define __DESIRED_SYMBOLS_H__
+
+#include <list>
+#include <map>
+#include <stdint.h>
+#include <string>
+
+#include "CoverageMapBase.h"
+#include "CoverageRanges.h"
+#include "ExecutableInfo.h"
+#include "ObjdumpProcessor.h"
+
+namespace Coverage {
+
+
+ /*!<span style="background-color: #FF0000"> </span>
+ *<span style="background-color: #FF0000"> </span>
+ * This class defines the statistics that are tracked.
+ */
+ class Statistics {
+ public:
+
+ /*!
+ * This member variable contains the total number of branches always
+ * taken.
+ */
+ int branchesAlwaysTaken;
+
+ /*!
+ * This member variable contains the total number of branches where<span style="background-color: #FF0000"> </span>
+ * one or more paths were executed.
+ */
+ int branchesExecuted;
+
+ /*!
+ * This member variable contains the total number of branches never
+ * taken.
+ */
+ int branchesNeverTaken;
+
+ /*!
+ * This member variable contains the total number of branches not
+ * executed AT ALL.
+ */
+ int branchesNotExecuted;
+
+ /*!
+ * This member contains the size in Bytes.
+ */
+ uint32_t sizeInBytes;
+<span style="background-color: #FF0000"> </span>
+ /*!
+ * This member contains the size in Bytes.
+ */
+ uint32_t sizeInInstructions;
+
+ /*!
+ * This member variable contains the total number of uncovered bytes.
+ */
+ int uncoveredBytes;
+
+ /*!
+ * This member variable contains the total number of uncovered assembly
+ * instructions.
+ */
+ int uncoveredInstructions;
+
+ /*!
+ * This member variable contains the total number of uncovered ranges.
+ */
+ int uncoveredRanges;
+
+ /*!
+ * This method returns the percentage of uncovered instructions.
+ *
+ * @return Returns the percent uncovered instructions
+ */
+ uint32_t getPercentUncoveredInstructions( void ) const;
+
+ /*!
+ * This method returns the percentage of uncovered bytes.
+ *
+ * @return Returns the percent uncovered bytes
+ */
+ uint32_t getPercentUncoveredBytes( void ) const;
+
+ /*!
+ * This method constructs a Statistics instance.
+ */<span style="background-color: #FF0000"> </span>
+ Statistics():
+ branchesAlwaysTaken(0),
+ branchesExecuted(0),
+ branchesNeverTaken(0),
+ branchesNotExecuted(0),
+ sizeInBytes(0),
+ sizeInInstructions(0),
+ uncoveredBytes(0),
+ uncoveredInstructions(0),
+ uncoveredRanges(0)
+ {
+ }
+
+ };
+
+ /*! @class SymbolInformation
+ *
+ * This class defines the information kept for each symbol that is
+ * to be analyzed.
+ */
+ class SymbolInformation {
+
+ public:
+
+ /*!
+ * This member contains the base address of the symbol.
+ */
+ uint32_t baseAddress;
+
+
+ /*!
+ * This member contains the disassembly associated with a symbol.
+ */
+ std::list<ObjdumpProcessor::objdumpLine_t> instructions;
+
+ /*!
+ * This member contains the executable that was used to
+ * generate the disassembled instructions.
+ */
+ ExecutableInfo* sourceFile;
+
+ /*!
+ * This member contains the statistics kept on each symbol.
+ */<span style="background-color: #FF0000"> </span>
+ Statistics stats;
+
+ /*!
+ * This member contains information about the branch instructions of
+ * a symbol that were not fully covered (i.e. taken/not taken).
+ */
+ CoverageRanges* uncoveredBranches;
+
+ /*!
+ * This member contains information about the instructions of a
+ * symbol that were not executed.
+ */
+ CoverageRanges* uncoveredRanges;
+
+ /*!
+ * This member contains the unified or merged coverage map
+ * for the symbol.
+ */
+ CoverageMapBase* unifiedCoverageMap;
+
+ /*!
+ * This method constructs a SymbolInformation instance.
+ */
+ SymbolInformation() :
+ baseAddress( 0 ),
+ uncoveredBranches( NULL ),
+ uncoveredRanges( NULL ),
+ unifiedCoverageMap( NULL )
+ {
+ }
+
+ ~SymbolInformation() {}
+ };
+
+ /*! @class DesiredSymbols
+ *
+ * This class defines the set of desired symbols to analyze.
+ */
+ class DesiredSymbols {
+
+ public:
+
+ /*!
+ * This map associates each symbol with its symbol information.
+ */
+ typedef std::map<std::string, SymbolInformation> symbolSet_t;
+
+ /*!
+ * This variable contains a map of ymbol sets for each<span style="background-color: #FF0000"> </span>
+ * symbol in the system keyed on the symbol name.
+ */
+ symbolSet_t set;
+
+ /*!<span style="background-color: #FF0000"> </span>
+ * This method constructs a DesiredSymbols instance.
+ */
+ DesiredSymbols();
+
+ /*!<span style="background-color: #FF0000"> </span>
+ * This method destructs a DesiredSymbols instance.
+ */
+ ~DesiredSymbols();
+
+ /*!
+ * This method loops through the coverage map and
+ * calculates the statistics that have not already<span style="background-color: #FF0000"> </span>
+ * been filled in.
+ */
+ void caculateStatistics( void );
+
+ /*!
+ * This method analyzes each symbols coverage map to determine any
+ * uncovered ranges or branches.
+ */
+ void computeUncovered( void );
+
+ /*!
+ * This method creates a coverage map for the specified symbol
+ * using the specified size.
+ *
+ * @param[in] symbolName specifies the symbol for which to create
+ * a coverage map
+ * @param[in] size specifies the size of the coverage map to create
+ */
+ void createCoverageMap(
+ const std::string& symbolName,
+ uint32_t size
+ );
+
+ /*!
+ * This method looks up the symbol information for the specified symbol.
+ *
+ * @param[in] symbolName specifies the symbol for which to search
+ *
+ * @return Returns a pointer to the symbol's information
+ */
+ SymbolInformation* find(
+ const std::string& symbolName
+ );
+
+ /*!
+ * This method determines the source lines that correspond to any
+ * uncovered ranges or branches.
+ */
+ void findSourceForUncovered( void );
+
+ /*!
+ * This method returns the total number of branches always taken
+ * for all analyzed symbols.
+ *
+ * @return Returns the total number of branches always taken
+ */
+ uint32_t getNumberBranchesAlwaysTaken( void ) const;
+
+ /*!
+ * This method returns the total number of branches found for
+ * all analyzed symbols.
+ *
+ * @return Returns the total number of branches found
+ */
+ uint32_t getNumberBranchesFound( void ) const;
+
+ /*!
+ * This method returns the total number of branches never taken
+ * for all analyzed symbols.
+ *
+ * @return Returns the total number of branches never taken
+ */
+ uint32_t getNumberBranchesNeverTaken( void ) const;
+
+ /*!
+ * This method returns the total number of uncovered ranges
+ * for all analyzed symbols.
+ *
+ * @return Returns the total number of uncovered ranges
+ */
+ uint32_t getNumberUncoveredRanges( void ) const;
+
+ /*!
+ * This method returns an indication of whether or not the specified
+ * symbol is a symbol to analyze.
+ *
+ * @return Returns TRUE if the specified symbol is a symbol to analyze
+ * and FALSE otherwise.
+ */
+ bool isDesired (
+ const std::string& symbolName
+ ) const;
+
+ /*!
+ * This method creates the set of symbols to analyze from the symbols
+ * listed in the specified file.
+ */
+ void load(
+ const char* const symbolsFile
+ );
+
+ /*!
+ * This method merges the coverage information from the source
+ * coverage map into the unified coverage map for the specified symbol.
+ *
+ * @param[in] symbolName specifies the symbol associated with the
+ * destination coverage map
+ * @param[in] sourceCoverageMap specifies the source coverage map
+ */
+ void mergeCoverageMap(
+ const std::string& symbolName,
+ const CoverageMapBase* const sourceCoverageMap
+ );
+
+ /*!
+ * This method preprocesses each symbol's coverage map to mark nop
+ * and branch information.
+ */
+ void preprocess( void );
+
+ /*!
+ * This member contains the statistics kept on each symbol.
+ */<span style="background-color: #FF0000"> </span>
+ Statistics stats;
+
+ private:
+
+ /*!
+ * This method uses the specified executable file to determine the
+ * source lines for the elements in the specified ranges.
+ */
+ void determineSourceLines(
+ CoverageRanges* const theRanges,
+ ExecutableInfo* const theExecutable
+ );
+
+ };
+}
+
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/DesiredSymbols.cc:1.1
--- /dev/null Mon May 24 15:10:05 2010
+++ gcc-testing/covoar/DesiredSymbols.cc Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,656 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file DesiredSymbols.cc
+ * @brief DesiredSymbols Implementation
+ *
+ * This file contains the implementation of the functions<span style="background-color: #FF0000"> </span>
+ * which provide the functionality of the DesiredSymbols.
+ */
+
+#include <libgen.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "DesiredSymbols.h"
+#include "app_common.h"
+#include "CoverageMap.h"
+#include "ObjdumpProcessor.h"
+
+namespace Coverage {
+
+ DesiredSymbols::DesiredSymbols()
+ {
+ }
+
+ DesiredSymbols::~DesiredSymbols()
+ {
+ }
+
+ void DesiredSymbols::load(
+ const char* const symbolsFile
+ )
+ {
+ #define MAX_LINE_LENGTH 512
+ char buffer[MAX_LINE_LENGTH];
+ char* cStatus;
+ bool done = false;
+ FILE* sFile;
+ SymbolInformation* symInfo;
+ int line = 1;
+ std::string symbol;
+
+ // Ensure that symbols file name is given.
+ if ( !symbolsFile ) {
+ fprintf(
+ stderr,
+ "ERROR: DesiredSymbols::load - no symbols file specified\n"
+ );
+ exit(-1);
+ }
+
+ // Open symbols file.
+ sFile = fopen( symbolsFile, "r" );
+ if ( !sFile ) {
+ fprintf(
+ stderr,
+ "ERROR: DesiredSymbols::load - unable to open symbols file %s\n",
+ symbolsFile
+ );
+ exit(-1);
+ }
+
+ // Process symbols file.
+ while ( !done ) {
+
+ symInfo = new SymbolInformation;
+
+ // Skip blank lines between symbols
+ do {<span style="background-color: #FF0000"> </span>
+ buffer[0] = '\0';
+ cStatus = fgets( buffer, MAX_LINE_LENGTH, sFile );
+ if ( cStatus == NULL ) {
+ done = true;
+ }
+ else {
+ buffer[ strlen(buffer) - 1] = '\0';
+ line++;
+ }
+ } while ( !done && (buffer[0] == '\0') );
+
+ // Have we already seen this one?
+ if ( !done ) {
+ if (set.find( buffer ) != set.end()) {
+ fprintf(
+ stderr,
+ "File: %s, Line %d: Duplicate symbol: %s\n",
+ symbolsFile,
+ line,
+ buffer
+ );
+ }
+
+ // Add this to the set of symbols.
+ else {
+ set[ buffer ] = *symInfo;
+ }
+ }
+ }
+ #undef MAX_LINE_LENGTH
+ }
+
+ void DesiredSymbols::preprocess( void )
+ {
+ ObjdumpProcessor::objdumpLines_t::iterator fitr;
+ DesiredSymbols::symbolSet_t::iterator sitr;
+ CoverageMapBase* theCoverageMap;
+
+ // Look at each symbol.
+ for (sitr = SymbolsToAnalyze->set.begin();
+ sitr != SymbolsToAnalyze->set.end();
+ sitr++) {
+
+ // If the unified coverage map does not exist, the symbol was
+ // never referenced by any executable. Just skip it.
+ theCoverageMap = sitr->second.unifiedCoverageMap;
+ if (!theCoverageMap)
+ continue;
+
+ // Mark any branch instructions.
+ for (fitr = sitr->second.instructions.begin();
+ fitr != sitr->second.instructions.end();
+ fitr++) {
+ if (fitr->isBranch) {
+ theCoverageMap->setIsBranch(
+ fitr->address - sitr->second.baseAddress
+ );
+ }
+ }
+ }
+ }
+
+ void DesiredSymbols::caculateStatistics( void )
+ {
+ uint32_t a;
+ uint32_t endAddress;
+ DesiredSymbols::symbolSet_t::iterator sitr;
+ CoverageMapBase* theCoverageMap;
+
+ // Look at each symbol.
+ for (sitr = SymbolsToAnalyze->set.begin();
+ sitr != SymbolsToAnalyze->set.end();
+ sitr++) {
+
+ // If the unified coverage map does not exist, the symbol was
+ // never referenced by any executable. Just skip it.
+ theCoverageMap = sitr->second.unifiedCoverageMap;
+ if (!theCoverageMap)
+ continue;
+
+ // Increment the total sizeInBytes byt the bytes in the symbol
+ stats.sizeInBytes += sitr->second.stats.sizeInBytes;
+
+ // Now scan through the coverage map of this symbol.
+ endAddress = sitr->second.stats.sizeInBytes - 1;
+ a = 0;
+ while (a <= endAddress) {
+
+ // If we are at the start of instruction increment
+ // instruction type counters as needed.<span style="background-color: #FF0000"> </span>
+ if ( theCoverageMap->isStartOfInstruction( a ) ) {
+
+ stats.sizeInInstructions++;
+ sitr->second.stats.sizeInInstructions++;
+
+ if (!theCoverageMap->wasExecuted( a ) ) {
+ stats.uncoveredInstructions++;
+ sitr->second.stats.uncoveredInstructions++;
+
+ if ( theCoverageMap->isBranch( a )) {
+ stats.branchesNotExecuted++;
+ sitr->second.stats.branchesNotExecuted++;
+ }
+ } else if (theCoverageMap->isBranch( a )) {
+ stats.branchesExecuted++;
+ sitr->second.stats.branchesExecuted++;
+ }
+<span style="background-color: #FF0000"> </span>
+ }
+
+<span style="background-color: #FF0000"> </span>
+ if (!theCoverageMap->wasExecuted( a )) {
+ stats.uncoveredBytes++;
+ sitr->second.stats.uncoveredBytes++;
+ }<span style="background-color: #FF0000"> </span>
+ a++;
+
+ }
+ }
+ }
+
+
+ void DesiredSymbols::computeUncovered( void )
+ {
+ uint32_t a, la, ha;
+ uint32_t endAddress;
+ uint32_t count;
+ DesiredSymbols::symbolSet_t::iterator sitr;
+ CoverageRanges* theBranches;
+ CoverageMapBase* theCoverageMap;
+ CoverageRanges* theRanges;
+
+ // Look at each symbol.
+ for (sitr = SymbolsToAnalyze->set.begin();
+ sitr != SymbolsToAnalyze->set.end();
+ sitr++) {
+
+ // If the unified coverage map does not exist, the symbol was
+ // never referenced by any executable. Just skip it.
+ theCoverageMap = sitr->second.unifiedCoverageMap;
+ if (!theCoverageMap)
+ continue;
+
+ // Create containers for the symbol's uncovered ranges and branches.
+ theRanges = new CoverageRanges();
+ sitr->second.uncoveredRanges = theRanges;
+ theBranches = new CoverageRanges();
+ sitr->second.uncoveredBranches = theBranches;
+
+ // Now scan through the coverage map of this symbol.
+ endAddress = sitr->second.stats.sizeInBytes - 1;
+ a = 0;
+ while (a <= endAddress) {
+<span style="background-color: #FF0000"> </span>
+ // If an address was NOT executed, find consecutive unexecuted
+ // addresses and add them to the uncovered ranges.
+ if (!theCoverageMap->wasExecuted( a )) {
+
+ la = a;
+ count = 1;
+ for (ha=a+1;
+ ha<=endAddress && !theCoverageMap->wasExecuted( ha );
+ ha++)
+ {
+ if ( theCoverageMap->isStartOfInstruction( ha ) )
+ count++;
+ }
+ ha--;
+
+ stats.uncoveredRanges++;
+ sitr->second.stats.uncoveredRanges++;
+ theRanges->add(
+ sitr->second.baseAddress + la,
+ sitr->second.baseAddress + ha,
+ CoverageRanges::UNCOVERED_REASON_NOT_EXECUTED,
+ count
+ );
+ a = ha + 1;
+ }
+
+ // If an address is a branch instruction, add any uncovered branches
+ // to the uncoverd branches.
+ else if (theCoverageMap->isBranch( a )) {
+ la = a;
+ for (ha=a+1;
+ ha<=endAddress && !theCoverageMap->isStartOfInstruction( ha );
+ ha++)
+ ;
+ ha--;
+
+ if (theCoverageMap->wasAlwaysTaken( la )) {
+ stats.branchesAlwaysTaken++;
+ sitr->second.stats.branchesAlwaysTaken++;
+ theBranches->add(
+ sitr->second.baseAddress + la,
+ sitr->second.baseAddress + ha,
+ CoverageRanges::UNCOVERED_REASON_BRANCH_ALWAYS_TAKEN,
+ 1
+ );
+ if (Verbose)
+ fprintf(
+ stderr,
+ "Branch always taken found in %s (0x%x - 0x%x)\n",
+ (sitr->first).c_str(),
+ sitr->second.baseAddress + la,
+ sitr->second.baseAddress + ha
+ );
+ }
+
+ else if (theCoverageMap->wasNeverTaken( la )) {
+ stats.branchesNeverTaken++;
+ sitr->second.stats.branchesNeverTaken++;
+ theBranches->add(
+ sitr->second.baseAddress + la,
+ sitr->second.baseAddress + ha,
+ CoverageRanges::UNCOVERED_REASON_BRANCH_NEVER_TAKEN,
+ 1
+ );
+ if (Verbose)
+ fprintf(
+ stderr,
+ "Branch never taken found in %s (0x%x - 0x%x)\n",
+ (sitr->first).c_str(),
+ sitr->second.baseAddress + la,
+ sitr->second.baseAddress + ha
+ );
+ }
+ a = ha + 1;
+ }
+ else
+ a++;
+ }
+ }
+ }
+
+
+ void DesiredSymbols::createCoverageMap(
+ const std::string& symbolName,
+ uint32_t size
+ )
+ {
+ CoverageMapBase* aCoverageMap;
+ uint32_t highAddress;
+ symbolSet_t::iterator itr;
+
+ // Ensure that the symbol is a desired symbol.
+ itr = set.find( symbolName );
+
+ if (itr == set.end()) {
+
+ fprintf(
+ stderr,
+ "ERROR: DesiredSymbols::createCoverageMap - Unable to create "
+ "unified coverage map for %s because it is NOT a desired symbol\n",
+ symbolName.c_str()
+ );
+ exit( -1 );
+ }
+
+ // If we have already created a coverage map, ...
+ if (itr->second.unifiedCoverageMap) {
+
+ // ensure that the specified size matches the existing size.
+ if (itr->second.stats.sizeInBytes != size) {
+
+ fprintf(
+ stderr,
+ "ERROR: DesiredSymbols::createCoverageMap - Attempt to create "
+ "unified coverage maps for %s with different sizes\n",
+ symbolName.c_str()
+ );
+ exit( -1 );
+ }
+ }
+
+ // If we don't already have a coverage map, create one.
+ else {
+
+ highAddress = size - 1;
+
+ aCoverageMap = new CoverageMap( 0, highAddress );
+ if (!aCoverageMap) {
+
+ fprintf(
+ stderr,
+ "ERROR: DesiredSymbols::createCoverageMap - Unable to allocate "
+ "coverage map for %s\n",
+ symbolName.c_str()
+ );
+ exit( -1 );
+ }
+
+ if ( Verbose )
+ fprintf(
+ stderr,
+ "Created unified coverage map for %s (0x%x - 0x%x)\n",
+ symbolName.c_str(), 0, highAddress
+ );
+ itr->second.unifiedCoverageMap = aCoverageMap;
+ itr->second.stats.sizeInBytes = size;
+ }
+ }
+
+ void DesiredSymbols::determineSourceLines(
+ CoverageRanges* const theRanges,
+ ExecutableInfo* const theExecutable
+
+ )
+ {
+ char* base;
+ char buffer[512];
+ char* cStatus;
+ char command[512];
+ std::string fileName;
+ CoverageRanges::ranges_t::iterator ritr;
+ char rpath[PATH_MAX];
+ FILE* tmpfile;
+
+ // Open a temporary file for the uncovered ranges.
+ tmpfile = fopen( "ranges1.tmp", "w" );
+ if ( !tmpfile ) {
+ fprintf(
+ stderr,
+ "ERROR: DesiredSymbols::determineSourceLines - "
+ "unable to open %s\n",
+ "ranges1.tmp"
+ );
+ exit(-1);
+ }
+
+ // Write the range addresses to the temporary file.
+ for (ritr = theRanges->set.begin();
+ ritr != theRanges->set.end();
+ ritr++ ) {
+ fprintf(
+ tmpfile,
+ "0x%08x\n0x%08x\n",
+ ritr->lowAddress - theExecutable->getLoadAddress(),
+ ritr->highAddress - theExecutable->getLoadAddress()
+ );
+ }
+
+ fclose( tmpfile );
+
+ // Invoke addr2line to generate the source lines for each address.
+ if (theExecutable->hasDynamicLibrary())
+ fileName = theExecutable->getLibraryName();
+ else
+ fileName = theExecutable->getFileName();
+
+ sprintf(
+ command,
+ "%s -e %s <%s | dos2unix >%s",
+ TargetInfo->getAddr2line(),
+ fileName.c_str(),
+ "ranges1.tmp",
+ "ranges2.tmp"
+ );
+ if (system( command )) {
+ fprintf(
+ stderr,
+ "ERROR: DesiredSymbols::determineSourceLines - "
+ "command (%s) failed\n",
+ command
+ );
+ exit( -1 );
+ }
+
+ // Open the addr2line output file.
+ tmpfile = fopen( "ranges2.tmp", "r" );
+ if ( !tmpfile ) {
+ fprintf(
+ stderr,
+ "ERROR: DesiredSymbols::determineSourceLines - "
+ "unable to open %s\n",
+ "ranges2.tmp"
+ );
+ exit(-1);
+ }
+
+ // Process the addr2line output.
+ for (ritr = theRanges->set.begin();
+ ritr != theRanges->set.end();
+ ritr++ ) {
+
+ cStatus = fgets( buffer, 512, tmpfile );
+ if ( cStatus == NULL ) {
+ fprintf(
+ stderr,
+ "ERROR: DesiredSymbols::determineSourceLines - "
+ "Out of sync in addr2line output\n"
+ );
+ exit( -1 );
+ }
+ buffer[ strlen(buffer) - 1] = '\0';
+
+ // Use only the base filename without directory path.
+ realpath( buffer, rpath );
+ base = basename( rpath );
+
+ ritr->lowSourceLine = std::string( base );
+
+ cStatus = fgets( buffer, 512, tmpfile );
+ if ( cStatus == NULL ) {
+ fprintf(
+ stderr,
+ "ERROR: DesiredSymbols::determineSourceLines - "
+ "Out of sync in addr2line output\n"
+ );
+ exit( -1 );
+ }
+ buffer[ strlen(buffer) - 1] = '\0';
+
+ // Use only the base filename without directory path.
+ realpath( buffer, rpath );
+ base = basename( rpath );
+
+ ritr->highSourceLine = std::string( base );
+ }
+
+ fclose( tmpfile );
+ unlink( "ranges1.tmp" );
+ unlink( "ranges2.tmp" );
+ }
+
+ SymbolInformation* DesiredSymbols::find(
+ const std::string& symbolName
+ )
+ {
+ if (set.find( symbolName ) == set.end())
+ return NULL;
+ else
+ return &set[ symbolName ];
+ }
+
+ void DesiredSymbols::findSourceForUncovered( void )
+ {
+ DesiredSymbols::symbolSet_t::iterator ditr;
+ CoverageRanges* theBranches;
+ CoverageRanges* theRanges;
+
+ // Process uncovered ranges and/or branches for each symbol.
+ for (ditr = SymbolsToAnalyze->set.begin();
+ ditr != SymbolsToAnalyze->set.end();
+ ditr++) {
+
+ // First the unexecuted ranges, ...
+ theRanges = ditr->second.uncoveredRanges;
+ if (theRanges == NULL)
+ continue;
+
+ if (!theRanges->set.empty()) {
+ if (Verbose)
+ fprintf(
+ stderr,
+ "Looking up source lines for uncovered ranges in %s\n",
+ (ditr->first).c_str()
+ );
+ determineSourceLines(
+ theRanges,
+ ditr->second.sourceFile
+ );
+ }
+
+ // then the uncovered branches.
+ theBranches = ditr->second.uncoveredBranches;
+ if (theBranches == NULL)
+ continue;
+
+ if (!theBranches->set.empty()) {
+ if (Verbose)
+ fprintf(
+ stderr,
+ "Looking up source lines for uncovered branches in %s\n",
+ (ditr->first).c_str()
+ );
+ determineSourceLines(
+ theBranches,
+ ditr->second.sourceFile
+ );
+ }
+ }
+ }
+
+ uint32_t DesiredSymbols::getNumberBranchesAlwaysTaken( void ) const {
+ return stats.branchesAlwaysTaken;
+ };
+
+ uint32_t DesiredSymbols::getNumberBranchesFound( void ) const {
+ return (stats.branchesNotExecuted + stats.branchesExecuted);
+ };
+
+ uint32_t DesiredSymbols::getNumberBranchesNeverTaken( void ) const {
+ return stats.branchesNeverTaken;
+ };
+
+ uint32_t DesiredSymbols::getNumberUncoveredRanges( void ) const {
+ return stats.uncoveredRanges;
+ };
+
+ bool DesiredSymbols::isDesired (
+ const std::string& symbolName
+ ) const
+ {
+ if (set.find( symbolName ) == set.end()) {
+ #if 0
+ fprintf( stderr,<span style="background-color: #FF0000"> </span>
+ "Warning: Unable to find symbol %s\n",<span style="background-color: #FF0000"> </span>
+ symbolName.c_str()<span style="background-color: #FF0000"> </span>
+ );
+ #endif
+ return false;
+ }
+ return true;
+ }
+
+ void DesiredSymbols::mergeCoverageMap(
+ const std::string& symbolName,
+ const CoverageMapBase* const sourceCoverageMap
+ )
+ {
+ uint32_t dAddress;
+ CoverageMapBase* destinationCoverageMap;
+ uint32_t dMapSize;
+ symbolSet_t::iterator itr;
+ uint32_t sAddress;
+ uint32_t sBaseAddress;
+ uint32_t sMapSize;
+
+ // Ensure that the symbol is a desired symbol.
+ itr = set.find( symbolName );
+
+ if (itr == set.end()) {
+
+ fprintf(
+ stderr,
+ "ERROR: DesiredSymbols::mergeCoverageMap - Unable to merge "
+ "coverage map for %s because it is NOT a desired symbol\n",
+ symbolName.c_str()
+ );
+ exit( -1 );
+ }
+
+ // Ensure that the source and destination coverage maps
+ // are the same size.
+ dMapSize = itr->second.stats.sizeInBytes;
+ sBaseAddress = sourceCoverageMap->getLowAddress();
+ sMapSize = sourceCoverageMap->getHighAddress() - sBaseAddress + 1;
+ if (dMapSize != sMapSize) {
+
+ fprintf(
+ stderr,
+ "ERROR: DesiredSymbols::mergeCoverageMap - Unable to merge "
+ "coverage map for %s because the sizes are different\n",
+ symbolName.c_str()
+ );
+ exit( -1 );
+ }
+
+ // Merge the data for each address.
+ destinationCoverageMap = itr->second.unifiedCoverageMap;
+
+ for (dAddress = 0; dAddress < dMapSize; dAddress++) {
+
+ sAddress = dAddress + sBaseAddress;
+
+ // Merge start of instruction indication.
+ if (sourceCoverageMap->isStartOfInstruction( sAddress ))
+ destinationCoverageMap->setIsStartOfInstruction( dAddress );
+
+ // Merge the execution data.
+ if (sourceCoverageMap->wasExecuted( sAddress ))
+ destinationCoverageMap->setWasExecuted( dAddress );
+
+ // Merge the branch data.
+ if (sourceCoverageMap->wasTaken( sAddress ))
+ destinationCoverageMap->setWasTaken( dAddress );
+
+ if (sourceCoverageMap->wasNotTaken( sAddress ))
+ destinationCoverageMap->setWasNotTaken( dAddress );
+ }
+ }
+
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/ExecutableInfo.h:1.1
--- /dev/null Mon May 24 15:10:05 2010
+++ gcc-testing/covoar/ExecutableInfo.h Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,162 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file ExecutableInfo.h
+ * @brief ExecutableInfo Specification
+ *
+ * This file contains the specification of the ExecutableInfo class.
+ */
+
+#ifndef __EXECUTABLEINFO_H__
+#define __EXECUTABLEINFO_H__
+
+#include <map>
+#include <stdint.h>
+#include <string>
+
+#include "CoverageMapBase.h"
+#include "SymbolTable.h"
+
+namespace Coverage {
+
+ /*! @class ExecutableInfo
+ *
+ * This class holds a collection of information for an executable
+ * that is to be analyzed.
+ */
+ class ExecutableInfo {
+
+ public:
+
+ /*!
+ * This method constructs an ExecutableInfo instance.
+ *
+ * @param[in] theExecutableName specifies the name of the executable
+ * @param[in] theLibraryName specifies the name of the executable
+ */
+ ExecutableInfo(
+ const char* const theExecutableName,
+ const char* const theLibraryName = NULL
+ );
+
+ /*!
+ * This method destructs an ExecutableInfo instance.
+ */
+ virtual ~ExecutableInfo();
+
+ /*!
+ * This method prints the contents of all coverage maps for
+ * this executable.
+ */
+ void dumpCoverageMaps( void );
+
+ /*!
+ * This method returns a pointer to the executable's coverage map
+ * that contains the specified address.
+ *
+ * @param[in] address specifies the desired address
+ *
+ * @return Returns a pointer to the coverage map
+ */
+ CoverageMapBase* getCoverageMap( uint32_t address );
+
+ /*!
+ * This method returns the file name of the executable.
+ *
+ * @return Returns the executable's file name
+ */
+ std::string getFileName( void ) const;
+
+ /*!
+ * This method returns the library name associated with the executable.
+ *
+ * @return Returns the executable's library name
+ */
+ std::string getLibraryName( void ) const;
+
+ /*!
+ * This method returns the load address of the dynamic library
+ *
+ * @return Returns the load address of the dynamic library
+ */
+ uint32_t getLoadAddress( void ) const;
+
+ /*!
+ * This method returns a pointer to the executable's symbol table.
+ *
+ * @return Returns a pointer to the symbol table.
+ */
+ SymbolTable* getSymbolTable( void ) const;
+
+ /*!
+ * This method creates a coverage map for the specified symbol.
+ *
+ * @param[in] symbolName specifies the name of the symbol
+ * @param[in] lowAddress specifies the low address of the coverage map
+ * @param[in] highAddress specifies the high address of the coverage map
+ *
+ * @return Returns a pointer to the coverage map
+ */
+ CoverageMapBase* createCoverageMap (
+ const std::string& symbolName,
+ uint32_t lowAddress,
+ uint32_t highAddress
+ );
+
+ /*!
+ * This method indicates whether a dynamic library has been
+ * associated with the executable.
+ *
+ * @return Returns TRUE if<span style="background-color: #FF0000"> </span>
+ */
+ bool hasDynamicLibrary( void );
+
+ /*!
+ * This method merges the coverage maps for this executable into
+ * the unified coverage map.
+ */
+ void mergeCoverage( void );
+
+ /*!
+ * This method sets the load address of the dynamic library
+ *
+ * @param[in] address specifies the load address of the dynamic
+ * library
+ */
+ void setLoadAddress( uint32_t address );
+
+ private:
+
+ /*!
+ * This map associates a symbol with its coverage map.
+ */
+ typedef std::map<std::string, CoverageMapBase *> coverageMaps_t;
+ coverageMaps_t coverageMaps;
+
+ /*!
+ * This member variable contains the name of the executable.
+ */
+ std::string executableName;
+
+ /*!
+ * This member variable contains the name of a dynamic library
+ * associated with the executable.
+ */
+ std::string libraryName;
+
+ /*!
+ * This member variable contains the load address of a dynamic library
+ * if one has been specified for the executable.
+ */
+ uint32_t loadAddress;
+
+ /*!
+ * This member variable contains a pointer to the symbol table
+ * of the executable or library.
+ */
+ SymbolTable* theSymbolTable;
+
+ };
+}
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/ExecutableInfo.cc:1.1
--- /dev/null Mon May 24 15:10:05 2010
+++ gcc-testing/covoar/ExecutableInfo.cc Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,127 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file ExecutableInfo.cc
+ * @brief ExecutableInfo Implementation
+ *
+ * This file contains the implementation of the functionality
+ * of the ExecutableInfo class.
+ */
+
+#include <stdio.h>
+
+#include "ExecutableInfo.h"
+#include "app_common.h"
+#include "CoverageMap.h"
+#include "DesiredSymbols.h"
+#include "SymbolTable.h"
+
+namespace Coverage {
+
+ ExecutableInfo::ExecutableInfo(
+ const char* const theExecutableName,
+ const char* const theLibraryName
+ )
+ {
+ executableName = theExecutableName;
+ loadAddress = 0;
+ libraryName = "";
+ if (theLibraryName)
+ libraryName = theLibraryName;
+ theSymbolTable = new SymbolTable();
+ }
+
+ ExecutableInfo::~ExecutableInfo()
+ {
+ if (theSymbolTable)
+ delete theSymbolTable;
+ }
+
+ void ExecutableInfo::dumpCoverageMaps( void ) {
+ ExecutableInfo::coverageMaps_t::iterator itr;
+
+ for (itr = coverageMaps.begin(); itr != coverageMaps.end(); itr++) {
+ fprintf( stderr, "Coverage Map for %s\n", ((*itr).first).c_str() );;
+ ((*itr).second)->dump();
+ }
+ }
+
+ CoverageMapBase* ExecutableInfo::getCoverageMap ( uint32_t address )
+ {
+ CoverageMapBase* aCoverageMap = NULL;
+ coverageMaps_t::iterator it;
+ std::string itsSymbol;
+
+ // Obtain the coverage map containing the specified address.
+ itsSymbol = theSymbolTable->getSymbol( address );
+ if (itsSymbol != "") {
+ it = coverageMaps.find( itsSymbol );
+ aCoverageMap = (*it).second;
+ }
+
+ return aCoverageMap;
+ }
+
+ std::string ExecutableInfo::getFileName ( void ) const
+ {
+ return executableName;
+ }
+
+ std::string ExecutableInfo::getLibraryName( void ) const
+ {
+ return libraryName;
+ }
+
+ uint32_t ExecutableInfo::getLoadAddress( void ) const
+ {
+ return loadAddress;
+ }
+
+
+ SymbolTable* ExecutableInfo::getSymbolTable ( void ) const
+ {
+ return theSymbolTable;
+ }
+
+ CoverageMapBase* ExecutableInfo::createCoverageMap (
+ const std::string& symbolName,
+ uint32_t lowAddress,
+ uint32_t highAddress
+ )
+ {
+ CoverageMapBase* theMap = NULL;
+
+ theMap = new CoverageMap( lowAddress, highAddress );
+
+ if (!theMap)
+ fprintf(
+ stderr, "Unable to create coverage map for %s\n",
+ symbolName.c_str()
+ );
+
+ else
+ coverageMaps[ symbolName ] = theMap;
+
+ return theMap;
+ }
+
+ bool ExecutableInfo::hasDynamicLibrary( void )
+ {
+ return (libraryName != "");
+ }
+
+ void ExecutableInfo::mergeCoverage( void ) {
+ ExecutableInfo::coverageMaps_t::iterator itr;
+
+ for (itr = coverageMaps.begin(); itr != coverageMaps.end(); itr++) {
+ SymbolsToAnalyze->mergeCoverageMap( (*itr).first, (*itr).second );
+ }
+ }
+
+ void ExecutableInfo::setLoadAddress( uint32_t address )
+ {
+ loadAddress = address;
+ }
+
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/Explanations.h:1.1
--- /dev/null Mon May 24 15:10:05 2010
+++ gcc-testing/covoar/Explanations.h Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,123 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file Explanations.h
+ * @brief Explanations Specification
+ *
+ * This file contains the specification of the Explanations class.
+ */
+
+#ifndef __EXPLANATIONS_H__
+#define __EXPLANATIONS_H__
+
+#include <map>
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+namespace Coverage {
+
+ /*! @class Explanation
+ *
+ * This class defines the information that comprises an explanation
+ * of an uncovered range or branch.
+ */
+ class Explanation {
+
+ public:
+
+ /*!
+ * This member variable contains the starting line number of
+ * the uncovered range or branch.
+ */
+ std::string startingPoint;
+
+ /*!
+ * This member variable contains the classification of
+ * the explanation.
+ */
+ std::string classification;
+
+ /*!
+ * This member variable contains the multi-line explanation text.
+ */
+ std::vector<std::string> explanation;
+
+ /*!
+ * This member variable indicates whether this explanation was
+ * used during analysis.
+ */
+ bool found;
+
+ /*!
+ * This method constructs an Explanation instance.
+ */
+ Explanation() {found = false;}
+
+ /*!
+ * This method destructs an Explanation instance.
+ */
+ ~Explanation() {}
+ };
+
+ /*! @class Explanations
+ *
+ * This class defines a set of Explanation instances.
+ */
+ class Explanations {
+
+ public:
+
+ /*!
+ * This member variable contains a list of Explanation instances.
+ */
+ std::map<std::string, Explanation> set;
+
+ /*!<span style="background-color: #FF0000"> </span>
+ * This method constructs an Explanations instance.
+ */
+ Explanations();
+
+ /*!<span style="background-color: #FF0000"> </span>
+ * This method destructs an Explanations instance.
+ */
+ ~Explanations();
+
+ /*!
+ * This methods loads the explanation information from the
+ * specified file.
+ *
+ * @param[in] explanations specifies the file name containing
+ * the explanation information
+ */
+ void load(
+ const char* const explanations
+ );
+
+ /*!
+ * This method returns the explanation associated with the
+ * specified starting line number.
+ *
+ * @param[in] start specifies the starting line number for
+ * which to search
+ */
+ const Explanation *lookupExplanation(
+ std::string& start
+ );
+
+ /*!
+ * This method writes a file that contains a list of any
+ * explanations that were not looked up.
+ *
+ * @param[in] fileName specifies the name of the file to write
+ */<span style="background-color: #FF0000"> </span>
+ void writeNotFound(
+ const char* const fileName
+ );
+
+ };
+
+}
+
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/Explanations.cc:1.1
--- /dev/null Mon May 24 15:10:06 2010
+++ gcc-testing/covoar/Explanations.cc Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,195 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file Explanations.cc
+ * @brief Explanations Implementation
+ *
+ * This file contains the implementation of the functions<span style="background-color: #FF0000"> </span>
+ * which provide a base level of functionality of a Explanations.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "Explanations.h"
+
+namespace Coverage {
+
+ Explanations::Explanations()
+ {
+ }
+
+ Explanations::~Explanations()
+ {
+ }
+
+ void Explanations::load(
+ const char* const explanations
+ )
+ {
+ #define MAX_LINE_LENGTH 512
+ FILE *explain;
+ char buffer[MAX_LINE_LENGTH];
+ char *cStatus;
+ Explanation *e;
+ int line = 1;
+
+ if (!explanations)
+ return;
+
+ explain = fopen( explanations, "r" );
+ if (!explain) {
+ fprintf(
+ stderr,
+ "ERROR: Explanations::load - unable to open explanations file %s\n",
+ explanations
+ );
+ exit(-1);
+ }
+
+ while ( 1 ) {
+ e = new Explanation;
+ // Read the starting line of this explanation and
+ // skip blank lines between
+ do {
+ buffer[0] = '\0';
+ cStatus = fgets( buffer, MAX_LINE_LENGTH, explain );
+ if (cStatus == NULL) {
+ goto done;
+ }
+ buffer[ strlen(buffer) - 1] = '\0';
+ line++;
+ } while ( buffer[0] == '\0' );
+
+ // Have we already seen this one?
+ if (set.find( buffer ) != set.end()) {
+ fprintf(
+ stderr,
+ "ERROR: Explanations::load - line %d "
+ "contains a duplicate explanation (%s)\n",
+ line,
+ buffer
+ );
+ exit( -1 );
+ }
+
+ // Add the starting line and file
+ e->startingPoint = std::string(buffer);
+ e->found = false;
+
+ // Get the classification<span style="background-color: #FF0000"> </span>
+ cStatus = fgets( buffer, MAX_LINE_LENGTH, explain );
+ if (cStatus == NULL) {
+ fprintf(
+ stderr,
+ "ERROR: Explanations::load - line %d "
+ "out of sync at the classification\n",
+ line
+ );
+ exit( -1 );
+ }
+ buffer[ strlen(buffer) - 1] = '\0';
+ e->classification = buffer;
+ line++;
+
+ // Get the explanation<span style="background-color: #FF0000"> </span>
+ while (1) {
+ cStatus = fgets( buffer, MAX_LINE_LENGTH, explain );
+ // fprintf( stderr, "%d - %s\n", line, buffer );
+ if (cStatus == NULL) {
+ fprintf(
+ stderr,
+ "ERROR: Explanations::load - line %d "
+ "out of sync at the explanation\n",
+ line
+ );
+ exit( -1 );
+ }
+ buffer[ strlen(buffer) - 1] = '\0';
+ line++;
+
+ const char delimiter[4] = "+++";
+ if (!strncmp( buffer, delimiter, 3 )) {
+ break;
+ }
+ // XXX only taking last line. Needs to be a vector
+ e->explanation.push_back( buffer );
+ }
+
+ // Add this to the set of Explanations
+ set[ e->startingPoint ] = *e;
+ }
+done:
+ ;
+
+ #undef MAX_LINE_LENGTH
+ }
+
+ const Explanation *Explanations::lookupExplanation(
+ std::string& start
+ )
+ {
+ if (set.find( start ) == set.end()) {
+ #if 0
+ fprintf( stderr,<span style="background-color: #FF0000"> </span>
+ "Warning: Unable to find explanation for %s\n",<span style="background-color: #FF0000"> </span>
+ start.c_str()<span style="background-color: #FF0000"> </span>
+ );
+ #endif
+ return NULL;
+ }
+ set[ start ].found = true;
+ return &set[ start ];
+ }
+
+ void Explanations::writeNotFound(
+ const char* const fileName
+ )
+ {
+ FILE* notFoundFile;
+ bool notFoundOccurred = false;
+
+ if (!fileName)
+ return;
+<span style="background-color: #FF0000"> </span>
+ notFoundFile = fopen( fileName, "w" );
+ if (!fileName) {
+ fprintf(
+ stderr,
+ "ERROR: Explanations::writeNotFound - unable to open file %s\n",
+ fileName
+ );
+ exit( -1 );
+ }
+<span style="background-color: #FF0000"> </span>
+ for (std::map<std::string, Explanation>::iterator itr = set.begin();
+ itr != set.end();
+ itr++) {
+ Explanation e = (*itr).second;
+ std::string key = (*itr).first;
+<span style="background-color: #FF0000"> </span>
+ if (!e.found) {
+ notFoundOccurred = true;
+ fprintf(
+ notFoundFile,
+ "%s\n",
+ e.startingPoint.c_str()
+ );
+ }<span style="background-color: #FF0000"> </span>
+ }
+ fclose( notFoundFile );
+
+ if (!notFoundOccurred) {
+ if (!unlink( fileName )) {
+ fprintf( stderr,<span style="background-color: #FF0000"> </span>
+ "Warning: Unable to unlink %s\n\n",<span style="background-color: #FF0000"> </span>
+ fileName<span style="background-color: #FF0000"> </span>
+ );
+ }
+ }<span style="background-color: #FF0000"> </span>
+ }
+
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/Makefile:1.1
--- /dev/null Mon May 24 15:10:06 2010
+++ gcc-testing/covoar/Makefile Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,154 @@
</font><font color='#000088'>+#
+# $Id$
+#
+
+INSTALL_DIR=../bin
+CXXFLAGS=-g -Wall -O3 -march=native -mtune=native
+PROGRAMS=covoar qemu-dump-trace trace-converter configfile-test
+
+COMMON_OBJS= app_common.o \
+ ConfigFile.o \
+ CoverageFactory.o \
+ CoverageMap.o \
+ CoverageMapBase.o \
+ CoverageRanges.o \
+ CoverageReaderBase.o \
+ CoverageReaderQEMU.o \
+ CoverageReaderRTEMS.o \
+ CoverageReaderSkyeye.o \
+ CoverageReaderTSIM.o \
+ CoverageWriterBase.o \
+ CoverageWriterRTEMS.o \
+ CoverageWriterSkyeye.o \
+ CoverageWriterTSIM.o \
+ DesiredSymbols.o \
+ ExecutableInfo.o \
+ Explanations.o \
+ ObjdumpProcessor.o \
+ ReportsBase.o \
+ ReportsText.o \
+ ReportsHtml.o \
+ SymbolTable.o \
+ Target_arm.o \
+ TargetBase.o \
+ TargetFactory.o \
+ Target_i386.o \
+ Target_lm32.o \
+ Target_m68k.o \
+ Target_powerpc.o \
+ Target_sparc.o \
+
+TRACECONVERTER_OBJS = \
+ $(COMMON_OBJS) \
+ TraceConverter.o \
+ TraceList.o \
+ TraceReaderBase.o \
+ TraceReaderLogQEMU.o \
+ TraceWriterBase.o \
+ TraceWriterQEMU.o
+
+COVOAR_OBJS = \
+ $(COMMON_OBJS) \
+ covoar.o
+
+CONFIGFILE_TEST_OBJS = \
+ $(COMMON_OBJS) \
+ configfile_test.cc
+
+INSTALLED= \
+ ../bin/qemu-dump-trace \
+ ../bin/trace-converter \
+ ../bin/covoar
+
+all: $(PROGRAMS) ${INSTALL_DIR} $(INSTALLED)
+
+${INSTALL_DIR}:
+ test -d ${INSTALL_DIR} || mkdir ${INSTALL_DIR}
+
+# INSTALLED PROGRAMS
+../bin/qemu-dump-trace: qemu-dump-trace ${INSTALL_DIR}
+ cp qemu-dump-trace ../bin
+
+../bin/trace-converter: trace-converter ${INSTALL_DIR}
+ cp trace-converter ../bin
+
+../bin/covoar: covoar ${INSTALL_DIR}
+ cp covoar ../bin
+
+# EXECUTABLES
+qemu-dump-trace: qemu-dump-trace.c ${INSTALL_DIR}
+ $(CXX) -o $(@) qemu-dump-trace.c
+
+covoar: $(COVOAR_OBJS)
+ $(CXX) $(CXXFLAGS) -o $(@) $(COVOAR_OBJS)
+
+trace-converter: $(TRACECONVERTER_OBJS)
+ $(CXX) $(CXXFLAGS) -o $(@) $(TRACECONVERTER_OBJS)
+
+configfile-test: $(CONFIGFILE_TEST_OBJS)
+ $(CXX) $(CXXFLAGS) -o $(@) $(CONFIGFILE_TEST_OBJS)
+
+# DEPENDENCIES ON SINGLE OBJECTS
+app_common.o: app_common.h app_common.cc
+
+covoar.o: covoar.cc CoverageFactory.h CoverageMap.h DesiredSymbols.h \
+ ExecutableInfo.h Explanations.h ObjdumpProcessor.h ReportsBase.h
+
+CoverageFactory.o: CoverageFactory.cc CoverageFactory.h \
+ CoverageReaderBase.h CoverageReaderQEMU.h CoverageReaderRTEMS.h \
+ CoverageReaderSkyeye.h CoverageReaderTSIM.h \
+ CoverageWriterBase.h CoverageWriterRTEMS.h \
+ CoverageWriterSkyeye.h CoverageWriterTSIM.h<span style="background-color: #FF0000"> </span>
+CoverageMap.o: CoverageMap.cc CoverageMap.h
+CoverageMapBase.o: CoverageMapBase.cc CoverageMapBase.h
+CoverageRanges.o: CoverageRanges.cc CoverageRanges.h
+CoverageReaderBase.o: CoverageReaderBase.cc CoverageReaderBase.h
+CoverageReaderQEMU.o: CoverageReaderQEMU.cc CoverageReaderQEMU.h \
+ ExecutableInfo.h qemu-traces.h
+CoverageReaderRTEMS.o: CoverageReaderRTEMS.cc CoverageReaderRTEMS.h \
+ ExecutableInfo.h rtemscov_header.h
+CoverageReaderSkyeye.o: CoverageReaderSkyeye.cc CoverageReaderSkyeye.h \
+ ExecutableInfo.h skyeye_header.h
+CoverageReaderTSIM.o: CoverageReaderTSIM.cc CoverageReaderTSIM.h \
+ ExecutableInfo.h
+CoverageWriterBase.o: CoverageWriterBase.cc CoverageWriterBase.h
+CoverageWriterRTEMS.o: CoverageWriterRTEMS.cc CoverageWriterRTEMS.h \
+ rtemscov_header.h
+CoverageWriterSkyeye.o: CoverageWriterSkyeye.cc CoverageWriterSkyeye.h \
+ skyeye_header.h
+CoverageWriterTSIM.o: CoverageWriterTSIM.cc CoverageWriterTSIM.h
+DesiredSymbols.o: DesiredSymbols.cc DesiredSymbols.h CoverageMap.h
+ExecutableInfo.o: ExecutableInfo.cc ExecutableInfo.h CoverageMap.h \
+ DesiredSymbols.h SymbolTable.h
+Explanations.o: Explanations.cc Explanations.h
+ObjdumpProcessor.o: ObjdumpProcessor.cc ObjdumpProcessor.h ExecutableInfo.h \
+ TargetBase.h TargetFactory.h
+ReportsBase.o: ReportsBase.cc ReportsBase.h CoverageRanges.h DesiredSymbols.h \
+ Explanations.h ObjdumpProcessor.h
+ReportsHtml.o: ReportsHtml.h ReportsText.cc
+ReportsText.o: ReportsBase.h ReportsText.cc
+SymbolTable.o: SymbolTable.cc SymbolTable.h
+Target_arm.o: Target_arm.cc Target_arm.h TargetBase.h
+TargetBase.o: TargetBase.cc TargetBase.h
+TargetFactory.o: TargetFactory.cc TargetFactory.h TargetBase.h Target_arm.h \
+ Target_i386.h Target_lm32.h Target_m68k.h Target_powerpc.h Target_sparc.h
+Target_i386.o: Target_i386.cc Target_i386.h TargetBase.h
+Target_lm32.o: Target_lm32.cc Target_lm32.h TargetBase.h
+Target_m68k.o: Target_m68k.cc Target_m68k.h TargetBase.h
+Target_powerpc.o: Target_powerpc.cc Target_powerpc.h TargetBase.h
+Target_sparc.o: Target_sparc.cc Target_sparc.h TargetBase.h
+
+TraceConverter.o: TraceConverter.cc TraceReaderBase.h TraceList.h
+TraceList.o: TraceList.cc TraceList.h
+TraceReaderBase.o: TraceReaderBase.cc TraceReaderBase.h TraceList.h
+TraceReaderLogQEMU.o: TraceReaderLogQEMU.cc TraceReaderLogQEMU.h TraceReaderBase.h TraceList.h
+TraceWriterBase.o: TraceWriterBase.cc TraceWriterBase.h
+TraceWriterQEMU.o: TraceWriterQEMU.cc TraceWriterQEMU.h TraceWriterBase.h TraceReaderLogQEMU.h TraceList.h
+
+clean:
+ rm -rf $(PROGRAMS) *.o doxy html latex *.exe *~ warnings.log
+
+doxygen:
+ doxygen Doxyfile
+
+install: all
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/ObjdumpProcessor.h:1.1
--- /dev/null Mon May 24 15:10:06 2010
+++ gcc-testing/covoar/ObjdumpProcessor.h Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,169 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file ObjdumpProcessor.h
+ * @brief ObjdumpProcessor Specification
+ *
+ * This file contains the specification of the ObjdumpProcessor class.
+ */
+
+#ifndef __OBJDUMP_PROCESSOR_H__
+#define __OBJDUMP_PROCESSOR_H__
+
+#include <list>
+#include <string>
+
+#include "ExecutableInfo.h"
+#include "TargetBase.h"
+
+namespace Coverage {
+
+ /*! @class ObjdumpProcessor
+ *
+ * This class implements the functionality which reads the output of
+ * an objdump. Various information is extracted from the objdump line
+ * to support analysis and report writing. Analysis of the objdump line
+ * also allows for identification of "nops". For the purpose of coverage
+ * analysis, nops in the executable may be ignored. Compilers often
+ * produce nops to align functions on particular alignment boundaries
+ * and the nop between functions can not possibly be executed.
+ */
+ class ObjdumpProcessor {
+
+ public:
+
+ /*!
+ * This type defines the elements of an objdump line.
+ */
+ typedef struct {
+ /*!
+ * This member variable contains the actual line from the object dump.
+ */
+ std::string line;
+
+ /*!
+ * This member variable contains the address from the object dump line.
+ */
+ uint32_t address;
+
+ /*!
+ * This member variable contains an indication of whether the line
+ * is an instruction.
+ */
+ bool isInstruction;
+
+ /*!
+ * This member variable contains an indication of whether the line
+ * is a nop instruction.
+ */
+ bool isNop;
+
+ /*!
+ * This member variable contains the size of the nop instruction.
+ */
+ int nopSize;
+
+ /*!
+ * This member variable contains an indication of whether the line
+ * is a branch instruction.
+ */
+ bool isBranch;
+
+ } objdumpLine_t;
+
+ /*!
+ * This object defines a list of object dump lines
+ * for a file.
+ */
+ typedef std::list<objdumpLine_t> objdumpLines_t;
+
+<span style="background-color: #FF0000"> </span>
+ /*!
+ * This object defines a list of instruction addresses
+ * that will be extracted from the objdump file.
+ */<span style="background-color: #FF0000"> </span>
+ typedef std::list<uint32_t> objdumpFile_t;
+
+ /*!
+ * This method constructs an ObjdumpProcessor instance.
+ */
+ ObjdumpProcessor();
+
+ /*!
+ * This method destructs an ObjdumpProcessor instance.
+ */
+ virtual ~ObjdumpProcessor();
+
+ uint32_t determineLoadAddress(
+ ExecutableInfo* theExecutable
+ );
+
+ /*!
+ * This method returns a file pointer to the objdump file
+ * for the given file name.<span style="background-color: #FF0000"> </span>
+ */
+ FILE* getFile( std::string fileName );<span style="background-color: #FF0000"> </span>
+
+ /*!
+ * This method fills the objdumpList list with all the<span style="background-color: #FF0000"> </span>
+ * instruction addresses in the object dump file.
+ */
+ void loadAddressTable (
+ ExecutableInfo* const executableInformation
+ );
+
+ /*!
+ * This method generates and processes an object dump for
+ * the specified executable.
+ */
+ void load(
+ ExecutableInfo* const executableInformation
+ );
+
+ /*!
+ * This method returns the next address in othe objdumpList.
+ */
+ uint32_t getAddressAfter( uint32_t address );
+
+ /*!
+ * This method returns true if the instrucation is
+ * an instruction that results in a code branch, otherwise
+ * it returns false.
+ */
+ bool IsBranch( const char *instruction );
+
+ /*!
+ * This method returns true if the instruction from<span style="background-color: #FF0000"> </span>
+ * the given line in the objdmp file is a branch instruction,
+ * otherwise it returns false.
+ */
+ bool isBranchLine(
+ const char* const line
+ );
+
+ private:
+
+ /*!
+ * This variable consists of a list of all instruction addresses
+ * extracted from the obj dump file.
+ */
+ objdumpFile_t objdumpList;
+
+ /*!
+ * This method determines whether the specified line is a
+ * nop instruction.
+ *
+ * @param[in] line contains the object dump line to check
+ * @param[out] size is set to the size in bytes of the nop
+ *
+ * @return Returns TRUE if the instruction is a nop, FALSE otherwise.
+ */
+ bool isNop(
+ const char* const line,
+ int& size
+ );
+
+ };
+}
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/ObjdumpProcessor.cc:1.1
--- /dev/null Mon May 24 15:10:06 2010
+++ gcc-testing/covoar/ObjdumpProcessor.cc Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,587 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file ObjdumpProcessor.cc
+ * @brief ObjdumpProcessor Implementation
+ *
+ * This file contains the implementation of the functions supporting
+ * the reading of an objdump output file and adding nops to a
+ * coverage map.<span style="background-color: #FF0000"> </span>
+ */
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <algorithm>
+#include <string>
+
+#include "app_common.h"
+#include "ObjdumpProcessor.h"
+#include "CoverageMap.h"
+#include "ExecutableInfo.h"
+#include "SymbolTable.h"
+#include "TargetFactory.h"
+
+namespace Coverage {
+
+ void finalizeSymbol(
+ ExecutableInfo* const executableInfo,
+ std::string& symbolName,
+ uint32_t lowAddress,
+ uint32_t highAddress,
+ ObjdumpProcessor::objdumpLines_t instructions
+ ) {
+
+ CoverageMapBase* aCoverageMap = NULL;
+ uint32_t endAddress = highAddress;
+ ObjdumpProcessor::objdumpLines_t::iterator itr, fnop, lnop;
+ ObjdumpProcessor::objdumpLines_t::reverse_iterator ritr;
+ SymbolInformation* symbolInfo = NULL;
+ SymbolTable* theSymbolTable;
+
+ //
+ // Remove trailing nop instructions.
+ //
+
+ // First find the last instruction.
+ for (ritr = instructions.rbegin();
+ ritr != instructions.rend();
+ ritr++) {
+ if (ritr->isInstruction)
+ break;
+ }
+
+ // If an instruction was found and it is a nop, ...
+ if ((ritr != instructions.rend()) && (ritr->isNop)) {
+
+ // save it as the last nop. Note that we must account for
+ // the difference between a forward and a reverse iterator.
+ lnop = ritr.base();
+ lnop--;
+ endAddress -= lnop->nopSize;
+
+ // Now look for the first nop in the sequence of trailing nops.
+ fnop = lnop;
+ ritr++;
+ for (; ritr != instructions.rend(); ritr++) {
+ if (ritr->isNop) {
+ fnop = ritr.base();
+ fnop--;
+ endAddress -= fnop->nopSize;
+ }
+ else
+ break;
+ }
+
+ // Erase trailing nops. The erase operation wants the first
+ // parameter to point to the first item to erase and the second
+ // parameter to point to the item beyond the last item to erase.
+ instructions.erase( fnop, ++lnop );
+ }
+
+ // If there are NOT already saved instructions, save them.
+ symbolInfo = SymbolsToAnalyze->find( symbolName );
+ if (symbolInfo->instructions.empty()) {
+ symbolInfo->sourceFile = executableInfo;
+ symbolInfo->baseAddress = lowAddress;
+ symbolInfo->instructions = instructions;
+ }
+
+ // Add the symbol to this executable's symbol table.
+ theSymbolTable = executableInfo->getSymbolTable();
+ theSymbolTable->addSymbol(
+ symbolName, lowAddress, endAddress - lowAddress + 1
+ );
+
+ // Create a coverage map for the symbol.
+ aCoverageMap = executableInfo->createCoverageMap(
+ symbolName, lowAddress, endAddress
+ );
+
+ if (aCoverageMap) {
+
+ // Mark the start of each instruction in the coverage map.
+ for (itr = instructions.begin();
+ itr != instructions.end();
+ itr++ ) {
+
+ aCoverageMap->setIsStartOfInstruction( itr->address );
+ }
+
+ // Create a unified coverage map for the symbol.
+ SymbolsToAnalyze->createCoverageMap(
+ symbolName, endAddress - lowAddress + 1
+ );
+ }
+ }
+
+ ObjdumpProcessor::ObjdumpProcessor()
+ {
+ }
+
+ ObjdumpProcessor::~ObjdumpProcessor()
+ {
+ }
+
+ uint32_t ObjdumpProcessor::determineLoadAddress(
+ ExecutableInfo* theExecutable
+ )
+ {
+ #define METHOD "ERROR: ObjdumpProcessor::determineLoadAddress - "
+ FILE* loadAddressFile = NULL;
+ char buffer[ 512 ];
+ char* cStatus;
+ uint32_t offset;
+
+ // This method should only be call for a dynamic library.
+ if (!theExecutable->hasDynamicLibrary())
+ return 0;
+
+#if 0
+ static FILE* gdbCommands = NULL;
+ int items;
+ uint32_t loadAddress;
+ FILE* objdumpFile = NULL;
+ int status;
+ char terminator;
+
+
+ //
+ // Invoke gdb to determine the physical load address
+ // of the .text section.
+ //
+
+ // Create a gdb input commands file.
+ if (!gdbCommands) {
+
+ gdbCommands = fopen( "gdbCommands", "w" );
+ if (!gdbCommands) {
+ fprintf(
+ stderr,
+ "ERROR: ObjdumpProcessor::determineLoadAddress - "
+ "unable to create gdbCommands\n"
+ );
+ exit( -1 );
+ }
+
+ fprintf(
+ gdbCommands,
+ "set pagination off\n"
+ "b main\n"
+ "r\n"
+ "info sharedlibrary\n"
+ "quit\n"
+ );
+
+ fclose( gdbCommands );
+ }
+
+ // Invoke gdb.
+ sprintf(
+ buffer,
+ "gdb -x gdbCommands %s | grep %s | cut -d ' ' -f1 > %s",
+ (theExecutable->getFileName()).c_str(),
+ (theExecutable->getLibraryName()).c_str(),
+ "library_addr.tmp"
+ );
+
+ status = system( buffer );
+ if (status) {
+ fprintf(
+ stderr,
+ "ERROR: ObjdumpProcessor::determineLoadAddress - "
+ "command (%s) failed with %d\n",
+ buffer,
+ status
+ );
+ exit( -1 );
+ }
+
+ // Read load address.
+ loadAddressFile = fopen( "library_addr.tmp", "r" );
+ if (!loadAddressFile) {
+ fprintf(
+ stderr,
+ "ERROR: ObjdumpProcessor::determineLoadAddress - "
+ "unable to open library_addr.tmp\n"
+ );
+ exit( -1 );
+ }
+
+ cStatus = fgets( buffer, 512, loadAddressFile );
+ items = sscanf(
+ buffer, "%x", &loadAddress
+ );
+
+ fclose( loadAddressFile );
+ unlink( "library_addr.tmp" );
+
+ //
+ // Partially process an objdump of the library to determine the first
+ // symbol's offset from the physical load address of the library.
+ //
+
+ // Obtain the objdump file.
+ objdumpFile = getFile( theExecutable->getLibraryName() );
+
+ // Process the objdump file.
+ while ( 1 ) {
+
+ // Get a line.
+ cStatus = fgets( buffer, 512, objdumpFile );
+ if (cStatus == NULL) {
+ fprintf(
+ stderr,
+ "ERROR: ObjdumpProcessor::determineLoadAddress - "
+ "no symbol found in objdump file\n"
+ );
+ exit( -1 );
+ }
+
+ // Look for the start of a symbol's objdump and extract
+ // address and symbol (i.e. address <symbolname>:).
+ items = sscanf(
+ buffer,
+ "%x <%*[^>]>%c",
+ &offset, &terminator
+ );
+
+ // If all items found, we have found the first symbol's objdump.
+ if ((items == 2) && (terminator == ':')) {
+ break;
+ }
+ }
+
+ return (loadAddress - offset);
+# endif
+#if 1
+ std::string dlinfoName = theExecutable->getFileName();
+ uint32_t address;
+ char inLibName[128];
+ std::string Library = theExecutable->getLibraryName();
+
+ dlinfoName += ".dlinfo";
+ // Read load address.
+ loadAddressFile = fopen( dlinfoName.c_str(), "r" );
+ if (!loadAddressFile) {
+ fprintf( stderr, METHOD "unable to open %s\n", dlinfoName.c_str() );
+ exit( -1 );
+ }
+
+ // Process the dlinfo file.
+ while ( 1 ) {
+
+ // Get a line.
+ cStatus = fgets( buffer, 512, loadAddressFile );
+ if (cStatus == NULL) {
+ fprintf(
+ stderr,
+ METHOD "library %s not found in %s\n",
+ Library.c_str(),
+ dlinfoName.c_str()
+ );
+ fclose( loadAddressFile );
+ exit( -1 );
+ }
+ sscanf( buffer, "%s %x", inLibName, &offset );
+ std::string tmp = inLibName;
+ if ( tmp.find( Library ) != tmp.npos ) {
+ // fprintf( stderr, "%s - 0x%08x\n", inLibName, offset );
+ address = offset;<span style="background-color: #FF0000"> </span>
+ break;
+ }
+ }
+
+ fclose( loadAddressFile );
+ return address;
+#endif
+ #undef METHOD
+ }
+
+ bool ObjdumpProcessor::IsBranch(
+ const char *instruction<span style="background-color: #FF0000"> </span>
+ )
+ {<span style="background-color: #FF0000"> </span>
+ if ( !TargetInfo ) {
+ fprintf(
+ stderr,
+ "ERROR: ObjdumpProcessor::IsBranch - unknown architecture\n"
+ );
+ assert(0);
+ return false;
+ }
+
+ return TargetInfo->isBranch( instruction );
+ }
+
+ bool ObjdumpProcessor::isBranchLine(
+ const char* const line
+ )
+ {
+ if ( !TargetInfo ) {
+ fprintf(
+ stderr,
+ "ERROR: ObjdumpProcessor::isBranchLine - unknown architecture\n"
+ );
+ assert(0);
+ return false;
+ }
+
+ return TargetInfo->isBranchLine( line );
+ }
+
+ bool ObjdumpProcessor::isNop(
+ const char* const line,
+ int& size
+ )
+ {
+ if ( !TargetInfo ){
+ fprintf(
+ stderr,
+ "ERROR: ObjdumpProcessor::isNop - unknown architecture\n"
+ );
+ assert(0);
+ return false;
+ }
+
+ return TargetInfo->isNopLine( line, size );
+ }
+
+ FILE* ObjdumpProcessor::getFile( std::string fileName )<span style="background-color: #FF0000"> </span>
+ {
+ char dumpFile[128];
+ FILE* objdumpFile;
+ char buffer[ 512 ];
+ int status;
+
+ sprintf( dumpFile, "%s.dmp", fileName.c_str() );
+<span style="background-color: #FF0000"> </span>
+ // Generate the objdump.
+ if (FileIsNewer( fileName.c_str(), dumpFile )) {
+ sprintf(
+ buffer,
+ "%s -da --section=.text --source %s | sed -e \'s/ *$//\' >%s",
+ TargetInfo->getObjdump(),
+ fileName.c_str(),
+ dumpFile
+ );
+
+ status = system( buffer );
+ if (status) {
+ fprintf(
+ stderr,
+ "ERROR: ObjdumpProcessor::getFile - command (%s) failed with %d\n",
+ buffer,
+ status
+ );
+ exit( -1 );
+ }
+ }<span style="background-color: #FF0000"> </span>
+
+ // Open the objdump file.
+ objdumpFile = fopen( dumpFile, "r" );
+ if (!objdumpFile) {
+ fprintf(
+ stderr,
+ "ERROR: ObjdumpProcessor::getFile - unable to open %s\n",
+ dumpFile
+ );
+ exit(-1);
+ }
+
+ return objdumpFile;
+ }
+
+ uint32_t ObjdumpProcessor::getAddressAfter( uint32_t address )
+ {
+ objdumpFile_t::iterator itr;
+
+ itr = find ( objdumpList.begin(), objdumpList.end(), address );
+ if (itr == objdumpList.end()) {
+ return 0;
+ }
+<span style="background-color: #FF0000"> </span>
+ itr++;
+ if (itr == objdumpList.end()) {
+ return 0;
+ }
+
+ return (*itr);
+
+ }
+
+ void ObjdumpProcessor::loadAddressTable (
+ ExecutableInfo* const executableInformation
+ )
+ {
+ char buffer[ 512 ];
+ char* cStatus;
+ int items;
+ FILE* objdumpFile;
+ uint32_t offset;
+ char terminator;
+
+ // Obtain the objdump file.
+ if (!executableInformation->hasDynamicLibrary())
+ objdumpFile = getFile( executableInformation->getFileName() );
+ else
+ objdumpFile = getFile( executableInformation->getLibraryName() );
+
+ // Process all lines from the objdump file.
+ while ( 1 ) {
+
+ // Get the line.
+ cStatus = fgets( buffer, 512, objdumpFile );
+ if (cStatus == NULL) {
+ break;
+ }
+ buffer[ strlen(buffer) - 1] = '\0';
+
+ // See if it is the dump of an instruction.
+ items = sscanf(
+ buffer,
+ "%x%c",
+ &offset, &terminator
+ );
+
+ // If it looks like an instruction ...
+ if ((items == 2) && (terminator == ':')){
+ objdumpList.push_back(
+ executableInformation->getLoadAddress() + offset
+ );
+ }
+ }
+ }
+
+ void ObjdumpProcessor::load(
+ ExecutableInfo* const executableInformation
+ )
+ {
+ char buffer[ 512 ];
+ char* cStatus;
+ std::string currentSymbol = "";
+ uint32_t endAddress;
+ uint32_t instructionOffset;
+ int items;
+ objdumpLine_t lineInfo;
+ FILE* objdumpFile;
+ uint32_t offset;
+ bool processSymbol = false;
+ uint32_t startAddress = 0;
+ char symbol[ 100 ];
+ char terminator1;
+ char terminator2;
+ objdumpLines_t theInstructions;
+
+ // Obtain the objdump file.
+ if (!executableInformation->hasDynamicLibrary())
+ objdumpFile = getFile( executableInformation->getFileName() );
+ else
+ objdumpFile = getFile( executableInformation->getLibraryName() );
+
+ // Process all lines from the objdump file.
+ while ( 1 ) {
+
+ // Get the line.
+ cStatus = fgets( buffer, 512, objdumpFile );
+ if (cStatus == NULL) {
+
+ // If we are currently processing a symbol, finalize it.
+ if (processSymbol) {
+ finalizeSymbol(
+ executableInformation,
+ currentSymbol,
+ startAddress,
+ executableInformation->getLoadAddress() + offset,
+ theInstructions
+ );
+ fprintf(
+ stderr,
+ "WARNING: ObjdumpProcessor::load - analysis of symbol %s \n"
+ " may be incorrect. It was the last symbol in %s\n"
+ " and the length of its last instruction is assumed "
+ " to be one.\n",
+ currentSymbol.c_str(),
+ executableInformation->getFileName().c_str()
+ );
+ }
+ break;
+ }
+
+ buffer[ strlen(buffer) - 1] = '\0';
+
+ lineInfo.line = buffer;
+ lineInfo.address = 0xffffffff;
+ lineInfo.isInstruction = false;
+ lineInfo.isNop = false;
+ lineInfo.nopSize = 0;
+ lineInfo.isBranch = false;
+
+ // Look for the start of a symbol's objdump and extract
+ // offset and symbol (i.e. offset <symbolname>:).
+ items = sscanf(
+ buffer,
+ "%x <%[^>]>%c",
+ &offset, symbol, &terminator1
+ );
+
+ // If all items found, we are at the beginning of a symbol's objdump.
+ if ((items == 3) && (terminator1 == ':')) {
+
+ endAddress = executableInformation->getLoadAddress() + offset - 1;
+
+ // If we are currently processing a symbol, finalize it.
+ if (processSymbol) {
+ finalizeSymbol(
+ executableInformation,
+ currentSymbol,
+ startAddress,
+ endAddress,
+ theInstructions
+ );
+ }
+
+ // Start processing of a new symbol.
+ startAddress = 0;
+ currentSymbol = "";
+ processSymbol = false;
+ theInstructions.clear();
+
+ // See if the new symbol is one that we care about.
+ if (SymbolsToAnalyze->isDesired( symbol )) {
+ startAddress = executableInformation->getLoadAddress() + offset;
+ currentSymbol = symbol;
+ processSymbol = true;
+ theInstructions.push_back( lineInfo );
+ }
+ }
+
+ else if (processSymbol) {
+
+ // See if it is the dump of an instruction.
+ items = sscanf(
+ buffer,
+ "%x%c\t%*[^\t]%c",
+ &instructionOffset, &terminator1, &terminator2
+ );
+
+ // If it looks like an instruction ...
+ if ((items == 3) && (terminator1 == ':') && (terminator2 == '\t')) {
+
+ // update the line's information, save it and ...
+ lineInfo.address =
+ executableInformation->getLoadAddress() + instructionOffset;
+ lineInfo.isInstruction = true;
+ lineInfo.isNop = isNop( buffer, lineInfo.nopSize );
+ lineInfo.isBranch = isBranchLine( buffer );
+ }
+
+ // Always save the line.
+ theInstructions.push_back( lineInfo );
+ }
+ }
+ }
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/ReportsBase.h:1.1
--- /dev/null Mon May 24 15:10:06 2010
+++ gcc-testing/covoar/ReportsBase.h Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,374 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file ReportsBase.h
+ * @brief Reports Base Class Specification
+ *
+ * This file contains the specification of the Reports methods. This
+ * collection of methods is used to generate the various reports of
+ * the analysis results.
+ */
+
+#ifndef __REPORTSBASE_H__
+#define __REPORTSBASE_H__
+
+#include <stdint.h>
+#include <string>
+#include <time.h>
+#include "DesiredSymbols.h"
+
+namespace Coverage {
+
+/*!
+ * This class contains the base information to create a report<span style="background-color: #FF0000"> </span>
+ * set. The report set may be text based, html based or some
+ * other format to be defined at a future time.
+ */
+class ReportsBase {
+
+ public:
+ ReportsBase( time_t timestamp );
+ ~ReportsBase();
+
+ /*!
+ * This method produces an index of the reports generated.
+ *
+ * @param[in] fileName identifies the report file name
+ */
+ virtual void WriteIndex(
+ const char* const fileName
+ );
+
+ /*!
+ * This method produces an annotated assembly listing report containing
+ * the disassembly of each symbol that was not completely covered.
+ *
+ * @param[in] fileName identifies the annotated report file name
+ */
+ void WriteAnnotatedReport(
+ const char* const fileName
+ );
+
+ /*!
+ * This method produces a report that contains information about each
+ * uncovered branch statement.
+ *
+ * @param[in] fileName identifies the branch report file name
+ */
+ void WriteBranchReport(
+ const char* const fileName
+ );
+
+ /*!
+ * This method produces a report that contains information about each
+ * uncovered range of bytes.
+ *
+ * @param[in] fileName identifies the coverage report file name
+ */
+ void WriteCoverageReport(
+ const char* const fileName
+ );
+
+ /*!
+ * This method produces a summary report that lists each uncovered
+ * range of bytes.
+ *
+ * @param[in] fileName identifies the report file name
+ */
+ void WriteSizeReport(
+ const char* const fileName
+ );
+
+ /*!
+ * This method produces a summary report that lists information on
+ * each symbol which did not achieve 100% coverage
+ *
+ * @param[in] fileName identifies the report file name
+ */
+ void WriteSymbolSummaryReport(
+ const char* const fileName
+ );
+
+ /*!
+ * This method returns the unique extension for the Report
+ * type. If the extension is ".txt" files will be<span style="background-color: #FF0000"> </span>
+ * named "annotated.txt", "branch.txt" ......
+ */
+ std::string ReportExtension() { return reportExtension_m; }
+
+ protected:
+
+ /*!
+ * This type is used to track a state during the annotated output.
+ */
+ typedef enum {
+ A_SOURCE,
+ A_EXECUTED,
+ A_NEVER_EXECUTED,
+ A_BRANCH_TAKEN,
+ A_BRANCH_NOT_TAKEN
+ } AnnotatedLineState_t;
+
+ /*!
+ * This member variable contains the extension used for all reports.
+ */
+ std::string reportExtension_m;
+
+ /*!
+ * This member variable contains the timestamp for the report.
+ */
+ time_t timestamp_m;
+
+ /*!
+ * This method Opens a report file and verifies that it opened
+ * correctly. Upon failure NULL is returned.
+ *
+ * @param[in] fileName identifies the report file name
+ */
+ virtual FILE* OpenFile(
+ const char* const fileName
+ );
+
+ /*!
+ * This method opens a report file and verifies that it opened.
+ * Then appedns any necessary header information onto the file.
+ *
+ * @param[in] fileName identifies the report file name
+ */
+ virtual FILE* OpenAnnotatedFile(
+ const char* const fileName
+ );
+
+ /*!
+ * This method opens a report file and verifies that it opened.
+ * Then appedns any necessary header information onto the file.
+ *
+ * @param[in] fileName identifies the report file name
+ * @param[in] hasBranches indicates if there are branches to report
+ */
+ virtual FILE* OpenBranchFile(
+ const char* const fileName,
+ bool hasBranches
+ );
+
+ /*!
+ * This method opens a report file and verifies that it opened.
+ * Then appedns any necessary header information onto the file.
+ *
+ * @param[in] fileName identifies the report file name
+ */
+ virtual FILE* OpenCoverageFile(
+ const char* const fileName
+ );
+<span style="background-color: #FF0000"> </span>
+ /*!
+ * This method opens a report file and verifies that it opened.
+ * Then appends any necessary header information onto the file.
+ *
+ * @param[in] fileName identifies the report file name
+ */
+ virtual FILE* OpenNoRangeFile(
+ const char* const fileName
+ );
+
+ /*!
+ * This method opens a report file and verifies that it opened.
+ * Then appedns any necessary header information onto the file.
+ *
+ * @param[in] fileName identifies the report file name
+ */
+ virtual FILE* OpenSizeFile(
+ const char* const fileName
+ );
+
+ /*!
+ * This method opens a report file and verifies that it opened.
+ * Then appedns any necessary header information onto the file.
+ *
+ * @param[in] fileName identifies the report file name
+ */
+ virtual FILE* OpenSymbolSummaryFile(
+ const char* const fileName
+ );
+
+ /*!
+ * This method Closes a report file.<span style="background-color: #FF0000"> </span>
+ *
+ * @param[in] aFile identifies the report file name
+ */
+ void CloseFile(
+ FILE* aFile
+ );
+
+ /*!
+ * This method puts any necessary footer information into
+ * the report then closes the file.
+ *
+ * @param[in] aFile identifies the report file name
+ */
+ virtual void CloseAnnotatedFile(
+ FILE* aFile
+ );
+
+ /*!
+ * This method puts any necessary footer information into
+ * the report then closes the file.
+ *
+ * @param[in] aFile identifies the report file name
+ * @param[in] hasBranches indicates if there are branches to report
+ */
+ virtual void CloseBranchFile(
+ FILE* aFile,
+ bool hasBranches
+ );
+
+ /*!
+ * This method puts any necessary footer information into
+ * the report then closes the file.
+ *
+ * @param[in] aFile identifies the report file name
+ */
+ virtual void CloseCoverageFile(
+ FILE* aFile
+ );
+
+ /*!
+ * This method puts any necessary footer information into
+ * the report then closes the file.
+ *
+ * @param[in] aFile identifies the report file name
+ */
+ void CloseNoRangeFile(
+ FILE* aFile
+ );
+
+ /*!
+ * This method puts any necessary footer information into
+ * the report then closes the file.
+ *
+ * @param[in] aFile identifies the report file name
+ */
+ virtual void CloseSizeFile(
+ FILE* aFile
+ );
+
+ /*!
+ * This method puts any necessary footer information into
+ * the report then closes the file.
+ *
+ * @param[in] aFile identifies the report file name
+ */
+ virtual void CloseSymbolSummaryFile(
+ FILE* aFile
+ );
+
+ /*!
+ * This method puts any necessary footer information into
+ * the report then closes the file.
+ *
+ * @param[in] aFile identifies the report file name
+ * @param[in] state identifies the state machine state
+ * @param[in] line identifies the string to print<span style="background-color: #FF0000"> </span>
+ * @param[in] id identifies the branch or range id.
+ */
+ virtual void PutAnnotatedLine(<span style="background-color: #FF0000"> </span>
+ FILE* aFile,<span style="background-color: #FF0000"> </span>
+ AnnotatedLineState_t state,<span style="background-color: #FF0000"> </span>
+ std::string line,
+ uint32_t id<span style="background-color: #FF0000"> </span>
+ )=0;
+
+ /*!
+ * This method puts any necessary footer information into
+ * the report then closes the file.
+ *
+ * @param[in] report identifies the report file name
+ */
+ virtual bool PutNoBranchInfo(
+ FILE* report
+ ) = 0;
+
+ /*!
+ * This method puts a branch entry into the branch report.<span style="background-color: #FF0000"> </span>
+ *
+ * @param[in] report identifies the report file name
+ * @param[in] number identifies the line number.
+ * @param[in] symbolPtr is a pointer to the symbol information
+ * @param[in] rangePtr is a pointer to the range information.
+ */
+ virtual bool PutBranchEntry(
+ FILE* report,
+ unsigned int number,
+ Coverage::DesiredSymbols::symbolSet_t::iterator symbolPtr,
+ Coverage::CoverageRanges::ranges_t::iterator rangePtr
+ )=0;
+
+ /*!
+ * This method reports when no range is available for<span style="background-color: #FF0000"> </span>
+ * a symbol in the coverage report.
+ *
+ * @param[in] report identifies the report file name
+ * @param[in] number identifies the line number.
+ * @param[in] symbol is a pointer to the symbol information
+ */
+ virtual void putCoverageNoRange(
+ FILE* report,
+ FILE* noRangeFile,
+ unsigned int number,
+ std::string symbol
+ )=0;
+
+ /*!
+ * This method puts a line in the coverage report.
+ *
+ * @param[in] report identifies the report file name
+ * @param[in] number identifies the line number.
+ * @param[in] ditr is a iterator to the symbol information
+ * @param[in] ritr is a iterator to the range information.
+ */
+ virtual bool PutCoverageLine(
+ FILE* report,
+ unsigned int number,
+ Coverage::DesiredSymbols::symbolSet_t::iterator ditr,
+ Coverage::CoverageRanges::ranges_t::iterator ritr
+ )=0;
+
+ /*!
+ * This method method puts a line into the size report.
+ *
+ * @param[in] report identifies the size report file name
+ * @param[in] number identifies the line number.
+ * @param[in] symbol is a pointer to the symbol information
+ * @param[in] range is a iterator to the range information.
+ */
+ virtual bool PutSizeLine(
+ FILE* report,
+ unsigned int number,
+ Coverage::DesiredSymbols::symbolSet_t::iterator symbol,
+ Coverage::CoverageRanges::ranges_t::iterator range
+ )=0;
+
+ /*!
+ * This method method puts a line into the symbol summary report.
+ *
+ * @param[in] report identifies the report file name
+ * @param[in] number identifies the line number.
+ * @param[in] symbol is a pointer to the symbol information
+ */
+ virtual bool PutSymbolSummaryLine(
+ FILE* report,
+ unsigned int number,
+ Coverage::DesiredSymbols::symbolSet_t::iterator symbol
+ )=0;
+};
+
+/*!
+ * This method iterates over all report set types and generates
+ * all reports.
+ */
+void GenerateReports();
+
+}
+
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/ReportsBase.cc:1.1
--- /dev/null Mon May 24 15:10:06 2010
+++ gcc-testing/covoar/ReportsBase.cc Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,497 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "ReportsBase.h"
+#include "app_common.h"
+#include "CoverageRanges.h"
+#include "DesiredSymbols.h"
+#include "Explanations.h"
+#include "ObjdumpProcessor.h"
+
+#include "ReportsText.h"
+#include "ReportsHtml.h"
+
+namespace Coverage {
+
+ReportsBase::ReportsBase( time_t timestamp ):
+ reportExtension_m(""),
+ timestamp_m( timestamp )
+{
+}
+
+ReportsBase::~ReportsBase()
+{
+}
+
+FILE* ReportsBase::OpenFile(
+ const char* const fileName
+)
+{
+ int sc;
+ FILE *aFile;
+ std::string file;
+
+ // Create the output directory if it does not already exist
+ sc = mkdir( outputDirectory,0755 );
+ if ( (sc == -1) && (errno != EEXIST) ) {
+ fprintf(stderr, "Unable to create output directory %s\n", outputDirectory);
+ return NULL;
+ }
+
+ file = outputDirectory;
+ file += "/";
+ file += fileName;
+
+ // Open the file.
+ aFile = fopen( file.c_str(), "w" );
+ if ( !aFile ) {
+ fprintf( stderr, "Unable to open %s\n", file.c_str() );
+ }
+ return aFile;
+}
+
+void ReportsBase::WriteIndex(
+ const char* const fileName
+)
+{
+}
+
+FILE* ReportsBase::OpenAnnotatedFile(
+ const char* const fileName
+)
+{
+ return OpenFile(fileName);
+}
+
+FILE* ReportsBase::OpenBranchFile(
+ const char* const fileName,
+ bool hasBranches
+)
+{
+ return OpenFile(fileName);
+}
+
+FILE* ReportsBase::OpenCoverageFile(
+ const char* const fileName
+)
+{
+ return OpenFile(fileName);
+}
+
+FILE* ReportsBase::OpenNoRangeFile(
+ const char* const fileName
+)
+{
+ return OpenFile(fileName);
+}
+
+
+FILE* ReportsBase::OpenSizeFile(
+ const char* const fileName
+)
+{
+ return OpenFile(fileName);
+}
+
+FILE* ReportsBase::OpenSymbolSummaryFile(
+ const char* const fileName
+)
+{
+ return OpenFile(fileName);
+}
+
+void ReportsBase::CloseFile(
+ FILE* aFile
+)
+{
+ fclose( aFile );
+}
+
+void ReportsBase::CloseAnnotatedFile(
+ FILE* aFile
+)
+{
+ CloseFile( aFile );
+}
+
+void ReportsBase::CloseBranchFile(
+ FILE* aFile,
+ bool hasBranches
+)
+{
+ CloseFile( aFile );
+}
+
+void ReportsBase::CloseCoverageFile(
+ FILE* aFile
+)
+{
+ CloseFile( aFile );
+}
+
+void ReportsBase::CloseNoRangeFile(
+ FILE* aFile
+)
+{
+ CloseFile( aFile );
+}
+
+void ReportsBase::CloseSizeFile(
+ FILE* aFile
+)
+{
+ CloseFile( aFile );
+}
+
+void ReportsBase::CloseSymbolSummaryFile(
+ FILE* aFile
+)
+{
+ CloseFile( aFile );
+}
+
+/*
+ * Write annotated report
+ */
+void ReportsBase::WriteAnnotatedReport(
+ const char* const fileName
+) {
+ FILE* aFile = NULL;
+ Coverage::DesiredSymbols::symbolSet_t::iterator ditr;
+ Coverage::CoverageRanges* theBranches;
+ Coverage::CoverageRanges* theRanges;
+ Coverage::CoverageMapBase* theCoverageMap = NULL;
+ uint32_t bAddress = 0;
+ AnnotatedLineState_t state;
+ std::list<Coverage::ObjdumpProcessor::objdumpLine_t>* theInstructions;
+ std::list<Coverage::ObjdumpProcessor::objdumpLine_t>::iterator itr;
+
+ aFile = OpenAnnotatedFile(fileName);
+ if (!aFile)
+ return;
+
+ // Process uncovered branches for each symbol.
+ for (ditr = SymbolsToAnalyze->set.begin();
+ ditr != SymbolsToAnalyze->set.end();
+ ditr++) {
+
+ // If uncoveredRanges and uncoveredBranches don't exist, then the
+ // symbol was never referenced by any executable. Just skip it.
+ if ((ditr->second.uncoveredRanges == NULL) &&
+ (ditr->second.uncoveredBranches == NULL))
+ continue;
+
+ // If uncoveredRanges and uncoveredBranches are empty, then everything
+ // must have been covered for this symbol. Just skip it.
+ if ((ditr->second.uncoveredRanges->set.empty()) &&
+ (ditr->second.uncoveredBranches->set.empty()))
+ continue;
+
+ theCoverageMap = ditr->second.unifiedCoverageMap;
+ bAddress = ditr->second.baseAddress;
+ theInstructions = &(ditr->second.instructions);
+ theRanges = ditr->second.uncoveredRanges;
+ theBranches = ditr->second.uncoveredBranches;
+
+ // Add annotations to each line where necessary
+ for (itr = theInstructions->begin();
+ itr != theInstructions->end();
+ itr++ ) {
+
+ uint32_t id = 0;
+ std::string annotation = "";
+ std::string line;
+ char textLine[150];
+
+ state = A_SOURCE;
+
+ if ( itr->isInstruction ) {
+ if (!theCoverageMap->wasExecuted( itr->address - bAddress )){
+ annotation = "<== NOT EXECUTED";<span style="background-color: #FF0000"> </span>
+ state = A_NEVER_EXECUTED;
+ id = theRanges->getId( itr->address );
+ } else if (theCoverageMap->isBranch( itr->address - bAddress )) {
+ id = theBranches->getId( itr->address );
+ if (theCoverageMap->wasAlwaysTaken( itr->address - bAddress )){
+ annotation = "<== ALWAYS TAKEN";
+ state = A_BRANCH_TAKEN;
+ } else if (theCoverageMap->wasNeverTaken( itr->address - bAddress )){
+ annotation = "<== NEVER TAKEN";
+ state = A_BRANCH_NOT_TAKEN;
+ }
+ } else {
+ state = A_EXECUTED;
+ }
+ }
+
+ sprintf( textLine, "%-70s", itr->line.c_str() );
+ line = textLine + annotation;
+<span style="background-color: #FF0000"> </span>
+ PutAnnotatedLine( aFile, state, line, id);<span style="background-color: #FF0000"> </span>
+ }
+ }
+
+ CloseAnnotatedFile( aFile );
+}
+
+/*
+ * Write branch report
+ */
+void ReportsBase::WriteBranchReport(
+ const char* const fileName
+) {
+ Coverage::DesiredSymbols::symbolSet_t::iterator ditr;
+ FILE* report = NULL;
+ Coverage::CoverageRanges::ranges_t::iterator ritr;
+ Coverage::CoverageRanges* theBranches;
+ unsigned int count;
+ bool hasBranches = true;
+
+ if ((SymbolsToAnalyze->getNumberBranchesFound() == 0) ||<span style="background-color: #FF0000"> </span>
+ (BranchInfoAvailable == false) )
+ hasBranches = false;
+
+ // Open the branch report file
+ report = OpenBranchFile( fileName, hasBranches );
+ if (!report)
+ return;
+
+ // If no branches were found of branch coverage is not supported
+ if ((SymbolsToAnalyze->getNumberBranchesFound() == 0) ||<span style="background-color: #FF0000"> </span>
+ (BranchInfoAvailable == false) ) {
+
+ PutNoBranchInfo(report);
+
+ // If branches were found, ...
+ } else {
+
+ // Process uncovered branches for each symbol.
+ count = 0;
+ for (ditr = SymbolsToAnalyze->set.begin();
+ ditr != SymbolsToAnalyze->set.end();
+ ditr++) {
+
+ theBranches = ditr->second.uncoveredBranches;
+
+ if (theBranches && !theBranches->set.empty()) {
+
+ for (ritr = theBranches->set.begin() ;
+ ritr != theBranches->set.end() ;
+ ritr++ ) {
+ count++;
+ PutBranchEntry( report, count, ditr, ritr );
+ }
+ }
+ }
+ }
+
+ CloseBranchFile( report, hasBranches );
+}
+
+/*
+ * Write coverage report
+ */
+void ReportsBase::WriteCoverageReport(
+ const char* const fileName
+) {
+ Coverage::DesiredSymbols::symbolSet_t::iterator ditr;
+ FILE* report;
+ Coverage::CoverageRanges::ranges_t::iterator ritr;
+ Coverage::CoverageRanges* theRanges;
+ unsigned int count, count2;
+ FILE* NoRangeFile;
+ std::string NoRangeName;
+
+ // Open special file that captures NoRange informaiton
+ NoRangeName = "no_range_";
+ NoRangeName += fileName;
+ NoRangeFile = OpenNoRangeFile ( NoRangeName.c_str() );
+ if (!NoRangeFile) {
+ return;
+ }
+
+ // Open the coverage report file.
+ report = OpenCoverageFile( fileName );
+ if ( !report ) {
+ return;
+ }
+
+ // Process uncovered ranges for each symbol.
+ count = 0;
+ for (ditr = SymbolsToAnalyze->set.begin();
+ ditr != SymbolsToAnalyze->set.end();
+ ditr++) {
+
+ theRanges = ditr->second.uncoveredRanges;
+
+ // If uncoveredRanges doesn't exist, then the symbol was never
+ // referenced by any executable. There may be a problem with the
+ // desired symbols list or with the executables so put something
+ // in the report.
+ if (theRanges == NULL) {
+ putCoverageNoRange( report, NoRangeFile, count, ditr->first );
+ count++;
+ } else if (!theRanges->set.empty()) {
+
+ for (ritr = theRanges->set.begin() ;
+ ritr != theRanges->set.end() ;
+ ritr++ ) {
+ PutCoverageLine( report, count, ditr, ritr );
+ count++;
+ }
+ }
+ }
+
+ CloseNoRangeFile( NoRangeFile );
+ CloseCoverageFile( report );
+
+}
+
+/*
+ * Write size report
+ */
+void ReportsBase::WriteSizeReport(
+ const char* const fileName
+)<span style="background-color: #FF0000"> </span>
+{
+ Coverage::DesiredSymbols::symbolSet_t::iterator ditr;
+ FILE* report;
+ Coverage::CoverageRanges::ranges_t::iterator ritr;
+ Coverage::CoverageRanges* theRanges;
+ unsigned int count;
+
+ // Open the report file.
+ report = OpenSizeFile( fileName );
+ if ( !report ) {
+ return;
+ }
+
+ // Process uncovered ranges for each symbol.
+ count = 0;
+ for (ditr = SymbolsToAnalyze->set.begin();
+ ditr != SymbolsToAnalyze->set.end();
+ ditr++) {
+
+ theRanges = ditr->second.uncoveredRanges;
+
+ if (theRanges && !theRanges->set.empty()) {
+
+ for (ritr = theRanges->set.begin() ;
+ ritr != theRanges->set.end() ;
+ ritr++ ) {
+ PutSizeLine( report, count, ditr, ritr );
+ count++;
+ }
+ }
+ }
+
+ CloseSizeFile( report );
+}
+
+void ReportsBase::WriteSymbolSummaryReport(
+ const char* const fileName
+)
+{
+ Coverage::DesiredSymbols::symbolSet_t::iterator ditr;
+ FILE* report;
+ unsigned int count;
+
+ // Open the report file.
+ report = OpenSymbolSummaryFile( fileName );
+ if ( !report ) {
+ return;
+ }
+
+ // Process each symbol.
+ count = 0;
+ for (ditr = SymbolsToAnalyze->set.begin();
+ ditr != SymbolsToAnalyze->set.end();
+ ditr++) {
+
+ PutSymbolSummaryLine( report, count, ditr );
+ count++;
+ }
+
+ CloseSymbolSummaryFile( report );
+}
+
+
+void GenerateReports()
+{
+ typedef std::list<ReportsBase *> reportList_t;
+
+ reportList_t reportList;
+ reportList_t::iterator ritr;
+ std::string reportName;
+ ReportsBase* reports;
+
+ time_t timestamp;
+
+<span style="background-color: #FF0000"> </span>
+ timestamp = time(NULL); /* get current cal time */
+ reports = new ReportsText(timestamp);
+ reportList.push_back(reports);
+ reports = new ReportsHtml(timestamp);
+ reportList.push_back(reports);
+
+ for (ritr = reportList.begin(); ritr != reportList.end(); ritr++ ) {
+ reports = *ritr;
+
+ reportName = "index" + reports->ReportExtension();
+ if (Verbose)
+ fprintf(
+ stderr, "Generate %s\n", reportName.c_str()
+ );
+ reports->WriteIndex( reportName.c_str() );
+
+ reportName = "annotated" + reports->ReportExtension();
+ if (Verbose)
+ fprintf(
+ stderr, "Generate %s\n", reportName.c_str()
+ );
+ reports->WriteAnnotatedReport( reportName.c_str() );
+
+ reportName = "branch" + reports->ReportExtension();
+ if (Verbose)
+ fprintf(
+ stderr, "Generate %s\n", reportName.c_str()
+ );
+ reports->WriteBranchReport(reportName.c_str() );
+
+ reportName = "uncovered" + reports->ReportExtension();
+ if (Verbose)
+ fprintf(
+ stderr, "Generate %s\n", reportName.c_str()
+ );
+ reports->WriteCoverageReport(reportName.c_str() );
+
+ reportName = "sizes" + reports->ReportExtension();
+ if (Verbose)
+ fprintf(
+ stderr, "Generate %s\n", reportName.c_str()
+ );
+ reports->WriteSizeReport(reportName.c_str() );
+
+ reportName = "symbolSummary" + reports->ReportExtension();
+ if (Verbose)
+ fprintf(
+ stderr, "Generate %s\n", reportName.c_str()
+ );
+ reports->WriteSymbolSummaryReport(reportName.c_str() );
+ }
+
+ for (ritr = reportList.begin(); ritr != reportList.end(); ritr++ ) {
+ reports = *ritr;
+ delete reports;
+ }
+<span style="background-color: #FF0000"> </span>
+}
+
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/ReportsHtml.h:1.1
--- /dev/null Mon May 24 15:10:06 2010
+++ gcc-testing/covoar/ReportsHtml.h Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,209 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file ReportsHtml.h
+ * @brief Reports in HTML Specification
+ *
+ * This file contains the specification of the Reports methods. This
+ * collection of methods is used to generate the various reports of
+ * the analysis results.
+ */
+
+#ifndef __REPORTSHTML_H__
+#define __REPORTSHTML_H__
+
+#include <stdint.h>
+#include "ReportsBase.h"
+#include "Explanations.h"
+
+namespace Coverage {
+
+/*!
+ * This class contains all methods and data necessary to
+ * do all of the HTML style reports.
+ */
+class ReportsHtml: public ReportsBase {
+
+ public:
+ ReportsHtml( time_t timestamp );
+ ~ReportsHtml();
+
+ /*!
+ * This method produces an index file.
+ *
+ * @param[in] fileName identifies the file name.
+ */
+ void WriteIndex(
+ const char* const fileName
+ );
+
+ /*!
+ * This method produces a report that contains information about each
+ * uncovered branch statement.
+ *
+ * @param[in] fileName identifies the branch report file name
+ */
+ void WriteBranchReport(
+ const char* const fileName
+ );
+
+ /*!
+ * This method produces a report that contains information about each
+ * uncovered range of bytes.
+ *
+ * @param[in] fileName identifies the coverage report file name
+ */
+ void WriteCoverageReport(
+ const char* const fileName
+ );
+
+ /*!
+ * This method produces a summary report that lists each uncovered
+ * range of bytes.
+ *
+ * @param[in] fileName identifies the size report file name
+ */
+ void WriteSizeReport(
+ const char* const fileName
+ );
+
+ protected:
+
+ /*!
+ * This variable tracks the annotated state at the time the<span style="background-color: #FF0000"> </span>
+ * last line was output. This allows the text formating to change
+ * based upon the type of lines being put out: source code or assembly
+ * object dump line....
+ */
+ AnnotatedLineState_t lastState_m;
+
+ /* Inherit documentation from base class. */<span style="background-color: #FF0000"> </span>
+ virtual FILE* OpenAnnotatedFile(
+ const char* const fileName
+ );
+
+ /* Inherit documentation from base class. */<span style="background-color: #FF0000"> </span>
+ virtual FILE* OpenBranchFile(
+ const char* const fileName,
+ bool hasBranches
+ );
+
+ /* Inherit documentation from base class. */<span style="background-color: #FF0000"> </span>
+ virtual FILE* OpenCoverageFile(
+ const char* const fileName
+ );
+
+ /* Inherit documentation from base class. */<span style="background-color: #FF0000"> </span>
+ FILE* OpenNoRangeFile(
+ const char* const fileName
+ );
+
+ /* Inherit documentation from base class. */<span style="background-color: #FF0000"> </span>
+ virtual FILE* OpenSizeFile(
+ const char* const fileName
+ );
+
+ /* Inherit documentation from base class. */<span style="background-color: #FF0000"> </span>
+ virtual FILE* OpenSymbolSummaryFile(
+ const char* const fileName
+ );
+
+ /* Inherit documentation from base class. */<span style="background-color: #FF0000"> </span>
+ virtual void CloseAnnotatedFile(
+ FILE* aFile
+ );
+
+ /* Inherit documentation from base class. */<span style="background-color: #FF0000"> </span>
+ virtual void CloseBranchFile(
+ FILE* aFile,
+ bool hasBranches
+ );
+
+ /* Inherit documentation from base class. */<span style="background-color: #FF0000"> </span>
+ virtual void CloseCoverageFile(
+ FILE* aFile
+ );
+
+ /* Inherit documentation from base class. */<span style="background-color: #FF0000"> </span>
+ void CloseNoRangeFile(
+ FILE* aFile
+ );
+
+ /* Inherit documentation from base class. */<span style="background-color: #FF0000"> </span>
+ virtual void CloseSizeFile(
+ FILE* aFile
+ );
+
+ /* Inherit documentation from base class. */<span style="background-color: #FF0000"> </span>
+ virtual void CloseSymbolSummaryFile(
+ FILE* aFile
+ );
+
+ /* Inherit documentation from base class. */<span style="background-color: #FF0000"> </span>
+ virtual void PutAnnotatedLine(<span style="background-color: #FF0000"> </span>
+ FILE* aFile,<span style="background-color: #FF0000"> </span>
+ AnnotatedLineState_t state,<span style="background-color: #FF0000"> </span>
+ std::string line,<span style="background-color: #FF0000"> </span>
+ uint32_t id<span style="background-color: #FF0000"> </span>
+ );
+
+ /* Inherit documentation from base class. */<span style="background-color: #FF0000"> </span>
+ virtual bool PutNoBranchInfo(
+ FILE* report
+ );
+
+ /* Inherit documentation from base class. */<span style="background-color: #FF0000"> </span>
+ virtual bool PutBranchEntry(
+ FILE* report,
+ unsigned int number,
+ Coverage::DesiredSymbols::symbolSet_t::iterator symbolPtr,
+ Coverage::CoverageRanges::ranges_t::iterator rangePtr
+ );
+
+ /* Inherit documentation from base class. */<span style="background-color: #FF0000"> </span>
+ virtual void putCoverageNoRange(
+ FILE* report,
+ FILE* noRangeFile,
+ unsigned int number,
+ std::string symbol
+ );
+
+ /* Inherit documentation from base class. */<span style="background-color: #FF0000"> </span>
+ virtual bool PutCoverageLine(
+ FILE* report,
+ unsigned int number,
+ Coverage::DesiredSymbols::symbolSet_t::iterator ditr,
+ Coverage::CoverageRanges::ranges_t::iterator ritr
+ );
+
+ /* Inherit documentation from base class. */<span style="background-color: #FF0000"> </span>
+ virtual bool PutSizeLine(
+ FILE* report,
+ unsigned int number,
+ Coverage::DesiredSymbols::symbolSet_t::iterator symbol,
+ Coverage::CoverageRanges::ranges_t::iterator range
+ );
+
+ /* Inherit documentation from base class. */<span style="background-color: #FF0000"> </span>
+ virtual bool PutSymbolSummaryLine(
+ FILE* report,
+ unsigned int number,
+ Coverage::DesiredSymbols::symbolSet_t::iterator symbol
+ );
+
+ /* Inherit documentation from base class. */<span style="background-color: #FF0000"> </span>
+ virtual FILE* OpenFile(
+ const char* const fileName
+ );
+
+ /* Inherit documentation from base class. */<span style="background-color: #FF0000"> </span>
+ virtual bool WriteExplationFile(
+ const char* fileName,
+ const Coverage::Explanation* explanation
+ );
+ };
+
+}
+
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/ReportsHtml.cc:1.1
--- /dev/null Mon May 24 15:10:06 2010
+++ gcc-testing/covoar/ReportsHtml.cc Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,1024 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "ReportsHtml.h"
+#include "app_common.h"
+#include "CoverageRanges.h"
+#include "DesiredSymbols.h"
+#include "ObjdumpProcessor.h"
+
+#if 0
+#define TABLE_HEADER_CLASS \
+ " table-autopage:10 table-page-number:pagenum table-page-count:pages "
+#define TABLE_FOOTER \
+ "<tfoot>\n" \
+ "<tr>\n" \
+ "<td class=\"table-page:previous\" " \
+ "style=\"cursor:pointer;\">< < Previous</td>\n" \
+ "<td colspan=\"4\" style=\"text-align:center;\">Page " \
+ "<span id=\"pagenum\"></span> of <span id=\"pages\"></span></td>\n" \
+ "<td class=\"table-page:next\" " \
+ "style=\"cursor:pointer;\">Next > ></td>\n" \
+ "</tr>\n" \
+ "</tfoot>\n"
+#else
+#define TABLE_HEADER_CLASS
+#define TABLE_FOOTER<span style="background-color: #FF0000"> </span>
+#endif
+
+namespace Coverage {
+
+ ReportsHtml::ReportsHtml( time_t timestamp ):
+ ReportsBase( timestamp )
+ {
+ reportExtension_m = ".html";
+ }
+
+ ReportsHtml::~ReportsHtml()
+ {
+ }
+
+ void ReportsHtml::WriteIndex(
+ const char* const fileName
+ )
+ {
+ #define PRINT_ITEM( _t, _n ) \
+ fprintf( \
+ aFile, \
+ "<li>%s (<a href=\"%s.html\">html</a> or "\
+ "<a href=\"%s.txt\">text</a>)</li>\n", \
+ _t, _n, _n );
+ #define PRINT_TEXT_ITEM( _t, _n ) \
+ fprintf( \
+ aFile, \
+ "<li>%s (<a href=\"%s\">text</a>)\n", \
+ _t, _n );
+
+ FILE* aFile;
+<span style="background-color: #FF0000"> </span>
+ // Open the file
+ aFile = OpenFile( fileName );
+
+ fprintf(
+ aFile,
+ "<title>Index</title>\n"
+ "<div class=\"heading-title\">"
+ );
+
+ if (projectName)
+ fprintf(
+ aFile,
+ "%s</br>",
+ projectName
+ );
+
+ fprintf(
+ aFile,
+ "Coverage Analysis Reports</div>\n"
+ "<div class =\"datetime\">%s</div>\n",
+ asctime( localtime(×tamp_m) )<span style="background-color: #FF0000"> </span>
+ );
+
+ fprintf( aFile, "<ul>\n" );
+
+ PRINT_ITEM( "Coverage Report", "uncovered" );
+ PRINT_ITEM( "Branch Report", "branch" );
+ PRINT_ITEM( "Annotated Assembly", "annotated" );
+ PRINT_ITEM( "Symbol Summary", "symbolSummary" );
+ PRINT_ITEM( "Size Report", "sizes" );
+
+ PRINT_TEXT_ITEM( "Explanations Not Found", "ExplanationsNotFound.txt" );
+
+ fprintf(
+ aFile,
+ "</li>\n"
+ "<!-- INSERT PROJECT SPECIFIC ITEMS HERE -->\n"
+ "</html>\n"
+ );
+
+ CloseFile( aFile );
+
+ #undef PRINT_ITEM
+ #undef PRINT_TEXT_ITEM
+ }
+
+ FILE* ReportsHtml::OpenFile(
+ const char* const fileName
+ )
+ {
+ FILE* aFile;
+<span style="background-color: #FF0000"> </span>
+ // Open the file
+ aFile = ReportsBase::OpenFile( fileName );
+
+ // Put Header information on the file
+ fprintf(
+ aFile,
+ "<html>\n"
+ "<meta http-equiv=\"Content-Language\" content=\"English\" >\n"
+ "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=us-ascii\" >\n"
+ "<link rel=\"stylesheet\" type=\"text/css\" href=\"covoar.css\" media=\"screen\" >\n"
+ "<script type=\"text/javascript\" src=\"table.js\"></script>\n"
+ );
+
+ return aFile;
+ }
+
+ FILE* ReportsHtml::OpenAnnotatedFile(
+ const char* const fileName
+ )
+ {
+ FILE *aFile;
+
+ // Open the file
+ aFile = OpenFile(fileName);
+
+ fprintf(
+ aFile,
+ "<title>Annotated Report</title>\n"
+ "<div class=\"heading-title\">"
+ );
+
+ if (projectName)
+ fprintf(
+ aFile,
+ "%s</br>",
+ projectName
+ );
+
+ fprintf(
+ aFile,
+ "Annotated Report</div>\n"
+ "<div class =\"datetime\">%s</div>\n"
+ "<body>\n"
+ "<pre class=\"code\">\n",
+ asctime( localtime(×tamp_m) )<span style="background-color: #FF0000"> </span>
+ );
+
+ return aFile;
+ }
+
+ FILE* ReportsHtml::OpenBranchFile(
+ const char* const fileName,
+ bool hasBranches
+ )
+ {
+ FILE *aFile;
+
+ // Open the file
+ aFile = OpenFile(fileName);
+
+ if ( hasBranches ) {
+ // Put header information into the file
+ fprintf(
+ aFile,
+ "<title>Branch Report</title\n"
+ "<div class=\"heading-title\">"
+ );
+
+ if (projectName)
+ fprintf(
+ aFile,
+ "%s</br>",
+ projectName
+ );
+
+ fprintf(
+ aFile,
+ "Branch Report</div>\n"
+ "<div class =\"datetime\">%s</div>\n"
+ "<body>\n"
+ "<table class=\"covoar table-autosort:0 table-autofilter table-stripeclass:covoar-tr-odd"
+ TABLE_HEADER_CLASS "\">\n"
+ "<thead>\n"
+ "<tr>\n"
+ "<th class=\"table-sortable:default\" align=\"left\">Symbol</th>\n"
+ "<th class=\"table-sortable:default\" align=\"left\">Line</th>\n"
+ "<th class=\"table-filterable table-sortable:default\" align=\"left\">File</th>\n"
+ "<th class=\"table-sortable:numeric\" align=\"left\">Size </br>Bytes</th>\n"
+ "<th class=\"table-sortable:default\" align=\"left\">Reason</th>\n"
+ "<th class=\"table-filterable table-sortable:default\" align=\"left\">Classification</th>\n"
+ "<th class=\"table-sortable:default\" align=\"left\">Explanation</th>\n"
+ "</tr>\n"
+ "</thead>\n"
+ "<tbody>\n",
+ asctime( localtime(×tamp_m) )<span style="background-color: #FF0000"> </span>
+ );
+ }
+<span style="background-color: #FF0000"> </span>
+ return aFile;
+ }
+
+ FILE* ReportsHtml::OpenCoverageFile(
+ const char* const fileName
+ )
+ {
+ FILE *aFile;
+
+ // Open the file
+ aFile = OpenFile(fileName);
+
+ // Put header information into the file
+ fprintf(
+ aFile,
+ "<title>Coverage Report</title>\n"
+ "<div class=\"heading-title\">"
+ );
+
+ if (projectName)
+ fprintf(
+ aFile,
+ "%s</br>",
+ projectName
+ );
+
+ fprintf(
+ aFile,
+ "Coverage Report</div>\n"
+ "<div class =\"datetime\">%s</div>\n"
+ "<body>\n"
+ "<table class=\"covoar table-autosort:0 table-autofilter table-stripeclass:covoar-tr-odd"
+ TABLE_HEADER_CLASS "\">\n"
+ "<thead>\n"
+ "<tr>\n"
+ "<th class=\"table-sortable:default\" align=\"left\">Symbol</th>\n"
+ "<th class=\"table-sortable:default\" align=\"left\">Range</th>\n"
+ "<th class=\"table-filterable table-sortable:default\" align=\"left\">File</th>\n"
+ "<th class=\"table-sortable:numeric\" align=\"left\">Size </br>Bytes</th>\n"
+ "<th class=\"table-sortable:numeric\" align=\"left\">Size </br>Instructions</th>\n"
+ "<th class=\"table-filterable table-sortable:default\" align=\"left\">Classification</th>\n"
+ "<th class=\"table-sortable:default\" align=\"left\">Explanation</th>\n"
+ "</tr>\n"
+ "</thead>\n"
+ "<tbody>\n",
+ asctime( localtime(×tamp_m) )<span style="background-color: #FF0000"> </span>
+
+ );
+
+ return aFile;
+ }
+
+ FILE* ReportsHtml::OpenNoRangeFile(
+ const char* const fileName
+ )
+ {
+ FILE *aFile;
+
+ // Open the file
+ aFile = OpenFile(fileName);
+
+ // Put header information into the file
+ fprintf(
+ aFile,
+ "<title> Report</title>\n"
+ "<div class=\"heading-title\">"
+ );
+
+ if (projectName)
+ fprintf(
+ aFile,
+ "%s</br>",
+ projectName
+ );
+
+ fprintf(
+ aFile,
+ "No Range Report</div>\n"
+ "<div class =\"datetime\">%s</div>\n"
+ "<body>\n"
+ "<table class=\"covoar table-autosort:0 table-autofilter table-stripeclass:covoar-tr-odd"
+ TABLE_HEADER_CLASS "\">\n"
+ "<thead>\n"
+ "<tr>\n"
+ "<th class=\"table-sortable:default\" align=\"left\">Symbol</th>\n"
+ "</tr>\n"
+ "</thead>\n"
+ "<tbody>\n",
+ asctime( localtime(×tamp_m) )<span style="background-color: #FF0000"> </span>
+
+ );
+
+ return aFile;
+ }
+
+
+
+ FILE* ReportsHtml::OpenSizeFile(
+ const char* const fileName
+ )
+ {
+ FILE *aFile;
+
+ // Open the file
+ aFile = OpenFile(fileName);
+
+ // Put header information into the file
+ fprintf(
+ aFile,
+ "<title>Size Report</title>\n"
+ "<div class=\"heading-title\">"
+ );
+
+ if (projectName)
+ fprintf(
+ aFile,
+ "%s</br>",
+ projectName
+ );
+
+ fprintf(
+ aFile,
+ "Size Report</div>\n"
+ "<div class =\"datetime\">%s</div>\n"
+ "<body>\n"
+ "<table class=\"covoar table-autosort:0 table-autofilter table-stripeclass:covoar-tr-odd"
+ TABLE_HEADER_CLASS "\">\n"
+ "<thead>\n"
+ "<tr>\n"
+ "<th class=\"table-sortable:numeric\" align=\"left\">Size</th>\n"
+ "<th class=\"table-sortable:default\" align=\"left\">Symbol</th>\n"
+ "<th class=\"table-sortable:default\" align=\"left\">Line</th>\n"
+ "<th class=\"table-filterable table-sortable:default\" align=\"left\">File</th>\n"
+ "</tr>\n"
+ "</thead>\n"
+ "<tbody>\n",
+ asctime( localtime(×tamp_m) )<span style="background-color: #FF0000"> </span>
+
+ );
+ return aFile;
+ }
+
+ FILE* ReportsHtml::OpenSymbolSummaryFile(
+ const char* const fileName
+ )
+ {
+ FILE *aFile;
+
+ // Open the file
+ aFile = OpenFile(fileName);
+
+ // Put header information into the file
+ fprintf(
+ aFile,
+ "<title>Symbol Summary Report</title>\n"
+ "<div class=\"heading-title\">"
+ );
+
+ if (projectName)
+ fprintf(
+ aFile,
+ "%s</br>",
+ projectName
+ );
+
+ fprintf(
+ aFile,
+ "Symbol Summary Report</div>\n"
+ "<div class =\"datetime\">%s</div>\n"
+ "<body>\n"
+ "<table class=\"covoar table-autosort:0 table-autofilter table-stripeclass:covoar-tr-odd"
+ TABLE_HEADER_CLASS "\">\n"
+ "<thead>\n"
+ "<tr>\n"
+ "<th class=\"table-sortable:default\" align=\"center\">Symbol</th>\n"
+ "<th class=\"table-sortable:numeric\" align=\"center\">Total</br>Size</br>Bytes</th>\n"
+ "<th class=\"table-sortable:numeric\" align=\"center\">Total</br>Size</br>Instr</th>\n"
+ "<th class=\"table-sortable:default\" align=\"center\">#</br>Ranges</th>\n"
+ "<th class=\"table-sortable:numeric\" align=\"center\">Uncovered</br>Size</br>Bytes</th>\n"
+ "<th class=\"table-sortable:numeric\" align=\"center\">Uncovered</br>Size</br>Instr</th>\n"
+ "<th class=\"table-sortable:default\" align=\"center\">#</br>Branches</th>\n"
+ "<th class=\"table-sortable:default\" align=\"center\">#</br>Always</br>Taken</th>\n"
+ "<th class=\"table-sortable:default\" align=\"center\">#</br>Never</br>Taken</th>\n"
+ "<th class=\"table-sortable:numeric\" align=\"center\">Percent</br>Uncovered</br>Instructions</th>\n"
+ "<th class=\"table-sortable:numeric\" align=\"center\">Percent</br>Uncovered</br>Bytes</th>\n"
+ "</tr>\n"
+ "</thead>\n"
+ "<tbody>\n",
+ asctime( localtime(×tamp_m) )<span style="background-color: #FF0000"> </span>
+
+ );
+ return aFile;
+ }
+
+ void ReportsHtml::PutAnnotatedLine(<span style="background-color: #FF0000"> </span>
+ FILE* aFile,<span style="background-color: #FF0000"> </span>
+ AnnotatedLineState_t state,<span style="background-color: #FF0000"> </span>
+ std::string line,<span style="background-color: #FF0000"> </span>
+ uint32_t id<span style="background-color: #FF0000"> </span>
+ )
+ {
+ std::string stateText;
+ char number[10];
+
+<span style="background-color: #FF0000"> </span>
+ sprintf(number,"%d", id);
+
+ // Set the stateText based upon the current state.
+ switch (state) {
+ case A_SOURCE:
+ stateText = "</pre>\n<pre class=\"code\">\n";
+ break;
+ case A_EXECUTED:
+ stateText = "</pre>\n<pre class=\"codeExecuted\">\n";
+ break;
+ case A_NEVER_EXECUTED:
+ stateText = "</pre>\n";
+ stateText += "<a name=\"range";
+ stateText += number;
+ stateText += "\"></a><pre class=\"codeNotExecuted\">\n";
+ break;
+ case A_BRANCH_TAKEN:
+ stateText = "</pre>\n";
+ stateText += "<a name=\"range";
+ stateText += number;
+ stateText += "\"></a><pre class=\"codeAlwaysTaken\">\n";
+ break;
+ case A_BRANCH_NOT_TAKEN:
+ stateText = "</pre>\n";
+ stateText += "<a name=\"range";
+ stateText += number;
+ stateText += "\"></a><pre class=\"codeNeverTaken\">\n";
+ break;
+ default:
+ fprintf(stderr, "ERROR: ReportsHtml::PutAnnotatedLine Unknown state\n");
+ exit( -1 );
+ break;
+ }
+
+ // If the state has not changed there is no need to change the text block
+ // format. If it has changed close out the old format and open up the
+ // new format.
+ if ( state != lastState_m ) {
+ fprintf( aFile, stateText.c_str() );
+ lastState_m = state;
+ }
+
+ // For all the characters in the line replace html reserved special
+ // characters and output the line. Note that for a /pre block this
+ // is only a '<' symbol.
+ for (unsigned int i=0; i<line.size(); i++ ) {
+ if ( line[i] == '<' )
+ fprintf( aFile, "<" );
+ else
+ fprintf( aFile, "%c", line[i] );
+ }
+ fprintf( aFile, "\n");
+ }
+
+ bool ReportsHtml::PutNoBranchInfo(
+ FILE* report
+ )
+ {
+ if ( BranchInfoAvailable )
+ fprintf( report, "All branch paths taken.\n" );
+ else
+ fprintf( report, "No branch information found.\n" );
+ return true;
+ }
+
+ bool ReportsHtml::PutBranchEntry(
+ FILE* report,
+ unsigned int count,
+ Coverage::DesiredSymbols::symbolSet_t::iterator symbolPtr,
+ Coverage::CoverageRanges::ranges_t::iterator rangePtr
+ )
+ {
+ const Coverage::Explanation* explanation;
+ std::string temp;
+ int i;
+
+ // Mark the background color different for odd and even lines.
+ if ( ( count%2 ) != 0 )
+ fprintf( report, "<tr class=\"covoar-tr-odd\">\n");
+ else
+ fprintf( report, "<tr>\n");
+
+ // symbol
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">%s</td>\n",<span style="background-color: #FF0000"> </span>
+ symbolPtr->first.c_str()
+ );
+
+ // line
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\"><a href =\"annotated.html#range%d\">%s</td>\n",<span style="background-color: #FF0000"> </span>
+ rangePtr->id,
+ rangePtr->lowSourceLine.c_str()
+ );
+
+ // File
+ i = rangePtr->lowSourceLine.find(":");
+ temp = rangePtr->lowSourceLine.substr (0, i);
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">%s</td>\n",<span style="background-color: #FF0000"> </span>
+ temp.c_str()
+ );
+<span style="background-color: #FF0000"> </span>
+ // Size in bytes
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">%d</td>\n",
+ rangePtr->highAddress - rangePtr->lowAddress + 1
+ );
+
+ // Reason Branch was uncovered
+ if (rangePtr->reason ==
+ Coverage::CoverageRanges::UNCOVERED_REASON_BRANCH_ALWAYS_TAKEN)
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,
+ "<td class=\"covoar-td\" align=\"center\">Always Taken</td>\n"
+ );
+ else if (rangePtr->reason ==
+ Coverage::CoverageRanges::UNCOVERED_REASON_BRANCH_NEVER_TAKEN)
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">Never Taken</td>\n"
+ );
+
+ // See if an explanation is available and write the Classification and
+ // the Explination Columns.
+ explanation = AllExplanations->lookupExplanation( rangePtr->lowSourceLine );
+ if ( !explanation ) {
+ // Write Classification
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">NONE</td>\n"
+ "<td class=\"covoar-td\" align=\"center\">No Explanation</td>\n"
+ );
+ } else {
+ char explanationFile[48];
+ sprintf( explanationFile, "explanation%d.html", rangePtr->id );
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">%s</td>\n"
+ "<td class=\"covoar-td\" align=\"center\">"
+ "<a href=\"%s\">Explanation</a></td>\n",
+ explanation->classification.c_str(),
+ explanationFile
+ );
+ WriteExplationFile( explanationFile, explanation );
+ }
+
+ fprintf( report, "</tr>\n");
+
+ return true;
+ }
+
+ bool ReportsHtml::WriteExplationFile(
+ const char* fileName,
+ const Coverage::Explanation* explanation
+ )
+ {
+ FILE* report;
+
+ report = OpenFile( fileName );
+
+ for ( unsigned int i=0 ; i < explanation->explanation.size(); i++) {
+ fprintf(
+ report,
+ "%s\n",
+ explanation->explanation[i].c_str()
+ );
+ }
+ CloseFile( report );
+ return true;
+ }
+
+ void ReportsHtml::putCoverageNoRange(
+ FILE* report,
+ FILE* noRangeFile,
+ unsigned int count,
+ std::string symbol
+ )
+ {
+ Coverage::Explanation explanation;
+
+ explanation.explanation.push_back(
+ "<html><p>\n"
+ "This symbol was never referenced by an analyzed executable. "
+ "Therefore there is no size or disassembly for this symbol. "
+ "This could be due to symbol misspelling or lack of a test for "
+ "this symbol."
+ "</p></html>\n"
+ );
+
+ // Mark the background color different for odd and even lines.
+ if ( ( count%2 ) != 0 ){
+ fprintf( report, "<tr class=\"covoar-tr-odd\">\n");
+ fprintf( noRangeFile, "<tr class=\"covoar-tr-odd\">\n");
+ } else {
+ fprintf( report, "<tr>\n");
+ fprintf( noRangeFile, "<tr>\n");
+ }
+
+ // symbol
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">%s</td>\n",<span style="background-color: #FF0000"> </span>
+ symbol.c_str()
+ );
+ fprintf(<span style="background-color: #FF0000"> </span>
+ noRangeFile,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">%s</td>\n",<span style="background-color: #FF0000"> </span>
+ symbol.c_str()
+ );
+
+ // starting line
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">unknown</td>\n"
+ );
+<span style="background-color: #FF0000"> </span>
+ // file
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">unknown</td>\n"
+ );
+<span style="background-color: #FF0000"> </span>
+ // Size in bytes
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">unknown</td>\n"
+ );
+
+ // Size in instructions
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">unknown</td>\n"
+ );<span style="background-color: #FF0000"> </span>
+
+ // See if an explanation is available
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">Unknown</td>\n"
+ "<td class=\"covoar-td\" align=\"center\">"
+ "<a href=\"NotReferenced.html\">No data</a></td>\n"
+ );
+ WriteExplationFile( "NotReferenced.html", &explanation );
+
+ fprintf( report, "</tr>\n");
+ fprintf( noRangeFile, "</tr>\n");
+ }
+
+ bool ReportsHtml::PutCoverageLine(
+ FILE* report,
+ unsigned int count,
+ Coverage::DesiredSymbols::symbolSet_t::iterator symbolPtr,
+ Coverage::CoverageRanges::ranges_t::iterator rangePtr
+ )
+ {
+ const Coverage::Explanation* explanation;
+ std::string temp;
+ int i;
+
+ // Mark the background color different for odd and even lines.
+ if ( ( count%2 ) != 0 )
+ fprintf( report, "<tr class=\"covoar-tr-odd\">\n");
+ else
+ fprintf( report, "<tr>\n");
+
+ // symbol
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">%s</td>\n",<span style="background-color: #FF0000"> </span>
+ symbolPtr->first.c_str()
+ );
+
+ // Range
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\"><a href =\"annotated.html#range%d\">%s </br>%s</td>\n",
+ rangePtr->id,<span style="background-color: #FF0000"> </span>
+ rangePtr->lowSourceLine.c_str(),
+ rangePtr->highSourceLine.c_str()
+ );
+
+ // File
+ i = rangePtr->lowSourceLine.find(":");
+ temp = rangePtr->lowSourceLine.substr (0, i);
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">%s</td>\n",<span style="background-color: #FF0000"> </span>
+ temp.c_str()
+ );
+<span style="background-color: #FF0000"> </span>
+ // Size in bytes
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">%d</td>\n",
+ rangePtr->highAddress - rangePtr->lowAddress + 1
+ );
+
+ // Size in instructions
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">%d</td>\n",
+ rangePtr->instructionCount
+ );<span style="background-color: #FF0000"> </span>
+
+ // See if an explanation is available
+ explanation = AllExplanations->lookupExplanation( rangePtr->lowSourceLine );
+ if ( !explanation ) {
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">NONE</td>\n"
+ );
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">No Explanation</td>\n"
+ );
+ } else {
+ char explanationFile[48];
+
+ sprintf( explanationFile, "explanation%d.html", rangePtr->id );
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">%s</td>\n"
+ "<td class=\"covoar-td\" align=\"center\">"
+ "<a href=\"%s\">Explanation</a></td>\n",
+ explanation->classification.c_str(),
+ explanationFile
+ );
+ WriteExplationFile( explanationFile, explanation );
+ }
+
+ fprintf( report, "</tr>\n");
+
+ return true;
+ }
+
+ bool ReportsHtml::PutSizeLine(
+ FILE* report,
+ unsigned int count,
+ Coverage::DesiredSymbols::symbolSet_t::iterator symbol,
+ Coverage::CoverageRanges::ranges_t::iterator range
+ )
+ {
+ std::string temp;
+ int i;
+
+ // Mark the background color different for odd and even lines.
+ if ( ( count%2 ) != 0 )
+ fprintf( report, "<tr class=\"covoar-tr-odd\">\n");
+ else
+ fprintf( report, "<tr>\n");
+
+ // size
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">%d</td>\n",
+ range->highAddress - range->lowAddress + 1
+ );
+
+ // symbol
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">%s</td>\n",<span style="background-color: #FF0000"> </span>
+ symbol->first.c_str()
+ );
+
+ // line
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\"><a href =\"annotated.html#range%d\">%s</td>\n",<span style="background-color: #FF0000"> </span>
+ range->id,
+ range->lowSourceLine.c_str()
+ );
+
+ // File
+ i = range->lowSourceLine.find(":");
+ temp = range->lowSourceLine.substr (0, i);
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">%s</td>\n",<span style="background-color: #FF0000"> </span>
+ temp.c_str()
+ );
+<span style="background-color: #FF0000"> </span>
+ fprintf( report, "</tr>\n");
+
+ return true;
+ }
+
+ bool ReportsHtml::PutSymbolSummaryLine(
+ FILE* report,
+ unsigned int count,
+ Coverage::DesiredSymbols::symbolSet_t::iterator symbol
+ )
+ {
+<span style="background-color: #FF0000"> </span>
+ // Mark the background color different for odd and even lines.
+ if ( ( count%2 ) != 0 )
+ fprintf( report, "<tr class=\"covoar-tr-odd\">\n");
+ else
+ fprintf( report, "<tr>\n");
+
+ // symbol
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">%s</td>\n",<span style="background-color: #FF0000"> </span>
+ symbol->first.c_str()
+ );
+
+ // Total Size in Bytes
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">%d</td>\n",
+ symbol->second.stats.sizeInBytes
+ );
+
+ // Total Size in Instructions<span style="background-color: #FF0000"> </span>
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">%d</td>\n",
+ symbol->second.stats.sizeInInstructions
+ );
+
+ // Total Uncovered Ranges
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">%d</td>\n",<span style="background-color: #FF0000"> </span>
+ symbol->second.stats.uncoveredRanges
+ );
+
+ // Uncovered Size in Bytes
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">%d</td>\n",
+ symbol->second.stats.uncoveredBytes
+ );
+
+ // Uncovered Size in Instructions<span style="background-color: #FF0000"> </span>
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">%d</td>\n",
+ symbol->second.stats.uncoveredInstructions
+ );
+
+ // Total number of branches
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">%d</td>\n",<span style="background-color: #FF0000"> </span>
+ symbol->second.stats.branchesNotExecuted + symbol->second.stats.branchesExecuted
+ );
+
+ // Total Always Taken
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">%d</td>\n",
+ symbol->second.stats.branchesAlwaysTaken
+ );
+
+ // Total Never Taken
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">%d</td>\n",
+ symbol->second.stats.branchesNeverTaken
+ );
+
+ // % Uncovered Instructions
+ if ( symbol->second.stats.sizeInInstructions == 0 )
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">100.00</td>\n"
+ );
+ else<span style="background-color: #FF0000"> </span>
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">%.2f</td>\n",
+ (symbol->second.stats.uncoveredInstructions*100.0)/
+ symbol->second.stats.sizeInInstructions
+ );
+
+ // % Uncovered Bytes
+ if ( symbol->second.stats.sizeInBytes == 0 )
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">100.00</td>\n"
+ );
+ else<span style="background-color: #FF0000"> </span>
+ fprintf(<span style="background-color: #FF0000"> </span>
+ report,<span style="background-color: #FF0000"> </span>
+ "<td class=\"covoar-td\" align=\"center\">%.2f</td>\n",
+ (symbol->second.stats.uncoveredBytes*100.0)/
+ symbol->second.stats.sizeInBytes
+ );
+
+ fprintf( report, "</tr>\n");
+ return true;
+ }
+
+ void ReportsHtml::CloseAnnotatedFile(
+ FILE* aFile
+ )
+ {
+ fprintf(
+ aFile,
+ "</pre>\n"
+ "</body>\n"
+ "</html>"
+ );
+
+ CloseFile(aFile);
+ }
+
+ void ReportsHtml::CloseBranchFile(
+ FILE* aFile,
+ bool hasBranches
+ )
+ {
+ if ( hasBranches ) {
+ fprintf(
+ aFile,
+ TABLE_FOOTER
+ "</tbody>\n"
+ "</table>\n"<span style="background-color: #FF0000"> </span>
+ );
+ }
+ fprintf(
+ aFile,
+ "</pre>\n"<span style="background-color: #FF0000"> </span>
+ "</body>\n"
+ "</html>"
+ );
+
+ CloseFile(aFile);
+ }
+
+ void ReportsHtml::CloseCoverageFile(
+ FILE* aFile
+ )
+ {
+ fprintf(
+ aFile,
+ TABLE_FOOTER
+ "</tbody>\n"
+ "</table>\n"<span style="background-color: #FF0000"> </span>
+ "</pre>\n"<span style="background-color: #FF0000"> </span>
+ "</body>\n"
+ "</html>"
+ );
+
+ CloseFile(aFile);
+ }
+
+ void ReportsHtml::CloseNoRangeFile(
+ FILE* aFile
+ )
+ {
+ fprintf(
+ aFile,
+ TABLE_FOOTER
+ "</tbody>\n"
+ "</table>\n"<span style="background-color: #FF0000"> </span>
+ "</pre>\n"<span style="background-color: #FF0000"> </span>
+ "</body>\n"
+ "</html>"
+ );
+
+ CloseFile(aFile);
+ }
+
+
+ void ReportsHtml::CloseSizeFile(
+ FILE* aFile
+ )
+ {
+ fprintf(
+ aFile,
+ TABLE_FOOTER
+ "</tbody>\n"
+ "</table>\n"<span style="background-color: #FF0000"> </span>
+ "</pre>\n"<span style="background-color: #FF0000"> </span>
+ "</body>\n"
+ "</html>"
+ );
+
+ CloseFile( aFile );
+ }
+
+ void ReportsHtml::CloseSymbolSummaryFile(
+ FILE* aFile
+ )
+ {
+ fprintf(
+ aFile,
+ TABLE_FOOTER
+ "</tbody>\n"
+ "</table>\n"<span style="background-color: #FF0000"> </span>
+ "</pre>\n"<span style="background-color: #FF0000"> </span>
+ "</body>\n"
+ "</html>"
+ );
+
+ CloseFile( aFile );
+ }
+
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/ReportsText.h:1.1
--- /dev/null Mon May 24 15:10:06 2010
+++ gcc-testing/covoar/ReportsText.h Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,112 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file ReportsText.h
+ * @brief Reports Text Format Write Specification
+ *
+ * This file contains the specification of the Reports methods. This
+ * collection of methods is used to generate the various reports of
+ * the analysis results.
+ */
+
+#ifndef __REPORTSTEXT_H__
+#define __REPORTSTEXT_H__
+
+#include <stdint.h>
+#include "ReportsBase.h"
+
+namespace Coverage {
+
+/*!
+ * This class contains all methods and data necessary to
+ * produce all text style reports.
+ */
+class ReportsText: public ReportsBase {
+
+ public:
+ ReportsText( time_t timestamp );
+ ~ReportsText();
+
+ /*!
+ * This method produces a report that contains information about each
+ * uncovered branch statement.
+ *
+ * @param[in] fileName identifies the branch report file name
+ */
+ void WriteBranchReport(
+ const char* const fileName
+ );
+
+ /*!
+ * This method produces a report that contains information about each
+ * uncovered range of bytes.
+ *
+ * @param[in] fileName identifies the coverage report file name
+ */
+ void WriteCoverageReport(
+ const char* const fileName
+ );
+
+ /*!
+ * This method produces a summary report that lists each uncovered
+ * range of bytes.
+ *
+ * @param[in] fileName identifies the size report file name
+ */
+ void WriteSizeReport(
+ const char* const fileName
+ );
+
+ protected:
+
+ virtual void PutAnnotatedLine(<span style="background-color: #FF0000"> </span>
+ FILE* aFile,<span style="background-color: #FF0000"> </span>
+ AnnotatedLineState_t state,<span style="background-color: #FF0000"> </span>
+ std::string line,<span style="background-color: #FF0000"> </span>
+ uint32_t id<span style="background-color: #FF0000"> </span>
+ );
+
+ virtual bool PutNoBranchInfo(
+ FILE* report
+ );
+
+ virtual bool PutBranchEntry(
+ FILE* report,
+ unsigned int number,
+ Coverage::DesiredSymbols::symbolSet_t::iterator symbolPtr,
+ Coverage::CoverageRanges::ranges_t::iterator rangePtr
+ );
+
+ virtual void putCoverageNoRange(
+ FILE* report,
+ FILE* noRangeFile,
+ unsigned int number,
+ std::string symbol
+ );
+
+ virtual bool PutCoverageLine(
+ FILE* report,
+ unsigned int number,
+ Coverage::DesiredSymbols::symbolSet_t::iterator ditr,
+ Coverage::CoverageRanges::ranges_t::iterator ritr
+ );
+
+ virtual bool PutSizeLine(
+ FILE* report,
+ unsigned int number,
+ Coverage::DesiredSymbols::symbolSet_t::iterator symbol,
+ Coverage::CoverageRanges::ranges_t::iterator range
+ );
+
+ virtual bool PutSymbolSummaryLine(
+ FILE* report,
+ unsigned int number,
+ Coverage::DesiredSymbols::symbolSet_t::iterator symbol
+ );
+
+};
+
+}
+
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/ReportsText.cc:1.1
--- /dev/null Mon May 24 15:10:06 2010
+++ gcc-testing/covoar/ReportsText.cc Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,258 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "ReportsText.h"
+#include "app_common.h"
+#include "CoverageRanges.h"
+#include "DesiredSymbols.h"
+#include "Explanations.h"
+#include "ObjdumpProcessor.h"
+
+
+namespace Coverage {
+
+ReportsText::ReportsText( time_t timestamp ):
+ ReportsBase( timestamp )
+{
+ reportExtension_m = ".txt";
+}
+
+void ReportsText::PutAnnotatedLine(<span style="background-color: #FF0000"> </span>
+ FILE* aFile,<span style="background-color: #FF0000"> </span>
+ AnnotatedLineState_t state,<span style="background-color: #FF0000"> </span>
+ std::string line,<span style="background-color: #FF0000"> </span>
+ uint32_t id<span style="background-color: #FF0000"> </span>
+)
+{
+ fprintf( aFile, "%s\n", line.c_str());
+}
+
+bool ReportsText::PutNoBranchInfo(
+ FILE* report
+)
+{
+ if ( BranchInfoAvailable )
+ fprintf( report, "All branch paths taken.\n" );
+ else
+ fprintf( report, "No branch information found.\n" );
+ return true;
+}
+
+
+bool ReportsText::PutBranchEntry(
+ FILE* report,
+ unsigned int number,
+ Coverage::DesiredSymbols::symbolSet_t::iterator symbolPtr,
+ Coverage::CoverageRanges::ranges_t::iterator rangePtr
+)
+{
+ const Coverage::Explanation* explanation;
+
+ // Add an entry to the report
+ fprintf(
+ report,
+ "============================================\n"
+ "Symbol : %s (0x%x)\n"
+ "Line : %s (0x%x)\n"
+ "Size in Bytes : %d\n",
+ symbolPtr->first.c_str(),
+ symbolPtr->second.baseAddress,
+ rangePtr->lowSourceLine.c_str(),
+ rangePtr->lowAddress,
+ rangePtr->highAddress - rangePtr->lowAddress + 1
+ );
+
+ if (rangePtr->reason ==
+ Coverage::CoverageRanges::UNCOVERED_REASON_BRANCH_ALWAYS_TAKEN)
+ fprintf(
+ report, "Reason : %s\n\n", "ALWAYS TAKEN"
+ );
+ else if (rangePtr->reason ==
+ Coverage::CoverageRanges::UNCOVERED_REASON_BRANCH_NEVER_TAKEN)
+ fprintf( report, "Reason : %s\n\n", "NEVER TAKEN" );
+
+ // See if an explanation is available
+ explanation = AllExplanations->lookupExplanation( rangePtr->lowSourceLine );
+
+ if ( !explanation ) {
+ fprintf(
+ report,
+ "Classification: NONE\n"
+ "\n"
+ "Explanation:\n"
+ "No Explanation\n"
+ );
+ } else {
+ fprintf(
+ report,
+ "Classification: %s\n"
+ "\n"
+ "Explanation:\n",
+ explanation->classification.c_str()
+ );
+
+ for ( unsigned int i=0 ;
+ i < explanation->explanation.size();
+ i++) {
+ fprintf(
+ report,
+ "%s\n",
+ explanation->explanation[i].c_str()
+ );
+ }
+ }
+
+ fprintf(
+ report, "============================================\n"
+ );
+
+ return true;
+}
+
+void ReportsText::putCoverageNoRange(
+ FILE* report,
+ FILE* noRangeFile,
+ unsigned int number,
+ std::string symbol
+)
+{
+ fprintf(
+ report,
+ "============================================\n"
+ "Symbol : %s\n\n"
+ " *** NEVER REFERENCED ***\n\n"
+ "This symbol was never referenced by an analyzed executable.\n"
+ "Therefore there is no size or disassembly for this symbol.\n"
+ "This could be due to symbol misspelling or lack of a test for\n"
+ "this symbol.\n"
+ "============================================\n",
+ symbol.c_str()
+ );
+ fprintf( noRangeFile, "%s\n", symbol.c_str() );
+}
+
+bool ReportsText::PutCoverageLine(
+ FILE* report,
+ unsigned int number,
+ Coverage::DesiredSymbols::symbolSet_t::iterator ditr,
+ Coverage::CoverageRanges::ranges_t::iterator ritr
+)
+{
+ const Coverage::Explanation* explanation;
+
+ fprintf(
+ report,
+ "============================================\n"
+ "Index : %d\n"
+ "Symbol : %s (0x%x)\n"
+ "Starting Line : %s (0x%x)\n"
+ "Ending Line : %s (0x%x)\n"
+ "Size in Bytes : %d\n"
+ "Size in Instructions : %d\n\n",
+ ritr->id,
+ ditr->first.c_str(),
+ ditr->second.baseAddress,
+ ritr->lowSourceLine.c_str(),
+ ritr->lowAddress,
+ ritr->highSourceLine.c_str(),
+ ritr->highAddress,
+ ritr->highAddress - ritr->lowAddress + 1,
+ ritr->instructionCount
+ );
+
+ explanation = AllExplanations->lookupExplanation( ritr->lowSourceLine );
+
+ if ( !explanation ) {
+ fprintf(
+ report,
+ "Classification: NONE\n"
+ "\n"
+ "Explanation:\n"
+ "No Explanation\n"
+ );
+ } else {
+ fprintf(
+ report,
+ "Classification: %s\n"
+ "\n"
+ "Explanation:\n",
+ explanation->classification.c_str()
+ );
+
+ for ( unsigned int i=0; i < explanation->explanation.size(); i++) {
+ fprintf( report,"%s\n", explanation->explanation[i].c_str() );
+ }
+ }
+
+ fprintf(report, "============================================\n");
+ return true;
+}
+
+bool ReportsText::PutSizeLine(
+ FILE* report,
+ unsigned int number,
+ Coverage::DesiredSymbols::symbolSet_t::iterator symbol,
+ Coverage::CoverageRanges::ranges_t::iterator range
+)
+{
+ fprintf(
+ report,
+ "%d\t%s\t%s\n",
+ range->highAddress - range->lowAddress + 1,
+ symbol->first.c_str(),
+ range->lowSourceLine.c_str()
+ );
+ return true;
+}
+
+bool ReportsText::PutSymbolSummaryLine(
+ FILE* report,
+ unsigned int number,
+ Coverage::DesiredSymbols::symbolSet_t::iterator symbol
+)
+{
+ float uncoveredBytes;
+ float uncoveredInstructions;
+
+ if ( symbol->second.stats.sizeInInstructions == 0 )
+ uncoveredInstructions = 0;
+ else
+ uncoveredInstructions = (symbol->second.stats.uncoveredInstructions*100.0)/
+ symbol->second.stats.sizeInInstructions;
+
+ if ( symbol->second.stats.sizeInBytes == 0 )
+ uncoveredBytes = 0;
+ else
+ uncoveredBytes = (symbol->second.stats.uncoveredBytes*100.0)/
+ symbol->second.stats.sizeInBytes;
+
+ fprintf(
+ report,
+ "============================================\n"
+ "Symbol : %s\n"
+ "Total Size in Bytes : %d\n"
+ "Total Size in Instructions : %d\n"
+ "Total number Branches : %d\n"
+ "Total Always Taken : %d\n"
+ "Total Never Taken : %d\n"
+ "Percentage Uncovered Instructions : %.2f\n"
+ "Percentage Uncovered Bytes : %.2f\n",
+ symbol->first.c_str(),
+ symbol->second.stats.sizeInBytes,
+ symbol->second.stats.sizeInInstructions,
+ symbol->second.stats.branchesNotExecuted + symbol->second.stats.branchesExecuted,
+ symbol->second.stats.branchesAlwaysTaken,
+ symbol->second.stats.branchesNeverTaken,
+ uncoveredInstructions,
+ uncoveredBytes
+ );
+
+ fprintf(report, "============================================\n");
+ return true;
+}
+
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/SymbolTable.h:1.1
--- /dev/null Mon May 24 15:10:06 2010
+++ gcc-testing/covoar/SymbolTable.h Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,119 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file SymbolTable.h
+ * @brief SymbolTable Specification
+ *
+ * This file contains the specification of the SymbolTable class.
+ */
+
+#ifndef __SYMBOLTABLE_H__
+#define __SYMBOLTABLE_H__
+
+#include <stdint.h>
+#include <string>
+#include <map>
+
+namespace Coverage {
+
+ /*! @class SymbolTable
+ *
+ * This class maintains information for each desired symbol within an
+ * executable. A desired symbol is a symbol for which analysis is to
+ * be performed.
+ */
+ class SymbolTable {
+
+ public:
+
+ /*!
+ * This structure defines the information kept for each symbol.
+ */
+ typedef struct {
+ uint32_t startingAddress;
+ uint32_t length;
+ } symbolInfo;
+
+ /*!
+ * This method constructs a SymbolTable instance.
+ */
+ SymbolTable();
+
+ /*!
+ * This method destructs a SymbolTable instance.
+ */
+ virtual ~SymbolTable();
+
+ /*!
+ * This method adds the specified symbol information to the
+ * symbol table.
+ *
+ * @param[in] symbol specifies the symbol to add
+ * @param[in] start specifies the symbol's start address
+ * @param[in] length specifies the symbol's length
+ *
+ */
+ void addSymbol(
+ const std::string& symbol,
+ const uint32_t start,
+ const uint32_t length
+ );
+
+ /*!
+ * This method returns the symbol information for the specified symbol.
+ *
+ * @param[in] symbol specifies the symbol for which to obtain information
+ *
+ * @return Returns a pointer to the symbol information
+ */
+ symbolInfo* getInfo(
+ const std::string& symbol
+ );
+
+ /*!
+ * This method returns the length in bytes of the specified symbol.
+ *
+ * @param[in] symbol specifies the symbol for which to obtain the length
+ *
+ * @return Returns the length of the symbol
+ */
+ uint32_t getLength(
+ const std::string& symbol
+ );
+
+ /*!
+ * This method returns the symbol that contains the specified address.
+ *
+ * @param[in] address specifies the address for which to obtain the symbol
+ *
+ * @return Returns the symbol containing the address
+ */
+ std::string getSymbol(
+ uint32_t address
+ );
+
+ private:
+
+ /*!
+ * This map associates the end address of a symbol's address
+ * range with the symbol's address range definition.
+ */
+ typedef struct {
+ uint32_t low;
+ uint32_t high;
+ std::string symbol;
+ } symbol_entry_t;
+ typedef std::map< uint32_t, symbol_entry_t > contents_t;
+ contents_t contents;
+
+ /*!
+ * This map associates each symbol from an executable with
+ * the symbol's information.
+ */
+ typedef std::map<std::string, symbolInfo> info_t;
+ info_t info;
+
+ };
+}
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/SymbolTable.cc:1.1
--- /dev/null Mon May 24 15:10:07 2010
+++ gcc-testing/covoar/SymbolTable.cc Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,99 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file SymbolTable.cc
+ * @brief SymbolTable Implementation
+ *
+ * This file contains ...
+ */
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "SymbolTable.h"
+#include "app_common.h"
+
+namespace Coverage {
+
+ SymbolTable::SymbolTable()
+ {
+ }
+
+ SymbolTable::~SymbolTable()
+ {
+ }
+
+ void SymbolTable::addSymbol(
+ const std::string& symbol,
+ const uint32_t start,
+ const uint32_t length
+ )
+ {
+ uint32_t end = 0;
+ symbol_entry_t entry;
+ symbolInfo symbolData;
+
+ // Add an entry to the address map.
+ end = start + length - 1;
+ entry.low = start;
+ entry.high = end;
+ entry.symbol = symbol;
+ contents[ end ] = entry;
+
+ // Add an entry to the symbol information map.
+ symbolData.startingAddress = start;
+ symbolData.length = length;
+ info[ symbol ] = symbolData;
+ }
+
+ SymbolTable::symbolInfo* SymbolTable::getInfo(
+ const std::string& symbol
+ )
+ {
+ info_t::iterator it = info.find( symbol );
+
+ if (it == info.end())
+ return NULL;
+ else
+ return (&(it->second));
+ }
+
+ uint32_t SymbolTable::getLength(
+ const std::string& symbol
+ )
+ {
+ info_t::iterator it = info.find( symbol );
+
+ if (it == info.end())
+ return 0;
+ else
+ return ((*it).second.length);
+ }
+
+ std::string SymbolTable::getSymbol(
+ uint32_t address
+ )
+ {
+ contents_t::iterator it;
+
+ // Ensure that the symbol table is not empty.
+ if ( contents.size() == 0 )
+ return "";
+
+ // Find the first entry whose end address is greater
+ // than the specified address.
+ it = contents.lower_bound( address );
+
+ // If an entry was found and its low address is less than or
+ // equal to the specified address, then return the symbol.
+ if ((it != contents.end()) && ((it->second).low <= address ))
+ return (it->second).symbol;
+
+ return "";
+ }
+
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/TargetBase.h:1.1
--- /dev/null Mon May 24 15:10:07 2010
+++ gcc-testing/covoar/TargetBase.h Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,180 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file TargetBase.h
+ * @brief TargetBase Specification
+ *
+ * This file contains the specification of the TargetBase class.
+ */
+
+#ifndef __TARGETBASE_H__
+#define __TARGETBASE_H__
+
+#include <list>
+#include <string>
+#include <stdint.h>
+
+namespace Target {
+
+ /*! @class TargetBase
+ *
+ * This class is the base class for all Target classes. Each
+ * target class contains routines that are specific to the target
+ * in question.
+ */
+ class TargetBase {
+
+ public:
+
+ /*!
+ * This method constructs an TargetBase instance.
+ *
+ * @param[in] targetName specifies the desired target
+ */
+ TargetBase(
+ std::string targetName
+ );
+
+ /*!
+ * This method destructs an TargetBase instance.
+ */
+ virtual ~TargetBase();
+
+ /*!
+ * This method returns the program name for addr2line.
+ *
+ * @return Returns the target specific addr2line program name
+ */
+ const char* getAddr2line( void ) const;
+
+ /*!
+ * This method returns the CPU name.
+ *
+ * @return Returns the target cpu name
+ */
+ const char* getCPU( void ) const;
+
+ /*!
+ * This method returns the program name for nm.
+ *
+ * @return Returns the target specific nm program name
+ */
+ const char* getNm( void ) const;
+
+ /*!
+ * This method returns the program name for objdump.
+ *
+ * @return Returns the target specific objdump program name
+ */
+ const char* getObjdump( void ) const;
+
+ /*!
+ * This method returns the target name.
+ *
+ * @return Returns the target name
+ */
+ const char* getTarget( void ) const;
+
+ /*!
+ * This method determines whether the specified line from a<span style="background-color: #FF0000"> </span>
+ * objdump file is a nop instruction.
+ *
+ * @param[in] line contains the object dump line to check
+ * @param[out] size is set to the size in bytes of the nop
+ *
+ * @return Returns TRUE if the instruction is a nop, FALSE otherwise.
+ */
+ virtual bool isNopLine(
+ const char* const line,
+ int& size
+ ) = 0;
+
+
+ /*!
+ * This method determins if the objdump line contains a
+ * branch instruction.
+ *
+ * @param[in] line contains the object dump line to check
+ * @param[out] size is set to the size in bytes of the nop
+ *
+ * @return Returns TRUE if the instruction is a branch, FALSE otherwise.
+ */
+ bool isBranchLine(
+ const char* const line
+ );
+
+<span style="background-color: #FF0000"> </span>
+ /*!
+ * This method determines if the specified line from an
+ * objdump file is a branch instruction.
+ */
+ bool isBranch(
+ const char* const instruction
+ );
+
+ /*!
+ * This method returns the bit set by Qemu in the trace record
+ * when a branch is taken.
+ */
+ virtual uint8_t qemuTakenBit(void);
+
+ /*!
+ * This method returns the bit set by Qemu in the trace record
+ * when a branch is taken.
+ */
+ virtual uint8_t qemuNotTakenBit(void);
+
+ protected:
+
+ /*!
+ * This member variable contains the target name string.
+ */
+ std::string targetName_m;
+
+ /*!
+ * This member variable indicates either the column that the instruction
+ * starts in the object dump file, when the objdump has no tabs; or the
+ * number of tabs to find the instruction.
+ */
+ int objdumpInstructionLocation;
+
+ /*!
+ * This member variable indicates whether or not the objdump has
+ * tabs as delemeters.
+ */
+ bool objdumpHasTabs;
+
+ /*!
+ * This member variable is an array of all branch instructions
+ * for this target.
+ */
+ std::list <std::string> branchInstructions;
+
+ private:
+
+ /*!
+ * This member variable contains the name of the host program
+ * which reports the source line for the specified program address.
+ */
+ std::string addr2line_m;
+
+ /*!
+ * This member variable contains the name of the target cpu architecture.
+ */
+ std::string cpu_m;
+
+ /*!
+ * This member variable contains the name of the host program
+ * which produces a symbol table.
+ */
+ std::string nm_m;
+
+ /*!
+ * This member variable contains the name of the host program
+ * which disassembles an executable or library.
+ */
+ std::string objdump_m;
+ };
+}
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/TargetBase.cc:1.1
--- /dev/null Mon May 24 15:10:07 2010
+++ gcc-testing/covoar/TargetBase.cc Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,145 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file TargetBase.cc
+ * @brief TargetBase Implementation
+ *
+ * This file contains the implementation of the base class for<span style="background-color: #FF0000"> </span>
+ * functions supporting target unique functionallity.
+ */
+
+#include "TargetBase.h"
+#include "qemu-traces.h"
+
+#include <algorithm>
+#include <stdio.h>
+
+namespace Target {
+
+ TargetBase::TargetBase(<span style="background-color: #FF0000"> </span>
+ std::string targetName
+ ):
+ targetName_m( targetName )
+ {
+ int i;
+ std::string front = "";
+
+ for (i=0 ; targetName_m[i] && targetName_m[i] != '-' ; ) {
+ cpu_m[i] = targetName_m[i];
+ cpu_m[++i] = '\0';
+ }
+ if (targetName_m[i] == '-')
+ front = targetName_m + "-";
+
+
+ addr2line_m = front + "addr2line";
+ nm_m = front + "nm";
+ objdump_m = front + "objdump";
+ }
+
+ TargetBase::~TargetBase()
+ {
+ }
+
+ const char* TargetBase::getAddr2line() const
+ {
+ return addr2line_m.c_str();
+ }
+
+ const char* TargetBase::getCPU( void ) const
+ {
+ return cpu_m.c_str();
+ }
+
+ const char* TargetBase::getNm() const
+ {
+ return nm_m.c_str();
+ }
+
+ const char* TargetBase::getObjdump() const
+ {
+ return objdump_m.c_str();
+ }
+
+ const char* TargetBase::getTarget( void ) const
+ {
+ return targetName_m.c_str();
+ }
+
+ bool TargetBase::isBranch(
+ const char* const instruction
+ )
+ {
+ std::list <std::string>::iterator i;
+
+ if (branchInstructions.empty()) {
+ fprintf(<span style="background-color: #FF0000"> </span>
+ stderr,
+ "DETERMINE BRANCH INSTRUCTIONS FOR THIS ARCHITECTURE! -- fix me\n"<span style="background-color: #FF0000"> </span>
+ );
+ exit( -1 );<span style="background-color: #FF0000"> </span>
+ }
+<span style="background-color: #FF0000"> </span>
+ i = find(branchInstructions.begin(), branchInstructions.end(), instruction);
+ if ( i == branchInstructions.end() )
+ return false;
+
+ return true;
+ }
+
+ bool TargetBase::isBranchLine(
+ const char* const line
+ )
+ {
+ #define WARNING \
+ "WARNING: TargetBase::isBranchLine - (%d) " \
+ "Unable to find instruction in: %s\n"
+ const char *ch;
+ char instruction[120];
+ int result;
+
+<span style="background-color: #FF0000"> </span>
+ ch = &(line[0]);
+
+ // Increment to the first tab in the line
+ while ((*ch != '\t') && (*ch != '\0')) {<span style="background-color: #FF0000"> </span>
+ ch++;
+ }
+ if (*ch != '\t') {
+ fprintf( stderr, WARNING, 1, line );
+ return false;
+ }
+ ch++;
+
+ // Increment to the second tab in the line
+ while ((*ch != '\t') && (*ch != '\0'))<span style="background-color: #FF0000"> </span>
+ ch++;
+ if (*ch != '\t') {
+ fprintf( stderr, WARNING, 2, line) ;
+ return false;
+ }
+ ch++;
+
+ // Grab the instruction which is the next word in the buffer
+ // after the second tab.
+ result = sscanf( ch, "%s", instruction );
+ if (result != 1) {
+ fprintf( stderr, WARNING, 3, line );
+ return false;
+ }
+
+ return isBranch( instruction );
+ }
+
+ uint8_t TargetBase::qemuTakenBit(void)
+ {
+ return TRACE_OP_BR0;
+ }
+
+ uint8_t TargetBase::qemuNotTakenBit(void)
+ {
+ return TRACE_OP_BR1;
+ }
+
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/TargetFactory.h:1.1
--- /dev/null Mon May 24 15:10:07 2010
+++ gcc-testing/covoar/TargetFactory.h Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,38 @@
</font><font color='#000088'>+//
+// $Id$
+//
+
+//! @file TargetFactory.h
+//! @brief TargetFactory Specification
+//!
+//! This file contains the specification of a factory for a
+//! instances of a family of classes derived from TargetBase.
+//!
+
+#ifndef __TARGET_FACTORY_H__
+#define __TARGET_FACTORY_H__
+
+#include <string>
+#include "TargetBase.h"
+
+namespace Target {
+
+ //!
+ //! @brief Target Construction Factory
+ //!
+ //! This method implements a factory for construction of instances
+ //! classes derived from TargetBase. Given the name of the class instance
+ //! and name of the instance, it returns an instance.
+ //!
+ //! @param [in] targetName is the name of the target to create.
+ //!
+ //! @return This method constructs a new instance of an TargetBase and
+ //! returns that to the caller.
+ //!
+ TargetBase *TargetFactory(
+ std::string targetName
+ );
+
+}
+#endif
+
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/TargetFactory.cc:1.1
--- /dev/null Mon May 24 15:10:07 2010
+++ gcc-testing/covoar/TargetFactory.cc Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,90 @@
</font><font color='#000088'>+//
+// $Id$
+//
+
+//! @file TargetFactory.cc
+//! @brief TargetFactory Implementation
+//!
+//! This file contains the implementation of a factory for a
+//! instances of a family of classes derived from TargetBase.
+//!
+
+#include "TargetFactory.h"
+
+#include "Target_arm.h"
+#include "Target_i386.h"
+#include "Target_m68k.h"
+#include "Target_powerpc.h"
+#include "Target_lm32.h"
+#include "Target_sparc.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+namespace Target {
+
+ //!
+ //! @brief TargetBase Factory Table Entry
+ //!
+ //! This structure contains the @a name associated with the target
+ //! in the configuration structures. The table of names is scanned
+ //! to find a constructor helper.
+ //!
+ typedef struct {
+ //! This is the string found in configuration to match.
+ const char *theTarget;
+ //! This is the static wrapper for the constructor.
+ TargetBase *(*theCtor)(<span style="background-color: #FF0000"> </span>
+ std::string
+ );
+ } FactoryEntry_t;
+
+ //!
+ //! @brief TargetBase Factory Table
+ //!
+ //! This is the table of possible types we can construct
+ //! dynamically based upon user specified configuration information.
+ //! All must be derived from TargetBase.
+ //!
+ static FactoryEntry_t FactoryTable[] = {
+ { "arm", Target_arm_Constructor },
+ { "i386", Target_i386_Constructor },
+ { "lm32", Target_lm32_Constructor },
+ { "m68k", Target_m68k_Constructor },
+ { "powerpc", Target_powerpc_Constructor },
+ { "sparc", Target_sparc_Constructor },
+ { "TBD", NULL },
+ };
+
+ TargetBase* TargetFactory(
+ std::string targetName
+ )
+ {
+ size_t i;
+ std::string cpu;
+
+ i = targetName.find( '-' );
+ if ( i == targetName.npos )
+ cpu = targetName;
+ else
+ cpu = targetName.substr( 0, i );
+
+ // fprintf( stderr, "%s --> %s\n", targetName.c_str(), cpu.c_str());
+ // Iterate over the table trying to find an entry with a matching name
+ for ( i=0 ; i < sizeof(FactoryTable) / sizeof(FactoryEntry_t); i++ ) {
+ if ( !strcmp(FactoryTable[i].theTarget, cpu.c_str() ) )
+ return FactoryTable[i].theCtor( targetName );
+ }
+
+ fprintf(
+ stderr,
+ "ERROR!!! %s is not a known architecture!!!\n",
+ cpu.c_str()
+ );
+ fprintf( stderr, "-- fix me\n" );
+ exit( 1 );
+
+ return NULL;
+ }
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/Target_arm.h:1.1
--- /dev/null Mon May 24 15:10:07 2010
+++ gcc-testing/covoar/Target_arm.h Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,81 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file Target_arm.h
+ * @brief Target_arm Specification
+ *
+ * This file contains the specification of the Target_arm class.
+ */
+
+#ifndef __TARGET_ARM_H__
+#define __TARGET_ARM_H__
+
+#include <list>
+#include <string>
+#include "TargetBase.h"
+
+namespace Target {
+
+ /*! @class Target_arm
+ *
+ * This class is the Target classe for the arm processor.
+ *
+ */
+ class Target_arm: public TargetBase {
+
+ public:
+
+ /*!
+ * This method constructs an Target_arm instance.
+ */
+ Target_arm( std::string targetName );
+
+ /*!
+ * This method destructs an Target_arm instance.
+ */
+ virtual ~Target_arm();
+
+ /*!
+ * This method determines whether the specified line from a<span style="background-color: #FF0000"> </span>
+ * objdump file is a nop instruction.
+ *
+ * @param[in] line contains the object dump line to check
+ * @param[out] size is set to the size in bytes of the nop
+ *
+ * @return Returns TRUE if the instruction is a nop, FALSE otherwise.
+ */
+ bool isNopLine(
+ const char* const line,
+ int& size
+ );
+
+ /*!
+ * This method determines if the specified line from an
+ * objdump file is a branch instruction.
+ */
+ bool isBranch(
+ const char* const instruction
+ );
+
+ private:
+
+ };
+
+ //!
+ //! @brief Constructor Helper
+ //!
+ //! This is a constructor helper for this class which can be used in support
+ //! of factories.
+ //!
+ //! @param [in] Targetname is the name of the Target being constructed.
+ //!
+ //! @return This method constructs a new instance of the Target and returns
+ //! that to the caller.
+ //!
+ TargetBase *Target_arm_Constructor(
+ std::string targetName
+ );
+
+}
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/Target_arm.cc:1.1
--- /dev/null Mon May 24 15:10:07 2010
+++ gcc-testing/covoar/Target_arm.cc Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,91 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file Target_arm.cc
+ * @brief Target_arm Implementation
+ *
+ * This file contains the implementation of the base class for<span style="background-color: #FF0000"> </span>
+ * functions supporting target unique functionallity.
+ */
+#include "Target_arm.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+namespace Target {
+
+ Target_arm::Target_arm( std::string targetName ):
+ TargetBase( targetName )
+ {
+ branchInstructions.push_back("bcc");
+ branchInstructions.push_back("bcs");
+ branchInstructions.push_back("beq");
+ branchInstructions.push_back("bge");
+ branchInstructions.push_back("bgt");
+ branchInstructions.push_back("bhi");
+ branchInstructions.push_back("bl-hi");
+ branchInstructions.push_back("bl-lo");
+ branchInstructions.push_back("ble");
+ branchInstructions.push_back("bls");
+ branchInstructions.push_back("blt");
+ branchInstructions.push_back("bmi");
+ branchInstructions.push_back("bne");
+ branchInstructions.push_back("bpl");
+ branchInstructions.push_back("bvc");
+ branchInstructions.push_back("bvs");
+<span style="background-color: #FF0000"> </span>
+ branchInstructions.sort();
+
+ }
+
+ Target_arm::~Target_arm()
+ {
+ }
+
+ bool Target_arm::isNopLine(
+ const char* const line,
+ int& size
+ )
+ {
+ if (!strcmp( &line[strlen(line)-3], "nop")) {
+ size = 4;<span style="background-color: #FF0000"> </span>
+ return true;
+ }
+
+ // On ARM, there are literal tables at the end of methods.
+ // We need to avoid them.
+ if (!strncmp( &line[strlen(line)-10], ".byte", 5)) {
+ size = 1;
+ return true;
+ }
+ if (!strncmp( &line[strlen(line)-13], ".short", 6)) {
+ size = 2;
+ return true;
+ }
+ if (!strncmp( &line[strlen(line)-16], ".word", 5)) {
+ size = 4;
+ return true;
+ }
+
+ return false;
+<span style="background-color: #FF0000"> </span>
+ }
+
+ bool Target_arm::isBranch(
+ const char* instruction
+ )<span style="background-color: #FF0000"> </span>
+ {
+ fprintf( stderr, "DETERMINE BRANCH INSTRUCTIONS FOR THIS ARCHITECTURE! -- fix me\n" );
+ exit( -1 );<span style="background-color: #FF0000"> </span>
+ }
+
+ TargetBase *Target_arm_Constructor(
+ std::string targetName
+ )
+ {
+ return new Target_arm( targetName );
+ }
+
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/Target_i386.h:1.1
--- /dev/null Mon May 24 15:10:07 2010
+++ gcc-testing/covoar/Target_i386.h Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,80 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file Target_i386.h
+ * @brief Target_i386 Specification
+ *
+ * This file contains the specification of the Target_i386 class.
+ */
+
+#ifndef __TARGET_I386_H__
+#define __TARGET_I386_H__
+
+#include <list>
+#include <string>
+#include "TargetBase.h"
+
+
+namespace Target {
+
+ /*! @class Target_i386
+ *
+ * This class is the class for i386 Target.
+ *
+ */
+ class Target_i386: public TargetBase {
+
+ public:
+
+ /*!
+ * This method constructs an Target_i386 instance.
+ */
+ Target_i386( std::string targetName );
+
+ /*!
+ * This method destructs an Target_i386 instance.
+ */
+ virtual ~Target_i386();
+
+ /*!
+ * This method determines whether the specified line from a<span style="background-color: #FF0000"> </span>
+ * objdump file is a nop instruction.
+ *
+ * @param[in] line contains the object dump line to check
+ * @param[out] size is set to the size in bytes of the nop
+ *
+ * @return Returns TRUE if the instruction is a nop, FALSE otherwise.
+ */
+ bool isNopLine(
+ const char* const line,
+ int& size
+ );
+
+ /* Documentation inherited from base class */
+ virtual uint8_t qemuTakenBit(void);
+
+ /* Documentation inherited from base class */
+ virtual uint8_t qemuNotTakenBit(void);
+
+ private:
+
+ };
+
+ //!
+ //! @brief Constructor Helper
+ //!
+ //! This is a constructor helper for this class which can be used in support
+ //! of factories.
+ //!
+ //! @param [in] Targetname is the name of the Target being constructed.
+ //!
+ //! @return This method constructs a new instance of the Target and returns
+ //! that to the caller.
+ //!
+ TargetBase *Target_i386_Constructor(
+ std::string targetName
+ );
+
+}
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/Target_i386.cc:1.1
--- /dev/null Mon May 24 15:10:07 2010
+++ gcc-testing/covoar/Target_i386.cc Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,115 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file Target_i386.cc
+ * @brief Target_i386 Implementation
+ *
+ * This file contains the implementation of the base class for<span style="background-color: #FF0000"> </span>
+ * functions supporting target unique functionallity.
+ */
+
+#include "Target_i386.h"
+#include "qemu-traces.h"
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+namespace Target {
+
+ Target_i386::Target_i386( std::string targetName ):
+ TargetBase( targetName )
+ {
+ branchInstructions.push_back("ja");
+ branchInstructions.push_back("jb");
+ branchInstructions.push_back("jc");
+ branchInstructions.push_back("je");
+ branchInstructions.push_back("jg");
+ branchInstructions.push_back("jl");
+ branchInstructions.push_back("jo");
+ branchInstructions.push_back("jp");
+ branchInstructions.push_back("js");
+ branchInstructions.push_back("jz");
+ branchInstructions.push_back("jae");
+ branchInstructions.push_back("jbe");
+ branchInstructions.push_back("jge");
+ branchInstructions.push_back("jle");
+ branchInstructions.push_back("jne");
+ branchInstructions.push_back("jna");
+ branchInstructions.push_back("jnb");
+ branchInstructions.push_back("jnc");
+ branchInstructions.push_back("jne");
+ branchInstructions.push_back("jng");
+ branchInstructions.push_back("jnl");
+ branchInstructions.push_back("jno");
+ branchInstructions.push_back("jnp");
+ branchInstructions.push_back("jns");
+ branchInstructions.push_back("jnz");
+ branchInstructions.push_back("jpe");
+ branchInstructions.push_back("jpo");
+ branchInstructions.push_back("jnbe");
+ branchInstructions.push_back("jnae");
+ branchInstructions.push_back("jnle");
+ branchInstructions.push_back("jnge");
+
+ branchInstructions.sort();
+
+ }
+
+ Target_i386::~Target_i386()
+ {
+ }
+
+ bool Target_i386::isNopLine(
+ const char* const line,
+ int& size
+ )
+ {
+ if (!strcmp( &line[strlen(line)-3], "nop")) {
+ size = 1;<span style="background-color: #FF0000"> </span>
+ return true;
+ }
+
+ // i386 has some two and three byte nops
+ if (!strncmp( &line[strlen(line)-14], "xchg %ax,%ax", 14)) {
+ size = 2;
+ return true;
+ }
+ if (!strncmp( &line[strlen(line)-16], "xor %eax,%eax", 16)) {
+ size = 2;
+ return true;
+ }
+ if (!strncmp( &line[strlen(line)-16], "xor %ebx,%ebx", 16)) {
+ size = 2;
+ return true;
+ }
+ if (!strncmp( &line[strlen(line)-16], "xor %esi,%esi", 16)) {
+ size = 2;
+ return true;
+ }
+ if (!strncmp( &line[strlen(line)-21], "lea 0x0(%esi),%esi", 21)) {
+ size = 3;
+ return true;
+ }
+
+ return false;
+ }
+
+ uint8_t Target_i386::qemuTakenBit(void)
+ {
+ return TRACE_OP_BR1;
+ }
+
+ uint8_t Target_i386::qemuNotTakenBit(void)
+ {
+ return TRACE_OP_BR0;
+ }
+
+ TargetBase *Target_i386_Constructor(
+ std::string targetName
+ )
+ {
+ return new Target_i386( targetName );
+ }
+
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/Target_lm32.h:1.1
--- /dev/null Mon May 24 15:10:07 2010
+++ gcc-testing/covoar/Target_lm32.h Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,74 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file Target_lm32.h
+ * @brief Target_lm32 Specification
+ *
+ * This file contains the specification of the Target_lm32 class.
+ */
+
+#ifndef __TARGET_LM32_H__
+#define __TARGET_LM32_H__
+
+#include <list>
+#include <string>
+#include "TargetBase.h"
+
+
+namespace Target {
+
+ /*!
+ *
+ * This class is the class for the m68k Target.
+ *
+ */
+ class Target_lm32: public TargetBase {
+
+ public:
+
+ /*!
+ * This method constructs a Target_lm32 instance.
+ */
+ Target_lm32( std::string targetName );
+
+ /*!
+ * This method destructs a Target_m68 instance.
+ */
+ virtual ~Target_lm32();
+
+ /*!
+ * This method determines whether the specified line from a<span style="background-color: #FF0000"> </span>
+ * objdump file is a nop instruction.
+ *
+ * @param[in] line contains the object dump line to check
+ * @param[out] size is set to the size in bytes of the nop
+ *
+ * @return Returns TRUE if the instruction is a nop, FALSE otherwise.
+ */
+ bool isNopLine(
+ const char* const line,
+ int& size
+ );
+
+ private:
+
+ };
+
+ //!
+ //! @brief Constructor Helper
+ //!
+ //! This is a constructor helper for this class which can be used in support
+ //! of factories.
+ //!
+ //! @param [in] Targetname is the name of the Target being constructed.
+ //!
+ //! @return This method constructs a new instance of the Target and returns
+ //! that to the caller.
+ //!
+ TargetBase *Target_lm32_Constructor(
+ std::string targetName
+ );
+
+}
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/Target_lm32.cc:1.1
--- /dev/null Mon May 24 15:10:07 2010
+++ gcc-testing/covoar/Target_lm32.cc Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,56 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file Target_lm32.cc
+ * @brief Target_lm32 Implementation
+ *
+ * This file contains the implementation of the base class for<span style="background-color: #FF0000"> </span>
+ * functions supporting target unique functionallity.
+ */
+#include "Target_lm32.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <algorithm>
+
+namespace Target {
+
+ // http://www.latticesemi.com/documents/doc20890x45.pdf
+ Target_lm32::Target_lm32( std::string targetName ):
+ TargetBase( targetName )
+ {
+ branchInstructions.push_back("be");
+ branchInstructions.push_back("bge");
+ branchInstructions.push_back("bgeu");
+ branchInstructions.push_back("bg");
+ branchInstructions.push_back("bgu");
+ branchInstructions.push_back("bne");
+ }
+
+ Target_lm32::~Target_lm32()
+ {
+ }
+
+ bool Target_lm32::isNopLine(
+ const char* const line,
+ int& size
+ )
+ {
+ if (!strcmp( &line[strlen(line)-3], "nop")) {
+ size = 4;<span style="background-color: #FF0000"> </span>
+ return true;
+ }
+
+ return false;
+ }
+
+ TargetBase *Target_lm32_Constructor(
+ std::string targetName
+ )
+ {
+ return new Target_lm32( targetName );
+ }
+
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/Target_m68k.h:1.1
--- /dev/null Mon May 24 15:10:07 2010
+++ gcc-testing/covoar/Target_m68k.h Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,88 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file Target_m68k.h
+ * @brief Target_m68k Specification
+ *
+ * This file contains the specification of the Target_m68k class.
+ */
+
+#ifndef __TARGET_M68K_H__
+#define __TARGET_M68K_H__
+
+#include <list>
+#include <string>
+#include "TargetBase.h"
+
+
+namespace Target {
+
+ /*!
+ *
+ * This class is the class for the m68k Target.
+ *
+ */
+ class Target_m68k: public TargetBase {
+
+ public:
+
+ /*!
+ * This method constructs a Target_m68k instance.
+ */
+ Target_m68k( std::string targetName );
+
+ /*!
+ * This method destructs a Target_m68 instance.
+ */
+ virtual ~Target_m68k();
+
+ /*!
+ * This method determines whether the specified line from a<span style="background-color: #FF0000"> </span>
+ * objdump file is a nop instruction.
+ *
+ * @param[in] line contains the object dump line to check
+ * @param[out] size is set to the size in bytes of the nop
+ *
+ * @return Returns TRUE if the instruction is a nop, FALSE otherwise.
+ */
+ bool isNopLine(
+ const char* const line,
+ int& size
+ );
+
+ /*!
+ * This method determines if the specified line from an
+ * objdump file is a branch instruction.
+ */
+ bool isBranch(
+ const char* const instruction
+ );
+
+ /* Documentation inherited from base class */
+ virtual uint8_t qemuTakenBit(void);
+
+ /* Documentation inherited from base class */
+ virtual uint8_t qemuNotTakenBit(void);
+
+ private:
+
+ };
+
+ //!
+ //! @brief Constructor Helper
+ //!
+ //! This is a constructor helper for this class which can be used in support
+ //! of factories.
+ //!
+ //! @param [in] Targetname is the name of the Target being constructed.
+ //!
+ //! @return This method constructs a new instance of the Target and returns
+ //! that to the caller.
+ //!
+ TargetBase *Target_m68k_Constructor(
+ std::string targetName
+ );
+
+}
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/Target_m68k.cc:1.1
--- /dev/null Mon May 24 15:10:08 2010
+++ gcc-testing/covoar/Target_m68k.cc Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,130 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file Target_m68k.cc
+ * @brief Target_m68k Implementation
+ *
+ * This file contains the implementation of the base class for<span style="background-color: #FF0000"> </span>
+ * functions supporting target unique functionallity.
+ */
+#include "Target_m68k.h"
+#include "qemu-traces.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+namespace Target {
+
+ Target_m68k::Target_m68k( std::string targetName ):
+ TargetBase( targetName )
+ {
+ branchInstructions.push_back("bcc");
+ branchInstructions.push_back("bccs");
+ branchInstructions.push_back("bccl");
+ branchInstructions.push_back("bcs");
+ branchInstructions.push_back("bcss");
+ branchInstructions.push_back("bcsl");
+ branchInstructions.push_back("beq");
+ branchInstructions.push_back("beqs");
+ branchInstructions.push_back("beql");
+ branchInstructions.push_back("bge");
+ branchInstructions.push_back("bges");
+ branchInstructions.push_back("bgel");
+ branchInstructions.push_back("bgt");
+ branchInstructions.push_back("bgts");
+ branchInstructions.push_back("bgtl");
+ branchInstructions.push_back("bhi");
+ branchInstructions.push_back("bhis");
+ branchInstructions.push_back("bhil");
+ branchInstructions.push_back("bhs");
+ branchInstructions.push_back("bhss");
+ branchInstructions.push_back("bhsl");
+ branchInstructions.push_back("ble");
+ branchInstructions.push_back("bles");
+ branchInstructions.push_back("blel");
+ branchInstructions.push_back("blo");
+ branchInstructions.push_back("blos");
+ branchInstructions.push_back("blol");
+ branchInstructions.push_back("bls");
+ branchInstructions.push_back("blss");
+ branchInstructions.push_back("blsl");
+ branchInstructions.push_back("blt");
+ branchInstructions.push_back("blts");
+ branchInstructions.push_back("bltl");
+ branchInstructions.push_back("bmi");
+ branchInstructions.push_back("bmis");
+ branchInstructions.push_back("bmil");
+ branchInstructions.push_back("bne");
+ branchInstructions.push_back("bnes");
+ branchInstructions.push_back("bnel");
+ branchInstructions.push_back("bpl");
+ branchInstructions.push_back("bpls");
+ branchInstructions.push_back("bpll");
+ branchInstructions.push_back("bvc");
+ branchInstructions.push_back("bvcs");
+ branchInstructions.push_back("bvcl");
+ branchInstructions.push_back("bvs");
+ branchInstructions.push_back("bvss");
+ branchInstructions.push_back("bvsl");
+<span style="background-color: #FF0000"> </span>
+ branchInstructions.sort();
+
+ }
+
+ Target_m68k::~Target_m68k()
+ {
+ }
+
+ bool Target_m68k::isNopLine(
+ const char* const line,
+ int& size
+ )
+ {
+ if (!strcmp( &line[strlen(line)-3], "nop")) {
+ size = 2;<span style="background-color: #FF0000"> </span>
+ return true;
+ }
+
+ #define GNU_LD_FILLS_ALIGNMENT_WITH_RTS
+ #if defined(GNU_LD_FILLS_ALIGNMENT_WITH_RTS)
+ // Until binutils 2.20, binutils would fill with rts not nop
+ if (!strcmp( &line[strlen(line)-3], "rts")) {
+ size = 4;<span style="background-color: #FF0000"> </span>
+ return true;
+ }<span style="background-color: #FF0000"> </span>
+ #endif
+
+ return false;
+ }
+
+ bool Target_m68k::isBranch(
+ const char* const instruction
+ )
+ {
+ fprintf(
+ stderr,
+ "DETERMINE BRANCH INSTRUCTIONS FOR THIS ARCHITECTURE! -- fix me\n"
+ );
+ exit( -1 );<span style="background-color: #FF0000"> </span>
+ }
+
+ uint8_t Target_m68k::qemuTakenBit(void)
+ {
+ return TRACE_OP_BR1;
+ }
+
+ uint8_t Target_m68k::qemuNotTakenBit(void)
+ {
+ return TRACE_OP_BR0;
+ }
+
+ TargetBase *Target_m68k_Constructor(
+ std::string targetName
+ )
+ {
+ return new Target_m68k( targetName );
+ }
+
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/Target_powerpc.h:1.1
--- /dev/null Mon May 24 15:10:08 2010
+++ gcc-testing/covoar/Target_powerpc.h Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,84 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file Target_powerpc.h
+ * @brief Target_powerpc Specification
+ *
+ * This file contains the specification of the Target_powerpc class.
+ */
+
+#ifndef __TARGET_POWERPC_H__
+#define __TARGET_POWERPC_H__
+
+#include <list>
+#include <string>
+#include "TargetBase.h"
+
+
+namespace Target {
+
+ /*!
+ *
+ * This class is the class for the powerpc target.
+ *
+ */
+ class Target_powerpc: public TargetBase {
+
+ public:
+
+ /*!
+ * This method constructs an Target_powerpc instance.
+ */
+ Target_powerpc( std::string targetName );
+
+ /*!
+ * This method destructs an Target_powerpc instance.
+ */
+ virtual ~Target_powerpc();
+
+ /*!
+ * This method determines whether the specified line from a<span style="background-color: #FF0000"> </span>
+ * objdump file is a nop instruction.
+ *
+ * @param[in] line contains the object dump line to check
+ * @param[out] size is set to the size in bytes of the nop
+ *
+ * @return Returns TRUE if the instruction is a nop, FALSE otherwise.
+ */
+ bool isNopLine(
+ const char* const line,
+ int& size
+ );
+
+ /*!
+ * This method determines if the specified line from an
+ * objdump file is a branch instruction.
+ */
+ bool isBranch(
+ const char* const instruction
+ );
+
+ private:
+
+ };
+
+
+ //!
+ //! @brief Constructor Helper
+ //!
+ //! This is a constructor helper for this class which can be used in support
+ //! of factories.
+ //!
+ //! @param [in] Targetname is the name of the Target being constructed.
+ //!
+ //! @return This method constructs a new instance of the Target and returns
+ //! that to the caller.
+ //!
+ TargetBase *Target_powerpc_Constructor(
+ std::string targetName
+ );
+
+
+}
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/Target_powerpc.cc:1.1
--- /dev/null Mon May 24 15:10:08 2010
+++ gcc-testing/covoar/Target_powerpc.cc Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,89 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file Target_powerpc.cc
+ * @brief Target_powerpc Implementation
+ *
+ * This file contains the implementation of the base class for<span style="background-color: #FF0000"> </span>
+ * functions supporting target unique functionallity.
+ */
+#include "Target_powerpc.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+namespace Target {
+
+ Target_powerpc::Target_powerpc( std::string targetName ):
+ TargetBase( targetName )
+ {
+ // bl is actually branch and link which is a call
+ // branchInstructions.push_back("b");
+ // branchInstructions.push_back("ba");
+ branchInstructions.push_back("beq");
+ branchInstructions.push_back("beq+");
+ branchInstructions.push_back("beq-");
+ branchInstructions.push_back("bne");
+ branchInstructions.push_back("bne+");
+ branchInstructions.push_back("bne-");
+ branchInstructions.push_back("bge");
+ branchInstructions.push_back("bge+");
+ branchInstructions.push_back("bge-");
+ branchInstructions.push_back("bgt");
+ branchInstructions.push_back("bgt+");
+ branchInstructions.push_back("bgt-");
+ branchInstructions.push_back("ble");
+ branchInstructions.push_back("ble+");
+ branchInstructions.push_back("ble-");
+ branchInstructions.push_back("blt");
+ branchInstructions.push_back("blt+");
+ branchInstructions.push_back("blt-");
+ branchInstructions.push_back("bla");
+ branchInstructions.push_back("bc");
+ branchInstructions.push_back("bca");
+ branchInstructions.push_back("bcl");
+ branchInstructions.push_back("bcla");
+ branchInstructions.push_back("bcctr");
+ branchInstructions.push_back("bcctrl");
+ branchInstructions.push_back("bclr");
+ branchInstructions.push_back("bclrl");
+
+<span style="background-color: #FF0000"> </span>
+ branchInstructions.sort();<span style="background-color: #FF0000"> </span>
+ }
+
+ Target_powerpc::~Target_powerpc()
+ {
+ }
+
+ bool Target_powerpc::isNopLine(
+ const char* const line,
+ int& size
+ )
+ {
+ if (!strcmp( &line[strlen(line)-3], "nop")) {
+ size = 4;<span style="background-color: #FF0000"> </span>
+ return true;
+ }
+
+ return false;
+ }
+
+ bool Target_powerpc::isBranch(
+ const char* const instruction
+ )
+ {
+ fprintf( stderr, "DETERMINE BRANCH INSTRUCTIONS FOR THIS ARCHITECTURE! -- fix me\n" );
+ exit( -1 );<span style="background-color: #FF0000"> </span>
+ }
+
+ TargetBase *Target_powerpc_Constructor(
+ std::string targetName
+ )
+ {
+ return new Target_powerpc( targetName );
+ }
+
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/Target_sparc.h:1.1
--- /dev/null Mon May 24 15:10:08 2010
+++ gcc-testing/covoar/Target_sparc.h Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,83 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file Target_sparc.h
+ * @brief Target_sparc Specification
+ *
+ * This file contains the specification of the Target_sparc class.
+ */
+
+#ifndef __TARGET_SPARC_H__
+#define __TARGET_SPARC_H__
+
+#include <list>
+#include <string>
+#include "TargetBase.h"
+
+
+namespace Target {
+
+ /*! @class Target_sparc
+ *
+ * This is the class for the sparc target.
+ *
+ */
+ class Target_sparc: public TargetBase {
+
+ public:
+
+ /*!
+ * This method constructs an Target_sparc instance.
+ */
+ Target_sparc( std::string targetName );
+
+ /*!
+ * This method destructs an Target_sparc instance.
+ */
+ virtual ~Target_sparc();
+
+ /*!
+ * This method determines whether the specified line from a<span style="background-color: #FF0000"> </span>
+ * objdump file is a nop instruction.
+ *
+ * @param[in] line contains the object dump line to check
+ * @param[out] size is set to the size in bytes of the nop
+ *
+ * @return Returns TRUE if the instruction is a nop, FALSE otherwise.
+ */
+ bool isNopLine(
+ const char* const line,
+ int& size
+ );
+
+ /*!
+ * This method determines if the specified line from an
+ * objdump file is a branch instruction.
+ */
+ bool isBranch(
+ const char* const instruction
+ );
+
+ private:
+
+ };
+
+ //!
+ //! @brief Constructor Helper
+ //!
+ //! This is a constructor helper for this class which can be used in support
+ //! of factories.
+ //!
+ //! @param [in] Targetname is the name of the Target being constructed.
+ //!
+ //! @return This method constructs a new instance of the Target and returns
+ //! that to the caller.
+ //!
+ TargetBase *Target_sparc_Constructor(
+ std::string targetName
+ );
+
+
+}
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/Target_sparc.cc:1.1
--- /dev/null Mon May 24 15:10:08 2010
+++ gcc-testing/covoar/Target_sparc.cc Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,79 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file Target_sparc.cc
+ * @brief Target_sparc Implementation
+ *
+ * This file contains the implementation of the base class for<span style="background-color: #FF0000"> </span>
+ * functions supporting target unique functionallity.
+ */
+#include "Target_sparc.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+namespace Target {
+
+ Target_sparc::Target_sparc( std::string targetName ):
+ TargetBase( targetName )
+ {
+ branchInstructions.push_back("bn");
+ branchInstructions.push_back("be");
+ branchInstructions.push_back("ble");
+ branchInstructions.push_back("bl");
+ branchInstructions.push_back("bleu");
+ branchInstructions.push_back("bcs");
+ branchInstructions.push_back("bneg");
+ branchInstructions.push_back("bvs");
+ branchInstructions.push_back("ba");
+ branchInstructions.push_back("bne");
+ branchInstructions.push_back("bg");
+ branchInstructions.push_back("bge");
+ branchInstructions.push_back("bgu");
+ branchInstructions.push_back("bcc");
+ branchInstructions.push_back("bpos");
+ branchInstructions.push_back("bvc");
+<span style="background-color: #FF0000"> </span>
+ branchInstructions.sort();<span style="background-color: #FF0000"> </span>
+ }
+
+ Target_sparc::~Target_sparc()
+ {
+ }
+
+ bool Target_sparc::isNopLine(
+ const char* const line,
+ int& size
+ )
+ {
+ if (!strcmp( &line[strlen(line)-3], "nop")) {
+ size = 4;
+ return true;
+ }
+
+ if (!strcmp( &line[strlen(line)-7], "unknown")) {
+ size = 4;<span style="background-color: #FF0000"> </span>
+ return true;
+ }<span style="background-color: #FF0000"> </span>
+ #define GNU_LD_FILLS_ALIGNMENT_WITH_RTS
+ #if defined(GNU_LD_FILLS_ALIGNMENT_WITH_RTS)
+ // Until binutils 2.20, binutils would fill with rts not nop
+ if (!strcmp( &line[strlen(line)-3], "rts")) {
+ size = 4;<span style="background-color: #FF0000"> </span>
+ return true;
+ }<span style="background-color: #FF0000"> </span>
+ #endif
+
+ return false;
+ }
+
+
+ TargetBase *Target_sparc_Constructor(
+ std::string targetName
+ )
+ {
+ return new Target_sparc( targetName );
+ }
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/TraceConverter.cc:1.1
--- /dev/null Mon May 24 15:10:08 2010
+++ gcc-testing/covoar/TraceConverter.cc Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,107 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file TraceReaderLogQEMU.cc
+ * @brief TraceReaderLogQEMU Implementation
+ *
+ * This file contains the implementation of the functions supporting
+ * reading the QEMU coverage data files.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <string.h>
+
+#include "qemu-log.h"
+
+#include "TraceReaderLogQEMU.h"
+#include "TraceWriterQEMU.h"
+#include "TraceList.h"
+#include "ObjdumpProcessor.h"
+#include "app_common.h"
+#include "TargetFactory.h"
+
+char* progname;
+
+void usage()
+{
+ fprintf(
+ stderr,
+ "Usage: %s [-v] -c CPU -e executable -t tracefile [-E logfile]\n",
+ progname
+ );
+ exit(1);
+}
+
+int main(
+ int argc,
+ char** argv
+)
+{
+ int opt;
+ Trace::TraceReaderLogQEMU log;
+ Trace::TraceWriterQEMU trace;
+ const char *cpuname = "";
+ const char *executable = "";
+ const char *tracefile = "";
+ const char *logname = "/tmp/qemu.log";
+ Coverage::ExecutableInfo* executableInfo;
+<span style="background-color: #FF0000"> </span>
+ //
+ // Process command line options.
+ //
+ progname = argv[0];
+
+ while ((opt = getopt(argc, argv, "c:e:l:L:t:v")) != -1) {
+ switch (opt) {
+ case 'c': cpuname = optarg; break;
+ case 'e': executable = optarg; break;
+ case 'l': logname = optarg; break;
+ case 'L': dynamicLibrary = optarg; break;
+ case 't': tracefile = optarg; break;
+ case 'v': Verbose = true; break;
+ default: usage();
+ }
+ }
+
+ // Make sure we have all the required parameters
+ if ( !cpuname ) {
+ fprintf( stderr, "cpuname not specified\n" );
+ usage();
+ }
+
+ if ( !executable ) {
+ fprintf( stderr, "executable not specified\n" );
+ usage();
+ }
+
+ if ( !tracefile ) {
+ fprintf( stderr, "output trace file not specified\n" );
+ usage();
+ }
+
+ // Create toolnames.
+ TargetInfo = Target::TargetFactory( cpuname );
+
+ if (dynamicLibrary)
+ executableInfo = new Coverage::ExecutableInfo( executable, dynamicLibrary );
+ else
+ executableInfo = new Coverage::ExecutableInfo( executable );
+
+ objdumpProcessor = new Coverage::ObjdumpProcessor();
+<span style="background-color: #FF0000"> </span>
+ // If a dynamic library was specified, determine the load address.
+ if (dynamicLibrary)
+ executableInfo->setLoadAddress(
+ objdumpProcessor->determineLoadAddress( executableInfo )
+ );
+
+ objdumpProcessor->loadAddressTable( executableInfo );
+
+ log.processFile( logname );
+
+ trace.writeFile( tracefile, &log );
+
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/TraceList.h:1.1
--- /dev/null Mon May 24 15:10:08 2010
+++ gcc-testing/covoar/TraceList.h Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,110 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file TraceList.h
+ * @brief TraceList Specification
+ *
+ * This file contains the specification of the TraceList class.
+ */
+
+#ifndef __TRACE_LIST_H__
+#define __TRACE_LIST_H__
+
+#include <stdint.h>
+#include <list>
+#include <string>
+
+namespace Trace {
+
+ /*! @class TraceList
+ *
+ * This class defines XXX<span style="background-color: #FF0000"> </span>
+ */
+ class TraceList {
+
+ public:
+
+ /*!
+ * This enumberated type defines an exit reason
+ * for the end of a section.
+ */
+ typedef enum {
+ EXIT_REASON_BRANCH_TAKEN,
+ EXIT_REASON_BRANCH_NOT_TAKEN,
+ EXIT_REASON_OTHER
+ } exitReason_t;
+
+ /*!
+ * This type defines the information kept for each range.
+ */
+ typedef struct {
+ /*!
+ * This member variable contains the low address for the
+ * trace range.
+ */
+ uint32_t lowAddress;
+
+ /*!
+ * This member variable contains the length of the trace
+ * range.
+ */
+ uint16_t length;
+
+ /*!
+ * This member variable contains the reason that this
+ * trace range ended.
+ */
+ exitReason_t exitReason;
+ } traceRange_t;
+
+ /*!
+ * This member variable contains a list of CoverageRange instances.
+ */
+ typedef std::list<traceRange_t> ranges_t;
+
+ /*!
+ * This member variable contains a list of coverageRange
+ * instaces.
+ */
+ ranges_t set;
+
+ /*!<span style="background-color: #FF0000"> </span>
+ * This method constructs a TraceList instance.
+ */
+ TraceList();
+
+ /*!<span style="background-color: #FF0000"> </span>
+ * This method destructs a TraceList instance.
+ */
+ ~TraceList();
+
+ /*!
+ * This method adds a range entry to the set of ranges.
+ *
+ * @param[in] lowAddressArg specifies the lowest address of the range
+ * @param[in] highAddressArg specifies the highest address of the range
+ * @param[in] why specifies the reason that the range was finished
+ *
+ */
+ void add(
+ uint32_t lowAddressArg,
+ uint32_t highAddressArg,
+ exitReason_t why
+ );
+
+ /*!
+ * This method displays the trace information in the variable t.
+ */
+ void ShowTrace( traceRange_t *t);
+
+
+ /*!
+ * This method iterates through set displaying the data on the screen.
+ */
+ void ShowList();
+
+ };
+
+}
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/TraceList.cc:1.1
--- /dev/null Mon May 24 15:10:08 2010
+++ gcc-testing/covoar/TraceList.cc Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,54 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+#include "TraceList.h"
+#include <stdio.h>
+
+namespace Trace {
+
+ TraceList::TraceList()
+ {
+ }
+
+ TraceList::~TraceList()<span style="background-color: #FF0000"> </span>
+ {<span style="background-color: #FF0000"> </span>
+ }
+
+ void TraceList::add(
+ uint32_t lowAddressArg,
+ uint32_t highAddressArg,
+ exitReason_t why
+ )
+ {
+ traceRange_t t;
+
+ t.lowAddress = lowAddressArg;
+ t.length = highAddressArg - lowAddressArg;
+ t.exitReason = why;
+
+ set.push_back( t );<span style="background-color: #FF0000"> </span>
+ }
+
+ void TraceList::ShowTrace( traceRange_t *t)
+ {
+ printf(
+ "Start 0x%x, length 0x%03x Reason %d\n",<span style="background-color: #FF0000"> </span>
+ t->lowAddress,<span style="background-color: #FF0000"> </span>
+ t->length,<span style="background-color: #FF0000"> </span>
+ t->exitReason
+ );
+ }
+
+ void TraceList::ShowList()
+ {
+ ranges_t::iterator ritr;
+ traceRange_t t;
+
+ for ( ritr=set.begin(); ritr != set.end(); ritr++ ) {
+ t = *ritr;
+ ShowTrace( &t );
+ }
+ }
+
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/TraceReaderBase.h:1.1
--- /dev/null Mon May 24 15:10:08 2010
+++ gcc-testing/covoar/TraceReaderBase.h Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,59 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file TraceReaderBase.h
+ * @brief TraceReaderBase Specification
+ *
+ * This file contains the specification of the TraceReaderBase class.
+ */
+
+#ifndef __TRACE_READER_BASE_H__
+#define __TRACE_READER_BASE_H__
+
+#include "TraceList.h"
+
+namespace Trace {
+
+ /*! @class TraceReaderBase
+ *
+ * This is the specification of the TraceReader base class.
+ * All TraceReader implementations inherit from this class.
+ */
+ class TraceReaderBase {
+
+ public:
+
+ /*!
+ * Trace list that is filled by processFile.
+ */
+ TraceList Trace;
+
+
+ /*!<span style="background-color: #FF0000"> </span>
+ * This method constructs a TraceReaderBase instance.
+ */
+ TraceReaderBase();
+
+ /*!<span style="background-color: #FF0000"> </span>
+ * This method destructs a TraceReaderBase instance.
+ */
+ virtual ~TraceReaderBase();
+
+ /*!
+ * This method processes the coverage information from the input
+ * @a file and adds it to the specified @a executableInformation.
+ *
+ * @param[in] file is the coverage file to process
+ * @param[in] executableInformation is the information for an
+ * associated executable
+ *
+ * @return Returns TRUE if the method succeeded and FALSE if it failed.
+ */
+ virtual bool processFile(
+ const char* const file
+ ) = 0;
+ };
+
+}
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/TraceReaderBase.cc:1.1
--- /dev/null Mon May 24 15:10:08 2010
+++ gcc-testing/covoar/TraceReaderBase.cc Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,23 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file TraceReaderBase.cc
+ * @brief TraceReaderBase Implementation
+ *
+ * This file contains the implementation of the TraceReader base class.
+ * All TraceReader implementations inherit from this.
+ */
+
+#include "TraceReaderBase.h"
+
+namespace Trace {
+
+ TraceReaderBase::TraceReaderBase()
+ {
+ }
+
+ TraceReaderBase::~TraceReaderBase()
+ {
+ }
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/TraceReaderLogQEMU.h:1.1
--- /dev/null Mon May 24 15:10:08 2010
+++ gcc-testing/covoar/TraceReaderLogQEMU.h Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,54 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file TraceReaderLogQEMU.h
+ * @brief TraceReaderLogQEMU Specification
+ *
+ * This file contains the specification of the TraceReaderLogQEMU class.
+ */
+
+#ifndef __TRACE_READER_LOG_QEMU_H__
+#define __TRACE_READER_LOG_QEMU_H__
+
+#include "TraceReaderBase.h"
+
+namespace Trace {
+
+ /*! @class TraceReaderLogQEMU
+ *
+ * This is the specification of the TraceReader base class.
+ * All TraceReader implementations inherit from this class.
+ */
+ class TraceReaderLogQEMU: public TraceReaderBase {
+
+ public:
+
+
+ /*!<span style="background-color: #FF0000"> </span>
+ * This method constructs a TraceReaderLogQEMU instance.
+ */
+ TraceReaderLogQEMU();
+
+ /*!<span style="background-color: #FF0000"> </span>
+ * This method destructs a TraceReaderLogQEMU instance.
+ */
+ virtual ~TraceReaderLogQEMU();
+
+ /*!
+ * This method processes the coverage information from the input
+ * @a file and adds it to the specified @a executableInformation.
+ *
+ * @param[in] file is the coverage file to process
+ * @param[in] executableInformation is the information for an
+ * associated executable
+ *
+ * @return Returns TRUE if the method succeeded and FALSE if it failed.
+ */
+ virtual bool processFile(
+ const char* const file
+ );
+ };
+
+}
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/TraceReaderLogQEMU.cc:1.1
--- /dev/null Mon May 24 15:10:09 2010
+++ gcc-testing/covoar/TraceReaderLogQEMU.cc Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,177 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file TraceReaderLogQEMU.cc
+ * @brief TraceReaderLogQEMU Implementation
+ *
+ * This file contains the implementation of the functions supporting
+ * reading the QEMU coverage data files.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <string.h>
+
+#include "qemu-log.h"
+
+#include "app_common.h"
+#include "TraceReaderBase.h"
+#include "TraceReaderLogQEMU.h"
+#include "TraceList.h"
+
+/* XXX really not always right */
+typedef uint32_t target_ulong;
+
+#include "qemu-traces.h"
+
+/* hack so this can compile on the RH7 RTEMS 4.5 host */
+#if (__GNUC__ <= 2)
+#define STAT stat
+#define OPEN fopen
+#else
+#define STAT stat64
+#define OPEN fopen64
+#endif
+
+
+namespace Trace {
+
+ TraceReaderLogQEMU::TraceReaderLogQEMU()
+ {
+ }
+
+ TraceReaderLogQEMU::~TraceReaderLogQEMU()
+ {
+ }
+
+ bool TraceReaderLogQEMU::processFile(
+ const char* const file
+ )
+ {
+ bool done = false;
+ QEMU_LOG_IN_Block_t first = { 0, "", "" };
+ QEMU_LOG_IN_Block_t last = { 0, "", "" };
+ QEMU_LOG_IN_Block_t nextExecuted = { 0, "", "" };
+ uint32_t nextlogical;
+ struct STAT statbuf;
+ int status;
+ FILE* logFile;
+ int result;
+ char buffer[120];
+
+ //
+ // Verify that the log file has a non-zero size.
+ //
+ // NOTE: We prefer stat64 because some of the coverage files are HUGE!
+ status = STAT( file, &statbuf );
+ if (status == -1) {
+ fprintf( stderr, "Unable to stat %s\n", file );
+ return false;
+ }
+
+ if (statbuf.st_size == 0) {
+ fprintf( stderr, "%s is 0 bytes long\n", file );
+ return false;
+ }
+
+ //
+ // Open the coverage file and discard the header.
+ //
+ logFile = OPEN( file, "r" );
+ if (!logFile) {
+ fprintf( stderr, "Unable to open %s\n", file );
+ return false;
+ }
+
+
+ //
+ // Discard Header section
+ //
+ if (! ReadUntilFound( logFile, QEMU_LOG_SECTION_END ) ) {
+ fprintf( stderr, "Unable to locate end of log file header\n" );
+ return false;
+ }
+
+ //
+ // Find first IN block
+ //
+ if (! ReadUntilFound( logFile, QEMU_LOG_IN_KEY )){
+ fprintf(stderr,"Error: Unable to locate first IN: Block in Log file \n");
+ return false;
+ }
+
+ //
+ // Read First Start Address
+ //
+ fgets(buffer, 120, logFile );
+ result = sscanf(<span style="background-color: #FF0000"> </span>
+ buffer,<span style="background-color: #FF0000"> </span>
+ "0x%08lx: %s %s\n",<span style="background-color: #FF0000"> </span>
+ &first.address,<span style="background-color: #FF0000"> </span>
+ first.instruction,<span style="background-color: #FF0000"> </span>
+ first.data<span style="background-color: #FF0000"> </span>
+ );
+ if ( result < 2 )<span style="background-color: #FF0000"> </span>
+ {
+ fprintf(stderr, "Error Unable to Read Initial First Block\n" );
+ done = true;
+ }
+
+ while (!done) {
+
+ last = first;
+<span style="background-color: #FF0000"> </span>
+ // Read until we get to the last instruction in the block.
+ do {
+ fgets(buffer, 120, logFile );
+ result = sscanf(<span style="background-color: #FF0000"> </span>
+ buffer,<span style="background-color: #FF0000"> </span>
+ "0x%08lx: %s %s\n",<span style="background-color: #FF0000"> </span>
+ &last.address,<span style="background-color: #FF0000"> </span>
+ last.instruction,<span style="background-color: #FF0000"> </span>
+ last.data<span style="background-color: #FF0000"> </span>
+ );
+ } while( result > 1);
+
+ nextlogical = objdumpProcessor->getAddressAfter(last.address);
+
+ if (! ReadUntilFound( logFile, QEMU_LOG_IN_KEY )) {
+ done = true;
+ nextExecuted = last;
+ } else {
+ fgets(buffer, 120, logFile );
+ result = sscanf(<span style="background-color: #FF0000"> </span>
+ buffer,<span style="background-color: #FF0000"> </span>
+ "0x%08lx: %s %s\n",<span style="background-color: #FF0000"> </span>
+ &nextExecuted.address,<span style="background-color: #FF0000"> </span>
+ nextExecuted.instruction,<span style="background-color: #FF0000"> </span>
+ nextExecuted.data<span style="background-color: #FF0000"> </span>
+ );
+ if ( result < 2 )<span style="background-color: #FF0000"> </span>
+ {
+ fprintf(stderr, "Error Unable to Read First Block\n" );
+ }
+ }
+
+ // If the nextlogical was not found we are throwing away
+ // the block; otherwise add the block to the trace list.
+ if (nextlogical != 0) {
+ TraceList::exitReason_t reason = TraceList::EXIT_REASON_OTHER;
+
+ if ( objdumpProcessor->IsBranch( last.instruction ) ) {
+ if ( nextExecuted.address == nextlogical ) {
+ reason = TraceList::EXIT_REASON_BRANCH_NOT_TAKEN;
+ } else {
+ reason = TraceList::EXIT_REASON_BRANCH_TAKEN;
+ }
+ }
+ Trace.add( first.address, nextlogical, reason );
+ }
+ first = nextExecuted;
+ }<span style="background-color: #FF0000"> </span>
+ fclose( logFile );
+ return true;
+ }
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/TraceWriterBase.h:1.1
--- /dev/null Mon May 24 15:10:09 2010
+++ gcc-testing/covoar/TraceWriterBase.h Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,53 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file TraceWriterBase.h
+ * @brief TraceWriterBase Specification
+ *
+ * This file contains the specification of the TraceWriterBase class.
+ */
+
+#ifndef __TRACE_WRITER_BASE_H__
+#define __TRACE_WRITER_BASE_H__
+
+#include <stdint.h>
+#include "TraceReaderBase.h"
+
+namespace Trace {
+
+ /*! @class TraceWriterBase
+ *
+ * This is the specification of the TraceWriter base class.
+ * All TraceWriter implementations inherit from this class.
+ */
+ class TraceWriterBase {
+
+ public:
+
+ /*!<span style="background-color: #FF0000"> </span>
+ * This method constructs a TraceWriterBase instance.
+ */
+ TraceWriterBase();
+
+ /*!<span style="background-color: #FF0000"> </span>
+ * This method destructs a TraceWriterBase instance.
+ */
+ virtual ~TraceWriterBase();
+
+ /*!
+ * This method writes the specified @a trace file.
+ *
+ * @param[in] file specifies the name of the file to write
+ * @param[in] log structure where the trace data was read into
+ *
+ * @return Returns TRUE if the method succeeded and FALSE if it failed.
+ */
+ virtual bool writeFile(
+ const char* const file,
+ Trace::TraceReaderBase *log
+ ) = 0;
+ };
+
+}
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/TraceWriterBase.cc:1.1
--- /dev/null Mon May 24 15:10:09 2010
+++ gcc-testing/covoar/TraceWriterBase.cc Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,24 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file TraceWriterBase.cc
+ * @brief TraceWriterBase Implementation
+ *
+ * This file contains the implementation of the TraceWriter base class.
+ * All TraceWriter implementations inherit from this.
+ */
+
+#include "TraceWriterBase.h"
+
+namespace Trace {
+
+ TraceWriterBase::TraceWriterBase()
+ {
+ }
+
+ TraceWriterBase::~TraceWriterBase()
+ {
+ }
+
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/TraceWriterQEMU.h:1.1
--- /dev/null Mon May 24 15:10:09 2010
+++ gcc-testing/covoar/TraceWriterQEMU.h Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,54 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file TraceWriterQEMU.h
+ * @brief TraceWriterQEMU Specification
+ *
+ * This file contains the specification of the TraceWriterQEMU class.
+ */
+
+#ifndef __TRACE_WRITER_QEMU_H__
+#define __TRACE_WRITER_QEMU_H__
+
+#include <stdint.h>
+#include "TraceReaderBase.h"
+#include "TraceWriterBase.h"
+
+namespace Trace {
+
+ /*! @class TraceWriterQEMU
+ *
+ * This is the specification of the TraceWriter base class.
+ * All TraceWriter implementations inherit from this class.
+ */
+ class TraceWriterQEMU: public TraceWriterBase {
+
+ public:
+
+ /*!<span style="background-color: #FF0000"> </span>
+ * This method constructs a TraceWriterQEMU instance.
+ */
+ TraceWriterQEMU();
+
+ /*!<span style="background-color: #FF0000"> </span>
+ * This method destructs a TraceWriterQEMU instance.
+ */
+ virtual ~TraceWriterQEMU();
+
+ /*!
+ * This method writes the specified @a trace file.
+ *
+ * @param[in] file specifies the name of the file to write
+ * @param[in] log structure where the trace data was read into
+ *
+ * @return Returns TRUE if the method succeeded and FALSE if it failed.
+ */
+ bool writeFile(
+ const char* const file,
+ Trace::TraceReaderBase *log
+ );
+ };
+
+}
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/TraceWriterQEMU.cc:1.1
--- /dev/null Mon May 24 15:10:09 2010
+++ gcc-testing/covoar/TraceWriterQEMU.cc Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,148 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file TraceWriterQEMU.cc
+ * @brief TraceWriterQEMU Implementation
+ *
+ * This file contains the implementation of the functions supporting
+ * reading the QEMU coverage data files.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#include "app_common.h"
+#include "TraceWriterQEMU.h"
+#include "ExecutableInfo.h"
+#include "CoverageMap.h"
+
+/* XXX really not always right */
+typedef uint32_t target_ulong;
+
+#include "qemu-traces.h"
+
+/* hack so this can compile on the RH7 RTEMS 4.5 host */
+#if (__GNUC__ <= 2)
+#define STAT stat
+#define OPEN fopen
+#else
+#define STAT stat64
+#define OPEN fopen64
+#endif
+
+namespace Trace {
+
+ TraceWriterQEMU::TraceWriterQEMU():
+ TraceWriterBase()
+ {
+ }
+
+ TraceWriterQEMU::~TraceWriterQEMU()
+ {
+ }
+
+ bool TraceWriterQEMU::writeFile(
+ const char* const file,
+ Trace::TraceReaderBase *log
+ )
+ {
+ struct trace_header header;
+ int status;
+ FILE* traceFile;
+ uint8_t taken;
+ uint8_t notTaken;
+
+ taken = TargetInfo->qemuTakenBit();
+ notTaken = TargetInfo->qemuNotTakenBit();
+
+ //
+ // Verify that the TraceList has a non-zero size.
+ //
+ if ( log->Trace.set.begin() == log->Trace.set.end() ){
+ fprintf( stderr, "ERROR: Empty TraceList\n" );
+ return false;
+ }
+
+ //
+ // Open the trace file.
+ //
+ traceFile = OPEN( file, "w" );
+ if (!traceFile) {
+ fprintf( stderr, "Unable to open %s\n", file );
+ return false;
+ }
+
+ //
+ // Write the Header to the file
+ //
+ sprintf( header.magic, "%s", QEMU_TRACE_MAGIC );
+ header.version = QEMU_TRACE_VERSION;
+ header.kind = QEMU_TRACE_KIND_RAW; // XXX ??
+ header.sizeof_target_pc = 32;
+ header.big_endian = false;
+ header.machine[0] = 0; // XXX ??
+ header.machine[1] = 0; // XXX ??
+ status = fwrite( &header, sizeof(trace_header), 1, traceFile );
+ if (status != 1) {
+ fprintf( stderr, "Unable to write header to %s\n", file );
+ return false;
+ }
+
+ if (Verbose)<span style="background-color: #FF0000"> </span>
+ fprintf(
+ stderr,
+ "magic = %s\n"
+ "version = %d\n"
+ "kind = %d\n"
+ "sizeof_target_pc = %d\n"
+ "big_endian = %d\n"
+ "machine = %02x:%02x\n",
+ header.magic,
+ header.version,
+ header.kind,
+ header.sizeof_target_pc,
+ header.big_endian,
+ header.machine[0], header.machine[1]
+ );
+
+ //
+ // Loop through log and write each entry.
+ //
+ struct trace_entry32 entry;
+ TraceList::ranges_t::iterator itr;
+
+ for (itr = log->Trace.set.begin(); (itr != log->Trace.set.end()); itr++ ){
+ entry.pc = itr->lowAddress;
+ entry.size = itr-> length;
+ entry.op = TRACE_OP_BLOCK;
+ switch (itr->exitReason) {
+ case TraceList::EXIT_REASON_BRANCH_TAKEN:
+ entry.op |= taken;
+ break;
+ case TraceList::EXIT_REASON_BRANCH_NOT_TAKEN:
+ entry.op |= notTaken;
+ break;
+ case TraceList::EXIT_REASON_OTHER:
+ break;
+ default:
+ fprintf(stderr, "Unknown exit Reason\n");
+ exit(1);
+ break;
+ }
+<span style="background-color: #FF0000"> </span>
+ if ( Verbose )
+ fprintf(stderr, "%x %x %x\n", entry.pc, entry.size, entry.op);
+
+ status = fwrite( &entry, sizeof(entry), 1, traceFile );
+ if (status != 1) {
+ fprintf( stderr, "Unable to emtry to %s\n", file );
+ return false;
+ }
+ }
+
+ fclose( traceFile );
+ return true;
+ }
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/app_common.h:1.1
--- /dev/null Mon May 24 15:10:09 2010
+++ gcc-testing/covoar/app_common.h Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,29 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+#ifndef __APP_COMMON_h
+#define __APP_COMMON_h
+
+#include <list>
+
+#include "DesiredSymbols.h"
+#include "Explanations.h"
+#include "TargetBase.h"
+
+extern Coverage::Explanations* AllExplanations;
+extern Coverage::ObjdumpProcessor* objdumpProcessor;
+extern Coverage::DesiredSymbols* SymbolsToAnalyze;
+extern bool Verbose;
+extern const char* outputDirectory;
+extern bool BranchInfoAvailable;
+extern Target::TargetBase* TargetInfo;
+extern const char* dynamicLibrary;
+extern const char* projectName;
+
+
+bool FileIsNewer( const char *f1, const char *f2 );<span style="background-color: #FF0000"> </span>
+bool FileIsReadable( const char *f1 );<span style="background-color: #FF0000"> </span>
+bool ReadUntilFound( FILE *file, const char *line );
+
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/app_common.cc:1.1
--- /dev/null Mon May 24 15:10:09 2010
+++ gcc-testing/covoar/app_common.cc Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,85 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "app_common.h"
+#include "DesiredSymbols.h"
+#include "Explanations.h"
+
+/* hack so this can compile on the RH7 RTEMS 4.5 host */
+#if (__GNUC__ <= 2)
+#define STAT stat
+#define OPEN fopen
+#else
+#define STAT stat64
+#define OPEN fopen64
+#endif
+
+/*
+ * Global variables for the program
+ */
+Coverage::Explanations* AllExplanations = NULL;
+Coverage::ObjdumpProcessor* objdumpProcessor = NULL;
+Coverage::DesiredSymbols* SymbolsToAnalyze = NULL;
+bool Verbose = false;
+const char* outputDirectory = ".";
+bool BranchInfoAvailable = false;
+Target::TargetBase* TargetInfo = NULL;
+const char* dynamicLibrary = NULL;
+const char* projectName = NULL;
+
+
+bool FileIsNewer(
+ const char *f1,
+ const char *f2
+)
+{
+ struct STAT buf1, buf2;
+
+ if (STAT( f2, &buf2 ) == -1)
+ return true;
+<span style="background-color: #FF0000"> </span>
+ if (STAT( f1, &buf1 ) == -1)
+ exit (1);
+
+ if (buf1.st_mtime > buf2.st_mtime)
+ return true;
+
+ return false;
+}
+
+bool FileIsReadable( const char *f1 )
+{
+ struct STAT buf1;
+
+ if (STAT( f1, &buf1 ) == -1)
+ return false;
+
+ if (buf1.st_size == 0)
+ return false;
+
+ // XXX check permission ??
+ return true;
+}
+
+bool ReadUntilFound( FILE *file, const char *line )
+{
+ char discardBuff[100];
+ size_t len = strlen( line );
+
+ do {<span style="background-color: #FF0000"> </span>
+ if ( !fgets( discardBuff, 99, file ) )
+ return false;
+
+ if ( strncmp( discardBuff, line, len ) == 0 )<span style="background-color: #FF0000"> </span>
+ return true;<span style="background-color: #FF0000"> </span>
+ } while (1);
+}
+
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/configfile_test.cc:1.1
--- /dev/null Mon May 24 15:10:09 2010
+++ gcc-testing/covoar/configfile_test.cc Mon May 24 15:07:08 2010
</font><font color='#997700'>@@ -0,0 +1,27 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+#include "ConfigFile.h"
+#include <stdio.h>
+
+Configuration::Options_t Options[] = {
+ { "projectName", NULL },
+ { "verbose", NULL },
+ { NULL, NULL }
+};
+
+int main(
+ int argc,
+ char *argv[]
+)
+{
+ Configuration::FileReader *config;
+
+ config = new Configuration::FileReader(Options);
+<span style="background-color: #FF0000"> </span>
+ config->processFile( "configFile.txt" );
+ config->printOptions();
+
+}
+
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/coverage_converter.cc:1.1
--- /dev/null Mon May 24 15:10:09 2010
+++ gcc-testing/covoar/coverage_converter.cc Mon May 24 15:07:09 2010
</font><font color='#997700'>@@ -0,0 +1,224 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <netdb.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "app_common.h"
+#include "CoverageFactory.h"
+#include "CoverageMap.h"
+
+/*
+ * Variables to control global behavior
+ */
+Coverage::CoverageReaderBase* coverageReader = NULL;
+Coverage::CoverageWriterBase* coverageWriter = NULL;
+uint32_t highAddress = 0xffffffff;
+Coverage::CoverageFormats_t inputFormat;
+uint32_t lowAddress = 0xffffffff;
+char* progname;
+
+/*
+ * Global variables for the program
+ */
+Coverage::CoverageMapBase *CoverageMap = NULL;
+
+/*
+ * Convert string to int with status out
+ */
+
+bool stringToUint32(
+ const char* s,
+ int base,
+ uint32_t* n
+)
+{
+ long long result;
+
+ if (!n)
+ return false;
+
+ errno = 0;
+ *n = 0;
+
+ result = strtoll( s, NULL, base );
+
+ if ((result == 0) && errno)
+ return false;<span style="background-color: #FF0000"> </span>
+
+ if ((result == LLONG_MAX) && (errno == ERANGE))
+ return false;<span style="background-color: #FF0000"> </span>
+
+ if ((result == LLONG_MIN) && (errno == ERANGE))
+ return false;<span style="background-color: #FF0000"> </span>
+
+ *n = (uint32_t)result;
+ return true;
+}
+
+/*
+ * Print program usage message
+ */
+void usage()
+{
+ fprintf(
+ stderr,
+ "Usage: %s [-v] -l ADDRESS -h ADDRESS coverage_in coverage_out\n"
+ "\n"
+ " -l low address - low address of range to merge\n"
+ " -l high address - high address of range to merge\n"
+ " -f format - coverage files are in <format> (Qemu)\n"
+ " -v - verbose at initialization\n"
+ "\n",
+ progname
+ );
+}
+
+#define PrintableString(_s) \
+ ((!(_s)) ? "NOT SET" : (_s))
+
+int main(
+ int argc,
+ char** argv
+)
+{
+ char* format = NULL;
+ const char* coverageFile;
+ const char* coverageIn;
+ int opt;
+
+ //
+ // Process command line options.
+ //
+ progname = argv[0];
+
+ while ((opt = getopt(argc, argv, "f:h:l:v")) != -1) {
+ switch (opt) {
+ case 'v': Verbose = 1; break;
+ case 'f':
+ inputFormat = Coverage::CoverageFormatToEnum(optarg);
+ format = optarg;
+ break;
+ case 'l':
+ if (!stringToUint32( optarg, 16, &lowAddress )) {
+ fprintf( stderr, "ERROR: Low address is not a hexadecimal number\n" );
+ usage();
+ exit(-1);
+ }
+ break;
+ case 'h':<span style="background-color: #FF0000"> </span>
+ if (!stringToUint32( optarg, 16, &highAddress )) {
+ fprintf( stderr, "ERROR: High address is not a hexadecimal number\n" );
+ usage();
+ exit(-1);
+ }
+ break;
+ default: /* '?' */
+ usage();
+ exit( -1 );
+ }
+ }
+
+ if ((argc - optind) != 2) {
+ fprintf( stderr, "ERROR: Must provide input and output files\n" );
+ exit(1);
+ }
+
+ coverageIn = argv[optind];
+ coverageFile = argv[optind + 1];
+
+ if (Verbose) {
+ fprintf( stderr, "Verbose : %d\n", Verbose );
+ fprintf( stderr, "Input Format : %s\n", format );
+ fprintf( stderr, "Input File : %s\n", coverageIn );
+ fprintf( stderr, "Output Format : %s\n", "RTEMS" );
+ fprintf( stderr, "Output File : %s\n", coverageFile );
+ fprintf( stderr, "low address : 0x%08x\n", lowAddress );
+ fprintf( stderr, "high address : 0x%08x\n", highAddress );
+ fprintf( stderr, "\n" );
+ }
+
+ //
+ // Validate inputs.
+ //
+
+ // Validate format.
+ if (!format) {
+ fprintf( stderr, "ERROR: input format must be given.\n\n" );
+ usage();
+ exit(-1);
+ }
+
+ // Validate address range
+ if (lowAddress == 0xffffffff) {
+ fprintf( stderr, "ERROR: Low address not specified.\n\n" );
+ usage();
+ exit(-1);
+ }
+
+ if (highAddress == 0xffffffff) {
+ fprintf( stderr, "ERROR: High address not specified.\n\n" );
+ usage();
+ exit(-1);
+ }
+
+ if (lowAddress >= highAddress) {
+ fprintf( stderr, "ERROR: Low address >= high address.\n\n" );
+ usage();
+ exit(-1);
+ }
+
+ //
+ // Create data to support conversion.
+ //
+
+ // Create coverage map.
+ CoverageMap = new Coverage::CoverageMap( lowAddress, highAddress );
+ if (!CoverageMap) {
+ fprintf( stderr, "ERROR: Unable to create coverage map.\n\n" );
+ exit(-1);
+ }
+
+ // Create coverage writer.
+ coverageWriter =
+ Coverage::CreateCoverageWriter(Coverage::COVERAGE_FORMAT_RTEMS);
+ if (!coverageWriter) {
+ fprintf( stderr, "ERROR: Unable to create coverage file writer.\n\n" );
+ exit(-1);
+ }
+
+ // Create coverage reader.
+ coverageReader = CreateCoverageReader( inputFormat );
+ if (!coverageReader) {
+ fprintf( stderr, "ERROR: Unable to create input file reader.\n\n" );
+ exit(-1);
+ }
+
+ // Now get to some real work.
+ if (Verbose)
+ fprintf( stderr, "Processing %s\n", coverageIn );
+ coverageReader->processFile( coverageIn, CoverageMap );
+
+ if (Verbose)
+ fprintf(
+ stderr, "Writing coverage file (%s)\n", coverageFile );
+ coverageWriter->writeFile(
+ coverageFile,
+ CoverageMap,
+ lowAddress,
+ highAddress
+ );
+
+ return 0;
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/covmerge.cc:1.1
--- /dev/null Mon May 24 15:10:09 2010
+++ gcc-testing/covoar/covmerge.cc Mon May 24 15:07:09 2010
</font><font color='#997700'>@@ -0,0 +1,545 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "app_common.h"
+#include "CoverageFactory.h"
+#include "CoverageMap.h"
+#include "CoverageRanges.h"
+#include "Explanations.h"
+#include "ObjdumpProcessor.h"
+#include "Reports.h"
+
+/*
+ * Variables to control global behavior
+ */
+int verbose = 0;
+Coverage::CoverageFormats_t coverageFormat;
+char *mergedCoverageFile = NULL;
+char *branchReportFile = NULL;
+char *coverageReportFile = NULL;
+char *sizeReportFile = NULL;
+uint32_t lowAddress = 0xffffffff;
+uint32_t highAddress = 0xffffffff;
+
+char *target = NULL;
+char *executable = NULL;
+char *explanations = NULL;
+char *noExplanations = NULL;
+char *progname;
+
+/*
+ * Global variables for the program
+ */
+Coverage::CoverageMapBase *CoverageMap = NULL;
+Coverage::CoverageReaderBase *CoverageReader = NULL;
+Coverage::CoverageWriterBase *CoverageWriter = NULL;
+Coverage::ObjdumpProcessor *ObjdumpProcessor = NULL;
+Coverage::CoverageRanges *Ranges = NULL;
+Coverage::Explanations *Explanations = NULL;
+
+int BranchesAlwaysTaken = 0;
+bool BranchesFound = false;
+int BranchesNeverTaken = 0;
+int UncoveredRanges = 0;
+
+/*
+ * Set of addresses we need source line number for
+ */
+std::list<uint32_t> AddressesNeedingSourceLine;<span style="background-color: #FF0000"> </span>
+
+/*
+ * Convert string to int with status out
+ */
+
+bool stringToUint32(
+ const char *s,
+ int base,
+ uint32_t *n
+)
+{
+ long long result;
+
+ if ( !n )
+ return false;
+
+ errno = 0;
+ *n = 0;
+
+ result = strtoll( s, NULL, base );
+
+ if ( (result == 0) && errno )
+ return false;<span style="background-color: #FF0000"> </span>
+
+ if ( (result == LLONG_MAX) && (errno == ERANGE))
+ return false;<span style="background-color: #FF0000"> </span>
+
+ if ( (result == LLONG_MIN) && (errno == ERANGE))
+ return false;<span style="background-color: #FF0000"> </span>
+
+ *n = (uint32_t)result;
+ return true;
+}
+
+/*
+ * Print program usage message
+ */
+void usage()
+{
+ fprintf(
+ stderr,
+ "Usage: %s [-v] [-t] [-m file] -T TARGET [-e EXECUTABLE]-l ADDRESS -h ADDRESS coverage1... coverageN\n"
+ "\n"
+ " -l low address - low address of range to merge\n"
+ " -l high address - high address of range to merge\n"
+ " -f format - coverage files are in <format> "
+ "(RTEMS, TSIM or Skyeye)\n"
+ " -m FILE - optional merged coverage file to write\n"
+ " -r REPORT - optional coverage report to write\n"
+ " -s REPORT - optional size report to write\n"
+ " -T TARGET - target name\n"
+ " -e EXECUTABLE - name of executable to get symbols from\n"
+ " -E EXPLANATIONS - name of file with explanations\n"
+ " -v - verbose at initialization\n"
+ "\n",
+ progname
+ );
+}
+
+/*
+ * Look over the coverage map and compute uncovered ranges and branches
+ */
+void ComputeUncovered(void)
+{
+ uint32_t a, la, ha;
+ std::list<Coverage::CoverageRange>::iterator it;
+
+ a = lowAddress;
+ while (a < highAddress) {
+
+ /*
+ * Find all the unexecuted addresses and add them to the range.
+ */
+ if (!CoverageMap->wasExecuted( a )) {
+ la = a;
+ for (ha=a+1; ha<=highAddress && !CoverageMap->wasExecuted(ha); ha++)
+ ;
+ ha--;
+
+ UncoveredRanges++;
+ Ranges->add( la, ha );
+ AddressesNeedingSourceLine.push_back( la );<span style="background-color: #FF0000"> </span>
+ AddressesNeedingSourceLine.push_back( ha );<span style="background-color: #FF0000"> </span>
+ a = ha + 1;
+ }
+
+ else if (CoverageMap->isBranch( a )) {
+ BranchesFound = true;
+ la = a;
+ for (ha=a+1;
+ ha<=highAddress && !CoverageMap->isStartOfInstruction(ha);
+ ha++)
+ ;
+ ha--;
+
+ if (CoverageMap->wasAlwaysTaken( la )) {
+ BranchesAlwaysTaken++;
+ AddressesNeedingSourceLine.push_back( la );<span style="background-color: #FF0000"> </span>
+ }
+ else if (CoverageMap->wasNeverTaken( la )) {
+ BranchesNeverTaken++;
+ AddressesNeedingSourceLine.push_back( la );<span style="background-color: #FF0000"> </span>
+ }
+ a = ha + 1;
+ }
+ else
+ a++;
+ }
+}
+
+/*
+ * Find source lines for addresses
+ */
+void FindSourceForAddresses(void)
+{
+ FILE *tmpfile;
+ std::list<uint32_t>::iterator it;<span style="background-color: #FF0000"> </span>
+
+ /*
+ * Write a temporary file with ranges
+ */
+ if ( verbose )
+ fprintf( stderr, "Writing ranges.tmp input to addr2line\n" );
+
+ tmpfile = fopen( "ranges.tmp", "w" );
+ if ( !tmpfile ) {
+ fprintf( stderr, "Unable to open %s\n\n", "ranges.tmp" );
+ exit(-1);
+ }
+
+ for (it = AddressesNeedingSourceLine.begin() ;
+ it != AddressesNeedingSourceLine.end() ;
+ it++ ) {
+ fprintf(tmpfile, "0x%08x\n", *it);
+ }
+
+ fclose( tmpfile );
+
+ /*
+ * Generate a file with the addr2line mapping
+ */
+ if ( verbose )
+ fprintf( stderr, "Running addr2line\n" );
+
+ {
+ char command[512];
+ sprintf(
+ command,
+ "%s -e %s <%s | dos2unix >%s",
+ Tools->getAddr2line(),
+ executable,
+ "ranges.tmp",
+ "ranges01.tmp"
+ );
+ if ( system( command ) ) {
+ fprintf( stderr, "addr2line command (%s) failed\n", command );
+ exit( -1 );
+ }
+ }
+
+ /*
+ * Go back over the ranges, read the addr2line output, and correlate it.
+ */
+ if ( verbose )
+ fprintf( stderr, "Merging addr2line output into range\n" );
+
+ tmpfile = fopen( "ranges01.tmp", "r" );
+ if ( !tmpfile ) {
+ fprintf( stderr, "Unable to open %s\n\n", "ranges01.tmp" );
+ exit(-1);
+ }
+
+ for (it = AddressesNeedingSourceLine.begin() ;
+ it != AddressesNeedingSourceLine.end() ;
+ it++ ) {
+ char buffer[512];
+ char *cStatus;
+
+ cStatus = fgets( buffer, 512, tmpfile );
+ if ( cStatus == NULL ) {
+ fprintf( stderr, "Out of sync in addr2line output\n" );
+ exit( -1 );
+ }
+ buffer[ strlen(buffer) - 1] = '\0';
+
+ CoverageMap->setSourceLine( *it, std::string( buffer ) );
+ }
+ fclose( tmpfile );
+}
+
+#define PrintableString(_s) \
+ ((!(_s)) ? "NOT SET" : (_s))
+
+int main(
+ int argc,
+ char **argv
+)
+{
+ int opt;
+ int i;
+ char *format = NULL;
+
+ progname = argv[0];
+
+ while ((opt = getopt(argc, argv, "b:e:E:f:h:l:m:r:s:T:v")) != -1) {
+ switch (opt) {
+ case 'b': branchReportFile = optarg; break;
+ case 'e': executable = optarg; break;
+ case 'E': explanations = optarg; break;
+ case 'm': mergedCoverageFile = optarg; break;
+ case 'r': coverageReportFile = optarg; break;
+ case 's': sizeReportFile = optarg; break;
+ case 'T': target = optarg; break;
+ case 'v': verbose = 1; break;
+ case 'f':
+ coverageFormat = Coverage::CoverageFormatToEnum(optarg);
+ format = optarg;
+ break;
+ case 'l':
+ if ( ! stringToUint32( optarg, 16, &lowAddress ) ) {
+ fprintf( stderr, "Low address is not a hexadecimal number\n" );
+ usage();
+ exit(-1);
+ }
+ break;
+ case 'h':<span style="background-color: #FF0000"> </span>
+ if ( ! stringToUint32( optarg, 16, &highAddress ) ) {
+ fprintf( stderr, "High address is not a hexadecimal number\n" );
+ usage();
+ exit(-1);
+ }
+ break;
+ default: /* '?' */
+ usage();
+ exit( -1 );
+ }
+ }
+ if ( verbose ) {
+ fprintf( stderr, "verbose : %d\n", verbose );
+ fprintf( stderr, "Coverage Format : %s\n", format );
+ fprintf( stderr, "low address : 0x%08x\n", lowAddress );
+ fprintf( stderr, "high address : 0x%08x\n", highAddress );
+ fprintf( stderr, "Target : %s\n", PrintableString(target) );
+ fprintf( stderr, "executable : %s\n", PrintableString(executable) );
+ fprintf( stderr, "merged coverage : %s\n",
+ PrintableString(mergedCoverageFile) );
+ fprintf( stderr, "\n" );
+ }
+
+ /*
+ * Target name must be set
+ */
+ if ( !target ) {
+ fprintf( stderr, "target must be given.\n\n" );
+ usage();
+ exit(-1);
+ }
+
+ /*
+ * Validate format
+ */
+ if ( !format ) {
+ fprintf( stderr, "coverage format report must be given.\n\n" );
+ usage();
+ exit(-1);
+ }
+
+ /*
+ * Validate address range
+ */
+ if ( lowAddress == 0xffffffff ) {
+ fprintf( stderr, "Low address not specified.\n\n" );
+ usage();
+ exit(-1);
+ }
+
+ if ( highAddress == 0xffffffff ) {
+ fprintf( stderr, "High address not specified.\n\n" );
+ usage();
+ exit(-1);
+ }
+
+ if ( lowAddress >= highAddress ) {
+ fprintf( stderr, "Low address >= high address.\n\n" );
+ usage();
+ exit(-1);
+ }
+
+ /*
+ * Create toolnames based on target
+ */
+ TargetInfo = Target::TargetFactory( target );
+
+ /*
+ * Create a ranges set
+ */
+ Ranges = new Coverage::CoverageRanges();
+ Explanations = new Coverage::Explanations();
+
+ Explanations->load( explanations );
+
+ /*
+ * Create coverage map
+ */
+ CoverageMap = new Coverage::CoverageMap( lowAddress, highAddress );
+ if ( !CoverageMap ) {
+ fprintf( stderr, "Unable to create coverage map.\n\n" );
+ exit(-1);
+ }
+
+ /*
+ * Create input
+ */
+ CoverageReader = Coverage::CreateCoverageReader(coverageFormat);
+ if ( !CoverageReader ) {
+ fprintf( stderr, "Unable to create coverage file reader.\n\n" );
+ exit(-1);
+ }
+
+ /*
+ * Create the objdump processor
+ */
+ ObjdumpProcessor = new Coverage::ObjdumpProcessor();
+
+ /*
+ * Create writer
+ *
+ * NOTE: We ALWAYS write the merged coverage in RTEMS format.
+ */
+ CoverageWriter = Coverage::CreateCoverageWriter(
+ Coverage::COVERAGE_FORMAT_RTEMS
+ );
+ if ( !CoverageWriter ) {
+ fprintf( stderr, "Unable to create coverage file writer.\n\n" );
+ exit(-1);
+ }
+
+ /*
+ * Add in the objdump before reading the coverage information. We may
+ * want to take advantage of the information line where instructions
+ * begin.
+ */
+ if ( executable ) {
+ if ( verbose )
+ fprintf( stderr, "Reading objdump of %s\n", executable );
+ ObjdumpProcessor->initialize( executable, CoverageMap );
+ }
+
+ /*
+ * Now get to some real work
+ */
+ if ( verbose )
+ fprintf( stderr, "Processing coverage files\n" );
+ for ( i=optind ; i < argc ; i++ ) {
+ //fprintf( stderr, "Processing %s\n", argv[i] );
+ CoverageReader->ProcessFile( argv[i], CoverageMap );
+ }<span style="background-color: #FF0000"> </span>
+
+ /*
+ * Now to write some output
+ */
+ if ( mergedCoverageFile ) {
+ if ( verbose )
+ fprintf(
+ stderr,
+ "Writing merged coverage file (%s)\n",
+ mergedCoverageFile
+ );
+ CoverageWriter->writeFile(
+ mergedCoverageFile,
+ CoverageMap,
+ lowAddress,
+ highAddress
+ );
+ }
+
+ /*
+ * Marks nops as executed when they are surrounded by executed instructions.
+ */
+ ObjdumpProcessor->markNopsAsExecuted( CoverageMap );
+
+ /*
+ * Iterate over the coverage map and determine the uncovered
+ * ranges and branches.
+ */
+ ComputeUncovered();
+
+ /*
+ * Look up the source file and line number for the addresses
+ * of interest.
+ */<span style="background-color: #FF0000"> </span>
+ FindSourceForAddresses();
+
+ /*
+ * Generate report of ranges not executed
+ */<span style="background-color: #FF0000"> </span>
+ if ( coverageReportFile ) {
+ if ( verbose )
+ fprintf( stderr, "Writing coverage report (%s)\n", coverageReportFile );
+ WriteCoverageReport( coverageReportFile );
+
+ /*
+ * Let the user know how many cases there were
+ */
+ printf( "%d uncovered ranges found\n", UncoveredRanges );
+ }
+
+ /*
+ * Generate report of branches taken/not taken
+ */<span style="background-color: #FF0000"> </span>
+ if ( branchReportFile ) {
+ if ( verbose )
+ fprintf( stderr, "Writing branch report (%s)\n", branchReportFile );
+ WriteBranchReport( branchReportFile, lowAddress, highAddress );
+
+ /*
+ * Let the user know how many branch cases were found
+ */
+ if (!BranchesFound)
+ printf( "No branch information found\n" );
+ else {
+ printf(
+ "%d uncovered branches found\n",
+ BranchesAlwaysTaken + BranchesNeverTaken
+ );
+ printf(
+ " %d branches always taken\n", BranchesAlwaysTaken
+ );
+ printf(
+ " %d branches never taken\n", BranchesNeverTaken
+ );
+ }
+ }
+
+ /*
+ * Simple formatted report of size of ranges<span style="background-color: #FF0000"> </span>
+ */<span style="background-color: #FF0000"> </span>
+ if ( sizeReportFile ) {
+ if ( verbose )
+ fprintf( stderr, "Writing size report (%s)\n", sizeReportFile );
+ WriteSizeReport( sizeReportFile );
+ }
+
+ /*
+ * Generate annotated assembly file
+ */
+ if ( verbose )
+ fprintf( stderr, "Writing annotated report (%s)\n", "annotated.txt" );
+ WriteAnnotatedReport( "annotated.txt", lowAddress, highAddress );
+
+ /*
+ * write explanations that were not found
+ */
+ std::string str = explanations;
+ str = str + ".NotFound";
+ if ( verbose )
+ fprintf( stderr, "Writing Not Found Report (%s)\n", str.c_str() );
+ Explanations->writeNotFound(str.c_str());
+
+ /*
+ * Calculate coverage percentage
+ */
+ {
+ uint32_t a;
+ uint32_t notExecuted = 0;
+ double percentage;
+
+ for ( a=lowAddress ; a < highAddress ; a++ ) {
+ if ( !CoverageMap->wasExecuted( a ) )
+ notExecuted++;
+ }
+
+ percentage = (double) notExecuted;
+ percentage /= (double) (highAddress - lowAddress);
+ percentage *= 100.0;
+ printf( "Bytes Analyzed : %d\n", highAddress - lowAddress );
+ printf( "Bytes Not Executed : %d\n", notExecuted );
+ printf( "Percentage Executed : %5.4g\n", 100.0 - percentage );
+ printf( "Percentage Not Executed : %5.4g\n", percentage );
+ }
+
+ return 0;
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/covoar.cc:1.1
--- /dev/null Mon May 24 15:10:09 2010
+++ gcc-testing/covoar/covoar.cc Mon May 24 15:07:09 2010
</font><font color='#997700'>@@ -0,0 +1,531 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <list>
+#include <netdb.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "app_common.h"
+#include "CoverageFactory.h"
+#include "CoverageMap.h"
+#include "DesiredSymbols.h"
+#include "ExecutableInfo.h"
+#include "Explanations.h"
+#include "ObjdumpProcessor.h"
+#include "ReportsBase.h"
+#include "TargetFactory.h"
+
+/*
+ * Variables to control general behavior
+ */
+const char* coverageFileExtension = NULL;
+std::list<std::string> coverageFileNames;
+int coverageExtensionLength = 0;
+Coverage::CoverageFormats_t coverageFormat;
+Coverage::CoverageReaderBase* coverageReader = NULL;
+char* executable = NULL;
+const char* executableExtension = NULL;
+int executableExtensionLength = 0;
+std::list<Coverage::ExecutableInfo*> executablesToAnalyze;
+const char* explanations = NULL;
+char* progname;
+const char* symbolsFile = NULL;
+const char* target = NULL;
+const char* format = NULL;
+
+/*
+ * Print program usage message
+ */
+void usage()
+{
+ fprintf(
+ stderr,
+ "Usage: %s [-v] -T TARGET -f FORMAT [-E EXPLANATIONS] -1 EXECUTABLE coverage1 ... coverageN\n"
+ "--OR--\n"
+ "Usage: %s [-v] -T TARGET -f FORMAT [-E EXPLANATIONS] -e EXE_EXTENSION -c COVERAGEFILE_EXTENSION EXECUTABLE1 ... EXECUTABLE2\n"
+ "\n"
+ " -v - verbose at initialization\n"
+ " -T TARGET - target name\n"
+ " -f FORMAT - coverage file format "
+ "(RTEMS, QEMU, TSIM or Skyeye)\n"
+ " -E EXPLANATIONS - name of file with explanations\n"
+ " -s SYMBOLS_FILE - name of file with symbols of interest\n"
+ " -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"
+ " -p PROJECT_NAME - name of the project\n"
+ " -C ConfigurationFileName - name of configuration file\n"
+ " -O Output_Directory - name of output directory (default=."
+ "\n",
+ progname,
+ progname
+ );
+}
+
+#define PrintableString(_s) \
+ ((!(_s)) ? "NOT SET" : (_s))
+
+/*
+ * Configuration File Support
+ */
+#include "ConfigFile.h"
+Configuration::FileReader *CoverageConfiguration;
+
+Configuration::Options_t Options[] = {
+ { "explanations", NULL },
+ { "format", NULL },
+ { "symbolsFile", NULL },
+ { "outputDirectory", NULL },
+ { "executableExtension", NULL },
+ { "coverageExtension", NULL },
+ { "target", NULL },
+ { "verbose", NULL },
+ { "projectName", NULL },
+ { NULL, NULL }
+};
+
+bool isTrue(const char *value)
+{
+ if ( !value ) return false;
+ if ( !strcmp(value, "true") ) return true;
+ if ( !strcmp(value, "TRUE") ) return true;
+ if ( !strcmp(value, "yes") ) return true;
+ if ( !strcmp(value, "YES") ) return true;
+ return false;
+}
+
+#define GET_BOOL(_opt, _val) \
+ if (isTrue(CoverageConfiguration->getOption(_opt))) \
+ _val = true;
+
+#define GET_STRING(_opt, _val) \
+ do { \
+ const char *_t; \
+ _t = CoverageConfiguration->getOption(_opt); \
+ if ( _t ) _val = _t; \
+ } while(0)
+<span style="background-color: #FF0000"> </span>
+
+void check_configuration(void)
+{
+ GET_BOOL( "verbose", Verbose );
+
+ GET_STRING( "format", format );
+ GET_STRING( "target", target );
+ GET_STRING( "explanations", explanations );
+ GET_STRING( "symbolsFile", symbolsFile );
+ GET_STRING( "outputDirectory", outputDirectory );
+ GET_STRING( "executableExtension", executableExtension );
+ GET_STRING( "coverageExtension", coverageFileExtension );
+ GET_STRING( "projectName", projectName );
+
+ // Now calculate some values
+ if ( coverageFileExtension )
+ coverageExtensionLength = strlen( coverageFileExtension );
+
+ if ( executableExtension )
+ executableExtensionLength = strlen( executableExtension );
+
+ if ( format )
+ coverageFormat = Coverage::CoverageFormatToEnum( format );
+}
+
+int main(
+ int argc,
+ char** argv
+)
+{
+ std::list<std::string>::iterator citr;
+ std::string coverageFileName;
+ std::list<Coverage::ExecutableInfo*>::iterator eitr;
+ Coverage::ExecutableInfo* executableInfo = NULL;
+ int i;
+ int opt;
+ const char* singleExecutable = NULL;
+
+ CoverageConfiguration = new Configuration::FileReader(Options);
+<span style="background-color: #FF0000"> </span>
+ //
+ // Process command line options.
+ //
+ progname = argv[0];
+
+ while ((opt = getopt(argc, argv, "C:1:L:e:c:E:f:s:T:O:p:v")) != -1) {
+ switch (opt) {
+ case 'C': CoverageConfiguration->processFile( optarg ); break;
+ case '1': singleExecutable = optarg; break;
+ case 'L': dynamicLibrary = optarg; break;
+ case 'e': executableExtension = optarg; break;
+ case 'c': coverageFileExtension = optarg; break;
+ case 'E': explanations = optarg; break;
+ case 'f': format = optarg; break;
+ case 's': symbolsFile = optarg; break;
+ case 'T': target = optarg; break;
+ case 'O': outputDirectory = optarg; break;
+ case 'v': Verbose = true; break;
+ case 'p': projectName = optarg; break;
+ default: /* '?' */
+ usage();
+ exit( -1 );
+ }
+ }
+
+ // Do not trust any arguments until after this point.
+ check_configuration();
+
+ // XXX We need to verify that all of the needed arguments are non-NULL.
+
+ // If a single executable was specified, process the remaining
+ // arguments as coverage file names.
+ if (singleExecutable) {
+
+ // Ensure that the executable is readable.
+ if (!FileIsReadable( singleExecutable )) {
+ fprintf(
+ stderr,
+ "WARNING: Unable to read executable %s\n",
+ singleExecutable
+ );
+ }
+
+ else {
+
+ for (i=optind; i < argc; i++) {
+
+ // Ensure that the coverage file is readable.
+ if (!FileIsReadable( argv[i] )) {
+ fprintf(
+ stderr,
+ "WARNING: Unable to read coverage file %s\n",
+ argv[i]
+ );
+ }
+
+ else
+ coverageFileNames.push_back( argv[i] );
+ }
+
+ // If there was at least one coverage file, create the
+ // executable information.
+ if (!coverageFileNames.empty()) {
+ if (dynamicLibrary)
+ executableInfo = new Coverage::ExecutableInfo(
+ singleExecutable, dynamicLibrary
+ );
+ else
+ executableInfo = new Coverage::ExecutableInfo( singleExecutable );
+
+ executablesToAnalyze.push_back( executableInfo );
+ }
+ }
+ }
+
+ // If not invoked with a single executable, process the remaining
+ // arguments as executables and derive the coverage file names.
+ else {
+ for (i = optind; i < argc; i++) {
+
+ // Ensure that the executable is readable.
+ if (!FileIsReadable( argv[i] )) {
+ fprintf(
+ stderr,
+ "WARNING: Unable to read executable %s\n",
+ argv[i]
+ );
+ }
+
+ else {
+ coverageFileName = argv[i];
+ coverageFileName.replace(
+ coverageFileName.length() - executableExtensionLength,
+ executableExtensionLength,
+ coverageFileExtension
+ );
+
+ if (!FileIsReadable( coverageFileName.c_str() )) {
+ fprintf(
+ stderr,
+ "WARNING: Unable to read coverage file %s\n",
+ coverageFileName.c_str()
+ );
+ }
+
+ else {
+ executableInfo = new Coverage::ExecutableInfo( argv[i] );
+ executablesToAnalyze.push_back( executableInfo );
+ coverageFileNames.push_back( coverageFileName );
+ }
+ }
+ }
+ }
+
+ // Ensure that there is at least one executable to process.
+ if (executablesToAnalyze.empty()) {
+ fprintf(
+ stderr, "ERROR: No information to analyze\n"
+ );
+ exit( -1 );
+ }
+
+ if (Verbose) {
+ if (singleExecutable)
+ fprintf(
+ stderr,
+ "Processing a single executable and multiple coverage files\n"
+ );
+ else
+ fprintf(
+ stderr,
+ "Processing multiple executable/coverage file pairs\n"
+ );
+ fprintf( stderr, "Coverage Format : %s\n", format );
+ fprintf( stderr, "Target : %s\n", PrintableString(target) );
+ fprintf( stderr, "\n" );
+#if 1
+ // Process each executable/coverage file pair.
+ eitr = executablesToAnalyze.begin();
+ for (citr = coverageFileNames.begin();
+ citr != coverageFileNames.end();
+ citr++) {
+
+ fprintf(
+ stderr,
+ "Coverage file %s for executable %s\n",
+ (*citr).c_str(),
+ ((*eitr)->getFileName()).c_str()
+ );
+
+ if (!singleExecutable)
+ eitr++;
+ }
+#endif
+ }
+
+ //
+ // Validate inputs.
+ //
+
+ // Target name must be set.
+ if (!target) {
+ fprintf( stderr, "ERROR: target not specified\n" );
+ usage();
+ exit(-1);
+ }
+
+ // Validate format.
+ if (!format) {
+ fprintf( stderr, "ERROR: coverage format report not specified\n" );
+ usage();
+ exit(-1);
+ }
+
+ // Validate that we have a symbols of interest file.
+ if (!symbolsFile) {
+ fprintf( stderr, "ERROR: symbols of interest file not specified\n" );
+ usage();
+ exit(-1);
+ }
+
+ //
+ // Create data to support analysis.
+ //
+
+ // Create data based on target.
+ TargetInfo = Target::TargetFactory( target );
+
+ // Create the set of desired symbols.
+ SymbolsToAnalyze = new Coverage::DesiredSymbols();
+ SymbolsToAnalyze->load( symbolsFile );
+ if (Verbose)
+ fprintf(
+ stderr, "Analyzing %d symbols\n", SymbolsToAnalyze->set.size()
+ );
+
+ // Create explanations.
+ AllExplanations = new Coverage::Explanations();
+ if ( explanations )
+ AllExplanations->load( explanations );
+
+ // Create coverage map reader.
+ coverageReader = Coverage::CreateCoverageReader(coverageFormat);
+ if (!coverageReader) {
+ fprintf( stderr, "ERROR: Unable to create coverage file reader\n" );
+ exit(-1);
+ }
+
+ // Create the objdump processor.
+ objdumpProcessor = new Coverage::ObjdumpProcessor();
+
+ // Prepare each executable for analysis.
+ for (eitr = executablesToAnalyze.begin();
+ eitr != executablesToAnalyze.end();
+ eitr++) {
+
+ if (Verbose)
+ fprintf(
+ stderr,
+ "Extracting information from %s\n",
+ ((*eitr)->getFileName()).c_str()
+ );
+
+ // If a dynamic library was specified, determine the load address.
+ if (dynamicLibrary)
+ (*eitr)->setLoadAddress(
+ objdumpProcessor->determineLoadAddress( *eitr )
+ );
+
+ // Load the objdump for the symbols in this executable.
+ objdumpProcessor->load( *eitr );
+ }
+
+ //
+ // Analyze the coverage data.
+ //
+
+ // Process each executable/coverage file pair.
+ eitr = executablesToAnalyze.begin();
+ for (citr = coverageFileNames.begin();
+ citr != coverageFileNames.end();
+ citr++) {
+
+ if (Verbose)
+ fprintf(
+ stderr,
+ "Processing coverage file %s for executable %s\n",
+ (*citr).c_str(),
+ ((*eitr)->getFileName()).c_str()
+ );
+
+ // Process its coverage file.
+ coverageReader->processFile( (*citr).c_str(), *eitr );
+
+ // Merge each symbols coverage map into a unified coverage map.
+ (*eitr)->mergeCoverage();
+
+ if (!singleExecutable)
+ eitr++;
+ }
+
+ // Do necessary preprocessing of uncovered ranges and branches
+ if (Verbose)
+ fprintf( stderr, "Preprocess uncovered ranges and branches\n" );
+ SymbolsToAnalyze->preprocess();
+
+ // Determine the uncovered ranges and branches.
+ if (Verbose)
+ fprintf( stderr, "Computing uncovered ranges and branches\n" );
+ SymbolsToAnalyze->computeUncovered();
+
+ // Calculate remainder of statistics.
+ if (Verbose)
+ fprintf( stderr, "Calculate statistics\n" );
+ SymbolsToAnalyze->caculateStatistics();
+
+ // Look up the source lines for any uncovered ranges and branches.
+ if (Verbose)
+ fprintf(
+ stderr, "Looking up source lines for uncovered ranges and branches\n"
+ );
+ SymbolsToAnalyze->findSourceForUncovered();
+
+ //
+ // Report the coverage data.
+ //
+ if (Verbose)
+ fprintf(
+ stderr, "Generate Reports\n"
+ );
+ Coverage::GenerateReports();
+
+ // Write explanations that were not found.
+ if ( explanations ) {
+ std::string notFound;
+
+ notFound = outputDirectory;
+ notFound += "/";
+ notFound += "ExplanationsNotFound.txt";
+
+ if (Verbose)
+ fprintf( stderr, "Writing Not Found Report (%s)\n", notFound.c_str() );
+ AllExplanations->writeNotFound( notFound.c_str() );
+ }
+
+ // Calculate coverage statistics and output results.
+ {
+ uint32_t a;
+ uint32_t endAddress;
+ Coverage::DesiredSymbols::symbolSet_t::iterator itr;
+ uint32_t notExecuted = 0;
+ double percentage;
+ Coverage::CoverageMapBase* theCoverageMap;
+ uint32_t totalBytes = 0;
+
+ // Look at each symbol.
+ for (itr = SymbolsToAnalyze->set.begin();
+ itr != SymbolsToAnalyze->set.end();
+ itr++) {
+
+ // If the symbol's unified coverage map exists, scan through it
+ // and count bytes.
+ theCoverageMap = itr->second.unifiedCoverageMap;
+ if (theCoverageMap) {
+
+ endAddress = itr->second.stats.sizeInBytes - 1;
+
+ for (a = 0; a <= endAddress; a++) {
+ totalBytes++;
+ if (!theCoverageMap->wasExecuted( a ))
+ notExecuted++;
+ }
+ }
+ }
+
+ percentage = (double) notExecuted;
+ percentage /= (double) totalBytes;
+ percentage *= 100.0;
+
+ printf( "Bytes Analyzed : %d\n", totalBytes );
+ printf( "Bytes Not Executed : %d\n", notExecuted );
+ printf( "Percentage Executed : %5.4g\n", 100.0 - percentage );
+ printf( "Percentage Not Executed : %5.4g\n", percentage );
+ printf(
+ "Uncovered ranges found : %d\n",
+ SymbolsToAnalyze->getNumberUncoveredRanges()
+ );
+ if ((SymbolsToAnalyze->getNumberBranchesFound() == 0) ||<span style="background-color: #FF0000"> </span>
+ (BranchInfoAvailable == false) ) {
+ printf( "No branch information available\n" );
+ } else {
+ printf(
+ "Total branches found : %d\n",
+ SymbolsToAnalyze->getNumberBranchesFound()
+ );
+ printf(
+ "Uncovered branches found : %d\n",
+ SymbolsToAnalyze->getNumberBranchesAlwaysTaken() +
+ SymbolsToAnalyze->getNumberBranchesNeverTaken()
+ );
+ printf(
+ " %d branches always taken\n",
+ SymbolsToAnalyze->getNumberBranchesAlwaysTaken()
+ );
+ printf(
+ " %d branches never taken\n",
+ SymbolsToAnalyze->getNumberBranchesNeverTaken()
+ );
+ }
+ }
+
+ return 0;
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/covoar.css:1.1
--- /dev/null Mon May 24 15:10:10 2010
+++ gcc-testing/covoar/covoar.css Mon May 24 15:07:09 2010
</font><font color='#997700'>@@ -0,0 +1,372 @@
</font><font color='#000088'>+body {<span style="background-color: #FF0000"> </span>
+ 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 {<span style="background-color: #FF0000"> </span>
+ color: rgb(180, 50, 50);
+ font-family: helvetica, sans-serif;
+ font-size: 1.0em;
+}
+
+a:visited {<span style="background-color: #FF0000"> </span>
+ color: purple;<span style="background-color: #FF0000"> </span>
+ 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;<span style="background-color: #FF0000"> </span>
+ font-family: helvetica, sans-serif;
+ font-size: 1.0em;
+}
+
+.code {
+ background: rgb(255,255,255);
+ font-family: courier, sans-serif;
+ font-size: 0.9em;
+ font-weight: bold;
+ line-height: 0.9;
+ margin-top: 0.0;
+ margin-bottom: 0.4em;
+ text-align: left;
+ padding-right: 10px;
+}
+
+.codeExecuted {
+ background: rgb(255,255,255);
+ font-family: courier, sans-serif;
+ font-size: 0.9em;
+ line-height: 0.9;
+ margin-top: 0.0;
+ margin-bottom: 0.4em;
+ text-align: left;
+ padding-right: 10px;
+}
+
+.codeNotExecuted {
+ background: rgb(255,255,255);
+ color: red;
+ font-family: courier, sans-serif;
+ font-size: 0.9em;
+ line-height: 0.9;
+ margin-top: 0.0;
+ margin-bottom: 0.4em;
+ text-align: left;
+ padding-right: 10px;
+}
+
+.codeAlwaysTaken {
+ background: rgb(255,255,255);
+ color: green;
+ font-family: courier, sans-serif;
+ font-size: 0.9em;
+ line-height: 0.9;
+ margin-top: 0.0;
+ margin-bottom: 0.4em;
+ text-align: left;
+ padding-right: 10px;
+}
+
+.codeNeverTaken {
+ background: rgb(255,255,255);
+ color: blue;
+ font-family: courier, sans-serif;
+ font-size: 0.9em;
+ line-height: 0.9;
+ margin-top: 0.0;
+ margin-bottom: 0.4em;
+ text-align: left;
+ padding-right: 10px;
+}
+
+.branchesEven {
+ background: rgb(255,255,255);
+ font-family: courier, sans-serif;
+ font-size: 0.9em;
+ line-height: 0.9;
+ margin-top: 0.0;
+ margin-bottom: 0.4em;
+ text-align: left;
+ padding-right: 10px;
+}
+
+.branchesOdd {
+ background: yellow;
+ font-family: courier, sans-serif;
+ font-size: 0.9em;
+ line-height: 0.9;
+ margin-top: 0.0;
+ margin-bottom: 0.4em;
+ text-align: left;
+ padding-right: 10px;
+}
+
+.covoar-table {
+ border-collapse: none;
+ background:black;
+ border:1px solid black;
+}
+
+.covoar-th {
+ text-align: center;
+}
+
+table.covoar {
+ border:1px solid black;
+ border-collapse:collapse;
+}
+table.covoar th, table.covoar td {
+ border:1px solid #aaaaaa;
+ padding: 2px 15px 2px 15px;
+}
+table.covoar thead th {
+ background-color:#A4BC92;
+}
+table.covoar tfoot td {
+ background-color:#A4BC92;
+}
+
+table.covoar tr.tbody_header {
+ font-weight:bold;
+ text-align:center;
+ background-color:#dddddd;
+}
+
+table.covoar a.pagelink {
+ padding-left:5px;
+ padding-right:5px;
+ border:1px solid #666666;
+ margin:0px 5px 0px 5px;
+}
+table.covoar a.currentpage {
+ background-color:yellow;
+}
+
+/* Sorting */
+th.table-sortable {
+ border:1px solid black;
+ color: #F8F8F8;
+ background: #A4BC92;
+ cursor:pointer;
+ background-image:url("05_unsorted.gif");
+ background-position:center left;
+ background-repeat:no-repeat;
+ padding-left:12px;
+}
+th.table-sorted-asc {
+ background-image:url("05_ascending.gif");
+ background-position:center left;
+ background-repeat:no-repeat;
+}
+th.table-sorted-desc {
+ background-image:url("05_descending.gif");
+ background-position:center left;
+ background-repeat:no-repeat;
+}
+th.table-filtered {
+ background-image:url("filter.gif");
+ background-position:center left;
+ background-repeat:no-repeat;
+}
+select.table-autofilter {
+ font-size:smaller;
+}
+
+/* Icons box */
+.iconset {
+ margin:5px;
+ border:1px solid #cccccc;
+ border-color:#cccccc #666666 #666666 #cccccc;
+ text-align:center;
+ cursor:pointer;
+ width:100px;
+}
+.iconset img {
+ margin:3px;
+}
+
+.covoar-tr-first {
+ color: #F8F8F8;
+ background: #A4BC92;
+}
+
+tr.alternate {
+ background: #CBE4B1;
+}
+
+/* Examples which stray from the default */
+table.altstripe tr.alternate2 {
+ background-color:#CBE4B1;
+}
+
+.covoar-tr-odd {
+ background: #CBE4B1;
+}
+
+.covoar-tr-even {
+ background: #DBE5C6;
+}
+
+.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: 3.5em;
+ font-weight: bold;
+ line-height: 0.9;
+ padding-top: 5px;
+ padding-left: 0px;
+ text-align: center;
+ width: 100%;
+}
+
+.datetime {
+ color: rgb(55,55,55);
+ font-size: 1.0em;
+ 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%;
+}
</font>
<font color='#FF0000'>*** DIFF FAILED: ***
</font><font color='#006600'>diff -u /dev/null gcc-testing/covoar/qemu-dump-trace.c:1.1
--- /dev/null Mon May 24 15:10:10 2010
+++ gcc-testing/covoar/qemu-dump-trace.c Mon May 24 15:07:09 2010
</font><font color='#997700'>@@ -0,0 +1,68 @@
</font><font color='#000088'>+
+#include <stdint.h>
+#include <stdio.h>
+
+/* XXX this isn't right */
+typedef uint32_t target_ulong;
+
+#include "qemu-traces.h"
+
+
+int dump_file(
+ const char *name
+)
+{
+ FILE *trace;
+ struct trace_header header;
+ struct trace_entry entry;
+ size_t bytes;
+ int instructions;
+
+ trace = fopen( name, "r" );
+ if ( !trace ) {
+ perror( "unable to open trace file" );
+ return -1;
+ }
+
+ bytes = fread( &header, sizeof(struct trace_header), 1, trace );
+ if ( bytes != 1 ) {
+ fprintf( stderr, "error reading header of %s (%d)\n", name );
+ return -1;
+ }
+ printf( "magic = %s\n", header.magic );
+ printf( "version = %d\n", header.version );
+ printf( "kind = %d\n", header.kind );
+ printf( "sizeof_target_pc = %d\n", header.sizeof_target_pc );
+ printf( "big_endian = %d\n", header.big_endian );
+ printf( "machine = %02x:%02x\n", header.machine[0], header.machine[1] );
+
+ instructions = 0;
+ while (1) {
+ bytes = fread( &entry, sizeof(struct trace_entry), 1, trace );
+ if ( bytes != 1 )
+ break;
+ instructions++;
+ printf( "0x%08x %d 0x%2x\n", entry.pc, entry.size, entry.op );
+ }
+
+<span style="background-color: #FF0000"> </span>
+ fclose( trace );
+ printf( "instructions = %d\n", instructions );
+<span style="background-color: #FF0000"> </span>
+ return 0;
+
+}
+
+int main(
+ int argc,
+ char **argv
+)
+{
+ int i;
+
+ for (i=1 ; i<argc ; i++) {
+ if ( dump_file( argv[i] ) )
+ return -1;
+ }
+ return 0;
+}
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/qemu-log.h:1.1
--- /dev/null Mon May 24 15:10:10 2010
+++ gcc-testing/covoar/qemu-log.h Mon May 24 15:07:09 2010
</font><font color='#997700'>@@ -0,0 +1,27 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+
+/*
+ * Qemu log file format.
+ */
+
+#ifndef QEMU_LOG_H
+#define QEMU_LOG_H
+
+#define QEMU_LOG_SECTION_END "----------------"
+#define QEMU_LOG_IN_KEY "IN: "
+
+/*!
+ * This structure breaks apart the log line information
+ * into the components address, instruction and data.
+ */
+typedef struct {
+ unsigned long address;
+ char instruction[10];
+ char data[20];
+} QEMU_LOG_IN_Block_t;
+
+
+#endif /* QEMU_LOG_H */
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/qemu-traces.h:1.1
--- /dev/null Mon May 24 15:10:10 2010
+++ gcc-testing/covoar/qemu-traces.h Mon May 24 15:07:09 2010
</font><font color='#997700'>@@ -0,0 +1,119 @@
</font><font color='#000088'>+/*
+ * QEMU System Emulator
+ *
+ * Copyright (C) 2009, AdaCore
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/*
+ * Qemu trace file format.
+ * It requires proper definition for uintXX_t where XX is 8, 16, 32 and 64
+ * and target_ulong (32 or 64 bits).
+ */
+
+#ifndef QEMU_TRACE_H
+#define QEMU_TRACE_H
+
+/* XXX really not always right */
+/* XXX Added for covoar so this compiles */
+typedef uint32_t target_ulong;
+
+/* File header definition. */
+struct trace_header
+{
+ char magic[12];
+#define QEMU_TRACE_MAGIC "#QEMU-Traces"
+
+ uint8_t version;
+#define QEMU_TRACE_VERSION 1
+
+ /* File kind. */
+ uint8_t kind;
+#define QEMU_TRACE_KIND_RAW 0
+#define QEMU_TRACE_KIND_HISTORY 1
+#define QEMU_TRACE_KIND_INFO 2
+#define QEMU_TRACE_KIND_DECISION_MAP 3
+#define QEMU_TRACE_KIND_CONSOLIDATED 248
+
+ /* Sizeof (target_pc). Indicates struct trace_entry length. */
+ uint8_t sizeof_target_pc;
+
+ /* True if host was big endian. All the trace data used the host
+ endianness. */
+ uint8_t big_endian;
+
+ /* Target machine (use ELF number) - always in big endian. */
+ uint8_t machine[2];
+
+ uint16_t _pad;
+};
+
+/* Header is followed by trace entries. */
+struct trace_entry
+{
+ target_ulong pc;
+ uint16_t size;
+ uint8_t op;
+};
+
+struct trace_entry32
+{
+ uint32_t pc;
+ uint16_t size;
+ uint8_t op;
+ uint8_t _pad[1];
+};
+
+struct trace_entry64
+{
+ uint64_t pc;
+ uint16_t size;
+ uint8_t op;
+ uint8_t _pad[5];
+};
+
+/*
+ * Trace operations for RAW and HISTORY
+ */
+
+/* _BLOCK means pc .. pc+size-1 was executed. */
+#define TRACE_OP_BLOCK 0x10 /* Block fully executed. */
+#define TRACE_OP_FAULT 0x20 /* Fault at pc. */
+#define TRACE_OP_DYN 0x40 /* Dynamic branch. */
+#define TRACE_OP_BR0 0x01 /* Branch taken "in direction 0". */
+#define TRACE_OP_BR1 0x02 /* Branch taken "in direction 1". */
+#define TRACE_OP_BR2 0x04
+#define TRACE_OP_BR3 0x08
+
+/*
+ * Decision map operations
+ */
+#define TRACE_OP_TRACE_CONDITIONAL 1
+/* Trace conditional jump instruction at address */
+
+extern struct trace_entry *trace_current;
+extern int tracefile_enabled;
+extern int tracefile_nobuf;
+extern int tracefile_history;
+
+void trace_init (const char *optarg);
+void trace_push_entry (void);
+
+#endif /* QEMU_TRACE_H */
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/rtemscov_header.h:1.1
--- /dev/null Mon May 24 15:10:10 2010
+++ gcc-testing/covoar/rtemscov_header.h Mon May 24 15:07:09 2010
</font><font color='#997700'>@@ -0,0 +1,36 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file rtemscov_header.h
+ * @brief rtemscov_header Implementation
+ *
+ * This file contains the implementation of the functions supporting
+ * RTEMS Common Coverage Map file format.
+ *
+ */
+
+#ifndef __RTEMS_Coverage_Header_h
+#define __RTEMS_Coverage_Header_h
+
+#define MAX_DESC_STR 32
+
+/*!
+ *
+ * This structure contains XXX
+ */
+
+typedef struct prof_header_s{
+ /** the version of header file */
+ int ver;
+ /** The length of header */
+ int header_length;
+ /** starting address */
+ int start;
+ /** ending address */
+ int end;
+ /** The description info for profiling file */
+ char desc[MAX_DESC_STR];
+} rtems_coverage_map_header_t;
+
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/skyeye_header.h:1.1
--- /dev/null Mon May 24 15:10:10 2010
+++ gcc-testing/covoar/skyeye_header.h Mon May 24 15:07:09 2010
</font><font color='#997700'>@@ -0,0 +1,25 @@
</font><font color='#000088'>+/*
+ * $Id$
+ */
+
+/*! @file skyeye_header.h
+ * @brief skyeye_header Implementation
+ *
+ * This file contains the definition of the format
+ * for coverage files written by the Skyeye simulator.
+ */
+
+#ifndef __Skyeye_Header_h
+#define __Skyeye_Header_h
+
+#define MAX_DESC_STR 32
+
+typedef struct prof_header_s {
+ int ver; /** the version of header file */
+ int header_length; /** The length of header */
+ int prof_start;
+ int prof_end;
+ char desc[MAX_DESC_STR]; /** The description info for profiling file */
+} prof_header_t;
+
+#endif
</font>
<font color='#006600'>diff -u /dev/null gcc-testing/covoar/table.js:1.1
--- /dev/null Mon May 24 15:10:10 2010
+++ gcc-testing/covoar/table.js Mon May 24 15:07:09 2010
</font><font color='#997700'>@@ -0,0 +1,1002 @@
</font><font color='#000088'>+/**
+ * Copyright (c)2005-2009 Matt Kruse (javascripttoolbox.com)
+ *<span style="background-color: #FF0000"> </span>
+ * Dual licensed under the MIT and GPL licenses.<span style="background-color: #FF0000"> </span>
+ * This basically means you can use this code however you want for
+ * free, but don't claim to have written it yourself!
+ * Donations always accepted: http://www.JavascriptToolbox.com/donate/
+ *<span style="background-color: #FF0000"> </span>
+ * Please do not link to the .js files on javascripttoolbox.com from
+ * your site. Copy the files locally to your server instead.
+ *<span style="background-color: #FF0000"> </span>
+ */
+/**
+ * Table.js
+ * Functions for interactive Tables
+ *
+ * Copyright (c) 2007 Matt Kruse (javascripttoolbox.com)
+ * Dual licensed under the MIT and GPL licenses.<span style="background-color: #FF0000"> </span>
+ *
+ * @version 0.981
+ *
+ * @history 0.981 2007-03-19 Added Sort.numeric_comma, additional date parsing formats
+ * @history 0.980 2007-03-18 Release new BETA release pending some testing. Todo: Additional docs, examples, plus jQuery plugin.
+ * @history 0.959 2007-03-05 Added more "auto" functionality, couple bug fixes
+ * @history 0.958 2007-02-28 Added auto functionality based on class names
+ * @history 0.957 2007-02-21 Speed increases, more code cleanup, added Auto Sort functionality
+ * @history 0.956 2007-02-16 Cleaned up the code and added Auto Filter functionality.
+ * @history 0.950 2006-11-15 First BETA release.
+ *
+ * @todo Add more date format parsers
+ * @todo Add style classes to colgroup tags after sorting/filtering in case the user wants to highlight the whole column
+ * @todo Correct for colspans in data rows (this may slow it down)
+ * @todo Fix for IE losing form control values after sort?
+ */
+
+/**
+ * Sort Functions
+ */
+var Sort = (function(){
+ var sort = {};
+ // Default alpha-numeric sort
+ // --------------------------
+ sort.alphanumeric = function(a,b) {
+ return (a==b)?0:(a<b)?-1:1;
+ };
+ sort['default'] = sort.alphanumeric; // IE chokes on sort.default
+
+ // This conversion is generalized to work for either a decimal separator of , or .
+ sort.numeric_converter = function(separator) {
+ return function(val) {
+ if (typeof(val)=="string") {
+ val = parseFloat(val.replace(/^[^\d\.]*([\d., ]+).*/g,"$1").replace(new RegExp("[^\\\d"+separator+"]","g"),'').replace(/,/,'.')) || 0;
+ }
+ return val || 0;
+ };
+ };
+
+ // Numeric Sort<span style="background-color: #FF0000"> </span>
+ // ------------
+ sort.numeric = function(a,b) {
+ return sort.numeric.convert(a)-sort.numeric.convert(b);
+ };
+ sort.numeric.convert = sort.numeric_converter(".");
+
+ // Numeric Sort - comma decimal separator
+ // --------------------------------------
+ sort.numeric_comma = function(a,b) {
+ return sort.numeric_comma.convert(a)-sort.numeric_comma.convert(b);
+ };
+ sort.numeric_comma.convert = sort.numeric_converter(",");
+
+ // Case-insensitive Sort
+ // ---------------------
+ sort.ignorecase = function(a,b) {
+ return sort.alphanumeric(sort.ignorecase.convert(a),sort.ignorecase.convert(b));
+ };
+ sort.ignorecase.convert = function(val) {
+ if (val==null) { return ""; }
+ return (""+val).toLowerCase();
+ };
+
+ // Currency Sort
+ // -------------
+ sort.currency = sort.numeric; // Just treat it as numeric!
+ sort.currency_comma = sort.numeric_comma;
+
+ // Date sort
+ // ---------
+ sort.date = function(a,b) {
+ return sort.numeric(sort.date.convert(a),sort.date.convert(b));
+ };
+ // Convert 2-digit years to 4
+ sort.date.fixYear=function(yr) {
+ yr = +yr;
+ if (yr<50) { yr += 2000; }
+ else if (yr<100) { yr += 1900; }
+ return yr;
+ };
+ sort.date.formats = [
+ // YY[YY]-MM-DD
+ { re:/(\d{2,4})-(\d{1,2})-(\d{1,2})/ , f:function(x){ return (new Date(sort.date.fixYear(x[1]),+x[2],+x[3])).getTime(); } }
+ // MM/DD/YY[YY] or MM-DD-YY[YY]
+ ,{ re:/(\d{1,2})[\/-](\d{1,2})[\/-](\d{2,4})/ , f:function(x){ return (new Date(sort.date.fixYear(x[3]),+x[1],+x[2])).getTime(); } }
+ // Any catch-all format that new Date() can handle. This is not reliable except for long formats, for example: 31 Jan 2000 01:23:45 GMT
+ ,{ re:/(.*\d{4}.*\d+:\d+\d+.*)/, f:function(x){ var d=new Date(x[1]); if(d){return d.getTime();} } }
+ ];
+ sort.date.convert = function(val) {
+ var m,v, f = sort.date.formats;
+ for (var i=0,L=f.length; i<L; i++) {
+ if (m=val.match(f[i].re)) {
+ v=f[i].f(m);
+ if (typeof(v)!="undefined") { return v; }
+ }
+ }
+ return 9999999999999; // So non-parsed dates will be last, not first
+ };
+
+ return sort;
+})();
+
+/**
+ * The main Table namespace
+ */
+var Table = (function(){
+
+ /**
+ * Determine if a reference is defined
+ */
+ function def(o) {return (typeof o!="undefined");};
+
+ /**
+ * Determine if an object or class string contains a given class.
+ */
+ function hasClass(o,name) {
+ return new RegExp("(^|\\s)"+name+"(\\s|$)").test(o.className);
+ };
+
+ /**
+ * Add a class to an object
+ */
+ function addClass(o,name) {
+ var c = o.className || "";
+ if (def(c) && !hasClass(o,name)) {
+ o.className += (c?" ":"") + name;
+ }
+ };
+
+ /**
+ * Remove a class from an object
+ */
+ function removeClass(o,name) {
+ var c = o.className || "";
+ o.className = c.replace(new RegExp("(^|\\s)"+name+"(\\s|$)"),"$1");
+ };
+
+ /**
+ * For classes that match a given substring, return the rest
+ */
+ function classValue(o,prefix) {
+ var c = o.className;
+ if (c.match(new RegExp("(^|\\s)"+prefix+"([^ ]+)"))) {
+ return RegExp.$2;
+ }
+ return null;
+ };
+
+ /**
+ * Return true if an object is hidden.
+ * This uses the "russian doll" technique to unwrap itself to the most efficient
+ * function after the first pass. This avoids repeated feature detection that<span style="background-color: #FF0000"> </span>
+ * would always fall into the same block of code.
+ */
+ function isHidden(o) {
+ if (window.getComputedStyle) {
+ var cs = window.getComputedStyle;
+ return (isHidden = function(o) {
+ return 'none'==cs(o,null).getPropertyValue('display');
+ })(o);
+ }
+ else if (window.currentStyle) {
+ return(isHidden = function(o) {
+ return 'none'==o.currentStyle['display'];
+ })(o);
+ }
+ return (isHidden = function(o) {
+ return 'none'==o.style['display'];
+ })(o);
+ };
+
+ /**
+ * Get a parent element by tag name, or the original element if it is of the tag type
+ */
+ function getParent(o,a,b) {
+ if (o!=null && o.nodeName) {
+ if (o.nodeName==a || (b && o.nodeName==b)) {
+ return o;
+ }
+ while (o=o.parentNode) {
+ if (o.nodeName && (o.nodeName==a || (b && o.nodeName==b))) {
+ return o;
+ }
+ }
+ }
+ return null;
+ };
+
+ /**
+ * Utility function to copy properties from one object to another
+ */
+ function copy(o1,o2) {
+ for (var i=2;i<arguments.length; i++) {
+ var a = arguments[i];
+ if (def(o1[a])) {
+ o2[a] = o1[a];
+ }
+ }
+ }
+
+ // The table object itself
+ var table = {
+ //Class names used in the code
+ AutoStripeClassName:"table-autostripe",
+ StripeClassNamePrefix:"table-stripeclass:",
+
+ AutoSortClassName:"table-autosort",
+ AutoSortColumnPrefix:"table-autosort:",
+ AutoSortTitle:"Click to sort",
+ SortedAscendingClassName:"table-sorted-asc",
+ SortedDescendingClassName:"table-sorted-desc",
+ SortableClassName:"table-sortable",
+ SortableColumnPrefix:"table-sortable:",
+ NoSortClassName:"table-nosort",
+
+ AutoFilterClassName:"table-autofilter",
+ FilteredClassName:"table-filtered",
+ FilterableClassName:"table-filterable",
+ FilteredRowcountPrefix:"table-filtered-rowcount:",
+ RowcountPrefix:"table-rowcount:",
+ FilterAllLabel:"Filter: All",
+
+ AutoPageSizePrefix:"table-autopage:",
+ AutoPageJumpPrefix:"table-page:",
+ PageNumberPrefix:"table-page-number:",
+ PageCountPrefix:"table-page-count:"
+ };
+
+ /**
+ * A place to store misc table information, rather than in the table objects themselves
+ */
+ table.tabledata = {};
+
+ /**
+ * Resolve a table given an element reference, and make sure it has a unique ID
+ */
+ table.uniqueId=1;
+ table.resolve = function(o,args) {
+ if (o!=null && o.nodeName && o.nodeName!="TABLE") {
+ o = getParent(o,"TABLE");
+ }
+ if (o==null) { return null; }
+ if (!o.id) {
+ var id = null;
+ do { var id = "TABLE_"+(table.uniqueId++); }<span style="background-color: #FF0000"> </span>
+ while (document.getElementById(id)!=null);
+ o.id = id;
+ }
+ this.tabledata[o.id] = this.tabledata[o.id] || {};
+ if (args) {
+ copy(args,this.tabledata[o.id],"stripeclass","ignorehiddenrows","useinnertext","sorttype","col","desc","page","pagesize");
+ }
+ return o;
+ };
+
+
+ /**
+ * Run a function against each cell in a table header or footer, usually<span style="background-color: #FF0000"> </span>
+ * to add or remove css classes based on sorting, filtering, etc.
+ */
+ table.processTableCells = function(t, type, func, arg) {
+ t = this.resolve(t);
+ if (t==null) { return; }
+ if (type!="TFOOT") {
+ this.processCells(t.tHead, func, arg);
+ }
+ if (type!="THEAD") {
+ this.processCells(t.tFoot, func, arg);
+ }
+ };
+
+ /**
+ * Internal method used to process an arbitrary collection of cells.
+ * Referenced by processTableCells.
+ * It's done this way to avoid getElementsByTagName() which would also return nested table cells.
+ */
+ table.processCells = function(section,func,arg) {
+ if (section!=null) {
+ if (section.rows && section.rows.length && section.rows.length>0) {<span style="background-color: #FF0000"> </span>
+ var rows = section.rows;
+ for (var j=0,L2=rows.length; j<L2; j++) {<span style="background-color: #FF0000"> </span>
+ var row = rows[j];
+ if (row.cells && row.cells.length && row.cells.length>0) {
+ var cells = row.cells;
+ for (var k=0,L3=cells.length; k<L3; k++) {
+ var cellsK = cells[k];
+ func.call(this,cellsK,arg);
+ }
+ }
+ }
+ }
+ }
+ };
+
+ /**
+ * Get the cellIndex value for a cell. This is only needed because of a Safari
+ * bug that causes cellIndex to exist but always be 0.
+ * Rather than feature-detecting each time it is called, the function will
+ * re-write itself the first time it is called.
+ */
+ table.getCellIndex = function(td) {
+ var tr = td.parentNode;
+ var cells = tr.cells;
+ if (cells && cells.length) {
+ if (cells.length>1 && cells[cells.length-1].cellIndex>0) {
+ // Define the new function, overwrite the one we're running now, and then run the new one
+ (this.getCellIndex = function(td) {
+ return td.cellIndex;
+ })(td);
+ }
+ // Safari will always go through this slower block every time. Oh well.
+ for (var i=0,L=cells.length; i<L; i++) {
+ if (tr.cells[i]==td) {
+ return i;
+ }
+ }
+ }
+ return 0;
+ };
+
+ /**
+ * A map of node names and how to convert them into their "value" for sorting, filtering, etc.
+ * These are put here so it is extensible.
+ */
+ table.nodeValue = {
+ 'INPUT':function(node) {<span style="background-color: #FF0000"> </span>
+ if (def(node.value) && node.type && ((node.type!="checkbox" && node.type!="radio") || node.checked)) {
+ return node.value;
+ }
+ return "";
+ },
+ 'SELECT':function(node) {
+ if (node.selectedIndex>=0 && node.options) {
+ // Sort select elements by the visible text
+ return node.options[node.selectedIndex].text;
+ }
+ return "";
+ },
+ 'IMG':function(node) {
+ return node.name || "";
+ }
+ };
+
+ /**
+ * Get the text value of a cell. Only use innerText if explicitly told to, because<span style="background-color: #FF0000"> </span>
+ * otherwise we want to be able to handle sorting on inputs and other types
+ */
+ table.getCellValue = function(td,useInnerText) {
+ if (useInnerText && def(td.innerText)) {
+ return td.innerText;
+ }
+ if (!td.childNodes) {<span style="background-color: #FF0000"> </span>
+ return "";<span style="background-color: #FF0000"> </span>
+ }
+ var childNodes=td.childNodes;
+ var ret = "";
+ for (var i=0,L=childNodes.length; i<L; i++) {
+ var node = childNodes[i];
+ var type = node.nodeType;
+ // In order to get realistic sort results, we need to treat some elements in a special way.
+ // These behaviors are defined in the nodeValue() object, keyed by node name
+ if (type==1) {
+ var nname = node.nodeName;
+ if (this.nodeValue[nname]) {
+ ret += this.nodeValue[nname](node);
+ }
+ else {
+ ret += this.getCellValue(node);
+ }
+ }
+ else if (type==3) {
+ if (def(node.innerText)) {
+ ret += node.innerText;
+ }
+ else if (def(node.nodeValue)) {
+ ret += node.nodeValue;
+ }
+ }
+ }
+ return ret;
+ };
+
+ /**
+ * Consider colspan and rowspan values in table header cells to calculate the actual cellIndex
+ * of a given cell. This is necessary because if the first cell in row 0 has a rowspan of 2,<span style="background-color: #FF0000"> </span>
+ * then the first cell in row 1 will have a cellIndex of 0 rather than 1, even though it really
+ * starts in the second column rather than the first.
+ * See: http://www.javascripttoolbox.com/temp/table_cellindex.html
+ */
+ table.tableHeaderIndexes = {};
+ table.getActualCellIndex = function(tableCellObj) {
+ if (!def(tableCellObj.cellIndex)) { return null; }
+ var tableObj = getParent(tableCellObj,"TABLE");
+ var cellCoordinates = tableCellObj.parentNode.rowIndex+"-"+this.getCellIndex(tableCellObj);
+
+ // If it has already been computed, return the answer from the lookup table
+ if (def(this.tableHeaderIndexes[tableObj.id])) {
+ return this.tableHeaderIndexes[tableObj.id][cellCoordinates];<span style="background-color: #FF0000"> </span>
+ }<span style="background-color: #FF0000"> </span>
+
+ var matrix = [];
+ this.tableHeaderIndexes[tableObj.id] = {};
+ var thead = getParent(tableCellObj,"THEAD");
+ var trs = thead.getElementsByTagName('TR');
+
+ // Loop thru every tr and every cell in the tr, building up a 2-d array "grid" that gets
+ // populated with an "x" for each space that a cell takes up. If the first cell is colspan
+ // 2, it will fill in values [0] and [1] in the first array, so that the second cell will
+ // find the first empty cell in the first row (which will be [2]) and know that this is
+ // where it sits, rather than its internal .cellIndex value of [1].
+ for (var i=0; i<trs.length; i++) {
+ var cells = trs[i].cells;
+ for (var j=0; j<cells.length; j++) {
+ var c = cells[j];
+ var rowIndex = c.parentNode.rowIndex;
+ var cellId = rowIndex+"-"+this.getCellIndex(c);
+ var rowSpan = c.rowSpan || 1;
+ var colSpan = c.colSpan || 1;
+ var firstAvailCol;
+ if(!def(matrix[rowIndex])) {<span style="background-color: #FF0000"> </span>
+ matrix[rowIndex] = [];<span style="background-color: #FF0000"> </span>
+ }
+ var m = matrix[rowIndex];
+ // Find first available column in the first row
+ for (var k=0; k<m.length+1; k++) {
+ if (!def(m[k])) {
+ firstAvailCol = k;
+ break;
+ }
+ }
+ this.tableHeaderIndexes[tableObj.id][cellId] = firstAvailCol;
+ for (var k=rowIndex; k<rowIndex+rowSpan; k++) {
+ if(!def(matrix[k])) {<span style="background-color: #FF0000"> </span>
+ matrix[k] = [];<span style="background-color: #FF0000"> </span>
+ }
+ var matrixrow = matrix[k];
+ for (var l=firstAvailCol; l<firstAvailCol+colSpan; l++) {
+ matrixrow[l] = "x";
+ }
+ }
+ }
+ }
+ // Store the map so future lookups are fast.
+ return this.tableHeaderIndexes[tableObj.id][cellCoordinates];
+ };
+
+ /**
+ * Sort all rows in each TBODY (tbodies are sorted independent of each other)
+ */
+ table.sort = function(o,args) {
+ var t, tdata, sortconvert=null;
+ // Allow for a simple passing of sort type as second parameter
+ if (typeof(args)=="function") {
+ args={sorttype:args};
+ }
+ args = args || {};
+
+ // If no col is specified, deduce it from the object sent in
+ if (!def(args.col)) {<span style="background-color: #FF0000"> </span>
+ args.col = this.getActualCellIndex(o) || 0;<span style="background-color: #FF0000"> </span>
+ }
+ // If no sort type is specified, default to the default sort
+ args.sorttype = args.sorttype || Sort['default'];
+
+ // Resolve the table
+ t = this.resolve(o,args);
+ tdata = this.tabledata[t.id];
+
+ // If we are sorting on the same column as last time, flip the sort direction
+ if (def(tdata.lastcol) && tdata.lastcol==tdata.col && def(tdata.lastdesc)) {
+ tdata.desc = !tdata.lastdesc;
+ }
+ else {
+ tdata.desc = !!args.desc;
+ }
+
+ // Store the last sorted column so clicking again will reverse the sort order
+ tdata.lastcol=tdata.col;
+ tdata.lastdesc=!!tdata.desc;
+
+ // If a sort conversion function exists, pre-convert cell values and then use a plain alphanumeric sort
+ var sorttype = tdata.sorttype;
+ if (typeof(sorttype.convert)=="function") {
+ sortconvert=tdata.sorttype.convert;
+ sorttype=Sort.alphanumeric;
+ }
+
+ // Loop through all THEADs and remove sorted class names, then re-add them for the col
+ // that is being sorted
+ this.processTableCells(t,"THEAD",
+ function(cell) {
+ if (hasClass(cell,this.SortableClassName)) {
+ removeClass(cell,this.SortedAscendingClassName);
+ removeClass(cell,this.SortedDescendingClassName);
+ // If the computed colIndex of the cell equals the sorted colIndex, flag it as sorted
+ if (tdata.col==table.getActualCellIndex(cell) && (classValue(cell,table.SortableClassName))) {
+ addClass(cell,tdata.desc?this.SortedAscendingClassName:this.SortedDescendingClassName);
+ }
+ }
+ }
+ );
+
+ // Sort each tbody independently
+ var bodies = t.tBodies;
+ if (bodies==null || bodies.length==0) { return; }
+
+ // Define a new sort function to be called to consider descending or not
+ var newSortFunc = (tdata.desc)?
+ function(a,b){return sorttype(b[0],a[0]);}
+ :function(a,b){return sorttype(a[0],b[0]);};
+
+ var useinnertext=!!tdata.useinnertext;
+ var col = tdata.col;
+
+ for (var i=0,L=bodies.length; i<L; i++) {
+ var tb = bodies[i], tbrows = tb.rows, rows = [];
+
+ // Allow tbodies to request that they not be sorted
+ if(!hasClass(tb,table.NoSortClassName)) {
+ // Create a separate array which will store the converted values and refs to the
+ // actual rows. This is the array that will be sorted.
+ var cRow, cRowIndex=0;
+ if (cRow=tbrows[cRowIndex]){
+ // Funky loop style because it's considerably faster in IE
+ do {
+ if (rowCells = cRow.cells) {
+ var cellValue = (col<rowCells.length)?this.getCellValue(rowCells[col],useinnertext):null;
+ if (sortconvert) cellValue = sortconvert(cellValue);
+ rows[cRowIndex] = [cellValue,tbrows[cRowIndex]];
+ }
+ } while (cRow=tbrows[++cRowIndex])
+ }
+
+ // Do the actual sorting
+ rows.sort(newSortFunc);
+
+ // Move the rows to the correctly sorted order. Appending an existing DOM object just moves it!
+ cRowIndex=0;
+ var displayedCount=0;
+ var f=[removeClass,addClass];
+ if (cRow=rows[cRowIndex]){
+ do {<span style="background-color: #FF0000"> </span>
+ tb.appendChild(cRow[1]);<span style="background-color: #FF0000"> </span>
+ } while (cRow=rows[++cRowIndex])
+ }
+ }
+ }
+
+ // If paging is enabled on the table, then we need to re-page because the order of rows has changed!
+ if (tdata.pagesize) {
+ this.page(t); // This will internally do the striping
+ }
+ else {
+ // Re-stripe if a class name was supplied
+ if (tdata.stripeclass) {
+ this.stripe(t,tdata.stripeclass,!!tdata.ignorehiddenrows);
+ }
+ }
+ };
+
+ /**
+ * Apply a filter to rows in a table and hide those that do not match.
+ */
+ table.filter = function(o,filters,args) {
+ var cell;
+ args = args || {};
+
+ var t = this.resolve(o,args);
+ var tdata = this.tabledata[t.id];
+
+ // If new filters were passed in, apply them to the table's list of filters
+ if (!filters) {
+ // If a null or blank value was sent in for 'filters' then that means reset the table to no filters
+ tdata.filters = null;
+ }
+ else {
+ // Allow for passing a select list in as the filter, since this is common design
+ if (filters.nodeName=="SELECT" && filters.type=="select-one" && filters.selectedIndex>-1) {
+ filters={ 'filter':filters.options[filters.selectedIndex].value };
+ }
+ // Also allow for a regular input
+ if (filters.nodeName=="INPUT" && filters.type=="text") {
+ filters={ 'filter':"/^"+filters.value+"/" };
+ }
+ // Force filters to be an array
+ if (typeof(filters)=="object" && !filters.length) {
+ filters = [filters];
+ }
+
+ // Convert regular expression strings to RegExp objects and function strings to function objects
+ for (var i=0,L=filters.length; i<L; i++) {
+ var filter = filters[i];
+ if (typeof(filter.filter)=="string") {
+ // If a filter string is like "/expr/" then turn it into a Regex
+ if (filter.filter.match(/^\/(.*)\/$/)) {
+ filter.filter = new RegExp(RegExp.$1);
+ filter.filter.regex=true;
+ }
+ // If filter string is like "function (x) { ... }" then turn it into a function
+ else if (filter.filter.match(/^function\s*\(([^\)]*)\)\s*\{(.*)}\s*$/)) {
+ filter.filter = Function(RegExp.$1,RegExp.$2);
+ }
+ }
+ // If some non-table object was passed in rather than a 'col' value, resolve it<span style="background-color: #FF0000"> </span>
+ // and assign it's column index to the filter if it doesn't have one. This way,<span style="background-color: #FF0000"> </span>
+ // passing in a cell reference or a select object etc instead of a table object<span style="background-color: #FF0000"> </span>
+ // will automatically set the correct column to filter.
+ if (filter && !def(filter.col) && (cell=getParent(o,"TD","TH"))) {
+ filter.col = this.getCellIndex(cell);
+ }
+
+ // Apply the passed-in filters to the existing list of filters for the table, removing those that have a filter of null or ""
+ if ((!filter || !filter.filter) && tdata.filters) {
+ delete tdata.filters[filter.col];
+ }
+ else {
+ tdata.filters = tdata.filters || {};
+ tdata.filters[filter.col] = filter.filter;
+ }
+ }
+ // If no more filters are left, then make sure to empty out the filters object
+ for (var j in tdata.filters) { var keep = true; }
+ if (!keep) {
+ tdata.filters = null;
+ }
+ }<span style="background-color: #FF0000"> </span>
+ // Everything's been setup, so now scrape the table rows
+ return table.scrape(o);
+ };
+
+ /**
+ * "Page" a table by showing only a subset of the rows
+ */
+ table.page = function(t,page,args) {
+ args = args || {};
+ if (def(page)) { args.page = page; }
+ return table.scrape(t,args);
+ };
+
+ /**
+ * Jump forward or back any number of pages
+ */
+ table.pageJump = function(t,count,args) {
+ t = this.resolve(t,args);
+ return this.page(t,(table.tabledata[t.id].page||0)+count,args);
+ };
+
+ /**
+ * Go to the next page of a paged table
+ */<span style="background-color: #FF0000"> </span>
+ table.pageNext = function(t,args) {
+ return this.pageJump(t,1,args);
+ };
+
+ /**
+ * Go to the previous page of a paged table
+ */<span style="background-color: #FF0000"> </span>
+ table.pagePrevious = function(t,args) {
+ return this.pageJump(t,-1,args);
+ };
+
+ /**
+ * Scrape a table to either hide or show each row based on filters and paging
+ */
+ table.scrape = function(o,args) {
+ var col,cell,filterList,filterReset=false,filter;
+ var page,pagesize,pagestart,pageend;
+ var unfilteredrows=[],unfilteredrowcount=0,totalrows=0;
+ var t,tdata,row,hideRow;
+ args = args || {};
+
+ // Resolve the table object
+ t = this.resolve(o,args);
+ tdata = this.tabledata[t.id];
+
+ // Setup for Paging
+ var page = tdata.page;
+ if (def(page)) {
+ // Don't let the page go before the beginning
+ if (page<0) { tdata.page=page=0; }
+ pagesize = tdata.pagesize || 25; // 25=arbitrary default
+ pagestart = page*pagesize+1;
+ pageend = pagestart + pagesize - 1;
+ }
+
+ // Scrape each row of each tbody
+ var bodies = t.tBodies;
+ if (bodies==null || bodies.length==0) { return; }
+ for (var i=0,L=bodies.length; i<L; i++) {
+ var tb = bodies[i];
+ for (var j=0,L2=tb.rows.length; j<L2; j++) {
+ row = tb.rows[j];
+ hideRow = false;
+
+ // Test if filters will hide the row
+ if (tdata.filters && row.cells) {
+ var cells = row.cells;
+ var cellsLength = cells.length;
+ // Test each filter
+ for (col in tdata.filters) {
+ if (!hideRow) {
+ filter = tdata.filters[col];
+ if (filter && col<cellsLength) {
+ var val = this.getCellValue(cells[col]);
+ if (filter.regex && val.search) {
+ hideRow=(val.search(filter)<0);
+ }
+ else if (typeof(filter)=="function") {
+ hideRow=!filter(val,cells[col]);
+ }
+ else {
+ hideRow = (val!=filter);
+ }
+ }
+ }
+ }
+ }
+
+ // Keep track of the total rows scanned and the total runs _not_ filtered out
+ totalrows++;
+ if (!hideRow) {
+ unfilteredrowcount++;
+ if (def(page)) {
+ // Temporarily keep an array of unfiltered rows in case the page we're on goes past
+ // the last page and we need to back up. Don't want to filter again!
+ unfilteredrows.push(row);
+ if (unfilteredrowcount<pagestart || unfilteredrowcount>pageend) {
+ hideRow = true;
+ }
+ }
+ }
+
+ row.style.display = hideRow?"none":"";
+ }
+ }
+
+ if (def(page)) {
+ // Check to see if filtering has put us past the requested page index. If it has,<span style="background-color: #FF0000"> </span>
+ // then go back to the last page and show it.
+ if (pagestart>=unfilteredrowcount) {
+ pagestart = unfilteredrowcount-(unfilteredrowcount%pagesize);
+ tdata.page = page = pagestart/pagesize;
+ for (var i=pagestart,L=unfilteredrows.length; i<L; i++) {
+ unfilteredrows[i].style.display="";
+ }
+ }
+ }
+
+ // Loop through all THEADs and add/remove filtered class names
+ this.processTableCells(t,"THEAD",
+ function(c) {
+ ((tdata.filters && def(tdata.filters[table.getCellIndex(c)]) && hasClass(c,table.FilterableClassName))?addClass:removeClass)(c,table.FilteredClassName);
+ }
+ );
+
+ // Stripe the table if necessary
+ if (tdata.stripeclass) {
+ this.stripe(t);
+ }
+
+ // Calculate some values to be returned for info and updating purposes
+ var pagecount = Math.floor(unfilteredrowcount/pagesize)+1;
+ if (def(page)) {
+ // Update the page number/total containers if they exist
+ if (tdata.container_number) {
+ tdata.container_number.innerHTML = page+1;
+ }
+ if (tdata.container_count) {
+ tdata.container_count.innerHTML = pagecount;
+ }
+ }
+
+ // Update the row count containers if they exist
+ if (tdata.container_filtered_count) {
+ tdata.container_filtered_count.innerHTML = unfilteredrowcount;
+ }
+ if (tdata.container_all_count) {
+ tdata.container_all_count.innerHTML = totalrows;
+ }
+ return { 'data':tdata, 'unfilteredcount':unfilteredrowcount, 'total':totalrows, 'pagecount':pagecount, 'page':page, 'pagesize':pagesize };
+ };
+
+ /**
+ * Shade alternate rows, aka Stripe the table.
+ */
+ table.stripe = function(t,className,args) {<span style="background-color: #FF0000"> </span>
+ args = args || {};
+ args.stripeclass = className;
+
+ t = this.resolve(t,args);
+ var tdata = this.tabledata[t.id];
+
+ var bodies = t.tBodies;
+ if (bodies==null || bodies.length==0) {<span style="background-color: #FF0000"> </span>
+ return;<span style="background-color: #FF0000"> </span>
+ }
+
+ className = tdata.stripeclass;
+ // Cache a shorter, quicker reference to either the remove or add class methods
+ var f=[removeClass,addClass];
+ for (var i=0,L=bodies.length; i<L; i++) {
+ var tb = bodies[i], tbrows = tb.rows, cRowIndex=0, cRow, displayedCount=0;
+ if (cRow=tbrows[cRowIndex]){
+ // The ignorehiddenrows test is pulled out of the loop for a slight speed increase.
+ // Makes a bigger difference in FF than in IE.
+ // In this case, speed always wins over brevity!
+ if (tdata.ignoreHiddenRows) {
+ do {
+ f[displayedCount++%2](cRow,className);
+ } while (cRow=tbrows[++cRowIndex])
+ }
+ else {
+ do {
+ if (!isHidden(cRow)) {
+ f[displayedCount++%2](cRow,className);
+ }
+ } while (cRow=tbrows[++cRowIndex])
+ }
+ }
+ }
+ };
+
+ /**
+ * Build up a list of unique values in a table column
+ */
+ table.getUniqueColValues = function(t,col) {
+ var values={}, bodies = this.resolve(t).tBodies;
+ for (var i=0,L=bodies.length; i<L; i++) {
+ var tbody = bodies[i];
+ for (var r=0,L2=tbody.rows.length; r<L2; r++) {
+ values[this.getCellValue(tbody.rows[r].cells[col])] = true;
+ }
+ }
+ var valArray = [];
+ for (var val in values) {
+ valArray.push(val);
+ }
+ return valArray.sort();
+ };
+
+ /**
+ * Scan the document on load and add sorting, filtering, paging etc ability automatically
+ * based on existence of class names on the table and cells.
+ */
+ table.auto = function(args) {
+ var cells = [], tables = document.getElementsByTagName("TABLE");
+ var val,tdata;
+ if (tables!=null) {
+ for (var i=0,L=tables.length; i<L; i++) {
+ var t = table.resolve(tables[i]);
+ tdata = table.tabledata[t.id];
+ if (val=classValue(t,table.StripeClassNamePrefix)) {
+ tdata.stripeclass=val;
+ }
+ // Do auto-filter if necessary
+ if (hasClass(t,table.AutoFilterClassName)) {
+ table.autofilter(t);
+ }
+ // Do auto-page if necessary
+ if (val = classValue(t,table.AutoPageSizePrefix)) {
+ table.autopage(t,{'pagesize':+val});
+ }
+ // Do auto-sort if necessary
+ if ((val = classValue(t,table.AutoSortColumnPrefix)) || (hasClass(t,table.AutoSortClassName))) {
+ table.autosort(t,{'col':(val==null)?null:+val});
+ }
+ // Do auto-stripe if necessary
+ if (tdata.stripeclass && hasClass(t,table.AutoStripeClassName)) {
+ table.stripe(t);
+ }
+ }
+ }
+ };
+
+ /**
+ * Add sorting functionality to a table header cell
+ */
+ table.autosort = function(t,args) {
+ t = this.resolve(t,args);
+ var tdata = this.tabledata[t.id];
+ this.processTableCells(t, "THEAD", function(c) {
+ var type = classValue(c,table.SortableColumnPrefix);
+ if (type!=null) {
+ type = type || "default";
+ c.title =c.title || table.AutoSortTitle;
+ addClass(c,table.SortableClassName);
+ c.onclick = Function("","Table.sort(this,{'sorttype':Sort['"+type+"']})");
+ // If we are going to auto sort on a column, we need to keep track of what kind of sort it will be
+ if (args.col!=null) {
+ if (args.col==table.getActualCellIndex(c)) {
+ tdata.sorttype=Sort['"+type+"'];
+ }
+ }
+ }
+ } );
+ if (args.col!=null) {
+ table.sort(t,args);
+ }
+ };
+
+ /**
+ * Add paging functionality to a table<span style="background-color: #FF0000"> </span>
+ */
+ table.autopage = function(t,args) {
+ t = this.resolve(t,args);
+ var tdata = this.tabledata[t.id];
+ if (tdata.pagesize) {
+ this.processTableCells(t, "THEAD,TFOOT", function(c) {
+ var type = classValue(c,table.AutoPageJumpPrefix);
+ if (type=="next") { type = 1; }
+ else if (type=="previous") { type = -1; }
+ if (type!=null) {
+ c.onclick = Function("","Table.pageJump(this,"+type+")");
+ }
+ } );
+ if (val = classValue(t,table.PageNumberPrefix)) {
+ tdata.container_number = document.getElementById(val);
+ }
+ if (val = classValue(t,table.PageCountPrefix)) {
+ tdata.container_count = document.getElementById(val);
+ }
+ return table.page(t,0,args);
+ }
+ };
+
+ /**
+ * A util function to cancel bubbling of clicks on filter dropdowns
+ */
+ table.cancelBubble = function(e) {
+ e = e || window.event;
+ if (typeof(e.stopPropagation)=="function") { e.stopPropagation(); }<span style="background-color: #FF0000"> </span>
+ if (def(e.cancelBubble)) { e.cancelBubble = true; }
+ };
+
+ /**
+ * Auto-filter a table
+ */
+ table.autofilter = function(t,args) {
+ args = args || {};
+ t = this.resolve(t,args);
+ var tdata = this.tabledata[t.id],val;
+ table.processTableCells(t, "THEAD", function(cell) {
+ if (hasClass(cell,table.FilterableClassName)) {
+ var cellIndex = table.getCellIndex(cell);
+ var colValues = table.getUniqueColValues(t,cellIndex);
+ if (colValues.length>0) {
+ if (typeof(args.insert)=="function") {
+ func.insert(cell,colValues);
+ }
+ else {
+ var sel = '<select onchange="Table.filter(this,this)" onclick="Table.cancelBubble(event)" class="'+table.AutoFilterClassName+'"><option value="">'+table.FilterAllLabel+'</option>';
+ for (var i=0; i<colValues.length; i++) {
+ sel += '<option value="'+colValues[i]+'">'+colValues[i]+'</option>';
+ }
+ sel += '</select>';
+ cell.innerHTML += "<br>"+sel;
+ }
+ }
+ }
+ });
+ if (val = classValue(t,table.FilteredRowcountPrefix)) {
+ tdata.container_filtered_count = document.getElementById(val);
+ }
+ if (val = classValue(t,table.RowcountPrefix)) {
+ tdata.container_all_count = document.getElementById(val);
+ }
+ };
+
+ /**
+ * Attach the auto event so it happens on load.
+ * use jQuery's ready() function if available
+ */
+ if (typeof(jQuery)!="undefined") {
+ jQuery(table.auto);
+ }
+ else if (window.addEventListener) {
+ window.addEventListener( "load", table.auto, false );
+ }
+ else if (window.attachEvent) {
+ window.attachEvent( "onload", table.auto );
+ }
+
+ return table;
+})();
</font></pre>
<p> </p>
<p>--<br />
<small>Generated by <a href="http://www.codewiz.org/projects/index.html#loginfo">Deluxe Loginfo</a> 2.122 by Bernardo Innocenti <bernie@develer.com></small></p>
</body>
</html>