1 //===-- DWARFDebugInfoEntry.cpp ---------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #include "DWARFDebugInfoEntry.h"
15 #include "llvm/Support/LEB128.h"
17 #include "lldb/Core/Module.h"
18 #include "lldb/Expression/DWARFExpression.h"
19 #include "lldb/Symbol/ObjectFile.h"
20 #include "lldb/Utility/Stream.h"
22 #include "DWARFCompileUnit.h"
23 #include "DWARFDebugAbbrev.h"
24 #include "DWARFDebugAranges.h"
25 #include "DWARFDebugInfo.h"
26 #include "DWARFDebugRanges.h"
27 #include "DWARFDeclContext.h"
28 #include "DWARFFormValue.h"
29 #include "DWARFUnit.h"
30 #include "SymbolFileDWARF.h"
31 #include "SymbolFileDWARFDwo.h"
33 using namespace lldb_private;
37 // Extract a debug info entry for a given DWARFUnit from the data
38 // starting at the offset in offset_ptr
39 bool DWARFDebugInfoEntry::Extract(const DWARFDataExtractor &data,
41 lldb::offset_t *offset_ptr) {
42 m_offset = *offset_ptr;
45 const uint64_t abbr_idx = data.GetULEB128(offset_ptr);
46 lldbassert(abbr_idx <= UINT16_MAX);
47 m_abbr_idx = abbr_idx;
49 // assert (fixed_form_sizes); // For best performance this should be
53 lldb::offset_t offset = *offset_ptr;
54 const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu);
55 if (abbrevDecl == nullptr) {
56 cu->GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
57 "{0x%8.8x}: invalid abbreviation code %u, please file a bug and "
58 "attach the file at the start of this error message",
59 m_offset, (unsigned)abbr_idx);
60 // WE can't parse anymore if the DWARF is borked...
61 *offset_ptr = UINT32_MAX;
64 m_tag = abbrevDecl->Tag();
65 m_has_children = abbrevDecl->HasChildren();
66 // Skip all data in the .debug_info or .debug_types for the attributes
67 const uint32_t numAttributes = abbrevDecl->NumAttributes();
70 for (i = 0; i < numAttributes; ++i) {
71 form = abbrevDecl->GetFormByIndexUnchecked(i);
72 llvm::Optional<uint8_t> fixed_skip_size =
73 DWARFFormValue::GetFixedSize(form, cu);
75 offset += *fixed_skip_size;
77 bool form_is_indirect = false;
79 form_is_indirect = false;
80 uint32_t form_size = 0;
82 // Blocks if inlined data that have a length field and the data bytes
83 // inlined in the .debug_info/.debug_types
86 form_size = data.GetULEB128(&offset);
89 form_size = data.GetU8_unchecked(&offset);
92 form_size = data.GetU16_unchecked(&offset);
95 form_size = data.GetU32_unchecked(&offset);
98 // Inlined NULL terminated C-strings
100 data.GetCStr(&offset);
103 // Compile unit address sized values
105 form_size = cu->GetAddressByteSize();
107 case DW_FORM_ref_addr:
108 if (cu->GetVersion() <= 2)
109 form_size = cu->GetAddressByteSize();
115 case DW_FORM_flag_present:
153 case DW_FORM_ref_sig8:
157 // signed or unsigned LEB 128 values
159 case DW_FORM_rnglistx:
162 case DW_FORM_ref_udata:
163 case DW_FORM_GNU_addr_index:
164 case DW_FORM_GNU_str_index:
166 data.Skip_LEB128(&offset);
169 case DW_FORM_indirect:
170 form_is_indirect = true;
171 form = data.GetULEB128(&offset);
175 case DW_FORM_sec_offset:
176 data.GetU32(&offset);
179 case DW_FORM_implicit_const:
184 *offset_ptr = m_offset;
189 } while (form_is_indirect);
192 *offset_ptr = offset;
196 m_has_children = false;
197 return true; // NULL debug tag entry
203 static DWARFRangeList GetRangesOrReportError(const DWARFUnit &unit,
204 const DWARFDebugInfoEntry &die,
205 const DWARFFormValue &value) {
206 llvm::Expected<DWARFRangeList> expected_ranges =
207 (value.Form() == DW_FORM_rnglistx)
208 ? unit.FindRnglistFromIndex(value.Unsigned())
209 : unit.FindRnglistFromOffset(value.Unsigned());
211 return std::move(*expected_ranges);
212 unit.GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
213 "{0x%8.8x}: DIE has DW_AT_ranges(0x%" PRIx64 ") attribute, but "
214 "range extraction failed (%s), please file a bug "
215 "and attach the file at the start of this error message",
216 die.GetOffset(), value.Unsigned(),
217 toString(expected_ranges.takeError()).c_str());
218 return DWARFRangeList();
221 // GetDIENamesAndRanges
223 // Gets the valid address ranges for a given DIE by looking for a
224 // DW_AT_low_pc/DW_AT_high_pc pair, DW_AT_entry_pc, or DW_AT_ranges attributes.
225 bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
226 const DWARFUnit *cu, const char *&name, const char *&mangled,
227 DWARFRangeList &ranges, int &decl_file, int &decl_line, int &decl_column,
228 int &call_file, int &call_line, int &call_column,
229 DWARFExpression *frame_base) const {
230 dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
231 dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
232 std::vector<DWARFDIE> dies;
233 bool set_frame_base_loclist_addr = false;
235 const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu);
237 SymbolFileDWARF &dwarf = cu->GetSymbolFileDWARF();
238 lldb::ModuleSP module = dwarf.GetObjectFile()->GetModule();
241 const DWARFDataExtractor &data = cu->GetData();
242 lldb::offset_t offset = GetFirstAttributeOffset();
244 if (!data.ValidOffset(offset))
247 const uint32_t numAttributes = abbrevDecl->NumAttributes();
248 bool do_offset = false;
250 for (uint32_t i = 0; i < numAttributes; ++i) {
251 DWARFFormValue form_value(cu);
253 abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value);
255 if (form_value.ExtractValue(data, &offset)) {
258 lo_pc = form_value.Address();
266 lo_pc = form_value.Address();
270 if (form_value.Form() == DW_FORM_addr ||
271 form_value.Form() == DW_FORM_addrx ||
272 form_value.Form() == DW_FORM_GNU_addr_index) {
273 hi_pc = form_value.Address();
275 hi_pc = form_value.Unsigned();
276 if (lo_pc == LLDB_INVALID_ADDRESS)
277 do_offset = hi_pc != LLDB_INVALID_ADDRESS;
279 hi_pc += lo_pc; // DWARF 4 introduces <offset-from-lo-pc> to save
285 ranges = GetRangesOrReportError(*cu, *this, form_value);
290 name = form_value.AsCString();
293 case DW_AT_MIPS_linkage_name:
294 case DW_AT_linkage_name:
295 if (mangled == nullptr)
296 mangled = form_value.AsCString();
299 case DW_AT_abstract_origin:
300 dies.push_back(form_value.Reference());
303 case DW_AT_specification:
304 dies.push_back(form_value.Reference());
307 case DW_AT_decl_file:
309 decl_file = form_value.Unsigned();
312 case DW_AT_decl_line:
314 decl_line = form_value.Unsigned();
317 case DW_AT_decl_column:
318 if (decl_column == 0)
319 decl_column = form_value.Unsigned();
322 case DW_AT_call_file:
324 call_file = form_value.Unsigned();
327 case DW_AT_call_line:
329 call_line = form_value.Unsigned();
332 case DW_AT_call_column:
333 if (call_column == 0)
334 call_column = form_value.Unsigned();
337 case DW_AT_frame_base:
339 if (form_value.BlockData()) {
340 uint32_t block_offset =
341 form_value.BlockData() - data.GetDataStart();
342 uint32_t block_length = form_value.Unsigned();
343 *frame_base = DWARFExpression(module, data, cu,
344 block_offset, block_length);
346 const DWARFDataExtractor &debug_loc_data = dwarf.DebugLocData();
347 const dw_offset_t debug_loc_offset = form_value.Unsigned();
349 size_t loc_list_length = DWARFExpression::LocationListSize(
350 cu, debug_loc_data, debug_loc_offset);
351 if (loc_list_length > 0) {
353 DWARFExpression(module, debug_loc_data, cu,
354 debug_loc_offset, loc_list_length);
355 if (lo_pc != LLDB_INVALID_ADDRESS) {
356 assert(lo_pc >= cu->GetBaseAddress());
357 frame_base->SetLocationListSlide(lo_pc -
358 cu->GetBaseAddress());
360 set_frame_base_loclist_addr = true;
374 if (ranges.IsEmpty()) {
375 if (lo_pc != LLDB_INVALID_ADDRESS) {
376 if (hi_pc != LLDB_INVALID_ADDRESS && hi_pc > lo_pc)
377 ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc));
379 ranges.Append(DWARFRangeList::Entry(lo_pc, 0));
383 if (set_frame_base_loclist_addr) {
384 dw_addr_t lowest_range_pc = ranges.GetMinRangeBase(0);
385 assert(lowest_range_pc >= cu->GetBaseAddress());
386 frame_base->SetLocationListSlide(lowest_range_pc - cu->GetBaseAddress());
389 if (ranges.IsEmpty() || name == nullptr || mangled == nullptr) {
390 for (const DWARFDIE &die : dies) {
392 die.GetDIE()->GetDIENamesAndRanges(die.GetCU(), name, mangled, ranges,
393 decl_file, decl_line, decl_column,
394 call_file, call_line, call_column);
398 return !ranges.IsEmpty();
403 // Dumps a debug information entry and all of it's attributes to the specified
405 void DWARFDebugInfoEntry::Dump(const DWARFUnit *cu, Stream &s,
406 uint32_t recurse_depth) const {
407 const DWARFDataExtractor &data = cu->GetData();
408 lldb::offset_t offset = m_offset;
410 if (data.ValidOffset(offset)) {
411 dw_uleb128_t abbrCode = data.GetULEB128(&offset);
413 s.Printf("\n0x%8.8x: ", m_offset);
415 if (abbrCode != m_abbr_idx) {
416 s.Printf("error: DWARF has been modified\n");
417 } else if (abbrCode) {
418 const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu);
420 s.PutCString(DW_TAG_value_to_name(abbrevDecl->Tag()));
421 s.Printf(" [%u] %c\n", abbrCode, abbrevDecl->HasChildren() ? '*' : ' ');
423 // Dump all data in the .debug_info/.debug_types for the attributes
424 const uint32_t numAttributes = abbrevDecl->NumAttributes();
425 for (uint32_t i = 0; i < numAttributes; ++i) {
426 DWARFFormValue form_value(cu);
428 abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value);
430 DumpAttribute(cu, data, &offset, s, attr, form_value);
433 const DWARFDebugInfoEntry *child = GetFirstChild();
434 if (recurse_depth > 0 && child) {
438 child->Dump(cu, s, recurse_depth - 1);
439 child = child->GetSibling();
444 s.Printf("Abbreviation code note found in 'debug_abbrev' class for "
455 // Dumps a debug information entry attribute along with it's form. Any special
456 // display of attributes is done (disassemble location lists, show enumeration
457 // values for attributes, etc).
458 void DWARFDebugInfoEntry::DumpAttribute(
459 const DWARFUnit *cu, const DWARFDataExtractor &data,
460 lldb::offset_t *offset_ptr, Stream &s, dw_attr_t attr,
461 DWARFFormValue &form_value) {
462 bool show_form = s.GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowForm);
465 s.Indent(DW_AT_value_to_name(attr));
468 s.Printf("[%s", DW_FORM_value_to_name(form_value.Form()));
471 if (!form_value.ExtractValue(data, offset_ptr))
475 if (form_value.Form() == DW_FORM_indirect) {
476 s.Printf(" [%s]", DW_FORM_value_to_name(form_value.Form()));
484 SymbolFileDWARF &dwarf = cu->GetSymbolFileDWARF();
486 // Check to see if we have any special attribute formatters
488 case DW_AT_stmt_list:
489 s.Printf("0x%8.8" PRIx64, form_value.Unsigned());
493 s.PutCString(DW_LANG_value_to_name(form_value.Unsigned()));
497 s.PutCString(DW_ATE_value_to_name(form_value.Unsigned()));
500 case DW_AT_frame_base:
502 case DW_AT_data_member_location: {
503 const uint8_t *blockData = form_value.BlockData();
505 // Location description is inlined in data in the form value
506 DWARFDataExtractor locationData(data,
507 (*offset_ptr) - form_value.Unsigned(),
508 form_value.Unsigned());
509 DWARFExpression::PrintDWARFExpression(
510 s, locationData, DWARFUnit::GetAddressByteSize(cu), 4, false);
512 // We have a location list offset as the value that is the offset into
513 // the .debug_loc section that describes the value over it's lifetime
514 uint64_t debug_loc_offset = form_value.Unsigned();
515 DWARFExpression::PrintDWARFLocationList(s, cu, dwarf.DebugLocData(),
520 case DW_AT_abstract_origin:
521 case DW_AT_specification: {
522 DWARFDIE abstract_die = form_value.Reference();
524 // *ostrm_ptr << HEX32 << abstract_die.GetOffset() << " ( ";
525 abstract_die.GetName(s);
529 DWARFDIE type_die = form_value.Reference();
531 type_die.AppendTypeName(s);
539 s.PutCString(" )\n");
542 // Get all attribute values for a given DIE, including following any
543 // specification or abstract origin attributes and including those in the
544 // results. Any duplicate attributes will have the first instance take
545 // precedence (this can happen for declaration attributes).
546 size_t DWARFDebugInfoEntry::GetAttributes(
547 const DWARFUnit *cu, DWARFAttributes &attributes,
548 uint32_t curr_depth) const {
549 const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu);
551 const DWARFDataExtractor &data = cu->GetData();
552 lldb::offset_t offset = GetFirstAttributeOffset();
554 const uint32_t num_attributes = abbrevDecl->NumAttributes();
555 for (uint32_t i = 0; i < num_attributes; ++i) {
556 DWARFFormValue form_value(cu);
558 abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value);
559 const dw_form_t form = form_value.Form();
561 // If we are tracking down DW_AT_specification or DW_AT_abstract_origin
562 // attributes, the depth will be non-zero. We need to omit certain
563 // attributes that don't make sense.
566 case DW_AT_declaration:
567 if (curr_depth > 0) {
568 // This attribute doesn't make sense when combined with the DIE that
569 // references this DIE. We know a DIE is referencing this DIE because
570 // curr_depth is not zero
575 attributes.Append(cu, offset, attr, form);
579 if ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin)) {
580 if (form_value.ExtractValue(data, &offset)) {
581 DWARFDIE spec_die = form_value.Reference();
583 spec_die.GetAttributes(attributes, curr_depth + 1);
586 llvm::Optional<uint8_t> fixed_skip_size = DWARFFormValue::GetFixedSize(form, cu);
588 offset += *fixed_skip_size;
590 DWARFFormValue::SkipValue(form, data, &offset, cu);
596 return attributes.Size();
601 // Get the value of an attribute and return the .debug_info or .debug_types
602 // offset of the attribute if it was properly extracted into form_value,
603 // or zero if we fail since an offset of zero is invalid for an attribute (it
604 // would be a compile unit header).
605 dw_offset_t DWARFDebugInfoEntry::GetAttributeValue(
606 const DWARFUnit *cu, const dw_attr_t attr, DWARFFormValue &form_value,
607 dw_offset_t *end_attr_offset_ptr,
608 bool check_specification_or_abstract_origin) const {
609 if (const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu)) {
610 uint32_t attr_idx = abbrevDecl->FindAttributeIndex(attr);
612 if (attr_idx != DW_INVALID_INDEX) {
613 const DWARFDataExtractor &data = cu->GetData();
614 lldb::offset_t offset = GetFirstAttributeOffset();
617 while (idx < attr_idx)
618 DWARFFormValue::SkipValue(abbrevDecl->GetFormByIndex(idx++),
621 const dw_offset_t attr_offset = offset;
622 form_value.SetUnit(cu);
623 form_value.SetForm(abbrevDecl->GetFormByIndex(idx));
624 if (form_value.ExtractValue(data, &offset)) {
625 if (end_attr_offset_ptr)
626 *end_attr_offset_ptr = offset;
632 if (check_specification_or_abstract_origin) {
633 if (GetAttributeValue(cu, DW_AT_specification, form_value)) {
634 DWARFDIE die = form_value.Reference();
636 dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(
637 die.GetCU(), attr, form_value, end_attr_offset_ptr, false);
643 if (GetAttributeValue(cu, DW_AT_abstract_origin, form_value)) {
644 DWARFDIE die = form_value.Reference();
646 dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(
647 die.GetCU(), attr, form_value, end_attr_offset_ptr, false);
654 // If we're a unit DIE, also check the attributes of the dwo unit (if any).
657 SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile();
658 if (!dwo_symbol_file)
661 DWARFCompileUnit *dwo_cu = dwo_symbol_file->GetCompileUnit();
665 DWARFBaseDIE dwo_cu_die = dwo_cu->GetUnitDIEOnly();
666 if (!dwo_cu_die.IsValid())
669 return dwo_cu_die.GetDIE()->GetAttributeValue(
670 dwo_cu, attr, form_value, end_attr_offset_ptr,
671 check_specification_or_abstract_origin);
674 // GetAttributeValueAsString
676 // Get the value of an attribute as a string return it. The resulting pointer
677 // to the string data exists within the supplied SymbolFileDWARF and will only
678 // be available as long as the SymbolFileDWARF is still around and it's content
680 const char *DWARFDebugInfoEntry::GetAttributeValueAsString(
681 const DWARFUnit *cu, const dw_attr_t attr, const char *fail_value,
682 bool check_specification_or_abstract_origin) const {
683 DWARFFormValue form_value;
684 if (GetAttributeValue(cu, attr, form_value, nullptr,
685 check_specification_or_abstract_origin))
686 return form_value.AsCString();
690 // GetAttributeValueAsUnsigned
692 // Get the value of an attribute as unsigned and return it.
693 uint64_t DWARFDebugInfoEntry::GetAttributeValueAsUnsigned(
694 const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value,
695 bool check_specification_or_abstract_origin) const {
696 DWARFFormValue form_value;
697 if (GetAttributeValue(cu, attr, form_value, nullptr,
698 check_specification_or_abstract_origin))
699 return form_value.Unsigned();
703 // GetAttributeValueAsReference
705 // Get the value of an attribute as reference and fix up and compile unit
706 // relative offsets as needed.
707 DWARFDIE DWARFDebugInfoEntry::GetAttributeValueAsReference(
708 const DWARFUnit *cu, const dw_attr_t attr,
709 bool check_specification_or_abstract_origin) const {
710 DWARFFormValue form_value;
711 if (GetAttributeValue(cu, attr, form_value, nullptr,
712 check_specification_or_abstract_origin))
713 return form_value.Reference();
717 uint64_t DWARFDebugInfoEntry::GetAttributeValueAsAddress(
718 const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value,
719 bool check_specification_or_abstract_origin) const {
720 DWARFFormValue form_value;
721 if (GetAttributeValue(cu, attr, form_value, nullptr,
722 check_specification_or_abstract_origin))
723 return form_value.Address();
727 // GetAttributeHighPC
729 // Get the hi_pc, adding hi_pc to lo_pc when specified as an <offset-from-low-
732 // Returns the hi_pc or fail_value.
733 dw_addr_t DWARFDebugInfoEntry::GetAttributeHighPC(
734 const DWARFUnit *cu, dw_addr_t lo_pc, uint64_t fail_value,
735 bool check_specification_or_abstract_origin) const {
736 DWARFFormValue form_value;
737 if (GetAttributeValue(cu, DW_AT_high_pc, form_value, nullptr,
738 check_specification_or_abstract_origin)) {
739 dw_form_t form = form_value.Form();
740 if (form == DW_FORM_addr || form == DW_FORM_addrx ||
741 form == DW_FORM_GNU_addr_index)
742 return form_value.Address();
744 // DWARF4 can specify the hi_pc as an <offset-from-lowpc>
745 return lo_pc + form_value.Unsigned();
750 // GetAttributeAddressRange
752 // Get the lo_pc and hi_pc, adding hi_pc to lo_pc when specified as an <offset-
755 // Returns true or sets lo_pc and hi_pc to fail_value.
756 bool DWARFDebugInfoEntry::GetAttributeAddressRange(
757 const DWARFUnit *cu, dw_addr_t &lo_pc, dw_addr_t &hi_pc,
758 uint64_t fail_value, bool check_specification_or_abstract_origin) const {
759 lo_pc = GetAttributeValueAsAddress(cu, DW_AT_low_pc, fail_value,
760 check_specification_or_abstract_origin);
761 if (lo_pc != fail_value) {
762 hi_pc = GetAttributeHighPC(cu, lo_pc, fail_value,
763 check_specification_or_abstract_origin);
764 if (hi_pc != fail_value)
772 size_t DWARFDebugInfoEntry::GetAttributeAddressRanges(
773 const DWARFUnit *cu, DWARFRangeList &ranges, bool check_hi_lo_pc,
774 bool check_specification_or_abstract_origin) const {
777 DWARFFormValue form_value;
778 if (GetAttributeValue(cu, DW_AT_ranges, form_value)) {
779 ranges = GetRangesOrReportError(*cu, *this, form_value);
780 } else if (check_hi_lo_pc) {
781 dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
782 dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
783 if (GetAttributeAddressRange(cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS,
784 check_specification_or_abstract_origin)) {
786 ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc));
789 return ranges.GetSize();
794 // Get value of the DW_AT_name attribute and return it if one exists, else
796 const char *DWARFDebugInfoEntry::GetName(const DWARFUnit *cu) const {
797 return GetAttributeValueAsString(cu, DW_AT_name, nullptr, true);
802 // Get value of the DW_AT_MIPS_linkage_name attribute and return it if one
803 // exists, else return the value of the DW_AT_name attribute
805 DWARFDebugInfoEntry::GetMangledName(const DWARFUnit *cu,
806 bool substitute_name_allowed) const {
807 const char *name = nullptr;
809 name = GetAttributeValueAsString(cu, DW_AT_MIPS_linkage_name, nullptr, true);
813 name = GetAttributeValueAsString(cu, DW_AT_linkage_name, nullptr, true);
817 if (!substitute_name_allowed)
820 name = GetAttributeValueAsString(cu, DW_AT_name, nullptr, true);
826 // Get value the name for a DIE as it should appear for a .debug_pubnames or
827 // .debug_pubtypes section.
828 const char *DWARFDebugInfoEntry::GetPubname(const DWARFUnit *cu) const {
829 const char *name = nullptr;
833 name = GetAttributeValueAsString(cu, DW_AT_MIPS_linkage_name, nullptr, true);
837 name = GetAttributeValueAsString(cu, DW_AT_linkage_name, nullptr, true);
841 name = GetAttributeValueAsString(cu, DW_AT_name, nullptr, true);
845 // BuildAddressRangeTable
846 void DWARFDebugInfoEntry::BuildAddressRangeTable(
847 const DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const {
849 if (m_tag == DW_TAG_subprogram) {
850 dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
851 dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
852 if (GetAttributeAddressRange(cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS)) {
853 /// printf("BuildAddressRangeTable() 0x%8.8x: %30s: [0x%8.8x -
854 /// 0x%8.8x)\n", m_offset, DW_TAG_value_to_name(tag), lo_pc, hi_pc);
855 debug_aranges->AppendRange(cu->GetOffset(), lo_pc, hi_pc);
859 const DWARFDebugInfoEntry *child = GetFirstChild();
861 child->BuildAddressRangeTable(cu, debug_aranges);
862 child = child->GetSibling();
867 // BuildFunctionAddressRangeTable
869 // This function is very similar to the BuildAddressRangeTable function except
870 // that the actual DIE offset for the function is placed in the table instead
871 // of the compile unit offset (which is the way the standard .debug_aranges
873 void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable(
874 const DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const {
876 if (m_tag == DW_TAG_subprogram) {
877 dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
878 dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
879 if (GetAttributeAddressRange(cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS)) {
880 // printf("BuildAddressRangeTable() 0x%8.8x: [0x%16.16" PRIx64 " -
881 // 0x%16.16" PRIx64 ")\n", m_offset, lo_pc, hi_pc); // DEBUG ONLY
882 debug_aranges->AppendRange(GetOffset(), lo_pc, hi_pc);
886 const DWARFDebugInfoEntry *child = GetFirstChild();
888 child->BuildFunctionAddressRangeTable(cu, debug_aranges);
889 child = child->GetSibling();
894 void DWARFDebugInfoEntry::GetDWARFDeclContext(
895 DWARFUnit *cu, DWARFDeclContext &dwarf_decl_ctx) const {
896 const dw_tag_t tag = Tag();
897 if (tag != DW_TAG_compile_unit && tag != DW_TAG_partial_unit) {
898 dwarf_decl_ctx.AppendDeclContext(tag, GetName(cu));
899 DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(cu);
900 if (parent_decl_ctx_die && parent_decl_ctx_die.GetDIE() != this) {
901 if (parent_decl_ctx_die.Tag() != DW_TAG_compile_unit &&
902 parent_decl_ctx_die.Tag() != DW_TAG_partial_unit)
903 parent_decl_ctx_die.GetDIE()->GetDWARFDeclContext(
904 parent_decl_ctx_die.GetCU(), dwarf_decl_ctx);
910 DWARFDebugInfoEntry::GetParentDeclContextDIE(DWARFUnit *cu) const {
911 DWARFAttributes attributes;
912 GetAttributes(cu, attributes);
913 return GetParentDeclContextDIE(cu, attributes);
917 DWARFDebugInfoEntry::GetParentDeclContextDIE(
918 DWARFUnit *cu, const DWARFAttributes &attributes) const {
919 DWARFDIE die(cu, const_cast<DWARFDebugInfoEntry *>(this));
922 // If this is the original DIE that we are searching for a declaration for,
923 // then don't look in the cache as we don't want our own decl context to be
924 // our decl context...
925 if (die.GetDIE() != this) {
927 case DW_TAG_compile_unit:
928 case DW_TAG_partial_unit:
929 case DW_TAG_namespace:
930 case DW_TAG_structure_type:
931 case DW_TAG_union_type:
932 case DW_TAG_class_type:
940 DWARFDIE spec_die = attributes.FormValueAsReference(DW_AT_specification);
942 DWARFDIE decl_ctx_die = spec_die.GetParentDeclContextDIE();
947 DWARFDIE abs_die = attributes.FormValueAsReference(DW_AT_abstract_origin);
949 DWARFDIE decl_ctx_die = abs_die.GetParentDeclContextDIE();
954 die = die.GetParent();
959 const char *DWARFDebugInfoEntry::GetQualifiedName(DWARFUnit *cu,
960 std::string &storage) const {
961 DWARFAttributes attributes;
962 GetAttributes(cu, attributes);
963 return GetQualifiedName(cu, attributes, storage);
967 DWARFDebugInfoEntry::GetQualifiedName(DWARFUnit *cu,
968 const DWARFAttributes &attributes,
969 std::string &storage) const {
971 const char *name = GetName(cu);
974 DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(cu);
976 // TODO: change this to get the correct decl context parent....
977 while (parent_decl_ctx_die) {
978 const dw_tag_t parent_tag = parent_decl_ctx_die.Tag();
979 switch (parent_tag) {
980 case DW_TAG_namespace: {
981 const char *namespace_name = parent_decl_ctx_die.GetName();
982 if (namespace_name) {
983 storage.insert(0, "::");
984 storage.insert(0, namespace_name);
986 storage.insert(0, "(anonymous namespace)::");
988 parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE();
991 case DW_TAG_class_type:
992 case DW_TAG_structure_type:
993 case DW_TAG_union_type: {
994 const char *class_union_struct_name = parent_decl_ctx_die.GetName();
996 if (class_union_struct_name) {
997 storage.insert(0, "::");
998 storage.insert(0, class_union_struct_name);
1000 parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE();
1004 parent_decl_ctx_die.Clear();
1009 if (storage.empty())
1010 storage.append("::");
1012 storage.append(name);
1014 if (storage.empty())
1016 return storage.c_str();
1019 bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address,
1020 const DWARFUnit *cu,
1021 DWARFDebugInfoEntry **function_die,
1022 DWARFDebugInfoEntry **block_die) {
1023 bool found_address = false;
1025 bool check_children = false;
1026 bool match_addr_range = false;
1027 // printf("0x%8.8x: %30s: address = 0x%8.8x - ", m_offset,
1028 // DW_TAG_value_to_name(tag), address);
1030 case DW_TAG_array_type:
1032 case DW_TAG_class_type:
1033 check_children = true;
1035 case DW_TAG_entry_point:
1036 case DW_TAG_enumeration_type:
1037 case DW_TAG_formal_parameter:
1038 case DW_TAG_imported_declaration:
1041 case DW_TAG_lexical_block:
1042 check_children = true;
1043 match_addr_range = true;
1046 case DW_TAG_pointer_type:
1047 case DW_TAG_reference_type:
1049 case DW_TAG_compile_unit:
1050 match_addr_range = true;
1052 case DW_TAG_string_type:
1054 case DW_TAG_structure_type:
1055 check_children = true;
1057 case DW_TAG_subroutine_type:
1058 case DW_TAG_typedef:
1059 case DW_TAG_union_type:
1060 case DW_TAG_unspecified_parameters:
1061 case DW_TAG_variant:
1063 case DW_TAG_common_block:
1064 check_children = true;
1066 case DW_TAG_common_inclusion:
1067 case DW_TAG_inheritance:
1069 case DW_TAG_inlined_subroutine:
1070 check_children = true;
1071 match_addr_range = true;
1074 match_addr_range = true;
1076 case DW_TAG_ptr_to_member_type:
1077 case DW_TAG_set_type:
1078 case DW_TAG_subrange_type:
1079 case DW_TAG_with_stmt:
1080 case DW_TAG_access_declaration:
1081 case DW_TAG_base_type:
1083 case DW_TAG_catch_block:
1084 match_addr_range = true;
1086 case DW_TAG_const_type:
1087 case DW_TAG_constant:
1088 case DW_TAG_enumerator:
1089 case DW_TAG_file_type:
1091 case DW_TAG_namelist:
1092 case DW_TAG_namelist_item:
1093 case DW_TAG_packed_type:
1095 case DW_TAG_subprogram:
1096 match_addr_range = true;
1098 case DW_TAG_template_type_parameter:
1099 case DW_TAG_template_value_parameter:
1100 case DW_TAG_GNU_template_parameter_pack:
1101 case DW_TAG_thrown_type:
1103 case DW_TAG_try_block:
1104 match_addr_range = true;
1106 case DW_TAG_variant_part:
1107 case DW_TAG_variable:
1108 case DW_TAG_volatile_type:
1109 case DW_TAG_dwarf_procedure:
1110 case DW_TAG_restrict_type:
1111 case DW_TAG_interface_type:
1113 case DW_TAG_namespace:
1114 check_children = true;
1116 case DW_TAG_imported_module:
1117 case DW_TAG_unspecified_type:
1119 case DW_TAG_partial_unit:
1120 match_addr_range = true;
1122 case DW_TAG_imported_unit:
1123 case DW_TAG_shared_type:
1128 if (match_addr_range) {
1130 GetAttributeValueAsAddress(cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
1131 if (lo_pc != LLDB_INVALID_ADDRESS) {
1132 dw_addr_t hi_pc = GetAttributeHighPC(cu, lo_pc, LLDB_INVALID_ADDRESS);
1133 if (hi_pc != LLDB_INVALID_ADDRESS) {
1134 // printf("\n0x%8.8x: %30s: address = 0x%8.8x [0x%8.8x - 0x%8.8x) ",
1135 // m_offset, DW_TAG_value_to_name(tag), address, lo_pc, hi_pc);
1136 if ((lo_pc <= address) && (address < hi_pc)) {
1137 found_address = true;
1138 // puts("***MATCH***");
1140 case DW_TAG_compile_unit: // File
1141 case DW_TAG_partial_unit: // File
1143 ((function_die != nullptr) || (block_die != nullptr));
1146 case DW_TAG_subprogram: // Function
1148 *function_die = this;
1149 check_children = (block_die != nullptr);
1152 case DW_TAG_inlined_subroutine: // Inlined Function
1153 case DW_TAG_lexical_block: // Block { } in code
1156 check_children = true;
1161 check_children = true;
1166 // Compile units may not have a valid high/low pc when there
1167 // are address gaps in subroutines so we must always search
1168 // if there is no valid high and low PC.
1170 (m_tag == DW_TAG_compile_unit || m_tag == DW_TAG_partial_unit) &&
1171 ((function_die != nullptr) || (block_die != nullptr));
1174 DWARFRangeList ranges;
1175 if (GetAttributeAddressRanges(cu, ranges, /*check_hi_lo_pc*/ false) &&
1176 ranges.FindEntryThatContains(address)) {
1177 found_address = true;
1178 // puts("***MATCH***");
1180 case DW_TAG_compile_unit: // File
1181 case DW_TAG_partial_unit: // File
1183 ((function_die != nullptr) || (block_die != nullptr));
1186 case DW_TAG_subprogram: // Function
1188 *function_die = this;
1189 check_children = (block_die != nullptr);
1192 case DW_TAG_inlined_subroutine: // Inlined Function
1193 case DW_TAG_lexical_block: // Block { } in code
1196 check_children = true;
1201 check_children = true;
1205 check_children = false;
1210 if (check_children) {
1211 // printf("checking children\n");
1212 DWARFDebugInfoEntry *child = GetFirstChild();
1214 if (child->LookupAddress(address, cu, function_die, block_die))
1216 child = child->GetSibling();
1220 return found_address;
1223 lldb::offset_t DWARFDebugInfoEntry::GetFirstAttributeOffset() const {
1224 return GetOffset() + llvm::getULEB128Size(m_abbr_idx);
1227 const DWARFAbbreviationDeclaration *
1228 DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr(const DWARFUnit *cu) const {
1230 const DWARFAbbreviationDeclarationSet *abbrev_set = cu->GetAbbreviations();
1232 return abbrev_set->GetAbbreviationDeclaration(m_abbr_idx);
1237 bool DWARFDebugInfoEntry::operator==(const DWARFDebugInfoEntry &rhs) const {
1238 return m_offset == rhs.m_offset && m_parent_idx == rhs.m_parent_idx &&
1239 m_sibling_idx == rhs.m_sibling_idx &&
1240 m_abbr_idx == rhs.m_abbr_idx && m_has_children == rhs.m_has_children &&
1244 bool DWARFDebugInfoEntry::operator!=(const DWARFDebugInfoEntry &rhs) const {
1245 return !(*this == rhs);