1 //===-- DWARFDebugInfoEntry.h -----------------------------------*- 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 #ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGINFOENTRY_H 10 #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGINFOENTRY_H 11 12 #include "SymbolFileDWARF.h" 13 #include "llvm/ADT/SmallVector.h" 14 15 #include "DWARFAbbreviationDeclaration.h" 16 #include "DWARFBaseDIE.h" 17 #include "DWARFDebugAbbrev.h" 18 #include "DWARFDebugRanges.h" 19 #include <map> 20 #include <set> 21 #include <vector> 22 23 class DWARFDeclContext; 24 25 #define DIE_SIBLING_IDX_BITSIZE 31 26 27 /// DWARFDebugInfoEntry objects assume that they are living in one big 28 /// vector and do pointer arithmetic on their this pointers. Don't 29 /// pass them by value. Due to the way they are constructed in a 30 /// std::vector, we cannot delete the copy constructor. 31 class DWARFDebugInfoEntry { 32 public: 33 typedef std::vector<DWARFDebugInfoEntry> collection; 34 typedef collection::iterator iterator; 35 typedef collection::const_iterator const_iterator; 36 37 DWARFDebugInfoEntry() 38 : m_offset(DW_INVALID_OFFSET), m_sibling_idx(0), m_has_children(false) {} 39 40 explicit operator bool() const { return m_offset != DW_INVALID_OFFSET; } 41 bool operator==(const DWARFDebugInfoEntry &rhs) const; 42 bool operator!=(const DWARFDebugInfoEntry &rhs) const; 43 44 void BuildFunctionAddressRangeTable(DWARFUnit *cu, 45 DWARFDebugAranges *debug_aranges) const; 46 47 bool Extract(const lldb_private::DWARFDataExtractor &data, 48 const DWARFUnit *cu, lldb::offset_t *offset_ptr); 49 50 using Recurse = DWARFBaseDIE::Recurse; 51 size_t GetAttributes(DWARFUnit *cu, DWARFAttributes &attrs, 52 Recurse recurse = Recurse::yes) const { 53 return GetAttributes(cu, attrs, recurse, 0 /* curr_depth */); 54 } 55 56 dw_offset_t 57 GetAttributeValue(const DWARFUnit *cu, const dw_attr_t attr, 58 DWARFFormValue &formValue, 59 dw_offset_t *end_attr_offset_ptr = nullptr, 60 bool check_specification_or_abstract_origin = false) const; 61 62 const char *GetAttributeValueAsString( 63 const DWARFUnit *cu, const dw_attr_t attr, const char *fail_value, 64 bool check_specification_or_abstract_origin = false) const; 65 66 uint64_t GetAttributeValueAsUnsigned( 67 const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value, 68 bool check_specification_or_abstract_origin = false) const; 69 70 DWARFDIE GetAttributeValueAsReference( 71 const DWARFUnit *cu, const dw_attr_t attr, 72 bool check_specification_or_abstract_origin = false) const; 73 74 uint64_t GetAttributeValueAsAddress( 75 const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value, 76 bool check_specification_or_abstract_origin = false) const; 77 78 dw_addr_t 79 GetAttributeHighPC(const DWARFUnit *cu, dw_addr_t lo_pc, uint64_t fail_value, 80 bool check_specification_or_abstract_origin = false) const; 81 82 bool GetAttributeAddressRange( 83 const DWARFUnit *cu, dw_addr_t &lo_pc, dw_addr_t &hi_pc, 84 uint64_t fail_value, 85 bool check_specification_or_abstract_origin = false) const; 86 87 size_t GetAttributeAddressRanges( 88 DWARFUnit *cu, DWARFRangeList &ranges, bool check_hi_lo_pc, 89 bool check_specification_or_abstract_origin = false) const; 90 91 const char *GetName(const DWARFUnit *cu) const; 92 93 const char *GetMangledName(const DWARFUnit *cu, 94 bool substitute_name_allowed = true) const; 95 96 const char *GetPubname(const DWARFUnit *cu) const; 97 98 const char *GetQualifiedName(DWARFUnit *cu, std::string &storage) const; 99 100 const char *GetQualifiedName(DWARFUnit *cu, const DWARFAttributes &attributes, 101 std::string &storage) const; 102 103 bool GetDIENamesAndRanges( 104 DWARFUnit *cu, const char *&name, const char *&mangled, 105 DWARFRangeList &rangeList, int &decl_file, int &decl_line, 106 int &decl_column, int &call_file, int &call_line, int &call_column, 107 lldb_private::DWARFExpression *frame_base = nullptr) const; 108 109 const DWARFAbbreviationDeclaration * 110 GetAbbreviationDeclarationPtr(const DWARFUnit *cu) const; 111 112 lldb::offset_t GetFirstAttributeOffset() const; 113 114 dw_tag_t Tag() const { return m_tag; } 115 116 bool IsNULL() const { return m_abbr_idx == 0; } 117 118 dw_offset_t GetOffset() const { return m_offset; } 119 120 bool HasChildren() const { return m_has_children; } 121 122 void SetHasChildren(bool b) { m_has_children = b; } 123 124 // We know we are kept in a vector of contiguous entries, so we know 125 // our parent will be some index behind "this". 126 DWARFDebugInfoEntry *GetParent() { 127 return m_parent_idx > 0 ? this - m_parent_idx : nullptr; 128 } 129 const DWARFDebugInfoEntry *GetParent() const { 130 return m_parent_idx > 0 ? this - m_parent_idx : nullptr; 131 } 132 // We know we are kept in a vector of contiguous entries, so we know 133 // our sibling will be some index after "this". 134 DWARFDebugInfoEntry *GetSibling() { 135 return m_sibling_idx > 0 ? this + m_sibling_idx : nullptr; 136 } 137 const DWARFDebugInfoEntry *GetSibling() const { 138 return m_sibling_idx > 0 ? this + m_sibling_idx : nullptr; 139 } 140 // We know we are kept in a vector of contiguous entries, so we know 141 // we don't need to store our child pointer, if we have a child it will 142 // be the next entry in the list... 143 DWARFDebugInfoEntry *GetFirstChild() { 144 return HasChildren() ? this + 1 : nullptr; 145 } 146 const DWARFDebugInfoEntry *GetFirstChild() const { 147 return HasChildren() ? this + 1 : nullptr; 148 } 149 150 DWARFDeclContext GetDWARFDeclContext(DWARFUnit *cu) const; 151 152 DWARFDIE GetParentDeclContextDIE(DWARFUnit *cu) const; 153 DWARFDIE GetParentDeclContextDIE(DWARFUnit *cu, 154 const DWARFAttributes &attributes) const; 155 156 void SetSiblingIndex(uint32_t idx) { m_sibling_idx = idx; } 157 void SetParentIndex(uint32_t idx) { m_parent_idx = idx; } 158 159 // This function returns true if the variable scope is either 160 // global or (file-static). It will return false for static variables 161 // that are local to a function, as they have local scope. 162 bool IsGlobalOrStaticScopeVariable() const; 163 164 protected: 165 static DWARFDeclContext 166 GetDWARFDeclContextStatic(const DWARFDebugInfoEntry *die, DWARFUnit *cu); 167 168 dw_offset_t m_offset; // Offset within the .debug_info/.debug_types 169 uint32_t m_parent_idx = 0; // How many to subtract from "this" to get the 170 // parent. If zero this die has no parent 171 uint32_t m_sibling_idx : 31, // How many to add to "this" to get the sibling. 172 // If it is zero, then the DIE doesn't have children, or the 173 // DWARF claimed it had children but the DIE only contained 174 // a single NULL terminating child. 175 m_has_children : 1; 176 uint16_t m_abbr_idx = 0; 177 /// A copy of the DW_TAG value so we don't have to go through the compile 178 /// unit abbrev table 179 dw_tag_t m_tag = llvm::dwarf::DW_TAG_null; 180 181 private: 182 size_t GetAttributes(DWARFUnit *cu, DWARFAttributes &attrs, Recurse recurse, 183 uint32_t curr_depth) const; 184 }; 185 186 #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGINFOENTRY_H 187