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