aboutsummaryrefslogtreecommitdiff
path: root/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
blob: 25c885608d859200515eb96625bc7b5ee7ca03b9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
//===-- DWARFDebugInfoEntry.h -----------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef SymbolFileDWARF_DWARFDebugInfoEntry_h_
#define SymbolFileDWARF_DWARFDebugInfoEntry_h_

#include "SymbolFileDWARF.h"
#include "llvm/ADT/SmallVector.h"

#include "DWARFAbbreviationDeclaration.h"
#include "DWARFDebugAbbrev.h"
#include "DWARFDebugRanges.h"
#include <map>
#include <set>
#include <vector>

class DWARFDeclContext;

#define DIE_SIBLING_IDX_BITSIZE 31

class DWARFDebugInfoEntry {
public:
  typedef std::vector<DWARFDebugInfoEntry> collection;
  typedef collection::iterator iterator;
  typedef collection::const_iterator const_iterator;

  DWARFDebugInfoEntry()
      : m_offset(DW_INVALID_OFFSET), m_parent_idx(0), m_sibling_idx(0),
        m_has_children(false), m_abbr_idx(0), m_tag(llvm::dwarf::DW_TAG_null) {}

  explicit operator bool() const { return m_offset != DW_INVALID_OFFSET; }
  bool operator==(const DWARFDebugInfoEntry &rhs) const;
  bool operator!=(const DWARFDebugInfoEntry &rhs) const;

  void BuildAddressRangeTable(const DWARFUnit *cu,
                              DWARFDebugAranges *debug_aranges) const;

  void BuildFunctionAddressRangeTable(const DWARFUnit *cu,
                                      DWARFDebugAranges *debug_aranges) const;

  bool Extract(const lldb_private::DWARFDataExtractor &data,
               const DWARFUnit *cu, lldb::offset_t *offset_ptr);

  bool LookupAddress(const dw_addr_t address, const DWARFUnit *cu,
                     DWARFDebugInfoEntry **function_die,
                     DWARFDebugInfoEntry **block_die);

  size_t GetAttributes(const DWARFUnit *cu,
                       DWARFAttributes &attrs,
                       uint32_t curr_depth = 0)
      const; // "curr_depth" for internal use only, don't set this yourself!!!

  dw_offset_t
  GetAttributeValue(const DWARFUnit *cu, const dw_attr_t attr,
                    DWARFFormValue &formValue,
                    dw_offset_t *end_attr_offset_ptr = nullptr,
                    bool check_specification_or_abstract_origin = false) const;

  const char *GetAttributeValueAsString(
      const DWARFUnit *cu, const dw_attr_t attr, const char *fail_value,
      bool check_specification_or_abstract_origin = false) const;

  uint64_t GetAttributeValueAsUnsigned(
      const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value,
      bool check_specification_or_abstract_origin = false) const;

  DWARFDIE GetAttributeValueAsReference(
      const DWARFUnit *cu, const dw_attr_t attr,
      bool check_specification_or_abstract_origin = false) const;

  uint64_t GetAttributeValueAsAddress(
      const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value,
      bool check_specification_or_abstract_origin = false) const;

  dw_addr_t
  GetAttributeHighPC(const DWARFUnit *cu, dw_addr_t lo_pc, uint64_t fail_value,
                     bool check_specification_or_abstract_origin = false) const;

  bool GetAttributeAddressRange(
      const DWARFUnit *cu, dw_addr_t &lo_pc, dw_addr_t &hi_pc,
      uint64_t fail_value,
      bool check_specification_or_abstract_origin = false) const;

  size_t GetAttributeAddressRanges(
      const DWARFUnit *cu, DWARFRangeList &ranges, bool check_hi_lo_pc,
      bool check_specification_or_abstract_origin = false) const;

  const char *GetName(const DWARFUnit *cu) const;

  const char *GetMangledName(const DWARFUnit *cu,
                             bool substitute_name_allowed = true) const;

