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