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