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