change log for gcc-testing (2010-05-24)

rtems-vc at rtems.org rtems-vc at rtems.org
Mon May 24 20:10:11 UTC 2010


 *jennifer*:
2010-05-24	Jennifer Averett <Jennifer.Averett at OARcorp.com>

	* VERSIONS-COVERAGE, do_coverage: Created covoar directory with source
	that will be moved from rtems-coverage.

M  1.273  rtems-coverage/ChangeLog
M   1.22  rtems-coverage/VERSIONS-COVERAGE
M   1.64  rtems-coverage/do_coverage

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
@@ -1,3 +1,8 @@
+2010-05-24	Jennifer Averett <Jennifer.Averett at OARcorp.com>
+
+	* VERSIONS-COVERAGE, do_coverage: Created covoar directory with source
+	that will be moved from rtems-coverage.
+
 2010-05-24	Jennifer Averett <Jennifer,.Averett at OARcorp.com>
 
 	* ReportsHtml.cc: Added link to size report. Added a filterable File

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
@@ -39,20 +39,9 @@
 # for publishing results
 FTPDIR=/home/ftp/pub/rtems/people/joel/coverage/
 
-
-# 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
-
 # Calculated
 SCRIPTDIR=${BASEDIR}/gcc-testing
 COVBASE=${SCRIPTDIR}/rtems-coverage
+COVOARBASE=${SCRIPTDIR}/covoar
 
 

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
@@ -406,7 +406,7 @@
     sort -n -r >${results_dir}/sizes_all.txt
 
   # Now create the archive of information
