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