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