source: rtems-testing/covoar/TraceReaderLogQEMU.cc @ e7bb58a

4.11
Last change on this file since e7bb58a was e7bb58a, checked in by Jennifer Averett <Jennifer.Averett@…>, on May 25, 2010 at 7:14:48 PM

2010-05-25 Jennifer Averett <Jennifer.Averett@…>

  • DesiredSymbols?.cc, Explanations.cc, ObjdumpProcessor?.cc, TraceReaderLogQEMU.cc, app_common.cc, app_common.h: Added a inputBuffer to app_common and modified all fgets calls to use this buffer. This will allow for a size increase if necessary.
  • Property mode set to 100644
File size: 4.1 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    QEMU_LOG_IN_Block_t first         = { 0, "", "" };
55    QEMU_LOG_IN_Block_t last          = { 0, "", "" };
56    QEMU_LOG_IN_Block_t nextExecuted  = { 0, "", "" };
57    uint32_t            nextlogical;
58    struct STAT         statbuf;
59    int                 status;
60    FILE*               logFile;
61    int                 result;
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    fgets(inputBuffer, MAX_LINE_LENGTH, logFile );
108    result = sscanf( 
109      inputBuffer, 
110      "0x%08lx: %s %s\n", 
111      &first.address, 
112      first.instruction, 
113      first.data
114    );
115    if ( result < 2 ) 
116    {
117      fprintf(stderr, "Error Unable to Read Initial First Block\n" );
118      done = true;
119    }
120
121    while (!done) {
122
123      last = first;
124   
125      // Read until we get to the last instruction in the block.
126      do {
127        fgets(inputBuffer, MAX_LINE_LENGTH, logFile );
128        result = sscanf( 
129          inputBuffer, 
130          "0x%08lx: %s %s\n", 
131          &last.address, 
132          last.instruction, 
133          last.data
134        );
135      } while( result > 1);
136
137      nextlogical = objdumpProcessor->getAddressAfter(last.address);
138
139      if (! ReadUntilFound( logFile, QEMU_LOG_IN_KEY )) {
140        done = true;
141        nextExecuted = last;
142      } else {
143        fgets(inputBuffer, MAX_LINE_LENGTH, logFile );
144        result = sscanf( 
145          inputBuffer, 
146          "0x%08lx: %s %s\n", 
147          &nextExecuted.address, 
148          nextExecuted.instruction, 
149          nextExecuted.data
150        );
151        if ( result < 2 ) 
152        {
153          fprintf(stderr, "Error Unable to Read First Block\n" );
154        }
155      }
156
157      // If the nextlogical was not found we are throwing away
158      // the block; otherwise add the block to the trace list.
159      if (nextlogical != 0) {
160        TraceList::exitReason_t reason = TraceList::EXIT_REASON_OTHER;
161
162        if ( objdumpProcessor->IsBranch( last.instruction ) ) {
163          if ( nextExecuted.address == nextlogical ) {
164            reason = TraceList::EXIT_REASON_BRANCH_NOT_TAKEN;
165          }  else {
166            reason = TraceList::EXIT_REASON_BRANCH_TAKEN;
167          }
168        }
169        Trace.add( first.address, nextlogical, reason );
170      }
171      first = nextExecuted;
172    } 
173    fclose( logFile );
174    return true;
175  }
176}
Note: See TracBrowser for help on using the repository browser.