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