]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/API/SBAddress.cpp
Merge ^/head r306906 through r307382.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / API / SBAddress.cpp
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/Core/StreamString.h"
18 #include "lldb/Symbol/LineEntry.h"
19 #include "lldb/Target/Target.h"
20
21
22 using namespace lldb;
23 using namespace lldb_private;
24
25
26 SBAddress::SBAddress () :
27     m_opaque_ap (new Address())
28 {
29 }
30
31 SBAddress::SBAddress (const Address *lldb_object_ptr) :
32     m_opaque_ap (new Address())
33 {
34     if (lldb_object_ptr)
35         ref() = *lldb_object_ptr;
36 }
37
38 SBAddress::SBAddress (const SBAddress &rhs) :
39     m_opaque_ap (new Address())
40 {
41     if (rhs.IsValid())
42         ref() = rhs.ref();
43 }
44
45
46 SBAddress::SBAddress (lldb::SBSection section, lldb::addr_t offset) :
47     m_opaque_ap(new Address (section.GetSP(), offset))
48 {
49 }
50
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())
54 {    
55     SetLoadAddress (load_addr, target);
56 }
57
58
59
60 SBAddress::~SBAddress ()
61 {
62 }
63
64 const SBAddress &
65 SBAddress::operator = (const SBAddress &rhs)
66 {
67     if (this != &rhs)
68     {
69         if (rhs.IsValid())
70             ref() = rhs.ref();
71         else
72             m_opaque_ap.reset (new Address());
73     }
74     return *this;
75 }
76
77 bool
78 SBAddress::IsValid () const
79 {
80     return m_opaque_ap.get() != NULL && m_opaque_ap->IsValid();
81 }
82
83 void
84 SBAddress::Clear ()
85 {
86     m_opaque_ap.reset (new Address());
87 }
88
89 void
90 SBAddress::SetAddress (lldb::SBSection section, lldb::addr_t offset)
91 {
92     Address &addr = ref();
93     addr.SetSection (section.GetSP());
94     addr.SetOffset (offset);
95 }
96
97
98 void
99 SBAddress::SetAddress (const Address *lldb_object_ptr)
100 {
101     if (lldb_object_ptr)
102         ref() =  *lldb_object_ptr;
103     else
104         m_opaque_ap.reset (new Address());
105 }
106
107 lldb::addr_t
108 SBAddress::GetFileAddress () const
109 {
110     if (m_opaque_ap->IsValid())
111         return m_opaque_ap->GetFileAddress();
112     else
113         return LLDB_INVALID_ADDRESS;
114 }
115
116 lldb::addr_t
117 SBAddress::GetLoadAddress (const SBTarget &target) const
118 {
119     Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
120
121     lldb::addr_t addr = LLDB_INVALID_ADDRESS;
122     TargetSP target_sp (target.GetSP());
123     if (target_sp)
124     {
125         if (m_opaque_ap->IsValid())
126         {
127             std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
128             addr = m_opaque_ap->GetLoadAddress (target_sp.get());
129         }
130     }
131
132     if (log)
133     {
134         if (addr == LLDB_INVALID_ADDRESS)
135             log->Printf ("SBAddress::GetLoadAddress (SBTarget(%p)) => LLDB_INVALID_ADDRESS",
136                          static_cast<void*>(target_sp.get()));
137         else
138             log->Printf ("SBAddress::GetLoadAddress (SBTarget(%p)) => 0x%" PRIx64,
139                          static_cast<void*>(target_sp.get()), addr);
140     }
141
142     return addr;
143 }
144
145 void
146 SBAddress::SetLoadAddress (lldb::addr_t load_addr, lldb::SBTarget &target)
147 {
148     // Create the address object if we don't already have one
149     ref();
150     if (target.IsValid())
151         *this = target.ResolveLoadAddress(load_addr);
152     else
153         m_opaque_ap->Clear();
154
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
158     // a valid offset
159     if (!m_opaque_ap->IsValid())
160         m_opaque_ap->SetOffset(load_addr);
161 }
162
163 bool
164 SBAddress::OffsetAddress (addr_t offset)
165 {
166     if (m_opaque_ap->IsValid())
167     {
168         addr_t addr_offset = m_opaque_ap->GetOffset();
169         if (addr_offset != LLDB_INVALID_ADDRESS)
170         {
171             m_opaque_ap->SetOffset(addr_offset + offset);
172             return true;
173         }
174     }
175     return false;
176 }
177
178 lldb::SBSection
179 SBAddress::GetSection ()
180 {
181     lldb::SBSection sb_section;
182     if (m_opaque_ap->IsValid())
183         sb_section.SetSP (m_opaque_ap->GetSection());
184     return sb_section;
185 }
186
187 lldb::addr_t
188 SBAddress::GetOffset ()
189 {
190     if (m_opaque_ap->IsValid())
191         return m_opaque_ap->GetOffset();
192     return 0;
193 }
194
195 Address *
196 SBAddress::operator->()
197 {
198     return m_opaque_ap.get();
199 }
200
201 const Address *
202 SBAddress::operator->() const
203 {
204     return m_opaque_ap.get();
205 }
206
207 Address &
208 SBAddress::ref ()
209 {
210     if (m_opaque_ap.get() == NULL)
211         m_opaque_ap.reset (new Address());
212     return *m_opaque_ap;
213 }
214
215 const Address &
216 SBAddress::ref () const
217 {
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());
222     return *m_opaque_ap;
223 }
224
225 Address *
226 SBAddress::get ()
227 {
228     return m_opaque_ap.get();
229 }
230
231 bool
232 SBAddress::GetDescription (SBStream &description)
233 {
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())
238     {
239         m_opaque_ap->Dump (&strm,
240                            NULL,
241                            Address::DumpStyleResolvedDescription,
242                            Address::DumpStyleModuleWithFileAddress,
243                            4);
244         StreamString sstrm;
245 //        m_opaque_ap->Dump (&sstrm, NULL, Address::DumpStyleResolvedDescription, Address::DumpStyleInvalid, 4);
246 //        if (sstrm.GetData())
247 //            strm.Printf (" (%s)", sstrm.GetData());
248     }
249     else
250         strm.PutCString ("No value");
251
252     return true;
253 }
254
255 SBModule
256 SBAddress::GetModule ()
257 {
258     SBModule sb_module;
259     if (m_opaque_ap->IsValid())
260         sb_module.SetSP (m_opaque_ap->GetModule());
261     return sb_module;
262 }
263
264 SBSymbolContext
265 SBAddress::GetSymbolContext (uint32_t resolve_scope)
266 {
267     SBSymbolContext sb_sc;
268     if (m_opaque_ap->IsValid())
269         m_opaque_ap->CalculateSymbolContext (&sb_sc.ref(), resolve_scope);
270     return sb_sc;
271 }
272
273 SBCompileUnit
274 SBAddress::GetCompileUnit ()
275 {
276     SBCompileUnit sb_comp_unit;
277     if (m_opaque_ap->IsValid())
278         sb_comp_unit.reset(m_opaque_ap->CalculateSymbolContextCompileUnit());
279     return sb_comp_unit;
280 }
281
282 SBFunction
283 SBAddress::GetFunction ()
284 {
285     SBFunction sb_function;
286     if (m_opaque_ap->IsValid())
287         sb_function.reset(m_opaque_ap->CalculateSymbolContextFunction());
288     return sb_function;
289 }
290
291 SBBlock
292 SBAddress::GetBlock ()
293 {
294     SBBlock sb_block;
295     if (m_opaque_ap->IsValid())
296         sb_block.SetPtr(m_opaque_ap->CalculateSymbolContextBlock());
297     return sb_block;
298 }
299
300 SBSymbol
301 SBAddress::GetSymbol ()
302 {
303     SBSymbol sb_symbol;
304     if (m_opaque_ap->IsValid())
305         sb_symbol.reset(m_opaque_ap->CalculateSymbolContextSymbol());
306     return sb_symbol;
307 }
308
309 SBLineEntry
310 SBAddress::GetLineEntry ()
311 {
312     SBLineEntry sb_line_entry;
313     if (m_opaque_ap->IsValid())
314     {
315         LineEntry line_entry;
316         if (m_opaque_ap->CalculateSymbolContextLineEntry (line_entry))
317             sb_line_entry.SetLineEntry (line_entry);
318     }
319     return sb_line_entry;
320 }
321
322 AddressClass
323 SBAddress::GetAddressClass ()
324 {
325     if (m_opaque_ap->IsValid())
326         return m_opaque_ap->GetAddressClass();
327     return eAddressClassInvalid;
328 }
329