summaryrefslogtreecommitdiffstats
path: root/tester/covoar/CoverageReaderQEMU.cc
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2014-05-09 21:50:37 +1000
committerChris Johns <chrisj@rtems.org>2014-06-18 16:48:08 +1200
commit100f517ab37265acdf067e36b6860020ec8b2184 (patch)
tree2316c8b888e11dcbcfbfc66a0c1e31991ea20656 /tester/covoar/CoverageReaderQEMU.cc
parent4.11: Add ntp patch. (diff)
downloadrtems-tools-100f517ab37265acdf067e36b6860020ec8b2184.tar.bz2
covoar: Merger the covoar source from rtems-testing.git.
Use waf to build covoar.
Diffstat (limited to 'tester/covoar/CoverageReaderQEMU.cc')
-rw-r--r--tester/covoar/CoverageReaderQEMU.cc169
1 files changed, 169 insertions, 0 deletions
diff --git a/tester/covoar/CoverageReaderQEMU.cc b/tester/covoar/CoverageReaderQEMU.cc
new file mode 100644
index 0000000..8e34f8f
--- /dev/null
+++ b/tester/covoar/CoverageReaderQEMU.cc
@@ -0,0 +1,169 @@
+/*! @file CoverageReaderQEMU.cc
+ * @brief CoverageReaderQEMU Implementation
+ *
+ * This file contains the implementation of the functions supporting
+ * reading the QEMU coverage data files.
+ */
+
+#include "covoar-config.h"
+
+#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"
+
+#if HAVE_STAT64
+#define OPEN fopen64
+#else
+#define OPEN fopen
+#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 ) {
+ uint32_t offset_e, offset_a;
+ uint32_t a = entry->pc + entry->size - 1;
+ if ((aCoverageMap->determineOffset( a, &offset_a ) != true) ||
+ (aCoverageMap->determineOffset( entry->pc, &offset_e ) != true))
+ {
+ fprintf(
+ stderr,
+ "*** Trace block is inconsistent with coverage map\n"
+ "*** Trace block (0x%08x - 0x%08x) for %d bytes\n"
+ "*** Coverage map XXX \n",
+ entry->pc,
+ a,
+ entry->size
+ );
+ } else {
+ while (!aCoverageMap->isStartOfInstruction(a))
+ a--;
+ if (entry->op & taken) {
+ aCoverageMap->setWasTaken( a );
+ } else if (entry->op & notTaken) {
+ aCoverageMap->setWasNotTaken( a );
+ }
+ }
+ }
+ }
+ }
+ fclose( traceFile );
+ }
+}