SBAddress.cpp revision 7dd5c51fbab8384b18f20ecc125f9a1bb3c9bcb2
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 107SBAddress::SBAddress (lldb::SBSection section, lldb::addr_t offset) : 108 m_opaque_ap(new AddressImpl (Address(section.GetSection(), offset))) 109{ 110} 111 112// Create an address by resolving a load address using the supplied target 113SBAddress::SBAddress (lldb::addr_t load_addr, lldb::SBTarget &target) : 114 m_opaque_ap() 115{ 116 SetLoadAddress (load_addr, target); 117} 118 119 120 121SBAddress::~SBAddress () 122{ 123} 124 125const SBAddress & 126SBAddress::operator = (const SBAddress &rhs) 127{ 128 if (this != &rhs) 129 { 130 if (rhs.IsValid()) 131 m_opaque_ap.reset(new AddressImpl(*rhs.m_opaque_ap.get())); 132 else 133 m_opaque_ap.reset(); 134 } 135 return *this; 136} 137 138bool 139SBAddress::IsValid () const 140{ 141 return m_opaque_ap.get() != NULL && m_opaque_ap->IsValid(); 142} 143 144void 145SBAddress::Clear () 146{ 147 m_opaque_ap.reset(); 148} 149 150void 151SBAddress::SetAddress (lldb::SBSection section, lldb::addr_t offset) 152{ 153 Address &addr = ref(); 154 addr.SetSection (section.GetSection()); 155 addr.SetOffset (offset); 156} 157 158 159void 160SBAddress::SetAddress (const Address *lldb_object_ptr) 161{ 162 if (lldb_object_ptr) 163 { 164 if (m_opaque_ap.get()) 165 *m_opaque_ap = *lldb_object_ptr; 166 else 167 m_opaque_ap.reset (new AddressImpl(*lldb_object_ptr)); 168 } 169 else 170 m_opaque_ap.reset(); 171} 172 173lldb::addr_t 174SBAddress::GetFileAddress () const 175{ 176 if (m_opaque_ap.get()) 177 return m_opaque_ap->GetAddress().GetFileAddress(); 178 else 179 return LLDB_INVALID_ADDRESS; 180} 181 182lldb::addr_t 183SBAddress::GetLoadAddress (const SBTarget &target) const 184{ 185 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 186 187 lldb::addr_t addr = LLDB_INVALID_ADDRESS; 188 TargetSP target_sp (target.GetSP()); 189 if (m_opaque_ap.get()) 190 { 191 Mutex::Locker api_locker (target_sp->GetAPIMutex()); 192 addr = m_opaque_ap->GetAddress().GetLoadAddress (target_sp.get()); 193 } 194 195 if (log) 196 { 197 if (addr == LLDB_INVALID_ADDRESS) 198 log->Printf ("SBAddress::GetLoadAddress (SBTarget(%p)) => LLDB_INVALID_ADDRESS", target_sp.get()); 199 else 200 log->Printf ("SBAddress::GetLoadAddress (SBTarget(%p)) => 0x%llx", target_sp.get(), addr); 201 } 202 203 return addr; 204} 205 206void 207SBAddress::SetLoadAddress (lldb::addr_t load_addr, lldb::SBTarget &target) 208{ 209 // Create the address object if we don't already have one 210 ref(); 211 if (target.IsValid()) 212 *this = target.ResolveLoadAddress(load_addr); 213 else 214 m_opaque_ap->GetAddress().Clear(); 215 216 // Check if we weren't were able to resolve a section offset address. 217 // If we weren't it is ok, the load address might be a location on the 218 // stack or heap, so we should just have an address with no section and 219 // a valid offset 220 if (!m_opaque_ap->IsValid()) 221 m_opaque_ap->GetAddress().SetOffset(load_addr); 222} 223 224bool 225SBAddress::OffsetAddress (addr_t offset) 226{ 227 if (m_opaque_ap.get()) 228 { 229 addr_t addr_offset = m_opaque_ap->GetAddress().GetOffset(); 230 if (addr_offset != LLDB_INVALID_ADDRESS) 231 { 232 m_opaque_ap->GetAddress().SetOffset(addr_offset + offset); 233 return true; 234 } 235 } 236 return false; 237} 238 239lldb::SBSection 240SBAddress::GetSection () 241{ 242 lldb::SBSection sb_section; 243 if (m_opaque_ap.get()) 244 sb_section.SetSection(m_opaque_ap->GetAddress().GetSection()); 245 return sb_section; 246} 247 248lldb::addr_t 249SBAddress::GetOffset () 250{ 251 if (m_opaque_ap.get()) 252 m_opaque_ap->GetAddress().GetOffset(); 253 return 0; 254} 255 256Address * 257SBAddress::operator->() 258{ 259 if (m_opaque_ap.get()) 260 return &m_opaque_ap->GetAddress(); 261 return NULL; 262} 263 264const Address * 265SBAddress::operator->() const 266{ 267 if (m_opaque_ap.get()) 268 return &m_opaque_ap->GetAddress(); 269 return NULL; 270} 271 272Address & 273SBAddress::ref () 274{ 275 if (m_opaque_ap.get() == NULL) 276 m_opaque_ap.reset (new AddressImpl()); 277 return m_opaque_ap->GetAddress(); 278} 279 280const Address & 281SBAddress::ref () const 282{ 283 // "const SBAddress &addr" should already have checked "addr.IsValid()" 284 // prior to calling this function. In case you didn't we will assert 285 // and die to let you know. 286 assert (m_opaque_ap.get()); 287 return m_opaque_ap->GetAddress(); 288} 289 290Address * 291SBAddress::get () 292{ 293 if (m_opaque_ap.get()) 294 return &m_opaque_ap->GetAddress(); 295 return NULL; 296} 297 298bool 299SBAddress::GetDescription (SBStream &description) 300{ 301 // Call "ref()" on the stream to make sure it creates a backing stream in 302 // case there isn't one already... 303 Stream &strm = description.ref(); 304 if (m_opaque_ap.get()) 305 m_opaque_ap->GetAddress().Dump (&strm, NULL, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleInvalid, 4); 306 else 307 strm.PutCString ("No value"); 308 309 return true; 310} 311 312SBModule 313SBAddress::GetModule () 314{ 315 SBModule sb_module; 316 if (m_opaque_ap.get()) 317 { 318 sb_module.SetSP (m_opaque_ap->GetModuleSP()); 319 } 320 return sb_module; 321} 322 323SBSymbolContext 324SBAddress::GetSymbolContext (uint32_t resolve_scope) 325{ 326 SBSymbolContext sb_sc; 327 if (m_opaque_ap.get()) 328 m_opaque_ap->GetAddress().CalculateSymbolContext (&sb_sc.ref(), resolve_scope); 329 return sb_sc; 330} 331 332SBCompileUnit 333SBAddress::GetCompileUnit () 334{ 335 SBCompileUnit sb_comp_unit; 336 if (m_opaque_ap.get()) 337 sb_comp_unit.reset(m_opaque_ap->GetAddress().CalculateSymbolContextCompileUnit()); 338 return sb_comp_unit; 339} 340 341SBFunction 342SBAddress::GetFunction () 343{ 344 SBFunction sb_function; 345 if (m_opaque_ap.get()) 346 sb_function.reset(m_opaque_ap->GetAddress().CalculateSymbolContextFunction()); 347 return sb_function; 348} 349 350SBBlock 351SBAddress::GetBlock () 352{ 353 SBBlock sb_block; 354 if (m_opaque_ap.get()) 355 sb_block.SetPtr(m_opaque_ap->GetAddress().CalculateSymbolContextBlock()); 356 return sb_block; 357} 358 359SBSymbol 360SBAddress::GetSymbol () 361{ 362 SBSymbol sb_symbol; 363 if (m_opaque_ap.get()) 364 sb_symbol.reset(m_opaque_ap->GetAddress().CalculateSymbolContextSymbol()); 365 return sb_symbol; 366} 367 368SBLineEntry 369SBAddress::GetLineEntry () 370{ 371 SBLineEntry sb_line_entry; 372 if (m_opaque_ap.get()) 373 { 374 LineEntry line_entry; 375 if (m_opaque_ap->GetAddress().CalculateSymbolContextLineEntry (line_entry)) 376 sb_line_entry.SetLineEntry (line_entry); 377 } 378 return sb_line_entry; 379} 380 381 382