1 //===-- SBAddress.cpp -------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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"
24 using namespace lldb_private;
27 SBAddress::SBAddress () :
28 m_opaque_ap (new Address())
32 SBAddress::SBAddress (const Address *lldb_object_ptr) :
33 m_opaque_ap (new Address())
36 ref() = *lldb_object_ptr;
39 SBAddress::SBAddress (const SBAddress &rhs) :
40 m_opaque_ap (new Address())
47 SBAddress::SBAddress (lldb::SBSection section, lldb::addr_t offset) :
48 m_opaque_ap(new Address (section.GetSP(), offset))
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())
56 SetLoadAddress (load_addr, target);
61 SBAddress::~SBAddress ()
66 SBAddress::operator = (const SBAddress &rhs)
73 m_opaque_ap.reset (new Address());
79 SBAddress::IsValid () const
81 return m_opaque_ap.get() != NULL && m_opaque_ap->IsValid();
87 m_opaque_ap.reset (new Address());
91 SBAddress::SetAddress (lldb::SBSection section, lldb::addr_t offset)
93 Address &addr = ref();
94 addr.SetSection (section.GetSP());
95 addr.SetOffset (offset);
100 SBAddress::SetAddress (const Address *lldb_object_ptr)
103 ref() = *lldb_object_ptr;
105 m_opaque_ap.reset (new Address());
109 SBAddress::GetFileAddress () const
111 if (m_opaque_ap->IsValid())
112 return m_opaque_ap->GetFileAddress();
114 return LLDB_INVALID_ADDRESS;
118 SBAddress::GetLoadAddress (const SBTarget &target) const
120 Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
122 lldb::addr_t addr = LLDB_INVALID_ADDRESS;
123 TargetSP target_sp (target.GetSP());
126 if (m_opaque_ap->IsValid())
128 Mutex::Locker api_locker (target_sp->GetAPIMutex());
129 addr = m_opaque_ap->GetLoadAddress (target_sp.get());
135 if (addr == LLDB_INVALID_ADDRESS)
136 log->Printf ("SBAddress::GetLoadAddress (SBTarget(%p)) => LLDB_INVALID_ADDRESS",
137 static_cast<void*>(target_sp.get()));
139 log->Printf ("SBAddress::GetLoadAddress (SBTarget(%p)) => 0x%" PRIx64,
140 static_cast<void*>(target_sp.get()), addr);
147 SBAddress::SetLoadAddress (lldb::addr_t load_addr, lldb::SBTarget &target)
149 // Create the address object if we don't already have one
151 if (target.IsValid())
152 *this = target.ResolveLoadAddress(load_addr);
154 m_opaque_ap->Clear();
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
160 if (!m_opaque_ap->IsValid())
161 m_opaque_ap->SetOffset(load_addr);
165 SBAddress::OffsetAddress (addr_t offset)
167 if (m_opaque_ap->IsValid())
169 addr_t addr_offset = m_opaque_ap->GetOffset();
170 if (addr_offset != LLDB_INVALID_ADDRESS)
172 m_opaque_ap->SetOffset(addr_offset + offset);
180 SBAddress::GetSection ()
182 lldb::SBSection sb_section;
183 if (m_opaque_ap->IsValid())
184 sb_section.SetSP (m_opaque_ap->GetSection());
189 SBAddress::GetOffset ()
191 if (m_opaque_ap->IsValid())
192 return m_opaque_ap->GetOffset();
197 SBAddress::operator->()
199 return m_opaque_ap.get();
203 SBAddress::operator->() const
205 return m_opaque_ap.get();
211 if (m_opaque_ap.get() == NULL)
212 m_opaque_ap.reset (new Address());
217 SBAddress::ref () const
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());
229 return m_opaque_ap.get();
233 SBAddress::GetDescription (SBStream &description)
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())
240 m_opaque_ap->Dump (&strm,
242 Address::DumpStyleResolvedDescription,
243 Address::DumpStyleModuleWithFileAddress,
246 // m_opaque_ap->Dump (&sstrm, NULL, Address::DumpStyleResolvedDescription, Address::DumpStyleInvalid, 4);
247 // if (sstrm.GetData())
248 // strm.Printf (" (%s)", sstrm.GetData());
251 strm.PutCString ("No value");
257 SBAddress::GetModule ()
260 if (m_opaque_ap->IsValid())
261 sb_module.SetSP (m_opaque_ap->GetModule());
266 SBAddress::GetSymbolContext (uint32_t resolve_scope)
268 SBSymbolContext sb_sc;
269 if (m_opaque_ap->IsValid())
270 m_opaque_ap->CalculateSymbolContext (&sb_sc.ref(), resolve_scope);
275 SBAddress::GetCompileUnit ()
277 SBCompileUnit sb_comp_unit;
278 if (m_opaque_ap->IsValid())
279 sb_comp_unit.reset(m_opaque_ap->CalculateSymbolContextCompileUnit());
284 SBAddress::GetFunction ()
286 SBFunction sb_function;
287 if (m_opaque_ap->IsValid())
288 sb_function.reset(m_opaque_ap->CalculateSymbolContextFunction());
293 SBAddress::GetBlock ()
296 if (m_opaque_ap->IsValid())
297 sb_block.SetPtr(m_opaque_ap->CalculateSymbolContextBlock());
302 SBAddress::GetSymbol ()
305 if (m_opaque_ap->IsValid())
306 sb_symbol.reset(m_opaque_ap->CalculateSymbolContextSymbol());
311 SBAddress::GetLineEntry ()
313 SBLineEntry sb_line_entry;
314 if (m_opaque_ap->IsValid())
316 LineEntry line_entry;
317 if (m_opaque_ap->CalculateSymbolContextLineEntry (line_entry))
318 sb_line_entry.SetLineEntry (line_entry);
320 return sb_line_entry;
324 SBAddress::GetAddressClass ()
326 if (m_opaque_ap->IsValid())
327 return m_opaque_ap->GetAddressClass();
328 return eAddressClassInvalid;