180814287SRaphael Isemann //===-- SBAddress.cpp -----------------------------------------------------===//
230fdc8d8SChris Lattner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
630fdc8d8SChris Lattner //
730fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
830fdc8d8SChris Lattner
930fdc8d8SChris Lattner #include "lldb/API/SBAddress.h"
10bd4bf82aSJonas Devlieghere #include "Utils.h"
1130fdc8d8SChris Lattner #include "lldb/API/SBProcess.h"
12cac9c5f9SGreg Clayton #include "lldb/API/SBSection.h"
13dde9cff3SCaroline Tice #include "lldb/API/SBStream.h"
1430fdc8d8SChris Lattner #include "lldb/Core/Address.h"
1505d2b7f7SGreg Clayton #include "lldb/Core/Module.h"
1632abc6edSZachary Turner #include "lldb/Symbol/LineEntry.h"
17af67cecdSGreg Clayton #include "lldb/Target/Target.h"
18*1755f5b1SJonas Devlieghere #include "lldb/Utility/Instrumentation.h"
19bf9a7730SZachary Turner #include "lldb/Utility/StreamString.h"
2030fdc8d8SChris Lattner
2130fdc8d8SChris Lattner using namespace lldb;
22ceb6b139SCaroline Tice using namespace lldb_private;
2330fdc8d8SChris Lattner
SBAddress()24baf5664fSJonas Devlieghere SBAddress::SBAddress() : m_opaque_up(new Address()) {
25*1755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this);
26baf5664fSJonas Devlieghere }
2730fdc8d8SChris Lattner
SBAddress(const Address & address)286cd4a4cdSJonas Devlieghere SBAddress::SBAddress(const Address &address)
296cd4a4cdSJonas Devlieghere : m_opaque_up(std::make_unique<Address>(address)) {}
3030fdc8d8SChris Lattner
SBAddress(const SBAddress & rhs)31d5b44036SJonas Devlieghere SBAddress::SBAddress(const SBAddress &rhs) : m_opaque_up(new Address()) {
32*1755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this, rhs);
33baf5664fSJonas Devlieghere
34bd4bf82aSJonas Devlieghere m_opaque_up = clone(rhs.m_opaque_up);
3530fdc8d8SChris Lattner }
3630fdc8d8SChris Lattner
SBAddress(lldb::SBSection section,lldb::addr_t offset)37b9c1b51eSKate Stone SBAddress::SBAddress(lldb::SBSection section, lldb::addr_t offset)
38baf5664fSJonas Devlieghere : m_opaque_up(new Address(section.GetSP(), offset)) {
39*1755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this, section, offset);
40baf5664fSJonas Devlieghere }
41819134a7SGreg Clayton
4200e6fbfeSGreg Clayton // Create an address by resolving a load address using the supplied target
SBAddress(lldb::addr_t load_addr,lldb::SBTarget & target)43b9c1b51eSKate Stone SBAddress::SBAddress(lldb::addr_t load_addr, lldb::SBTarget &target)
44d5b44036SJonas Devlieghere : m_opaque_up(new Address()) {
45*1755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this, load_addr, target);
46baf5664fSJonas Devlieghere
4700e6fbfeSGreg Clayton SetLoadAddress(load_addr, target);
4800e6fbfeSGreg Clayton }
4900e6fbfeSGreg Clayton
50866b7a65SJonas Devlieghere SBAddress::~SBAddress() = default;
5100e6fbfeSGreg Clayton
operator =(const SBAddress & rhs)52b9c1b51eSKate Stone const SBAddress &SBAddress::operator=(const SBAddress &rhs) {
53*1755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this, rhs);
54baf5664fSJonas Devlieghere
55bd4bf82aSJonas Devlieghere if (this != &rhs)
56bd4bf82aSJonas Devlieghere m_opaque_up = clone(rhs.m_opaque_up);
57d232abc3SJonas Devlieghere return *this;
5830fdc8d8SChris Lattner }
5930fdc8d8SChris Lattner
operator ==(const SBAddress & lhs,const SBAddress & rhs)60dd125943SNitesh Jain bool lldb::operator==(const SBAddress &lhs, const SBAddress &rhs) {
61dd125943SNitesh Jain if (lhs.IsValid() && rhs.IsValid())
62dd125943SNitesh Jain return lhs.ref() == rhs.ref();
63dd125943SNitesh Jain return false;
64dd125943SNitesh Jain }
65dd125943SNitesh Jain
operator !=(const SBAddress & rhs) const664bc05006SPavel Labath bool SBAddress::operator!=(const SBAddress &rhs) const {
67*1755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this, rhs);
684bc05006SPavel Labath
694bc05006SPavel Labath return !(*this == rhs);
704bc05006SPavel Labath }
714bc05006SPavel Labath
IsValid() const72b9c1b51eSKate Stone bool SBAddress::IsValid() const {
73*1755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this);
747f5237bcSPavel Labath return this->operator bool();
757f5237bcSPavel Labath }
operator bool() const767f5237bcSPavel Labath SBAddress::operator bool() const {
77*1755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this);
78baf5664fSJonas Devlieghere
79248a1305SKonrad Kleine return m_opaque_up != nullptr && m_opaque_up->IsValid();
8030fdc8d8SChris Lattner }
8130fdc8d8SChris Lattner
Clear()82baf5664fSJonas Devlieghere void SBAddress::Clear() {
83*1755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this);
84baf5664fSJonas Devlieghere
851c0bbe43SJonas Devlieghere m_opaque_up = std::make_unique<Address>();
86baf5664fSJonas Devlieghere }
8709960031SGreg Clayton
SetAddress(lldb::SBSection section,lldb::addr_t offset)88b9c1b51eSKate Stone void SBAddress::SetAddress(lldb::SBSection section, lldb::addr_t offset) {
89*1755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this, section, offset);
90baf5664fSJonas Devlieghere
91819134a7SGreg Clayton Address &addr = ref();
92e72dfb32SGreg Clayton addr.SetSection(section.GetSP());
93819134a7SGreg Clayton addr.SetOffset(offset);
94819134a7SGreg Clayton }
95819134a7SGreg Clayton
SetAddress(const Address & address)966cd4a4cdSJonas Devlieghere void SBAddress::SetAddress(const Address &address) { ref() = address; }
9730fdc8d8SChris Lattner
GetFileAddress() const98b9c1b51eSKate Stone lldb::addr_t SBAddress::GetFileAddress() const {
99*1755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this);
100baf5664fSJonas Devlieghere
101d5b44036SJonas Devlieghere if (m_opaque_up->IsValid())
102d5b44036SJonas Devlieghere return m_opaque_up->GetFileAddress();
10330fdc8d8SChris Lattner else
10430fdc8d8SChris Lattner return LLDB_INVALID_ADDRESS;
10530fdc8d8SChris Lattner }
10630fdc8d8SChris Lattner
GetLoadAddress(const SBTarget & target) const107b9c1b51eSKate Stone lldb::addr_t SBAddress::GetLoadAddress(const SBTarget &target) const {
108*1755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this, target);
109baf5664fSJonas Devlieghere
110af67cecdSGreg Clayton lldb::addr_t addr = LLDB_INVALID_ADDRESS;
111b9556accSGreg Clayton TargetSP target_sp(target.GetSP());
112b9c1b51eSKate Stone if (target_sp) {
113d5b44036SJonas Devlieghere if (m_opaque_up->IsValid()) {
114bb19a13cSSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
115d5b44036SJonas Devlieghere addr = m_opaque_up->GetLoadAddress(target_sp.get());
116ceb6b139SCaroline Tice }
117e4c1ef55SGreg Clayton }
118af67cecdSGreg Clayton
119af67cecdSGreg Clayton return addr;
120ceb6b139SCaroline Tice }
12130fdc8d8SChris Lattner
SetLoadAddress(lldb::addr_t load_addr,lldb::SBTarget & target)122b9c1b51eSKate Stone void SBAddress::SetLoadAddress(lldb::addr_t load_addr, lldb::SBTarget &target) {
123*1755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this, load_addr, target);
124baf5664fSJonas Devlieghere
12500e6fbfeSGreg Clayton // Create the address object if we don't already have one
12600e6fbfeSGreg Clayton ref();
12700e6fbfeSGreg Clayton if (target.IsValid())
12800e6fbfeSGreg Clayton *this = target.ResolveLoadAddress(load_addr);
12900e6fbfeSGreg Clayton else
130d5b44036SJonas Devlieghere m_opaque_up->Clear();
13100e6fbfeSGreg Clayton
13205097246SAdrian Prantl // Check if we weren't were able to resolve a section offset address. If we
13305097246SAdrian Prantl // weren't it is ok, the load address might be a location on the stack or
13405097246SAdrian Prantl // heap, so we should just have an address with no section and a valid offset
135d5b44036SJonas Devlieghere if (!m_opaque_up->IsValid())
136d5b44036SJonas Devlieghere m_opaque_up->SetOffset(load_addr);
13700e6fbfeSGreg Clayton }
13800e6fbfeSGreg Clayton
OffsetAddress(addr_t offset)139b9c1b51eSKate Stone bool SBAddress::OffsetAddress(addr_t offset) {
140*1755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this, offset);
141baf5664fSJonas Devlieghere
142d5b44036SJonas Devlieghere if (m_opaque_up->IsValid()) {
143d5b44036SJonas Devlieghere addr_t addr_offset = m_opaque_up->GetOffset();
144b9c1b51eSKate Stone if (addr_offset != LLDB_INVALID_ADDRESS) {
145d5b44036SJonas Devlieghere m_opaque_up->SetOffset(addr_offset + offset);
14630fdc8d8SChris Lattner return true;
14730fdc8d8SChris Lattner }
14830fdc8d8SChris Lattner }
14930fdc8d8SChris Lattner return false;
15030fdc8d8SChris Lattner }
15130fdc8d8SChris Lattner
GetSection()152b9c1b51eSKate Stone lldb::SBSection SBAddress::GetSection() {
153*1755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this);
154baf5664fSJonas Devlieghere
155cac9c5f9SGreg Clayton lldb::SBSection sb_section;
156d5b44036SJonas Devlieghere if (m_opaque_up->IsValid())
157d5b44036SJonas Devlieghere sb_section.SetSP(m_opaque_up->GetSection());
158d232abc3SJonas Devlieghere return sb_section;
159cac9c5f9SGreg Clayton }
160cac9c5f9SGreg Clayton
GetOffset()161b9c1b51eSKate Stone lldb::addr_t SBAddress::GetOffset() {
162*1755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this);
163baf5664fSJonas Devlieghere
164d5b44036SJonas Devlieghere if (m_opaque_up->IsValid())
165d5b44036SJonas Devlieghere return m_opaque_up->GetOffset();
16613d1950aSGreg Clayton return 0;
16713d1950aSGreg Clayton }
168cac9c5f9SGreg Clayton
operator ->()169d5b44036SJonas Devlieghere Address *SBAddress::operator->() { return m_opaque_up.get(); }
17030fdc8d8SChris Lattner
operator ->() const171d5b44036SJonas Devlieghere const Address *SBAddress::operator->() const { return m_opaque_up.get(); }
17230fdc8d8SChris Lattner
ref()173b9c1b51eSKate Stone Address &SBAddress::ref() {
174248a1305SKonrad Kleine if (m_opaque_up == nullptr)
1751c0bbe43SJonas Devlieghere m_opaque_up = std::make_unique<Address>();
176d5b44036SJonas Devlieghere return *m_opaque_up;
17709960031SGreg Clayton }
17809960031SGreg Clayton
ref() const179b9c1b51eSKate Stone const Address &SBAddress::ref() const {
18005097246SAdrian Prantl // This object should already have checked with "IsValid()" prior to calling
18105097246SAdrian Prantl // this function. In case you didn't we will assert and die to let you know.
182d5b44036SJonas Devlieghere assert(m_opaque_up.get());
183d5b44036SJonas Devlieghere return *m_opaque_up;
18430fdc8d8SChris Lattner }
18530fdc8d8SChris Lattner
get()186d5b44036SJonas Devlieghere Address *SBAddress::get() { return m_opaque_up.get(); }
18730fdc8d8SChris Lattner
GetDescription(SBStream & description)188b9c1b51eSKate Stone bool SBAddress::GetDescription(SBStream &description) {
189*1755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this, description);
190baf5664fSJonas Devlieghere
191cfd1acedSGreg Clayton // Call "ref()" on the stream to make sure it creates a backing stream in
192cfd1acedSGreg Clayton // case there isn't one already...
193da7bc7d0SGreg Clayton Stream &strm = description.ref();
194d5b44036SJonas Devlieghere if (m_opaque_up->IsValid()) {
195248a1305SKonrad Kleine m_opaque_up->Dump(&strm, nullptr, Address::DumpStyleResolvedDescription,
196b9c1b51eSKate Stone Address::DumpStyleModuleWithFileAddress, 4);
197b9c1b51eSKate Stone } else
198da7bc7d0SGreg Clayton strm.PutCString("No value");
199dde9cff3SCaroline Tice
200dde9cff3SCaroline Tice return true;
201dde9cff3SCaroline Tice }
20205d2b7f7SGreg Clayton
GetModule()203b9c1b51eSKate Stone SBModule SBAddress::GetModule() {
204*1755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this);
205baf5664fSJonas Devlieghere
20605d2b7f7SGreg Clayton SBModule sb_module;
207d5b44036SJonas Devlieghere if (m_opaque_up->IsValid())
208d5b44036SJonas Devlieghere sb_module.SetSP(m_opaque_up->GetModule());
209d232abc3SJonas Devlieghere return sb_module;
21005d2b7f7SGreg Clayton }
21105d2b7f7SGreg Clayton
GetSymbolContext(uint32_t resolve_scope)212b9c1b51eSKate Stone SBSymbolContext SBAddress::GetSymbolContext(uint32_t resolve_scope) {
213*1755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this, resolve_scope);
214baf5664fSJonas Devlieghere
2157e9b1fd0SGreg Clayton SBSymbolContext sb_sc;
216991e4453SZachary Turner SymbolContextItem scope = static_cast<SymbolContextItem>(resolve_scope);
217d5b44036SJonas Devlieghere if (m_opaque_up->IsValid())
218d5b44036SJonas Devlieghere m_opaque_up->CalculateSymbolContext(&sb_sc.ref(), scope);
219d232abc3SJonas Devlieghere return sb_sc;
2207e9b1fd0SGreg Clayton }
2217e9b1fd0SGreg Clayton
GetCompileUnit()222b9c1b51eSKate Stone SBCompileUnit SBAddress::GetCompileUnit() {
223*1755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this);
224baf5664fSJonas Devlieghere
2257e9b1fd0SGreg Clayton SBCompileUnit sb_comp_unit;
226d5b44036SJonas Devlieghere if (m_opaque_up->IsValid())
227d5b44036SJonas Devlieghere sb_comp_unit.reset(m_opaque_up->CalculateSymbolContextCompileUnit());
228d232abc3SJonas Devlieghere return sb_comp_unit;
2297e9b1fd0SGreg Clayton }
2307e9b1fd0SGreg Clayton
GetFunction()231b9c1b51eSKate Stone SBFunction SBAddress::GetFunction() {
232*1755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this);
233baf5664fSJonas Devlieghere
2347e9b1fd0SGreg Clayton SBFunction sb_function;
235d5b44036SJonas Devlieghere if (m_opaque_up->IsValid())
236d5b44036SJonas Devlieghere sb_function.reset(m_opaque_up->CalculateSymbolContextFunction());
237d232abc3SJonas Devlieghere return sb_function;
2387e9b1fd0SGreg Clayton }
2397e9b1fd0SGreg Clayton
GetBlock()240b9c1b51eSKate Stone SBBlock SBAddress::GetBlock() {
241*1755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this);
242baf5664fSJonas Devlieghere
2437e9b1fd0SGreg Clayton SBBlock sb_block;
244d5b44036SJonas Devlieghere if (m_opaque_up->IsValid())
245d5b44036SJonas Devlieghere sb_block.SetPtr(m_opaque_up->CalculateSymbolContextBlock());
246d232abc3SJonas Devlieghere return sb_block;
2477e9b1fd0SGreg Clayton }
2487e9b1fd0SGreg Clayton
GetSymbol()249b9c1b51eSKate Stone SBSymbol SBAddress::GetSymbol() {
250*1755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this);
251baf5664fSJonas Devlieghere
2527e9b1fd0SGreg Clayton SBSymbol sb_symbol;
253d5b44036SJonas Devlieghere if (m_opaque_up->IsValid())
254d5b44036SJonas Devlieghere sb_symbol.reset(m_opaque_up->CalculateSymbolContextSymbol());
255d232abc3SJonas Devlieghere return sb_symbol;
2567e9b1fd0SGreg Clayton }
2577e9b1fd0SGreg Clayton
GetLineEntry()258b9c1b51eSKate Stone SBLineEntry SBAddress::GetLineEntry() {
259*1755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this);
260baf5664fSJonas Devlieghere
2617e9b1fd0SGreg Clayton SBLineEntry sb_line_entry;
262d5b44036SJonas Devlieghere if (m_opaque_up->IsValid()) {
2637e9b1fd0SGreg Clayton LineEntry line_entry;
264d5b44036SJonas Devlieghere if (m_opaque_up->CalculateSymbolContextLineEntry(line_entry))
2657e9b1fd0SGreg Clayton sb_line_entry.SetLineEntry(line_entry);
2667e9b1fd0SGreg Clayton }
267d232abc3SJonas Devlieghere return sb_line_entry;
2687e9b1fd0SGreg Clayton }
269