LLDB  mainline
DWARFDebugInfoEntry.cpp
Go to the documentation of this file.
1 //===-- DWARFDebugInfoEntry.cpp -------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "DWARFDebugInfoEntry.h"
10 
11 #include <cassert>
12 
13 #include <algorithm>
14 
15 #include "llvm/Support/LEB128.h"
16 
17 #include "lldb/Core/Module.h"
19 #include "lldb/Symbol/ObjectFile.h"
20 #include "lldb/Utility/Stream.h"
22 
23 #include "DWARFCompileUnit.h"
24 #include "DWARFDebugAbbrev.h"
25 #include "DWARFDebugAranges.h"
26 #include "DWARFDebugInfo.h"
27 #include "DWARFDebugRanges.h"
28 #include "DWARFDeclContext.h"
29 #include "DWARFFormValue.h"
30 #include "DWARFUnit.h"
31 #include "SymbolFileDWARF.h"
32 #include "SymbolFileDWARFDwo.h"
33 
34 using namespace lldb_private;
35 using namespace lldb_private::dwarf;
36 extern int g_verbose;
37 
38 // Extract a debug info entry for a given DWARFUnit from the data
39 // starting at the offset in offset_ptr
41  const DWARFUnit *cu,
42  lldb::offset_t *offset_ptr) {
43  m_offset = *offset_ptr;
44  m_parent_idx = 0;
45  m_sibling_idx = 0;
46  const uint64_t abbr_idx = data.GetULEB128(offset_ptr);
47  lldbassert(abbr_idx <= UINT16_MAX);
48  m_abbr_idx = abbr_idx;
49 
50  // assert (fixed_form_sizes); // For best performance this should be
51  // specified!
52 
53  if (m_abbr_idx == 0) {
54  m_tag = llvm::dwarf::DW_TAG_null;
55  m_has_children = false;
56  return true; // NULL debug tag entry
57  }
58 
59  lldb::offset_t offset = *offset_ptr;
60  const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu);
61  if (abbrevDecl == nullptr) {
62  cu->GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
63  "{0x%8.8x}: invalid abbreviation code %u, please file a bug and "
64  "attach the file at the start of this error message",
65  m_offset, (unsigned)abbr_idx);
66  // WE can't parse anymore if the DWARF is borked...
67  *offset_ptr = UINT32_MAX;
68  return false;
69  }
70  m_tag = abbrevDecl->Tag();
71  m_has_children = abbrevDecl->HasChildren();
72  // Skip all data in the .debug_info or .debug_types for the attributes
73  const uint32_t numAttributes = abbrevDecl->NumAttributes();
74  uint32_t i;
75  dw_form_t form;
76  for (i = 0; i < numAttributes; ++i) {
77  form = abbrevDecl->GetFormByIndexUnchecked(i);
78  llvm::Optional<uint8_t> fixed_skip_size =
80  if (fixed_skip_size)
81  offset += *fixed_skip_size;
82  else {
83  bool form_is_indirect = false;
84  do {
85  form_is_indirect = false;
86  uint32_t form_size = 0;
87  switch (form) {
88  // Blocks if inlined data that have a length field and the data bytes
89  // inlined in the .debug_info/.debug_types
90  case DW_FORM_exprloc:
91  case DW_FORM_block:
92  form_size = data.GetULEB128(&offset);
93  break;
94  case DW_FORM_block1:
95  form_size = data.GetU8_unchecked(&offset);
96  break;
97  case DW_FORM_block2:
98  form_size = data.GetU16_unchecked(&offset);
99  break;
100  case DW_FORM_block4:
101  form_size = data.GetU32_unchecked(&offset);
102  break;
103 
104  // Inlined NULL terminated C-strings
105  case DW_FORM_string:
106  data.GetCStr(&offset);
107  break;
108 
109  // Compile unit address sized values
110  case DW_FORM_addr:
111  form_size = cu->GetAddressByteSize();
112  break;
113  case DW_FORM_ref_addr:
114  if (cu->GetVersion() <= 2)
115  form_size = cu->GetAddressByteSize();
116  else
117  form_size = 4;
118  break;
119 
120  // 0 sized form
121  case DW_FORM_flag_present:
122  form_size = 0;
123  break;
124 
125  // 1 byte values
126  case DW_FORM_addrx1:
127  case DW_FORM_data1:
128  case DW_FORM_flag:
129  case DW_FORM_ref1:
130  case DW_FORM_strx1:
131  form_size = 1;
132  break;
133 
134  // 2 byte values
135  case DW_FORM_addrx2:
136  case DW_FORM_data2:
137  case DW_FORM_ref2:
138  case DW_FORM_strx2:
139  form_size = 2;
140  break;
141 
142  // 3 byte values
143  case DW_FORM_addrx3:
144  case DW_FORM_strx3:
145  form_size = 3;
146  break;
147 
148  // 4 byte values
149  case DW_FORM_addrx4:
150  case DW_FORM_data4:
151  case DW_FORM_ref4:
152  case DW_FORM_strx4:
153  form_size = 4;
154  break;
155 
156  // 8 byte values
157  case DW_FORM_data8:
158  case DW_FORM_ref8:
159  case DW_FORM_ref_sig8:
160  form_size = 8;
161  break;
162 
163  // signed or unsigned LEB 128 values
164  case DW_FORM_addrx:
165  case DW_FORM_loclistx:
166  case DW_FORM_rnglistx:
167  case DW_FORM_sdata:
168  case DW_FORM_udata:
169  case DW_FORM_ref_udata:
170  case DW_FORM_GNU_addr_index:
171  case DW_FORM_GNU_str_index:
172  case DW_FORM_strx:
173  data.Skip_LEB128(&offset);
174  break;
175 
176  case DW_FORM_indirect:
177  form_is_indirect = true;
178  form = data.GetULEB128(&offset);
179  break;
180 
181  case DW_FORM_strp:
182  case DW_FORM_line_strp:
183  case DW_FORM_sec_offset:
184  data.GetU32(&offset);
185  break;
186 
187  case DW_FORM_implicit_const:
188  form_size = 0;
189  break;
190 
191  default:
192  cu->GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
193  "{0x%8.8x}: Unsupported DW_FORM_0x%x, please file a bug and "
194  "attach the file at the start of this error message",
195  m_offset, (unsigned)form);
196  *offset_ptr = m_offset;
197  return false;
198  }
199  offset += form_size;
200 
201  } while (form_is_indirect);
202  }
203  }
204  *offset_ptr = offset;
205  return true;
206 }
207 
209  const DWARFDebugInfoEntry &die,
210  const DWARFFormValue &value) {
211  llvm::Expected<DWARFRangeList> expected_ranges =
212  (value.Form() == DW_FORM_rnglistx)
213  ? unit.FindRnglistFromIndex(value.Unsigned())
214  : unit.FindRnglistFromOffset(value.Unsigned());
215  if (expected_ranges)
216  return std::move(*expected_ranges);
217  unit.GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
218  "{0x%8.8x}: DIE has DW_AT_ranges(%s 0x%" PRIx64 ") attribute, but "
219  "range extraction failed (%s), please file a bug "
220  "and attach the file at the start of this error message",
221  die.GetOffset(),
222  llvm::dwarf::FormEncodingString(value.Form()).str().c_str(),
223  value.Unsigned(), toString(expected_ranges.takeError()).c_str());
224  return DWARFRangeList();
225 }
226 
227 // GetDIENamesAndRanges
228 //
229 // Gets the valid address ranges for a given DIE by looking for a
230 // DW_AT_low_pc/DW_AT_high_pc pair, DW_AT_entry_pc, or DW_AT_ranges attributes.
232  DWARFUnit *cu, const char *&name, const char *&mangled,
233  DWARFRangeList &ranges, int &decl_file, int &decl_line, int &decl_column,
234  int &call_file, int &call_line, int &call_column,
235  DWARFExpressionList *frame_base) const {
238  std::vector<DWARFDIE> dies;
239  bool set_frame_base_loclist_addr = false;
240 
241  const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu);
242 
244  lldb::ModuleSP module = dwarf.GetObjectFile()->GetModule();
245 
246  if (abbrevDecl) {
247  const DWARFDataExtractor &data = cu->GetData();
248  lldb::offset_t offset = GetFirstAttributeOffset();
249 
250  if (!data.ValidOffset(offset))
251  return false;
252 
253  const uint32_t numAttributes = abbrevDecl->NumAttributes();
254  bool do_offset = false;
255 
256  for (uint32_t i = 0; i < numAttributes; ++i) {
257  DWARFFormValue form_value(cu);
258  dw_attr_t attr;
259  abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value);
260 
261  if (form_value.ExtractValue(data, &offset)) {
262  switch (attr) {
263  case DW_AT_low_pc:
264  lo_pc = form_value.Address();
265 
266  if (do_offset)
267  hi_pc += lo_pc;
268  do_offset = false;
269  break;
270 
271  case DW_AT_entry_pc:
272  lo_pc = form_value.Address();
273  break;
274 
275  case DW_AT_high_pc:
276  if (form_value.Form() == DW_FORM_addr ||
277  form_value.Form() == DW_FORM_addrx ||
278  form_value.Form() == DW_FORM_GNU_addr_index) {
279  hi_pc = form_value.Address();
280  } else {
281  hi_pc = form_value.Unsigned();
282  if (lo_pc == LLDB_INVALID_ADDRESS)
283  do_offset = hi_pc != LLDB_INVALID_ADDRESS;
284  else
285  hi_pc += lo_pc; // DWARF 4 introduces <offset-from-lo-pc> to save
286  // on relocations
287  }
288  break;
289 
290  case DW_AT_ranges:
291  ranges = GetRangesOrReportError(*cu, *this, form_value);
292  break;
293 
294  case DW_AT_name:
295  if (name == nullptr)
296  name = form_value.AsCString();
297  break;
298 
299  case DW_AT_MIPS_linkage_name:
300  case DW_AT_linkage_name:
301  if (mangled == nullptr)
302  mangled = form_value.AsCString();
303  break;
304 
305  case DW_AT_abstract_origin:
306  dies.push_back(form_value.Reference());
307  break;
308 
309  case DW_AT_specification:
310  dies.push_back(form_value.Reference());
311  break;
312 
313  case DW_AT_decl_file:
314  if (decl_file == 0)
315  decl_file = form_value.Unsigned();
316  break;
317 
318  case DW_AT_decl_line:
319  if (decl_line == 0)
320  decl_line = form_value.Unsigned();
321  break;
322 
323  case DW_AT_decl_column:
324  if (decl_column == 0)
325  decl_column = form_value.Unsigned();
326  break;
327 
328  case DW_AT_call_file:
329  if (call_file == 0)
330  call_file = form_value.Unsigned();
331  break;
332 
333  case DW_AT_call_line:
334  if (call_line == 0)
335  call_line = form_value.Unsigned();
336  break;
337 
338  case DW_AT_call_column:
339  if (call_column == 0)
340  call_column = form_value.Unsigned();
341  break;
342 
343  case DW_AT_frame_base:
344  if (frame_base) {
345  if (form_value.BlockData()) {
346  uint32_t block_offset =
347  form_value.BlockData() - data.GetDataStart();
348  uint32_t block_length = form_value.Unsigned();
349  *frame_base =
350  DWARFExpressionList(module,
352  data, block_offset, block_length)),
353  cu);
354  } else {
355  DataExtractor data = cu->GetLocationData();
356  const dw_offset_t offset = form_value.Unsigned();
357  if (data.ValidOffset(offset)) {
358  data = DataExtractor(data, offset, data.GetByteSize() - offset);
359  if (lo_pc != LLDB_INVALID_ADDRESS) {
360  assert(lo_pc >= cu->GetBaseAddress());
361  DWARFExpression::ParseDWARFLocationList(cu, data, frame_base);
362  frame_base->SetFuncFileAddress(lo_pc);
363  } else
364  set_frame_base_loclist_addr = true;
365  }
366  }
367  }
368  break;
369 
370  default:
371  break;
372  }
373  }
374  }
375  }
376 
377  if (ranges.IsEmpty()) {
378  if (lo_pc != LLDB_INVALID_ADDRESS) {
379  if (hi_pc != LLDB_INVALID_ADDRESS && hi_pc > lo_pc)
380  ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc));
381  else
382  ranges.Append(DWARFRangeList::Entry(lo_pc, 0));
383  }
384  }
385 
386  if (set_frame_base_loclist_addr) {
387  dw_addr_t lowest_range_pc = ranges.GetMinRangeBase(0);
388  assert(lowest_range_pc >= cu->GetBaseAddress());
389  frame_base->SetFuncFileAddress(lowest_range_pc);
390  }
391 
392  if (ranges.IsEmpty() || name == nullptr || mangled == nullptr) {
393  for (const DWARFDIE &die : dies) {
394  if (die) {
395  die.GetDIE()->GetDIENamesAndRanges(die.GetCU(), name, mangled, ranges,
396  decl_file, decl_line, decl_column,
397  call_file, call_line, call_column);
398  }
399  }
400  }
401  return !ranges.IsEmpty();
402 }
403 
404 // Get all attribute values for a given DIE, including following any
405 // specification or abstract origin attributes and including those in the
406 // results. Any duplicate attributes will have the first instance take
407 // precedence (this can happen for declaration attributes).
409  DWARFAttributes &attributes,
410  Recurse recurse,
411  uint32_t curr_depth) const {
412  const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu);
413  if (abbrevDecl) {
414  const DWARFDataExtractor &data = cu->GetData();
415  lldb::offset_t offset = GetFirstAttributeOffset();
416 
417  const uint32_t num_attributes = abbrevDecl->NumAttributes();
418  for (uint32_t i = 0; i < num_attributes; ++i) {
419  DWARFFormValue form_value(cu);
420  dw_attr_t attr;
421  abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value);
422  const dw_form_t form = form_value.Form();
423 
424  // If we are tracking down DW_AT_specification or DW_AT_abstract_origin
425  // attributes, the depth will be non-zero. We need to omit certain
426  // attributes that don't make sense.
427  switch (attr) {
428  case DW_AT_sibling:
429  case DW_AT_declaration:
430  if (curr_depth > 0) {
431  // This attribute doesn't make sense when combined with the DIE that
432  // references this DIE. We know a DIE is referencing this DIE because
433  // curr_depth is not zero
434  break;
435  }
436  [[fallthrough]];
437  default:
438  attributes.Append(form_value, offset, attr);
439  break;
440  }
441 
442  if (recurse == Recurse::yes &&
443  ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin))) {
444  if (form_value.ExtractValue(data, &offset)) {
445  DWARFDIE spec_die = form_value.Reference();
446  if (spec_die)
447  spec_die.GetDIE()->GetAttributes(spec_die.GetCU(), attributes,
448  recurse, curr_depth + 1);
449  }
450  } else {
451  llvm::Optional<uint8_t> fixed_skip_size = DWARFFormValue::GetFixedSize(form, cu);
452  if (fixed_skip_size)
453  offset += *fixed_skip_size;
454  else
455  DWARFFormValue::SkipValue(form, data, &offset, cu);
456  }
457  }
458  } else {
459  attributes.Clear();
460  }
461  return attributes.Size();
462 }
463 
464 // GetAttributeValue
465 //
466 // Get the value of an attribute and return the .debug_info or .debug_types
467 // offset of the attribute if it was properly extracted into form_value,
468 // or zero if we fail since an offset of zero is invalid for an attribute (it
469 // would be a compile unit header).
471  const DWARFUnit *cu, const dw_attr_t attr, DWARFFormValue &form_value,
472  dw_offset_t *end_attr_offset_ptr,
473  bool check_specification_or_abstract_origin) const {
474  if (const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu)) {
475  uint32_t attr_idx = abbrevDecl->FindAttributeIndex(attr);
476 
477  if (attr_idx != DW_INVALID_INDEX) {
478  const DWARFDataExtractor &data = cu->GetData();
479  lldb::offset_t offset = GetFirstAttributeOffset();
480 
481  uint32_t idx = 0;
482  while (idx < attr_idx)
483  DWARFFormValue::SkipValue(abbrevDecl->GetFormByIndex(idx++),
484  data, &offset, cu);
485 
486  const dw_offset_t attr_offset = offset;
487  form_value.SetUnit(cu);
488  form_value.SetForm(abbrevDecl->GetFormByIndex(idx));
489  if (form_value.ExtractValue(data, &offset)) {
490  if (end_attr_offset_ptr)
491  *end_attr_offset_ptr = offset;
492  return attr_offset;
493  }
494  }
495  }
496 
497  if (check_specification_or_abstract_origin) {
498  if (GetAttributeValue(cu, DW_AT_specification, form_value)) {
499  DWARFDIE die = form_value.Reference();
500  if (die) {
501  dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(
502  die.GetCU(), attr, form_value, end_attr_offset_ptr, false);
503  if (die_offset)
504  return die_offset;
505  }
506  }
507 
508  if (GetAttributeValue(cu, DW_AT_abstract_origin, form_value)) {
509  DWARFDIE die = form_value.Reference();
510  if (die) {
511  dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(
512  die.GetCU(), attr, form_value, end_attr_offset_ptr, false);
513  if (die_offset)
514  return die_offset;
515  }
516  }
517  }
518  return 0;
519 }
520 
521 // GetAttributeValueAsString
522 //
523 // Get the value of an attribute as a string return it. The resulting pointer
524 // to the string data exists within the supplied SymbolFileDWARF and will only
525 // be available as long as the SymbolFileDWARF is still around and it's content
526 // doesn't change.
528  const DWARFUnit *cu, const dw_attr_t attr, const char *fail_value,
529  bool check_specification_or_abstract_origin) const {
530  DWARFFormValue form_value;
531  if (GetAttributeValue(cu, attr, form_value, nullptr,
532  check_specification_or_abstract_origin))
533  return form_value.AsCString();
534  return fail_value;
535 }
536 
537 // GetAttributeValueAsUnsigned
538 //
539 // Get the value of an attribute as unsigned and return it.
541  const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value,
542  bool check_specification_or_abstract_origin) const {
543  DWARFFormValue form_value;
544  if (GetAttributeValue(cu, attr, form_value, nullptr,
545  check_specification_or_abstract_origin))
546  return form_value.Unsigned();
547  return fail_value;
548 }
549 
550 llvm::Optional<uint64_t>
552  const DWARFUnit *cu, const dw_attr_t attr,
553  bool check_specification_or_abstract_origin) const {
554  DWARFFormValue form_value;
555  if (GetAttributeValue(cu, attr, form_value, nullptr,
556  check_specification_or_abstract_origin))
557  return form_value.Unsigned();
558  return llvm::None;
559 }
560 
561 // GetAttributeValueAsReference
562 //
563 // Get the value of an attribute as reference and fix up and compile unit
564 // relative offsets as needed.
566  const DWARFUnit *cu, const dw_attr_t attr,
567  bool check_specification_or_abstract_origin) const {
568  DWARFFormValue form_value;
569  if (GetAttributeValue(cu, attr, form_value, nullptr,
570  check_specification_or_abstract_origin))
571  return form_value.Reference();
572  return {};
573 }
574 
576  const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value,
577  bool check_specification_or_abstract_origin) const {
578  DWARFFormValue form_value;
579  if (GetAttributeValue(cu, attr, form_value, nullptr,
580  check_specification_or_abstract_origin))
581  return form_value.Address();
582  return fail_value;
583 }
584 
585 // GetAttributeHighPC
586 //
587 // Get the hi_pc, adding hi_pc to lo_pc when specified as an <offset-from-low-
588 // pc>.
589 //
590 // Returns the hi_pc or fail_value.
592  const DWARFUnit *cu, dw_addr_t lo_pc, uint64_t fail_value,
593  bool check_specification_or_abstract_origin) const {
594  DWARFFormValue form_value;
595  if (GetAttributeValue(cu, DW_AT_high_pc, form_value, nullptr,
596  check_specification_or_abstract_origin)) {
597  dw_form_t form = form_value.Form();
598  if (form == DW_FORM_addr || form == DW_FORM_addrx ||
599  form == DW_FORM_GNU_addr_index)
600  return form_value.Address();
601 
602  // DWARF4 can specify the hi_pc as an <offset-from-lowpc>
603  return lo_pc + form_value.Unsigned();
604  }
605  return fail_value;
606 }
607 
608 // GetAttributeAddressRange
609 //
610 // Get the lo_pc and hi_pc, adding hi_pc to lo_pc when specified as an <offset-
611 // from-low-pc>.
612 //
613 // Returns true or sets lo_pc and hi_pc to fail_value.
615  const DWARFUnit *cu, dw_addr_t &lo_pc, dw_addr_t &hi_pc,
616  uint64_t fail_value, bool check_specification_or_abstract_origin) const {
617  lo_pc = GetAttributeValueAsAddress(cu, DW_AT_low_pc, fail_value,
618  check_specification_or_abstract_origin);
619  if (lo_pc != fail_value) {
620  hi_pc = GetAttributeHighPC(cu, lo_pc, fail_value,
621  check_specification_or_abstract_origin);
622  if (hi_pc != fail_value)
623  return true;
624  }
625  lo_pc = fail_value;
626  hi_pc = fail_value;
627  return false;
628 }
629 
631  DWARFUnit *cu, DWARFRangeList &ranges, bool check_hi_lo_pc,
632  bool check_specification_or_abstract_origin) const {
633  ranges.Clear();
634 
635  DWARFFormValue form_value;
636  if (GetAttributeValue(cu, DW_AT_ranges, form_value)) {
637  ranges = GetRangesOrReportError(*cu, *this, form_value);
638  } else if (check_hi_lo_pc) {
641  if (GetAttributeAddressRange(cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS,
642  check_specification_or_abstract_origin)) {
643  if (lo_pc < hi_pc)
644  ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc));
645  }
646  }
647  return ranges.GetSize();
648 }
649 
650 // GetName
651 //
652 // Get value of the DW_AT_name attribute and return it if one exists, else
653 // return NULL.
654 const char *DWARFDebugInfoEntry::GetName(const DWARFUnit *cu) const {
655  return GetAttributeValueAsString(cu, DW_AT_name, nullptr, true);
656 }
657 
658 // GetMangledName
659 //
660 // Get value of the DW_AT_MIPS_linkage_name attribute and return it if one
661 // exists, else return the value of the DW_AT_name attribute
662 const char *
664  bool substitute_name_allowed) const {
665  const char *name = nullptr;
666 
667  name = GetAttributeValueAsString(cu, DW_AT_MIPS_linkage_name, nullptr, true);
668  if (name)
669  return name;
670 
671  name = GetAttributeValueAsString(cu, DW_AT_linkage_name, nullptr, true);
672  if (name)
673  return name;
674 
675  if (!substitute_name_allowed)
676  return nullptr;
677 
678  name = GetAttributeValueAsString(cu, DW_AT_name, nullptr, true);
679  return name;
680 }
681 
682 // GetPubname
683 //
684 // Get value the name for a DIE as it should appear for a .debug_pubnames or
685 // .debug_pubtypes section.
686 const char *DWARFDebugInfoEntry::GetPubname(const DWARFUnit *cu) const {
687  const char *name = nullptr;
688  if (!cu)
689  return name;
690 
691  name = GetAttributeValueAsString(cu, DW_AT_MIPS_linkage_name, nullptr, true);
692  if (name)
693  return name;
694 
695  name = GetAttributeValueAsString(cu, DW_AT_linkage_name, nullptr, true);
696  if (name)
697  return name;
698 
699  name = GetAttributeValueAsString(cu, DW_AT_name, nullptr, true);
700  return name;
701 }
702 
703 /// This function is builds a table very similar to the standard .debug_aranges
704 /// table, except that the actual DIE offset for the function is placed in the
705 /// table instead of the compile unit offset.
707  DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const {
708  if (m_tag) {
709  if (m_tag == DW_TAG_subprogram) {
710  DWARFRangeList ranges;
711  GetAttributeAddressRanges(cu, ranges,
712  /*check_hi_lo_pc=*/true);
713  for (const auto &r : ranges) {
714  debug_aranges->AppendRange(GetOffset(), r.GetRangeBase(),
715  r.GetRangeEnd());
716  }
717  }
718 
719  const DWARFDebugInfoEntry *child = GetFirstChild();
720  while (child) {
721  child->BuildFunctionAddressRangeTable(cu, debug_aranges);
722  child = child->GetSibling();
723  }
724  }
725 }
726 
729  DWARFUnit *cu) {
730  DWARFDeclContext dwarf_decl_ctx;
731  for (;;) {
732  const dw_tag_t tag = die->Tag();
733  if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit)
734  return dwarf_decl_ctx;
735  dwarf_decl_ctx.AppendDeclContext(tag, die->GetName(cu));
736  DWARFDIE parent_decl_ctx_die = die->GetParentDeclContextDIE(cu);
737  if (!parent_decl_ctx_die || parent_decl_ctx_die.GetDIE() == die)
738  return dwarf_decl_ctx;
739  if (parent_decl_ctx_die.Tag() == DW_TAG_compile_unit ||
740  parent_decl_ctx_die.Tag() == DW_TAG_partial_unit)
741  return dwarf_decl_ctx;
742  die = parent_decl_ctx_die.GetDIE();
743  cu = parent_decl_ctx_die.GetCU();
744  }
745 }
746 
748  return GetDWARFDeclContextStatic(this, cu);
749 }
750 
751 DWARFDIE
753  DWARFAttributes attributes;
754  GetAttributes(cu, attributes, Recurse::yes);
755  return GetParentDeclContextDIE(cu, attributes);
756 }
757 
758 DWARFDIE
760  DWARFUnit *cu, const DWARFAttributes &attributes) const {
761  DWARFDIE die(cu, const_cast<DWARFDebugInfoEntry *>(this));
762 
763  while (die) {
764  // If this is the original DIE that we are searching for a declaration for,
765  // then don't look in the cache as we don't want our own decl context to be
766  // our decl context...
767  if (die.GetDIE() != this) {
768  switch (die.Tag()) {
769  case DW_TAG_compile_unit:
770  case DW_TAG_partial_unit:
771  case DW_TAG_namespace:
772  case DW_TAG_structure_type:
773  case DW_TAG_union_type:
774  case DW_TAG_class_type:
775  return die;
776 
777  default:
778  break;
779  }
780  }
781 
782  DWARFDIE spec_die = attributes.FormValueAsReference(DW_AT_specification);
783  if (spec_die) {
784  DWARFDIE decl_ctx_die = spec_die.GetParentDeclContextDIE();
785  if (decl_ctx_die)
786  return decl_ctx_die;
787  }
788 
789  DWARFDIE abs_die = attributes.FormValueAsReference(DW_AT_abstract_origin);
790  if (abs_die) {
791  DWARFDIE decl_ctx_die = abs_die.GetParentDeclContextDIE();
792  if (decl_ctx_die)
793  return decl_ctx_die;
794  }
795 
796  die = die.GetParent();
797  }
798  return DWARFDIE();
799 }
800 
802  return GetOffset() + llvm::getULEB128Size(m_abbr_idx);
803 }
804 
807  if (cu) {
808  const DWARFAbbreviationDeclarationSet *abbrev_set = cu->GetAbbreviations();
809  if (abbrev_set)
810  return abbrev_set->GetAbbreviationDeclaration(m_abbr_idx);
811  }
812  return nullptr;
813 }
814 
816  if (Tag() != DW_TAG_variable)
817  return false;
818  const DWARFDebugInfoEntry *parent_die = GetParent();
819  while (parent_die != nullptr) {
820  switch (parent_die->Tag()) {
821  case DW_TAG_subprogram:
822  case DW_TAG_lexical_block:
823  case DW_TAG_inlined_subroutine:
824  return false;
825 
826  case DW_TAG_compile_unit:
827  case DW_TAG_partial_unit:
828  return true;
829 
830  default:
831  break;
832  }
833  parent_die = parent_die->GetParent();
834  }
835  return false;
836 }
837 
839  return m_offset == rhs.m_offset && m_parent_idx == rhs.m_parent_idx &&
840  m_sibling_idx == rhs.m_sibling_idx &&
841  m_abbr_idx == rhs.m_abbr_idx && m_has_children == rhs.m_has_children &&
842  m_tag == rhs.m_tag;
843 }
844 
846  return !(*this == rhs);
847 }
lldb_private::toString
const char * toString(AppleArm64ExceptionClass EC)
Definition: AppleArm64ExceptionClass.h:38
DWARFFormValue.h
DWARFDebugInfoEntry::GetAttributeValueAsReference
DWARFDIE GetAttributeValueAsReference(const DWARFUnit *cu, const dw_attr_t attr, bool check_specification_or_abstract_origin=false) const
Definition: DWARFDebugInfoEntry.cpp:565
lldb_private::DataExtractor::GetULEB128
uint64_t GetULEB128(lldb::offset_t *offset_ptr) const
Extract a unsigned LEB128 value from *offset_ptr.
Definition: DataExtractor.cpp:842
DWARFDebugInfoEntry::GetAttributeValueAsAddress
uint64_t GetAttributeValueAsAddress(const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value, bool check_specification_or_abstract_origin=false) const
Definition: DWARFDebugInfoEntry.cpp:575
DWARFFormValue::Reference
DWARFDIE Reference() const
Definition: DWARFFormValue.cpp:502
DWARFDIE::GetParent
DWARFDIE GetParent() const
Definition: DWARFDIE.cpp:86
DWARFCompileUnit.h
DWARFDebugInfoEntry::GetOffset
dw_offset_t GetOffset() const
Definition: DWARFDebugInfoEntry.h:117
DWARFUnit::GetData
const lldb_private::DWARFDataExtractor & GetData() const
Get the data that contains the DIE information for this unit.
Definition: DWARFUnit.cpp:992
DWARFDebugInfoEntry::GetMangledName
const char * GetMangledName(const DWARFUnit *cu, bool substitute_name_allowed=true) const
Definition: DWARFDebugInfoEntry.cpp:663
DWARFDebugAranges
Definition: DWARFDebugAranges.h:16
lldb_private::DataExtractor::ValidOffset
bool ValidOffset(lldb::offset_t offset) const
Test the validity of offset.
Definition: DataExtractor.h:956
DWARFBaseDIE::GetAttributes
size_t GetAttributes(DWARFAttributes &attributes, Recurse recurse=Recurse::yes) const
Definition: DWARFBaseDIE.cpp:114
dw_tag_t
llvm::dwarf::Tag dw_tag_t
Definition: dwarf.h:28
DWARFFormValue::Address
dw_addr_t Address() const
Definition: DWARFFormValue.cpp:484
lldb_private::RangeVector::GetMinRangeBase
BaseType GetMinRangeBase(BaseType fail_value) const
Definition: RangeMap.h:261
DWARFAttributes::FormValueAsReference
DWARFDIE FormValueAsReference(dw_attr_t attr) const
Definition: DWARFAttribute.cpp:52
Module.h
SymbolFileDWARF
Definition: SymbolFileDWARF.h:60
DWARFFormValue::SetForm
void SetForm(dw_form_t form)
Definition: DWARFFormValue.h:49
SymbolFileDWARF.h
lldb_private::DataExtractor::GetU16_unchecked
uint16_t GetU16_unchecked(lldb::offset_t *offset_ptr) const
Definition: DataExtractor.cpp:360
lldb_private::DWARFExpression::ParseDWARFLocationList
static bool ParseDWARFLocationList(const DWARFUnit *dwarf_cu, const DataExtractor &data, DWARFExpressionList *loc_list)
Definition: DWARFExpression.cpp:2608
lldb::offset_t
uint64_t offset_t
Definition: lldb-types.h:87
DWARFDebugInfoEntry::GetSibling
DWARFDebugInfoEntry * GetSibling()
Definition: DWARFDebugInfoEntry.h:133
lldb_private::DWARFDataExtractor
Definition: DWARFDataExtractor.h:18
DWARFFormValue::SetUnit
void SetUnit(const DWARFUnit *unit)
Definition: DWARFFormValue.h:46
DWARFBaseDIE::GetCU
DWARFUnit * GetCU() const
Definition: DWARFBaseDIE.h:54
lldb_private::RangeVector::Clear
void Clear()
Definition: RangeMap.h:289
DWARFDebugInfoEntry
DWARFDebugInfoEntry objects assume that they are living in one big vector and do pointer arithmetic o...
Definition: DWARFDebugInfoEntry.h:31
g_verbose
int g_verbose
DWARFAttributes::Clear
void Clear()
Definition: DWARFAttribute.h:66
DWARFUnit::FindRnglistFromOffset
llvm::Expected< DWARFRangeList > FindRnglistFromOffset(dw_offset_t offset)
Return a list of address ranges resulting from a (possibly encoded) range list starting at a given of...
Definition: DWARFUnit.cpp:1020
DWARFAttributes
Definition: DWARFAttribute.h:44
lldb_private::RangeVector::Append
void Append(const Entry &entry)
Definition: RangeMap.h:179
DWARFDeclContext.h
DWARFDebugInfoEntry::GetFirstAttributeOffset
lldb::offset_t GetFirstAttributeOffset() const
Definition: DWARFDebugInfoEntry.cpp:801
DWARFDIE
Definition: DWARFDIE.h:16
DWARFDebugInfoEntry::m_abbr_idx
uint16_t m_abbr_idx
Definition: DWARFDebugInfoEntry.h:175
SymbolFileDWARFDwo.h
DWARFUnit::GetAddressByteSize
uint8_t GetAddressByteSize() const
Definition: DWARFUnit.h:157
DWARFDebugInfoEntry::m_offset
dw_offset_t m_offset
Definition: DWARFDebugInfoEntry.h:167
DWARFUnit
Definition: DWARFUnit.h:83
DWARFDebugInfoEntry::GetParentDeclContextDIE
DWARFDIE GetParentDeclContextDIE(DWARFUnit *cu) const
Definition: DWARFDebugInfoEntry.cpp:752
dwarf
Definition: ABISysV_arc.cpp:61
lldb_private::DataExtractor
Definition: DataExtractor.h:48
DWARFDebugInfoEntry::GetDWARFDeclContext
DWARFDeclContext GetDWARFDeclContext(DWARFUnit *cu) const
Definition: DWARFDebugInfoEntry.cpp:747
StreamString.h
lldb_private::DWARFExpression
Definition: DWARFExpression.h:36
DWARFFormValue::Form
dw_form_t Form() const
Definition: DWARFFormValue.h:47
lldb_private::DataExtractor::GetDataStart
const uint8_t * GetDataStart() const
Get the data start pointer.
Definition: DataExtractor.h:422
DWARFDeclContext::AppendDeclContext
void AppendDeclContext(dw_tag_t tag, const char *name)
Definition: DWARFDeclContext.h:46
DWARFDebugAranges::AppendRange
void AppendRange(dw_offset_t cu_offset, dw_addr_t low_pc, dw_addr_t high_pc)
Definition: DWARFDebugAranges.cpp:84
DWARFDebugInfoEntry::m_tag
dw_tag_t m_tag
A copy of the DW_TAG value so we don't have to go through the compile unit abbrev table.
Definition: DWARFDebugInfoEntry.h:178
DWARFDebugAranges.h
DWARFDebugInfoEntry::GetPubname
const char * GetPubname(const DWARFUnit *cu) const
Definition: DWARFDebugInfoEntry.cpp:686
DWARFFormValue
Definition: DWARFFormValue.h:20
DWARFDebugInfoEntry::GetDWARFDeclContextStatic
static DWARFDeclContext GetDWARFDeclContextStatic(const DWARFDebugInfoEntry *die, DWARFUnit *cu)
Definition: DWARFDebugInfoEntry.cpp:728
lldb_private::Range
Definition: Process.h:61
DWARFFormValue::GetFixedSize
llvm::Optional< uint8_t > GetFixedSize() const
Definition: DWARFFormValue.cpp:199
DWARFRangeList
lldb_private::RangeVector< dw_addr_t, dw_addr_t, 2 > DWARFRangeList
Definition: dwarf.h:44
DWARFDebugInfoEntry::Extract
bool Extract(const lldb_private::DWARFDataExtractor &data, const DWARFUnit *cu, lldb::offset_t *offset_ptr)
Definition: DWARFDebugInfoEntry.cpp:40
DWARFDebugInfoEntry::BuildFunctionAddressRangeTable
void BuildFunctionAddressRangeTable(DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const
This function is builds a table very similar to the standard .debug_aranges table,...
Definition: DWARFDebugInfoEntry.cpp:706
DWARFDebugInfo.h
lldb_private::DataExtractor::Skip_LEB128
uint32_t Skip_LEB128(lldb::offset_t *offset_ptr) const
Skip an LEB128 number at *offset_ptr.
Definition: DataExtractor.cpp:876
DWARFDebugInfoEntry::m_parent_idx
uint32_t m_parent_idx
Definition: DWARFDebugInfoEntry.h:168
DWARFUnit.h
lldb_private::RangeVector::IsEmpty
bool IsEmpty() const
Definition: RangeMap.h:293
lldb_private::DataExtractor::GetU8_unchecked
uint8_t GetU8_unchecked(lldb::offset_t *offset_ptr) const
Definition: DataExtractor.h:612
lldb_private::RangeVector
Definition: RangeMap.h:136
DWARFDebugInfoEntry::GetAttributeValueAsString
const char * GetAttributeValueAsString(const DWARFUnit *cu, const dw_attr_t attr, const char *fail_value, bool check_specification_or_abstract_origin=false) const
Definition: DWARFDebugInfoEntry.cpp:527
DWARFDebugInfoEntry::operator!=
bool operator!=(const DWARFDebugInfoEntry &rhs) const
Definition: DWARFDebugInfoEntry.cpp:845
DWARFFormValue::Unsigned
uint64_t Unsigned() const
Definition: DWARFFormValue.h:64
DWARFUnit::GetBaseAddress
dw_addr_t GetBaseAddress() const
Definition: DWARFUnit.h:159
ObjectFile.h
lldb_private::DWARFExpressionList::SetFuncFileAddress
void SetFuncFileAddress(lldb::addr_t func_file_addr)
Definition: DWARFExpressionList.h:57
DW_INVALID_INDEX
#define DW_INVALID_INDEX
Definition: dwarf.h:38
lldbassert
#define lldbassert(x)
Definition: LLDBAssert.h:15
DWARFDebugInfoEntry::GetAttributeAddressRange
bool GetAttributeAddressRange(const DWARFUnit *cu, dw_addr_t &lo_pc, dw_addr_t &hi_pc, uint64_t fail_value, bool check_specification_or_abstract_origin=false) const
Definition: DWARFDebugInfoEntry.cpp:614
DWARFAbbreviationDeclarationSet
Definition: DWARFDebugAbbrev.h:27
GetRangesOrReportError
static DWARFRangeList GetRangesOrReportError(DWARFUnit &unit, const DWARFDebugInfoEntry &die, const DWARFFormValue &value)
Definition: DWARFDebugInfoEntry.cpp:208
uint32_t
DWARFDebugInfoEntry.h
DWARFUnit::GetVersion
uint16_t GetVersion() const
Definition: DWARFUnit.h:154
DWARFFormValue::ExtractValue
bool ExtractValue(const lldb_private::DWARFDataExtractor &data, lldb::offset_t *offset_ptr)
Definition: DWARFFormValue.cpp:31
DWARFFormValue::BlockData
const uint8_t * BlockData() const
Definition: DWARFFormValue.cpp:567
DWARFBaseDIE::Recurse
Recurse
Definition: DWARFBaseDIE.h:116
DWARFDebugInfoEntry::IsGlobalOrStaticScopeVariable
bool IsGlobalOrStaticScopeVariable() const
Definition: DWARFDebugInfoEntry.cpp:815
DWARFDebugRanges.h
DWARFDIE::GetDIE
DWARFDIE GetDIE(dw_offset_t die_offset) const
Definition: DWARFDIE.cpp:118
UINT32_MAX
#define UINT32_MAX
Definition: lldb-defines.h:19
DWARFDebugInfoEntry::GetDIENamesAndRanges
bool GetDIENamesAndRanges(DWARFUnit *cu, const char *&name, const char *&mangled, DWARFRangeList &rangeList, int &decl_file, int &decl_line, int &decl_column, int &call_file, int &call_line, int &call_column, lldb_private::DWARFExpressionList *frame_base=nullptr) const
Definition: DWARFDebugInfoEntry.cpp:231
lldb_private::ModuleChild::GetModule
lldb::ModuleSP GetModule() const
Get const accessor for the module pointer.
Definition: ModuleChild.cpp:24
DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr
const DWARFAbbreviationDeclaration * GetAbbreviationDeclarationPtr(const DWARFUnit *cu) const
Definition: DWARFDebugInfoEntry.cpp:806
uint16_t
DWARFDebugAbbrev.h
lldb_private::DataExtractor::GetU32
uint32_t GetU32(lldb::offset_t *offset_ptr) const
Extract a uint32_t value from *offset_ptr.
Definition: DataExtractor.cpp:425
DWARFDIE::GetParentDeclContextDIE
DWARFDIE GetParentDeclContextDIE() const
Definition: DWARFDIE.cpp:420
DWARFUnit::GetLocationData
lldb_private::DWARFDataExtractor GetLocationData() const
Definition: DWARFUnit.cpp:517
LLDB_INVALID_ADDRESS
#define LLDB_INVALID_ADDRESS
Definition: lldb-defines.h:74
DWARFAbbreviationDeclaration
Definition: DWARFAbbreviationDeclaration.h:17
DWARFFormValue::AsCString
const char * AsCString() const
Definition: DWARFFormValue.cpp:459
DWARFExpression.h
lldb_private::SymbolFileCommon::GetObjectFile
ObjectFile * GetObjectFile() override
Definition: SymbolFile.h:453
DWARFDeclContext
Definition: DWARFDeclContext.h:23
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::DataExtractor::GetCStr
const char * GetCStr(lldb::offset_t *offset_ptr) const
Extract a C string from *offset_ptr.
Definition: DataExtractor.cpp:784
DWARFDebugInfoEntry::Tag
dw_tag_t Tag() const
Definition: DWARFDebugInfoEntry.h:113
DWARFDebugInfoEntry::m_sibling_idx
uint32_t m_sibling_idx
Definition: DWARFDebugInfoEntry.h:170
DWARFDebugInfoEntry::m_has_children
uint32_t m_has_children
Definition: DWARFDebugInfoEntry.h:174
DWARFDebugInfoEntry::GetAttributeAddressRanges
size_t GetAttributeAddressRanges(DWARFUnit *cu, DWARFRangeList &ranges, bool check_hi_lo_pc, bool check_specification_or_abstract_origin=false) const
Definition: DWARFDebugInfoEntry.cpp:630
DWARFAttributes::Size
size_t Size() const
Definition: DWARFAttribute.h:67
DWARFDebugInfoEntry::GetAttributes
size_t GetAttributes(DWARFUnit *cu, DWARFAttributes &attrs, Recurse recurse=Recurse::yes) const
Definition: DWARFDebugInfoEntry.h:51
lldb_private::DWARFExpressionList
Definition: DWARFExpressionList.h:24
Stream.h
DWARFUnit::GetSymbolFileDWARF
SymbolFileDWARF & GetSymbolFileDWARF() const
Definition: DWARFUnit.h:199
DWARFUnit::GetAbbreviations
const DWARFAbbreviationDeclarationSet * GetAbbreviations() const
Definition: DWARFUnit.cpp:431
DWARFUnit::FindRnglistFromIndex
llvm::Expected< DWARFRangeList > FindRnglistFromIndex(uint32_t index)
Return a list of address ranges retrieved from an encoded range list whose offset is found via a tabl...
Definition: DWARFUnit.cpp:1067
dw_addr_t
uint64_t dw_addr_t
Definition: dwarf.h:29
DWARFDebugInfoEntry::GetAttributeHighPC
dw_addr_t GetAttributeHighPC(const DWARFUnit *cu, dw_addr_t lo_pc, uint64_t fail_value, bool check_specification_or_abstract_origin=false) const
Definition: DWARFDebugInfoEntry.cpp:591
DWARFAttributes::Append
void Append(const DWARFFormValue &form_value, dw_offset_t attr_die_offset, dw_attr_t attr)
Definition: DWARFAttribute.cpp:30
lldb_private::DataExtractor::GetByteSize
uint64_t GetByteSize() const
Get the number of bytes contained in this object.
Definition: DataExtractor.h:270
DWARFDebugInfoEntry::GetName
const char * GetName(const DWARFUnit *cu) const
Definition: DWARFDebugInfoEntry.cpp:654
DWARFDebugInfoEntry::GetParent
DWARFDebugInfoEntry * GetParent()
Definition: DWARFDebugInfoEntry.h:125
DWARFDebugInfoEntry::GetAttributeValueAsUnsigned
uint64_t GetAttributeValueAsUnsigned(const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value, bool check_specification_or_abstract_origin=false) const
Definition: DWARFDebugInfoEntry.cpp:540
DWARFDebugInfoEntry::operator==
bool operator==(const DWARFDebugInfoEntry &rhs) const
Definition: DWARFDebugInfoEntry.cpp:838
DWARFBaseDIE::Tag
dw_tag_t Tag() const
Definition: DWARFBaseDIE.cpp:29
lldb_private::dwarf
Definition: dwarf.h:19
DWARFDebugInfoEntry::GetAttributeValueAsOptionalUnsigned
llvm::Optional< uint64_t > GetAttributeValueAsOptionalUnsigned(const DWARFUnit *cu, const dw_attr_t attr, bool check_specification_or_abstract_origin=false) const
Definition: DWARFDebugInfoEntry.cpp:551
DWARFFormValue::SkipValue
bool SkipValue(const lldb_private::DWARFDataExtractor &debug_info_data, lldb::offset_t *offset_ptr) const
Definition: DWARFFormValue.cpp:203
DWARFDebugInfoEntry::GetAttributeValue
dw_offset_t GetAttributeValue(const DWARFUnit *cu, const dw_attr_t attr, DWARFFormValue &formValue, dw_offset_t *end_attr_offset_ptr=nullptr, bool check_specification_or_abstract_origin=false) const
Definition: DWARFDebugInfoEntry.cpp:470
lldb_private::DataExtractor::GetU32_unchecked
uint32_t GetU32_unchecked(lldb::offset_t *offset_ptr) const
Definition: DataExtractor.cpp:370
DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration
const DWARFAbbreviationDeclaration * GetAbbreviationDeclaration(dw_uleb128_t abbrCode) const
Definition: DWARFDebugAbbrev.cpp:52
lldb_private::RangeVector::GetSize
size_t GetSize() const
Definition: RangeMap.h:295