1 //===-- SBAddress.cpp -------------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #include "lldb/API/SBAddress.h"
10 #include "SBReproducerPrivate.h"
12 #include "lldb/API/SBProcess.h"
13 #include "lldb/API/SBSection.h"
14 #include "lldb/API/SBStream.h"
15 #include "lldb/Core/Address.h"
16 #include "lldb/Core/Module.h"
17 #include "lldb/Symbol/LineEntry.h"
18 #include "lldb/Target/Target.h"
19 #include "lldb/Utility/StreamString.h"
22 using namespace lldb_private
;
24 SBAddress::SBAddress() : m_opaque_up(new Address()) {
25 LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBAddress
);
28 SBAddress::SBAddress(const Address
*lldb_object_ptr
)
29 : m_opaque_up(new Address()) {
31 m_opaque_up
= std::make_unique
<Address
>(*lldb_object_ptr
);
34 SBAddress::SBAddress(const SBAddress
&rhs
) : m_opaque_up(new Address()) {
35 LLDB_RECORD_CONSTRUCTOR(SBAddress
, (const lldb::SBAddress
&), rhs
);
37 m_opaque_up
= clone(rhs
.m_opaque_up
);
40 SBAddress::SBAddress(lldb::SBSection section
, lldb::addr_t offset
)
41 : m_opaque_up(new Address(section
.GetSP(), offset
)) {
42 LLDB_RECORD_CONSTRUCTOR(SBAddress
, (lldb::SBSection
, lldb::addr_t
), section
,
46 // Create an address by resolving a load address using the supplied target
47 SBAddress::SBAddress(lldb::addr_t load_addr
, lldb::SBTarget
&target
)
48 : m_opaque_up(new Address()) {
49 LLDB_RECORD_CONSTRUCTOR(SBAddress
, (lldb::addr_t
, lldb::SBTarget
&),
52 SetLoadAddress(load_addr
, target
);
55 SBAddress::~SBAddress() {}
57 const SBAddress
&SBAddress::operator=(const SBAddress
&rhs
) {
58 LLDB_RECORD_METHOD(const lldb::SBAddress
&,
59 SBAddress
, operator=,(const lldb::SBAddress
&), rhs
);
62 m_opaque_up
= clone(rhs
.m_opaque_up
);
63 return LLDB_RECORD_RESULT(*this);
66 bool lldb::operator==(const SBAddress
&lhs
, const SBAddress
&rhs
) {
67 if (lhs
.IsValid() && rhs
.IsValid())
68 return lhs
.ref() == rhs
.ref();
72 bool SBAddress::operator!=(const SBAddress
&rhs
) const {
73 LLDB_RECORD_METHOD_CONST(bool, SBAddress
, operator!=,(const SBAddress
&),
76 return !(*this == rhs
);
79 bool SBAddress::IsValid() const {
80 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBAddress
, IsValid
);
81 return this->operator bool();
83 SBAddress::operator bool() const {
84 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBAddress
, operator bool);
86 return m_opaque_up
!= nullptr && m_opaque_up
->IsValid();
89 void SBAddress::Clear() {
90 LLDB_RECORD_METHOD_NO_ARGS(void, SBAddress
, Clear
);
92 m_opaque_up
.reset(new Address());
95 void SBAddress::SetAddress(lldb::SBSection section
, lldb::addr_t offset
) {
96 LLDB_RECORD_METHOD(void, SBAddress
, SetAddress
,
97 (lldb::SBSection
, lldb::addr_t
), section
, offset
);
99 Address
&addr
= ref();
100 addr
.SetSection(section
.GetSP());
101 addr
.SetOffset(offset
);
104 void SBAddress::SetAddress(const Address
*lldb_object_ptr
) {
106 ref() = *lldb_object_ptr
;
108 m_opaque_up
.reset(new Address());
111 lldb::addr_t
SBAddress::GetFileAddress() const {
112 LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::addr_t
, SBAddress
, GetFileAddress
);
114 if (m_opaque_up
->IsValid())
115 return m_opaque_up
->GetFileAddress();
117 return LLDB_INVALID_ADDRESS
;
120 lldb::addr_t
SBAddress::GetLoadAddress(const SBTarget
&target
) const {
121 LLDB_RECORD_METHOD_CONST(lldb::addr_t
, SBAddress
, GetLoadAddress
,
122 (const lldb::SBTarget
&), target
);
124 lldb::addr_t addr
= LLDB_INVALID_ADDRESS
;
125 TargetSP
target_sp(target
.GetSP());
127 if (m_opaque_up
->IsValid()) {
128 std::lock_guard
<std::recursive_mutex
> guard(target_sp
->GetAPIMutex());
129 addr
= m_opaque_up
->GetLoadAddress(target_sp
.get());
136 void SBAddress::SetLoadAddress(lldb::addr_t load_addr
, lldb::SBTarget
&target
) {
137 LLDB_RECORD_METHOD(void, SBAddress
, SetLoadAddress
,
138 (lldb::addr_t
, lldb::SBTarget
&), load_addr
, target
);
140 // Create the address object if we don't already have one
142 if (target
.IsValid())
143 *this = target
.ResolveLoadAddress(load_addr
);
145 m_opaque_up
->Clear();
147 // Check if we weren't were able to resolve a section offset address. If we
148 // weren't it is ok, the load address might be a location on the stack or
149 // heap, so we should just have an address with no section and a valid offset
150 if (!m_opaque_up
->IsValid())
151 m_opaque_up
->SetOffset(load_addr
);
154 bool SBAddress::OffsetAddress(addr_t offset
) {
155 LLDB_RECORD_METHOD(bool, SBAddress
, OffsetAddress
, (lldb::addr_t
), offset
);
157 if (m_opaque_up
->IsValid()) {
158 addr_t addr_offset
= m_opaque_up
->GetOffset();
159 if (addr_offset
!= LLDB_INVALID_ADDRESS
) {
160 m_opaque_up
->SetOffset(addr_offset
+ offset
);
167 lldb::SBSection
SBAddress::GetSection() {
168 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBSection
, SBAddress
, GetSection
);
170 lldb::SBSection sb_section
;
171 if (m_opaque_up
->IsValid())
172 sb_section
.SetSP(m_opaque_up
->GetSection());
173 return LLDB_RECORD_RESULT(sb_section
);
176 lldb::addr_t
SBAddress::GetOffset() {
177 LLDB_RECORD_METHOD_NO_ARGS(lldb::addr_t
, SBAddress
, GetOffset
);
179 if (m_opaque_up
->IsValid())
180 return m_opaque_up
->GetOffset();
184 Address
*SBAddress::operator->() { return m_opaque_up
.get(); }
186 const Address
*SBAddress::operator->() const { return m_opaque_up
.get(); }
188 Address
&SBAddress::ref() {
189 if (m_opaque_up
== nullptr)
190 m_opaque_up
.reset(new Address());
194 const Address
&SBAddress::ref() const {
195 // This object should already have checked with "IsValid()" prior to calling
196 // this function. In case you didn't we will assert and die to let you know.
197 assert(m_opaque_up
.get());
201 Address
*SBAddress::get() { return m_opaque_up
.get(); }
203 bool SBAddress::GetDescription(SBStream
&description
) {
204 LLDB_RECORD_METHOD(bool, SBAddress
, GetDescription
, (lldb::SBStream
&),
207 // Call "ref()" on the stream to make sure it creates a backing stream in
208 // case there isn't one already...
209 Stream
&strm
= description
.ref();
210 if (m_opaque_up
->IsValid()) {
211 m_opaque_up
->Dump(&strm
, nullptr, Address::DumpStyleResolvedDescription
,
212 Address::DumpStyleModuleWithFileAddress
, 4);
214 strm
.PutCString("No value");
219 SBModule
SBAddress::GetModule() {
220 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBModule
, SBAddress
, GetModule
);
223 if (m_opaque_up
->IsValid())
224 sb_module
.SetSP(m_opaque_up
->GetModule());
225 return LLDB_RECORD_RESULT(sb_module
);
228 SBSymbolContext
SBAddress::GetSymbolContext(uint32_t resolve_scope
) {
229 LLDB_RECORD_METHOD(lldb::SBSymbolContext
, SBAddress
, GetSymbolContext
,
230 (uint32_t), resolve_scope
);
232 SBSymbolContext sb_sc
;
233 SymbolContextItem scope
= static_cast<SymbolContextItem
>(resolve_scope
);
234 if (m_opaque_up
->IsValid())
235 m_opaque_up
->CalculateSymbolContext(&sb_sc
.ref(), scope
);
236 return LLDB_RECORD_RESULT(sb_sc
);
239 SBCompileUnit
SBAddress::GetCompileUnit() {
240 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBCompileUnit
, SBAddress
, GetCompileUnit
);
242 SBCompileUnit sb_comp_unit
;
243 if (m_opaque_up
->IsValid())
244 sb_comp_unit
.reset(m_opaque_up
->CalculateSymbolContextCompileUnit());
245 return LLDB_RECORD_RESULT(sb_comp_unit
);
248 SBFunction
SBAddress::GetFunction() {
249 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBFunction
, SBAddress
, GetFunction
);
251 SBFunction sb_function
;
252 if (m_opaque_up
->IsValid())
253 sb_function
.reset(m_opaque_up
->CalculateSymbolContextFunction());
254 return LLDB_RECORD_RESULT(sb_function
);
257 SBBlock
SBAddress::GetBlock() {
258 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBBlock
, SBAddress
, GetBlock
);
261 if (m_opaque_up
->IsValid())
262 sb_block
.SetPtr(m_opaque_up
->CalculateSymbolContextBlock());
263 return LLDB_RECORD_RESULT(sb_block
);
266 SBSymbol
SBAddress::GetSymbol() {
267 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBSymbol
, SBAddress
, GetSymbol
);
270 if (m_opaque_up
->IsValid())
271 sb_symbol
.reset(m_opaque_up
->CalculateSymbolContextSymbol());
272 return LLDB_RECORD_RESULT(sb_symbol
);
275 SBLineEntry
SBAddress::GetLineEntry() {
276 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBLineEntry
, SBAddress
, GetLineEntry
);
278 SBLineEntry sb_line_entry
;
279 if (m_opaque_up
->IsValid()) {
280 LineEntry line_entry
;
281 if (m_opaque_up
->CalculateSymbolContextLineEntry(line_entry
))
282 sb_line_entry
.SetLineEntry(line_entry
);
284 return LLDB_RECORD_RESULT(sb_line_entry
);
287 namespace lldb_private
{
291 void RegisterMethods
<SBAddress
>(Registry
&R
) {
292 LLDB_REGISTER_CONSTRUCTOR(SBAddress
, ());
293 LLDB_REGISTER_CONSTRUCTOR(SBAddress
, (const lldb::SBAddress
&));
294 LLDB_REGISTER_CONSTRUCTOR(SBAddress
, (lldb::SBSection
, lldb::addr_t
));
295 LLDB_REGISTER_CONSTRUCTOR(SBAddress
, (lldb::addr_t
, lldb::SBTarget
&));
296 LLDB_REGISTER_METHOD(const lldb::SBAddress
&,
297 SBAddress
, operator=,(const lldb::SBAddress
&));
298 LLDB_REGISTER_METHOD_CONST(bool,
299 SBAddress
, operator!=,(const lldb::SBAddress
&));
300 LLDB_REGISTER_METHOD_CONST(bool, SBAddress
, IsValid
, ());
301 LLDB_REGISTER_METHOD_CONST(bool, SBAddress
, operator bool, ());
302 LLDB_REGISTER_METHOD(void, SBAddress
, Clear
, ());
303 LLDB_REGISTER_METHOD(void, SBAddress
, SetAddress
,
304 (lldb::SBSection
, lldb::addr_t
));
305 LLDB_REGISTER_METHOD_CONST(lldb::addr_t
, SBAddress
, GetFileAddress
, ());
306 LLDB_REGISTER_METHOD_CONST(lldb::addr_t
, SBAddress
, GetLoadAddress
,
307 (const lldb::SBTarget
&));
308 LLDB_REGISTER_METHOD(void, SBAddress
, SetLoadAddress
,
309 (lldb::addr_t
, lldb::SBTarget
&));
310 LLDB_REGISTER_METHOD(bool, SBAddress
, OffsetAddress
, (lldb::addr_t
));
311 LLDB_REGISTER_METHOD(lldb::SBSection
, SBAddress
, GetSection
, ());
312 LLDB_REGISTER_METHOD(lldb::addr_t
, SBAddress
, GetOffset
, ());
313 LLDB_REGISTER_METHOD(bool, SBAddress
, GetDescription
, (lldb::SBStream
&));
314 LLDB_REGISTER_METHOD(lldb::SBModule
, SBAddress
, GetModule
, ());
315 LLDB_REGISTER_METHOD(lldb::SBSymbolContext
, SBAddress
, GetSymbolContext
,
317 LLDB_REGISTER_METHOD(lldb::SBCompileUnit
, SBAddress
, GetCompileUnit
, ());
318 LLDB_REGISTER_METHOD(lldb::SBFunction
, SBAddress
, GetFunction
, ());
319 LLDB_REGISTER_METHOD(lldb::SBBlock
, SBAddress
, GetBlock
, ());
320 LLDB_REGISTER_METHOD(lldb::SBSymbol
, SBAddress
, GetSymbol
, ());
321 LLDB_REGISTER_METHOD(lldb::SBLineEntry
, SBAddress
, GetLineEntry
, ());