LLDB  mainline
DWARFDebugInfoEntry.cpp
Go to the documentation of this file.
1 //===-- DWARFDebugInfoEntry.cpp ---------------------------------*- C++ -*-===//
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 <assert.h>
12 
13 #include <algorithm>
14 
15 #include "lldb/Core/Module.h"
17 #include "lldb/Symbol/ObjectFile.h"
18 #include "lldb/Utility/Stream.h"
19 
20 #include "DWARFUnit.h"
21 #include "DWARFDebugAbbrev.h"
22 #include "DWARFDebugAranges.h"
23 #include "DWARFDebugInfo.h"
24 #include "DWARFDebugRanges.h"
25 #include "DWARFDeclContext.h"
26 #include "DWARFFormValue.h"
27 #include "SymbolFileDWARF.h"
28 #include "SymbolFileDWARFDwo.h"
29 
30 using namespace lldb_private;
31 using namespace std;
32 extern int g_verbose;
33 
35  const DWARFDataExtractor &debug_info_data, const DWARFUnit *cu,
36  const DWARFFormValue::FixedFormSizes &fixed_form_sizes,
37  lldb::offset_t *offset_ptr) {
38  m_offset = *offset_ptr;
39  m_parent_idx = 0;
40  m_sibling_idx = 0;
41  const uint64_t abbr_idx = debug_info_data.GetULEB128(offset_ptr);
42  lldbassert(abbr_idx <= UINT16_MAX);
43  m_abbr_idx = abbr_idx;
44 
45  // assert (fixed_form_sizes); // For best performance this should be
46  // specified!
47 
48  if (m_abbr_idx) {
49  lldb::offset_t offset = *offset_ptr;
50 
51  const DWARFAbbreviationDeclaration *abbrevDecl =
53 
54  if (abbrevDecl == NULL) {
55  cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError(
56  "{0x%8.8x}: invalid abbreviation code %u, please file a bug and "
57  "attach the file at the start of this error message",
58  m_offset, (unsigned)abbr_idx);
59  // WE can't parse anymore if the DWARF is borked...
60  *offset_ptr = UINT32_MAX;
61  return false;
62  }
63  m_tag = abbrevDecl->Tag();
64  m_has_children = abbrevDecl->HasChildren();
65  // Skip all data in the .debug_info for the attributes
66  const uint32_t numAttributes = abbrevDecl->NumAttributes();
67  uint32_t i;
68  dw_form_t form;
69  for (i = 0; i < numAttributes; ++i) {
70  form = abbrevDecl->GetFormByIndexUnchecked(i);
71 
72  const uint8_t fixed_skip_size = fixed_form_sizes.GetSize(form);
73  if (fixed_skip_size)
74  offset += fixed_skip_size;
75  else {
76  bool form_is_indirect = false;
77  do {
78  form_is_indirect = false;
79  uint32_t form_size = 0;
80  switch (form) {
81  // Blocks if inlined data that have a length field and the data bytes
82  // inlined in the .debug_info
83  case DW_FORM_exprloc:
84  case DW_FORM_block:
85  form_size = debug_info_data.GetULEB128(&offset);
86  break;
87  case DW_FORM_block1:
88  form_size = debug_info_data.GetU8_unchecked(&offset);
89  break;
90  case DW_FORM_block2:
91  form_size = debug_info_data.GetU16_unchecked(&offset);
92  break;
93  case DW_FORM_block4:
94  form_size = debug_info_data.GetU32_unchecked(&offset);
95  break;
96 
97  // Inlined NULL terminated C-strings
98  case DW_FORM_string:
99  debug_info_data.GetCStr(&offset);
100  break;
101 
102  // Compile unit address sized values
103  case DW_FORM_addr:
104  form_size = cu->GetAddressByteSize();
105  break;
106  case DW_FORM_ref_addr:
107  if (cu->GetVersion() <= 2)
108  form_size = cu->GetAddressByteSize();
109  else
110  form_size = 4;
111  break;
112 
113  // 0 sized form
114  case DW_FORM_flag_present:
115  form_size = 0;
116  break;
117 
118  // 1 byte values
119  case DW_FORM_addrx1:
120  case DW_FORM_data1:
121  case DW_FORM_flag:
122  case DW_FORM_ref1:
123  case DW_FORM_strx1:
124  form_size = 1;
125  break;
126 
127  // 2 byte values
128  case DW_FORM_addrx2:
129  case DW_FORM_data2:
130  case DW_FORM_ref2:
131  case DW_FORM_strx2:
132  form_size = 2;
133  break;
134 
135  // 3 byte values
136  case DW_FORM_addrx3:
137  case DW_FORM_strx3:
138  form_size = 3;
139  break;
140 
141  // 4 byte values
142  case DW_FORM_addrx4:
143  case DW_FORM_data4:
144  case DW_FORM_ref4:
145  case DW_FORM_strx4:
146  form_size = 4;
147  break;
148 
149  // 8 byte values
150  case DW_FORM_data8:
151  case DW_FORM_ref8:
152  case DW_FORM_ref_sig8:
153  form_size = 8;
154  break;
155 
156  // signed or unsigned LEB 128 values
157  case DW_FORM_addrx:
158  case DW_FORM_rnglistx:
159  case DW_FORM_sdata:
160  case DW_FORM_udata:
161  case DW_FORM_ref_udata:
162  case DW_FORM_GNU_addr_index:
163  case DW_FORM_GNU_str_index:
164  case DW_FORM_strx:
165  debug_info_data.Skip_LEB128(&offset);
166  break;
167 
168  case DW_FORM_indirect:
169  form_is_indirect = true;
170  form = debug_info_data.GetULEB128(&offset);
171  break;
172 
173  case DW_FORM_strp:
174  case DW_FORM_sec_offset:
175  debug_info_data.GetU32(&offset);
176  break;
177 
178  case DW_FORM_implicit_const:
179  form_size = 0;
180  break;
181 
182  default:
183  *offset_ptr = m_offset;
184  return false;
185  }
186  offset += form_size;
187 
188  } while (form_is_indirect);
189  }
190  }
191  *offset_ptr = offset;
192  return true;
193  } else {
194  m_tag = 0;
195  m_has_children = false;
196  return true; // NULL debug tag entry
197  }
198 
199  return false;
200 }
201 
202 // Extract
203 //
204 // Extract a debug info entry for a given compile unit from the .debug_info and
205 // .debug_abbrev data within the SymbolFileDWARF class starting at the given
206 // offset
208  lldb::offset_t *offset_ptr) {
209  const DWARFDataExtractor &debug_info_data = cu->GetData();
210  // const DWARFDataExtractor& debug_str_data =
211  // dwarf2Data->get_debug_str_data();
212  const uint32_t cu_end_offset = cu->GetNextCompileUnitOffset();
213  lldb::offset_t offset = *offset_ptr;
214  // if (offset >= cu_end_offset)
215  // Log::Status("DIE at offset 0x%8.8x is beyond the end of the current
216  // compile unit (0x%8.8x)", m_offset, cu_end_offset);
217  if ((offset < cu_end_offset) && debug_info_data.ValidOffset(offset)) {
218  m_offset = offset;
219 
220  const uint64_t abbr_idx = debug_info_data.GetULEB128(&offset);
221  lldbassert(abbr_idx <= UINT16_MAX);
222  m_abbr_idx = abbr_idx;
223  if (abbr_idx) {
224  const DWARFAbbreviationDeclaration *abbrevDecl =
226 
227  if (abbrevDecl) {
228  m_tag = abbrevDecl->Tag();
229  m_has_children = abbrevDecl->HasChildren();
230 
231  bool isCompileUnitTag = (m_tag == DW_TAG_compile_unit ||
232  m_tag == DW_TAG_partial_unit);
233  if (cu && isCompileUnitTag)
234  const_cast<DWARFUnit *>(cu)->SetBaseAddress(0);
235 
236  // Skip all data in the .debug_info for the attributes
237  const uint32_t numAttributes = abbrevDecl->NumAttributes();
238  for (uint32_t i = 0; i < numAttributes; ++i) {
239  DWARFFormValue form_value(cu);
240  dw_attr_t attr;
241  abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value);
242  dw_form_t form = form_value.Form();
243 
244  if (isCompileUnitTag &&
245  ((attr == DW_AT_entry_pc) || (attr == DW_AT_low_pc))) {
246  if (form_value.ExtractValue(debug_info_data, &offset)) {
247  if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc)
248  const_cast<DWARFUnit *>(cu)->SetBaseAddress(
249  form_value.Address());
250  }
251  } else {
252  bool form_is_indirect = false;
253  do {
254  form_is_indirect = false;
255  uint32_t form_size = 0;
256  switch (form) {
257  // Blocks if inlined data that have a length field and the data
258  // bytes inlined in the .debug_info
259  case DW_FORM_exprloc:
260  case DW_FORM_block:
261  form_size = debug_info_data.GetULEB128(&offset);
262  break;
263  case DW_FORM_block1:
264  form_size = debug_info_data.GetU8(&offset);
265  break;
266  case DW_FORM_block2:
267  form_size = debug_info_data.GetU16(&offset);
268  break;
269  case DW_FORM_block4:
270  form_size = debug_info_data.GetU32(&offset);
271  break;
272 
273  // Inlined NULL terminated C-strings
274  case DW_FORM_string:
275  debug_info_data.GetCStr(&offset);
276  break;
277 
278  // Compile unit address sized values
279  case DW_FORM_addr:
280  form_size = cu->GetAddressByteSize();
281  break;
282  case DW_FORM_ref_addr:
283  if (cu->GetVersion() <= 2)
284  form_size = cu->GetAddressByteSize();
285  else
286  form_size = 4;
287  break;
288 
289  // 0 sized form
290  case DW_FORM_flag_present:
291  case DW_FORM_implicit_const:
292  form_size = 0;
293  break;
294 
295  // 1 byte values
296  case DW_FORM_data1:
297  case DW_FORM_flag:
298  case DW_FORM_ref1:
299  form_size = 1;
300  break;
301 
302  // 2 byte values
303  case DW_FORM_data2:
304  case DW_FORM_ref2:
305  form_size = 2;
306  break;
307 
308  // 4 byte values
309  case DW_FORM_data4:
310  case DW_FORM_ref4:
311  form_size = 4;
312  break;
313 
314  // 8 byte values
315  case DW_FORM_data8:
316  case DW_FORM_ref8:
317  case DW_FORM_ref_sig8:
318  form_size = 8;
319  break;
320 
321  // signed or unsigned LEB 128 values
322  case DW_FORM_addrx:
323  case DW_FORM_sdata:
324  case DW_FORM_udata:
325  case DW_FORM_ref_udata:
326  case DW_FORM_GNU_addr_index:
327  case DW_FORM_GNU_str_index:
328  debug_info_data.Skip_LEB128(&offset);
329  break;
330 
331  case DW_FORM_indirect:
332  form = debug_info_data.GetULEB128(&offset);
333  form_is_indirect = true;
334  break;
335 
336  case DW_FORM_strp:
337  case DW_FORM_sec_offset:
338  debug_info_data.GetU32(&offset);
339  break;
340 
341  default:
342  *offset_ptr = offset;
343  return false;
344  }
345 
346  offset += form_size;
347  } while (form_is_indirect);
348  }
349  }
350  *offset_ptr = offset;
351  return true;
352  }
353  } else {
354  m_tag = 0;
355  m_has_children = false;
356  *offset_ptr = offset;
357  return true; // NULL debug tag entry
358  }
359  }
360 
361  return false;
362 }
363 
365  DWARFFormValue &form_value) {
366  if (form_value.Form() == DW_FORM_rnglistx)
367  return debug_ranges->GetOffset(form_value.Unsigned());
368  return form_value.Unsigned();
369 }
370 
371 // GetDIENamesAndRanges
372 //
373 // Gets the valid address ranges for a given DIE by looking for a
374 // DW_AT_low_pc/DW_AT_high_pc pair, DW_AT_entry_pc, or DW_AT_ranges attributes.
376  SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, const char *&name,
377  const char *&mangled, DWARFRangeList &ranges, int &decl_file,
378  int &decl_line, int &decl_column, int &call_file, int &call_line,
379  int &call_column, DWARFExpression *frame_base) const {
380  if (dwarf2Data == nullptr)
381  return false;
382 
383  SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile();
384  if (dwo_symbol_file)
385  return GetDIENamesAndRanges(
386  dwo_symbol_file, dwo_symbol_file->GetCompileUnit(), name, mangled,
387  ranges, decl_file, decl_line, decl_column, call_file, call_line,
388  call_column, frame_base);
389 
392  std::vector<DIERef> die_refs;
393  bool set_frame_base_loclist_addr = false;
394 
395  lldb::offset_t offset;
396  const DWARFAbbreviationDeclaration *abbrevDecl =
397  GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
398 
399  lldb::ModuleSP module = dwarf2Data->GetObjectFile()->GetModule();
400 
401  if (abbrevDecl) {
402  const DWARFDataExtractor &debug_info_data = cu->GetData();
403 
404  if (!debug_info_data.ValidOffset(offset))
405  return false;
406 
407  const uint32_t numAttributes = abbrevDecl->NumAttributes();
408  bool do_offset = false;
409 
410  for (uint32_t i = 0; i < numAttributes; ++i) {
411  DWARFFormValue form_value(cu);
412  dw_attr_t attr;
413  abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value);
414 
415  if (form_value.ExtractValue(debug_info_data, &offset)) {
416  switch (attr) {
417  case DW_AT_low_pc:
418  lo_pc = form_value.Address();
419 
420  if (do_offset)
421  hi_pc += lo_pc;
422  do_offset = false;
423  break;
424 
425  case DW_AT_entry_pc:
426  lo_pc = form_value.Address();
427  break;
428 
429  case DW_AT_high_pc:
430  if (form_value.Form() == DW_FORM_addr ||
431  form_value.Form() == DW_FORM_addrx ||
432  form_value.Form() == DW_FORM_GNU_addr_index) {
433  hi_pc = form_value.Address();
434  } else {
435  hi_pc = form_value.Unsigned();
436  if (lo_pc == LLDB_INVALID_ADDRESS)
437  do_offset = hi_pc != LLDB_INVALID_ADDRESS;
438  else
439  hi_pc += lo_pc; // DWARF 4 introduces <offset-from-lo-pc> to save
440  // on relocations
441  }
442  break;
443 
444  case DW_AT_ranges: {
445  const DWARFDebugRangesBase *debug_ranges = dwarf2Data->DebugRanges();
446  if (debug_ranges)
447  debug_ranges->FindRanges(cu, GetRangesOffset(debug_ranges, form_value), ranges);
448  else
449  cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError(
450  "{0x%8.8x}: DIE has DW_AT_ranges(0x%" PRIx64
451  ") attribute yet DWARF has no .debug_ranges, please file a bug "
452  "and attach the file at the start of this error message",
453  m_offset, form_value.Unsigned());
454  } break;
455 
456  case DW_AT_name:
457  if (name == NULL)
458  name = form_value.AsCString();
459  break;
460 
461  case DW_AT_MIPS_linkage_name:
462  case DW_AT_linkage_name:
463  if (mangled == NULL)
464  mangled = form_value.AsCString();
465  break;
466 
467  case DW_AT_abstract_origin:
468  die_refs.emplace_back(form_value);
469  break;
470 
471  case DW_AT_specification:
472  die_refs.emplace_back(form_value);
473  break;
474 
475  case DW_AT_decl_file:
476  if (decl_file == 0)
477  decl_file = form_value.Unsigned();
478  break;
479 
480  case DW_AT_decl_line:
481  if (decl_line == 0)
482  decl_line = form_value.Unsigned();
483  break;
484 
485  case DW_AT_decl_column:
486  if (decl_column == 0)
487  decl_column = form_value.Unsigned();
488  break;
489 
490  case DW_AT_call_file:
491  if (call_file == 0)
492  call_file = form_value.Unsigned();
493  break;
494 
495  case DW_AT_call_line:
496  if (call_line == 0)
497  call_line = form_value.Unsigned();
498  break;
499 
500  case DW_AT_call_column:
501  if (call_column == 0)
502  call_column = form_value.Unsigned();
503  break;
504 
505  case DW_AT_frame_base:
506  if (frame_base) {
507  if (form_value.BlockData()) {
508  uint32_t block_offset =
509  form_value.BlockData() - debug_info_data.GetDataStart();
510  uint32_t block_length = form_value.Unsigned();
511  frame_base->SetOpcodeData(module, debug_info_data, block_offset,
512  block_length);
513  } else {
514  const DWARFDataExtractor &debug_loc_data =
515  dwarf2Data->DebugLocData();
516  const dw_offset_t debug_loc_offset = form_value.Unsigned();
517 
518  size_t loc_list_length = DWARFExpression::LocationListSize(
519  cu, debug_loc_data, debug_loc_offset);
520  if (loc_list_length > 0) {
521  frame_base->SetOpcodeData(module, debug_loc_data,
522  debug_loc_offset, loc_list_length);
523  if (lo_pc != LLDB_INVALID_ADDRESS) {
524  assert(lo_pc >= cu->GetBaseAddress());
525  frame_base->SetLocationListSlide(lo_pc -
526  cu->GetBaseAddress());
527  } else {
528  set_frame_base_loclist_addr = true;
529  }
530  }
531  }
532  }
533  break;
534 
535  default:
536  break;
537  }
538  }
539  }
540  }
541 
542  if (ranges.IsEmpty()) {
543  if (lo_pc != LLDB_INVALID_ADDRESS) {
544  if (hi_pc != LLDB_INVALID_ADDRESS && hi_pc > lo_pc)
545  ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc));
546  else
547  ranges.Append(DWARFRangeList::Entry(lo_pc, 0));
548  }
549  }
550 
551  if (set_frame_base_loclist_addr) {
552  dw_addr_t lowest_range_pc = ranges.GetMinRangeBase(0);
553  assert(lowest_range_pc >= cu->GetBaseAddress());
554  frame_base->SetLocationListSlide(lowest_range_pc - cu->GetBaseAddress());
555  }
556 
557  if (ranges.IsEmpty() || name == NULL || mangled == NULL) {
558  for (const DIERef &die_ref : die_refs) {
559  if (die_ref.die_offset != DW_INVALID_OFFSET) {
560  DWARFDIE die = dwarf2Data->GetDIE(die_ref);
561  if (die)
563  die.GetDWARF(), die.GetCU(), name, mangled, ranges, decl_file,
564  decl_line, decl_column, call_file, call_line, call_column);
565  }
566  }
567  }
568  return !ranges.IsEmpty();
569 }
570 
571 // Dump
572 //
573 // Dumps a debug information entry and all of it's attributes to the specified
574 // stream.
576  const DWARFUnit *cu, Stream &s,
577  uint32_t recurse_depth) const {
578  const DWARFDataExtractor &debug_info_data = cu->GetData();
579  lldb::offset_t offset = m_offset;
580 
581  if (debug_info_data.ValidOffset(offset)) {
582  dw_uleb128_t abbrCode = debug_info_data.GetULEB128(&offset);
583 
584  s.Printf("\n0x%8.8x: ", m_offset);
585  s.Indent();
586  if (abbrCode != m_abbr_idx) {
587  s.Printf("error: DWARF has been modified\n");
588  } else if (abbrCode) {
589  const DWARFAbbreviationDeclaration *abbrevDecl =
591 
592  if (abbrevDecl) {
593  s.PutCString(DW_TAG_value_to_name(abbrevDecl->Tag()));
594  s.Printf(" [%u] %c\n", abbrCode, abbrevDecl->HasChildren() ? '*' : ' ');
595 
596  // Dump all data in the .debug_info for the attributes
597  const uint32_t numAttributes = abbrevDecl->NumAttributes();
598  for (uint32_t i = 0; i < numAttributes; ++i) {
599  DWARFFormValue form_value(cu);
600  dw_attr_t attr;
601  abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value);
602 
603  DumpAttribute(dwarf2Data, cu, debug_info_data, &offset, s, attr,
604  form_value);
605  }
606 
607  const DWARFDebugInfoEntry *child = GetFirstChild();
608  if (recurse_depth > 0 && child) {
609  s.IndentMore();
610 
611  while (child) {
612  child->Dump(dwarf2Data, cu, s, recurse_depth - 1);
613  child = child->GetSibling();
614  }
615  s.IndentLess();
616  }
617  } else
618  s.Printf("Abbreviation code note found in 'debug_abbrev' class for "
619  "code: %u\n",
620  abbrCode);
621  } else {
622  s.Printf("NULL\n");
623  }
624  }
625 }
626 
627 // DumpAttribute
628 //
629 // Dumps a debug information entry attribute along with it's form. Any special
630 // display of attributes is done (disassemble location lists, show enumeration
631 // values for attributes, etc).
633  SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
634  const DWARFDataExtractor &debug_info_data, lldb::offset_t *offset_ptr,
635  Stream &s, dw_attr_t attr, DWARFFormValue &form_value) {
636  bool show_form = s.GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowForm);
637 
638  s.Printf(" ");
639  s.Indent(DW_AT_value_to_name(attr));
640 
641  if (show_form) {
642  s.Printf("[%s", DW_FORM_value_to_name(form_value.Form()));
643  }
644 
645  if (!form_value.ExtractValue(debug_info_data, offset_ptr))
646  return;
647 
648  if (show_form) {
649  if (form_value.Form() == DW_FORM_indirect) {
650  s.Printf(" [%s]", DW_FORM_value_to_name(form_value.Form()));
651  }
652 
653  s.PutCString("] ");
654  }
655 
656  s.PutCString("( ");
657 
658  // Check to see if we have any special attribute formatters
659  switch (attr) {
660  case DW_AT_stmt_list:
661  s.Printf("0x%8.8" PRIx64, form_value.Unsigned());
662  break;
663 
664  case DW_AT_language:
665  s.PutCString(DW_LANG_value_to_name(form_value.Unsigned()));
666  break;
667 
668  case DW_AT_encoding:
669  s.PutCString(DW_ATE_value_to_name(form_value.Unsigned()));
670  break;
671 
672  case DW_AT_frame_base:
673  case DW_AT_location:
674  case DW_AT_data_member_location: {
675  const uint8_t *blockData = form_value.BlockData();
676  if (blockData) {
677  // Location description is inlined in data in the form value
678  DWARFDataExtractor locationData(debug_info_data,
679  (*offset_ptr) - form_value.Unsigned(),
680  form_value.Unsigned());
682  s, locationData, DWARFUnit::GetAddressByteSize(cu), 4, false);
683  } else {
684  // We have a location list offset as the value that is the offset into
685  // the .debug_loc section that describes the value over it's lifetime
686  uint64_t debug_loc_offset = form_value.Unsigned();
687  if (dwarf2Data) {
689  s, cu, dwarf2Data->DebugLocData(), debug_loc_offset);
690  }
691  }
692  } break;
693 
694  case DW_AT_abstract_origin:
695  case DW_AT_specification: {
696  uint64_t abstract_die_offset = form_value.Reference();
697  form_value.Dump(s);
698  // *ostrm_ptr << HEX32 << abstract_die_offset << " ( ";
699  GetName(dwarf2Data, cu, abstract_die_offset, s);
700  } break;
701 
702  case DW_AT_type: {
703  uint64_t type_die_offset = form_value.Reference();
704  s.PutCString(" ( ");
705  AppendTypeName(dwarf2Data, cu, type_die_offset, s);
706  s.PutCString(" )");
707  } break;
708 
709  case DW_AT_ranges: {
710  if (!dwarf2Data)
711  break;
712  lldb::offset_t ranges_offset =
713  GetRangesOffset(dwarf2Data->DebugRanges(), form_value);
714  dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0;
716  &ranges_offset, base_addr);
717  } break;
718 
719  default:
720  break;
721  }
722 
723  s.PutCString(" )\n");
724 }
725 
726 // Get all attribute values for a given DIE, including following any
727 // specification or abstract origin attributes and including those in the
728 // results. Any duplicate attributes will have the first instance take
729 // precedence (this can happen for declaration attributes).
731  const DWARFUnit *cu, DWARFFormValue::FixedFormSizes fixed_form_sizes,
732  DWARFAttributes &attributes, uint32_t curr_depth) const {
733  SymbolFileDWARF *dwarf2Data = nullptr;
734  const DWARFAbbreviationDeclaration *abbrevDecl = nullptr;
735  lldb::offset_t offset = 0;
736  if (cu) {
737  if (m_tag != DW_TAG_compile_unit && m_tag != DW_TAG_partial_unit) {
738  SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile();
739  if (dwo_symbol_file)
740  return GetAttributes(dwo_symbol_file->GetCompileUnit(),
741  fixed_form_sizes, attributes, curr_depth);
742  }
743 
744  dwarf2Data = cu->GetSymbolFileDWARF();
745  abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
746  }
747 
748  if (abbrevDecl) {
749  const DWARFDataExtractor &debug_info_data = cu->GetData();
750 
751  if (fixed_form_sizes.Empty())
753  cu->GetAddressByteSize());
754 
755  const uint32_t num_attributes = abbrevDecl->NumAttributes();
756  for (uint32_t i = 0; i < num_attributes; ++i) {
757  DWARFFormValue form_value(cu);
758  dw_attr_t attr;
759  abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value);
760  const dw_form_t form = form_value.Form();
761 
762  // If we are tracking down DW_AT_specification or DW_AT_abstract_origin
763  // attributes, the depth will be non-zero. We need to omit certain
764  // attributes that don't make sense.
765  switch (attr) {
766  case DW_AT_sibling:
767  case DW_AT_declaration:
768  if (curr_depth > 0) {
769  // This attribute doesn't make sense when combined with the DIE that
770  // references this DIE. We know a DIE is referencing this DIE because
771  // curr_depth is not zero
772  break;
773  }
774  LLVM_FALLTHROUGH;
775  default:
776  attributes.Append(cu, offset, attr, form);
777  break;
778  }
779 
780  if ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin)) {
781  if (form_value.ExtractValue(debug_info_data, &offset)) {
782  dw_offset_t die_offset = form_value.Reference();
783  DWARFDIE spec_die =
784  const_cast<DWARFUnit *>(cu)->GetDIE(die_offset);
785  if (spec_die)
786  spec_die.GetAttributes(attributes, curr_depth + 1);
787  }
788  } else {
789  const uint8_t fixed_skip_size = fixed_form_sizes.GetSize(form);
790  if (fixed_skip_size)
791  offset += fixed_skip_size;
792  else
793  DWARFFormValue::SkipValue(form, debug_info_data, &offset, cu);
794  }
795  }
796  } else {
797  attributes.Clear();
798  }
799  return attributes.Size();
800 }
801 
802 // GetAttributeValue
803 //
804 // Get the value of an attribute and return the .debug_info offset of the
805 // attribute if it was properly extracted into form_value, or zero if we fail
806 // since an offset of zero is invalid for an attribute (it would be a compile
807 // unit header).
809  SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
810  const dw_attr_t attr, DWARFFormValue &form_value,
811  dw_offset_t *end_attr_offset_ptr,
812  bool check_specification_or_abstract_origin) const {
813  SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile();
814  if (dwo_symbol_file && m_tag != DW_TAG_compile_unit &&
815  m_tag != DW_TAG_partial_unit)
816  return GetAttributeValue(dwo_symbol_file, dwo_symbol_file->GetCompileUnit(),
817  attr, form_value, end_attr_offset_ptr,
818  check_specification_or_abstract_origin);
819 
820  lldb::offset_t offset;
821  const DWARFAbbreviationDeclaration *abbrevDecl =
822  GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
823 
824  if (abbrevDecl) {
825  uint32_t attr_idx = abbrevDecl->FindAttributeIndex(attr);
826 
827  if (attr_idx != DW_INVALID_INDEX) {
828  const DWARFDataExtractor &debug_info_data = cu->GetData();
829 
830  uint32_t idx = 0;
831  while (idx < attr_idx)
832  DWARFFormValue::SkipValue(abbrevDecl->GetFormByIndex(idx++),
833  debug_info_data, &offset, cu);
834 
835  const dw_offset_t attr_offset = offset;
836  form_value.SetCompileUnit(cu);
837  form_value.SetForm(abbrevDecl->GetFormByIndex(idx));
838  if (form_value.ExtractValue(debug_info_data, &offset)) {
839  if (end_attr_offset_ptr)
840  *end_attr_offset_ptr = offset;
841  return attr_offset;
842  }
843  }
844  }
845 
846  if (check_specification_or_abstract_origin) {
847  if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value)) {
848  DWARFDIE die =
849  const_cast<DWARFUnit *>(cu)->GetDIE(form_value.Reference());
850  if (die) {
851  dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(
852  die.GetDWARF(), die.GetCU(), attr, form_value, end_attr_offset_ptr,
853  false);
854  if (die_offset)
855  return die_offset;
856  }
857  }
858 
859  if (GetAttributeValue(dwarf2Data, cu, DW_AT_abstract_origin, form_value)) {
860  DWARFDIE die =
861  const_cast<DWARFUnit *>(cu)->GetDIE(form_value.Reference());
862  if (die) {
863  dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(
864  die.GetDWARF(), die.GetCU(), attr, form_value, end_attr_offset_ptr,
865  false);
866  if (die_offset)
867  return die_offset;
868  }
869  }
870  }
871 
872  if (!dwo_symbol_file)
873  return 0;
874 
875  DWARFUnit *dwo_cu = dwo_symbol_file->GetCompileUnit();
876  if (!dwo_cu)
877  return 0;
878 
879  DWARFBaseDIE dwo_cu_die = dwo_cu->GetUnitDIEOnly();
880  if (!dwo_cu_die.IsValid())
881  return 0;
882 
883  return dwo_cu_die.GetDIE()->GetAttributeValue(
884  dwo_symbol_file, dwo_cu, attr, form_value, end_attr_offset_ptr,
885  check_specification_or_abstract_origin);
886 }
887 
888 // GetAttributeValueAsString
889 //
890 // Get the value of an attribute as a string return it. The resulting pointer
891 // to the string data exists within the supplied SymbolFileDWARF and will only
892 // be available as long as the SymbolFileDWARF is still around and it's content
893 // doesn't change.
895  SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
896  const dw_attr_t attr, const char *fail_value,
897  bool check_specification_or_abstract_origin) const {
898  DWARFFormValue form_value;
899  if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr,
900  check_specification_or_abstract_origin))
901  return form_value.AsCString();
902  return fail_value;
903 }
904 
905 // GetAttributeValueAsUnsigned
906 //
907 // Get the value of an attribute as unsigned and return it.
909  SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
910  const dw_attr_t attr, uint64_t fail_value,
911  bool check_specification_or_abstract_origin) const {
912  DWARFFormValue form_value;
913  if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr,
914  check_specification_or_abstract_origin))
915  return form_value.Unsigned();
916  return fail_value;
917 }
918 
919 // GetAttributeValueAsReference
920 //
921 // Get the value of an attribute as reference and fix up and compile unit
922 // relative offsets as needed.
924  SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
925  const dw_attr_t attr, uint64_t fail_value,
926  bool check_specification_or_abstract_origin) const {
927  DWARFFormValue form_value;
928  if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr,
929  check_specification_or_abstract_origin))
930  return form_value.Reference();
931  return fail_value;
932 }
933 
935  SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
936  const dw_attr_t attr, uint64_t fail_value,
937  bool check_specification_or_abstract_origin) const {
938  DWARFFormValue form_value;
939  if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr,
940  check_specification_or_abstract_origin))
941  return form_value.Address();
942  return fail_value;
943 }
944 
945 // GetAttributeHighPC
946 //
947 // Get the hi_pc, adding hi_pc to lo_pc when specified as an <offset-from-low-
948 // pc>.
949 //
950 // Returns the hi_pc or fail_value.
952  SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, dw_addr_t lo_pc,
953  uint64_t fail_value, bool check_specification_or_abstract_origin) const {
954  DWARFFormValue form_value;
955  if (GetAttributeValue(dwarf2Data, cu, DW_AT_high_pc, form_value, nullptr,
956  check_specification_or_abstract_origin)) {
957  dw_form_t form = form_value.Form();
958  if (form == DW_FORM_addr || form == DW_FORM_addrx ||
959  form == DW_FORM_GNU_addr_index)
960  return form_value.Address();
961 
962  // DWARF4 can specify the hi_pc as an <offset-from-lowpc>
963  return lo_pc + form_value.Unsigned();
964  }
965  return fail_value;
966 }
967 
968 // GetAttributeAddressRange
969 //
970 // Get the lo_pc and hi_pc, adding hi_pc to lo_pc when specified as an <offset-
971 // from-low-pc>.
972 //
973 // Returns true or sets lo_pc and hi_pc to fail_value.
975  SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, dw_addr_t &lo_pc,
976  dw_addr_t &hi_pc, uint64_t fail_value,
977  bool check_specification_or_abstract_origin) const {
978  lo_pc = GetAttributeValueAsAddress(dwarf2Data, cu, DW_AT_low_pc, fail_value,
979  check_specification_or_abstract_origin);
980  if (lo_pc != fail_value) {
981  hi_pc = GetAttributeHighPC(dwarf2Data, cu, lo_pc, fail_value,
982  check_specification_or_abstract_origin);
983  if (hi_pc != fail_value)
984  return true;
985  }
986  lo_pc = fail_value;
987  hi_pc = fail_value;
988  return false;
989 }
990 
992  SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
993  DWARFRangeList &ranges, bool check_hi_lo_pc,
994  bool check_specification_or_abstract_origin) const {
995  ranges.Clear();
996 
997  DWARFFormValue form_value;
998  if (GetAttributeValue(dwarf2Data, cu, DW_AT_ranges, form_value)) {
999  if (DWARFDebugRangesBase *debug_ranges = dwarf2Data->DebugRanges())
1000  debug_ranges->FindRanges(cu, GetRangesOffset(debug_ranges, form_value),
1001  ranges);
1002  } else if (check_hi_lo_pc) {
1005  if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc,
1007  check_specification_or_abstract_origin)) {
1008  if (lo_pc < hi_pc)
1009  ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc));
1010  }
1011  }
1012  return ranges.GetSize();
1013 }
1014 
1015 // GetName
1016 //
1017 // Get value of the DW_AT_name attribute and return it if one exists, else
1018 // return NULL.
1020  const DWARFUnit *cu) const {
1021  return GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true);
1022 }
1023 
1024 // GetMangledName
1025 //
1026 // Get value of the DW_AT_MIPS_linkage_name attribute and return it if one
1027 // exists, else return the value of the DW_AT_name attribute
1028 const char *
1030  const DWARFUnit *cu,
1031  bool substitute_name_allowed) const {
1032  const char *name = nullptr;
1033 
1034  name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_MIPS_linkage_name,
1035  nullptr, true);
1036  if (name)
1037  return name;
1038 
1039  name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_linkage_name, nullptr,
1040  true);
1041  if (name)
1042  return name;
1043 
1044  if (!substitute_name_allowed)
1045  return nullptr;
1046 
1047  name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true);
1048  return name;
1049 }
1050 
1051 // GetPubname
1052 //
1053 // Get value the name for a DIE as it should appear for a .debug_pubnames or
1054 // .debug_pubtypes section.
1056  const DWARFUnit *cu) const {
1057  const char *name = nullptr;
1058  if (!dwarf2Data)
1059  return name;
1060 
1061  name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_MIPS_linkage_name,
1062  nullptr, true);
1063  if (name)
1064  return name;
1065 
1066  name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_linkage_name, nullptr,
1067  true);
1068  if (name)
1069  return name;
1070 
1071  name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true);
1072  return name;
1073 }
1074 
1075 // GetName
1076 //
1077 // Get value of the DW_AT_name attribute for a debug information entry that
1078 // exists at offset "die_offset" and place that value into the supplied stream
1079 // object. If the DIE is a NULL object "NULL" is placed into the stream, and if
1080 // no DW_AT_name attribute exists for the DIE then nothing is printed.
1082  const DWARFUnit *cu,
1083  const dw_offset_t die_offset, Stream &s) {
1084  if (dwarf2Data == NULL) {
1085  s.PutCString("NULL");
1086  return false;
1087  }
1088 
1089  DWARFDebugInfoEntry die;
1090  lldb::offset_t offset = die_offset;
1091  if (die.Extract(cu, &offset)) {
1092  if (die.IsNULL()) {
1093  s.PutCString("NULL");
1094  return true;
1095  } else {
1096  const char *name = die.GetAttributeValueAsString(
1097  dwarf2Data, cu, DW_AT_name, nullptr, true);
1098  if (name) {
1099  s.PutCString(name);
1100  return true;
1101  }
1102  }
1103  }
1104  return false;
1105 }
1106 
1107 // AppendTypeName
1108 //
1109 // Follows the type name definition down through all needed tags to end up with
1110 // a fully qualified type name and dump the results to the supplied stream.
1111 // This is used to show the name of types given a type identifier.
1113  const DWARFUnit *cu,
1114  const dw_offset_t die_offset,
1115  Stream &s) {
1116  if (dwarf2Data == NULL) {
1117  s.PutCString("NULL");
1118  return false;
1119  }
1120 
1121  DWARFDebugInfoEntry die;
1122  lldb::offset_t offset = die_offset;
1123  if (die.Extract(cu, &offset)) {
1124  if (die.IsNULL()) {
1125  s.PutCString("NULL");
1126  return true;
1127  } else {
1128  const char *name = die.GetPubname(dwarf2Data, cu);
1129  if (name)
1130  s.PutCString(name);
1131  else {
1132  bool result = true;
1133  const DWARFAbbreviationDeclaration *abbrevDecl =
1134  die.GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
1135 
1136  if (abbrevDecl == NULL)
1137  return false;
1138 
1139  switch (abbrevDecl->Tag()) {
1140  case DW_TAG_array_type:
1141  break; // print out a "[]" after printing the full type of the element
1142  // below
1143  case DW_TAG_base_type:
1144  s.PutCString("base ");
1145  break;
1146  case DW_TAG_class_type:
1147  s.PutCString("class ");
1148  break;
1149  case DW_TAG_const_type:
1150  s.PutCString("const ");
1151  break;
1152  case DW_TAG_enumeration_type:
1153  s.PutCString("enum ");
1154  break;
1155  case DW_TAG_file_type:
1156  s.PutCString("file ");
1157  break;
1158  case DW_TAG_interface_type:
1159  s.PutCString("interface ");
1160  break;
1161  case DW_TAG_packed_type:
1162  s.PutCString("packed ");
1163  break;
1164  case DW_TAG_pointer_type:
1165  break; // print out a '*' after printing the full type below
1166  case DW_TAG_ptr_to_member_type:
1167  break; // print out a '*' after printing the full type below
1168  case DW_TAG_reference_type:
1169  break; // print out a '&' after printing the full type below
1170  case DW_TAG_restrict_type:
1171  s.PutCString("restrict ");
1172  break;
1173  case DW_TAG_set_type:
1174  s.PutCString("set ");
1175  break;
1176  case DW_TAG_shared_type:
1177  s.PutCString("shared ");
1178  break;
1179  case DW_TAG_string_type:
1180  s.PutCString("string ");
1181  break;
1182  case DW_TAG_structure_type:
1183  s.PutCString("struct ");
1184  break;
1185  case DW_TAG_subrange_type:
1186  s.PutCString("subrange ");
1187  break;
1188  case DW_TAG_subroutine_type:
1189  s.PutCString("function ");
1190  break;
1191  case DW_TAG_thrown_type:
1192  s.PutCString("thrown ");
1193  break;
1194  case DW_TAG_union_type:
1195  s.PutCString("union ");
1196  break;
1197  case DW_TAG_unspecified_type:
1198  s.PutCString("unspecified ");
1199  break;
1200  case DW_TAG_volatile_type:
1201  s.PutCString("volatile ");
1202  break;
1203  default:
1204  return false;
1205  }
1206 
1207  // Follow the DW_AT_type if possible
1208  DWARFFormValue form_value;
1209  if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_type, form_value)) {
1210  uint64_t next_die_offset = form_value.Reference();
1211  result = AppendTypeName(dwarf2Data, cu, next_die_offset, s);
1212  }
1213 
1214  switch (abbrevDecl->Tag()) {
1215  case DW_TAG_array_type:
1216  s.PutCString("[]");
1217  break;
1218  case DW_TAG_pointer_type:
1219  s.PutChar('*');
1220  break;
1221  case DW_TAG_ptr_to_member_type:
1222  s.PutChar('*');
1223  break;
1224  case DW_TAG_reference_type:
1225  s.PutChar('&');
1226  break;
1227  default:
1228  break;
1229  }
1230  return result;
1231  }
1232  }
1233  }
1234  return false;
1235 }
1236 
1237 // BuildAddressRangeTable
1239  SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
1240  DWARFDebugAranges *debug_aranges) const {
1241  if (m_tag) {
1242  if (m_tag == DW_TAG_subprogram) {
1245  if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc,
1247  /// printf("BuildAddressRangeTable() 0x%8.8x: %30s: [0x%8.8x -
1248  /// 0x%8.8x)\n", m_offset, DW_TAG_value_to_name(tag), lo_pc, hi_pc);
1249  debug_aranges->AppendRange(cu->GetOffset(), lo_pc, hi_pc);
1250  }
1251  }
1252 
1253  const DWARFDebugInfoEntry *child = GetFirstChild();
1254  while (child) {
1255  child->BuildAddressRangeTable(dwarf2Data, cu, debug_aranges);
1256  child = child->GetSibling();
1257  }
1258  }
1259 }
1260 
1261 // BuildFunctionAddressRangeTable
1262 //
1263 // This function is very similar to the BuildAddressRangeTable function except
1264 // that the actual DIE offset for the function is placed in the table instead
1265 // of the compile unit offset (which is the way the standard .debug_aranges
1266 // section does it).
1268  SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
1269  DWARFDebugAranges *debug_aranges) const {
1270  if (m_tag) {
1271  if (m_tag == DW_TAG_subprogram) {
1274  if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc,
1276  // printf("BuildAddressRangeTable() 0x%8.8x: [0x%16.16" PRIx64 " -
1277  // 0x%16.16" PRIx64 ")\n", m_offset, lo_pc, hi_pc); // DEBUG ONLY
1278  debug_aranges->AppendRange(GetOffset(), lo_pc, hi_pc);
1279  }
1280  }
1281 
1282  const DWARFDebugInfoEntry *child = GetFirstChild();
1283  while (child) {
1284  child->BuildFunctionAddressRangeTable(dwarf2Data, cu, debug_aranges);
1285  child = child->GetSibling();
1286  }
1287  }
1288 }
1289 
1290 std::vector<DWARFDIE>
1292 
1293  DWARFDIE die(cu, const_cast<DWARFDebugInfoEntry *>(this));
1294  return die.GetDeclContextDIEs();
1295 }
1296 
1298  SymbolFileDWARF *dwarf2Data, DWARFUnit *cu,
1299  DWARFDeclContext &dwarf_decl_ctx) const {
1300  const dw_tag_t tag = Tag();
1301  if (tag != DW_TAG_compile_unit && tag != DW_TAG_partial_unit) {
1302  dwarf_decl_ctx.AppendDeclContext(tag, GetName(dwarf2Data, cu));
1303  DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(dwarf2Data, cu);
1304  if (parent_decl_ctx_die && parent_decl_ctx_die.GetDIE() != this) {
1305  if (parent_decl_ctx_die.Tag() != DW_TAG_compile_unit &&
1306  parent_decl_ctx_die.Tag() != DW_TAG_partial_unit)
1307  parent_decl_ctx_die.GetDIE()->GetDWARFDeclContext(
1308  parent_decl_ctx_die.GetDWARF(), parent_decl_ctx_die.GetCU(),
1309  dwarf_decl_ctx);
1310  }
1311  }
1312 }
1313 
1315  SymbolFileDWARF *dwarf2Data, DWARFUnit *cu,
1316  const DWARFDeclContext &dwarf_decl_ctx) const {
1317 
1318  DWARFDeclContext this_dwarf_decl_ctx;
1319  GetDWARFDeclContext(dwarf2Data, cu, this_dwarf_decl_ctx);
1320  return this_dwarf_decl_ctx == dwarf_decl_ctx;
1321 }
1322 
1323 DWARFDIE
1325  DWARFUnit *cu) const {
1326  DWARFAttributes attributes;
1327  GetAttributes(cu, DWARFFormValue::FixedFormSizes(), attributes);
1328  return GetParentDeclContextDIE(dwarf2Data, cu, attributes);
1329 }
1330 
1331 DWARFDIE
1333  SymbolFileDWARF *dwarf2Data, DWARFUnit *cu,
1334  const DWARFAttributes &attributes) const {
1335  DWARFDIE die(cu, const_cast<DWARFDebugInfoEntry *>(this));
1336 
1337  while (die) {
1338  // If this is the original DIE that we are searching for a declaration for,
1339  // then don't look in the cache as we don't want our own decl context to be
1340  // our decl context...
1341  if (die.GetDIE() != this) {
1342  switch (die.Tag()) {
1343  case DW_TAG_compile_unit:
1344  case DW_TAG_partial_unit:
1345  case DW_TAG_namespace:
1346  case DW_TAG_structure_type:
1347  case DW_TAG_union_type:
1348  case DW_TAG_class_type:
1349  return die;
1350 
1351  default:
1352  break;
1353  }
1354  }
1355 
1356  dw_offset_t die_offset;
1357 
1358  die_offset =
1359  attributes.FormValueAsUnsigned(DW_AT_specification, DW_INVALID_OFFSET);
1360  if (die_offset != DW_INVALID_OFFSET) {
1361  DWARFDIE spec_die = cu->GetDIE(die_offset);
1362  if (spec_die) {
1363  DWARFDIE decl_ctx_die = spec_die.GetParentDeclContextDIE();
1364  if (decl_ctx_die)
1365  return decl_ctx_die;
1366  }
1367  }
1368 
1369  die_offset = attributes.FormValueAsUnsigned(DW_AT_abstract_origin,
1371  if (die_offset != DW_INVALID_OFFSET) {
1372  DWARFDIE abs_die = cu->GetDIE(die_offset);
1373  if (abs_die) {
1374  DWARFDIE decl_ctx_die = abs_die.GetParentDeclContextDIE();
1375  if (decl_ctx_die)
1376  return decl_ctx_die;
1377  }
1378  }
1379 
1380  die = die.GetParent();
1381  }
1382  return DWARFDIE();
1383 }
1384 
1386  DWARFUnit *cu,
1387  std::string &storage) const {
1388  DWARFAttributes attributes;
1389  GetAttributes(cu, DWARFFormValue::FixedFormSizes(), attributes);
1390  return GetQualifiedName(dwarf2Data, cu, attributes, storage);
1391 }
1392 
1394  SymbolFileDWARF *dwarf2Data, DWARFUnit *cu,
1395  const DWARFAttributes &attributes, std::string &storage) const {
1396 
1397  const char *name = GetName(dwarf2Data, cu);
1398 
1399  if (name) {
1400  DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(dwarf2Data, cu);
1401  storage.clear();
1402  // TODO: change this to get the correct decl context parent....
1403  while (parent_decl_ctx_die) {
1404  const dw_tag_t parent_tag = parent_decl_ctx_die.Tag();
1405  switch (parent_tag) {
1406  case DW_TAG_namespace: {
1407  const char *namespace_name = parent_decl_ctx_die.GetName();
1408  if (namespace_name) {
1409  storage.insert(0, "::");
1410  storage.insert(0, namespace_name);
1411  } else {
1412  storage.insert(0, "(anonymous namespace)::");
1413  }
1414  parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE();
1415  } break;
1416 
1417  case DW_TAG_class_type:
1418  case DW_TAG_structure_type:
1419  case DW_TAG_union_type: {
1420  const char *class_union_struct_name = parent_decl_ctx_die.GetName();
1421 
1422  if (class_union_struct_name) {
1423  storage.insert(0, "::");
1424  storage.insert(0, class_union_struct_name);
1425  }
1426  parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE();
1427  } break;
1428 
1429  default:
1430  parent_decl_ctx_die.Clear();
1431  break;
1432  }
1433  }
1434 
1435  if (storage.empty())
1436  storage.append("::");
1437 
1438  storage.append(name);
1439  }
1440  if (storage.empty())
1441  return NULL;
1442  return storage.c_str();
1443 }
1444 
1445 // LookupAddress
1447  SymbolFileDWARF *dwarf2Data,
1448  const DWARFUnit *cu,
1449  DWARFDebugInfoEntry **function_die,
1450  DWARFDebugInfoEntry **block_die) {
1451  bool found_address = false;
1452  if (m_tag) {
1453  bool check_children = false;
1454  bool match_addr_range = false;
1455  // printf("0x%8.8x: %30s: address = 0x%8.8x - ", m_offset,
1456  // DW_TAG_value_to_name(tag), address);
1457  switch (m_tag) {
1458  case DW_TAG_array_type:
1459  break;
1460  case DW_TAG_class_type:
1461  check_children = true;
1462  break;
1463  case DW_TAG_entry_point:
1464  break;
1465  case DW_TAG_enumeration_type:
1466  break;
1467  case DW_TAG_formal_parameter:
1468  break;
1469  case DW_TAG_imported_declaration:
1470  break;
1471  case DW_TAG_label:
1472  break;
1473  case DW_TAG_lexical_block:
1474  check_children = true;
1475  match_addr_range = true;
1476  break;
1477  case DW_TAG_member:
1478  break;
1479  case DW_TAG_pointer_type:
1480  break;
1481  case DW_TAG_reference_type:
1482  break;
1483  case DW_TAG_compile_unit:
1484  match_addr_range = true;
1485  break;
1486  case DW_TAG_string_type:
1487  break;
1488  case DW_TAG_structure_type:
1489  check_children = true;
1490  break;
1491  case DW_TAG_subroutine_type:
1492  break;
1493  case DW_TAG_typedef:
1494  break;
1495  case DW_TAG_union_type:
1496  break;
1497  case DW_TAG_unspecified_parameters:
1498  break;
1499  case DW_TAG_variant:
1500  break;
1501  case DW_TAG_common_block:
1502  check_children = true;
1503  break;
1504  case DW_TAG_common_inclusion:
1505  break;
1506  case DW_TAG_inheritance:
1507  break;
1508  case DW_TAG_inlined_subroutine:
1509  check_children = true;
1510  match_addr_range = true;
1511  break;
1512  case DW_TAG_module:
1513  match_addr_range = true;
1514  break;
1515  case DW_TAG_ptr_to_member_type:
1516  break;
1517  case DW_TAG_set_type:
1518  break;
1519  case DW_TAG_subrange_type:
1520  break;
1521  case DW_TAG_with_stmt:
1522  break;
1523  case DW_TAG_access_declaration:
1524  break;
1525  case DW_TAG_base_type:
1526  break;
1527  case DW_TAG_catch_block:
1528  match_addr_range = true;
1529  break;
1530  case DW_TAG_const_type:
1531  break;
1532  case DW_TAG_constant:
1533  break;
1534  case DW_TAG_enumerator:
1535  break;
1536  case DW_TAG_file_type:
1537  break;
1538  case DW_TAG_friend:
1539  break;
1540  case DW_TAG_namelist:
1541  break;
1542  case DW_TAG_namelist_item:
1543  break;
1544  case DW_TAG_packed_type:
1545  break;
1546  case DW_TAG_subprogram:
1547  match_addr_range = true;
1548  break;
1549  case DW_TAG_template_type_parameter:
1550  break;
1551  case DW_TAG_template_value_parameter:
1552  break;
1553  case DW_TAG_GNU_template_parameter_pack:
1554  break;
1555  case DW_TAG_thrown_type:
1556  break;
1557  case DW_TAG_try_block:
1558  match_addr_range = true;
1559  break;
1560  case DW_TAG_variant_part:
1561  break;
1562  case DW_TAG_variable:
1563  break;
1564  case DW_TAG_volatile_type:
1565  break;
1566  case DW_TAG_dwarf_procedure:
1567  break;
1568  case DW_TAG_restrict_type:
1569  break;
1570  case DW_TAG_interface_type:
1571  break;
1572  case DW_TAG_namespace:
1573  check_children = true;
1574  break;
1575  case DW_TAG_imported_module:
1576  break;
1577  case DW_TAG_unspecified_type:
1578  break;
1579  case DW_TAG_partial_unit:
1580  match_addr_range = true;
1581  break;
1582  case DW_TAG_imported_unit:
1583  break;
1584  case DW_TAG_shared_type:
1585  break;
1586  default:
1587  break;
1588  }
1589 
1590  if (match_addr_range) {
1591  dw_addr_t lo_pc = GetAttributeValueAsAddress(dwarf2Data, cu, DW_AT_low_pc,
1593  if (lo_pc != LLDB_INVALID_ADDRESS) {
1594  dw_addr_t hi_pc =
1595  GetAttributeHighPC(dwarf2Data, cu, lo_pc, LLDB_INVALID_ADDRESS);
1596  if (hi_pc != LLDB_INVALID_ADDRESS) {
1597  // printf("\n0x%8.8x: %30s: address = 0x%8.8x [0x%8.8x - 0x%8.8x) ",
1598  // m_offset, DW_TAG_value_to_name(tag), address, lo_pc, hi_pc);
1599  if ((lo_pc <= address) && (address < hi_pc)) {
1600  found_address = true;
1601  // puts("***MATCH***");
1602  switch (m_tag) {
1603  case DW_TAG_compile_unit: // File
1604  case DW_TAG_partial_unit: // File
1605  check_children = ((function_die != NULL) || (block_die != NULL));
1606  break;
1607 
1608  case DW_TAG_subprogram: // Function
1609  if (function_die)
1610  *function_die = this;
1611  check_children = (block_die != NULL);
1612  break;
1613 
1614  case DW_TAG_inlined_subroutine: // Inlined Function
1615  case DW_TAG_lexical_block: // Block { } in code
1616  if (block_die) {
1617  *block_die = this;
1618  check_children = true;
1619  }
1620  break;
1621 
1622  default:
1623  check_children = true;
1624  break;
1625  }
1626  }
1627  } else {
1628  // Compile units may not have a valid high/low pc when there
1629  // are address gaps in subroutines so we must always search
1630  // if there is no valid high and low PC.
1631  check_children = (m_tag == DW_TAG_compile_unit ||
1632  m_tag == DW_TAG_partial_unit) &&
1633  ((function_die != NULL) || (block_die != NULL));
1634  }
1635  } else {
1636  DWARFFormValue form_value;
1637  if (GetAttributeValue(dwarf2Data, cu, DW_AT_ranges, form_value)) {
1638  DWARFRangeList ranges;
1639  DWARFDebugRangesBase *debug_ranges = dwarf2Data->DebugRanges();
1640  debug_ranges->FindRanges(
1641  cu, GetRangesOffset(debug_ranges, form_value), ranges);
1642 
1643  if (ranges.FindEntryThatContains(address)) {
1644  found_address = true;
1645  // puts("***MATCH***");
1646  switch (m_tag) {
1647  case DW_TAG_compile_unit: // File
1648  case DW_TAG_partial_unit: // File
1649  check_children = ((function_die != NULL) || (block_die != NULL));
1650  break;
1651 
1652  case DW_TAG_subprogram: // Function
1653  if (function_die)
1654  *function_die = this;
1655  check_children = (block_die != NULL);
1656  break;
1657 
1658  case DW_TAG_inlined_subroutine: // Inlined Function
1659  case DW_TAG_lexical_block: // Block { } in code
1660  if (block_die) {
1661  *block_die = this;
1662  check_children = true;
1663  }
1664  break;
1665 
1666  default:
1667  check_children = true;
1668  break;
1669  }
1670  } else {
1671  check_children = false;
1672  }
1673  }
1674  }
1675  }
1676 
1677  if (check_children) {
1678  // printf("checking children\n");
1679  DWARFDebugInfoEntry *child = GetFirstChild();
1680  while (child) {
1681  if (child->LookupAddress(address, dwarf2Data, cu, function_die,
1682  block_die))
1683  return true;
1684  child = child->GetSibling();
1685  }
1686  }
1687  }
1688  return found_address;
1689 }
1690 
1693  SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
1694  lldb::offset_t &offset) const {
1695  if (dwarf2Data) {
1696  offset = GetOffset();
1697 
1698  const DWARFAbbreviationDeclarationSet *abbrev_set = cu->GetAbbreviations();
1699  if (abbrev_set) {
1700  const DWARFAbbreviationDeclaration *abbrev_decl =
1701  abbrev_set->GetAbbreviationDeclaration(m_abbr_idx);
1702  if (abbrev_decl) {
1703  // Make sure the abbreviation code still matches. If it doesn't and the
1704  // DWARF data was mmap'ed, the backing file might have been modified
1705  // which is bad news.
1706  const uint64_t abbrev_code = cu->GetData().GetULEB128(&offset);
1707 
1708  if (abbrev_decl->Code() == abbrev_code)
1709  return abbrev_decl;
1710 
1711  dwarf2Data->GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
1712  "0x%8.8x: the DWARF debug information has been modified (abbrev "
1713  "code was %u, and is now %u)",
1714  GetOffset(), (uint32_t)abbrev_decl->Code(), (uint32_t)abbrev_code);
1715  }
1716  }
1717  }
1718  offset = DW_INVALID_OFFSET;
1719  return NULL;
1720 }
1721 
1723  const DWARFDebugInfoEntry &b) {
1724  return a.GetOffset() < b.GetOffset();
1725 }
1726 
1728  return m_offset == rhs.m_offset && m_parent_idx == rhs.m_parent_idx &&
1729  m_sibling_idx == rhs.m_sibling_idx &&
1730  m_abbr_idx == rhs.m_abbr_idx && m_has_children == rhs.m_has_children &&
1731  m_tag == rhs.m_tag;
1732 }
1733 
1735  return !(*this == rhs);
1736 }
DWARFBaseDIE GetUnitDIEOnly()
Definition: DWARFUnit.h:122
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition: Stream.cpp:61
dw_addr_t GetBaseAddress() const
Definition: DWARFUnit.h:101
uint8_t GetSize(uint32_t index) const
static void DumpAttribute(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, const lldb_private::DWARFDataExtractor &debug_info_data, lldb::offset_t *offset_ptr, lldb_private::Stream &s, dw_attr_t attr, DWARFFormValue &form_value)
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
const char * AsCString() const
std::vector< DWARFDIE > GetDeclContextDIEs(DWARFUnit *cu) const
void SetOpcodeData(const DataExtractor &data)
Make the expression parser read its location information from a given data source.
const char * DW_FORM_value_to_name(uint32_t val)
const char * DW_LANG_value_to_name(uint32_t val)
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
dw_addr_t Address() const
SymbolFileDWARF * GetDWARF() const
size_t GetAttributes(DWARFAttributes &attributes, uint32_t depth=0) const
virtual bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset, DWARFRangeList &range_list) const =0
#define lldbassert(x)
Definition: LLDBAssert.h:15
const char * GetCStr(lldb::offset_t *offset_ptr) const
Extract a C string from *offset_ptr.
DWARFUnit * GetCU() const
Definition: DWARFBaseDIE.h:52
uint32_t GetU32(lldb::offset_t *offset_ptr) const
Extract a uint32_t value from *offset_ptr.
Flags & GetFlags()
The flags accessor.
Definition: Stream.cpp:235
uint32_t dw_offset_t
Definition: dwarf.h:30
bool LookupAddress(const dw_addr_t address, SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, DWARFDebugInfoEntry **function_die, DWARFDebugInfoEntry **block_die)
DWARFDIE GetDIE(dw_offset_t die_offset)
Definition: DWARFUnit.cpp:530
"lldb/Expression/DWARFExpression.h" Encapsulates a DWARF location expression and interprets it...
size_t Size() const
static size_t LocationListSize(const DWARFUnit *dwarf_cu, const DataExtractor &debug_loc_data, lldb::offset_t offset)
dw_form_t GetFormByIndexUnchecked(uint32_t idx) const
bool GetAttributeAddressRange(SymbolFileDWARF *dwarf2Data, 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
dw_form_t GetFormByIndex(uint32_t idx) const
dw_form_t Form() const
const char * GetQualifiedName(SymbolFileDWARF *dwarf2Data, DWARFUnit *cu, std::string &storage) const
DWARFDIE GetParent() const
Definition: DWARFDIE.cpp:90
uint8_t GetU8_unchecked(lldb::offset_t *offset_ptr) const
const char * GetPubname(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu) const
static bool PrintDWARFExpression(Stream &s, const DataExtractor &data, int address_size, int dwarf_ref_size, bool location_expression)
uint32_t FindAttributeIndex(dw_attr_t attr) const
uint64_t dw_addr_t
Definition: dwarf.h:26
Definition: DIERef.h:18
bool FastExtract(const lldb_private::DWARFDataExtractor &debug_info_data, const DWARFUnit *cu, const DWARFFormValue::FixedFormSizes &fixed_form_sizes, lldb::offset_t *offset_ptr)
static void PrintDWARFLocationList(Stream &s, const DWARFUnit *cu, const DataExtractor &debug_loc_data, lldb::offset_t offset)
uint16_t GetVersion() const
Definition: DWARFUnit.h:97
DWARFDebugRangesBase * DebugRanges()
virtual uint64_t GetOffset(size_t Index) const =0
void SetLocationListSlide(lldb::addr_t slide)
Tells the expression that it refers to a location list.
lldb::ModuleSP GetModule() const
Get const accessor for the module pointer.
Definition: ModuleChild.cpp:27
size_t GetAttributeAddressRanges(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, DWARFRangeList &ranges, bool check_hi_lo_pc, bool check_specification_or_abstract_origin=false) const
#define DW_INVALID_INDEX
Definition: dwarf.h:35
uint64_t GetAttributeValueAsReference(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value, bool check_specification_or_abstract_origin=false) const
const char * DW_AT_value_to_name(uint32_t val)
void GetDWARFDeclContext(SymbolFileDWARF *dwarf2Data, DWARFUnit *cu, DWARFDeclContext &dwarf_decl_ctx) const
const DWARFAbbreviationDeclarationSet * GetAbbreviations() const
Definition: DWARFUnit.cpp:377
size_t GetAttributes(const DWARFUnit *cu, DWARFFormValue::FixedFormSizes fixed_form_sizes, DWARFAttributes &attrs, uint32_t curr_depth=0) const
#define UINT32_MAX
Definition: lldb-defines.h:31
dw_offset_t GetAttributeValue(SymbolFileDWARF *dwarf2Data, 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
static bool OffsetLessThan(const DWARFDebugInfoEntry &a, const DWARFDebugInfoEntry &b)
#define LLDB_INVALID_ADDRESS
Invalid value definitions.
Definition: lldb-defines.h:85
bool ExtractValue(const lldb_private::DWARFDataExtractor &data, lldb::offset_t *offset_ptr)
bool MatchesDWARFDeclContext(SymbolFileDWARF *dwarf2Data, DWARFUnit *cu, const DWARFDeclContext &dwarf_decl_ctx) const
bool Test(ValueType bit) const
Test a single flag bit.
Definition: Flags.h:107
uint64_t offset_t
Definition: lldb-types.h:87
dw_offset_t GetNextCompileUnitOffset() const
Definition: DWARFUnit.cpp:369
uint64_t GetAttributeValueAsUnsigned(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value, bool check_specification_or_abstract_origin=false) const
void GetAttrAndFormValueByIndex(uint32_t idx, dw_attr_t &attr, DWARFFormValue &form_value) const
virtual const lldb_private::DWARFDataExtractor & GetData() const =0
Get the data that contains the DIE information for this unit.
uint16_t GetU16_unchecked(lldb::offset_t *offset_ptr) const
void AppendRange(dw_offset_t cu_offset, dw_addr_t low_pc, dw_addr_t high_pc)
size_t GetSize() const
Definition: RangeMap.h:241
uint64_t Reference() const
void IndentLess(int amount=2)
Decrement the current indentation level.
Definition: Stream.cpp:221
const Entry * FindEntryThatContains(B addr) const
Definition: RangeMap.h:283
uint64_t Unsigned() const
const lldb_private::DWARFDataExtractor & DebugLocData()
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:106
uint64_t FormValueAsUnsigned(dw_attr_t attr, uint64_t fail_value) const
dw_offset_t GetOffset() const
uint8_t GetAddressByteSize() const
Definition: DWARFUnit.h:100
bool operator!=(const DWARFDebugInfoEntry &rhs) const
bool GetDIENamesAndRanges(const char *&name, const char *&mangled, DWARFRangeList &ranges, int &decl_file, int &decl_line, int &decl_column, int &call_file, int &call_line, int &call_column, lldb_private::DWARFExpression *frame_base) const
Definition: DWARFDIE.cpp:328
dw_offset_t GetOffset() const
Definition: DWARFUnit.h:76
bool Extract(const DWARFUnit *cu, lldb::offset_t *offset_ptr)
bool ValidOffset(lldb::offset_t offset) const
Test the validity of offset.
void Clear()
Definition: DWARFBaseDIE.h:71
std::vector< DWARFDIE > GetDeclContextDIEs() const
Definition: DWARFDIE.cpp:202
DWARFDebugInfoEntry * GetDIE() const
Definition: DWARFBaseDIE.h:54
static bool AppendTypeName(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, const dw_offset_t die_offset, lldb_private::Stream &s)
static FixedFormSizes GetFixedFormSizesForAddressSize(uint8_t addr_size)
void GetDWARFDeclContext(DWARFDeclContext &dwarf_decl_ctx) const
Definition: DWARFDIE.cpp:216
size_t PutChar(char ch)
Definition: Stream.cpp:103
const char * GetAttributeValueAsString(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, const dw_attr_t attr, const char *fail_value, bool check_specification_or_abstract_origin=false) const
DWARFUnit * GetCompileUnit()
static dw_offset_t GetRangesOffset(const DWARFDebugRangesBase *debug_ranges, DWARFFormValue &form_value)
void BuildFunctionAddressRangeTable(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const
dw_addr_t GetAttributeHighPC(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, dw_addr_t lo_pc, uint64_t fail_value, bool check_specification_or_abstract_origin=false) const
const uint8_t * GetDataStart() const
Get the data start pointer.
const DWARFAbbreviationDeclaration * GetAbbreviationDeclarationPtr(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, lldb::offset_t &offset) const
bool GetDIENamesAndRanges(SymbolFileDWARF *dwarf2Data, const 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::DWARFExpression *frame_base=NULL) const
SymbolFileDWARF * GetSymbolFileDWARF() const
Definition: DWARFUnit.cpp:590
const char * DW_ATE_value_to_name(uint32_t val)
DWARFDIE GetDIE(dw_offset_t die_offset) const
Definition: DWARFDIE.cpp:124
DWARFDebugInfoEntry * GetSibling()
bool IsValid() const
Definition: DWARFBaseDIE.h:43
size_t Indent(const char *s=nullptr)
Indent the current line in the stream.
Definition: Stream.cpp:131
bool SkipValue(const lldb_private::DWARFDataExtractor &debug_info_data, lldb::offset_t *offset_ptr) const
dw_tag_t Tag() const
ObjectFile * GetObjectFile()
Definition: SymbolFile.h:213
#define DW_INVALID_OFFSET
Definition: dwarf.h:34
const char * GetName(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu) const
uint64_t GetULEB128(lldb::offset_t *offset_ptr) const
Extract a unsigned LEB128 value from *offset_ptr.
const char * GetMangledName(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, bool substitute_name_allowed=true) const
DWARFDIE GetParentDeclContextDIE() const
Definition: DWARFDIE.cpp:275
void AppendDeclContext(dw_tag_t tag, const char *name)
uint8_t GetU8(lldb::offset_t *offset_ptr) const
Extract a uint8_t value from *offset_ptr.
virtual DWARFDIE GetDIE(const DIERef &die_ref)
const lldb_private::DWARFDataExtractor & get_debug_ranges_data()
int g_verbose
uint32_t Skip_LEB128(lldb::offset_t *offset_ptr) const
Skip an LEB128 number at *offset_ptr.
const DWARFAbbreviationDeclaration * GetAbbreviationDeclaration(dw_uleb128_t abbrCode) const
void IndentMore(int amount=2)
Increment the current indentation level.
Definition: Stream.cpp:218
uint32_t GetU32_unchecked(lldb::offset_t *offset_ptr) const
uint64_t GetAttributeValueAsAddress(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value, bool check_specification_or_abstract_origin=false) const
const char * GetName() const
DWARFDIE GetParentDeclContextDIE(SymbolFileDWARF *dwarf2Data, DWARFUnit *cu) const
void Dump(lldb_private::Stream &s) const
const uint8_t * BlockData() const
SymbolFileDWARFDwo * GetDwoSymbolFile() const
Definition: DWARFUnit.cpp:767
uint16_t GetU16(lldb::offset_t *offset_ptr) const
Extract a uint16_t value from *offset_ptr.
void Dump(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, lldb_private::Stream &s, uint32_t recurse_depth) const
static void Dump(lldb_private::Stream &s, const lldb_private::DWARFDataExtractor &debug_ranges_data, lldb::offset_t *offset_ptr, dw_addr_t cu_base_addr)
const char * DW_TAG_value_to_name(uint32_t val)
void Append(const DWARFUnit *cu, dw_offset_t attr_die_offset, dw_attr_t attr, dw_form_t form)
bool operator==(const DWARFDebugInfoEntry &rhs) const
void BuildAddressRangeTable(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const
void Append(const Entry &entry)
Definition: RangeMap.h:139