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