summaryrefslogtreecommitdiffstats
path: root/tester/covoar/AddressToLineMapper.h
blob: 308925a003d82748a35ad71c0d51be752f79768d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
/*! @file AddressToLineMapper.h
 *  @brief AddressToLineMapper Specification
 *
 *  This file contains the specification of the AddressToLineMapper class.
 */

#ifndef __ADDRESS_TO_LINE_MAPPER_H__
#define __ADDRESS_TO_LINE_MAPPER_H__

#include <cstdint>
#include <memory>
#include <set>
#include <string>
#include <vector>

#include <rld-dwarf.h>

namespace Coverage {

  /*! @class SourceLine
   *
   *  This class stores source information for a specific address.
   */
  class SourceLine {

  public:

    SourceLine()
    : address(0),
      path_(nullptr),
      line_num(-1),
      is_end_sequence(true)
    {
    }

    SourceLine(
      uint64_t addr,
      const std::shared_ptr<std::string>& src,
      int line,
      bool end_sequence
    ) : address(addr),
        path_(src),
        line_num(line),
        is_end_sequence(end_sequence)
    {
    }

    /*!
     *  This method gets the address of this source information.
     *
     *  @return Returns the address of this source information
     */
    uint64_t location() const;

    /*!
     *  This method gets a value indicating whether this address represents an
     *  end sequence.
     *
     *  @return Returns whether this address represents an end sequence or not
     */
    bool is_an_end_sequence() const;

    /*!
     *  This method gets the source file path of this address.
     *
     *  @return Returns the source file path of this address
     */
    const std::string path() const;

    /*!
     *  This method gets the source line number of this address.
     *
     *  @return Returns the source line number of this address
     */
    int line() const;

  private:

    /*!
     *  The address of this source information.
     */
    uint64_t address;

    /*!
     *  An iterator pointing to the location in the set that contains the
     *  source file path of the address.
     */
    const std::shared_ptr<std::string> path_;

    /*!
     *  The source line number of the address.
     */
    int line_num;

    /*!
     *  Whether the address represents an end sequence or not.
     */
    bool is_end_sequence;

  };

  typedef std::vector<SourceLine> SourceLines;

  /* This allows comparison of strings owned by shared_ptrs. */
  struct SharedStringCmp {
    bool operator()(
      const std::shared_ptr<std::string>& lhs,
      const std::shared_ptr<std::string>& rhs
    ) const {
      return *lhs < *rhs;
    }
  };

  typedef std::set<std::shared_ptr<std::string>, SharedStringCmp> SourcePaths;

  /*! @class AddressLineRange
   *
   *  This class stores source information for an address range.
   */
  class AddressLineRange {

  public:

    class SourceNotFoundError : public std::runtime_error {
      /* Use the base class constructors. */
      using std::runtime_error::runtime_error;
    };

    AddressLineRange(
      uint32_t low,
      uint32_t high
    ) : lowAddress(low), highAddress(high)
    {
    }

    /*!
     *  This method adds source and line information for a specified address.
     *
     *  @param[in] address specifies the DWARF address information
     */
    void addSourceLine(const rld::dwarf::address& address);

    /*!
     *  This method gets the source file name and line number for a given
     *  address.
     *
     *  @param[in] address specifies the address to look up
     *
     *  @return Returns the source information for the specified address.
     */
    const SourceLine& getSourceLine(uint32_t address) const;

  private:

    /*!
     *  The low address for this range.
     */
    uint32_t lowAddress;

    /*!
     *  The high address for this range.
     */
    uint32_t highAddress;

    /*!
     *  The source information for addresses in this range.
     */
    SourceLines sourceLines;

    /*!
     *  The set of source file names for this range.
     */
    SourcePaths sourcePaths;

  };

  typedef std::vector<AddressLineRange> AddressLineRanges;

  /*! @class AddressToLineMapper
   *
   *  This class provides address-to-line capabilities.
   */
  class AddressToLineMapper {

  public:

    /*!
     *  This method gets the source file name and line number for a given
     *  address.
     *
     *  @param[in] address specifies the address to look up
     *  @param[out] sourceFile specifies the name of the source file
     *  @param[out] sourceLine specifies the line number in the source file
     */
    void getSource(
      uint32_t address,
      std::string& sourceFile,
      int& sourceLine
    ) const;

    /*!
     *  This method creates a new range with the specified addresses.
     *
     *  @param[in] low specifies the low address of the range
     *  @param[in] high specifies the high address of the range
     *
     *  @return Returns a reference to the newly created range
     */
    AddressLineRange& makeRange(uint32_t low, uint32_t high);

  private:

    /*!
     *  The address and line information ranges.
     */
    AddressLineRanges addressLineRanges;

  };

}

#endif