1//===-- SBAddress.cpp -------------------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include "lldb/API/SBAddress.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/Log.h" 16#include "lldb/Core/Module.h" 17#include "lldb/Host/Mutex.h" 18#include "lldb/Target/Target.h" 19 20 21using namespace lldb; 22using namespace lldb_private; 23 24 25SBAddress::SBAddress () : 26 m_opaque_ap () 27{ 28} 29 30SBAddress::SBAddress (const Address *lldb_object_ptr) : 31 m_opaque_ap () 32{ 33 if (lldb_object_ptr) 34 ref() = *lldb_object_ptr; 35} 36 37SBAddress::SBAddress (const SBAddress &rhs) : 38 m_opaque_ap () 39{ 40 if (rhs.IsValid()) 41 ref() = rhs.ref(); 42} 43 44 45SBAddress::SBAddress (lldb::SBSection section, lldb::addr_t offset) : 46 m_opaque_ap(new Address (section.GetSP(), offset)) 47{ 48} 49 50// Create an address by resolving a load address using the supplied target 51SBAddress::SBAddress (lldb::addr_t load_addr, lldb::SBTarget &target) : 52 m_opaque_ap() 53{ 54 SetLoadAddress (load_addr, target); 55} 56 57 58 59SBAddress::~SBAddress () 60{ 61} 62 63const SBAddress & 64SBAddress::operator = (const SBAddress &rhs) 65{ 66 if (this != &rhs) 67 { 68 if (rhs.IsValid()) 69 ref() = rhs.ref(); 70 else 71 m_opaque_ap.reset(); 72 } 73 return *this; 74} 75 76bool 77SBAddress::IsValid () const 78{ 79 return m_opaque_ap.get() != NULL && m_opaque_ap->IsValid(); 80} 81 82void 83SBAddress::Clear () 84{ 85 m_opaque_ap.reset(); 86} 87 88void 89SBAddress::SetAddress (lldb::SBSection section, lldb::addr_t offset) 90{ 91 Address &addr = ref(); 92 addr.SetSection (section.GetSP()); 93 addr.SetOffset (offset); 94} 95 96 97void 98SBAddress::SetAddress (const Address *lldb_object_ptr) 99{ 100 if (lldb_object_ptr) 101 ref() = *lldb_object_ptr; 102 else 103 m_opaque_ap.reset(); 104} 105 106lldb::addr_t 107SBAddress::GetFileAddress () const 108{ 109 if (m_opaque_ap.get()) 110 return m_opaque_ap->GetFileAddress(); 111 else 112 return LLDB_INVALID_ADDRESS; 113} 114 115lldb::addr_t 116SBAddress::GetLoadAddress (const SBTarget &target) const 117{ 118 Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 119 120 lldb::addr_t addr = LLDB_INVALID_ADDRESS; 121 TargetSP target_sp (target.GetSP()); 122 if (target_sp) 123 { 124 if (m_opaque_ap.get()) 125 { 126 Mutex::Locker api_locker (target_sp->GetAPIMutex()); 127 addr = m_opaque_ap->GetLoadAddress (target_sp.get()); 128 } 129 } 130 131 if (log) 132 { 133 if (addr == LLDB_INVALID_ADDRESS) 134 log->Printf ("SBAddress::GetLoadAddress (SBTarget(%p)) => LLDB_INVALID_ADDRESS", target_sp.get()); 135 else 136 log->Printf ("SBAddress::GetLoadAddress (SBTarget(%p)) => 0x%" PRIx64, target_sp.get(), addr); 137 } 138 139 return addr; 140} 141 142void 143SBAddress::SetLoadAddress (lldb::addr_t load_addr, lldb::SBTarget &target) 144{ 145 // Create the address object if we don't already have one 146 ref(); 147 if (target.IsValid()) 148 *this = target.ResolveLoadAddress(load_addr); 149 else 150 m_opaque_ap->Clear(); 151 152 // Check if we weren't were able to resolve a section offset address. 153 // If we weren't it is ok, the load address might be a location on the 154 // stack or heap, so we should just have an address with no section and 155 // a valid offset 156 if (!m_opaque_ap->IsValid()) 157 m_opaque_ap->SetOffset(load_addr); 158} 159 160bool 161SBAddress::OffsetAddress (addr_t offset) 162{ 163 if (m_opaque_ap.get()) 164 { 165 addr_t addr_offset = m_opaque_ap->GetOffset(); 166 if (addr_offset != LLDB_INVALID_ADDRESS) 167 { 168 m_opaque_ap->SetOffset(addr_offset + offset); 169 return true; 170 } 171 } 172 return false; 173} 174 175lldb::SBSection 176SBAddress::GetSection () 177{ 178 lldb::SBSection sb_section; 179 if (m_opaque_ap.get()) 180 sb_section.SetSP (m_opaque_ap->GetSection()); 181 return sb_section; 182} 183 184lldb::addr_t 185SBAddress::GetOffset () 186{ 187 if (m_opaque_ap.get()) 188 return m_opaque_ap->GetOffset(); 189 return 0; 190} 191 192Address * 193SBAddress::operator->() 194{ 195 return m_opaque_ap.get(); 196} 197 198const Address * 199SBAddress::operator->() const 200{ 201 return m_opaque_ap.get(); 202} 203 204Address & 205SBAddress::ref () 206{ 207 if (m_opaque_ap.get() == NULL) 208 m_opaque_ap.reset (new Address()); 209 return *m_opaque_ap; 210} 211 212const Address & 213SBAddress::ref () const 214{ 215 // This object should already have checked with "IsValid()" 216 // prior to calling this function. In case you didn't we will assert 217 // and die to let you know. 218 assert (m_opaque_ap.get()); 219 return *m_opaque_ap; 220} 221 222Address * 223SBAddress::get () 224{ 225 return m_opaque_ap.get(); 226} 227 228bool 229SBAddress::GetDescription (SBStream &description) 230{ 231 // Call "ref()" on the stream to make sure it creates a backing stream in 232 // case there isn't one already... 233 Stream &strm = description.ref(); 234 if (m_opaque_ap.get()) 235 { 236 m_opaque_ap->Dump (&strm, 237 NULL, 238 Address::DumpStyleResolvedDescription, 239 Address::DumpStyleModuleWithFileAddress, 240 4); 241 StreamString sstrm; 242// m_opaque_ap->Dump (&sstrm, NULL, Address::DumpStyleResolvedDescription, Address::DumpStyleInvalid, 4); 243// if (sstrm.GetData()) 244// strm.Printf (" (%s)", sstrm.GetData()); 245 } 246 else 247 strm.PutCString ("No value"); 248 249 return true; 250} 251 252SBModule 253SBAddress::GetModule () 254{ 255 SBModule sb_module; 256 if (m_opaque_ap.get()) 257 sb_module.SetSP (m_opaque_ap->GetModule()); 258 return sb_module; 259} 260 261SBSymbolContext 262SBAddress::GetSymbolContext (uint32_t resolve_scope) 263{ 264 SBSymbolContext sb_sc; 265 if (m_opaque_ap.get()) 266 m_opaque_ap->CalculateSymbolContext (&sb_sc.ref(), resolve_scope); 267 return sb_sc; 268} 269 270SBCompileUnit 271SBAddress::GetCompileUnit () 272{ 273 SBCompileUnit sb_comp_unit; 274 if (m_opaque_ap.get()) 275 sb_comp_unit.reset(m_opaque_ap->CalculateSymbolContextCompileUnit()); 276 return sb_comp_unit; 277} 278 279SBFunction 280SBAddress::GetFunction () 281{ 282 SBFunction sb_function; 283 if (m_opaque_ap.get()) 284 sb_function.reset(m_opaque_ap->CalculateSymbolContextFunction()); 285 return sb_function; 286} 287 288SBBlock 289SBAddress::GetBlock () 290{ 291 SBBlock sb_block; 292 if (m_opaque_ap.get()) 293 sb_block.SetPtr(m_opaque_ap->CalculateSymbolContextBlock()); 294 return sb_block; 295} 296 297SBSymbol 298SBAddress::GetSymbol () 299{ 300 SBSymbol sb_symbol; 301 if (m_opaque_ap.get()) 302 sb_symbol.reset(m_opaque_ap->CalculateSymbolContextSymbol()); 303 return sb_symbol; 304} 305 306SBLineEntry 307SBAddress::GetLineEntry () 308{ 309 SBLineEntry sb_line_entry; 310 if (m_opaque_ap.get()) 311 { 312 LineEntry line_entry; 313 if (m_opaque_ap->CalculateSymbolContextLineEntry (line_entry)) 314 sb_line_entry.SetLineEntry (line_entry); 315 } 316 return sb_line_entry; 317} 318 319AddressClass 320SBAddress::GetAddressClass () 321{ 322 if (m_opaque_ap.get()) 323 return m_opaque_ap->GetAddressClass(); 324 return eAddressClassInvalid; 325} 326 327