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