dwarf.cc
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 #include <assert.h>
16 #include <stdio.h>
17 
18 #include <algorithm>
19 #include <initializer_list>
20 #include <iostream>
21 #include <limits>
22 #include <memory>
23 #include <stack>
24 #include <unordered_map>
25 #include <unordered_set>
26 #include <vector>
27 
28 #include "absl/base/attributes.h"
29 #include "absl/base/macros.h"
30 #include "absl/strings/string_view.h"
31 #include "absl/strings/substitute.h"
32 #include "absl/types/optional.h"
33 #include "bloaty.h"
34 #include "bloaty.pb.h"
35 #include "dwarf_constants.h"
36 #include "util.h"
37 #include "dwarf/attr.h"
38 #include "dwarf/dwarf_util.h"
39 #include "dwarf/line_info.h"
40 
41 using namespace dwarf2reader;
42 using absl::string_view;
43 
44 namespace bloaty {
45 
46 extern int verbose_level;
47 
48 namespace dwarf {
49 
50 // AddressRanges ///////////////////////////////////////////////////////////////
51 
52 // Code for reading address ranges out of .debug_aranges.
53 
55  public:
56  AddressRanges(string_view data) : section_(data), next_unit_(data) {}
57 
58  // Offset into .debug_info for the current compilation unit.
59  uint64_t debug_info_offset() { return debug_info_offset_; }
60 
61  // Address and length for this range.
62  uint64_t address() { return address_; }
63  uint64_t length() { return length_; }
64  // The range of the file where this data occurs.
65  string_view data() { return data_; }
66 
67  // Advance to the next range. The values will be available in address() and
68  // length(). Returns false when the end of this compilation unit is hit.
69  // Must call this once before reading the first range.
70  bool NextRange();
71 
72  // Advance to the next compilation unit. The unit offset will be available in
73  // debug_info_offset(). Must call this once before reading the first unit.
74  bool NextUnit();
75 
76  uint8_t address_size() const { return sizes_.address_size(); }
77 
78  private:
87 };
88 
89 bool AddressRanges::NextRange() {
90  if (unit_remaining_.empty()) {
91  return false;
92  }
93 
94  const char* start = unit_remaining_.data();
95  address_ = sizes_.ReadAddress(&unit_remaining_);
96  length_ = sizes_.ReadAddress(&unit_remaining_);
97  data_ = string_view(start, unit_remaining_.data() - start);
98  return true;
99 }
100 
101 bool AddressRanges::NextUnit() {
102  if (next_unit_.empty()) {
103  return false;
104  }
105 
106  unit_remaining_ = sizes_.ReadInitialLength(&next_unit_);
107  sizes_.ReadDWARFVersion(&unit_remaining_);
108 
109  if (sizes_.dwarf_version() > 4) {
110  THROW("DWARF data is too new for us");
111  }
112 
113  debug_info_offset_ = sizes_.ReadDWARFOffset(&unit_remaining_);
114 
115  uint8_t segment_size;
116 
117  sizes_.SetAddressSize(ReadFixed<uint8_t>(&unit_remaining_));
118  segment_size = ReadFixed<uint8_t>(&unit_remaining_);
119 
120  if (segment_size) {
121  THROW("we don't know how to handle segmented addresses.");
122  }
123 
124  size_t ofs = unit_remaining_.data() - section_.data();
125  size_t aligned_ofs = AlignUp(ofs, sizes_.address_size() * 2);
126  SkipBytes(aligned_ofs - ofs, &unit_remaining_);
127  return true;
128 }
129 
130 
131 // LocationList ////////////////////////////////////////////////////////////////
132 
133 // Code for reading entries out of a location list.
134 // For the moment we only care about finding the bounds of a list given its
135 // offset, so we don't actually vend any of the data.
136 
138  public:
140  : sizes_(sizes), remaining_(data) {}
141 
142  const char* read_offset() const { return remaining_.data(); }
143  bool NextEntry();
144 
145  private:
148 };
149 
150 bool LocationList::NextEntry() {
151  uint64_t start, end;
152  start = sizes_.ReadAddress(&remaining_);
153  end = sizes_.ReadAddress(&remaining_);
154  if (start == 0 && end == 0) {
155  return false;
156  } else if (start == UINT64_MAX ||
157  (start == UINT32_MAX && sizes_.address_size() == 4)) {
158  // Base address selection, nothing more to do.
159  } else {
160  // Need to skip the location description.
161  uint16_t length = ReadFixed<uint16_t>(&remaining_);
163  }
164  return true;
165 }
166 
168  string_view available) {
169  LocationList list(sizes, available);
170  while (list.NextEntry()) {}
171  return available.substr(0, list.read_offset() - available.data());
172 }
173 
174 // RangeList ///////////////////////////////////////////////////////////////////
175 
176 void ReadRangeList(const CU& cu, uint64_t low_pc, string_view name,
178  std::string name_str(name);
179  uint64_t max_address = cu.unit_sizes().MaxAddress();
180  while (true) {
181  uint64_t start, end;
183  end = cu.unit_sizes().ReadAddress(data);
184  if (start == 0 && end == 0) {
185  return;
186  } else if (start == max_address) {
187  low_pc = end;
188  } else {
189  uint64_t size = end - start;
190  sink->AddVMRangeIgnoreDuplicate("dwarf_rangelist", low_pc + start, size,
191  name_str);
192  }
193  }
194 }
195 
196 string_view* File::GetFieldByName(string_view name) {
197  if (name == "aranges") {
198  return &debug_aranges;
199  } else if (name == "addr") {
200  return &debug_addr;
201  } else if (name == "str") {
202  return &debug_str;
203  } else if (name == "str_offsets") {
204  return &debug_str_offsets;
205  } else if (name == "info") {
206  return &debug_info;
207  } else if (name == "types") {
208  return &debug_types;
209  } else if (name == "abbrev") {
210  return &debug_abbrev;
211  } else if (name == "line") {
212  return &debug_line;
213  } else if (name == "loc") {
214  return &debug_loc;
215  } else if (name == "pubnames") {
216  return &debug_pubnames;
217  } else if (name == "pubtypes") {
218  return &debug_pubtypes;
219  } else if (name == "ranges") {
220  return &debug_ranges;
221  } else if (name == "rnglists") {
222  return &debug_rnglists;
223  } else {
224  return nullptr;
225  }
226 }
227 
228 } // namespace dwarf
229 
230 // Bloaty DWARF Data Sources ///////////////////////////////////////////////////
231 
232 // The DWARF .debug_aranges section should, in theory, give us exactly the
233 // information we need to map file ranges in linked binaries to compilation
234 // units from where that code came. However, .debug_aranges is often incomplete
235 // or missing completely, so we use it as just one of several data sources for
236 // the "compileunits" data source.
238  // Maps compilation unit offset -> source filename
239  // Lazily initialized.
240  class FilenameMap {
241  public:
242  FilenameMap(const dwarf::File& file)
243  : info_reader_(file),
244  missing_("[DWARF is missing filename]") {}
245 
246  std::string GetFilename(uint64_t compilation_unit_offset) {
247  auto& name = map_[compilation_unit_offset];
248  if (name.empty()) {
249  name = LookupFilename(compilation_unit_offset);
250  }
251  return name;
252  }
253 
254  private:
255  bool ReadName(std::string* name, uint64_t offset) {
256  auto sec = dwarf::InfoReader::Section::kDebugInfo;
257  dwarf::CUIter iter = info_reader_.GetCUIter(sec, offset);
258  dwarf::CU cu;
259  if (!iter.NextCU(info_reader_, &cu)) {
260  return false;
261  }
262  *name = cu.unit_name();
263  return true;
264  }
265 
266  std::string LookupFilename(uint64_t compilation_unit_offset) {
268  if (ReadName(&name, compilation_unit_offset)) {
269  return name;
270  } else {
271  return missing_;
272  }
273  }
274 
275  dwarf::InfoReader info_reader_;
276  std::unordered_map<uint64_t, std::string> map_;
277  std::string missing_;
278  } map(file);
279 
280  dwarf::AddressRanges ranges(file.debug_aranges);
281 
282  while (ranges.NextUnit()) {
283  std::string filename = map.GetFilename(ranges.debug_info_offset());
284 
285  while (ranges.NextRange()) {
286  if (dwarf::IsValidDwarfAddress(ranges.address(), ranges.address_size())) {
287  sink->AddVMRangeIgnoreDuplicate("dwarf_aranges", ranges.address(),
288  ranges.length(), filename);
289  }
290  sink->AddFileRange("dwarf_aranges_data", filename, ranges.data());
291  }
292  }
293 
294  return true;
295 }
296 
297 struct GeneralDIE {
308  bool declaration = false;
309 };
310 
312  GeneralDIE* die) {
313  switch (tag) {
314  case DW_AT_name:
315  if (val.IsString()) {
316  die->name = val.GetString(cu);
317  }
318  break;
319  case DW_AT_declaration:
320  if (auto uint = val.ToUint(cu)) {
321  die->declaration = *uint;
322  }
323  break;
324  case DW_AT_location:
325  if (val.IsString()) {
326  die->location_string = val.GetString(cu);
327  } else if (val.form() == DW_FORM_sec_offset) {
328  die->location_uint64 = val.GetUint(cu);
329  }
330  break;
331  case DW_AT_low_pc:
332  if (auto uint = val.ToUint(cu)) {
333  die->low_pc = *uint;
334  }
335  break;
336  case DW_AT_high_pc:
337  switch (val.form()) {
338  case DW_FORM_addr:
339  case DW_FORM_addrx:
340  case DW_FORM_addrx1:
341  case DW_FORM_addrx2:
342  case DW_FORM_addrx3:
343  case DW_FORM_addrx4:
344  // high_pc is absolute.
345  die->high_pc_addr = val.GetUint(cu);
346  break;
347  case DW_FORM_data1:
348  case DW_FORM_data2:
349  case DW_FORM_data4:
350  case DW_FORM_data8:
351  // high_pc is a size.
352  die->high_pc_size = val.ToUint(cu);
353  break;
354  default:
355  if (verbose_level > 0) {
356  fprintf(stderr, "Unexpected form for high_pc: %d\n", val.form());
357  }
358  break;
359  }
360  break;
361  case DW_AT_stmt_list:
362  if (auto uint = val.ToUint(cu)) {
363  die->stmt_list = *uint;
364  }
365  break;
366  case DW_AT_ranges:
367  if (auto uint = val.ToUint(cu)) {
368  if (val.form() == DW_FORM_rnglistx) {
369  die->rnglistx = *uint;
370  } else {
371  die->ranges = *uint;
372  }
373  }
374  break;
375  case DW_AT_start_scope:
376  if (auto uint = val.ToUint(cu)) {
377  die->start_scope = *uint;
378  }
379  break;
380  }
381 }
382 
384  RangeSink* sink) {
385  uint64_t addr;
386  uint64_t size;
387 
388  if (!die.low_pc) return 0;
389  addr = *die.low_pc;
390 
391  if (die.high_pc_addr) {
392  size = *die.high_pc_addr - addr;
393  } else if (die.high_pc_size) {
394  size = *die.high_pc_size;
395  } else{
396  return 0;
397  }
398 
399  sink->AddVMRangeIgnoreDuplicate("dwarf_pcpair", addr, size, cu.unit_name());
400  return addr;
401 }
402 
403 // To view DIEs for a given file, try:
404 // readelf --debug-dump=info foo.bin
405 void AddDIE(const dwarf::CU& cu, const GeneralDIE& die,
406  const DualMap& symbol_map, RangeSink* sink) {
407  uint64_t low_pc = TryReadPcPair(cu, die, sink);
408 
409  // Sometimes the DIE has a "location", which gives the location as an address.
410  // This parses a very small subset of the overall DWARF expression grammar.
411  if (die.location_string) {
412  string_view location = *die.location_string;
413  if (location.size() == cu.unit_sizes().address_size() + 1 &&
414  location[0] == DW_OP_addr) {
415  location.remove_prefix(1);
416  uint64_t addr;
417  // TODO(haberman): endian?
418  if (cu.unit_sizes().address_size() == 4) {
419  addr = ReadFixed<uint32_t>(&location);
420  } else if (cu.unit_sizes().address_size() == 8) {
421  addr = ReadFixed<uint64_t>(&location);
422  } else {
424  }
425 
426  // Unfortunately the location doesn't include a size, so we look that part
427  // up in the symbol map.
428  uint64_t size;
429  if (symbol_map.vm_map.TryGetSize(addr, &size)) {
430  sink->AddVMRangeIgnoreDuplicate("dwarf_location", addr, size,
431  cu.unit_name());
432  } else {
433  if (verbose_level > 0) {
434  fprintf(stderr,
435  "bloaty: warning: couldn't find DWARF location in symbol "
436  "table, address: %" PRIx64 ", name: %s\n",
437  addr, cu.unit_name().c_str());
438  }
439  }
440  }
441  }
442 
443  // Sometimes a location is given as an offset into debug_loc.
444  if (die.location_uint64) {
445  uint64_t location = *die.location_uint64;;
446  if (location < cu.dwarf().debug_loc.size()) {
447  absl::string_view loc_range = cu.dwarf().debug_loc.substr(location);
448  loc_range = GetLocationListRange(cu.unit_sizes(), loc_range);
449  sink->AddFileRange("dwarf_locrange", cu.unit_name(), loc_range);
450  } else if (verbose_level > 0) {
451  fprintf(stderr,
452  "bloaty: warning: DWARF location out of range, location=%" PRIx64
453  "\n",
454  location);
455  }
456  }
457 
458  // DWARF 5 range list is the same information as "ranges" but in a different
459  // format.
460  if (die.rnglistx) {
461  uint64_t range_list = *die.rnglistx;
462  size_t offset_size = cu.unit_sizes().dwarf64() ? 8 : 4;
463  string_view offset_data =
465  cu.range_lists_base() + (range_list * offset_size));
466  uint64_t offset = cu.unit_sizes().ReadDWARFOffset(&offset_data);
469  const char* start = data.data();
470  bool done = false;
471  uint64_t base_address = cu.addr_base();
472  while (!done) {
473  switch (ReadFixed<uint8_t>(&data)) {
474  case DW_RLE_end_of_list:
475  done = true;
476  break;
478  base_address =
479  ReadIndirectAddress(cu, dwarf::ReadLEB128<uint64_t>(&data));
480  break;
481  case DW_RLE_startx_endx: {
482  uint64_t start =
483  ReadIndirectAddress(cu, dwarf::ReadLEB128<uint64_t>(&data));
484  uint64_t end =
485  ReadIndirectAddress(cu, dwarf::ReadLEB128<uint64_t>(&data));
486  sink->AddVMRangeIgnoreDuplicate("dwarf_rangelst", start, end - start,
487  cu.unit_name());
488  break;
489  }
490  case DW_RLE_startx_length: {
491  uint64_t start =
492  ReadIndirectAddress(cu, dwarf::ReadLEB128<uint64_t>(&data));
493  uint64_t length = dwarf::ReadLEB128<uint64_t>(&data);
494  sink->AddVMRangeIgnoreDuplicate("dwarf_rangelst", start, length,
495  cu.unit_name());
496  break;
497  }
498  case DW_RLE_offset_pair: {
499  uint64_t start = dwarf::ReadLEB128<uint64_t>(&data) + base_address;
500  uint64_t end = dwarf::ReadLEB128<uint64_t>(&data) + base_address;
501  sink->AddVMRangeIgnoreDuplicate("dwarf_rangelst", start, end - start,
502  cu.unit_name());
503  break;
504  }
505  case DW_RLE_base_address:
506  case DW_RLE_start_end:
507  case DW_RLE_start_length:
508  THROW("NYI");
509  break;
510  }
511  }
512  string_view all(start, data.data() - start);
513  sink->AddFileRange("dwarf_rangelst_addrs", cu.unit_name(), all);
514  } else {
515  uint64_t ranges_offset = UINT64_MAX;
516 
517  // There are two different attributes that sometimes contain an offset into
518  // debug_ranges.
519  if (die.ranges) {
520  ranges_offset = *die.ranges;
521  } else if (die.start_scope) {
522  ranges_offset = *die.start_scope;
523  }
524 
525  if (ranges_offset != UINT64_MAX) {
526  if (ranges_offset < cu.dwarf().debug_ranges.size()) {
527  absl::string_view data = cu.dwarf().debug_ranges.substr(ranges_offset);
528  const char* start = data.data();
529  ReadRangeList(cu, low_pc, cu.unit_name(), sink, &data);
530  string_view all(start, data.data() - start);
531  sink->AddFileRange("dwarf_debugrange", cu.unit_name(), all);
532  } else if (verbose_level > 0) {
533  fprintf(stderr,
534  "bloaty: warning: DWARF debug range out of range, "
535  "ranges_offset=%" PRIx64 "\n",
536  ranges_offset);
537  }
538  }
539  }
540 }
541 
543  RangeSink* sink) {
544  string_view remaining = section;
545 
546  while (remaining.size() > 0) {
548  string_view full_unit = remaining;
549  string_view unit = sizes.ReadInitialLength(&remaining);
550  full_unit =
551  full_unit.substr(0, unit.size() + (unit.data() - full_unit.data()));
552  sizes.ReadDWARFVersion(&unit);
553  uint64_t debug_info_offset = sizes.ReadDWARFOffset(&unit);
554 
555  dwarf::CUIter iter = reader.GetCUIter(
556  dwarf::InfoReader::Section::kDebugInfo, debug_info_offset);
557  dwarf::CU cu;
558  if (iter.NextCU(reader, &cu) && !cu.unit_name().empty()) {
559  sink->AddFileRange("dwarf_pubnames", cu.unit_name(), full_unit);
560  }
561  }
562 }
563 
565  RangeSink* sink) {
567  SkipBytes(offset, &data);
568  string_view data_with_length = data;
570  data = sizes.ReadInitialLength(&data);
571  data = data_with_length.substr(
572  0, data.size() + (data.data() - data_with_length.data()));
573  sink->AddFileRange("dwarf_stmtlistrange", cu.unit_name(), data);
574 }
575 
576 // The DWARF debug info can help us get compileunits info. DIEs for compilation
577 // units, functions, and global variables often have attributes that will
578 // resolve to addresses.
581  const DualMap& symbol_map, RangeSink* sink) {
582  dwarf::CUIter iter = reader.GetCUIter(section);
583  dwarf::CU cu;
585  sink->AddFileRange("dwarf_strp", cu.unit_name(), str);
586  });
587 
588  while (iter.NextCU(reader, &cu)) {
589  dwarf::DIEReader die_reader = cu.GetDIEReader();
590  GeneralDIE compileunit_die;
591  auto* abbrev = die_reader.ReadCode(cu);
592  die_reader.ReadAttributes(
593  cu, abbrev,
594  [&cu, &compileunit_die](uint16_t tag, dwarf::AttrValue value) {
595  ReadGeneralDIEAttr(tag, value, cu, &compileunit_die);
596  });
597 
598  if (cu.unit_name().empty()) {
599  continue;
600  }
601 
602  sink->AddFileRange("dwarf_debuginfo", cu.unit_name(), cu.entire_unit());
603  AddDIE(cu, compileunit_die, symbol_map, sink);
604 
605  if (compileunit_die.stmt_list) {
606  ReadDWARFStmtListRange(cu, *compileunit_die.stmt_list, sink);
607  }
608 
609  sink->AddFileRange("dwarf_abbrev", cu.unit_name(), cu.unit_abbrev().abbrev_data());
610 
611  while (auto abbrev = die_reader.ReadCode(cu)) {
612  GeneralDIE die;
613  die_reader.ReadAttributes(
614  cu, abbrev, [&cu, &die](uint16_t tag, dwarf::AttrValue value) {
615  ReadGeneralDIEAttr(tag, value, cu, &die);
616  });
617 
618  // low_pc == 0 is a signal that this routine was stripped out of the
619  // final binary. Also any declaration should be skipped.
620  if ((die.low_pc && !cu.IsValidDwarfAddress(*die.low_pc)) ||
621  die.declaration) {
622  die_reader.SkipChildren(cu, abbrev);
623  } else {
624  AddDIE(cu, die, symbol_map, sink);
625  }
626  }
627  }
628 }
629 
630 void ReadDWARFCompileUnits(const dwarf::File& file, const DualMap& symbol_map,
631  RangeSink* sink) {
632  if (!file.debug_info.size()) {
633  THROW("missing debug info");
634  }
635 
636  if (file.debug_aranges.size()) {
638  }
639 
640  // Share a reader to avoid re-parsing debug abbreviations.
642 
643  ReadDWARFDebugInfo(reader, dwarf::InfoReader::Section::kDebugInfo, symbol_map,
644  sink);
645  ReadDWARFDebugInfo(reader, dwarf::InfoReader::Section::kDebugTypes,
646  symbol_map, sink);
647  ReadDWARFPubNames(reader, file.debug_pubnames, sink);
648  ReadDWARFPubNames(reader, file.debug_pubtypes, sink);
649 }
650 
652  bool include_line) {
653  if (include_line) {
654  return file + ":" + std::to_string(line);
655  } else {
656  return file;
657  }
658 }
659 
660 static void ReadDWARFStmtList(bool include_line,
661  dwarf::LineInfoReader* line_info_reader,
662  RangeSink* sink) {
663  uint64_t span_startaddr = 0;
664  std::string last_source;
665 
666  while (line_info_reader->ReadLineInfo()) {
667  const auto& line_info = line_info_reader->lineinfo();
668  auto addr = line_info.address;
669  auto number = line_info.line;
670  auto name =
671  line_info.end_sequence
672  ? last_source
673  : LineInfoKey(line_info_reader->GetExpandedFilename(line_info.file),
674  number, include_line);
675  if (!span_startaddr) {
676  span_startaddr = addr;
677  } else if (line_info.end_sequence ||
678  (!last_source.empty() && name != last_source)) {
679  sink->AddVMRange("dwarf_stmtlist", span_startaddr, addr - span_startaddr,
680  last_source);
681  if (line_info.end_sequence) {
682  span_startaddr = 0;
683  } else {
684  span_startaddr = addr;
685  }
686  }
687  last_source = name;
688  }
689 }
690 
692  bool include_line) {
693  if (!file.debug_info.size() || !file.debug_line.size()) {
694  THROW("no debug info");
695  }
696 
698  dwarf::CUIter iter = reader.GetCUIter(dwarf::InfoReader::Section::kDebugInfo);
699  dwarf::CU cu;
700  dwarf::DIEReader die_reader = cu.GetDIEReader();
701  dwarf::LineInfoReader line_info_reader(file);
702 
703  if (!iter.NextCU(reader, &cu)) {
704  THROW("debug info is present, but empty");
705  }
706 
707  while (auto abbrev = die_reader.ReadCode(cu)) {
708  absl::optional<uint64_t> stmt_list;
709  die_reader.ReadAttributes(
710  cu, abbrev, [&stmt_list, &cu](uint16_t tag, dwarf::AttrValue val) {
711  if (tag == DW_AT_stmt_list) {
712  stmt_list = val.ToUint(cu);
713  }
714  });
715 
716  if (stmt_list) {
717  line_info_reader.SeekToOffset(*stmt_list, cu.unit_sizes().address_size());
718  ReadDWARFStmtList(include_line, &line_info_reader, sink);
719  }
720  }
721 }
722 
723 } // namespace bloaty
xds_interop_client.str
str
Definition: xds_interop_client.py:487
dwarf2reader::DW_FORM_data8
@ DW_FORM_data8
Definition: dwarf_constants.h:134
bloaty::dwarf::DIEReader::ReadCode
const AbbrevTable::Abbrev * ReadCode(const CU &cu)
Definition: debug_info.cc:243
test_group_name.all
all
Definition: test_group_name.py:241
dwarf2reader::DW_FORM_addrx
@ DW_FORM_addrx
Definition: dwarf_constants.h:156
bloaty::dwarf::AddressRanges::length
uint64_t length()
Definition: dwarf.cc:63
bloaty::dwarf::AbbrevTable::abbrev_data
absl::string_view abbrev_data() const
Definition: debug_info.h:171
filename
const char * filename
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:135
bloaty
Definition: bloaty.cc:69
bloaty::ReadDWARFStmtList
static void ReadDWARFStmtList(bool include_line, dwarf::LineInfoReader *line_info_reader, RangeSink *sink)
Definition: dwarf.cc:660
attr.h
bloaty::dwarf::AddressRanges::unit_remaining_
string_view unit_remaining_
Definition: dwarf.cc:82
dwarf2reader::DW_FORM_addrx4
@ DW_FORM_addrx4
Definition: dwarf_constants.h:175
bloaty::dwarf::AttrValue::GetUint
uint64_t GetUint(const CU &cu) const
Definition: attr.cc:44
bloaty::dwarf::AddressRanges::AddressRanges
AddressRanges(string_view data)
Definition: dwarf.cc:56
bloaty::GeneralDIE::declaration
bool declaration
Definition: dwarf.cc:308
bloaty::dwarf::File::debug_rnglists
absl::string_view debug_rnglists
Definition: debug_info.h:74
bloaty::dwarf::AddressRanges::address_size
uint8_t address_size() const
Definition: dwarf.cc:76
section
OPENSSL_EXPORT const char * section
Definition: conf.h:114
bloaty::dwarf::AddressRanges::address_
uint64_t address_
Definition: dwarf.cc:85
file
const grpc_generator::File * file
Definition: python_private_generator.h:38
bloaty::dwarf::LineInfoReader::ReadLineInfo
bool ReadLineInfo()
Definition: line_info.cc:150
dwarf2reader::DW_AT_declaration
@ DW_AT_declaration
Definition: dwarf_constants.h:227
uint16_t
unsigned short uint16_t
Definition: stdint-msvc2008.h:79
bloaty::dwarf::DIEReader
Definition: debug_info.h:304
bloaty::verbose_level
int verbose_level
Definition: bloaty.cc:74
bloaty::DualMap::vm_map
RangeMap vm_map
Definition: bloaty.h:313
bloaty::ReadGeneralDIEAttr
void ReadGeneralDIEAttr(uint16_t tag, dwarf::AttrValue val, const dwarf::CU &cu, GeneralDIE *die)
Definition: dwarf.cc:311
bloaty::ReadDWARFAddressRanges
static bool ReadDWARFAddressRanges(const dwarf::File &file, RangeSink *sink)
Definition: dwarf.cc:237
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
bloaty::dwarf::LocationList
Definition: dwarf.cc:137
bloaty::GeneralDIE::high_pc_size
absl::optional< uint64_t > high_pc_size
Definition: dwarf.cc:303
dwarf2reader::DW_FORM_addrx2
@ DW_FORM_addrx2
Definition: dwarf_constants.h:173
dwarf2reader::DW_RLE_end_of_list
@ DW_RLE_end_of_list
Definition: dwarf_constants.h:697
bloaty.h
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
address_
ServerAddress address_
Definition: ring_hash.cc:194
UINT64_MAX
#define UINT64_MAX
Definition: stdint-msvc2008.h:143
bloaty::dwarf::LocationList::sizes_
CompilationUnitSizes sizes_
Definition: dwarf.cc:146
UINT32_MAX
#define UINT32_MAX
Definition: stdint-msvc2008.h:142
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
absl::flags_internal::AlignUp
constexpr size_t AlignUp(size_t x, size_t align)
Definition: abseil-cpp/absl/flags/internal/sequence_lock.h:33
dwarf2reader::DW_RLE_start_end
@ DW_RLE_start_end
Definition: dwarf_constants.h:703
setup.name
name
Definition: setup.py:542
bloaty::dwarf::LineInfoReader
Definition: line_info.h:39
dwarf2reader::DW_FORM_data2
@ DW_FORM_data2
Definition: dwarf_constants.h:132
bloaty::dwarf::GetLocationListRange
string_view GetLocationListRange(CompilationUnitSizes sizes, string_view available)
Definition: dwarf.cc:167
bloaty::dwarf::AddressRanges::section_
string_view section_
Definition: dwarf.cc:81
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
map
zval * map
Definition: php/ext/google/protobuf/encode_decode.c:480
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
bloaty::GeneralDIE::ranges
absl::optional< uint64_t > ranges
Definition: dwarf.cc:306
remaining_
string_view remaining_
Definition: elf.cc:155
python_utils.port_server.stderr
stderr
Definition: port_server.py:51
line_info.h
bloaty::dwarf::AddressRanges::data_
string_view data_
Definition: dwarf.cc:80
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::GeneralDIE::low_pc
absl::optional< uint64_t > low_pc
Definition: dwarf.cc:301
dwarf2reader::DW_FORM_addr
@ DW_FORM_addr
Definition: dwarf_constants.h:129
start
static uint64_t start
Definition: benchmark-pound.c:74
bloaty::dwarf::LocationList::remaining_
string_view remaining_
Definition: dwarf.cc:147
bloaty::SkipBytes
void SkipBytes(size_t bytes, absl::string_view *data)
Definition: bloaty/src/util.h:174
dwarf2reader::DW_RLE_base_address
@ DW_RLE_base_address
Definition: dwarf_constants.h:702
end
char * end
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1008
bloaty::dwarf::CU::unit_abbrev
const AbbrevTable & unit_abbrev() const
Definition: debug_info.h:252
absl::string_view::size
constexpr size_type size() const noexcept
Definition: abseil-cpp/absl/strings/string_view.h:277
bloaty::dwarf::AddressRanges::data
string_view data()
Definition: dwarf.cc:65
THROW
#define THROW(msg)
Definition: bloaty/src/util.h:45
tag
static void * tag(intptr_t t)
Definition: bad_client.cc:318
bloaty::dwarf::LocationList::LocationList
LocationList(CompilationUnitSizes sizes, string_view data)
Definition: dwarf.cc:139
dwarf2reader::DW_FORM_rnglistx
@ DW_FORM_rnglistx
Definition: dwarf_constants.h:166
bloaty::dwarf::CU
Definition: debug_info.h:241
dwarf_util.h
bloaty::RangeMap::TryGetSize
bool TryGetSize(uint64_t addr, uint64_t *size) const
Definition: range_map.cc:128
bloaty::GeneralDIE::location_string
absl::optional< string_view > location_string
Definition: dwarf.cc:299
dwarf2reader::DW_FORM_data1
@ DW_FORM_data1
Definition: dwarf_constants.h:138
dwarf_constants.h
bloaty::dwarf::ReadRangeList
void ReadRangeList(const CU &cu, uint64_t low_pc, string_view name, RangeSink *sink, string_view *data)
Definition: dwarf.cc:176
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::LineInfoReader::lineinfo
const LineInfo & lineinfo() const
Definition: line_info.h:68
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::AddressRanges::sizes_
CompilationUnitSizes sizes_
Definition: dwarf.cc:79
bloaty::dwarf::LineInfoReader::GetExpandedFilename
const std::string & GetExpandedFilename(size_t index)
Definition: line_info.cc:29
absl::optional
Definition: abseil-cpp/absl/types/internal/optional.h:61
dwarf2reader::DW_FORM_data4
@ DW_FORM_data4
Definition: dwarf_constants.h:133
bloaty::dwarf::File::debug_loc
absl::string_view debug_loc
Definition: debug_info.h:70
done
struct tab * done
Definition: bloaty/third_party/zlib/examples/enough.c:176
bloaty::dwarf::AddressRanges::next_unit_
string_view next_unit_
Definition: dwarf.cc:83
bloaty::dwarf::AddressRanges::length_
uint64_t length_
Definition: dwarf.cc:86
bloaty::GeneralDIE::start_scope
absl::optional< uint64_t > start_scope
Definition: dwarf.cc:307
bloaty::dwarf::CU::IsValidDwarfAddress
bool IsValidDwarfAddress(uint64_t addr) const
Definition: debug_info.h:265
bloaty::dwarf::AttrValue::form
uint16_t form() const
Definition: attr.h:35
dwarf2reader::DW_AT_name
@ DW_AT_name
Definition: dwarf_constants.h:185
number
int32_t number
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:850
dwarf2reader::DW_AT_high_pc
@ DW_AT_high_pc
Definition: dwarf_constants.h:194
bloaty::RangeSink
Definition: bloaty.h:110
dwarf2reader::DW_AT_stmt_list
@ DW_AT_stmt_list
Definition: dwarf_constants.h:192
dwarf2reader::DW_AT_location
@ DW_AT_location
Definition: dwarf_constants.h:184
bloaty::dwarf::AddressRanges::address
uint64_t address()
Definition: dwarf.cc:62
dwarf2reader
Definition: dwarf_constants.h:20
data
char data[kBufferLength]
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1006
uint
unsigned int uint
Definition: bloaty/third_party/zlib/examples/gzlog.c:242
bloaty::ReadDWARFDebugInfo
static void ReadDWARFDebugInfo(dwarf::InfoReader &reader, dwarf::InfoReader::Section section, const DualMap &symbol_map, RangeSink *sink)
Definition: dwarf.cc:579
bloaty::AddDIE
void AddDIE(const dwarf::CU &cu, const GeneralDIE &die, const DualMap &symbol_map, RangeSink *sink)
Definition: dwarf.cc:405
bloaty::dwarf::AttrValue::GetString
absl::string_view GetString(const CU &cu) const
Definition: attr.cc:53
bloaty::DualMap
Definition: bloaty.h:312
section
Definition: loader.h:337
bloaty::dwarf::AddressRanges
Definition: dwarf.cc:54
bloaty::dwarf::CompilationUnitSizes
Definition: debug_info.h:88
value
const char * value
Definition: hpack_parser_table.cc:165
bloaty::ReadDWARFPubNames
static void ReadDWARFPubNames(dwarf::InfoReader &reader, string_view section, RangeSink *sink)
Definition: dwarf.cc:542
dwarf2reader::DW_AT_low_pc
@ DW_AT_low_pc
Definition: dwarf_constants.h:193
bloaty::TryReadPcPair
uint64_t TryReadPcPair(const dwarf::CU &cu, const GeneralDIE &die, RangeSink *sink)
Definition: dwarf.cc:383
dwarf2reader::DW_RLE_base_addressx
@ DW_RLE_base_addressx
Definition: dwarf_constants.h:698
bloaty::dwarf::IsValidDwarfAddress
bool IsValidDwarfAddress(uint64_t addr, uint8_t address_size)
Definition: dwarf_util.cc:23
dwarf2reader::DW_RLE_startx_endx
@ DW_RLE_startx_endx
Definition: dwarf_constants.h:699
bloaty::dwarf::CU::entire_unit
absl::string_view entire_unit() const
Definition: debug_info.h:248
bloaty::dwarf::InfoReader
Definition: debug_info.h:198
bloaty::dwarf::LineInfoReader::SeekToOffset
void SeekToOffset(uint64_t offset, uint8_t address_size)
Definition: line_info.cc:76
bloaty::dwarf::AddressRanges::debug_info_offset_
uint64_t debug_info_offset_
Definition: dwarf.cc:84
bloaty::dwarf::CompilationUnitSizes::ReadInitialLength
absl::string_view ReadInitialLength(absl::string_view *remaining)
Definition: debug_info.cc:74
bloaty::dwarf::LocationList::NextEntry
bool NextEntry()
Definition: dwarf.cc:150
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
uint
#define uint
Definition: M68KDisassembler.c:64
dwarf2reader::DW_FORM_addrx3
@ DW_FORM_addrx3
Definition: dwarf_constants.h:174
sink
FormatSinkImpl * sink
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:450
absl::string_view::remove_prefix
ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR void remove_prefix(size_type n)
Definition: abseil-cpp/absl/strings/string_view.h:344
bloaty::dwarf::AddressRanges::NextUnit
bool NextUnit()
Definition: dwarf.cc:101
bloaty::dwarf::InfoReader::Section
Section
Definition: debug_info.h:207
dwarf2reader::DW_AT_ranges
@ DW_AT_ranges
Definition: dwarf_constants.h:253
bloaty::dwarf::LocationList::read_offset
const char * read_offset() const
Definition: dwarf.cc:142
string_view
absl::string_view string_view
Definition: attr.cc:22
bloaty::dwarf::DIEReader::SkipChildren
void SkipChildren(const CU &cu, const AbbrevTable::Abbrev *code)
Definition: debug_info.cc:259
bloaty::ReadDWARFStmtListRange
static void ReadDWARFStmtListRange(const dwarf::CU &cu, uint64_t offset, RangeSink *sink)
Definition: dwarf.cc:564
dwarf2reader::DW_AT_start_scope
@ DW_AT_start_scope
Definition: dwarf_constants.h:213
bloaty::dwarf::CU::dwarf
const File & dwarf() const
Definition: debug_info.h:245
file::size
int size
Definition: bloaty/third_party/zlib/examples/gzappend.c:172
bloaty::dwarf::CU::unit_sizes
const CompilationUnitSizes & unit_sizes() const
Definition: debug_info.h:246
regen-readme.line
line
Definition: regen-readme.py:30
dwarf2reader::DW_RLE_offset_pair
@ DW_RLE_offset_pair
Definition: dwarf_constants.h:701
bloaty::dwarf::AddressRanges::debug_info_offset
uint64_t debug_info_offset()
Definition: dwarf.cc:59
bloaty::dwarf::File::debug_line
absl::string_view debug_line
Definition: debug_info.h:69
data_
std::string data_
Definition: cord_rep_btree_navigator_test.cc:84
bloaty::GeneralDIE
Definition: dwarf.cc:297
bloaty::GeneralDIE::high_pc_addr
absl::optional< uint64_t > high_pc_addr
Definition: dwarf.cc:302
dwarf2reader::DW_FORM_sec_offset
@ DW_FORM_sec_offset
Definition: dwarf_constants.h:151
bloaty::dwarf::CompilationUnitSizes::ReadDWARFVersion
void ReadDWARFVersion(absl::string_view *data)
Definition: debug_info.h:129
bloaty::dwarf::ReadIndirectAddress
uint64_t ReadIndirectAddress(const CU &cu, uint64_t val)
Definition: debug_info.h:326
iter
Definition: test_winkernel.cpp:47
bloaty::dwarf::CUIter
Definition: debug_info.h:225
bloaty::GeneralDIE::rnglistx
absl::optional< uint64_t > rnglistx
Definition: dwarf.cc:305
util.h
bloaty::dwarf::File::debug_ranges
absl::string_view debug_ranges
Definition: debug_info.h:73
bloaty::GeneralDIE::location_uint64
absl::optional< uint64_t > location_uint64
Definition: dwarf.cc:300
size
voidpf void uLong size
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
length
std::size_t length
Definition: abseil-cpp/absl/time/internal/test_util.cc:57
bloaty::dwarf::CU::addr_base
uint64_t addr_base() const
Definition: debug_info.h:249
bloaty::GeneralDIE::name
absl::optional< string_view > name
Definition: dwarf.cc:298
dwarf2reader::DW_FORM_addrx1
@ DW_FORM_addrx1
Definition: dwarf_constants.h:172
bloaty::dwarf::AddressRanges::NextRange
bool NextRange()
Definition: dwarf.cc:89
absl::string_view::data
constexpr const_pointer data() const noexcept
Definition: abseil-cpp/absl/strings/string_view.h:336
bloaty::LineInfoKey
static std::string LineInfoKey(const std::string &file, uint32_t line, bool include_line)
Definition: dwarf.cc:651
to_string
static bool to_string(zval *from)
Definition: protobuf/php/ext/google/protobuf/convert.c:333
bloaty::StrictSubstr
absl::string_view StrictSubstr(absl::string_view data, size_t off, size_t n)
Definition: bloaty/src/util.h:89
bloaty::dwarf::File
Definition: debug_info.h:64
absl::string_view::substr
constexpr string_view substr(size_type pos=0, size_type n=npos) const
Definition: abseil-cpp/absl/strings/string_view.h:399
bloaty::dwarf::AttrValue::ToUint
absl::optional< uint64_t > ToUint(const CU &cu) const
Definition: attr.cc:28
addr
struct sockaddr_in addr
Definition: libuv/docs/code/tcp-echo-server/main.c:10
bloaty::dwarf::AttrValue::IsString
bool IsString() const
Definition: attr.h:41
bloaty::ReadDWARFInlines
void ReadDWARFInlines(const dwarf::File &file, RangeSink *sink, bool include_line)
Definition: dwarf.cc:691
reader
void reader(void *n)
Definition: libuv/docs/code/locks/main.c:8
bloaty::GeneralDIE::stmt_list
absl::optional< uint64_t > stmt_list
Definition: dwarf.cc:304
offset
voidpf uLong offset
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:142
dwarf2reader::DW_RLE_start_length
@ DW_RLE_start_length
Definition: dwarf_constants.h:704
dwarf2reader::DW_OP_addr
@ DW_OP_addr
Definition: dwarf_constants.h:487
bloaty::ReadDWARFCompileUnits
void ReadDWARFCompileUnits(const dwarf::File &file, const DualMap &map, RangeSink *sink)
Definition: dwarf.cc:630
bloaty::dwarf::AttrValue
Definition: attr.h:28
dwarf2reader::DW_RLE_startx_length
@ DW_RLE_startx_length
Definition: dwarf_constants.h:700


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