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/Symbol/LineEntry.h"
19 #include "lldb/Target/Target.h"
23 using namespace lldb_private;
26 SBAddress::SBAddress () :
27 m_opaque_ap (new Address())
31 SBAddress::SBAddress (const Address *lldb_object_ptr) :
32 m_opaque_ap (new Address())
35 ref() = *lldb_object_ptr;
38 SBAddress::SBAddress (const SBAddress &rhs) :
39 m_opaque_ap (new Address())
46 SBAddress::SBAddress (lldb::SBSection section, lldb::addr_t offset) :
47 m_opaque_ap(new Address (section.GetSP(), offset))
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())
55 SetLoadAddress (load_addr, target);
60 SBAddress::~SBAddress ()
65 SBAddress::operator = (const SBAddress &rhs)
72 m_opaque_ap.reset (new Address());
78 SBAddress::IsValid () const
80 return m_opaque_ap.get() != NULL && m_opaque_ap->IsValid();
86 m_opaque_ap.reset (new Address());
90 SBAddress::SetAddress (lldb::SBSection section, lldb::addr_t offset)
92 Address &addr = ref();
93 addr.SetSection (section.GetSP());
94 addr.SetOffset (offset);
99 SBAddress::SetAddress (const Address *lldb_object_ptr)
102 ref() = *lldb_object_ptr;
104 m_opaque_ap.reset (new Address());
108 SBAddress::GetFileAddress () const
110 if (m_opaque_ap->IsValid())
111 return m_opaque_ap->GetFileAddress();
113 return LLDB_INVALID_ADDRESS;
117 SBAddress::GetLoadAddress (const SBTarget &target) const
119 Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
121 lldb::addr_t addr = LLDB_INVALID_ADDRESS;
122 TargetSP target_sp (target.GetSP());
125 if (m_opaque_ap->IsValid())
127 std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
128 addr = m_opaque_ap->GetLoadAddress (target_sp.get());
134 if (addr == LLDB_INVALID_ADDRESS)
135 log->Printf ("SBAddress::GetLoadAddress (SBTarget(%p)) => LLDB_INVALID_ADDRESS",
136 static_cast<void*>(target_sp.get()));
138 log->Printf ("SBAddress::GetLoadAddress (SBTarget(%p)) => 0x%" PRIx64,
139 static_cast<void*>(target_sp.get()), addr);
146 SBAddress::SetLoadAddress (lldb::addr_t load_addr, lldb::SBTarget &target)
148 // Create the address object if we don't already have one
150 if (target.IsValid())
151 *this = target.ResolveLoadAddress(load_addr);
153 m_opaque_ap->Clear();
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
159 if (!m_opaque_ap->IsValid())
160 m_opaque_ap->SetOffset(load_addr);
164 SBAddress::OffsetAddress (addr_t offset)
166 if (m_opaque_ap->IsValid())
168 addr_t addr_offset = m_opaque_ap->GetOffset();
169 if (addr_offset != LLDB_INVALID_ADDRESS)
171 m_opaque_ap->SetOffset(addr_offset + offset);
179 SBAddress::GetSection ()
181 lldb::SBSection sb_section;
182 if (m_opaque_ap->IsValid())
183 sb_section.SetSP (m_opaque_ap->GetSection());
188 SBAddress::GetOffset ()
190 if (m_opaque_ap->IsValid())
191 return m_opaque_ap->GetOffset();
196 SBAddress::operator->()
198 return m_opaque_ap.get();
202 SBAddress::operator->() const
204 return m_opaque_ap.get();
210 if (m_opaque_ap.get() == NULL)
211 m_opaque_ap.reset (new Address());
216 SBAddress::ref () const
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());
228 return m_opaque_ap.get();
232 SBAddress::GetDescription (SBStream &description)
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())
239 m_opaque_ap->Dump (&strm,
241 Address::DumpStyleResolvedDescription,
242 Address::DumpStyleModuleWithFileAddress,
245 // m_opaque_ap->Dump (&sstrm, NULL, Address::DumpStyleResolvedDescription, Address::DumpStyleInvalid, 4);
246 // if (sstrm.GetData())
247 // strm.Printf (" (%s)", sstrm.GetData());
250 strm.PutCString ("No value");
256 SBAddress::GetModule ()
259 if (m_opaque_ap->IsValid())
260 sb_module.SetSP (m_opaque_ap->GetModule());
265 SBAddress::GetSymbolContext (uint32_t resolve_scope)
267 SBSymbolContext sb_sc;
268 if (m_opaque_ap->IsValid())
269 m_opaque_ap->CalculateSymbolContext (&sb_sc.ref(), resolve_scope);
274 SBAddress::GetCompileUnit ()
276 SBCompileUnit sb_comp_unit;
277 if (m_opaque_ap->IsValid())
278 sb_comp_unit.reset(m_opaque_ap->CalculateSymbolContextCompileUnit());
283 SBAddress::GetFunction ()
285 SBFunction sb_function;
286 if (m_opaque_ap->IsValid())
287 sb_function.reset(m_opaque_ap->CalculateSymbolContextFunction());
292 SBAddress::GetBlock ()
295 if (m_opaque_ap->IsValid())
296 sb_block.SetPtr(m_opaque_ap->CalculateSymbolContextBlock());
301 SBAddress::GetSymbol ()
304 if (m_opaque_ap->IsValid())
305 sb_symbol.reset(m_opaque_ap->CalculateSymbolContextSymbol());
310 SBAddress::GetLineEntry ()
312 SBLineEntry sb_line_entry;
313 if (m_opaque_ap->IsValid())
315 LineEntry line_entry;
316 if (m_opaque_ap->CalculateSymbolContextLineEntry (line_entry))
317 sb_line_entry.SetLineEntry (line_entry);
319 return sb_line_entry;
323 SBAddress::GetAddressClass ()
325 if (m_opaque_ap->IsValid())
326 return m_opaque_ap->GetAddressClass();
327 return eAddressClassInvalid;