xref: /freebsd-src/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===-- DWARFDebugInfoEntry.h -----------------------------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
95ffd83dbSDimitry Andric #ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGINFOENTRY_H
105ffd83dbSDimitry Andric #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGINFOENTRY_H
110b57cec5SDimitry Andric 
120b57cec5SDimitry Andric #include "SymbolFileDWARF.h"
130b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
140b57cec5SDimitry Andric 
1506c3fb27SDimitry Andric #include "DWARFAttribute.h"
165ffd83dbSDimitry Andric #include "DWARFBaseDIE.h"
170b57cec5SDimitry Andric #include "DWARFDebugRanges.h"
180b57cec5SDimitry Andric #include <map>
19bdd1243dSDimitry Andric #include <optional>
200b57cec5SDimitry Andric #include <set>
210b57cec5SDimitry Andric #include <vector>
220b57cec5SDimitry Andric 
2306c3fb27SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
2406c3fb27SDimitry Andric 
255f757f3fSDimitry Andric namespace lldb_private::plugin {
265f757f3fSDimitry Andric namespace dwarf {
270b57cec5SDimitry Andric class DWARFDeclContext;
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric #define DIE_SIBLING_IDX_BITSIZE 31
300b57cec5SDimitry Andric 
31480093f4SDimitry Andric /// DWARFDebugInfoEntry objects assume that they are living in one big
32480093f4SDimitry Andric /// vector and do pointer arithmetic on their this pointers. Don't
33480093f4SDimitry Andric /// pass them by value. Due to the way they are constructed in a
34480093f4SDimitry Andric /// std::vector, we cannot delete the copy constructor.
350b57cec5SDimitry Andric class DWARFDebugInfoEntry {
360b57cec5SDimitry Andric public:
370b57cec5SDimitry Andric   typedef std::vector<DWARFDebugInfoEntry> collection;
380b57cec5SDimitry Andric   typedef collection::iterator iterator;
390b57cec5SDimitry Andric   typedef collection::const_iterator const_iterator;
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric   DWARFDebugInfoEntry()
4206c3fb27SDimitry Andric       : m_offset(DW_INVALID_OFFSET), m_parent_idx(0), m_sibling_idx(0),
4306c3fb27SDimitry Andric         m_has_children(false) {}
440b57cec5SDimitry Andric 
450b57cec5SDimitry Andric   explicit operator bool() const { return m_offset != DW_INVALID_OFFSET; }
460b57cec5SDimitry Andric   bool operator==(const DWARFDebugInfoEntry &rhs) const;
470b57cec5SDimitry Andric   bool operator!=(const DWARFDebugInfoEntry &rhs) const;
480b57cec5SDimitry Andric 
49e8d8bef9SDimitry Andric   void BuildFunctionAddressRangeTable(DWARFUnit *cu,
500b57cec5SDimitry Andric                                       DWARFDebugAranges *debug_aranges) const;
510b57cec5SDimitry Andric 
52*0fca6ea1SDimitry Andric   bool Extract(const DWARFDataExtractor &data, const DWARFUnit &cu,
535f757f3fSDimitry Andric                lldb::offset_t *offset_ptr);
540b57cec5SDimitry Andric 
555ffd83dbSDimitry Andric   using Recurse = DWARFBaseDIE::Recurse;
5606c3fb27SDimitry Andric   DWARFAttributes GetAttributes(DWARFUnit *cu,
575ffd83dbSDimitry Andric                                 Recurse recurse = Recurse::yes) const {
5806c3fb27SDimitry Andric     DWARFAttributes attrs;
5906c3fb27SDimitry Andric     GetAttributes(cu, attrs, recurse, 0 /* curr_depth */);
6006c3fb27SDimitry Andric     return attrs;
615ffd83dbSDimitry Andric   }
620b57cec5SDimitry Andric 
630b57cec5SDimitry Andric   dw_offset_t
640b57cec5SDimitry Andric   GetAttributeValue(const DWARFUnit *cu, const dw_attr_t attr,
650b57cec5SDimitry Andric                     DWARFFormValue &formValue,
660b57cec5SDimitry Andric                     dw_offset_t *end_attr_offset_ptr = nullptr,
670b57cec5SDimitry Andric                     bool check_specification_or_abstract_origin = false) const;
680b57cec5SDimitry Andric 
690b57cec5SDimitry Andric   const char *GetAttributeValueAsString(
700b57cec5SDimitry Andric       const DWARFUnit *cu, const dw_attr_t attr, const char *fail_value,
710b57cec5SDimitry Andric       bool check_specification_or_abstract_origin = false) const;
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric   uint64_t GetAttributeValueAsUnsigned(
740b57cec5SDimitry Andric       const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value,
750b57cec5SDimitry Andric       bool check_specification_or_abstract_origin = false) const;
760b57cec5SDimitry Andric 
77bdd1243dSDimitry Andric   std::optional<uint64_t> GetAttributeValueAsOptionalUnsigned(
78bdd1243dSDimitry Andric       const DWARFUnit *cu, const dw_attr_t attr,
79bdd1243dSDimitry Andric       bool check_specification_or_abstract_origin = false) const;
80bdd1243dSDimitry Andric 
810b57cec5SDimitry Andric   DWARFDIE GetAttributeValueAsReference(
820b57cec5SDimitry Andric       const DWARFUnit *cu, const dw_attr_t attr,
830b57cec5SDimitry Andric       bool check_specification_or_abstract_origin = false) const;
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric   uint64_t GetAttributeValueAsAddress(
860b57cec5SDimitry Andric       const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value,
870b57cec5SDimitry Andric       bool check_specification_or_abstract_origin = false) const;
880b57cec5SDimitry Andric 
890b57cec5SDimitry Andric   dw_addr_t
900b57cec5SDimitry Andric   GetAttributeHighPC(const DWARFUnit *cu, dw_addr_t lo_pc, uint64_t fail_value,
910b57cec5SDimitry Andric                      bool check_specification_or_abstract_origin = false) const;
920b57cec5SDimitry Andric 
930b57cec5SDimitry Andric   bool GetAttributeAddressRange(
940b57cec5SDimitry Andric       const DWARFUnit *cu, dw_addr_t &lo_pc, dw_addr_t &hi_pc,
950b57cec5SDimitry Andric       uint64_t fail_value,
960b57cec5SDimitry Andric       bool check_specification_or_abstract_origin = false) const;
970b57cec5SDimitry Andric 
9806c3fb27SDimitry Andric   DWARFRangeList GetAttributeAddressRanges(
9906c3fb27SDimitry Andric       DWARFUnit *cu, bool check_hi_lo_pc,
1000b57cec5SDimitry Andric       bool check_specification_or_abstract_origin = false) const;
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric   const char *GetName(const DWARFUnit *cu) const;
1030b57cec5SDimitry Andric 
1040b57cec5SDimitry Andric   const char *GetMangledName(const DWARFUnit *cu,
1050b57cec5SDimitry Andric                              bool substitute_name_allowed = true) const;
1060b57cec5SDimitry Andric 
1070b57cec5SDimitry Andric   const char *GetPubname(const DWARFUnit *cu) const;
1080b57cec5SDimitry Andric 
1095f757f3fSDimitry Andric   bool GetDIENamesAndRanges(DWARFUnit *cu, const char *&name,
1105f757f3fSDimitry Andric                             const char *&mangled, DWARFRangeList &rangeList,
1115f757f3fSDimitry Andric                             std::optional<int> &decl_file,
1125f757f3fSDimitry Andric                             std::optional<int> &decl_line,
1135f757f3fSDimitry Andric                             std::optional<int> &decl_column,
1145f757f3fSDimitry Andric                             std::optional<int> &call_file,
1155f757f3fSDimitry Andric                             std::optional<int> &call_line,
11606c3fb27SDimitry Andric                             std::optional<int> &call_column,
1175f757f3fSDimitry Andric                             DWARFExpressionList *frame_base = nullptr) const;
1180b57cec5SDimitry Andric 
11906c3fb27SDimitry Andric   const llvm::DWARFAbbreviationDeclaration *
1200b57cec5SDimitry Andric   GetAbbreviationDeclarationPtr(const DWARFUnit *cu) const;
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric   lldb::offset_t GetFirstAttributeOffset() const;
1230b57cec5SDimitry Andric 
1240b57cec5SDimitry Andric   dw_tag_t Tag() const { return m_tag; }
1250b57cec5SDimitry Andric 
1260b57cec5SDimitry Andric   bool IsNULL() const { return m_abbr_idx == 0; }
1270b57cec5SDimitry Andric 
1280b57cec5SDimitry Andric   dw_offset_t GetOffset() const { return m_offset; }
1290b57cec5SDimitry Andric 
1300b57cec5SDimitry Andric   bool HasChildren() const { return m_has_children; }
1310b57cec5SDimitry Andric 
1320b57cec5SDimitry Andric   void SetHasChildren(bool b) { m_has_children = b; }
1330b57cec5SDimitry Andric 
1340b57cec5SDimitry Andric   // We know we are kept in a vector of contiguous entries, so we know
1350b57cec5SDimitry Andric   // our parent will be some index behind "this".
1360b57cec5SDimitry Andric   DWARFDebugInfoEntry *GetParent() {
1370b57cec5SDimitry Andric     return m_parent_idx > 0 ? this - m_parent_idx : nullptr;
1380b57cec5SDimitry Andric   }
1390b57cec5SDimitry Andric   const DWARFDebugInfoEntry *GetParent() const {
1400b57cec5SDimitry Andric     return m_parent_idx > 0 ? this - m_parent_idx : nullptr;
1410b57cec5SDimitry Andric   }
1420b57cec5SDimitry Andric   // We know we are kept in a vector of contiguous entries, so we know
1430b57cec5SDimitry Andric   // our sibling will be some index after "this".
1440b57cec5SDimitry Andric   DWARFDebugInfoEntry *GetSibling() {
1450b57cec5SDimitry Andric     return m_sibling_idx > 0 ? this + m_sibling_idx : nullptr;
1460b57cec5SDimitry Andric   }
1470b57cec5SDimitry Andric   const DWARFDebugInfoEntry *GetSibling() const {
1480b57cec5SDimitry Andric     return m_sibling_idx > 0 ? this + m_sibling_idx : nullptr;
1490b57cec5SDimitry Andric   }
1500b57cec5SDimitry Andric   // We know we are kept in a vector of contiguous entries, so we know
1510b57cec5SDimitry Andric   // we don't need to store our child pointer, if we have a child it will
1520b57cec5SDimitry Andric   // be the next entry in the list...
1530b57cec5SDimitry Andric   DWARFDebugInfoEntry *GetFirstChild() {
1540b57cec5SDimitry Andric     return HasChildren() ? this + 1 : nullptr;
1550b57cec5SDimitry Andric   }
1560b57cec5SDimitry Andric   const DWARFDebugInfoEntry *GetFirstChild() const {
1570b57cec5SDimitry Andric     return HasChildren() ? this + 1 : nullptr;
1580b57cec5SDimitry Andric   }
1590b57cec5SDimitry Andric 
1600b57cec5SDimitry Andric   void SetSiblingIndex(uint32_t idx) { m_sibling_idx = idx; }
1610b57cec5SDimitry Andric   void SetParentIndex(uint32_t idx) { m_parent_idx = idx; }
1620b57cec5SDimitry Andric 
1635ffd83dbSDimitry Andric   // This function returns true if the variable scope is either
1645ffd83dbSDimitry Andric   // global or (file-static). It will return false for static variables
1655ffd83dbSDimitry Andric   // that are local to a function, as they have local scope.
1665ffd83dbSDimitry Andric   bool IsGlobalOrStaticScopeVariable() const;
1675ffd83dbSDimitry Andric 
1680b57cec5SDimitry Andric protected:
16906c3fb27SDimitry Andric   // Up to 2TB offset within the .debug_info/.debug_types
17006c3fb27SDimitry Andric   dw_offset_t m_offset : DW_DIE_OFFSET_MAX_BITSIZE;
17106c3fb27SDimitry Andric   // How many to subtract from "this" to get the parent. If zero this die has no
17206c3fb27SDimitry Andric   // parent
17306c3fb27SDimitry Andric   dw_offset_t m_parent_idx : 64 - DW_DIE_OFFSET_MAX_BITSIZE;
17406c3fb27SDimitry Andric   // How many to add to "this" to get the sibling.
17506c3fb27SDimitry Andric   // If it is zero, then the DIE doesn't have children,
17606c3fb27SDimitry Andric   // or the DWARF claimed it had children but the DIE
17706c3fb27SDimitry Andric   // only contained a single NULL terminating child.
17806c3fb27SDimitry Andric   uint32_t m_sibling_idx : 31, m_has_children : 1;
179fe6060f1SDimitry Andric   uint16_t m_abbr_idx = 0;
1809dba64beSDimitry Andric   /// A copy of the DW_TAG value so we don't have to go through the compile
1819dba64beSDimitry Andric   /// unit abbrev table
1829dba64beSDimitry Andric   dw_tag_t m_tag = llvm::dwarf::DW_TAG_null;
1835ffd83dbSDimitry Andric 
1845ffd83dbSDimitry Andric private:
18506c3fb27SDimitry Andric   void GetAttributes(DWARFUnit *cu, DWARFAttributes &attrs, Recurse recurse,
186e8d8bef9SDimitry Andric                      uint32_t curr_depth) const;
1870b57cec5SDimitry Andric };
1885f757f3fSDimitry Andric } // namespace dwarf
1895f757f3fSDimitry Andric } // namespace lldb_private::plugin
1900b57cec5SDimitry Andric 
1915ffd83dbSDimitry Andric #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGINFOENTRY_H
192