change log for rtems-testing (2011-12-02)
rtems-vc at rtems.org
rtems-vc at rtems.org
Fri Dec 2 07:31:49 UTC 2011
*joel*:
2011-12-01 Joel Sherrill <joel.sherrill at oarcorp.com>
* jmr3904.in: Add Data Bus Error to detected faults to exit simulator
on.
M 1.107 sim-scripts/ChangeLog
M 1.8 sim-scripts/jmr3904.in
diff -u rtems-testing/sim-scripts/ChangeLog:1.106 rtems-testing/sim-scripts/ChangeLog:1.107
--- rtems-testing/sim-scripts/ChangeLog:1.106 Sun Nov 6 10:55:26 2011
+++ rtems-testing/sim-scripts/ChangeLog Thu Dec 1 13:12:53 2011
@@ -1,3 +1,8 @@
+2011-12-01 Joel Sherrill <joel.sherrill at oarcorp.com>
+
+ * jmr3904.in: Add Data Bus Error to detected faults to exit simulator
+ on.
+
2011-11-06 Joel Sherrill <joel.sherrill at oarcorp.com>
* uC5282.in: Use grep -E rather rather than egrep as Open Group has
diff -u rtems-testing/sim-scripts/jmr3904.in:1.7 rtems-testing/sim-scripts/jmr3904.in:1.8
--- rtems-testing/sim-scripts/jmr3904.in:1.7 Mon Oct 12 16:16:23 2009
+++ rtems-testing/sim-scripts/jmr3904.in Thu Dec 1 13:12:53 2011
@@ -16,7 +16,10 @@
exceptionExit=$?
grep "^mips-core: " ${logfile}
badAccessExit=$?
- if [ $badAccessExit -eq 0 -o $exceptionExit -eq 0 ] ; then
+ grep "Data Bus Error" ${logfile}
+ dataBusError=$?
+ if [ $badAccessExit -eq 0 -o $exceptionExit -eq 0 -o \
+ $dataBusError -eq 0 ] ; then
return 1
fi
return 0
*joel*:
2011-12-01 Joel Sherrill <joel.sherrill at oarcorp.com>
* do_one: If a secondary language fails to build, do not abort build but
continue on and attempt other secondary languages.
Clean up arguments to rundeja to reflect clean up in that script.
* rtems_gcc_main.c: Add /tmp directory and file support so more tests pass.
Make sure argc/argv are correctly setup.
* rtems_gcj_init.c: Add comment.
* rundeja: Consolidate similar cases to eliminate duplication.
* test_driver: Install autotools if autoconf is not at install point.
M 1.25 gcc/ChangeLog
M 1.27 gcc/do_one
M 1.3 gcc/rtems_gcc_main.c
M 1.2 gcc/rtems_gcj_init.c
M 1.18 gcc/rundeja
M 1.25 gcc/test_driver
diff -u rtems-testing/gcc/ChangeLog:1.24 rtems-testing/gcc/ChangeLog:1.25
--- rtems-testing/gcc/ChangeLog:1.24 Sun Nov 6 09:35:35 2011
+++ rtems-testing/gcc/ChangeLog Thu Dec 1 13:17:33 2011
@@ -1,3 +1,14 @@
+2011-12-01 Joel Sherrill <joel.sherrill at oarcorp.com>
+
+ * do_one: If a secondary language fails to build, do not abort build but
+ continue on and attempt other secondary languages.
+ Clean up arguments to rundeja to reflect clean up in that script.
+ * rtems_gcc_main.c: Add /tmp directory and file support so more tests pass.
+ Make sure argc/argv are correctly setup.
+ * rtems_gcj_init.c: Add comment.
+ * rundeja: Consolidate similar cases to eliminate duplication.
+ * test_driver: Install autotools if autoconf is not at install point.
+
2011-11-06 Joel Sherrill <joel.sherrill at oarcorp.com>
* do_one: do_cleanup defaults to "no".
diff -u rtems-testing/gcc/do_one:1.26 rtems-testing/gcc/do_one:1.27
--- rtems-testing/gcc/do_one:1.26 Sun Nov 6 09:35:35 2011
+++ rtems-testing/gcc/do_one Thu Dec 1 13:17:34 2011
@@ -592,7 +592,6 @@
echo "Failed to install GCC C/C++ .. bailing"
exit 1
fi
-
}
if [ ${do_stage1} = "yes" ] ; then
@@ -647,13 +646,15 @@
cd ..
if [ $status -ne 0 ] ; then
echo "Failed building RTEMS for ${cpuArg}/${bspArg}"
- exit $status
+ if [ ${bspArg} != "multilib" ] ; then
+ exit $status
+ fi
fi
}
if [ ${do_rtems} = "yes" ] ; then
echo "Building RTEMS for ${cpu} ${bsp} ..."
- time j_rtems ${cpu} multilib >${LOGDIR}/${cpu}-rtems-multilib.log 2>&1
+ time j_rtems ${cpu} multilib ${bsp} >${LOGDIR}/${cpu}-rtems-multilib.log 2>&1
if [ $? -ne 0 ] ; then
echo "Failed to build RTEMS multilib for ${cpu}"
exit 1
@@ -828,7 +829,7 @@
make install
status=$?
if [ $status -ne 0 ] ; then
- echo "Failed building Ada"
+ echo "Failed building Ada - continuing to next secondary language"
fi
return $status
}
@@ -917,9 +918,9 @@
make install
status=$?
if [ $status -ne 0 ] ; then
- echo "Failed building Go"
+ echo "Failed building Go - continuing to next secondary language"
fi
- exit $status
+ return $status
}
go_fail="no"
@@ -986,7 +987,6 @@
if [ ${do_gccgo} = "yes" ] ; then
test ${do_cleanup} = "yes" && rm -rf ${BUILDDIR}/b-${cpu}-go
fi
-exit 0
##### Build a GCJ compiler now that we have a cross installed
j_gcj()
@@ -1031,9 +1031,9 @@
make install
status=$?
if [ $status -ne 0 ] ; then
- echo "Failed building GCJ"
+ echo "Failed building GCJ - continuing to next secondary language"
fi
- exit $status
+ return $status
}
gcj_fail="no"
@@ -1054,7 +1054,7 @@
-d ${BASEDIR}/b-${cpu}-gcj -a ${gcj_fail} = "no" ] ; then
echo "Running libjava DejaGNU tests..."
cd ${BASEDIR}/b-${cpu}-gcj || exit 1
- time sh -x ${SCRIPTDIR}/gcc/rundeja ${bsp} libjava \
+ time sh -x ${SCRIPTDIR}/gcc/rundeja ${bsp} java \
>${LOGDIR}/${cpu}-libjavatests-${bsp}.log 2>&1
RDIR=${RESULTSDIR}/${TARGET}-${bsp}/`date +%Y-%m-%d-%H-%M-%S`
@@ -1096,9 +1096,9 @@
make install
status=$?
if [ $status -ne 0 ] ; then
- echo "Failed building FORTRAN"
+ echo "Failed building FORTRAN - continuing to next secondary language"
fi
- exit $status
+ return $status
}
fortran_fail="no"
diff -u rtems-testing/gcc/rtems_gcc_main.c:1.2 rtems-testing/gcc/rtems_gcc_main.c:1.3
--- rtems-testing/gcc/rtems_gcc_main.c:1.2 Tue Jan 20 16:16:52 2009
+++ rtems-testing/gcc/rtems_gcc_main.c Thu Dec 1 13:17:34 2011
@@ -1,6 +1,7 @@
-/* Init
- *
- * COPYRIGHT (c) 1989-2008.
+/*
+ * Main for GCC Tests
+ *
+ * COPYRIGHT (c) 1989-2011.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -11,8 +12,23 @@
*/
#include <rtems.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+/*
+ * Set up first argument
+ */
+static int argc = 1;
+static char arg0[20] = "rtems";
+static char *argv[20] = { arg0 };
-int main( int, char **, char **);
+int main(int argc, char **argv, char **environp);
+
+rtems_task Init(rtems_task_argument ignored)
+{
+ mkdir( "/tmp", 0777 );
+ main(argc, argv, NULL);
+}
/* configuration information */
#define CONFIGURE_MAXIMUM_TASKS 1
@@ -24,7 +40,6 @@
/* GCC tests start at main, use a lot of stack and may use the FPU */
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
-#define CONFIGURE_INIT_TASK_ENTRY_POINT (void *)main
#if defined(__m32c__)
#define CONFIGURE_INIT_TASK_STACK_SIZE (16 * 1024)
#else
@@ -32,6 +47,10 @@
#endif
#define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+/* This helps language tests which need a real filesystem */
+#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
+#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 20
+
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
#define CONFIGURE_INIT
diff -u rtems-testing/gcc/rtems_gcj_init.c:1.1 rtems-testing/gcc/rtems_gcj_init.c:1.2
--- rtems-testing/gcc/rtems_gcj_init.c:1.1 Sat Aug 20 13:37:29 2011
+++ rtems-testing/gcc/rtems_gcj_init.c Thu Dec 1 13:17:34 2011
@@ -1,3 +1,7 @@
+/*
+ * Main for GCJ Testing
+ */
+
#include <bsp.h>
#include <stdlib.h>
#include <pthread.h>
diff -u rtems-testing/gcc/rundeja:1.17 rtems-testing/gcc/rundeja:1.18
--- rtems-testing/gcc/rundeja:1.17 Sun Nov 6 09:35:36 2011
+++ rtems-testing/gcc/rundeja Thu Dec 1 13:17:34 2011
@@ -117,7 +117,32 @@
echo "set boards_dir ${SCRIPTDIR}/dejagnu/boards" >${dfile}
fi
-case $2 in
+testsuite=$2
+case ${testsuite} in
+ libgo) ;;
+ gccgo)
+ testmain=rtems_gccgo_init.o
+ makefile=Makefile.rtems_gccgoinit
+ stanza=check-go
+ ;;
+ java)
+ testmain=rtems_gcj_init.o
+ makefile=Makefile.rtems_gcjinit
+ stanza=check-gcc-java
+ ;;
+ gcc|objc|fortran|gccgo|java)
+ testmain=rtems_gcc_main.o
+ makefile=Makefile.rtems_gccmain
+ stanza=check-${testsuite}
+ ;;
+ *)
+ testmain=rtems_gcc_main.o
+ makefile=Makefile.rtems_gccmain
+ stanza=check
+ ;;
+esac
+
+case ${testsuite} in
libgo)
rtems_libgo_init=${SCRIPTDIR}/gcc/rtems_libgo_init.c
rtems_bin2c=${INSTALL}/bin/rtems-bin2c
@@ -130,86 +155,21 @@
--target_board=rtems-${CPU}-${DEJABSP} \
"
;;
- gccgo)
- RTEMS_MAKEFILE_PATH=${rtemsdir} \
- SCRIPTDIR=${SCRIPTDIR} \
- make -f ${SCRIPTDIR}/gcc/Makefile.rtems_gccgoinit
- if [ $? -ne 0 ] ; then
- echo unable to compile RTEMS GCC Go Init File
- exit 1
- fi
- rtems_config=`pwd`/rtems_gccgo_init.o
- make check-go RUNTESTFLAGS="\
- SIM=${BSP_SIM} \
- RTEMS_MAKEFILE_PATH=${rtemsdir} \
- RTEMS_CONFIG_OBJ=${rtems_config} \
- --target_board=rtems-${CPU}-${DEJABSP} \
- "
- ;;
- objc)
- RTEMS_MAKEFILE_PATH=${rtemsdir} \
- SCRIPTDIR=${SCRIPTDIR} \
- make -f ${SCRIPTDIR}/gcc/Makefile.rtems_gccmain
- if [ $? -ne 0 ] ; then
- echo unable to compile RTEMS GCC Main
- exit 1
- fi
- rtems_config=`pwd`/rtems_gcc_main.o
- make check-objc RUNTESTFLAGS="\
- SIM=${BSP_SIM} \
- RTEMS_MAKEFILE_PATH=${rtemsdir} \
- RTEMS_CONFIG_OBJ=${rtems_config} \
- --target_board=rtems-${CPU}-${DEJABSP} \
- "
- ;;
- libjava)
- RTEMS_MAKEFILE_PATH=${rtemsdir} \
- SCRIPTDIR=${SCRIPTDIR} \
- make -f ${SCRIPTDIR}/gcc/Makefile.rtems_gcjinit
- if [ $? -ne 0 ] ; then
- echo unable to compile RTEMS GCC Java Init File
- exit 1
- fi
- rtems_config=`pwd`/rtems_gcj_init.o
- make check-gcc-java RUNTESTFLAGS="\
- SIM=${BSP_SIM} \
- RTEMS_MAKEFILE_PATH=${rtemsdir} \
- RTEMS_CONFIG_OBJ=${rtems_config} \
- --target_board=rtems-${CPU}-${DEJABSP} \
- "
- ;;
- gcc)
- RTEMS_MAKEFILE_PATH=${rtemsdir} \
- SCRIPTDIR=${SCRIPTDIR} \
- make -f ${SCRIPTDIR}/gcc/Makefile.rtems_gccmain
- if [ $? -ne 0 ] ; then
- echo unable to compile RTEMS GCC Main
- exit 1
- fi
- rtems_config=`pwd`/rtems_gcc_main.o
- make check-gcc RUNTESTFLAGS="\
- SIM=${BSP_SIM} \
- RTEMS_MAKEFILE_PATH=${rtemsdir} \
- RTEMS_CONFIG_OBJ=${rtems_config} \
- --target_board=rtems-${CPU}-${DEJABSP} \
- "
- ;;
- *)
+ gcc|objc|fortran|gccgo|java|*)
RTEMS_MAKEFILE_PATH=${rtemsdir} \
SCRIPTDIR=${SCRIPTDIR} \
- make -f ${SCRIPTDIR}/gcc/Makefile.rtems_gccmain
+ make -f ${SCRIPTDIR}/gcc/${makefile}
if [ $? -ne 0 ] ; then
- echo unable to compile RTEMS GCC Main
+ echo unable to compile RTEMS Init File for ${testsuite}
exit 1
fi
- rtems_config=`pwd`/rtems_gcc_main.o
- echo make check RUNTESTFLAGS="\
+ rtems_config=`pwd`/${testmain}
+ make ${stanza} RUNTESTFLAGS="\
SIM=${BSP_SIM} \
RTEMS_MAKEFILE_PATH=${rtemsdir} \
RTEMS_CONFIG_OBJ=${rtems_config} \
--target_board=rtems-${CPU}-${DEJABSP} \
"
-exit 0
;;
esac
diff -u rtems-testing/gcc/test_driver:1.24 rtems-testing/gcc/test_driver:1.25
--- rtems-testing/gcc/test_driver:1.24 Sun Nov 6 09:35:36 2011
+++ rtems-testing/gcc/test_driver Thu Dec 1 13:17:34 2011
@@ -298,7 +298,7 @@
fi
# Update gcc and install autotools in parallel
- if [ ${doCleanInstallPoint} = "yes" ] ; then
+ if [ ! -r ${INSTALL}/bin/autoconf ] ; then
install_auto
fi
if [ ${doUpdateTools} = "yes" ] ; then
*joel*:
2011-11-06 Pawel Zagorski <pzagor at agh.edu.pl>
* DesiredSymbols.cc, ExecutableInfo.cc, SymbolTable.cc, covoar.cc:
Added methods dumpExecutableInfo( void ) and dumpSymbolTable( void )
that can dump cointainers to stdout for debug purposes. Covoar now
accepts aditional command line argument -g GCNOS_LIST with list of
xxx.gcno files. If non-empty list is provided gcov outputs will be
craeated based on each file in the list.
M 1.27 covoar/ChangeLog
M 1.6 covoar/CoverageMapBase.h
M 1.12 covoar/DesiredSymbols.cc
M 1.2 covoar/ExecutableInfo.h
M 1.4 covoar/ExecutableInfo.cc
A 1.1 covoar/GcovData.h
A 1.1 covoar/GcovData.cc
A 1.1 covoar/GcovFunctionData.h
A 1.1 covoar/GcovFunctionData.cc
M 1.4 covoar/Makefile
M 1.3 covoar/SymbolTable.h
M 1.3 covoar/SymbolTable.cc
M 1.6 covoar/covoar.cc
diff -u rtems-testing/covoar/ChangeLog:1.26 rtems-testing/covoar/ChangeLog:1.27
--- rtems-testing/covoar/ChangeLog:1.26 Fri Nov 4 11:02:36 2011
+++ rtems-testing/covoar/ChangeLog Thu Dec 1 14:24:46 2011
@@ -1,3 +1,12 @@
+2011-11-06 Pawel Zagorski <pzagor at agh.edu.pl>
+
+ * DesiredSymbols.cc, ExecutableInfo.cc, SymbolTable.cc, covoar.cc:
+ Added methods dumpExecutableInfo( void ) and dumpSymbolTable( void )
+ that can dump cointainers to stdout for debug purposes. Covoar now
+ accepts aditional command line argument -g GCNOS_LIST with list of
+ xxx.gcno files. If non-empty list is provided gcov outputs will be
+ craeated based on each file in the list.
+
2011-11-04 Joel Sherrill <joel.sherrill at oarcorp.com>
* DesiredSymbols.cc, ReportsBase.h, ReportsText.cc, ReportsText.h,
diff -u rtems-testing/covoar/CoverageMapBase.h:1.5 rtems-testing/covoar/CoverageMapBase.h:1.6
--- rtems-testing/covoar/CoverageMapBase.h:1.5 Wed Aug 31 15:44:25 2011
+++ rtems-testing/covoar/CoverageMapBase.h Thu Dec 1 14:24:46 2011
@@ -46,7 +46,8 @@
/*
* This type identifies a list of ranges.
*/
- typedef std::list< AddressRange_t > AddressRange;
+ typedef std::list< AddressRange_t > AddressRange;
+ typedef std::list< AddressRange_t >::iterator AddressRangeIterator_t;
/*!
* This method constructs a CoverageMapBase instance.
diff -u rtems-testing/covoar/DesiredSymbols.cc:1.11 rtems-testing/covoar/DesiredSymbols.cc:1.12
--- rtems-testing/covoar/DesiredSymbols.cc:1.11 Fri Nov 4 11:02:36 2011
+++ rtems-testing/covoar/DesiredSymbols.cc Thu Dec 1 14:24:46 2011
@@ -72,7 +72,6 @@
inputBuffer[0] = '\0';
inputBuffer2[0] = '\0';
cStatus = fscanf( sFile, "%s %s", inputBuffer, inputBuffer2 );
- //TODO: Store inputBuffer2 value containing symbol source file
if ( cStatus == EOF ) {
done = true;
}
@@ -97,9 +96,8 @@
}
// Add this to the set of symbols.
- else {
+ else
set[ inputBuffer ] = *symInfo;
- }
}
}
}
@@ -462,6 +460,7 @@
"ranges1.tmp",
"ranges2.tmp"
);
+
if (system( command )) {
fprintf(
stderr,
diff -u rtems-testing/covoar/ExecutableInfo.h:1.1 rtems-testing/covoar/ExecutableInfo.h:1.2
--- rtems-testing/covoar/ExecutableInfo.h:1.1 Mon May 24 15:07:08 2010
+++ rtems-testing/covoar/ExecutableInfo.h Thu Dec 1 14:24:47 2011
@@ -52,6 +52,11 @@
void dumpCoverageMaps( void );
/*!
+ * This method prints the contents of Executable info containers
+ */
+ void dumpExecutableInfo( void );
+
+ /*!
* This method returns a pointer to the executable's coverage map
* that contains the specified address.
*
diff -u rtems-testing/covoar/ExecutableInfo.cc:1.3 rtems-testing/covoar/ExecutableInfo.cc:1.4
--- rtems-testing/covoar/ExecutableInfo.cc:1.3 Tue Jan 25 15:26:00 2011
+++ rtems-testing/covoar/ExecutableInfo.cc Thu Dec 1 14:24:47 2011
@@ -47,6 +47,14 @@
}
}
+ void ExecutableInfo::dumpExecutableInfo( void ){
+ fprintf( stdout, "\n== Executable info ==\n");
+ fprintf( stdout, "executableName = %s\n", executableName.c_str());
+ fprintf( stdout, "libraryName = %s\n", libraryName.c_str());
+ fprintf( stdout, "loadAddress = %u\n", loadAddress);
+ theSymbolTable->dumpSymbolTable();
+ }
+
CoverageMapBase* ExecutableInfo::getCoverageMap ( uint32_t address )
{
CoverageMapBase* aCoverageMap = NULL;
diff -u /dev/null rtems-testing/covoar/GcovData.h:1.1
--- /dev/null Fri Dec 2 01:31:47 2011
+++ rtems-testing/covoar/GcovData.h Thu Dec 1 14:24:47 2011
@@ -0,0 +1,204 @@
+/*
+ * $Id$
+ */
+
+/*! @file GcovData.h
+ * @brief GcovData Specification
+ *
+ * This file contains the specification of the GcovGcnoWriter class.
+ */
+
+#ifndef __GCOV_DATA_H__
+#define __GCOV_DATA_H__
+
+#include <stdint.h>
+#include <list>
+#include <iostream>
+#include "GcovFunctionData.h"
+
+namespace Gcov {
+
+#define GCDA_MAGIC ((uint32_t) 0x67636461 ) /* "gcda" */
+#define GCNO_MAGIC ((uint32_t) 0x67636e6f ) /* "gcno" */
+
+/* we are using gcc 4.6 release format, coded as "406R" */
+#define GCNO_VERSION ((uint32_t) 0x34303652 )
+
+/* GCOV tags */
+#define GCOV_TAG_FUNCTION ((uint32_t)0x01000000)
+#define GCOV_TAG_BLOCKS ((uint32_t)0x01410000)
+#define GCOV_TAG_ARCS ((uint32_t)0x01430000)
+#define GCOV_TAG_LINES ((uint32_t)0x01450000)
+#define GCOV_TAG_COUNTER ((uint32_t)0x01a10000)
+#define GCOV_TAG_OBJECT_SUMMARY ((uint32_t)0xa1000000)
+#define GCOV_TAG_PROGRAM_SUMMARY ((uint32_t)0xa3000000)
+
+
+typedef std::list<Gcov::GcovFunctionData*> functions_t;
+typedef std::list<Gcov::GcovFunctionData*>::iterator functions_iterator_t;
+
+struct gcov_preamble
+{
+ uint32_t magic;
+ uint32_t version;
+ uint32_t timestamp;
+};
+
+struct gcov_frame_header
+{
+ uint32_t tag;
+ uint32_t length;
+};
+
+struct gcov_statistics
+{
+ uint32_t checksum; // checksum
+ uint32_t counters; // number of counters
+ uint32_t runs; // number of runs
+ uint64_t sum; // sum of all couter values
+ uint64_t max; // max value on a single run
+ uint64_t sumMax; // sum of individual runs max values
+};
+
+ /*! @class GcovData
+ *
+ * This is the specification of the GcovData class.
+ */
+ class GcovData {
+
+ public:
+
+ /*!
+ * This method constructs a GcnoReader instance.
+ */
+ GcovData();
+
+ /*!
+ * This method destructs a GcnoReader instance.
+ */
+ virtual ~GcovData();
+
+ /*!
+ * This method reads the *.gcno file
+ *
+ * @param[in] fileName name of the file to read
+ *
+ * @return Returns TRUE if the method succeeded and FALSE if it failed.
+ */
+ bool readGcnoFile( const char* const fileName );
+
+ /*!
+ * This method writes the *.gcda file. It also produces and stores
+ * gcda and txt file names for future outputs.
+ *
+ * @return Returns TRUE if the method succeeded and FALSE if it failed.
+ */
+ bool writeGcdaFile ();
+
+ /*!
+ * This method writes all contained information to stdout file
+ *
+ * @return Returns TRUE if the method succeeded and FALSE if it failed.
+ */
+ bool writeReportFile();
+
+ /*!
+ * This method runs gcov to generate report. This method should
+ * be used only when gcno and gcda files are already generated.
+ */
+ void writeGcovFile( );
+
+ /*!
+ * This method calculates values of counters for all functions
+ */
+ bool processCounters( void );
+
+ private:
+
+ uint32_t numberOfFunctions;
+ gcov_preamble gcdaPreamble;
+ gcov_preamble gcnoPreamble;
+ char gcnoFileName[FILE_NAME_LENGTH];
+ char gcdaFileName[FILE_NAME_LENGTH];
+ char textFileName[FILE_NAME_LENGTH];
+ char cFileName[FILE_NAME_LENGTH];
+ functions_t functions;
+
+
+ /*!
+ * This method reads a frame from *.gcno file
+ *
+ * @param[in] file points to a file to read
+ *
+ * @return true if read was succesfull, false otherwise
+ */
+ bool readFrame(
+ FILE* gcovFile
+ );
+
+ /*!
+ * This method reads a string from gcov file
+ *
+ * @param[in] buffer stores the string
+ * @param[in] file specifies the name of the file to read
+ *
+ * @return Returns length of words read (word = 32bit) or -1 if error ocurred
+ */
+ int readString(
+ char* buffer,
+ FILE* gcovFile
+ );
+
+ /*!
+ * This method reads a frame header from gcov file
+ *
+ * @param[in] header stores the header
+ * @param[in] file specifies the name of the file to read
+ *
+ * @return Returns length of words read (word = 32bit)
+ * or -1 if error ocurred
+ */
+ int readFrameHeader(
+ gcov_frame_header* header,
+ FILE* gcovFile
+ );
+
+ /*!
+ * This method reads a frame header from gcov file
+ *
+ * @param[in] preamble stores the preamble
+ * @param[in] gcovFile specifies the name of the file to read
+ * @param[in] desiredMagic stores the expected magic of a file
+ *
+ * @return Returns length of words read (word = 32bit)
+ * or -1 if error ocurred
+ */
+ int readFilePreamble(
+ gcov_preamble* preamble,
+ FILE* gcovFile,
+ const uint32_t desiredMagic
+ );
+
+ /*!
+ * This method reads a function frame from gcov file
+ *
+ * @param[in] header passes frame header
+ * @param[in] gcovFile specifies the name of the file to read
+ * @param[in] function stores the expected magic of a file
+ *
+ * @return Returns true if operation was succesfull
+ */
+ bool readFunctionFrame(
+ gcov_frame_header header,
+ FILE* gcovFile,
+ GcovFunctionData* function
+ );
+
+ /*!
+ * This method prints info about previously read *.gcno file
+ * to a specified report file
+ */
+ void printGcnoFileInfo( FILE * textFile );
+ };
+}
+#endif
diff -u /dev/null rtems-testing/covoar/GcovData.cc:1.1
--- /dev/null Fri Dec 2 01:31:48 2011
+++ rtems-testing/covoar/GcovData.cc Thu Dec 1 14:24:47 2011
@@ -0,0 +1,506 @@
+/*
+ * $Id$
+ *
+ * TODO: use strings instead of cstrings for reliability and saving memory
+ * TODO: use global buffers
+ *
+ */
+
+/*! @file GcovData.cc
+ * @brief GcovData Implementation
+ *
+ * This file contains the implementation of the functions supporting
+ * reading *.gcno and writing *.gcda files for gcov support
+ */
+
+#include <libgen.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+//#include <sys/stat.h>
+
+//#include "app_common.h"
+#include "GcovData.h"
+//#include "ExecutableInfo.h"
+//#include "CoverageMap.h"
+//#include "qemu-traces.h"
+
+
+namespace Gcov {
+
+ GcovData::GcovData()
+ {
+ numberOfFunctions = 0;
+ }
+
+ GcovData::~GcovData()
+ {
+ }
+
+ bool GcovData::readGcnoFile( const char* const fileName )
+ {
+ int status;
+ FILE* gcovFile;
+ char* tempString;
+ char* tempString2;
+ char* tempString3;
+
+ if ( strlen(fileName) >= FILE_NAME_LENGTH ){
+ fprintf( stderr, "ERROR: File name is to long to be correctly stored: %u\n", strlen(fileName) );
+ return false;
+ }
+ strcpy( gcnoFileName, fileName );
+ strcpy( gcdaFileName, fileName );
+ strcpy( textFileName, fileName );
+ strcpy( cFileName, fileName );
+ tempString = strstr( gcdaFileName,".gcno" );
+ tempString2 = strstr( textFileName,".gcno" );
+ tempString3 = strstr( cFileName,".gcno" );
+
+ if ( (tempString == NULL) && (tempString2 == NULL) ){
+ fprintf(stderr, "ERROR: incorrect name of *.gcno file\n");
+ }
+ else
+ {
+ strcpy( tempString, ".gcda"); // construct gcda file name
+ strcpy( tempString2, ".txt"); // construct report file name
+ strcpy( tempString3, ".c"); // construct source file name
+ }
+
+ // Debug message
+ // fprintf( stderr, "Readning file: %s\n", gcnoFileName);
+
+ // Open the notes file.
+ gcovFile = fopen( gcnoFileName, "r" );
+ if ( !gcovFile ) {
+ fprintf( stderr, "Unable to open %s\n", gcnoFileName );
+ return false;
+ }
+
+ // Read and validate the gcnoPreamble (magic, version, timestamp) from the file
+ status = readFilePreamble( &gcnoPreamble, gcovFile, GCNO_MAGIC );
+ if ( status <= 0 ){
+ fprintf( stderr, "Unable to read %s\n", gcnoFileName );
+ fclose( gcovFile );
+ return false;
+ }
+
+ //Read all remaining frames from file
+ while( readFrame(gcovFile) ){}
+
+ fclose( gcovFile );
+ return true;
+ }
+
+
+ bool GcovData::writeGcdaFile ()
+ {
+ gcov_preamble preamble;
+ gcov_frame_header header;
+ FILE* gcdaFile;
+ functions_iterator_t currentFunction;
+ arcs_iterator_t currentArc;
+ uint32_t buffer;
+ uint32_t countersFound;
+ uint32_t countersFoundSum;
+ uint64_t countersSum;
+ uint64_t countersMax;
+ uint64_t llBuffer[4096]; // TODO: Use common buffer
+ gcov_statistics objectStats;
+ gcov_statistics programStats;
+ size_t status;
+
+ // Debug message
+ // fprintf( stderr, "Writing file: %s\n", gcdaFileName);
+
+ // Lets clear counters sumators
+ countersSum = 0;
+ countersMax = 0;
+ countersFoundSum = 0;
+
+ // Open the data file.
+ gcdaFile = fopen( gcdaFileName, "w" );
+ if ( !gcdaFile ) {
+ fprintf( stderr, "Unable to create %s\n", gcdaFileName );
+ return false;
+ }
+
+ //Form preamble
+ preamble.magic = GCDA_MAGIC;
+ preamble.version = gcnoPreamble.version;
+ preamble.timestamp = gcnoPreamble.timestamp;
+
+ //Write preamble
+ status = fwrite (&preamble , sizeof( preamble ), 1 , gcdaFile );
+ if ( status != 1 )
+ fprintf( stderr, "Error while writing gcda preamble to a file %s\n", gcdaFileName );
+
+ //Write function info and counter counts
+ for (
+ currentFunction = functions.begin();
+ currentFunction != functions.end();
+ currentFunction++
+ )
+ {
+ //Write function announcement frame header (length always equals 2)
+ header.tag = GCOV_TAG_FUNCTION;
+ header.length = 2;
+ status = fwrite (&header, sizeof(header), 1, gcdaFile );
+ if ( status != 1 )
+ fprintf( stderr, "Error while writing function announcement to a file %s\n", gcdaFileName );
+
+ //Write function id
+ buffer = (*currentFunction)->getId();
+ status = fwrite (&buffer, sizeof( buffer ), 1, gcdaFile );
+ if ( status != 1 )
+ fprintf( stderr, "Error while writing function id to a file %s\n", gcdaFileName );
+
+ //Write function checksum
+ buffer = (*currentFunction)->getChecksum();
+ status = fwrite (&buffer, sizeof( buffer ), 1, gcdaFile );
+ if ( status != 1 )
+ fprintf( stderr, "Error while writing function checksum to a file %s\n", gcdaFileName );
+
+ // Determine how many counters there are
+ // and store their counts in buffer
+ countersFound = 0;
+ (*currentFunction)->getCounters( llBuffer, countersFound, countersSum, countersMax );
+ countersFoundSum += countersFound;
+
+ //Write info about counters
+ header.tag = GCOV_TAG_COUNTER;
+ header.length = countersFound * 2;
+ status = fwrite (&header, sizeof( header ), 1, gcdaFile );
+ if ( status != 1 )
+ fprintf( stderr, "Error while writing counter header to a file %s\n", gcdaFileName );
+
+ status = fwrite (llBuffer, sizeof( uint64_t ), countersFound , gcdaFile );
+ if ( status != countersFound )
+ fprintf( stderr, "Error while writing counter data to a file %s\n", gcdaFileName );
+ }
+
+ // Prepare frame with object file statistics
+ header.tag = GCOV_TAG_OBJECT_SUMMARY;
+ header.length = 9;
+ objectStats.checksum = 0; // TODO: have no idea hov to calculates it :)
+ objectStats.counters = countersFoundSum;
+ objectStats.runs = 1; // We are lying for now, we have no means of figuring this out
+ objectStats.sum = countersSum; // Sum of all counters
+ objectStats.max = countersMax; // max value for counter on last run, we have no clue
+ objectStats.sumMax = countersMax; // we have no clue
+
+ // Write data
+ status = fwrite (&header, sizeof( header ), 1, gcdaFile );
+ if ( status != 1 )
+ fprintf( stderr, "Error while writing stats header to a file %s\n", gcdaFileName );
+ status = fwrite (&objectStats, sizeof( objectStats ), 1, gcdaFile );
+ if ( status != 1 )
+ fprintf( stderr, "Error while writing object stats to a file %s\n", gcdaFileName );
+
+
+ // Prepare frame with program statistics
+ header.tag = GCOV_TAG_PROGRAM_SUMMARY;
+ header.length = 9;
+ programStats.checksum = 0; // TODO: have no idea hov to calculate it :)
+ programStats.counters = countersFoundSum;
+ programStats.runs = 1; // We are lying for now, we have no clue
+ programStats.sum = countersSum; // Sum of all counters
+ programStats.max = countersMax; // max value for counter on last run, we have no clue
+ programStats.sumMax = countersMax; // we have no clue
+
+ // Write data
+ status = fwrite (&header, sizeof( header ), 1, gcdaFile );
+ if ( status != 1 )
+ fprintf( stderr, "Error while writing stats header to a file %s\n", gcdaFileName );
+ status = fwrite (&programStats, sizeof( programStats ), 1, gcdaFile );
+ if ( status != 1 )
+ fprintf( stderr, "Error while writing program stats to a file %s\n", gcdaFileName );
+
+ fclose( gcdaFile );
+
+ return true;
+ }
+
+ bool GcovData::readFrame(
+ FILE* gcovFile
+ )
+ {
+ gcov_frame_header header;
+ char buffer[512];
+ uint32_t intBuffer[4096];
+ uint32_t tempBlockId;
+ blocks_iterator_t tempBlockIterator;
+ int status;
+ GcovFunctionData* newFunction;
+
+ status = readFrameHeader( &header, gcovFile);
+
+ if ( status <= 0 ){
+ // Not printing error message because this
+ // happenns at the end of each file
+ return false;
+ }
+
+ switch (header.tag){
+
+ case GCOV_TAG_FUNCTION:
+
+ numberOfFunctions++;
+ newFunction = new GcovFunctionData;
+ if ( !readFunctionFrame(header, gcovFile, newFunction) ){
+ fprintf( stderr, "Error while reading FUNCTION from gcov file...\n" );
+ return false;
+ }
+ functions.push_back(newFunction);
+ break;
+
+ case GCOV_TAG_BLOCKS:
+
+ status = fread( &intBuffer, 4, header.length, gcovFile );
+ if ( status != (int) header.length){
+ fprintf(
+ stderr, "Error while reading BLOCKS from gcov file...\n"
+ "Header lenght is %u instead of %u\n",
+ header.length,
+ status
+ );
+ return false;
+ }
+
+ for( uint32_t i = 0; i < header.length; i++ )
+ functions.back()->addBlock(i, intBuffer[i], "");
+
+ break;
+
+ case GCOV_TAG_ARCS:
+
+ status = fread( &intBuffer, 4, header.length, gcovFile );
+ if (status != (int) header.length){
+ return false;
+ }
+
+ for ( int i = 1; i < (int) header.length; i += 2 )
+ functions.back()->addArc(intBuffer[0], intBuffer[i], intBuffer[i+1]);
+
+ break;
+
+ case GCOV_TAG_LINES:
+
+ status = fread( &intBuffer, 4, 2, gcovFile );
+ if (status != 2 || intBuffer[1] != 0){
+ fprintf(
+ stderr,
+ "Error while reading block id for LINES from gcov file..."
+ );
+ return false;
+ }
+ tempBlockId = intBuffer[0];
+ header.length -= 2;
+
+ // Find the right block
+ tempBlockIterator =functions.back()->findBlockById(tempBlockId);
+
+ header.length -= readString(buffer, gcovFile);
+ functions.back()->setBlockFileName( tempBlockIterator, buffer );
+
+ status = fread( &intBuffer, 4, header.length, gcovFile );
+ if (status != (int) header.length){
+ fprintf( stderr, "Error while reading LINES from gcov file..." );
+ return false;
+ }
+
+ else
+ for (int i = 0; i < (int) (header.length - 2); i++)
+ functions.back()->addBlockLine( tempBlockIterator, intBuffer[i] );
+
+ break;
+
+ default:
+
+ fprintf( stderr, "\n\nERROR - encountered unknown *.gcno tag : 0x%x\n", header.tag );
+ break;
+ }
+
+ return true;
+ }
+
+ int GcovData::readString(
+ char* buffer, //TODO: use global buffer here
+ FILE* gcovFile
+ )
+ {
+ int status;
+ int length;
+
+ status = fread( &length, sizeof(int), 1, gcovFile );
+ if (status != 1){
+ fprintf( stderr, "ERROR: Unable to read string length from gcov file\n" );
+ return -1;
+ }
+
+ status = fread( buffer, length * 4 , 1, gcovFile );
+ if (status != 1){
+ fprintf( stderr, "ERROR: Unable to read string from gcov file\n" );
+ return -1;
+ }
+
+ buffer[length * 4] = '\0';
+
+ return length +1;
+ }
+
+ int GcovData::readFrameHeader(
+ gcov_frame_header* header,
+ FILE* gcovFile
+ )
+ {
+ int status;
+ int length;
+
+ length = sizeof(gcov_frame_header);
+ status = fread( header, length, 1, gcovFile );
+ if (status != 1){
+ //fprintf( stderr, "ERROR: Unable to read frame header from gcov file\n" );
+ return -1;
+ }
+
+ return length / 4;
+ }
+
+ int GcovData::readFilePreamble(
+ gcov_preamble* preamble,
+ FILE* gcovFile,
+ uint32_t desiredMagic
+ )
+ {
+ int status;
+ int length;
+
+ length = sizeof( gcov_preamble );
+ status = fread( preamble, sizeof( gcov_preamble), 1, gcovFile );
+ if (status <= 0) {
+ fprintf( stderr, "Error while reading file preamble\n" );
+ return -1;
+ }
+
+ if ( preamble->magic != GCNO_MAGIC ) {
+ fprintf( stderr, "File is not a valid *.gcno output (magic: 0x%4x)\n", preamble->magic );
+ return -1;
+ }
+
+ return length / 4;
+ }
+
+ bool GcovData::readFunctionFrame(
+ gcov_frame_header header,
+ FILE* gcovFile,
+ GcovFunctionData* function
+ )
+ {
+ char buffer[512]; //TODO: use common buffers
+ uint32_t intBuffer[4096];
+ int status;
+
+ status = fread( &intBuffer, 8, 1, gcovFile );
+ if (status != 1){
+ fprintf( stderr, "ERROR: Unable to read Function ID & checksum\n" );
+ return false;
+ }
+ header.length -= 2;
+ function->setId( intBuffer[0] );
+ function->setChecksum( intBuffer[1] );
+
+ header.length -= readString( buffer, gcovFile );
+ function->setFunctionName( buffer );
+ header.length -= readString( buffer, gcovFile );
+ function->setFileName( buffer );
+ status = fread( &intBuffer, 4, header.length, gcovFile );
+ if (status <= 0){
+ fprintf( stderr, "ERROR: Unable to read Function starting line number\n" );
+ return false;
+ }
+ function->setFirstLineNumber( intBuffer[0] );
+
+ return true;
+ }
+
+ bool GcovData::writeReportFile()
+ {
+ functions_iterator_t currentFunction;
+ uint32_t i = 1; //iterator
+ FILE* textFile;
+
+ // Debug message
+ // fprintf( stderr, "Writing file: %s\n", textFileName);
+
+ // Open the data file.
+ textFile = fopen( textFileName, "w" );
+ if ( !textFile ) {
+ fprintf( stderr, "Unable to create %s\n", textFileName );
+ return false;
+ }
+
+ printGcnoFileInfo( textFile );
+
+ for (
+ currentFunction = functions.begin();
+ currentFunction != functions.end();
+ currentFunction++
+ )
+ {
+ (*currentFunction)->printFunctionInfo( textFile, i );
+ (*currentFunction)->printCoverageInfo( textFile, i );
+ i++;
+ }
+
+ fclose ( textFile );
+ return true;
+ }
+
+ void GcovData::printGcnoFileInfo( FILE * textFile )
+ {
+ fprintf(
+ textFile,
+ "\nFILE:\t\t\t%s\n"
+ "magic:\t\t\t%x\n"
+ "version:\t\t%x\n"
+ "timestamp:\t\t%x\n"
+ "functions found: \t%u\n\n",
+ gcnoFileName,
+ gcnoPreamble.magic,
+ gcnoPreamble.version,
+ gcnoPreamble.timestamp,
+ numberOfFunctions
+ );
+ }
+
+ void GcovData::writeGcovFile( )
+ {
+ char path[512];
+ char command[512];
+
+ //fprintf (stderr, "Attempting to run gcov for: %s\n", cFileName );
+ strcpy( path, cFileName );
+ dirname( path );
+ sprintf( command, "( cd %s && gcov %s &>> gcov.log)", path, basename( cFileName ) );
+ //fprintf (stderr, "> %s\n", command );
+ system( command );
+ }
+
+ bool GcovData::processCounters( )
+ {
+ functions_iterator_t currentFunction;
+ bool status = true;
+ for (
+ currentFunction = functions.begin();
+ currentFunction != functions.end();
+ currentFunction++
+ )
+ {
+ if ( !(*currentFunction)->processFunctionCounters( ) )
+ status = false;
+ }
+
+ return status;
+ }
+}
diff -u /dev/null rtems-testing/covoar/GcovFunctionData.h:1.1
--- /dev/null Fri Dec 2 01:31:48 2011
+++ rtems-testing/covoar/GcovFunctionData.h Thu Dec 1 14:24:47 2011
@@ -0,0 +1,278 @@
+/*
+ * $Id$
+ */
+
+/*! @file GcovFunctionData.h
+ * @brief GcovFunctionData Specification
+ *
+ * This file contains the specification of the GcovGcnoWriter class.
+ */
+
+#ifndef __GCOV_FUNCTION_DATA_H__
+#define __GCOV_FUNCTION_DATA_H__
+
+#include <stdint.h>
+#include <list>
+#include "CoverageMapBase.h"
+#include "DesiredSymbols.h"
+
+namespace Gcov {
+
+#define FUNCTION_NAME_LENGTH 64
+#define FILE_NAME_LENGTH 256
+
+#define ON_TREE_ARC_FLAG 0x1
+#define FAKE_ARC_FLAG 0x2
+#define FALLTHROUGH_ARC_FLAG 0x4
+
+struct gcov_arc_info
+{
+ uint32_t sourceBlock;
+ uint32_t destinationBlock;
+ uint32_t flags;
+ uint64_t counter;
+};
+
+struct gcov_block_info
+{
+ uint32_t id;
+ uint32_t flags;
+ uint32_t numberOfLines;
+ uint64_t counter;
+ char sourceFileName[FILE_NAME_LENGTH];
+ std::list<uint32_t> lines;
+};
+
+typedef std::list<gcov_arc_info> arcs_t;
+typedef std::list<gcov_arc_info>::iterator arcs_iterator_t;
+typedef std::list<gcov_block_info> blocks_t;
+typedef std::list<gcov_block_info>::iterator blocks_iterator_t;
+
+ /*! @class GcovFunctionData
+ *
+ * This is the specification of the GcovFunctionData class.
+ */
+ class GcovFunctionData {
+
+ public:
+
+ /*!
+ * This method constructs a GcovFunctionData instance.
+ */
+ GcovFunctionData();
+
+ /*!
+ * This method destructs a GcovFunctionData instance.
+ */
+ virtual ~GcovFunctionData();
+
+ /*!
+ * This method stores checksum related to function
+ *
+ * @param[in] chk stores the checksum value
+ */
+ void setChecksum(
+ const uint32_t chk
+ );
+
+ /*!
+ * This method stores id of function
+ *
+ * @param[in] idNumber stores the id value
+ */
+ void setId(
+ const uint32_t idNumber
+ );
+
+ /*!
+ * This method stores checksum related to function
+ *
+ * @param[in] lineNo passes number of the line begining the function
+ */
+ void setFirstLineNumber(
+ const uint32_t lineNo
+ );
+
+ /*!
+ * This method stores name of the function and ties it to its
+ * unified coverage map.
+ *
+ * @param[in] functionName passes name of the the function
+ *
+ * @return Returns TRUE if the method succeeded and FALSE if it failed.
+ */
+ bool setFunctionName(
+ const char* fcnName
+ );
+
+ /*!
+ * This method stores name of the source file where function is located
+ *
+ * @param[in] fileName passes name of the the file
+ *
+ * @return Returns TRUE if the method succeeded and FALSE if it failed.
+ */
+ bool setFileName(
+ const char* fileName
+ );
+
+ /*!
+ * This method stores name of the source file where block is located
+ *
+ * @param[in] block identifies block
+ * @param[in] fileName passes name of the the file
+ *
+ * @return Returns TRUE if the method succeeded and FALSE if it failed.
+ */
+ void setBlockFileName(
+ const blocks_iterator_t block,
+ const char* fileName
+ );
+
+ /*!
+ * This method returns arcs list
+ */
+ arcs_t getArcs() const;
+
+ /*!
+ * This method returns blocks list
+ */
+ blocks_t getBlocks() const;
+
+ /*!
+ * This method returns checksum
+ */
+ uint32_t getChecksum() const;
+
+ /*!
+ * This method returns id
+ */
+ uint32_t getId() const;
+
+ /*!
+ * This method returns counters
+ *
+ * @param[out] counterValues array of counter values
+ * @param[out] countersFound used to return counters number
+ * @param[out] countersSum used to return sum counters values
+ * @param[out] countersMax used to return max counter value
+ */
+ void getCounters( uint64_t* counterValues, uint32_t &countersFound, uint64_t &countersSum, uint64_t &countersMax );
+
+ /*!
+ * This method adds new arc to arc list
+ *
+ * @param[in] source passes source block number
+ * @param[in] destination passes destination block number
+ */
+ void addArc(
+ uint32_t source,
+ uint32_t destination,
+ uint32_t flags
+ );
+
+ /*!
+ * This method adds new arc to arc list
+ *
+ * @param[in] block identifies block
+ * @param[in] line passes the line number
+ */
+ void addBlockLine(
+ const blocks_iterator_t block,
+ const uint32_t line
+ );
+
+ /*!
+ * This method finds block by its ID
+ *
+ * @param[in] id passes block id number
+ *
+ * @return Returns iterator to a matching block or NULL for error.
+ */
+ blocks_iterator_t findBlockById(
+ const uint32_t id
+ );
+
+ /*!
+ * This method adds new block to block list
+ *
+ * @param[in] id passes block id number
+ * @param[in] flags passes per block flags
+ * @param[in] sourceFileName passes containing file name
+ */
+ void addBlock(
+ const uint32_t id,
+ const uint32_t flags,
+ const char * sourceFileName
+ );
+
+ /*!
+ * This method prints info about function
+ */
+ void printFunctionInfo( FILE * textFile, uint32_t function_number );
+
+ /*!
+ * This method prints info about coverage of this function
+ */
+ void printCoverageInfo( FILE * textFile, uint32_t function_number );
+
+ /*!
+ * This method prints info about chosen arc in arcs list
+ *
+ * @param[in] textFile specifies output file
+ * @param[in] arc passes iterator identifying arc
+ */
+ void printArcInfo(
+ FILE * textFile,
+ arcs_iterator_t arc
+ );
+
+ /*!
+ * This method prints info about chosen block in blocks list
+ *
+ * @param[in] block passes iterator identifying block
+ */
+ void printBlockInfo(
+ FILE * textFile,
+ blocks_iterator_t block
+ );
+
+ /*!
+ * This method calculates values of arc counters
+ */
+ bool processFunctionCounters( void );
+
+ private:
+
+ uint32_t id;
+ uint32_t checksum;
+ uint32_t firstLineNumber;
+ uint32_t numberOfBlocks;
+ uint32_t numberOfArcs;
+ arcs_t arcs;
+ blocks_t blocks;
+ char functionName[FUNCTION_NAME_LENGTH];
+ char sourceFileName[FILE_NAME_LENGTH];
+
+ /*!
+ * This member contains the unified or merged coverage map
+ * and symbol info for the symbol.
+ */
+ Coverage::CoverageMapBase* coverageMap;
+ Coverage::SymbolInformation* symbolInfo;
+
+ /*!
+ * This method creates list of taken/not taken values
+ * for branches
+ *
+ * @param[in] taken used to return taken counts list
+ * @param[in] notTaken used to return not taken counts list
+ */
+ bool processBranches(
+ std::list<uint64_t> * taken ,
+ std::list<uint64_t> * notTaken
+ );
+ };
+
+}
+#endif
diff -u /dev/null rtems-testing/covoar/GcovFunctionData.cc:1.1
--- /dev/null Fri Dec 2 01:31:48 2011
+++ rtems-testing/covoar/GcovFunctionData.cc Thu Dec 1 14:24:47 2011
@@ -0,0 +1,595 @@
+/*
+ * $Id$
+ */
+
+/*! @file GcovFunctionData.cc
+ * @brief GcovFunctionData Implementation
+ *
+ * This file contains the implementation of the class storing information
+ * about single function.
+ */
+
+#include <stdio.h>
+#include <string.h>
+//#include <stdlib.h>
+//#include <sys/stat.h>
+
+#include "app_common.h"
+#include "GcovFunctionData.h"
+#include "ObjdumpProcessor.h"
+#include "CoverageMapBase.h"
+//#include "ExecutableInfo.h"
+//#include "CoverageMap.h"
+//#include "qemu-traces.h"
+
+
+namespace Gcov {
+
+ GcovFunctionData::GcovFunctionData()
+ {
+ numberOfArcs = 0;
+ numberOfBlocks = 0;
+ coverageMap = NULL;
+ }
+
+ GcovFunctionData::~GcovFunctionData()
+ {
+ }
+
+ void GcovFunctionData::setChecksum( const uint32_t chk )
+ {
+ checksum = chk;
+ }
+
+ void GcovFunctionData::setId( const uint32_t idNumber )
+ {
+ id = idNumber;
+ }
+
+
+ void GcovFunctionData::setFirstLineNumber( const uint32_t lineNo )
+ {
+ firstLineNumber = lineNo;
+ }
+
+ bool GcovFunctionData::setFunctionName( const char* fcnName )
+ {
+ std::string symbolName;
+
+ symbolName = fcnName;
+
+ if ( strlen(fcnName) >= FUNCTION_NAME_LENGTH ) {
+ fprintf( stderr,
+ "ERROR: Function name is to long to be correctly stored: %u\n",
+ strlen(fcnName)
+ );
+ return false;
+ }
+
+ strcpy (functionName, fcnName);
+
+ // Tie function to its coverage map
+ symbolInfo = SymbolsToAnalyze->find( symbolName );
+ if ( symbolInfo != NULL )
+ coverageMap = symbolInfo->unifiedCoverageMap;
+
+ //if ( coverageMap == NULL)
+ // fprintf( stderr, "ERROR: Could not find coverage map for: %s\n", symbolName.c_str() );
+ //else
+ // fprintf( stderr, "SUCCESS: Hound coverage map for: %s\n", symbolName.c_str() );
+
+ return true;
+ }
+
+ bool GcovFunctionData::setFileName( const char* fileName ) {
+ if ( strlen(fileName) >= FILE_NAME_LENGTH ){
+ fprintf( stderr,
+ "ERROR: File name is to long to be correctly stored: %u\n",
+ strlen(fileName)
+ );
+ return false;
+ }
+ strcpy (sourceFileName, fileName);
+ return true;
+ }
+
+ arcs_t GcovFunctionData::getArcs() const
+ {
+ return arcs;
+ }
+
+ uint32_t GcovFunctionData::getChecksum() const
+ {
+ return checksum;
+ }
+
+ uint32_t GcovFunctionData::getId() const
+ {
+ return id;
+ }
+
+ void GcovFunctionData::getCounters(
+ uint64_t* counterValues,
+ uint32_t &countersFound,
+ uint64_t &countersSum,
+ uint64_t &countersMax
+ )
+ {
+ arcs_iterator_t currentArc;
+ int i;
+
+ countersFound = 0;
+ countersSum = 0;
+ countersMax = 0;
+
+ // Locate relevant counters and copy their values
+ i = 0;
+ for(
+ currentArc = arcs.begin();
+ currentArc != arcs.end();
+ currentArc++
+ )
+ {
+ if ( currentArc->flags == 0 || currentArc->flags == 2 || currentArc->flags == 4 ) {
+ countersFound++;
+ countersSum += currentArc->counter;
+ counterValues[i] = currentArc->counter;
+ if ( countersMax <= currentArc->counter)
+ countersMax = currentArc->counter;
+ i++;
+ }
+ }
+ }
+
+ blocks_t GcovFunctionData::getBlocks() const
+ {
+ return blocks;
+ }
+
+ void GcovFunctionData::addArc(
+ uint32_t source,
+ uint32_t destination,
+ uint32_t flags
+ )
+ {
+ gcov_arc_info arc;
+
+ numberOfArcs++;
+ arc.sourceBlock = source;
+ arc.destinationBlock = destination;
+ arc.flags = flags;
+ arc.counter = 0;
+ arcs.push_back(arc);
+ }
+
+ void GcovFunctionData::addBlock(
+ const uint32_t id,
+ const uint32_t flags,
+ const char * sourceFileName
+ )
+ {
+ gcov_block_info block;
+ numberOfBlocks++;
+ block.id = id;
+ block.flags = flags;
+ block.numberOfLines = 0;
+ block.counter = 0;
+ strcpy (block.sourceFileName, sourceFileName);
+ blocks.push_back(block);
+ }
+
+ void GcovFunctionData::printFunctionInfo( FILE * textFile,
+ uint32_t function_number
+ )
+ {
+ blocks_iterator_t currentBlock;
+ arcs_iterator_t currentArc;
+
+ fprintf(
+ textFile,
+ "\n\n=========================="
+ "FUNCTION %3d "
+ "==========================\n\n",
+ function_number
+ );
+ fprintf(
+ textFile,
+ "Name: %s\n"
+ "File: %s\n"
+ "Line: %u\n"
+ "Id: %u\n"
+ "Checksum: 0x%x\n\n",
+ functionName,
+ sourceFileName,
+ firstLineNumber,
+ id,
+ checksum
+ );
+
+ // Print arcs info
+ for (
+ currentArc = arcs.begin();
+ currentArc != arcs.end();
+ currentArc++
+ )
+ {
+ printArcInfo( textFile, currentArc );
+ }
+ fprintf( textFile, "\n");
+
+ // Print blocks info
+ for (
+ currentBlock = blocks.begin();
+ currentBlock != blocks.end();
+ currentBlock++
+ )
+ {
+ printBlockInfo( textFile, currentBlock );
+ }
+ }
+
+ void GcovFunctionData::printCoverageInfo( FILE * textFile,
+ uint32_t function_number
+ )
+ {
+ uint32_t baseAddress = 0;
+ uint32_t baseSize;
+ uint32_t currentAddress;
+ std::list<Coverage::ObjdumpProcessor::objdumpLine_t>::iterator instruction;
+
+ if ( coverageMap != NULL ) {
+
+ for (instruction = symbolInfo->instructions.begin(); instruction != symbolInfo->instructions.end(); instruction++)
+ if( instruction->isInstruction ) {
+ baseAddress = instruction->address;
+ break;
+ }
+ baseSize = coverageMap->getSize();
+
+ fprintf( textFile,
+ "\nInstructions (Base address: 0x%08x, Size: %4u): \n\n",
+ baseAddress,
+ baseSize
+ );
+ for (
+ instruction = symbolInfo->instructions.begin();
+ instruction != symbolInfo->instructions.end();
+ instruction++
+ )
+ {
+ if ( instruction->isInstruction ) {
+ currentAddress = instruction->address - baseAddress;
+ fprintf( textFile, "0x%-70s ", instruction->line.c_str() );
+ fprintf( textFile, "| 0x%08x ", currentAddress );
+ fprintf( textFile, "*");
+ fprintf( textFile,
+ "| exec: %4u ",
+ coverageMap->getWasExecuted( currentAddress )
+ );
+ fprintf( textFile, "| taken/not: %4u/%4u ",
+ coverageMap->getWasTaken( currentAddress ),
+ coverageMap->getWasNotTaken( currentAddress )
+ );
+
+ if ( instruction->isBranch )
+ fprintf( textFile, "| Branch " );
+ else
+ fprintf( textFile, " " );
+
+ if ( instruction->isNop )
+ fprintf( textFile, "| NOP(%3u) \n", instruction->nopSize );
+ else
+ fprintf( textFile, " \n" );
+ }
+ }
+ }
+ }
+
+ void GcovFunctionData::setBlockFileName(
+ const blocks_iterator_t block,
+ const char *fileName
+ )
+ {
+ strcpy(block->sourceFileName, fileName);
+ }
+
+ void GcovFunctionData::addBlockLine(
+ const blocks_iterator_t block,
+ const uint32_t line
+ )
+ {
+ block->lines.push_back(line);
+ (block->numberOfLines)++;
+ }
+
+ blocks_iterator_t GcovFunctionData::findBlockById(
+ const uint32_t id
+ )
+ {
+ blocks_iterator_t blockIterator;
+ if ( !blocks.empty() ){
+ blockIterator = blocks.begin();
+ while ( blockIterator != blocks.end( ) ){
+ if ( blockIterator->id == id)
+ break;
+ blockIterator++;
+ }
+ }
+ else
+ fprintf( stderr,
+ "ERROR: GcovFunctionData::findBlockById() failed,"
+ "no blocks present\n"
+ );
+ return blockIterator;
+ }
+
+ void GcovFunctionData::printArcInfo(
+ FILE * textFile, arcs_iterator_t arc
+ )
+ {
+ fprintf( textFile,
+ " > ARC %3u -> %3u ",
+ arc->sourceBlock,
+ arc->destinationBlock
+ );
+
+ fprintf( textFile, "\tFLAGS: ");
+ switch ( arc->flags ){
+ case 0:
+ fprintf( textFile, "( ___________ ____ _______ )");
+ break;
+ case 1:
+ fprintf( textFile, "( ___________ ____ ON_TREE )");
+ break;
+ case 2:
+ fprintf( textFile, "( ___________ FAKE _______ )");
+ break;
+ case 3:
+ fprintf( textFile, "( ___________ FAKE ON_TREE )");
+ break;
+ case 4:
+ fprintf( textFile, "( FALLTHROUGH ____ _______ )");
+ break;
+ case 5:
+ fprintf( textFile, "( FALLTHROUGH ____ ON_TREE )");
+ break;
+ default:
+ fprintf( textFile, "( =======FLAGS_ERROR====== )");
+ fprintf( stderr,
+ " ERROR: Unknown arc flag: 0x%x\n",
+ arcs.back().flags
+ );
+ break;
+ }
+ fprintf( textFile, "\tTaken: %5llu\n", arc->counter );
+ }
+
+ void GcovFunctionData::printBlockInfo(
+ FILE * textFile,
+ blocks_iterator_t block )
+ {
+ std::list<uint32_t>::iterator line;
+
+ fprintf( textFile,
+ " > BLOCK %3u from %s\n"
+ " -counter: %5llu\n"
+ " -flags: 0x%x\n"
+ " -lines: ",
+ block->id,
+ block->sourceFileName,
+ block->counter,
+ block->flags
+ );
+ if ( !block->lines.empty( ) )
+ for ( line = block->lines.begin() ; line != block->lines.end(); line++ )
+ fprintf ( textFile, "%u, ", *line);
+ fprintf ( textFile, "\n");
+ }
+
+ bool GcovFunctionData::processFunctionCounters( void ) {
+
+ uint32_t baseAddress = 0;
+ uint32_t currentAddress = 0;
+ std::list<Coverage::ObjdumpProcessor::objdumpLine_t>::iterator instruction;
+ blocks_iterator_t blockIterator;
+ blocks_iterator_t blockIterator2;
+ arcs_iterator_t arcIterator;
+ arcs_iterator_t arcIterator2;
+ std::list<uint64_t> taken; // List of taken counts for branches
+ std::list<uint64_t> notTaken; // List of not taken counts for branches
+
+ //fprintf( stderr, "DEBUG: Processing counters for file: %s\n", sourceFileName );
+ if ( blocks.empty() || arcs.empty() || coverageMap == NULL || symbolInfo->instructions.empty())
+ {
+ //fprintf( stderr,
+ // "DEBUG: sanity check returned false for function: %s from file: %s\n",
+ // functionName,
+ // sourceFileName
+ //);
+ return false;
+ }
+
+ // Reset iterators and variables
+ blockIterator = blocks.begin();
+ arcIterator = arcs.begin();
+ arcIterator2 = arcIterator;
+ arcIterator2++;
+ instruction = symbolInfo->instructions.begin();
+ baseAddress = coverageMap->getFirstLowAddress(); //symbolInfo->baseAddress;
+ currentAddress = baseAddress;
+
+ // Find taken/not taken values for branches
+ if ( !processBranches( &taken , ¬Taken ) )
+ {
+ //fprintf( stderr,
+ // "ERROR: Failed to process branches for function: %s from file: %s\n",
+ // functionName,
+ // sourceFileName
+ //);
+ return false;
+ };
+
+ // Process the branching arcs
+ while ( blockIterator != blocks.end() ) {
+ //fprintf( stderr, "DEBUG: Processing branches\n" );
+ while ( arcIterator->sourceBlock != blockIterator->id ) {
+ if ( arcIterator == arcs.end() ) {
+ //fprintf( stderr, "ERROR: Unexpectedly runned out of arcs to analyze\n" );
+ return false;
+ }
+ arcIterator++;
+ arcIterator2++;
+ }
+
+ // If no more branches break;
+ if ( arcIterator2 == arcs.end() )
+ break;
+
+ // If this is a branch without FAKE arcs process it
+ if (
+ (arcIterator->sourceBlock == arcIterator2->sourceBlock ) &&
+ !( arcIterator->flags & FAKE_ARC_FLAG ) &&
+ !( arcIterator2->flags & FAKE_ARC_FLAG )
+ )
+ {
+ if ( taken.empty() || notTaken.empty() ) {
+ fprintf( stderr,
+ "ERROR: Branchess missing for function: %s from file: %s\n",
+ functionName,
+ sourceFileName
+ );
+ return false;
+ }
+ //fprintf( stderr, "DEBUG: Found true branching arc %3u -> %3u\n", arcIterator->sourceBlock, arcIterator->destinationBlock );
+ if ( arcIterator->flags & FALLTHROUGH_ARC_FLAG ) {
+ arcIterator->counter = notTaken.front();
+ notTaken.pop_front();
+ arcIterator2->counter = taken.front();
+ taken.pop_front();
+ }
+ else {
+ arcIterator2->counter = notTaken.front();
+ notTaken.pop_front();
+ arcIterator->counter = taken.front();
+ taken.pop_front();
+ }
+
+ blockIterator2 = blocks.begin();
+ //TODO: ADD FAILSAFE
+ while ( arcIterator->destinationBlock != blockIterator2->id)
+ blockIterator2++;
+ blockIterator2->counter += arcIterator->counter;
+
+ blockIterator2 = blocks.begin();
+ //TODO: ADD FAILSAFE
+ while ( arcIterator2->destinationBlock != blockIterator2->id)
+ blockIterator2++;
+ blockIterator2->counter += arcIterator2->counter;
+ }
+ blockIterator++;
+ }
+
+
+ // Reset iterators and variables
+ blockIterator = blocks.begin();
+ arcIterator = arcs.begin();
+ arcIterator2 = arcIterator;
+ arcIterator2++;
+
+ // Set the first block
+ blockIterator->counter = coverageMap->getWasExecuted( currentAddress );
+
+ // Analyze remaining arcs and blocks
+ while ( blockIterator != blocks.end() ) {
+ while ( arcIterator->sourceBlock != blockIterator->id ) {
+ if ( arcIterator == arcs.end() ) {
+ fprintf( stderr, "ERROR: Unexpectedly runned out of arcs to analyze\n" );
+ return false;
+ }
+ arcIterator++;
+ arcIterator2++;
+ }
+
+ // If this is the last arc, propagate counter and exit
+ if ( arcIterator2 == arcs.end() ) {
+ //fprintf( stderr,
+ // "DEBUG: Found last arc %3u -> %3u\n",
+ // arcIterator->sourceBlock,
+ // arcIterator->destinationBlock
+ //);
+ arcIterator->counter = blockIterator->counter;
+ blockIterator2 = blocks.begin();
+ while ( arcIterator->destinationBlock != blockIterator2->id) //TODO: ADD FAILSAFE
+ blockIterator2++;
+ blockIterator2->counter += arcIterator->counter;
+ return true;
+ }
+
+ // If this is not a branch, propagate counter and continue
+ if ( arcIterator->sourceBlock != arcIterator2->sourceBlock ) {
+ //fprintf( stderr, "DEBUG: Found simple arc %3u -> %3u\n", arcIterator->sourceBlock, arcIterator->destinationBlock );
+ arcIterator->counter = blockIterator->counter;
+ blockIterator2 = blocks.begin();;
+ while ( arcIterator->destinationBlock != blockIterator2->id) //TODO: ADD FAILSAFE
+ blockIterator2++;
+ blockIterator2->counter += arcIterator->counter;
+ }
+
+ // If this is a branch with FAKE arc
+ else if ( (arcIterator->sourceBlock == arcIterator2->sourceBlock ) && ( arcIterator2->flags & FAKE_ARC_FLAG ))
+ {
+ //fprintf( stderr, "DEBUG: Found fake branching arc %3u -> %3u\n", arcIterator->sourceBlock, arcIterator->destinationBlock );
+ arcIterator->counter = blockIterator->counter;
+ blockIterator2 = blocks.begin();
+ while ( arcIterator->destinationBlock != blockIterator2->id) //TODO: ADD FAILSAFE
+ blockIterator2++;
+ blockIterator2->counter += arcIterator->counter;
+ }
+
+ // If this is a legitimate branch
+ blockIterator++;
+ }
+
+ return true;
+ }
+
+ bool GcovFunctionData::processBranches(
+ std::list<uint64_t> * taken ,
+ std::list<uint64_t> * notTaken
+ )
+ {
+ uint32_t baseAddress = 0;
+ uint32_t currentAddress;
+ std::list<Coverage::ObjdumpProcessor::objdumpLine_t>::iterator instruction;
+
+ if ( coverageMap == NULL )
+ return false;
+
+ //baseAddress = coverageMap->getFirstLowAddress(); //symbolInfo->baseAddress;
+ for (instruction = symbolInfo->instructions.begin(); instruction != symbolInfo->instructions.end(); instruction++)
+ if( instruction->isInstruction ) {
+ baseAddress = instruction->address;
+ break;
+ }
+
+ //fprintf( stderr, "DEBUG: Processing instructions in search of branches\n" );
+ for (instruction = symbolInfo->instructions.begin(); instruction != symbolInfo->instructions.end(); instruction++)
+ {
+ if ( instruction->isInstruction) {
+ currentAddress = instruction-> address - baseAddress;
+ if ( instruction->isBranch ) {
+ taken->push_back ( (uint64_t) coverageMap->getWasTaken( currentAddress ) );
+ notTaken->push_back ( (uint64_t) coverageMap->getWasNotTaken( currentAddress ) );
+ //fprintf( stderr,
+ // "Added branch to list taken/not: %4u/%4u\n",
+ // coverageMap->getWasTaken( currentAddress ),
+ // coverageMap->getWasNotTaken( currentAddress )
+ //);
+ }
+ }
+ }
+ return true;
+ }
+}
+
+
diff -u rtems-testing/covoar/Makefile:1.3 rtems-testing/covoar/Makefile:1.4
--- rtems-testing/covoar/Makefile:1.3 Fri Jun 18 11:13:00 2010
+++ rtems-testing/covoar/Makefile Thu Dec 1 14:24:47 2011
@@ -24,6 +24,8 @@
DesiredSymbols.o \
ExecutableInfo.o \
Explanations.o \
+ GcovData.o \
+ GcovFunctionData.o \
ObjdumpProcessor.o \
ReportsBase.o \
ReportsText.o \
@@ -125,6 +127,8 @@
ExecutableInfo.o: ExecutableInfo.cc ExecutableInfo.h CoverageMap.h \
DesiredSymbols.h SymbolTable.h
Explanations.o: Explanations.cc Explanations.h
+GcovData.o: GcovData.h GcovData.cc
+GcovFunctionData.o: GcovFunctionData.h GcovFunctionData.cc
ObjdumpProcessor.o: ObjdumpProcessor.cc ObjdumpProcessor.h ExecutableInfo.h \
TargetBase.h TargetFactory.h
ReportsBase.o: ReportsBase.cc ReportsBase.h CoverageRanges.h DesiredSymbols.h \
diff -u rtems-testing/covoar/SymbolTable.h:1.2 rtems-testing/covoar/SymbolTable.h:1.3
--- rtems-testing/covoar/SymbolTable.h:1.2 Tue Jan 25 15:26:00 2011
+++ rtems-testing/covoar/SymbolTable.h Thu Dec 1 14:24:47 2011
@@ -37,6 +37,7 @@
} symbolInfo_t;
typedef std::list< symbolInfo_t > symbolInfo;
+ typedef std::list< symbolInfo_t >::iterator symbolInfoIterator_t;
@@ -98,6 +99,12 @@
uint32_t address
);
+ /*!
+ * This method prints SymbolTable content to stdout
+ *
+ */
+ void dumpSymbolTable( void );
+
private:
/*!
@@ -117,6 +124,7 @@
* the symbol's information.
*/
typedef std::map<std::string, symbolInfo> info_t;
+ typedef std::map<std::string, symbolInfo>::iterator infoIterator_t;
info_t info;
};
diff -u rtems-testing/covoar/SymbolTable.cc:1.2 rtems-testing/covoar/SymbolTable.cc:1.3
--- rtems-testing/covoar/SymbolTable.cc:1.2 Tue Jan 25 15:26:00 2011
+++ rtems-testing/covoar/SymbolTable.cc Thu Dec 1 14:24:47 2011
@@ -104,4 +104,19 @@
return "";
}
+ void SymbolTable::dumpSymbolTable( void )
+ {
+ symbolInfo symbolTable;
+ symbolInfoIterator_t symbolIterator;
+ infoIterator_t infoIterator;
+
+ for (infoIterator = info.begin() ; infoIterator != info.end(); infoIterator++)
+ {
+ for (symbolIterator = infoIterator->second.begin() ; symbolIterator != infoIterator->second.end(); symbolIterator++)
+ {
+ fprintf( stdout, "%s:\tStarting address = %#x\tLength = %u\n", infoIterator->first.c_str(), symbolIterator->startingAddress, symbolIterator->length );
+ }
+ }
+ }
+
}
diff -u rtems-testing/covoar/covoar.cc:1.5 rtems-testing/covoar/covoar.cc:1.6
--- rtems-testing/covoar/covoar.cc:1.5 Fri Nov 4 11:02:36 2011
+++ rtems-testing/covoar/covoar.cc Thu Dec 1 14:24:47 2011
@@ -25,6 +25,7 @@
#include "ObjdumpProcessor.h"
#include "ReportsBase.h"
#include "TargetFactory.h"
+#include "GcovData.h"
/*
* Variables to control general behavior
@@ -41,8 +42,14 @@
const char* explanations = NULL;
char* progname;
const char* symbolsFile = NULL;
+const char* gcnosFileName = NULL;
+char gcnoFileName[FILE_NAME_LENGTH];
+char gcdaFileName[FILE_NAME_LENGTH];
+char gcovBashCommand[256];
const char* target = NULL;
const char* format = NULL;
+FILE* gcnosFile = NULL;
+Gcov::GcovData* gcovFile;
/*
* Print program usage message
@@ -64,6 +71,7 @@
" -1 EXECUTABLE - name of executable to get symbols from\n"
" -e EXE_EXTENSION - extension of the executables to analyze\n"
" -c COVERAGEFILE_EXTENSION - extension of the coverage files to analyze\n"
+ " -g GCNOS_LIST - name of file with list of *.gcno files\n"
" -p PROJECT_NAME - name of the project\n"
" -C ConfigurationFileName - name of configuration file\n"
" -O Output_Directory - name of output directory (default=."
@@ -88,6 +96,7 @@
{ "outputDirectory", NULL },
{ "executableExtension", NULL },
{ "coverageExtension", NULL },
+ { "gcnosFile", NULL },
{ "target", NULL },
{ "verbose", NULL },
{ "projectName", NULL },
@@ -127,6 +136,7 @@
GET_STRING( "outputDirectory", outputDirectory );
GET_STRING( "executableExtension", executableExtension );
GET_STRING( "coverageExtension", coverageFileExtension );
+ GET_STRING( "gcnosFile", gcnosFileName );
GET_STRING( "projectName", projectName );
// Now calculate some values
@@ -160,13 +170,14 @@
//
progname = argv[0];
- while ((opt = getopt(argc, argv, "C:1:L:e:c:E:f:s:T:O:p:v")) != -1) {
+ while ((opt = getopt(argc, argv, "C:1:L:e:c:g: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 'g': gcnosFileName = optarg; break;
case 'E': explanations = optarg; break;
case 'f': format = optarg; break;
case 's': symbolsFile = optarg; break;
@@ -348,7 +359,7 @@
SymbolsToAnalyze->load( symbolsFile );
if (Verbose)
fprintf(
- stderr, "Analyzing %ld symbols\n", SymbolsToAnalyze->set.size()
+ stderr, "Analyzing %u symbols\n", SymbolsToAnalyze->set.size()
);
// Create explanations.
@@ -412,6 +423,9 @@
// Merge each symbols coverage map into a unified coverage map.
(*eitr)->mergeCoverage();
+ // DEBUG Print ExecutableInfo content
+ //(*eitr)->dumpExecutableInfo();
+
if (!singleExecutable)
eitr++;
}
@@ -421,6 +435,37 @@
fprintf( stderr, "Preprocess uncovered ranges and branches\n" );
SymbolsToAnalyze->preprocess();
+ //
+ // Generate Gcov reports
+ //
+ if (Verbose)
+ fprintf( stderr, "Generating Gcov reports...\n");
+ gcnosFile = fopen ( gcnosFileName , "r" );
+
+ if ( !gcnosFile ) {
+ fprintf( stderr, "Unable to open %s\n", gcnosFileName );
+ }
+ else {
+ while ( fscanf( gcnosFile, "%s", inputBuffer ) != EOF) {
+ gcovFile = new Gcov::GcovData();
+ strcpy( gcnoFileName, inputBuffer );
+
+ if ( Verbose )
+ fprintf( stderr, "Processing file: %s\n", gcnoFileName );
+
+ if ( gcovFile->readGcnoFile( gcnoFileName ) ) {
+ // Those need to be in this order
+ gcovFile->processCounters();
+ gcovFile->writeReportFile();
+ gcovFile->writeGcdaFile();
+ gcovFile->writeGcovFile();
+ }
+
+ delete gcovFile;
+ }
+ fclose( gcnosFile );
+ }
+
// Determine the uncovered ranges and branches.
if (Verbose)
fprintf( stderr, "Computing uncovered ranges and branches\n" );
*joel*:
2011-12-01 Pawel Zagorski <pzagor at agh.edu.pl>
* do_coverage, rtems_config.in: Add GNU coverage support.
M 1.312 rtems-coverage/ChangeLog
M 1.79 rtems-coverage/do_coverage
M 1.3 rtems-coverage/rtems_config.in
diff -u rtems-testing/rtems-coverage/ChangeLog:1.311 rtems-testing/rtems-coverage/ChangeLog:1.312
--- rtems-testing/rtems-coverage/ChangeLog:1.311 Mon Nov 28 09:02:20 2011
+++ rtems-testing/rtems-coverage/ChangeLog Thu Dec 1 14:28:13 2011
@@ -1,3 +1,7 @@
+2011-12-01 Pawel Zagorski <pzagor at agh.edu.pl>
+
+ * do_coverage, rtems_config.in: Add GNU coverage support.
+
2011-11-28 Aleksejs Popovs <me at popoffka.ru>
* generate_coverage_html, style.css: Google Code-In 2011 task to make
diff -u rtems-testing/rtems-coverage/do_coverage:1.78 rtems-testing/rtems-coverage/do_coverage:1.79
--- rtems-testing/rtems-coverage/do_coverage:1.78 Fri Nov 4 14:29:01 2011
+++ rtems-testing/rtems-coverage/do_coverage Thu Dec 1 14:28:13 2011
@@ -39,6 +39,7 @@
-L -- do not link files to test execution point (default=link)
-r -- run the tests (default=no)
-R -- generate reports (default=no)
+ -g -- generate GCOV reports (default=no)
-f -- publish the results to ftp site (default=no)
-t -- save the results locally (default=no)
-O -- output directory (default=BSP-CONF-YYYYMMDD-HHMM)
@@ -81,6 +82,7 @@
# parse arguments for these
verbose="no"
+do_all="no"
do_posix="yes"
do_optimize_size="no"
do_covoar="no"
@@ -90,6 +92,7 @@
do_copy_tests="no"
do_link_tests="yes"
do_run_tests="no"
+do_generate_gcov="no"
do_reports="no"
do_publish="no"
do_save_tarballs="yes"
@@ -98,10 +101,11 @@
outputDir=""
BSP="not_set"
-while getopts vB:PSmAucbCLrRftO:dD OPT
+while getopts vB:PSmAucbCLrgRftO:dD OPT
do
case "$OPT" in
A)
+ do_all="yes"
do_covoar="yes"
do_posix="yes"
do_rtems_update="yes"
@@ -125,6 +129,7 @@
C) do_copy_tests=`toggle ${do_copy_tests}` ;;
L) do_link_tests=`toggle ${do_link_tests}` ;;
r) do_run_tests=`toggle ${do_run_tests}` ;;
+ g) do_generate_gcov=`toggle ${do_generate_gcov}` ;;
R) do_reports=`toggle ${do_reports}` ;;
f) do_publish=`toggle ${do_publish}` ;;
t) do_save_tarballs=`toggle ${do_save_tarballs}` ;;
@@ -221,6 +226,7 @@
echo "POSIX Enabled: " ${do_posix}
echo "Core Configuration " ${do_core}
echo "Developmental Code: " ${do_developmental}
+ echo "do_all: " ${do_all}
echo "do_covoar " ${do_covoar}
echo "do_rtems_update: " ${do_rtems_update}
echo "do_rtems_configure: " ${do_rtems_configure}
@@ -228,6 +234,7 @@
echo "do_copy_tests: " ${do_copy_tests}
echo "do_link_tests: " ${do_link_tests}
echo "do_run_tests: " ${do_run_tests}
+ echo "do_generate_gcov: " ${do_generate_gcov}
echo "do_reports: " ${do_reports}
echo "do_publish: " ${do_publish}
echo "do_save_tarballs: " ${do_save_tarballs}
@@ -283,7 +290,7 @@
fi
fi
-grep "^CFLAGS_OPTIMIZE_V.*=.*-O[s01234]" ${custom} >/dev/null
+grep "^CFLAGS_OPTIMIZE_V.*=.*-O[s01234].*" ${custom} >/dev/null
if [ $? -ne 0 ] ; then
echo "Unable to find CFLAGS_OPTIMIZE_V in ${custom}"
exit 1
@@ -386,6 +393,7 @@
-e "s, at OUTPUT_DIRECTORY@,${results_dir}," \
-e "s/@EXECUTABLE_EXTENSION@/exe/" \
-e "s/@COVERAGE_EXTENSION@/${RTEMSEXT}.${COVEXT}/" \
+ -e "s, at GCNOS_LIST@,${rtems_gcnos_file}," \
-e "s/@PROJECT_NAME@/RTEMS ${RTEMS_VERSION}/" \
<${COVBASE}/rtems_config.in \
>${BASEDIR}/${BSP}-tests/config
@@ -418,7 +426,7 @@
RTEMSLIB=${BASEDIR}/b-${BSP}/${TARGET}/${BSP}/lib/librtemscpu.a
if [ -r ${RTEMSLIB} ] ; then
- cut -d' ' -f1 ${results_dir}/no_range_uncovered.txt | while read symbol
+ while read symbol
do
line=`${TARGET}-nm --format=sysv \
${BASEDIR}/b-${BSP}/${TARGET}/${BSP}/lib/librtemscpu.a | \
@@ -426,7 +434,7 @@
size=`echo ${line} | cut -d'|' -f5 | tr "[:lower:]" "[:upper:]"`
size=`echo 16 i ${size} p | dc`
echo "${size} ${symbol} unknown"
- done | sort -n -r \
+ done <${results_dir}/no_range_uncovered.txt | sort -n -r \
>${results_dir}/sizes_unreferenced.txt
fi
@@ -602,7 +610,15 @@
# If requested, configure RTEMS
if [ ${do_rtems_configure} = "yes" ] ; then
# Now let's patch the make/custom file
- sed -e "s/-O[0123s]/${c_opt}/" <${custom} >${custom}.tmp
+ cat ${custom} |
+ sed -e '/^CFLAGS_OPTIMIZE_V.*=.*-ftest-coverage -finline-functions -g/d' \
+ -e "s/-O[0123s]/${c_opt}/" |
+ if [ ${do_generate_gcov} = "yes" ] ; then
+ sed -e \
+ '/^CFLAGS_OPTIMIZE_V/a CFLAGS_OPTIMIZE_V += -ftest-coverage -finline-functions -g'
+ else
+ cat
+ fi >${custom}.tmp
mv ${custom}.tmp ${custom}
echo "Configuring RTEMS..."
@@ -694,6 +710,22 @@
echo "Skipping copying tests..."
fi
+# If requested prepare data to create gcov reports
+if [ ${do_generate_gcov} = "yes" ] ; then
+ echo "Preparing data for gcov reports..."
+
+ cd ${BASEDIR}/b-${BSP}/
+ check_status $? "cd b-${BSP}"
+
+ rtems_gcnos_file="${BASEDIR}/${BSP}-tests/rtems.gcnos"
+ find `pwd` -name \*.gcno >${rtems_gcnos_file}
+
+ check_status $? "Preparing data for gcov reports for for ${BSP}"
+else
+ rtems_gcnos_file="/dev/null"
+ echo "Skipping creating gcov reports ..."
+fi
+
# If requested, run the tests with coverage reporting enabled
if [ ${do_run_tests} = "yes" ] ; then
echo "Running tests..."
diff -u rtems-testing/rtems-coverage/rtems_config.in:1.2 rtems-testing/rtems-coverage/rtems_config.in:1.3
--- rtems-testing/rtems-coverage/rtems_config.in:1.2 Fri May 21 15:14:30 2010
+++ rtems-testing/rtems-coverage/rtems_config.in Thu Dec 1 14:28:14 2011
@@ -22,6 +22,9 @@
# This is the extension on the coverage/trace files.
coverageExtension = @COVERAGE_EXTENSION@
+# This is the path to file containing *.gcno list
+gcnosFile = @GCNOS_LIST@
+
# This is the extension on the executable files.
executableExtension = @EXECUTABLE_EXTENSION@
--
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/20111202/e0241218/attachment.html>
More information about the vc
mailing list