Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h
39645 views
1
//===-- DIERef.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_DIEREF_H
10
#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DIEREF_H
11
12
#include "lldb/Core/dwarf.h"
13
#include "lldb/Utility/LLDBAssert.h"
14
#include <cassert>
15
#include <optional>
16
17
namespace lldb_private::plugin {
18
namespace dwarf {
19
/// Identifies a DWARF debug info entry within a given Module. It contains three
20
/// "coordinates":
21
/// - file_index: identifies the separate stand alone debug info file
22
/// that is referred to by the main debug info file. This will be the
23
/// index of a DWO file for fission, or the .o file on mac when not
24
/// using a dSYM file. If this field is not set, then this references
25
/// a DIE inside the original object file.
26
/// - section: identifies the section of the debug info entry in the given file:
27
/// debug_info or debug_types.
28
/// - die_offset: The offset of the debug info entry as an absolute offset from
29
/// the beginning of the section specified in the section field.
30
class DIERef {
31
public:
32
enum Section : uint8_t { DebugInfo, DebugTypes };
33
DIERef(std::optional<uint32_t> file_index, Section section,
34
dw_offset_t die_offset)
35
: m_die_offset(die_offset), m_file_index(file_index.value_or(0)),
36
m_file_index_valid(file_index ? true : false), m_section(section) {
37
assert(this->file_index() == file_index && "File Index is out of range?");
38
}
39
40
explicit DIERef(lldb::user_id_t uid) {
41
m_die_offset = uid & k_die_offset_mask;
42
m_file_index_valid = (uid & k_file_index_valid_bit) != 0;
43
m_file_index = m_file_index_valid
44
? (uid >> k_die_offset_bit_size) & k_file_index_mask
45
: 0;
46
m_section =
47
(uid & k_section_bit) != 0 ? Section::DebugTypes : Section::DebugInfo;
48
}
49
50
lldb::user_id_t get_id() const {
51
if (m_die_offset == k_die_offset_mask)
52
return LLDB_INVALID_UID;
53
54
return lldb::user_id_t(file_index().value_or(0)) << k_die_offset_bit_size |
55
die_offset() | (m_file_index_valid ? k_file_index_valid_bit : 0) |
56
(section() == Section::DebugTypes ? k_section_bit : 0);
57
}
58
59
std::optional<uint32_t> file_index() const {
60
if (m_file_index_valid)
61
return m_file_index;
62
return std::nullopt;
63
}
64
65
Section section() const { return static_cast<Section>(m_section); }
66
67
dw_offset_t die_offset() const { return m_die_offset; }
68
69
bool operator<(DIERef other) const {
70
if (m_file_index_valid != other.m_file_index_valid)
71
return m_file_index_valid < other.m_file_index_valid;
72
if (m_file_index_valid && (m_file_index != other.m_file_index))
73
return m_file_index < other.m_file_index;
74
if (m_section != other.m_section)
75
return m_section < other.m_section;
76
return m_die_offset < other.m_die_offset;
77
}
78
79
bool operator==(const DIERef &rhs) const {
80
return file_index() == rhs.file_index() && m_section == rhs.m_section &&
81
m_die_offset == rhs.m_die_offset;
82
}
83
84
bool operator!=(const DIERef &rhs) const { return !(*this == rhs); }
85
86
/// Decode a serialized version of this object from data.
87
///
88
/// \param data
89
/// The decoder object that references the serialized data.
90
///
91
/// \param offset_ptr
92
/// A pointer that contains the offset from which the data will be decoded
93
/// from that gets updated as data gets decoded.
94
///
95
/// \return
96
/// Returns a valid DIERef if decoding succeeded, std::nullopt if there was
97
/// unsufficient or invalid values that were decoded.
98
static std::optional<DIERef> Decode(const DataExtractor &data,
99
lldb::offset_t *offset_ptr);
100
101
/// Encode this object into a data encoder object.
102
///
103
/// This allows this object to be serialized to disk.
104
///
105
/// \param encoder
106
/// A data encoder object that serialized bytes will be encoded into.
107
///
108
void Encode(DataEncoder &encoder) const;
109
110
static constexpr uint64_t k_die_offset_bit_size = DW_DIE_OFFSET_MAX_BITSIZE;
111
static constexpr uint64_t k_file_index_bit_size =
112
64 - DW_DIE_OFFSET_MAX_BITSIZE - /* size of control bits */ 2;
113
114
static constexpr uint64_t k_file_index_valid_bit =
115
(1ull << (k_file_index_bit_size + k_die_offset_bit_size));
116
static constexpr uint64_t k_section_bit =
117
(1ull << (k_file_index_bit_size + k_die_offset_bit_size + 1));
118
static constexpr uint64_t
119
k_file_index_mask = (~0ull) >> (64 - k_file_index_bit_size); // 0x3fffff;
120
static constexpr uint64_t k_die_offset_mask = (~0ull) >>
121
(64 - k_die_offset_bit_size);
122
123
private:
124
// Allow 2TB of .debug_info/.debug_types offset
125
dw_offset_t m_die_offset : k_die_offset_bit_size;
126
// Used for DWO index or for .o file index on mac
127
dw_offset_t m_file_index : k_file_index_bit_size;
128
// Set to 1 if m_file_index is a DWO number
129
dw_offset_t m_file_index_valid : 1;
130
// Set to 0 for .debug_info 1 for .debug_types,
131
dw_offset_t m_section : 1;
132
};
133
static_assert(sizeof(DIERef) == 8);
134
135
typedef std::vector<DIERef> DIEArray;
136
} // namespace dwarf
137
} // namespace lldb_private::plugin
138
139
namespace llvm {
140
template <> struct format_provider<lldb_private::plugin::dwarf::DIERef> {
141
static void format(const lldb_private::plugin::dwarf::DIERef &ref,
142
raw_ostream &OS, StringRef Style);
143
};
144
} // namespace llvm
145
146
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DIEREF_H
147
148