source: rtems-tools/tester/covoar/CoverageMapBase.cc @ 99c90b3

Last change on this file since 99c90b3 was 99c90b3, checked in by Chris Johns <chrisj@…>, on Aug 5, 2018 at 11:41:08 PM

tester/covoar: Integrate DWARF function data.

Use DAWRF function data to create the executable coverage
maps. Integrate the existing objdump processing with this
data.

  • Refactor CoverageMapBase? to have the address ranges and address info as separate objects. Move the to address info into a vector. Add support for multiple address ranges.
  • DesiredSymbols? is only interested in function symbols.
  • ExecutableInfo? creates coverage maps from DWARF function data.
  • Add warning flags to the covoar build.
  • Varous C++11 refactoring.
  • Property mode set to 100644
File size: 8.6 KB
Line 
1
2/*! @file CoverageMapBase.cc
3 *  @brief CoverageMapBase Implementation
4 *
5 *  This file contains the implementation of the functions
6 *  which provide a base level of functionality of a CoverageMap.
7 */
8
9#include <limits.h>
10
11#include <iostream>
12#include <iomanip>
13
14#include <rld.h>
15
16#include "CoverageMapBase.h"
17
18namespace Coverage {
19
20  AddressInfo::AddressInfo ()
21    : isStartOfInstruction (false),
22      wasExecuted (false),
23      isBranch (false),
24      isNop (false),
25      wasTaken (false),
26      wasNotTaken (false)
27  {
28  }
29
30  AddressRange::AddressRange ()
31    : lowAddress(0),
32      highAddress(0)
33  {
34  }
35
36  AddressRange::AddressRange (const std::string& name,
37                              uint32_t           lowAddress,
38                              uint32_t           highAddress)
39    : fileName (name),
40      lowAddress (lowAddress),
41      highAddress (highAddress)
42  {
43    info.resize( size( ) );
44  }
45
46  size_t AddressRange::size () const
47  {
48    return highAddress - lowAddress + 1;
49  }
50
51  bool AddressRange::inside (uint32_t address) const
52  {
53    return address >= lowAddress && address <= highAddress;
54  }
55
56  AddressInfo& AddressRange::get (uint32_t address)
57  {
58    if ( !inside( address ) )
59      throw rld::error( "address outside range", "AddressRange::get" );
60    size_t slot = address - lowAddress;
61    if (slot >= info.size ())
62      throw rld::error( "address slot not found", "AddressRange::get" );
63    return info[slot];
64  }
65
66  const AddressInfo& AddressRange::get (uint32_t address) const
67  {
68    if ( !inside( address ) )
69      throw rld::error( "address outside range", "AddressRange::get" );
70    size_t slot = address - lowAddress;
71    if (slot >= info.size ())
72      throw rld::error( "address slot not found", "AddressRange::get" );
73    return info[slot];
74  }
75
76  void AddressRange::dump (std::ostream& out, bool show_slots) const
77  {
78    out << std::hex << std::setfill('0')
79        << "Address range: low = " << std::setw(8) << lowAddress
80        << " high = " << std::setw(8) << highAddress
81        << std::endl;
82    if (show_slots) {
83      size_t slot = 0;
84      for (auto& i : info) {
85        out << std::hex << std::setfill('0')
86            << "0x" << std::setw(8) << slot++ + lowAddress
87            << "- isStartOfInstruction:"
88            << (char*) (i.isStartOfInstruction ? "yes" : "no")
89            << " wasExecuted:"
90            << (char*) (i.wasExecuted ? "yes" : "no")
91            << std::endl
92            << "           isBranch:"
93            << (char*) (i.isBranch ? "yes" : "no")
94            << " wasTaken:"
95            << (char*) (i.wasTaken ? "yes" : "no")
96            << " wasNotTaken:"
97            << (char*) (i.wasNotTaken ? "yes" : "no")
98            << std::dec << std::setfill(' ')
99            << std::endl;
100      }
101    }
102  }
103
104  CoverageMapBase::CoverageMapBase(
105    const std::string& exefileName,
106    uint32_t           low,
107    uint32_t           high
108    ) : exefileName (exefileName)
109  {
110    Ranges.push_back( AddressRange( exefileName, low, high ) );
111  }
112
113  CoverageMapBase::~CoverageMapBase()
114  {
115  }
116
117  void CoverageMapBase::Add( uint32_t low, uint32_t high )
118  {
119    Ranges.push_back( AddressRange( exefileName, low, high ) );
120  }
121
122  bool CoverageMapBase::validAddress( const uint32_t address ) const
123  {
124    for ( auto r : Ranges )
125      if (r.inside( address ))
126        return true;
127    return false;
128  }
129
130  void CoverageMapBase::dump( void ) const
131  {
132    std::cerr << "Coverage Map Contents:" << std::endl;
133    for (auto& r : Ranges)
134      r.dump( std::cerr );
135  }
136
137  uint32_t CoverageMapBase::getSize() const
138  {
139    size_t size = 0;
140    for (auto& r : Ranges)
141      size += r.size ();
142    return size;
143  }
144
145  bool CoverageMapBase::getBeginningOfInstruction(
146    uint32_t  address,
147    uint32_t* beginning
148  ) const
149  {
150    bool         status = false;
151    uint32_t     start;
152    AddressRange range;
153
154    status = getRange( address, range );
155    if ( status != true )
156      return status;
157
158    start = address;
159
160    while (start >= range.lowAddress ) {
161      if (isStartOfInstruction( start - range.lowAddress )) {
162        *beginning = start;
163        status = true;
164        break;
165      }
166      else
167        start--;
168    }
169
170    return status;
171  }
172
173  int32_t CoverageMapBase::getFirstLowAddress() const
174  {
175    /*
176     * This is broken, do not trust it.
177     */
178    return Ranges.front().lowAddress;
179  }
180
181  bool CoverageMapBase::getRange( uint32_t address, AddressRange& range ) const
182  {
183    for ( auto r : Ranges ) {
184      if (r.inside( address )) {
185        range.lowAddress = r.lowAddress;
186        range.highAddress = r.highAddress;
187        range.info = r.info;
188        return true;
189      }
190    }
191    return false;
192  }
193
194  AddressInfo& CoverageMapBase::getInfo( uint32_t address )
195  {
196    for ( auto& r : Ranges )
197      if (r.inside( address ))
198        return r.get( address );
199    throw rld::error( "address out of bounds", "CoverageMapBase::getInfo" );
200  }
201
202  const AddressInfo& CoverageMapBase::getInfo( uint32_t address ) const
203  {
204    for ( auto& r : Ranges )
205      if (r.inside( address ))
206        return r.get( address );
207    throw rld::error( "address out of bounds", "CoverageMapBase::getInfo" );
208  }
209
210  void CoverageMapBase::setIsStartOfInstruction(
211    uint32_t    address
212  )
213  {
214    if ( validAddress( address ) )
215      getInfo( address ).isStartOfInstruction = true;
216  }
217
218  bool CoverageMapBase::isStartOfInstruction( uint32_t address ) const
219  {
220    if ( !validAddress( address ) )
221      return false;
222    return getInfo( address ).isStartOfInstruction;
223  }
224
225  void CoverageMapBase::setWasExecuted( uint32_t address )
226  {
227    if ( validAddress( address ) )
228      getInfo( address ).wasExecuted += 1;
229  }
230
231  void CoverageMapBase::sumWasExecuted( uint32_t address, uint32_t addition)
232  {
233    if ( validAddress( address ) )
234      getInfo( address ).wasExecuted += addition;
235  }
236
237  bool CoverageMapBase::wasExecuted( uint32_t address ) const
238  {
239    bool result = false;
240    if ( validAddress( address ) && (getInfo( address ).wasExecuted > 0))
241      result = true;
242    return result;
243  }
244
245  uint32_t CoverageMapBase::getWasExecuted( uint32_t address ) const
246  {
247    if ( !validAddress( address ) )
248      return 0;
249    return getInfo( address ).wasExecuted;
250  }
251
252  void CoverageMapBase::setIsBranch(
253    uint32_t    address
254  )
255  {
256    if ( validAddress( address ) )
257      getInfo( address ).isBranch = true;
258  }
259
260  bool CoverageMapBase::isNop( uint32_t address ) const
261  {
262    if ( !validAddress( address ) )
263      return false;
264    return getInfo( address ).isNop;
265  }
266
267  void CoverageMapBase::setIsNop(
268    uint32_t    address
269  )
270  {
271    if ( !validAddress( address ) )
272      return;
273    getInfo( address ).isNop = true;
274  }
275
276  bool CoverageMapBase::isBranch( uint32_t address ) const
277  {
278    if ( !validAddress( address ) )
279      return false;
280    return getInfo( address ).isBranch;
281  }
282
283  void CoverageMapBase::setWasTaken(
284    uint32_t    address
285  )
286  {
287    if ( !validAddress( address ) )
288      return;
289    getInfo( address ).wasTaken += 1;
290  }
291
292  void CoverageMapBase::setWasNotTaken(
293    uint32_t    address
294  )
295  {
296    if ( !validAddress( address ) )
297      return;
298    getInfo( address ).wasNotTaken += 1;
299  }
300
301  bool CoverageMapBase::wasAlwaysTaken( uint32_t address ) const
302  {
303    if ( !validAddress( address ) )
304      return false;
305    const AddressInfo& info = getInfo( address );
306    return info.wasTaken && !info.wasNotTaken;
307  }
308
309  bool CoverageMapBase::wasNeverTaken( uint32_t address ) const
310  {
311    if ( !validAddress( address ) )
312      return false;
313    const AddressInfo& info = getInfo( address );
314    return !info.wasTaken && info.wasNotTaken;
315  }
316
317  bool CoverageMapBase::wasNotTaken( uint32_t address ) const
318  {
319    bool result = true;
320    if ( !validAddress( address ) )
321      result = false;
322    else if ( getInfo( address ).wasNotTaken <= 0 )
323      result = false;
324    return result;
325  }
326
327  void CoverageMapBase::sumWasNotTaken( uint32_t address, uint32_t addition)
328  {
329    if ( validAddress( address ) )
330      getInfo( address ).wasNotTaken += addition;
331  }
332
333  uint32_t CoverageMapBase::getWasNotTaken( uint32_t address ) const
334  {
335    if ( !validAddress( address ) )
336      return 0;
337    return getInfo( address ).wasNotTaken;
338  }
339
340  bool CoverageMapBase::wasTaken( uint32_t address ) const
341  {
342    bool result = true;
343    if ( !validAddress( address ) )
344      result = false;
345    else if ( getInfo( address ).wasTaken <= 0 )
346      result = false;
347    return result;
348  }
349
350  void CoverageMapBase::sumWasTaken( uint32_t address, uint32_t addition)
351  {
352    if ( !validAddress( address ) )
353      return;
354    getInfo( address ).wasTaken += addition;
355  }
356
357  uint32_t CoverageMapBase::getWasTaken( uint32_t address ) const
358  {
359    if ( !validAddress( address ) )
360      return 0;
361    return getInfo( address ).wasTaken;
362  }
363}
Note: See TracBrowser for help on using the repository browser.