269 lines · cpp
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-exception6//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 21using namespace lldb;22using namespace lldb_private;23 24SBAddress::SBAddress() : m_opaque_up(new Address()) {25 LLDB_INSTRUMENT_VA(this);26}27 28SBAddress::SBAddress(const Address &address)29 : m_opaque_up(std::make_unique<Address>(address)) {}30 31SBAddress::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 37SBAddress::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 target43SBAddress::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 50SBAddress::~SBAddress() = default;51 52const 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 60bool 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 66bool SBAddress::operator!=(const SBAddress &rhs) const {67 LLDB_INSTRUMENT_VA(this, rhs);68 69 return !(*this == rhs);70}71 72bool SBAddress::IsValid() const {73 LLDB_INSTRUMENT_VA(this);74 return this->operator bool();75}76SBAddress::operator bool() const {77 LLDB_INSTRUMENT_VA(this);78 79 return m_opaque_up != nullptr && m_opaque_up->IsValid();80}81 82void SBAddress::Clear() {83 LLDB_INSTRUMENT_VA(this);84 85 m_opaque_up = std::make_unique<Address>();86}87 88void 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 96void SBAddress::SetAddress(const Address &address) { ref() = address; }97 98lldb::addr_t SBAddress::GetFileAddress() const {99 LLDB_INSTRUMENT_VA(this);100 101 if (m_opaque_up->IsValid())102 return m_opaque_up->GetFileAddress();103 else104 return LLDB_INVALID_ADDRESS;105}106 107lldb::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 122void 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 one126 ref();127 if (target.IsValid())128 *this = target.ResolveLoadAddress(load_addr);129 else130 m_opaque_up->Clear();131 132 // Check if we weren't were able to resolve a section offset address. If we133 // weren't it is ok, the load address might be a location on the stack or134 // heap, so we should just have an address with no section and a valid offset135 if (!m_opaque_up->IsValid())136 m_opaque_up->SetOffset(load_addr);137}138 139bool 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 152lldb::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 161lldb::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 169Address *SBAddress::operator->() { return m_opaque_up.get(); }170 171const Address *SBAddress::operator->() const { return m_opaque_up.get(); }172 173Address &SBAddress::ref() {174 if (m_opaque_up == nullptr)175 m_opaque_up = std::make_unique<Address>();176 return *m_opaque_up;177}178 179const Address &SBAddress::ref() const {180 // This object should already have checked with "IsValid()" prior to calling181 // 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 186Address *SBAddress::get() { return m_opaque_up.get(); }187 188bool 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 in192 // 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 } else198 strm.PutCString("No value");199 200 return true;201}202 203SBModule 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 212SBSymbolContext 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 222SBCompileUnit 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 231SBFunction 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 240SBBlock 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 249SBSymbol 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 258SBLineEntry 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