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