Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/API/SBAddress.cpp
39587 views
1
//===-- SBAddress.cpp -----------------------------------------------------===//
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
#include "lldb/API/SBAddress.h"
10
#include "Utils.h"
11
#include "lldb/API/SBProcess.h"
12
#include "lldb/API/SBSection.h"
13
#include "lldb/API/SBStream.h"
14
#include "lldb/Core/Address.h"
15
#include "lldb/Core/Module.h"
16
#include "lldb/Symbol/LineEntry.h"
17
#include "lldb/Target/Target.h"
18
#include "lldb/Utility/Instrumentation.h"
19
#include "lldb/Utility/StreamString.h"
20
21
using namespace lldb;
22
using namespace lldb_private;
23
24
SBAddress::SBAddress() : m_opaque_up(new Address()) {
25
LLDB_INSTRUMENT_VA(this);
26
}
27
28
SBAddress::SBAddress(const Address &address)
29
: m_opaque_up(std::make_unique<Address>(address)) {}
30
31
SBAddress::SBAddress(const SBAddress &rhs) : m_opaque_up(new Address()) {
32
LLDB_INSTRUMENT_VA(this, rhs);
33
34
m_opaque_up = clone(rhs.m_opaque_up);
35
}
36
37
SBAddress::SBAddress(lldb::SBSection section, lldb::addr_t offset)
38
: m_opaque_up(new Address(section.GetSP(), offset)) {
39
LLDB_INSTRUMENT_VA(this, section, offset);
40
}
41
42
// Create an address by resolving a load address using the supplied target
43
SBAddress::SBAddress(lldb::addr_t load_addr, lldb::SBTarget &target)
44
: m_opaque_up(new Address()) {
45
LLDB_INSTRUMENT_VA(this, load_addr, target);
46
47
SetLoadAddress(load_addr, target);
48
}
49
50
SBAddress::~SBAddress() = default;
51
52
const SBAddress &SBAddress::operator=(const SBAddress &rhs) {
53
LLDB_INSTRUMENT_VA(this, rhs);
54
55
if (this != &rhs)
56
m_opaque_up = clone(rhs.m_opaque_up);
57
return *this;
58
}
59
60
bool lldb::operator==(const SBAddress &lhs, const SBAddress &rhs) {
61
if (lhs.IsValid() && rhs.IsValid())
62
return lhs.ref() == rhs.ref();
63
return false;
64
}
65
66
bool SBAddress::operator!=(const SBAddress &rhs) const {
67
LLDB_INSTRUMENT_VA(this, rhs);
68
69
return !(*this == rhs);
70
}
71
72
bool SBAddress::IsValid() const {
73
LLDB_INSTRUMENT_VA(this);
74
return this->operator bool();
75
}
76
SBAddress::operator bool() const {
77
LLDB_INSTRUMENT_VA(this);
78
79
return m_opaque_up != nullptr && m_opaque_up->IsValid();
80
}
81
82
void SBAddress::Clear() {
83
LLDB_INSTRUMENT_VA(this);
84
85
m_opaque_up = std::make_unique<Address>();
86
}
87
88
void SBAddress::SetAddress(lldb::SBSection section, lldb::addr_t offset) {
89
LLDB_INSTRUMENT_VA(this, section, offset);
90
91
Address &addr = ref();
92
addr.SetSection(section.GetSP());
93
addr.SetOffset(offset);
94
}
95
96
void SBAddress::SetAddress(const Address &address) { ref() = address; }
97
98
lldb::addr_t SBAddress::GetFileAddress() const {
99
LLDB_INSTRUMENT_VA(this);
100
101
if (m_opaque_up->IsValid())
102
return m_opaque_up->GetFileAddress();
103
else
104
return LLDB_INVALID_ADDRESS;
105
}
106
107
lldb::addr_t SBAddress::GetLoadAddress(const SBTarget &target) const {
108
LLDB_INSTRUMENT_VA(this, target);
109
110
lldb::addr_t addr = LLDB_INVALID_ADDRESS;
111
TargetSP target_sp(target.GetSP());
112
if (target_sp) {
113
if (m_opaque_up->IsValid()) {
114
std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
115
addr = m_opaque_up->GetLoadAddress(target_sp.get());
116
}
117
}
118
119
return addr;
120
}
121
122
void SBAddress::SetLoadAddress(lldb::addr_t load_addr, lldb::SBTarget &target) {
123
LLDB_INSTRUMENT_VA(this, load_addr, target);
124
125
// Create the address object if we don't already have one
126
ref();
127
if (target.IsValid())
128
*this = target.ResolveLoadAddress(load_addr);
129
else
130
m_opaque_up->Clear();
131
132
// Check if we weren't were able to resolve a section offset address. If we
133
// weren't it is ok, the load address might be a location on the stack or
134
// heap, so we should just have an address with no section and a valid offset
135
if (!m_opaque_up->IsValid())
136
m_opaque_up->SetOffset(load_addr);
137
}
138
139
bool SBAddress::OffsetAddress(addr_t offset) {
140
LLDB_INSTRUMENT_VA(this, offset);
141
142
if (m_opaque_up->IsValid()) {
143
addr_t addr_offset = m_opaque_up->GetOffset();
144
if (addr_offset != LLDB_INVALID_ADDRESS) {
145
m_opaque_up->SetOffset(addr_offset + offset);
146
return true;
147
}
148
}
149
return false;
150
}
151
152
lldb::SBSection SBAddress::GetSection() {
153
LLDB_INSTRUMENT_VA(this);
154
155
lldb::SBSection sb_section;
156
if (m_opaque_up->IsValid())
157
sb_section.SetSP(m_opaque_up->GetSection());
158
return sb_section;
159
}
160
161
lldb::addr_t SBAddress::GetOffset() {
162
LLDB_INSTRUMENT_VA(this);
163
164
if (m_opaque_up->IsValid())
165
return m_opaque_up->GetOffset();
166
return 0;
167
}
168
169
Address *SBAddress::operator->() { return m_opaque_up.get(); }
170
171
const Address *SBAddress::operator->() const { return m_opaque_up.get(); }
172
173
Address &SBAddress::ref() {
174
if (m_opaque_up == nullptr)
175
m_opaque_up = std::make_unique<Address>();
176
return *m_opaque_up;
177
}
178
179
const Address &SBAddress::ref() const {
180
// This object should already have checked with "IsValid()" prior to calling
181
// this function. In case you didn't we will assert and die to let you know.
182
assert(m_opaque_up.get());
183
return *m_opaque_up;
184
}
185
186
Address *SBAddress::get() { return m_opaque_up.get(); }
187
188
bool SBAddress::GetDescription(SBStream &description) {
189
LLDB_INSTRUMENT_VA(this, description);
190
191
// Call "ref()" on the stream to make sure it creates a backing stream in
192
// case there isn't one already...
193
Stream &strm = description.ref();
194
if (m_opaque_up->IsValid()) {
195
m_opaque_up->Dump(&strm, nullptr, Address::DumpStyleResolvedDescription,
196
Address::DumpStyleModuleWithFileAddress, 4);
197
} else
198
strm.PutCString("No value");
199
200
return true;
201
}
202
203
SBModule SBAddress::GetModule() {
204
LLDB_INSTRUMENT_VA(this);
205
206
SBModule sb_module;
207
if (m_opaque_up->IsValid())
208
sb_module.SetSP(m_opaque_up->GetModule());
209
return sb_module;
210
}
211
212
SBSymbolContext SBAddress::GetSymbolContext(uint32_t resolve_scope) {
213
LLDB_INSTRUMENT_VA(this, resolve_scope);
214
215
SBSymbolContext sb_sc;
216
SymbolContextItem scope = static_cast<SymbolContextItem>(resolve_scope);
217
if (m_opaque_up->IsValid())
218
m_opaque_up->CalculateSymbolContext(&sb_sc.ref(), scope);
219
return sb_sc;
220
}
221
222
SBCompileUnit SBAddress::GetCompileUnit() {
223
LLDB_INSTRUMENT_VA(this);
224
225
SBCompileUnit sb_comp_unit;
226
if (m_opaque_up->IsValid())
227
sb_comp_unit.reset(m_opaque_up->CalculateSymbolContextCompileUnit());
228
return sb_comp_unit;
229
}
230
231
SBFunction SBAddress::GetFunction() {
232
LLDB_INSTRUMENT_VA(this);
233
234
SBFunction sb_function;
235
if (m_opaque_up->IsValid())
236
sb_function.reset(m_opaque_up->CalculateSymbolContextFunction());
237
return sb_function;
238
}
239
240
SBBlock SBAddress::GetBlock() {
241
LLDB_INSTRUMENT_VA(this);
242
243
SBBlock sb_block;
244
if (m_opaque_up->IsValid())
245
sb_block.SetPtr(m_opaque_up->CalculateSymbolContextBlock());
246
return sb_block;
247
}
248
249
SBSymbol SBAddress::GetSymbol() {
250
LLDB_INSTRUMENT_VA(this);
251
252
SBSymbol sb_symbol;
253
if (m_opaque_up->IsValid())
254
sb_symbol.reset(m_opaque_up->CalculateSymbolContextSymbol());
255
return sb_symbol;
256
}
257
258
SBLineEntry SBAddress::GetLineEntry() {
259
LLDB_INSTRUMENT_VA(this);
260
261
SBLineEntry sb_line_entry;
262
if (m_opaque_up->IsValid()) {
263
LineEntry line_entry;
264
if (m_opaque_up->CalculateSymbolContextLineEntry(line_entry))
265
sb_line_entry.SetLineEntry(line_entry);
266
}
267
return sb_line_entry;
268
}
269
270