debug_info.h
Go to the documentation of this file.
1 // Copyright 2016 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // Classes for reading .debug_info and .debug_types.
16 //
17 // Usage overview:
18 //
19 // // Stores/caches abbreviation info and CU names.
20 // dwarf::InfoReader reader;
21 //
22 // // Iterator type for enumerating CUs. Initially positioned at the beginning
23 // // of the given section unless you pass an explicit offset.
24 // dwarf::CUIter iter = reader.GetCUIter(
25 // dwarf::InfoReader::Section::kDebugInfo);
26 //
27 // // Represents a single CU and vends a lot of useful data about it, like its
28 // // name. Starts out empty/undefined until you call NextCU().
29 // dwarf::CU cu;
30 //
31 // while (iter.NextCU(reader, &cu)) {
32 // std::cout << "Parsing CU with name=" << cu.unit_name() << "\n";
33 //
34 // // Iterator for enumerating DIEs in a given CU.
35 // dwarf::DIEReader die_reader = cu.GetDIEReader();
36 // while (auto abbrev = die_reader.ReadCode(cu)) {
37 // if (IsInteresting(abbrev->tag)) {
38 // die_reader.ReadAttributes(
39 // cu, abbrev, [](uint16_t tag, dwarf::AttrValue val) {
40 // // Process attribute.
41 // });
42 // } else {
43 // die_reader.SkipChildren(cu, abbrev);
44 // }
45 // }
46 // }
47 
48 #ifndef BLOATY_DWARF_DEBUG_INFO_H_
49 #define BLOATY_DWARF_DEBUG_INFO_H_
50 
51 #include <functional>
52 #include <unordered_map>
53 
54 #include "absl/strings/string_view.h"
55 #include "absl/strings/substitute.h"
56 #include "dwarf/attr.h"
57 #include "dwarf/dwarf_util.h"
58 #include "dwarf_constants.h"
59 #include "util.h"
60 
61 namespace bloaty {
62 namespace dwarf {
63 
64 struct File {
78 
82  if (member) *member = contents;
83  }
84 };
85 
86 // A class that represents the DWARF version and address sizes for a given
87 // compilation unit.
89  public:
90  // When true, DWARF offsets are 64 bits, otherwise they are 32 bit.
91  bool dwarf64() const { return dwarf64_; }
92 
93  // The size of addresses. Guaranteed to be either 4 or 8.
94  uint8_t address_size() const { return addr8_ ? 8 : 4; }
95 
96  // DWARF version of this unit.
97  uint8_t dwarf_version() const { return dwarf_version_; }
98 
100  if (address_size != 4 && address_size != 8) {
101  THROWF("Unexpected address size: $0", address_size);
102  }
103  addr8_ = address_size == 8;
104  }
105 
106  // Reads a DWARF offset based on whether we are reading dwarf32 or dwarf64
107  // format.
109  return dwarf64_ ? ReadFixed<uint64_t>(data) : ReadFixed<uint32_t>(data);
110  }
111 
112  // Reads an address according to the expected address_size.
114  return addr8_ ? ReadFixed<uint64_t>(data) : ReadFixed<uint32_t>(data);
115  }
116 
118  return addr8_ ? 0xffffffffffffffff : 0xffffffff;
119  }
120 
121  // Reads an "initial length" as specified in many DWARF headers. This
122  // contains either a 32-bit or a 64-bit length, and signals whether we are
123  // using the 32-bit or 64-bit DWARF format (so it sets dwarf64 appropriately).
124  //
125  // Returns the range for this section and stores the remaining data
126  // in |remaining|.
128 
130  dwarf_version_ = ReadFixed<uint16_t>(data);
131  }
132 
133  private:
135  bool dwarf64_;
136  bool addr8_;
137 };
138 
139 // AbbrevTable /////////////////////////////////////////////////////////////////
140 
141 // Parses and stores a representation of (a portion of) the .debug_abbrev
142 // section of a DWARF file. An abbreviation is defined by a unique "code"
143 // (unique within one table), and defines the DIE tag and set of attributes.
144 // The encoding of the DIE then contains just the abbreviation code and the
145 // attribute values -- thanks to the abbreviation table, the tag and attribute
146 // keys/names are not required.
147 //
148 // The abbreviations are an internal detail of the DWARF format and users should
149 // not need to care about them.
150 
151 class AbbrevTable {
152  public:
153  // Reads abbreviations until a terminating abbreviation is seen.
155 
156  // In a DWARF abbreviation, each attribute has a name and a form.
157  struct Attribute {
160  };
161 
162  // The representation of a single abbreviation.
163  struct Abbrev {
166  bool has_child;
167  std::vector<Attribute> attr;
168  };
169 
170  bool IsEmpty() const { return abbrev_.empty(); }
172 
173  // Looks for an abbreviation with the given code. Returns true if the lookup
174  // succeeded.
175  bool GetAbbrev(uint32_t code, const Abbrev** abbrev) const {
176  auto it = abbrev_.find(code);
177  if (it != abbrev_.end()) {
178  *abbrev = &it->second;
179  return true;
180  } else {
181  return false;
182  }
183  }
184 
185  private:
186  // Keyed by abbreviation code.
187  // Generally we expect these to be small, so we could almost use a vector<>.
188  // But you never know what crazy input data is going to do...
189  std::unordered_map<uint32_t, Abbrev> abbrev_;
191 };
192 
193 class CUIter;
194 class CU;
195 class DIEReader;
196 
197 // Stores/caches abbreviation info and CU names.
198 class InfoReader {
199  public:
201  InfoReader(const InfoReader&) = delete;
202  InfoReader& operator=(const InfoReader&) = delete;
203 
204  const File& dwarf() const { return dwarf_; }
205 
206  // DIEs exist in both .debug_info and .debug_types.
207  enum class Section {
208  kDebugInfo,
210  };
211 
213 
214  private:
215  friend class CU;
216  const File& dwarf_;
217 
218  std::unordered_map<uint64_t, std::string> stmt_list_map_;
219 
220  // All of the AbbrevTables we've read from .debug_abbrev, indexed by their
221  // offset within .debug_abbrev.
222  std::unordered_map<uint64_t, AbbrevTable> abbrev_tables_;
223 };
224 
225 class CUIter {
226  public:
227  bool NextCU(InfoReader& reader, CU* cu);
228 
229  private:
230  friend class InfoReader;
232  : section_(section), next_unit_(next_unit) {}
233 
234  // Data for the next compilation unit.
237 };
238 
239 // CompilationUnit: stores info about a single compilation unit in .debug_info
240 // or .debug_types.
241 class CU {
242  public:
244 
245  const File& dwarf() const { return *dwarf_; }
246  const CompilationUnitSizes& unit_sizes() const { return unit_sizes_; }
247  const std::string& unit_name() const { return unit_name_; }
249  uint64_t addr_base() const { return addr_base_; }
252  const AbbrevTable& unit_abbrev() const { return *unit_abbrev_; }
253 
255  if (strp_callback_) {
257  }
258  }
259 
261  std::function<void(absl::string_view)> strp_sink) {
262  strp_callback_ = strp_sink;
263  }
264 
267  }
268 
269  private:
270  friend class CUIter;
271  friend class DIEReader;
272 
276 
277  const File* dwarf_;
278 
279  // Info that comes from the CU header.
280  absl::string_view entire_unit_; // Entire CU's range.
281  absl::string_view data_; // Entire unit excluding CU header.
284 
285  // Only for skeleton and split CUs.
288 
289  // Only for .debug_types
292 
293  // Info that comes from the top-level DIE.
298 
300 };
301 
302 // DIEReader: for reading a sequence of Debugging Information Entries in a
303 // compilation unit.
304 class DIEReader {
305  public:
306  // Abbreviation for the current entry.
307  const AbbrevTable::Abbrev* ReadCode(const CU& cu);
308 
309  template <class T>
310  void ReadAttributes(const CU& cu, const AbbrevTable::Abbrev* code, T&& func);
311 
312  void SkipChildren(const CU& cu, const AbbrevTable::Abbrev* code);
313 
314  private:
315  // Internal APIs.
316  friend class CU;
317 
319  void SkipNullEntries();
320 
321  // Our current read position.
323  int depth_ = 0;
324 };
325 
326 inline uint64_t ReadIndirectAddress(const CU& cu, uint64_t val) {
327  absl::string_view addrs = cu.dwarf().debug_addr;
328  switch (cu.unit_sizes().address_size()) {
329  case 4:
330  SkipBytes((val * 4) + cu.addr_base(), &addrs);
331  return ReadFixed<uint32_t>(&addrs);
332  case 8:
333  SkipBytes((val * 8) + cu.addr_base(), &addrs);
334  return ReadFixed<uint64_t>(&addrs);
335  default:
337  }
338 }
339 
340 // Reads all attributes for this DIE, calling the given function for each one.
341 template <class T>
342 void DIEReader::ReadAttributes(const CU& cu, const AbbrevTable::Abbrev* abbrev,
343  T&& func) {
344  for (auto attr : abbrev->attr) {
346  func(attr.name, value);
347  }
348 }
349 
351 
352 } // namespace dwarf
353 } // namespace bloaty
354 
355 #endif // BLOATY_DWARF_DEBUG_INFO_H_
bloaty::dwarf::CU::ReadTopLevelDIE
void ReadTopLevelDIE(InfoReader &reader)
Definition: debug_info.cc:187
bloaty::dwarf::DIEReader::ReadCode
const AbbrevTable::Abbrev * ReadCode(const CU &cu)
Definition: debug_info.cc:243
bloaty::dwarf::CompilationUnitSizes::dwarf64_
bool dwarf64_
Definition: debug_info.h:135
bloaty::dwarf::AbbrevTable::abbrev_data
absl::string_view abbrev_data() const
Definition: debug_info.h:171
bloaty
Definition: bloaty.cc:69
regen-readme.it
it
Definition: regen-readme.py:15
attr.h
bloaty::dwarf::CompilationUnitSizes::dwarf_version
uint8_t dwarf_version() const
Definition: debug_info.h:97
bloaty::dwarf::CompilationUnitSizes::addr8_
bool addr8_
Definition: debug_info.h:136
bloaty::dwarf::CU::strp_callback_
std::function< void(absl::string_view)> strp_callback_
Definition: debug_info.h:299
bloaty::dwarf::AbbrevTable
Definition: debug_info.h:151
bloaty::dwarf::File::debug_rnglists
absl::string_view debug_rnglists
Definition: debug_info.h:74
bloaty::dwarf::AbbrevTable::Attribute::form
uint8_t form
Definition: debug_info.h:159
bloaty::dwarf::AbbrevTable::Attribute
Definition: debug_info.h:157
bloaty::dwarf::InfoReader::dwarf_
const File & dwarf_
Definition: debug_info.h:216
uint16_t
unsigned short uint16_t
Definition: stdint-msvc2008.h:79
bloaty::dwarf::File::SetFieldByName
void SetFieldByName(absl::string_view name, absl::string_view contents)
Definition: debug_info.h:80
capstone.range
range
Definition: third_party/bloaty/third_party/capstone/bindings/python/capstone/__init__.py:6
bloaty::dwarf::CU::unit_type_signature_
uint64_t unit_type_signature_
Definition: debug_info.h:290
bloaty::dwarf::DIEReader
Definition: debug_info.h:304
bloaty::dwarf::CU::dwarf_
const File * dwarf_
Definition: debug_info.h:277
bloaty::dwarf::InfoReader::Section::kDebugTypes
@ kDebugTypes
bloaty::dwarf::InfoReader::operator=
InfoReader & operator=(const InfoReader &)=delete
bloaty::dwarf::CU::data_
absl::string_view data_
Definition: debug_info.h:281
bloaty::dwarf::DIEReader::ReadAttributes
void ReadAttributes(const CU &cu, const AbbrevTable::Abbrev *code, T &&func)
Definition: debug_info.h:342
absl::string_view
Definition: abseil-cpp/absl/strings/string_view.h:167
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
file
Definition: bloaty/third_party/zlib/examples/gzappend.c:170
bloaty::dwarf::CompilationUnitSizes::ReadDWARFOffset
uint64_t ReadDWARFOffset(absl::string_view *data) const
Definition: debug_info.h:108
bloaty::dwarf::AbbrevTable::ReadAbbrevs
void ReadAbbrevs(absl::string_view data)
Definition: debug_info.cc:26
setup.name
name
Definition: setup.py:542
bloaty::dwarf::InfoReader::InfoReader
InfoReader(const File &file)
Definition: debug_info.h:200
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
bloaty::dwarf::DIEReader::DIEReader
DIEReader(absl::string_view data)
Definition: debug_info.h:318
bloaty::dwarf::CU::GetDIEReader
DIEReader GetDIEReader()
Definition: debug_info.h:350
bloaty::dwarf::CU::range_lists_base
uint64_t range_lists_base() const
Definition: debug_info.h:251
T
#define T(upbtypeconst, upbtype, ctype, default_value)
bloaty::dwarf::DIEReader::depth_
int depth_
Definition: debug_info.h:323
bloaty::dwarf::InfoReader::dwarf
const File & dwarf() const
Definition: debug_info.h:204
bloaty::dwarf::CU::addr_base_
uint64_t addr_base_
Definition: debug_info.h:295
bloaty::dwarf::CUIter::section_
InfoReader::Section section_
Definition: debug_info.h:235
bloaty::dwarf::CUIter::next_unit_
absl::string_view next_unit_
Definition: debug_info.h:236
bloaty::dwarf::AbbrevTable::Abbrev::code
uint32_t code
Definition: debug_info.h:164
bloaty::dwarf::File::debug_str_offsets
absl::string_view debug_str_offsets
Definition: debug_info.h:76
bloaty::dwarf::CompilationUnitSizes::ReadAddress
uint64_t ReadAddress(absl::string_view *data) const
Definition: debug_info.h:113
uint32_t
unsigned int uint32_t
Definition: stdint-msvc2008.h:80
bloaty::dwarf::File::debug_abbrev
absl::string_view debug_abbrev
Definition: debug_info.h:65
bloaty::dwarf::CU::str_offsets_base
uint64_t str_offsets_base() const
Definition: debug_info.h:250
bloaty::dwarf::AbbrevTable::Attribute::name
uint16_t name
Definition: debug_info.h:158
bloaty::SkipBytes
void SkipBytes(size_t bytes, absl::string_view *data)
Definition: bloaty/src/util.h:174
bloaty::dwarf::File::debug_pubtypes
absl::string_view debug_pubtypes
Definition: debug_info.h:72
bloaty::dwarf::CU::unit_abbrev
const AbbrevTable & unit_abbrev() const
Definition: debug_info.h:252
bloaty::dwarf::DIEReader::remaining_
absl::string_view remaining_
Definition: debug_info.h:322
bloaty::dwarf::CU
Definition: debug_info.h:241
bloaty::dwarf::AbbrevTable::Abbrev::attr
std::vector< Attribute > attr
Definition: debug_info.h:167
member
int member
Definition: abseil-cpp/absl/base/invoke_test.cc:87
dwarf_util.h
bloaty::dwarf::AbbrevTable::GetAbbrev
bool GetAbbrev(uint32_t code, const Abbrev **abbrev) const
Definition: debug_info.h:175
dwarf_constants.h
uint64_t
unsigned __int64 uint64_t
Definition: stdint-msvc2008.h:90
bloaty::dwarf::CU::unit_name
const std::string & unit_name() const
Definition: debug_info.h:247
bloaty::dwarf::CompilationUnitSizes::dwarf64
bool dwarf64() const
Definition: debug_info.h:91
bloaty::dwarf::CompilationUnitSizes::MaxAddress
uint64_t MaxAddress() const
Definition: debug_info.h:117
bloaty::dwarf::File::debug_loc
absl::string_view debug_loc
Definition: debug_info.h:70
bloaty::dwarf::AbbrevTable::IsEmpty
bool IsEmpty() const
Definition: debug_info.h:170
bloaty::dwarf::CU::IsValidDwarfAddress
bool IsValidDwarfAddress(uint64_t addr) const
Definition: debug_info.h:265
bloaty::dwarf::CUIter::CUIter
CUIter(InfoReader::Section section, absl::string_view next_unit)
Definition: debug_info.h:231
bloaty::dwarf::InfoReader::stmt_list_map_
std::unordered_map< uint64_t, std::string > stmt_list_map_
Definition: debug_info.h:218
bloaty::dwarf::AbbrevTable::Abbrev::has_child
bool has_child
Definition: debug_info.h:166
bloaty::dwarf::AttrValue::ParseAttr
static AttrValue ParseAttr(const CU &cu, uint8_t form, absl::string_view *data)
Definition: attr.cc:105
bloaty::dwarf::File::debug_addr
absl::string_view debug_addr
Definition: debug_info.h:66
bloaty::dwarf::File::debug_pubnames
absl::string_view debug_pubnames
Definition: debug_info.h:71
data
char data[kBufferLength]
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1006
bloaty::dwarf::File::debug_info
absl::string_view debug_info
Definition: debug_info.h:68
bloaty::dwarf::File::GetFieldByName
absl::string_view * GetFieldByName(absl::string_view name)
Definition: dwarf.cc:196
bloaty::dwarf::InfoReader::GetCUIter
CUIter GetCUIter(Section section, uint64_t offset=0)
Definition: debug_info.cc:95
section
Definition: loader.h:337
bloaty::dwarf::CompilationUnitSizes
Definition: debug_info.h:88
value
const char * value
Definition: hpack_parser_table.cc:165
bloaty::dwarf::CU::DIEReader
friend class DIEReader
Definition: debug_info.h:271
bloaty::dwarf::CU::ReadHeader
void ReadHeader(absl::string_view entire_unit, absl::string_view data, InfoReader::Section section, InfoReader &reader)
Definition: debug_info.cc:124
bloaty::dwarf::IsValidDwarfAddress
bool IsValidDwarfAddress(uint64_t addr, uint8_t address_size)
Definition: dwarf_util.cc:23
bloaty::dwarf::CU::entire_unit
absl::string_view entire_unit() const
Definition: debug_info.h:248
bloaty::dwarf::CU::str_offsets_base_
uint64_t str_offsets_base_
Definition: debug_info.h:296
bloaty::dwarf::InfoReader
Definition: debug_info.h:198
contents
string_view contents
Definition: elf.cc:597
attr
OPENSSL_EXPORT X509_ATTRIBUTE * attr
Definition: x509.h:1666
bloaty::dwarf::File::debug_str
absl::string_view debug_str
Definition: debug_info.h:75
func
const EVP_CIPHER *(* func)(void)
Definition: cipher_extra.c:73
bloaty::dwarf::CompilationUnitSizes::ReadInitialLength
absl::string_view ReadInitialLength(absl::string_view *remaining)
Definition: debug_info.cc:74
bloaty::dwarf::CU::range_lists_base_
uint64_t range_lists_base_
Definition: debug_info.h:297
BLOATY_UNREACHABLE
#define BLOATY_UNREACHABLE()
Definition: bloaty/src/util.h:53
bloaty::dwarf::CompilationUnitSizes::address_size
uint8_t address_size() const
Definition: debug_info.h:94
bloaty::dwarf::CU::SetIndirectStringCallback
void SetIndirectStringCallback(std::function< void(absl::string_view)> strp_sink)
Definition: debug_info.h:260
bloaty::dwarf::CU::entire_unit_
absl::string_view entire_unit_
Definition: debug_info.h:280
bloaty::dwarf::InfoReader::Section
Section
Definition: debug_info.h:207
bloaty::dwarf::CU::unit_abbrev_
AbbrevTable * unit_abbrev_
Definition: debug_info.h:283
bloaty::dwarf::CompilationUnitSizes::SetAddressSize
void SetAddressSize(uint8_t address_size)
Definition: debug_info.h:99
bloaty::dwarf::CU::unit_name_
std::string unit_name_
Definition: debug_info.h:294
bloaty::dwarf::DIEReader::SkipChildren
void SkipChildren(const CU &cu, const AbbrevTable::Abbrev *code)
Definition: debug_info.cc:259
bloaty::dwarf::CU::dwarf
const File & dwarf() const
Definition: debug_info.h:245
bloaty::dwarf::CU::unit_sizes_
CompilationUnitSizes unit_sizes_
Definition: debug_info.h:282
bloaty::dwarf::CU::unit_sizes
const CompilationUnitSizes & unit_sizes() const
Definition: debug_info.h:246
THROWF
#define THROWF(...)
Definition: bloaty/src/util.h:46
bloaty::dwarf::File::debug_line
absl::string_view debug_line
Definition: debug_info.h:69
bloaty::dwarf::InfoReader::Section::kDebugInfo
@ kDebugInfo
bloaty::dwarf::File::debug_types
absl::string_view debug_types
Definition: debug_info.h:77
bloaty::dwarf::CompilationUnitSizes::ReadDWARFVersion
void ReadDWARFVersion(absl::string_view *data)
Definition: debug_info.h:129
bloaty::dwarf::CU::dwo_id_
uint64_t dwo_id_
Definition: debug_info.h:287
bloaty::dwarf::ReadIndirectAddress
uint64_t ReadIndirectAddress(const CU &cu, uint64_t val)
Definition: debug_info.h:326
bloaty::dwarf::CU::AddIndirectString
void AddIndirectString(absl::string_view range) const
Definition: debug_info.h:254
bloaty::dwarf::InfoReader::abbrev_tables_
std::unordered_map< uint64_t, AbbrevTable > abbrev_tables_
Definition: debug_info.h:222
bloaty::dwarf::CUIter
Definition: debug_info.h:225
bloaty::dwarf::AbbrevTable::abbrev_data_
absl::string_view abbrev_data_
Definition: debug_info.h:190
bloaty::dwarf::DIEReader::SkipNullEntries
void SkipNullEntries()
Definition: debug_info.cc:235
bloaty::dwarf::File::debug_ranges
absl::string_view debug_ranges
Definition: debug_info.h:73
code
Definition: bloaty/third_party/zlib/contrib/infback9/inftree9.h:24
bloaty::dwarf::CU::unit_type_offset_
uint64_t unit_type_offset_
Definition: debug_info.h:291
bloaty::dwarf::CU::unit_type_
uint8_t unit_type_
Definition: debug_info.h:286
function
std::function< bool(GrpcTool *, int, const char **, const CliCredentials &, GrpcToolOutputCallback)> function
Definition: grpc_tool.cc:250
bloaty::dwarf::CompilationUnitSizes::dwarf_version_
uint16_t dwarf_version_
Definition: debug_info.h:134
bloaty::dwarf::CU::addr_base
uint64_t addr_base() const
Definition: debug_info.h:249
bloaty::dwarf::File::debug_aranges
absl::string_view debug_aranges
Definition: debug_info.h:67
bloaty::dwarf::AbbrevTable::abbrev_
std::unordered_map< uint32_t, Abbrev > abbrev_
Definition: debug_info.h:189
bloaty::dwarf::AbbrevTable::Abbrev::tag
uint16_t tag
Definition: debug_info.h:165
bloaty::dwarf::File
Definition: debug_info.h:64
addr
struct sockaddr_in addr
Definition: libuv/docs/code/tcp-echo-server/main.c:10
bloaty::dwarf::CUIter::NextCU
bool NextCU(InfoReader &reader, CU *cu)
Definition: debug_info.cc:108
reader
void reader(void *n)
Definition: libuv/docs/code/locks/main.c:8
offset
voidpf uLong offset
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:142
bloaty::dwarf::AbbrevTable::Abbrev
Definition: debug_info.h:163
bloaty::dwarf::AttrValue
Definition: attr.h:28


grpc
Author(s):
autogenerated on Thu Mar 13 2025 02:59:02