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