-  cp ${COVBASE}/covoar.css ${COVBASE}/*gif ${COVBASE}/table.js ${results_dir}
+  cp ${COVOARBASE}/covoar.css ${COVOARBASE}/*gif ${COVOARBASE}/table.js ${results_dir}
   echo "Results saved in ${results_dir}.tar.bz2"
   tar cjf ${results_dir}.tar.bz2 ${results_dir}
 }


 *jennifer*:
2010-05-24	Jennifer Averett <Jennifer.Averett at 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.

M   1.56  ChangeLog
A    1.1  covoar/05_ascending.gif
A    1.1  covoar/05_descending.gif
A    1.1  covoar/05_unsorted.gif
A    1.1  covoar/ConfigFile.h
A    1.1  covoar/ConfigFile.cc
A    1.1  covoar/CoverageFactory.h
A    1.1  covoar/CoverageFactory.cc
A    1.1  covoar/CoverageMap.h
A    1.1  covoar/CoverageMap.cc
A    1.1  covoar/CoverageMapBase.h
A    1.1  covoar/CoverageMapBase.cc
A    1.1  covoar/CoverageRanges.h
A    1.1  covoar/CoverageRanges.cc
A    1.1  covoar/CoverageReaderBase.h
A    1.1  covoar/CoverageReaderBase.cc
A    1.1  covoar/CoverageReaderQEMU.h
A    1.1  covoar/CoverageReaderQEMU.cc
A    1.1  covoar/CoverageReaderRTEMS.h
A    1.1  covoar/CoverageReaderRTEMS.cc
A    1.1  covoar/CoverageReaderSkyeye.h
A    1.1  covoar/CoverageReaderSkyeye.cc
A    1.1  covoar/CoverageReaderTSIM.h
A    1.1  covoar/CoverageReaderTSIM.cc
A    1.1  covoar/CoverageWriterBase.h
A    1.1  covoar/CoverageWriterBase.cc
A    1.1  covoar/CoverageWriterRTEMS.h
A    1.1  covoar/CoverageWriterRTEMS.cc
A    1.1  covoar/CoverageWriterSkyeye.h
A    1.1  covoar/CoverageWriterSkyeye.cc
A    1.1  covoar/CoverageWriterTSIM.h
A    1.1  covoar/CoverageWriterTSIM.cc
A    1.1  covoar/DesiredSymbols.h
A    1.1  covoar/DesiredSymbols.cc
A    1.1  covoar/ExecutableInfo.h
A    1.1  covoar/ExecutableInfo.cc
A    1.1  covoar/Explanations.h
A    1.1  covoar/Explanations.cc
A    1.1  covoar/Makefile
A    1.1  covoar/ObjdumpProcessor.h
A    1.1  covoar/ObjdumpProcessor.cc
A    1.1  covoar/ReportsBase.h
A    1.1  covoar/ReportsBase.cc
A    1.1  covoar/ReportsHtml.h
A    1.1  covoar/ReportsHtml.cc
A    1.1  covoar/ReportsText.h
A    1.1  covoar/ReportsText.cc
A    1.1  covoar/SymbolTable.h
A    1.1  covoar/SymbolTable.cc
A    1.1  covoar/TargetBase.h
A    1.1  covoar/TargetBase.cc
A    1.1  covoar/TargetFactory.h
A    1.1  covoar/TargetFactory.cc
A    1.1  covoar/Target_arm.h
A    1.1  covoar/Target_arm.cc
A    1.1  covoar/Target_i386.h
A    1.1  covoar/Target_i386.cc
A    1.1  covoar/Target_lm32.h
A    1.1  covoar/Target_lm32.cc
A    1.1  covoar/Target_m68k.h
A    1.1  covoar/Target_m68k.cc
A    1.1  covoar/Target_powerpc.h
A    1.1  covoar/Target_powerpc.cc
A    1.1  covoar/Target_sparc.h
A    1.1  covoar/Target_sparc.cc
A    1.1  covoar/TraceConverter.cc
A    1.1  covoar/TraceList.h
A    1.1  covoar/TraceList.cc
A    1.1  covoar/TraceReaderBase.h
A    1.1  covoar/TraceReaderBase.cc
A    1.1  covoar/TraceReaderLogQEMU.h
A    1.1  covoar/TraceReaderLogQEMU.cc
A    1.1  covoar/TraceWriterBase.h
A    1.1  covoar/TraceWriterBase.cc
A    1.1  covoar/TraceWriterQEMU.h
A    1.1  covoar/TraceWriterQEMU.cc
A    1.1  covoar/app_common.h
A    1.1  covoar/app_common.cc
A    1.1  covoar/configfile_test.cc
A    1.1  covoar/coverage_converter.cc
A    1.1  covoar/covmerge.cc
A    1.1  covoar/covoar.cc
A    1.1  covoar/covoar.css
A    1.1  covoar/filter.gif
A    1.1  covoar/qemu-dump-trace.c
A    1.1  covoar/qemu-log.h
A    1.1  covoar/qemu-traces.h
A    1.1  covoar/rtemscov_header.h
A    1.1  covoar/skyeye_header.h
A    1.1  covoar/table.js

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
@@ -1,3 +1,44 @@
+2010-05-24	Jennifer Averett <Jennifer.Averett at 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.
+
 2010-03-25	Joel Sherrill <joel.sherrill at oarcorp.com>
 
 	* VERSIONS: Update.

*** DIFF FAILED:  ***
*** DIFF FAILED:  ***
*** DIFF FAILED:  ***
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
@@ -0,0 +1,90 @@
+/*
+ *   $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 {
+
+  /*!
+   *  
+   *  This structure contains the configuration parameter
+   *  name and value pair.
+   */ 
+  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:
+
+    /*! 
+     *  This method constructs a FileReader instance.
+     *
+     *  @param[in] options is the set of options
+     */
+    FileReader(
+      Options_t *options
+    );
+
+    /*! 
+     *  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

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
@@ -0,0 +1,200 @@
+/*
+ *   $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') 
+        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'; 
+      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 );
+    }
+  }
+}

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
@@ -0,0 +1,68 @@
+/*
+ *  $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

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
@@ -0,0 +1,85 @@
+/*
+ *  $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;
+}

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
@@ -0,0 +1,44 @@
+/*
+ *  $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. 
+   */
+  class CoverageMap : public CoverageMapBase {
+
+  public:
+
+    /*! 
+     *  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

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
@@ -0,0 +1,27 @@
+/*
+ *  $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()
+  {
+  }
+
+}

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
@@ -0,0 +1,248 @@
+/*
+ *  $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:
+
+    /*! 
+     *  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
+    );
+
+    /*! 
+     *  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.
+     *  
+     *  @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
+     *  
+     *  @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

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
@@ -0,0 +1,202 @@
+
+/*
+ *  $Id$
+ */
+
+/*! @file CoverageMapBase.cc
+ *  @brief CoverageMapBase Implementation
+ *
+ *  This file contains the implementation of the functions 
+ *  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);
+  }
+}

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
@@ -0,0 +1,133 @@
+/*
+ *  $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 
+       *  coverage range.
+       */
+      uint32_t          id;
+
+      /*!
+       *  This member contains the low address of this coverage 
+       *  range.
+       */
+      uint32_t          lowAddress;
+
+      /*!
+       *  This member contains the source line associated with the 
+       *  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 
+       * 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;
+
+    /*! 
+     *  This method constructs a CoverageRanges instance.
+     */
+    CoverageRanges();
+
+    /*! 
+     *  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
+    );
+ 
+
+    /*!
+     *  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 );
+ 
+    protected:
+
+
+  };
+
+}
+#endif

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
@@ -0,0 +1,65 @@
+/*
+ *  $Id$
+ */
+
+/*! @file CoverageRanges.cc
+ *  @brief CoverageRanges Implementation
+ *
+ *  This file contains the implementation of the functions 
+ *  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;
+  }
+
+}

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
@@ -0,0 +1,52 @@
+/*
+ *  $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:
+
+    /*! 
+     *  This method constructs a CoverageReaderBase instance.
+     */
+    CoverageReaderBase();
+
+    /*! 
+     *  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

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
@@ -0,0 +1,23 @@
+/*
+ *  $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()
+  {
+  }
+}

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
@@ -0,0 +1,50 @@
+/*
+ *  $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.
+ at verbatim
+TBD
+ at 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

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
@@ -0,0 +1,158 @@
+/*
+ *  $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( 
+        entries, 
+        sizeof(struct trace_entry), 
+        ENTRIES, 
+        traceFile 
+      );
+      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];
+      
+        // 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 );
+  }
+}

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
@@ -0,0 +1,48 @@
+/*
+ *  $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.
+ at verbatim
+TBD
+ at 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

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
@@ -0,0 +1,112 @@
+/*
+ *  $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;
+    
+    #if 0
+    fprintf( 
+      stderr,
+      "%s: 0x%08x 0x%08x 0x%08lx/%ld\n", 
+      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 );
+  }
+}

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
@@ -0,0 +1,48 @@
+/*
+ *  $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.
+ at verbatim
+TBD
+ at 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

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
@@ -0,0 +1,130 @@
+/*
+ *  $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;
+    
+    #if 0
+    fprintf( 
+      stderr,
+      "%s: 0x%08x 0x%08x 0x%08lx/%ld\n", 
+      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 );
+  }
+}

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
@@ -0,0 +1,49 @@
+/*
+ *  $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.
+ at 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 
+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 
+ at 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

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
@@ -0,0 +1,96 @@
+/*
+ *  $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 );
+  }
+}

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
@@ -0,0 +1,61 @@
+/*
+ *  $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:
+
+    /*! 
+     *  This method constructs a CoverageWriterBase instance.
+     */
+    CoverageWriterBase();
+
+    /*! 
+     *  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

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
@@ -0,0 +1,24 @@
+/*
+ *  $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()
+  {
+  }
+
+}

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
@@ -0,0 +1,48 @@
+/*
+ *  $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 
+   *  documented in CoverageReaderRTEMS.
+   */
+  class CoverageWriterRTEMS : public CoverageWriterBase {
+
+  public:
+
+    /*! 
+     *  This method constructs a CoverageWriterRTEMS instance.
+     */
+    CoverageWriterRTEMS();
+
+    /*! 
+     *  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

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
@@ -0,0 +1,92 @@
+/*
+ *  $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 {
+  
+  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 );
+  }
+}

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
@@ -0,0 +1,48 @@
+/*
+ *  $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 
+   *  documented in CoverageReaderSkyeye.
+   */
+  class CoverageWriterSkyeye : public CoverageWriterBase {
+
+  public:
+
+    /*! 
+     *  This method constructs a CoverageWriterSkyeye instance.
+     */
+    CoverageWriterSkyeye();
+
+    /*! 
+     *  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

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
@@ -0,0 +1,94 @@
+/*
+ *  $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 {
+  
+  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 );
+  }
+}

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
@@ -0,0 +1,48 @@
+/*
+ *  $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 
+   *  documented in CoverageReaderTSIM.
+   */
+  class CoverageWriterTSIM : public CoverageWriterBase {
+
+  public:
+
+    /*! 
+     *  This method constructs a CoverageWriterTSIM instance.
+     */
+    CoverageWriterTSIM();
+
+    /*! 
+     *  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

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
@@ -0,0 +1,82 @@
+/*
+ *  $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 {
+  
+  CoverageWriterTSIM::CoverageWriterTSIM()
+  {
+  }
+
+  CoverageWriterTSIM::~CoverageWriterTSIM()
+  {
+  }
+
+  
+  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" );
+  
+    }
+
+    fclose( coverageFile );
+  }
+}

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
@@ -0,0 +1,340 @@
+/*
+ *  $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 {
+
+
+  /*! 
+   * 
+   *  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 
+     *  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;
+    
+    /*!
+     *  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.
+     */   
+     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.
+     */    
+    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 
+     *  symbol in the system keyed on the symbol name.
+     */
+    symbolSet_t set;
+
+    /*! 
+     *  This method constructs a DesiredSymbols instance.
+     */
+    DesiredSymbols();
+
+    /*! 
+     *  This method destructs a DesiredSymbols instance.
+     */
+    ~DesiredSymbols();
+
+    /*!
+     *  This method loops through the coverage map and
+     *  calculates the statistics that have not already 
+     *  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.
+     */    
+    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

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
@@ -0,0 +1,656 @@
+/*
+ *  $Id$
+ */
+
+/*! @file DesiredSymbols.cc
+ *  @brief DesiredSymbols Implementation
+ *
+ *  This file contains the implementation of the functions 
+ *  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 { 
+        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. 
+        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++;
+          }
+ 
+        }
+
+ 
+        if (!theCoverageMap->wasExecuted( a )) {
+          stats.uncoveredBytes++;
+          sitr->second.stats.uncoveredBytes++;
+        }       
+        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) {
+        
+        // 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, 
+          "Warning: Unable to find symbol %s\n", 
+          symbolName.c_str() 
+        );
+      #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 );
+    }
+  }
+
+}

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
@@ -0,0 +1,162 @@
+/*
+ *  $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 
+     */
+    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

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
@@ -0,0 +1,127 @@
+/*
+ * $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;
+  }
+
+}

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
@@ -0,0 +1,123 @@
+/*
+ *  $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;
+
+    /*! 
+     *  This method constructs an Explanations instance.
+     */
+    Explanations();
+
+    /*! 
+     *  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
+     */  
+    void writeNotFound(
+      const char* const fileName
+    );
+
+  };
+
+}
+
+#endif

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
@@ -0,0 +1,195 @@
+/*
+ *  $Id$
+ */
+
+/*! @file Explanations.cc
+ *  @brief Explanations Implementation
+ *
+ *  This file contains the implementation of the functions 
+ *  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 
+      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 
+      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, 
+          "Warning: Unable to find explanation for %s\n", 
+          start.c_str() 
+        );
+      #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;
+   
+    notFoundFile = fopen( fileName, "w" );
+    if (!fileName) {
+      fprintf(
+        stderr,
+        "ERROR: Explanations::writeNotFound - unable to open file %s\n",
+        fileName
+      );
+      exit( -1 );
+    }
+    
+    for (std::map<std::string, Explanation>::iterator itr = set.begin();
+         itr != set.end();
+         itr++) {
+      Explanation e = (*itr).second;
+      std::string key = (*itr).first;
+ 
+      if (!e.found) {
+        notFoundOccurred = true;
+        fprintf(
+          notFoundFile,
+          "%s\n",
+          e.startingPoint.c_str()
+        );
+      } 
+    }
+    fclose( notFoundFile );
+
+    if (!notFoundOccurred) {
+      if (!unlink( fileName )) {
+        fprintf( stderr, 
+          "Warning: Unable to unlink %s\n\n", 
+          fileName 
+        );
+      }
+    } 
+  }
+
+}

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
@@ -0,0 +1,154 @@
+#
+# $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 
+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

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
@@ -0,0 +1,169 @@
+/*
+ *  $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;
+
+   
+    /*!
+     *  This object defines a list of instruction addresses
+     *  that will be extracted from the objdump file.
+     */ 
+    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.  
+     */
+    FILE* getFile( std::string fileName ); 
+
+    /*!
+     *  This method fills the objdumpList list with all the 
+     *  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 
+     *  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

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
@@ -0,0 +1,587 @@
+/*
+ *  $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. 
+ */
+
+#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; 
+        break;
+      }
+    }
+
+    fclose( loadAddressFile );
+    return address;
+#endif
+    #undef METHOD
+  }
+
+  bool ObjdumpProcessor::IsBranch(
+    const char *instruction 
+  )
+  { 
+    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 ) 
+  {
+    char               dumpFile[128];
+    FILE*              objdumpFile;
+    char               buffer[ 512 ];
+    int                status;
+
+    sprintf( dumpFile, "%s.dmp", fileName.c_str() );
+      
+    // 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 );
+      }
+    } 
+
+    // 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;
+    }
+    
+    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 );
+      }
+    }
+  }
+}

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
@@ -0,0 +1,374 @@
+/*
+ *   $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 
+ *   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 
+     *  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
+    );
+    
+    /*!
+     *  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. 
+     *
+     *  @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  
+     *  @param[in] id identifies the branch or range id.
+     */
+    virtual void PutAnnotatedLine( 
+      FILE*                aFile, 
+      AnnotatedLineState_t state, 
+      std::string          line,
+      uint32_t             id 
+    )=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. 
+     *
+     *  @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 
+     *  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

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
@@ -0,0 +1,497 @@
+/*
+ *   $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";           
+          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;
+      
+      PutAnnotatedLine( aFile, state, line, id); 
+    }
+  }
+
+  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) || 
+      (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) || 
+      (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
+) 
+{
+  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;
+
+ 
+  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;
+  }
+  
+}
+
+}

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
@@ -0,0 +1,209 @@
+/*
+ *   $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 
+     *  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. */ 
+    virtual FILE* OpenAnnotatedFile(
+      const char* const fileName
+    );
+
+    /* Inherit documentation from base class. */ 
+    virtual FILE* OpenBranchFile(
+      const char* const fileName,
+      bool              hasBranches
+    );
+
+    /* Inherit documentation from base class. */ 
+    virtual FILE* OpenCoverageFile(
+      const char* const fileName
+    );
+
+    /* Inherit documentation from base class. */ 
+    FILE* OpenNoRangeFile(
+      const char* const fileName
+    );
+
+    /* Inherit documentation from base class. */ 
+    virtual FILE* OpenSizeFile(
+      const char* const fileName
+    );
+
+    /* Inherit documentation from base class. */ 
+    virtual FILE* OpenSymbolSummaryFile(
+      const char* const fileName
+    );
+
+    /* Inherit documentation from base class. */ 
+    virtual void CloseAnnotatedFile(
+      FILE*  aFile
+    );
+
+    /* Inherit documentation from base class. */ 
+    virtual void CloseBranchFile(
+      FILE*  aFile,
+      bool   hasBranches
+    );
+
+    /* Inherit documentation from base class. */ 
+    virtual void CloseCoverageFile(
+      FILE*  aFile
+    );
+
+    /* Inherit documentation from base class. */ 
+    void CloseNoRangeFile(
+      FILE*  aFile
+    );
+
+    /* Inherit documentation from base class. */ 
+    virtual void CloseSizeFile(
+      FILE*  aFile
+    );
+
+    /* Inherit documentation from base class. */ 
+    virtual void CloseSymbolSummaryFile(
+      FILE*  aFile
+    );
+
+    /* Inherit documentation from base class. */ 
+    virtual void PutAnnotatedLine( 
+      FILE*                aFile, 
+      AnnotatedLineState_t state, 
+      std::string          line, 
+      uint32_t             id 
+    );
+
+    /* Inherit documentation from base class. */ 
+    virtual bool PutNoBranchInfo(
+      FILE* report
+    );
+
+    /* Inherit documentation from base class. */ 
+    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. */ 
+    virtual void putCoverageNoRange(
+      FILE*        report,
+      FILE*        noRangeFile,
+      unsigned int number,
+      std::string  symbol
+    );
+
+    /* Inherit documentation from base class. */ 
+    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. */ 
+    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. */ 
+    virtual bool PutSymbolSummaryLine(
+      FILE*                                           report,
+      unsigned int                                    number,
+      Coverage::DesiredSymbols::symbolSet_t::iterator symbol
+    );
+
+    /* Inherit documentation from base class. */ 
+    virtual FILE* OpenFile(
+      const char* const fileName
+    );
+
+    /* Inherit documentation from base class. */ 
+    virtual bool WriteExplationFile(
+      const char*                  fileName,
+      const Coverage::Explanation* explanation
+    );
+  };
+
+}
+
+#endif

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
@@ -0,0 +1,1024 @@
+/*
+ *   $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 
+#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;
+    
+    // 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(&timestamp_m) ) 
+    );
+
+    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;
+    
+    // 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(&timestamp_m) ) 
+    );
+
+    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(&timestamp_m) ) 
+      );
+    }
+   
+    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(&timestamp_m) ) 
+
+     );
+
+    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(&timestamp_m) ) 
+
+     );
+
+    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(&timestamp_m) ) 
+
+    );
+    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(&timestamp_m) ) 
+
+    );
+    return aFile;
+  }
+
+  void ReportsHtml::PutAnnotatedLine( 
+    FILE*                aFile, 
+    AnnotatedLineState_t state, 
+    std::string          line, 
+    uint32_t             id 
+  )
+  {
+    std::string stateText;
+    char        number[10];
+
+    
+    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( 
+      report, 
+      "<td class=\"covoar-td\" align=\"center\">%s</td>\n",     
+      symbolPtr->first.c_str()
+    );
+
+    // line
+    fprintf( 
+      report, 
+      "<td class=\"covoar-td\" align=\"center\"><a href =\"annotated.html#range%d\">%s</td>\n",     
+      rangePtr->id,
+      rangePtr->lowSourceLine.c_str()
+    );
+
+    // File
+    i = rangePtr->lowSourceLine.find(":");
+    temp =  rangePtr->lowSourceLine.substr (0, i);
+    fprintf( 
+      report, 
+      "<td class=\"covoar-td\" align=\"center\">%s</td>\n",     
+      temp.c_str()
+    );
+  
+    // Size in bytes
+    fprintf( 
+      report, 
+      "<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( 
+        report,
+        "<td class=\"covoar-td\" align=\"center\">Always Taken</td>\n"
+      );
+    else if (rangePtr->reason ==
+      Coverage::CoverageRanges::UNCOVERED_REASON_BRANCH_NEVER_TAKEN)
+      fprintf( 
+        report, 
+        "<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( 
+        report, 
+        "<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( 
+        report, 
+        "<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( 
+      report, 
+      "<td class=\"covoar-td\" align=\"center\">%s</td>\n",     
+      symbol.c_str()
+    );
+    fprintf( 
+      noRangeFile, 
+      "<td class=\"covoar-td\" align=\"center\">%s</td>\n",     
+      symbol.c_str()
+    );
+
+    // starting line
+    fprintf( 
+      report, 
+      "<td class=\"covoar-td\" align=\"center\">unknown</td>\n"
+     );
+     
+    // file
+    fprintf( 
+      report, 
+      "<td class=\"covoar-td\" align=\"center\">unknown</td>\n"
+     );
+     
+     // Size in bytes
+    fprintf( 
+      report, 
+      "<td class=\"covoar-td\" align=\"center\">unknown</td>\n"
+    );
+
+    // Size in instructions
+    fprintf( 
+      report, 
+      "<td class=\"covoar-td\" align=\"center\">unknown</td>\n"
+    ); 
+
+    // See if an explanation is available
+    fprintf( 
+      report, 
+      "<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( 
+      report, 
+      "<td class=\"covoar-td\" align=\"center\">%s</td>\n",     
+      symbolPtr->first.c_str()
+    );
+
+    // Range
+    fprintf( 
+      report, 
+      "<td class=\"covoar-td\" align=\"center\"><a href =\"annotated.html#range%d\">%s </br>%s</td>\n",
+      rangePtr->id,    
+      rangePtr->lowSourceLine.c_str(),
+      rangePtr->highSourceLine.c_str()
+     );
+
+    // File
+    i = rangePtr->lowSourceLine.find(":");
+    temp =  rangePtr->lowSourceLine.substr (0, i);
+    fprintf( 
+      report, 
+      "<td class=\"covoar-td\" align=\"center\">%s</td>\n",     
+      temp.c_str()
+    );
+       
+    // Size in bytes
+    fprintf( 
+      report, 
+      "<td class=\"covoar-td\" align=\"center\">%d</td>\n",
+      rangePtr->highAddress - rangePtr->lowAddress + 1
+    );
+
+    // Size in instructions
+    fprintf( 
+      report, 
+      "<td class=\"covoar-td\" align=\"center\">%d</td>\n",
+      rangePtr->instructionCount
+    ); 
+
+    // See if an explanation is available
+    explanation = AllExplanations->lookupExplanation( rangePtr->lowSourceLine );
+    if ( !explanation ) {
+      fprintf( 
+        report, 
+        "<td class=\"covoar-td\" align=\"center\">NONE</td>\n"
+      );
+      fprintf( 
+        report, 
+        "<td class=\"covoar-td\" align=\"center\">No Explanation</td>\n"
+      );
+    } else {
+      char explanationFile[48];
+
+      sprintf( explanationFile, "explanation%d.html", rangePtr->id );
+      fprintf( 
+        report, 
+        "<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( 
+      report, 
+      "<td class=\"covoar-td\" align=\"center\">%d</td>\n",
+      range->highAddress - range->lowAddress + 1
+    );
+
+    // symbol
+    fprintf( 
+      report, 
+      "<td class=\"covoar-td\" align=\"center\">%s</td>\n",     
+      symbol->first.c_str()
+    );
+
+    // line
+    fprintf( 
+      report, 
+      "<td class=\"covoar-td\" align=\"center\"><a href =\"annotated.html#range%d\">%s</td>\n",     
+      range->id,
+      range->lowSourceLine.c_str()
+    );
+
+    // File
+    i = range->lowSourceLine.find(":");
+    temp =  range->lowSourceLine.substr (0, i);
+    fprintf( 
+      report, 
+      "<td class=\"covoar-td\" align=\"center\">%s</td>\n",     
+      temp.c_str()
+    );
+    
+    fprintf( report, "</tr>\n");
+
+    return true;
+  }
+
+  bool  ReportsHtml::PutSymbolSummaryLine(
+    FILE*                                           report,
+    unsigned int                                    count,
+    Coverage::DesiredSymbols::symbolSet_t::iterator symbol
+  )
+  {
+ 
+    // 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( 
+      report, 
+      "<td class=\"covoar-td\" align=\"center\">%s</td>\n",     
+      symbol->first.c_str()
+    );
+
+    // Total Size in Bytes
+    fprintf( 
+      report, 
+      "<td class=\"covoar-td\" align=\"center\">%d</td>\n",
+      symbol->second.stats.sizeInBytes
+    );
+
+    // Total Size in Instructions 
+    fprintf( 
+      report, 
+      "<td class=\"covoar-td\" align=\"center\">%d</td>\n",
+      symbol->second.stats.sizeInInstructions
+    );
+
+    // Total Uncovered Ranges
+    fprintf( 
+      report, 
+      "<td class=\"covoar-td\" align=\"center\">%d</td>\n",     
+      symbol->second.stats.uncoveredRanges
+    );
+
+    // Uncovered Size in Bytes
+    fprintf( 
+      report, 
+      "<td class=\"covoar-td\" align=\"center\">%d</td>\n",
+      symbol->second.stats.uncoveredBytes
+    );
+
+    // Uncovered Size in Instructions 
+    fprintf( 
+      report, 
+      "<td class=\"covoar-td\" align=\"center\">%d</td>\n",
+       symbol->second.stats.uncoveredInstructions
+    );
+
+    // Total number of branches
+    fprintf( 
+      report, 
+      "<td class=\"covoar-td\" align=\"center\">%d</td>\n",     
+      symbol->second.stats.branchesNotExecuted +  symbol->second.stats.branchesExecuted
+    );
+
+    // Total Always Taken
+    fprintf( 
+      report, 
+      "<td class=\"covoar-td\" align=\"center\">%d</td>\n",
+      symbol->second.stats.branchesAlwaysTaken
+    );
+
+    // Total Never Taken
+    fprintf( 
+      report, 
+      "<td class=\"covoar-td\" align=\"center\">%d</td>\n",
+      symbol->second.stats.branchesNeverTaken
+     );
+
+    // % Uncovered Instructions
+    if ( symbol->second.stats.sizeInInstructions == 0 )
+      fprintf( 
+        report, 
+        "<td class=\"covoar-td\" align=\"center\">100.00</td>\n"
+      );
+    else     
+      fprintf( 
+        report, 
+        "<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( 
+        report, 
+        "<td class=\"covoar-td\" align=\"center\">100.00</td>\n"
+      );
+    else     
+      fprintf( 
+        report, 
+        "<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" 
+      );
+    }
+    fprintf(
+      aFile,
+      "</pre>\n" 
+      "</body>\n"
+      "</html>"
+    );
+
+    CloseFile(aFile);
+  }
+
+  void ReportsHtml::CloseCoverageFile(
+    FILE*  aFile
+  )
+  {
+    fprintf(
+      aFile,
+      TABLE_FOOTER
+      "</tbody>\n"
+      "</table>\n" 
+      "</pre>\n" 
+      "</body>\n"
+      "</html>"
+    );
+
+    CloseFile(aFile);
+  }
+
+  void ReportsHtml::CloseNoRangeFile(
+    FILE*  aFile
+  )
+  {
+    fprintf(
+      aFile,
+      TABLE_FOOTER
+      "</tbody>\n"
+      "</table>\n" 
+      "</pre>\n" 
+      "</body>\n"
+      "</html>"
+    );
+
+    CloseFile(aFile);
+  }
+
+
+  void ReportsHtml::CloseSizeFile(
+    FILE*  aFile
+  )
+  {
+    fprintf(
+      aFile,
+      TABLE_FOOTER
+      "</tbody>\n"
+      "</table>\n" 
+      "</pre>\n" 
+      "</body>\n"
+      "</html>"
+    );
+
+    CloseFile( aFile );
+  }
+
+  void ReportsHtml::CloseSymbolSummaryFile(
+    FILE*  aFile
+  )
+  {
+    fprintf(
+      aFile,
+      TABLE_FOOTER
+       "</tbody>\n"
+      "</table>\n" 
+      "</pre>\n" 
+      "</body>\n"
+      "</html>"
+    );
+
+     CloseFile( aFile );
+  }
+
+}

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
@@ -0,0 +1,112 @@
+/*
+ *   $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( 
+      FILE*                aFile, 
+      AnnotatedLineState_t state, 
+      std::string          line, 
+      uint32_t             id 
+    );
+
+    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

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
@@ -0,0 +1,258 @@
+/*
+ *   $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( 
+  FILE*                aFile, 
+  AnnotatedLineState_t state, 
+  std::string          line, 
+  uint32_t             id 
+)
+{
+  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;
+}
+
+}

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
@@ -0,0 +1,119 @@
+/*
+ *  $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

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
@@ -0,0 +1,99 @@
+/*
+ *  $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 "";
+  }
+
+}

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
@@ -0,0 +1,180 @@
+/*
+ *  $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 
+     *  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
+    );
+
+    
+    /*!
+     *  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

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
@@ -0,0 +1,145 @@
+/*
+ *  $Id$
+ */
+
+/*! @file TargetBase.cc
+ *  @brief TargetBase Implementation
+ *
+ *  This file contains the implementation of the base class for 
+ *  functions supporting target unique functionallity.
+ */
+
+#include "TargetBase.h"
+#include "qemu-traces.h"
+
+#include <algorithm>
+#include <stdio.h>
+
+namespace Target {
+
+  TargetBase::TargetBase( 
+    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( 
+        stderr,
+        "DETERMINE BRANCH INSTRUCTIONS FOR THIS ARCHITECTURE! -- fix me\n" 
+       );
+       exit( -1 );    
+    }
+    
+    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;
+
+    
+    ch = &(line[0]);
+
+    // Increment to the first tab in the line
+    while ((*ch != '\t') && (*ch != '\0')) { 
+      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')) 
+      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;
+  }
+
+}

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
@@ -0,0 +1,38 @@
+//
+//  $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
+

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
@@ -0,0 +1,90 @@
+//
+//  $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)( 
+       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;
+  }
+}

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
@@ -0,0 +1,81 @@
+/*
+ *  $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 
+     *  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

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
@@ -0,0 +1,91 @@
+/*
+ *  $Id$
+ */
+
+/*! @file Target_arm.cc
+ *  @brief Target_arm Implementation
+ *
+ *  This file contains the implementation of the base class for 
+ *  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");
+  
+    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; 
+      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;
+ 
+  }
+
+  bool Target_arm::isBranch(
+      const char* instruction
+  ) 
+  {
+    fprintf( stderr, "DETERMINE BRANCH INSTRUCTIONS FOR THIS ARCHITECTURE! -- fix me\n" );
+    exit( -1 );    
+  }
+
+  TargetBase *Target_arm_Constructor(
+    std::string          targetName
+  )
+  {
+    return new Target_arm( targetName );
+  }
+
+}

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
@@ -0,0 +1,80 @@
+/*
+ *  $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 
+     *  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

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
@@ -0,0 +1,115 @@
+/*
+ *  $Id$
+ */
+
+/*! @file Target_i386.cc
+ *  @brief Target_i386 Implementation
+ *
+ *  This file contains the implementation of the base class for 
+ *  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; 
+      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 );
+  }
+
+}

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
@@ -0,0 +1,74 @@
+/*
+ *  $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 
+     *  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

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
@@ -0,0 +1,56 @@
+/*
+ *  $Id$
+ */
+
+/*! @file Target_lm32.cc
+ *  @brief Target_lm32 Implementation
+ *
+ *  This file contains the implementation of the base class for 
+ *  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; 
+      return true;
+    }
+
+    return false;
+  }
+
+  TargetBase *Target_lm32_Constructor(
+    std::string          targetName
+  )
+  {
+    return new Target_lm32( targetName );
+  }
+
+}

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
@@ -0,0 +1,88 @@
+/*
+ *  $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 
+     *  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

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
@@ -0,0 +1,130 @@
+/*
+ *  $Id$
+ */
+
+/*! @file Target_m68k.cc
+ *  @brief Target_m68k Implementation
+ *
+ *  This file contains the implementation of the base class for 
+ *  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");
+  
+    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; 
+      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; 
+        return true;
+      } 
+    #endif
+
+    return false;
+  }
+
+  bool Target_m68k::isBranch(
+      const char* const instruction
+  )
+  {
+    fprintf(
+      stderr,
+      "DETERMINE BRANCH INSTRUCTIONS FOR THIS ARCHITECTURE! -- fix me\n"
+    );
+    exit( -1 );    
+  }
+
+  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 );
+  }
+
+}

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
@@ -0,0 +1,84 @@
+/*
+ *  $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 
+     *  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

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
@@ -0,0 +1,89 @@
+/*
+ *  $Id$
+ */
+
+/*! @file Target_powerpc.cc
+ *  @brief Target_powerpc Implementation
+ *
+ *  This file contains the implementation of the base class for 
+ *  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");
+
+  
+    branchInstructions.sort();    
+  }
+
+  Target_powerpc::~Target_powerpc()
+  {
+  }
+
+  bool Target_powerpc::isNopLine(
+    const char* const line,
+    int&              size
+  )
+  {
+    if (!strcmp( &line[strlen(line)-3], "nop")) {
+      size = 4; 
+      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 );    
+  }
+
+  TargetBase *Target_powerpc_Constructor(
+    std::string          targetName
+  )
+  {
+    return new Target_powerpc( targetName );
+  }
+
+}

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
@@ -0,0 +1,83 @@
+/*
+ *  $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 
+     *  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

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
@@ -0,0 +1,79 @@
+/*
+ *  $Id$
+ */
+
+/*! @file Target_sparc.cc
+ *  @brief Target_sparc Implementation
+ *
+ *  This file contains the implementation of the base class for 
+ *  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");
+  
+    branchInstructions.sort();    
+  }
+
+  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; 
+      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; 
+        return true;
+      } 
+    #endif
+
+    return false;
+  }
+
+
+  TargetBase *Target_sparc_Constructor(
+    std::string          targetName
+  )
+  {
+    return new Target_sparc( targetName );
+  }
+}

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
@@ -0,0 +1,107 @@
+/*
+ *  $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;
+   
+  //
+  // 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();
+ 
+  // 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 );
+
+}

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
@@ -0,0 +1,110 @@
+/*
+ *  $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 
+   */
+  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;
+
+    /*! 
+     *  This method constructs a TraceList instance.
+     */
+    TraceList();
+
+    /*! 
+     *  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

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
@@ -0,0 +1,54 @@
+/*
+ *  $Id$
+ */
+
+#include "TraceList.h"
+#include <stdio.h>
+
+namespace Trace {
+
+    TraceList::TraceList()
+    {
+    }
+
+    TraceList::~TraceList() 
+    { 
+    }
+
+    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 );     
+    }
+
+    void TraceList::ShowTrace( traceRange_t *t)
+    {
+      printf(
+        "Start 0x%x, length 0x%03x Reason %d\n", 
+        t->lowAddress, 
+        t->length, 
+        t->exitReason
+      );
+    }
+
+    void  TraceList::ShowList()
+    {
+      ranges_t::iterator   ritr;
+      traceRange_t         t;
+
+      for ( ritr=set.begin(); ritr != set.end(); ritr++ ) {
+        t = *ritr;
+        ShowTrace( &t );
+      }
+    }
+
+}

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
@@ -0,0 +1,59 @@
+/*
+ *  $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;
+
+
+    /*! 
+     *  This method constructs a TraceReaderBase instance.
+     */
+    TraceReaderBase();
+
+    /*! 
+     *  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

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
@@ -0,0 +1,23 @@
+/*
+ *  $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()
+  {
+  }
+}

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
@@ -0,0 +1,54 @@
+/*
+ *  $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:
+
+
+    /*! 
+     *  This method constructs a TraceReaderLogQEMU instance.
+     */
+    TraceReaderLogQEMU();
+
+    /*! 
+     *  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

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
@@ -0,0 +1,177 @@
+/*
+ *  $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( 
+      buffer, 
+      "0x%08lx: %s %s\n", 
+      &first.address, 
+      first.instruction, 
+      first.data 
+    );
+    if ( result < 2 ) 
+    {
+      fprintf(stderr, "Error Unable to Read Initial First Block\n" );
+      done = true;
+    }
+
+    while (!done) {
+
+      last = first;
+   
+      // Read until we get to the last instruction in the block.
+      do {
+        fgets(buffer, 120, logFile );
+        result = sscanf( 
+          buffer, 
+          "0x%08lx: %s %s\n", 
+          &last.address, 
+          last.instruction, 
+          last.data 
+        );
+      } 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( 
+          buffer, 
+          "0x%08lx: %s %s\n", 
+          &nextExecuted.address, 
+          nextExecuted.instruction, 
+          nextExecuted.data 
+        );
+        if ( result < 2 )  
+        {
+          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;
+    } 
+    fclose( logFile );
+    return true;
+  }
+}

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
@@ -0,0 +1,53 @@
+/*
+ *  $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:
+
+    /*! 
+     *  This method constructs a TraceWriterBase instance.
+     */
+    TraceWriterBase();
+
+    /*! 
+     *  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

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
@@ -0,0 +1,24 @@
+/*
+ *  $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()
+  {
+  }
+
+}

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
@@ -0,0 +1,54 @@
+/*
+ *  $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:
+
+    /*! 
+     *  This method constructs a TraceWriterQEMU instance.
+     */
+    TraceWriterQEMU();
+
+    /*! 
+     *  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

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
@@ -0,0 +1,148 @@
+/*
+ *  $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) 
+      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;
+       }
+       
+      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;
+  }
+}

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
@@ -0,0 +1,29 @@
+/*
+ *   $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 ); 
+bool FileIsReadable( const char *f1 ); 
+bool ReadUntilFound( FILE *file, const char *line );
+
+#endif

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
@@ -0,0 +1,85 @@
+/*
+ *  $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;
+  
+  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 { 
+    if ( !fgets( discardBuff, 99, file ) )
+      return false;
+
+    if ( strncmp( discardBuff, line, len ) == 0 ) 
+      return true; 
+  } while (1);
+}
+

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
@@ -0,0 +1,27 @@
+/*
+ * $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);
+  
+  config->processFile( "configFile.txt" );
+  config->printOptions();
+
+}
+

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
@@ -0,0 +1,224 @@
+/*
+ *  $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; 
+
+  if ((result == LLONG_MAX) && (errno == ERANGE))
+    return false; 
+
+  if ((result == LLONG_MIN) && (errno == ERANGE))
+    return false; 
+
+  *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': 
+        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;
+}

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
@@ -0,0 +1,545 @@
+/*
+ *  $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; 
+
+/*
+ *  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; 
+
+  if ( (result == LLONG_MAX) && (errno == ERANGE))
+    return false; 
+
+  if ( (result == LLONG_MIN) && (errno == ERANGE))
+    return false; 
+
+  *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 ); 
+      AddressesNeedingSourceLine.push_back( ha ); 
+      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 ); 
+      }
+      else if (CoverageMap->wasNeverTaken( la )) {
+        BranchesNeverTaken++;
+        AddressesNeedingSourceLine.push_back( la ); 
+      }
+      a = ha + 1;
+    }
+    else
+      a++;
+  }
+}
+
+/*
+ *  Find source lines for addresses
+ */
+void FindSourceForAddresses(void)
+{
+  FILE                          *tmpfile;
+  std::list<uint32_t>::iterator  it; 
+
+  /*
+   *  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': 
+        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 );
+  } 
+
+  /*
+   * 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.
+   */ 
+  FindSourceForAddresses();
+
+  /*
+   *  Generate report of ranges not executed
+   */ 
+  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
+   */ 
+  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 
+   */ 
+  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;
+}

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
@@ -0,0 +1,531 @@
+/*
+ *  $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)
+  
+
+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);
+  
+  //
+  // 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) || 
+        (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;
+}

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
@@ -0,0 +1,372 @@
+body { 
+    background: rgb(253,253,253);
+    color: rgb(0,0,0);
+    font-family: helvetica, sans-serif;
+    font-size: 1em;
+    line-height: 1.4;
+    margin: 5px, 5px, 5px, 5px;
+    padding: 0;
+}
+
+a:link { 
+    color: rgb(180, 50, 50);
+    font-family: helvetica, sans-serif;
+    font-size: 1.0em;
+}
+
+a:visited { 
+    color: purple; 
+    font-family: helvetica, sans-serif;
+    font-size: 1.0em;
+}
+
+a:hover {
+    color: rgb(0, 0, 0);
+    font-family: helvetica, sans-serif;
+    font-size: 1.0em;
+}
+
+a:active {
+    color: red; 
+    font-family: helvetica, sans-serif;
+    font-size: 1.0em;
+}
+
+.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%;
+}

*** DIFF FAILED:  ***
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
@@ -0,0 +1,68 @@
+
+#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 );
+  }
+
+  
+  fclose( trace );
+  printf( "instructions = %d\n", instructions );
+ 
+  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;
+}

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
@@ -0,0 +1,27 @@
+/*
+ *  $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 */

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
@@ -0,0 +1,119 @@
+/*
+ * 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 */

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
@@ -0,0 +1,36 @@
+/*
+ *  $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

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
@@ -0,0 +1,25 @@
+/*
+ *  $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

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
@@ -0,0 +1,1002 @@
+/**
+ * Copyright (c)2005-2009 Matt Kruse (javascripttoolbox.com)
+ * 
+ * Dual licensed under the MIT and GPL licenses. 
+ * 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/
+ * 
+ * Please do not link to the .js files on javascripttoolbox.com from
+ * your site. Copy the files locally to your server instead.
+ * 
+ */
+/**
+ * Table.js
+ * Functions for interactive Tables
+ *
+ * Copyright (c) 2007 Matt Kruse (javascripttoolbox.com)
+ * Dual licensed under the MIT and GPL licenses. 
+ *
+ * @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	
+	// ------------
+	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 
+	 * 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++); } 
+				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 
+	 * 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) { 
+				var rows = section.rows;
+				for (var j=0,L2=rows.length; j<L2; j++) { 
+					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) { 
+			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 
+	 * 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) { 
+			return ""; 
+		}
+		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, 
+	 * 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];      
+		} 
+
+		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])) { 
+					matrix[rowIndex] = []; 
+				}
+				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])) { 
+						matrix[k] = []; 
+					}
+					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)) { 
+			args.col = this.getActualCellIndex(o) || 0; 
+		}
+		// 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 { 
+						tb.appendChild(cRow[1]); 
+					} 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 
+				// and assign it's column index to the filter if it doesn't have one. This way, 
+				// passing in a cell reference or a select object etc instead of a table object 
+				// 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;
+			}
+		}		
+		// 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
+	 */	
+	table.pageNext = function(t,args) {
+		return this.pageJump(t,1,args);
+	};
+
+	/**
+	 * Go to the previous page of a paged table
+	 */	
+	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, 
+			// 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) { 
+		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) { 
+			return; 
+		}
+
+		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 
+	 */
+	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(); } 
+		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;
+})();



--

Generated by Deluxe Loginfo [http://www.codewiz.org/projects/index.html#loginfo] 2.122 by Bernardo Innocenti <bernie at develer.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/vc/attachments/20100524/c86eb0d2/attachment-0001.html>


More information about the vc mailing list