1 //===-- SBFrame.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/SBFrame.h"
11 
12 #include <string>
13 #include <algorithm>
14 
15 #include "lldb/lldb-types.h"
16 
17 #include "lldb/Core/Address.h"
18 #include "lldb/Core/ConstString.h"
19 #include "lldb/Core/Stream.h"
20 #include "lldb/Core/StreamFile.h"
21 #include "lldb/Core/ValueObjectRegister.h"
22 #include "lldb/Core/ValueObjectVariable.h"
23 #include "lldb/Symbol/Block.h"
24 #include "lldb/Symbol/SymbolContext.h"
25 #include "lldb/Symbol/VariableList.h"
26 #include "lldb/Symbol/Variable.h"
27 #include "lldb/Target/ExecutionContext.h"
28 #include "lldb/Target/Target.h"
29 #include "lldb/Target/Process.h"
30 #include "lldb/Target/RegisterContext.h"
31 #include "lldb/Target/StackFrame.h"
32 #include "lldb/Target/Thread.h"
33 
34 #include "lldb/API/SBDebugger.h"
35 #include "lldb/API/SBValue.h"
36 #include "lldb/API/SBAddress.h"
37 #include "lldb/API/SBSymbolContext.h"
38 #include "lldb/API/SBThread.h"
39 
40 using namespace lldb;
41 using namespace lldb_private;
42 
43 SBFrame::SBFrame () :
44     m_opaque_sp ()
45 {
46 }
47 
48 SBFrame::SBFrame (const lldb::StackFrameSP &lldb_object_sp) :
49     m_opaque_sp (lldb_object_sp)
50 {
51 }
52 
53 SBFrame::~SBFrame()
54 {
55 }
56 
57 
58 void
59 SBFrame::SetFrame (const lldb::StackFrameSP &lldb_object_sp)
60 {
61     m_opaque_sp = lldb_object_sp;
62 }
63 
64 
65 bool
66 SBFrame::IsValid() const
67 {
68     return (m_opaque_sp.get() != NULL);
69 }
70 
71 SBSymbolContext
72 SBFrame::GetSymbolContext (uint32_t resolve_scope) const
73 {
74     SBSymbolContext sb_sym_ctx;
75     if (m_opaque_sp)
76         sb_sym_ctx.SetSymbolContext(&m_opaque_sp->GetSymbolContext (resolve_scope));
77     return sb_sym_ctx;
78 }
79 
80 SBModule
81 SBFrame::GetModule () const
82 {
83     SBModule sb_module (m_opaque_sp->GetSymbolContext (eSymbolContextModule).module_sp);
84     return sb_module;
85 }
86 
87 SBCompileUnit
88 SBFrame::GetCompileUnit () const
89 {
90     SBCompileUnit sb_comp_unit(m_opaque_sp->GetSymbolContext (eSymbolContextCompUnit).comp_unit);
91     return sb_comp_unit;
92 }
93 
94 SBFunction
95 SBFrame::GetFunction () const
96 {
97     SBFunction sb_function(m_opaque_sp->GetSymbolContext (eSymbolContextFunction).function);
98     return sb_function;
99 }
100 
101 SBBlock
102 SBFrame::GetBlock () const
103 {
104     SBBlock sb_block(m_opaque_sp->GetSymbolContext (eSymbolContextBlock).block);
105     return sb_block;
106 }
107 
108 SBLineEntry
109 SBFrame::GetLineEntry () const
110 {
111     SBLineEntry sb_line_entry(&m_opaque_sp->GetSymbolContext (eSymbolContextLineEntry).line_entry);
112     return sb_line_entry;
113 }
114 
115 uint32_t
116 SBFrame::GetFrameID () const
117 {
118     if (m_opaque_sp)
119         return m_opaque_sp->GetID();
120     else
121         return UINT32_MAX;
122 }
123 
124 
125 lldb::addr_t
126 SBFrame::GetPC () const
127 {
128     if (m_opaque_sp)
129         return m_opaque_sp->GetPC().GetLoadAddress (&m_opaque_sp->GetThread().GetProcess());
130     return LLDB_INVALID_ADDRESS;
131 }
132 
133 bool
134 SBFrame::SetPC (lldb::addr_t new_pc)
135 {
136     if (m_opaque_sp)
137         return m_opaque_sp->GetRegisterContext()->SetPC (new_pc);
138     return false;
139 }
140 
141 lldb::addr_t
142 SBFrame::GetSP () const
143 {
144     if (m_opaque_sp)
145         return m_opaque_sp->GetRegisterContext()->GetSP();
146     return LLDB_INVALID_ADDRESS;
147 }
148 
149 
150 lldb::addr_t
151 SBFrame::GetFP () const
152 {
153     if (m_opaque_sp)
154         return m_opaque_sp->GetRegisterContext()->GetFP();
155     return LLDB_INVALID_ADDRESS;
156 }
157 
158 
159 SBAddress
160 SBFrame::GetPCAddress () const
161 {
162     SBAddress sb_addr;
163     if (m_opaque_sp)
164         sb_addr.SetAddress (&m_opaque_sp->GetPC());
165     return sb_addr;
166 }
167 
168 void
169 SBFrame::Clear()
170 {
171     m_opaque_sp.reset();
172 }
173 
174 SBValue
175 SBFrame::LookupVar (const char *var_name)
176 {
177     lldb::VariableSP var_sp;
178     if (IsValid ())
179     {
180         lldb_private::VariableList variable_list;
181         SBSymbolContext sc = GetSymbolContext (eSymbolContextEverything);
182 
183         SBBlock block = sc.GetBlock();
184         if (block.IsValid())
185             block.AppendVariables (true, true, &variable_list);
186 
187         const uint32_t num_variables = variable_list.GetSize();
188 
189         bool found = false;
190         for (int i = 0; i < num_variables && !found; ++i)
191         {
192             var_sp = variable_list.GetVariableAtIndex(i);
193             if (var_sp
194                 && (var_sp.get()->GetName() == lldb_private::ConstString(var_name)))
195                 found = true;
196         }
197         if (!found)
198             var_sp.reset();
199     }
200     SBValue sb_value (ValueObjectSP (new ValueObjectVariable (var_sp)));
201     return sb_value;
202 }
203 
204 SBValue
205 SBFrame::LookupVarInScope (const char *var_name, const char *scope)
206 {
207     lldb::VariableSP var_sp;
208     if (IsValid())
209     {
210         std::string scope_str = scope;
211         lldb::ValueType var_scope = eValueTypeInvalid;
212         // Convert scope_str to be all lowercase;
213         std::transform (scope_str.begin(), scope_str.end(), scope_str.begin(), ::tolower);
214 
215         if (scope_str.compare ("global") == 0)
216             var_scope = eValueTypeVariableGlobal;
217         else if (scope_str.compare ("local") == 0)
218             var_scope = eValueTypeVariableLocal;
219         else if (scope_str.compare ("parameter") == 0)
220            var_scope = eValueTypeVariableArgument;
221 
222         if (var_scope != eValueTypeInvalid)
223         {
224             lldb_private::VariableList variable_list;
225             SBSymbolContext sc = GetSymbolContext (eSymbolContextEverything);
226 
227             SBBlock block = sc.GetBlock();
228             if (block.IsValid())
229                 block.AppendVariables (true, true, &variable_list);
230 
231             const uint32_t num_variables = variable_list.GetSize();
232 
233             bool found = false;
234             for (int i = 0; i < num_variables && !found; ++i)
235             {
236                 var_sp = variable_list.GetVariableAtIndex(i);
237                 if (var_sp
238                     && (var_sp.get()->GetName() == lldb_private::ConstString(var_name))
239                     && var_sp.get()->GetScope() == var_scope)
240                     found = true;
241             }
242             if (!found)
243                 var_sp.reset();
244         }
245     }
246     SBValue sb_value (ValueObjectSP (new ValueObjectVariable (var_sp)));
247     return sb_value;
248 }
249 
250 bool
251 SBFrame::operator == (const SBFrame &rhs) const
252 {
253     return m_opaque_sp.get() == rhs.m_opaque_sp.get();
254 }
255 
256 bool
257 SBFrame::operator != (const SBFrame &rhs) const
258 {
259     return m_opaque_sp.get() != rhs.m_opaque_sp.get();
260 }
261 
262 lldb_private::StackFrame *
263 SBFrame::operator->() const
264 {
265     return m_opaque_sp.get();
266 }
267 
268 lldb_private::StackFrame *
269 SBFrame::get() const
270 {
271     return m_opaque_sp.get();
272 }
273 
274 
275 SBThread
276 SBFrame::GetThread () const
277 {
278     SBThread sb_thread (m_opaque_sp->GetThread().GetSP());
279     return sb_thread;
280 }
281 
282 const char *
283 SBFrame::Disassemble () const
284 {
285     if (m_opaque_sp)
286         return m_opaque_sp->Disassemble();
287     return NULL;
288 }
289 
290 
291 
292 lldb_private::StackFrame *
293 SBFrame::GetLLDBObjectPtr ()
294 {
295     return m_opaque_sp.get();
296 }
297 
298 SBValueList
299 SBFrame::GetVariables (bool arguments,
300                        bool locals,
301                        bool statics,
302                        bool in_scope_only)
303 {
304     SBValueList value_list;
305     if (m_opaque_sp)
306     {
307         size_t i;
308         VariableList *variable_list = m_opaque_sp->GetVariableList();
309         if (variable_list)
310         {
311             const size_t num_variables = variable_list->GetSize();
312             if (num_variables)
313             {
314                 for (i = 0; i < num_variables; ++i)
315                 {
316                     VariableSP variable_sp (variable_list->GetVariableAtIndex(i));
317                     if (variable_sp)
318                     {
319                         bool add_variable = false;
320                         switch (variable_sp->GetScope())
321                         {
322                         case eValueTypeVariableGlobal:
323                         case eValueTypeVariableStatic:
324                             add_variable = statics;
325                             break;
326 
327                         case eValueTypeVariableArgument:
328                             add_variable = arguments;
329                             break;
330 
331                         case eValueTypeVariableLocal:
332                             add_variable = locals;
333                             break;
334                         }
335                         if (add_variable)
336                         {
337                             if (in_scope_only && !variable_sp->IsInScope(m_opaque_sp.get()))
338                                 continue;
339 
340                             value_list.Append(ValueObjectSP (new ValueObjectVariable (variable_sp)));
341                         }
342                     }
343                 }
344             }
345         }
346 
347         if (statics)
348         {
349             CompileUnit *frame_comp_unit = m_opaque_sp->GetSymbolContext (eSymbolContextCompUnit).comp_unit;
350 
351             if (frame_comp_unit)
352             {
353                 variable_list = frame_comp_unit->GetVariableList(true).get();
354 
355                 if (variable_list)
356                 {
357                     const size_t num_variables = variable_list->GetSize();
358                     if (num_variables)
359                     {
360                         for (i = 0; i < num_variables; ++i)
361                         {
362                             VariableSP variable_sp (variable_list->GetVariableAtIndex(i));
363                             if (variable_sp)
364                             {
365                                 value_list.Append(ValueObjectSP (new ValueObjectVariable (variable_sp)));
366                             }
367                         }
368                     }
369                 }
370             }
371         }
372     }
373     return value_list;
374 }
375 
376 lldb::SBValueList
377 SBFrame::GetRegisters ()
378 {
379     SBValueList value_list;
380     if (m_opaque_sp)
381     {
382         RegisterContext *reg_ctx = m_opaque_sp->GetRegisterContext();
383         if (reg_ctx)
384         {
385             const uint32_t num_sets = reg_ctx->GetRegisterSetCount();
386             for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx)
387             {
388                 value_list.Append(ValueObjectSP (new ValueObjectRegisterSet (reg_ctx, set_idx)));
389             }
390         }
391     }
392     return value_list;
393 }
394 
395