  const char *GetPubname(const DWARFUnit *cu) const;

  const char *GetQualifiedName(DWARFUnit *cu, std::string &storage) const;

  const char *GetQualifiedName(DWARFUnit *cu, const DWARFAttributes &attributes,
                               std::string &storage) const;

  void Dump(const DWARFUnit *cu, lldb_private::Stream &s,
            uint32_t recurse_depth) const;

  static void
  DumpAttribute(const DWARFUnit *cu,
                const lldb_private::DWARFDataExtractor &data,
                lldb::offset_t *offset_ptr, lldb_private::Stream &s,
                dw_attr_t attr, DWARFFormValue &form_value);

  bool GetDIENamesAndRanges(
      const DWARFUnit *cu, const char *&name, const char *&mangled,
      DWARFRangeList &rangeList, int &decl_file, int &decl_line,
      int &decl_column, int &call_file, int &call_line, int &call_column,
      lldb_private::DWARFExpression *frame_base = nullptr) const;

  const DWARFAbbreviationDeclaration *
  GetAbbreviationDeclarationPtr(const DWARFUnit *cu) const;

  lldb::offset_t GetFirstAttributeOffset() const;

  dw_tag_t Tag() const { return m_tag; }

  bool IsNULL() const { return m_abbr_idx == 0; }

  dw_offset_t GetOffset() const { return m_offset; }

  bool HasChildren() const { return m_has_children; }

  void SetHasChildren(bool b) { m_has_children = b; }

  // We know we are kept in a vector of contiguous entries, so we know
  // our parent will be some index behind "this".
  DWARFDebugInfoEntry *GetParent() {
    return m_parent_idx > 0 ? this - m_parent_idx : nullptr;
  }
  const DWARFDebugInfoEntry *GetParent() const {
    return m_parent_idx > 0 ? this - m_parent_idx : nullptr;
  }
  // We know we are kept in a vector of contiguous entries, so we know
  // our sibling will be some index after "this".
  DWARFDebugInfoEntry *GetSibling() {
    return m_sibling_idx > 0 ? this + m_sibling_idx : nullptr;
  }
  const DWARFDebugInfoEntry *GetSibling() const {
    return m_sibling_idx > 0 ? this + m_sibling_idx : nullptr;
  }
  // We know we are kept in a vector of contiguous entries, so we know
  // we don't need to store our child pointer, if we have a child it will
  // be the next entry in the list...
  DWARFDebugInfoEntry *GetFirstChild() {
    return HasChildren() ? this + 1 : nullptr;
  }
  const DWARFDebugInfoEntry *GetFirstChild() const {
    return HasChildren() ? this + 1 : nullptr;
  }

  void GetDWARFDeclContext(DWARFUnit *cu,
                           DWARFDeclContext &dwarf_decl_ctx) const;

  DWARFDIE GetParentDeclContextDIE(DWARFUnit *cu) const;
  DWARFDIE GetParentDeclContextDIE(DWARFUnit *cu,
                                   const DWARFAttributes &attributes) const;

  void SetSiblingIndex(uint32_t idx) { m_sibling_idx = idx; }
  void SetParentIndex(uint32_t idx) { m_parent_idx = idx; }

protected:
  dw_offset_t m_offset; // Offset within the .debug_info/.debug_types
  uint32_t m_parent_idx; // How many to subtract from "this" to get the parent.
                         // If zero this die has no parent
  uint32_t m_sibling_idx : 31, // How many to add to "this" to get the sibling.
      // If it is zero, then the DIE doesn't have children, or the
      // DWARF claimed it had children but the DIE only contained
      // a single NULL terminating child.
      m_has_children : 1;
  uint16_t m_abbr_idx;
  /// A copy of the DW_TAG value so we don't have to go through the compile
  /// unit abbrev table
  dw_tag_t m_tag = llvm::dwarf::DW_TAG_null;
};

#endif // SymbolFileDWARF_DWARFDebugInfoEntry_h_