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