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