source: rtems-tools/tester/covoar/TraceWriterQEMU.cc @ 0c4884a

Last change on this file since 0c4884a was 177c752, checked in by Joel Sherrill <joel@…>, on 04/11/21 at 01:08:20

TraceWriterQEMU.cc: Multiple clean ups

Change sprintf() to strncpy() to avoid buffer overwrite CID 1399603,
Switch to auto pointer for iterator.
Initialize _pad field of entry CID 1399603,
fclose file on error patch CID 1399621,

  • Property mode set to 100644
File size: 5.2 KB
Line 
1/*
2 * RTEMS Tools Project (http://www.rtems.org/)
3 * Copyright 2014 OAR Corporation
4 * All rights reserved.
5 *
6 * This file is part of the RTEMS Tools package in 'rtems-tools'.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright notice,
12 * this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright notice,
15 * this list of conditions and the following disclaimer in the documentation
16 * and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30/*! @file TraceWriterQEMU.cc
31 *  @brief TraceWriterQEMU Implementation
32 *
33 *  This file contains the implementation of the functions supporting
34 *  reading the QEMU coverage data files.
35 */
36
37#include <cstring>
38#include <cstdio>
39
40#include <iostream>
41#include <iomanip>
42
43#include <rld-process.h>
44
45#include "app_common.h"
46#include "TraceWriterQEMU.h"
47#include "ExecutableInfo.h"
48#include "CoverageMap.h"
49#include "qemu-traces.h"
50
51#if HAVE_STAT64
52#define STAT stat64
53#else
54#define STAT stat
55#endif
56
57#if HAVE_OPEN64
58#define OPEN fopen64
59#else
60#define OPEN fopen
61#endif
62
63namespace Trace {
64
65  TraceWriterQEMU::TraceWriterQEMU():
66    TraceWriterBase()
67  {
68  }
69
70  TraceWriterQEMU::~TraceWriterQEMU()
71  {
72  }
73
74  bool TraceWriterQEMU::writeFile(
75    const char* const          file,
76    Trace::TraceReaderBase    *log
77  )
78  {
79    struct trace_header header;
80    int                 status;
81    FILE*               traceFile;
82    uint8_t             taken;
83    uint8_t             notTaken;
84
85    taken    = TargetInfo->qemuTakenBit();
86    notTaken = TargetInfo->qemuNotTakenBit();
87
88    //
89    // Verify that the TraceList has a non-zero size.
90    //
91    if ( log->Trace.set.begin() == log->Trace.set.end() ){
92      fprintf( stderr, "ERROR: Empty TraceList\n" );
93      return false;
94    }
95
96    //
97    // Open the trace file.
98    //
99    traceFile = ::OPEN( file, "w" );
100    if (!traceFile) {
101      std::ostringstream what;
102      std::cerr << "Unable to open " << file << std::endl;
103      return false;
104    }
105
106    //
107    //  Write the Header to the file
108    //
109    strncpy( header.magic, QEMU_TRACE_MAGIC, sizeof(header.magic) );
110    header.version = QEMU_TRACE_VERSION;
111    header.kind    = QEMU_TRACE_KIND_RAW;  // XXX ??
112    header.sizeof_target_pc = 32;
113    header.big_endian = false;
114    header.machine[0] = 0; // XXX ??
115    header.machine[1] = 0; // XXX ??
116    status = ::fwrite( &header, sizeof(trace_header), 1, traceFile );
117    if (status != 1) {
118      std::cerr << "Unable to write header to " << file << std::endl;
119      return false;
120    }
121
122    if (Verbose)
123      std::cerr << "magic = " << header.magic << std::endl
124                << "version = " << header.version << std::endl
125                << "kind = " << header.kind << std::endl
126                << "sizeof_target_pc = " << header.sizeof_target_pc << std::endl
127                << "big_endian = " << header.big_endian << std::endl
128                << std::hex << std::setfill('0')
129                << "machine = " << std::setw(2) << header.machine[0]
130                << ':' << header.machine[1]
131                << std::dec << std::setfill(' ')
132                << std::endl;
133
134    //
135    // Loop through log and write each entry.
136    //
137
138    for (const auto & itr : log->Trace.set) {
139      struct trace_entry32  entry;
140
141      entry._pad[0] = 0;
142      entry.pc      = itr.lowAddress;
143      entry.size    = itr.length;
144      entry.op      = TRACE_OP_BLOCK;
145      switch (itr.exitReason) {
146        case TraceList::EXIT_REASON_BRANCH_TAKEN:
147          entry.op |= taken;
148          break;
149        case TraceList::EXIT_REASON_BRANCH_NOT_TAKEN:
150          entry.op |= notTaken;
151          break;
152        case TraceList::EXIT_REASON_OTHER:
153          break;
154        default:
155          throw rld::error( "Unknown exit Reason", "TraceWriterQEMU::writeFile" );
156          break;
157       }
158
159      if ( Verbose )
160        std::cerr << std::hex << std::setfill('0')
161                  << entry.pc << ' ' << entry.size << ' ' << entry.op
162                  << std::dec << std::setfill(' ')
163                  << std::endl;
164
165      status = ::fwrite( &entry, sizeof(entry), 1, traceFile );
166      if (status != 1) {
167        ::fclose( traceFile );
168        std::cerr << "Unable to write entry to " << file << std::endl;
169        return false;
170      }
171    }
172
173    ::fclose( traceFile );
174    return true;
175  }
176}
Note: See TracBrowser for help on using the repository browser.