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