source: rtems-testing/rtems-coverage/TraceReaderLogQEMU.cc @ b212961

4.11
Last change on this file since b212961 was b212961, checked in by Jennifer Averett <Jennifer.Averett@…>, on Apr 22, 2010 at 7:14:07 PM

2010-04-22 Jennifer Averett <Jennifer.Averett@…>

  • Property mode set to 100644
File size: 4.2 KB
Line 
1/*
2 *  $Id$
3 */
4
5/*! @file TraceReaderLogQEMU.cc
6 *  @brief TraceReaderLogQEMU Implementation
7 *
8 *  This file contains the implementation of the functions supporting
9 *  reading the QEMU coverage data files.
10 */
11
12#include <stdio.h>
13#include <stdlib.h>
14#include <sys/stat.h>
15#include <string.h>
16
17#include "qemu-log.h"
18
19#include "app_common.h"
20#include "TraceReaderBase.h"
21#include "TraceReaderLogQEMU.h"
22#include "TraceList.h"
23
24/* XXX really not always right */
25typedef uint32_t target_ulong;
26
27#include "qemu-traces.h"
28
29/* hack so this can compile on the RH7 RTEMS 4.5 host */
30#if (__GNUC__ <= 2)
31#define STAT stat
32#define OPEN fopen
33#else
34#define STAT stat64
35#define OPEN fopen64
36#endif
37
38
39namespace Trace {
40
41  TraceReaderLogQEMU::TraceReaderLogQEMU()
42  {
43  }
44
45  TraceReaderLogQEMU::~TraceReaderLogQEMU()
46  {
47  }
48
49  bool TraceReaderLogQEMU::processFile(
50    const char* const     file
51  )
52  {
53    bool                done          = false;
54    bool                isBranch      = false;
55    QEMU_LOG_IN_Block_t first         = { 0, "", "" };
56    QEMU_LOG_IN_Block_t last          = { 0, "", "" };
57    QEMU_LOG_IN_Block_t nextExecuted  = { 0, "", "" };
58    uint32_t            nextlogical;
59    struct STAT         statbuf;
60    int                 status;
61    FILE*               logFile;
62
63    //
64    // Verify that the log file has a non-zero size.
65    //
66    // NOTE: We prefer stat64 because some of the coverage files are HUGE!
67    status = STAT( file, &statbuf );
68    if (status == -1) {
69      fprintf( stderr, "Unable to stat %s\n", file );
70      return false;
71    }
72
73    if (statbuf.st_size == 0) {
74      fprintf( stderr, "%s is 0 bytes long\n", file );
75      return false;
76    }
77
78    //
79    // Open the coverage file and discard the header.
80    //
81    logFile = OPEN( file, "r" );
82    if (!logFile) {
83      fprintf( stderr, "Unable to open %s\n", file );
84      return false;
85    }
86
87
88    //
89    //  Discard Header section
90    //
91    if (! ReadUntilFound( logFile, QEMU_LOG_SECTION_END ) ) {
92      fprintf( stderr, "Unable to locate end of log file header\n" );
93      return false;
94    }
95
96    //
97    //  Find first IN block
98    //
99    if (! ReadUntilFound( logFile, QEMU_LOG_IN_KEY )){
100      fprintf(stderr,"Error: Unable to locate first IN: Block in Log file \n");
101      return false;
102    }
103
104    //
105    //  Read First Start Address
106    //
107    if ( 
108      fscanf( 
109        logFile, 
110        "0x%08lx: %s %s\n", 
111        &first.address, 
112        first.instruction, 
113        first.data
114      ) != 3  ) 
115    {
116      fprintf(stderr, "Error Unable to Read Initial First Block\n" );
117      done = true;
118    }
119
120    while (!done) {
121
122        last = first;
123   
124        // Read until we get to the last instruction in the block.
125        while( 
126          fscanf( 
127             logFile, 
128             "0x%08lx: %s %s\n", 
129             &last.address, 
130             last.instruction, 
131             last.data
132           ) == 3 
133        );
134
135        // If (last.instruction is a branch instruction) {
136
137        nextlogical = objdumpProcessor->getAddressAfter(last.address);
138
139        if (! ReadUntilFound( logFile, QEMU_LOG_IN_KEY )) {
140          done = true;
141        }
142        if ( 
143          fscanf( 
144            logFile, 
145            "0x%08lx: %s %s\n", 
146            &nextExecuted.address, 
147            nextExecuted.instruction, 
148            nextExecuted.data
149          ) != 3 
150        ) {
151          fprintf(stderr, "Error Unable to Read First Block\n" );
152        }
153
154
155        // If the nextlogical was not found we are throwing away
156        // the block; otherwise add the block to the trace list.
157        if (nextlogical != 0) {
158          isBranch = objdumpProcessor->IsBranch( last.instruction ); 
159
160          if (  isBranch &&
161               ( nextExecuted.address == nextlogical )) {
162            Trace.add( 
163              first.address, 
164              nextlogical, 
165              TraceList::EXIT_REASON_BRANCH_NOT_TAKEN
166            );
167          } else if (isBranch) {
168            Trace.add( 
169              first.address, 
170              nextlogical, 
171              TraceList::EXIT_REASON_BRANCH_TAKEN
172            );
173          } else
174            Trace.add(first.address, nextlogical, TraceList::EXIT_REASON_OTHER);
175        }   
176        first = nextExecuted;
177    } 
178
179    fclose( logFile );
180    return true;
181  }
182}
Note: See TracBrowser for help on using the repository browser.