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