brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.1 KiB · e519f0b Raw
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