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 namespace 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 83 using namespace lldb; 84 using namespace lldb_private; 85 86 87 SBAddress::SBAddress () : 88 m_opaque_ap () 89 { 90 } 91 92 SBAddress::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 99 SBAddress::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 107 SBAddress::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 113 SBAddress::SBAddress (lldb::addr_t load_addr, lldb::SBTarget &target) : 114 m_opaque_ap() 115 { 116 SetLoadAddress (load_addr, target); 117 } 118 119 120 121 SBAddress::~SBAddress () 122 { 123 } 124 125 const SBAddress & 126 SBAddress::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 138 bool 139 SBAddress::IsValid () const 140 { 141 return m_opaque_ap.get() != NULL && m_opaque_ap->IsValid(); 142 } 143 144 void 145 SBAddress::Clear () 146 { 147 m_opaque_ap.reset(); 148 } 149 150 void 151 SBAddress::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 159 void 160 SBAddress::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 173 lldb::addr_t 174 SBAddress::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 182 lldb::addr_t 183 SBAddress::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 206 void 207 SBAddress::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 224 bool 225 SBAddress::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 239 lldb::SBSection 240 SBAddress::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 248 lldb::addr_t 249 SBAddress::GetOffset () 250 { 251 if (m_opaque_ap.get()) 252 m_opaque_ap->GetAddress().GetOffset(); 253 return 0; 254 } 255 256 Address * 257 SBAddress::operator->() 258 { 259 if (m_opaque_ap.get()) 260 return &m_opaque_ap->GetAddress(); 261 return NULL; 262 } 263 264 const Address * 265 SBAddress::operator->() const 266 { 267 if (m_opaque_ap.get()) 268 return &m_opaque_ap->GetAddress(); 269 return NULL; 270 } 271 272 Address & 273 SBAddress::ref () 274 { 275 if (m_opaque_ap.get() == NULL) 276 m_opaque_ap.reset (new AddressImpl()); 277 return m_opaque_ap->GetAddress(); 278 } 279 280 const Address & 281 SBAddress::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 290 Address * 291 SBAddress::get () 292 { 293 if (m_opaque_ap.get()) 294 return &m_opaque_ap->GetAddress(); 295 return NULL; 296 } 297 298 bool 299 SBAddress::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 312 SBModule 313 SBAddress::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 323 SBSymbolContext 324 SBAddress::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 332 SBCompileUnit 333 SBAddress::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 341 SBFunction 342 SBAddress::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 350 SBBlock 351 SBAddress::GetBlock () 352 { 353 SBBlock sb_block; 354 if (m_opaque_ap.get()) 355 sb_block.reset(m_opaque_ap->GetAddress().CalculateSymbolContextBlock()); 356 return sb_block; 357 } 358 359 SBSymbol 360 SBAddress::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 368 SBLineEntry 369 SBAddress::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