1 //===-- StackFrame.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/Target/StackFrame.h"
11 
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Core/Module.h"
17 #include "lldb/Core/Disassembler.h"
18 #include "lldb/Core/Value.h"
19 #include "lldb/Symbol/Function.h"
20 #include "lldb/Target/ExecutionContext.h"
21 #include "lldb/Target/Process.h"
22 #include "lldb/Target/RegisterContext.h"
23 #include "lldb/Target/Target.h"
24 #include "lldb/Target/Thread.h"
25 
26 using namespace lldb;
27 using namespace lldb_private;
28 
29 // The first bits in the flags are reserved for the SymbolContext::Scope bits
30 // so we know if we have tried to look up information in our internal symbol
31 // context (m_sc) already.
32 #define RESOLVED_FRAME_ADDR (uint32_t(eSymbolContextEverything + 1))
33 #define RESOLVED_FRAME_ID   (RESOLVED_FRAME_ADDR << 1)
34 #define GOT_FRAME_BASE      (RESOLVED_FRAME_ID << 1)
35 #define FRAME_IS_OBSOLETE   (GOT_FRAME_BASE << 1)
36 #define RESOLVED_VARIABLES  (FRAME_IS_OBSOLETE << 1)
37 
38 StackFrame::StackFrame
39 (
40     lldb::user_id_t frame_idx,
41     lldb::user_id_t concrete_frame_index,
42     Thread &thread,
43     lldb::addr_t cfa,
44     lldb::addr_t pc,
45     const SymbolContext *sc_ptr
46 ) :
47     m_frame_index (frame_idx),
48     m_concrete_frame_index (concrete_frame_index),
49     m_thread (thread),
50     m_reg_context_sp (),
51     m_id (cfa, 0),
52     m_pc (NULL, pc),
53     m_sc (),
54     m_flags (),
55     m_frame_base (),
56     m_frame_base_error (),
57     m_variable_list_sp (),
58     m_value_object_list ()
59 {
60     if (sc_ptr != NULL)
61     {
62         m_sc = *sc_ptr;
63         m_flags.Set(m_sc.GetResolvedMask ());
64     }
65 }
66 
67 StackFrame::StackFrame
68 (
69     lldb::user_id_t frame_idx,
70     lldb::user_id_t concrete_frame_index,
71     Thread &thread,
72     const RegisterContextSP &reg_context_sp,
73     lldb::addr_t cfa,
74     lldb::addr_t pc,
75     const SymbolContext *sc_ptr
76 ) :
77     m_frame_index (frame_idx),
78     m_concrete_frame_index (concrete_frame_index),
79     m_thread (thread),
80     m_reg_context_sp (reg_context_sp),
81     m_id (cfa, 0),
82     m_pc (NULL, pc),
83     m_sc (),
84     m_flags (),
85     m_frame_base (),
86     m_frame_base_error (),
87     m_variable_list_sp (),
88     m_value_object_list ()
89 {
90     if (sc_ptr != NULL)
91     {
92         m_sc = *sc_ptr;
93         m_flags.Set(m_sc.GetResolvedMask ());
94     }
95 
96     if (reg_context_sp && !m_sc.target_sp)
97     {
98         m_sc.target_sp = reg_context_sp->GetThread().GetProcess().GetTarget().GetSP();
99         m_flags.Set (eSymbolContextTarget);
100     }
101 }
102 
103 StackFrame::StackFrame
104 (
105     lldb::user_id_t frame_idx,
106     lldb::user_id_t concrete_frame_index,
107     Thread &thread,
108     const RegisterContextSP &reg_context_sp,
109     lldb::addr_t cfa,
110     const Address& pc_addr,
111     const SymbolContext *sc_ptr
112 ) :
113     m_frame_index (frame_idx),
114     m_concrete_frame_index (concrete_frame_index),
115     m_thread (thread),
116     m_reg_context_sp (reg_context_sp),
117     m_id (cfa, 0),
118     m_pc (pc_addr),
119     m_sc (),
120     m_flags (),
121     m_frame_base (),
122     m_frame_base_error (),
123     m_variable_list_sp (),
124     m_value_object_list ()
125 {
126     if (sc_ptr != NULL)
127     {
128         m_sc = *sc_ptr;
129         m_flags.Set(m_sc.GetResolvedMask ());
130     }
131 
132     if (m_sc.target_sp.get() == NULL && reg_context_sp)
133     {
134         m_sc.target_sp = reg_context_sp->GetThread().GetProcess().GetTarget().GetSP();
135         m_flags.Set (eSymbolContextTarget);
136     }
137 
138     if (m_sc.module_sp.get() == NULL && pc_addr.GetSection())
139     {
140         Module *pc_module = pc_addr.GetSection()->GetModule();
141         if (pc_module)
142         {
143             m_sc.module_sp = pc_module->GetSP();
144             m_flags.Set (eSymbolContextModule);
145         }
146     }
147 }
148 
149 
150 //----------------------------------------------------------------------
151 // Destructor
152 //----------------------------------------------------------------------
153 StackFrame::~StackFrame()
154 {
155 }
156 
157 StackID&
158 StackFrame::GetStackID()
159 {
160     // Make sure we have resolved our stack ID's address range before we give
161     // it out to any external clients
162     if (m_id.GetStartAddress().IsValid() == 0 && m_flags.IsClear(RESOLVED_FRAME_ID))
163     {
164         m_flags.Set (RESOLVED_FRAME_ID);
165 
166         // Resolve our PC to section offset if we haven't alreday done so
167         // and if we don't have a module. The resolved address section will
168         // contain the module to which it belongs.
169         if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_ADDR))
170             GetFrameCodeAddress();
171 
172         if (GetSymbolContext (eSymbolContextFunction).function)
173         {
174             m_id.SetStartAddress (m_sc.function->GetAddressRange().GetBaseAddress());
175         }
176         else if (GetSymbolContext (eSymbolContextSymbol).symbol)
177         {
178             AddressRange *symbol_range_ptr = m_sc.symbol->GetAddressRangePtr();
179             if (symbol_range_ptr)
180                 m_id.SetStartAddress(symbol_range_ptr->GetBaseAddress());
181         }
182     }
183     return m_id;
184 }
185 
186 Address&
187 StackFrame::GetFrameCodeAddress()
188 {
189     if (m_flags.IsClear(RESOLVED_FRAME_ADDR) && !m_pc.IsSectionOffset())
190     {
191         m_flags.Set (RESOLVED_FRAME_ADDR);
192 
193         // Resolve the PC into a temporary address because if ResolveLoadAddress
194         // fails to resolve the address, it will clear the address object...
195         Address resolved_pc;
196         if (m_thread.GetProcess().ResolveLoadAddress(m_pc.GetOffset(), resolved_pc))
197         {
198             m_pc = resolved_pc;
199             const Section *section = m_pc.GetSection();
200             if (section)
201             {
202                 Module *module = section->GetModule();
203                 if (module)
204                 {
205                     m_sc.module_sp = module->GetSP();
206                     if (m_sc.module_sp)
207                         m_flags.Set(eSymbolContextModule);
208                 }
209             }
210         }
211     }
212     return m_pc;
213 }
214 
215 void
216 StackFrame::ChangePC (addr_t pc)
217 {
218     m_pc.SetOffset(pc);
219     m_pc.SetSection(NULL);
220     m_sc.Clear();
221     m_flags.SetAllFlagBits(0);
222     m_thread.ClearStackFrames ();
223 }
224 
225 const char *
226 StackFrame::Disassemble ()
227 {
228     if (m_disassembly.GetSize() == 0)
229     {
230         ExecutionContext exe_ctx;
231         Calculate(exe_ctx);
232         Target &target = m_thread.GetProcess().GetTarget();
233         Disassembler::Disassemble (target.GetDebugger(),
234                                    target.GetArchitecture(),
235                                    exe_ctx,
236                                    0,
237                                    false,
238                                    m_disassembly);
239         if (m_disassembly.GetSize() == 0)
240             return NULL;
241     }
242     return m_disassembly.GetData();
243 }
244 
245 //----------------------------------------------------------------------
246 // Get the symbol context if we already haven't done so by resolving the
247 // PC address as much as possible. This way when we pass around a
248 // StackFrame object, everyone will have as much information as
249 // possible and no one will ever have to look things up manually.
250 //----------------------------------------------------------------------
251 const SymbolContext&
252 StackFrame::GetSymbolContext (uint32_t resolve_scope)
253 {
254     // Copy our internal symbol context into "sc".
255     if ((m_flags.GetAllFlagBits() & resolve_scope) != resolve_scope)
256     {
257         // Resolve our PC to section offset if we haven't alreday done so
258         // and if we don't have a module. The resolved address section will
259         // contain the module to which it belongs
260         if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_ADDR))
261             GetFrameCodeAddress();
262 
263         // If this is not frame zero, then we need to subtract 1 from the PC
264         // value when doing address lookups since the PC will be on the
265         // instruction following the function call instruction...
266 
267         Address lookup_addr(GetFrameCodeAddress());
268         if (m_frame_index > 0 && lookup_addr.IsValid())
269         {
270             addr_t offset = lookup_addr.GetOffset();
271             if (offset > 0)
272                 lookup_addr.SetOffset(offset - 1);
273         }
274 
275 
276         uint32_t resolved = 0;
277         if (m_sc.module_sp)
278         {
279             // We have something in our stack frame symbol context, lets check
280             // if we haven't already tried to lookup one of those things. If we
281             // haven't then we will do the query.
282 
283             uint32_t actual_resolve_scope = 0;
284 
285             if (resolve_scope & eSymbolContextCompUnit)
286             {
287                 if (m_flags.IsClear (eSymbolContextCompUnit))
288                 {
289                     if (m_sc.comp_unit)
290                         resolved |= eSymbolContextCompUnit;
291                     else
292                         actual_resolve_scope |= eSymbolContextCompUnit;
293                 }
294             }
295 
296             if (resolve_scope & eSymbolContextFunction)
297             {
298                 if (m_flags.IsClear (eSymbolContextFunction))
299                 {
300                     if (m_sc.function)
301                         resolved |= eSymbolContextFunction;
302                     else
303                         actual_resolve_scope |= eSymbolContextFunction;
304                 }
305             }
306 
307             if (resolve_scope & eSymbolContextBlock)
308             {
309                 if (m_flags.IsClear (eSymbolContextBlock))
310                 {
311                     if (m_sc.block)
312                         resolved |= eSymbolContextBlock;
313                     else
314                         actual_resolve_scope |= eSymbolContextBlock;
315                 }
316             }
317 
318             if (resolve_scope & eSymbolContextSymbol)
319             {
320                 if (m_flags.IsClear (eSymbolContextSymbol))
321                 {
322                     if (m_sc.symbol)
323                         resolved |= eSymbolContextSymbol;
324                     else
325                         actual_resolve_scope |= eSymbolContextSymbol;
326                 }
327             }
328 
329             if (resolve_scope & eSymbolContextLineEntry)
330             {
331                 if (m_flags.IsClear (eSymbolContextLineEntry))
332                 {
333                     if (m_sc.line_entry.IsValid())
334                         resolved |= eSymbolContextLineEntry;
335                     else
336                         actual_resolve_scope |= eSymbolContextLineEntry;
337                 }
338             }
339 
340             if (actual_resolve_scope)
341             {
342                 // We might be resolving less information than what is already
343                 // in our current symbol context so resolve into a temporary
344                 // symbol context "sc" so we don't clear out data we have
345                 // already found in "m_sc"
346                 SymbolContext sc;
347                 // Set flags that indicate what we have tried to resolve
348                 resolved |= m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, actual_resolve_scope, sc);
349                 // Only replace what we didn't already have as we may have
350                 // information for an inlined function scope that won't match
351                 // what a standard lookup by address would match
352                 if ((resolved & eSymbolContextCompUnit)  && m_sc.comp_unit == NULL)
353                     m_sc.comp_unit = sc.comp_unit;
354                 if ((resolved & eSymbolContextFunction)  && m_sc.function == NULL)
355                     m_sc.function = sc.function;
356                 if ((resolved & eSymbolContextBlock)     && m_sc.block == NULL)
357                     m_sc.block = sc.block;
358                 if ((resolved & eSymbolContextSymbol)    && m_sc.symbol == NULL)
359                     m_sc.symbol = sc.symbol;
360                 if ((resolved & eSymbolContextLineEntry) && !m_sc.line_entry.IsValid())
361                     m_sc.line_entry = sc.line_entry;
362 
363             }
364         }
365         else
366         {
367             // If we don't have a module, then we can't have the compile unit,
368             // function, block, line entry or symbol, so we can safely call
369             // ResolveSymbolContextForAddress with our symbol context member m_sc.
370             resolved |= m_thread.GetProcess().GetTarget().GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc);
371         }
372 
373         // If the target was requested add that:
374         if (m_sc.target_sp.get() == NULL)
375         {
376             m_sc.target_sp = CalculateProcess()->GetTarget().GetSP();
377             if (m_sc.target_sp)
378                 resolved |= eSymbolContextTarget;
379         }
380 
381         // Update our internal flags so we remember what we have tried to locate so
382         // we don't have to keep trying when more calls to this function are made.
383         // We might have dug up more information that was requested (for example
384         // if we were asked to only get the block, we will have gotten the
385         // compile unit, and function) so set any additional bits that we resolved
386         m_flags.Set (resolve_scope | resolved);
387     }
388 
389     // Return the symbol context with everything that was possible to resolve
390     // resolved.
391     return m_sc;
392 }
393 
394 
395 VariableList *
396 StackFrame::GetVariableList ()
397 {
398     if (m_flags.IsClear(RESOLVED_VARIABLES))
399     {
400         m_flags.Set(RESOLVED_VARIABLES);
401 
402         if (GetSymbolContext (eSymbolContextFunction).function)
403         {
404             bool get_child_variables = true;
405             bool can_create = true;
406             m_variable_list_sp = m_sc.function->GetBlock (can_create).GetVariableList (get_child_variables, can_create);
407         }
408     }
409     return m_variable_list_sp.get();
410 }
411 
412 
413 bool
414 StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr)
415 {
416     if (m_flags.IsClear(GOT_FRAME_BASE))
417     {
418         if (m_sc.function)
419         {
420             m_frame_base.Clear();
421             m_frame_base_error.Clear();
422 
423             m_flags.Set(GOT_FRAME_BASE);
424             ExecutionContext exe_ctx (&m_thread.GetProcess(), &m_thread, this);
425             Value expr_value;
426             if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, NULL, expr_value, &m_frame_base_error) < 0)
427             {
428                 // We should really have an error if evaluate returns, but in case
429                 // we don't, lets set the error to something at least.
430                 if (m_frame_base_error.Success())
431                     m_frame_base_error.SetErrorString("Evaluation of the frame base expression failed.");
432             }
433             else
434             {
435                 m_frame_base = expr_value.ResolveValue(&exe_ctx, NULL);
436             }
437         }
438         else
439         {
440             m_frame_base_error.SetErrorString ("No function in symbol context.");
441         }
442     }
443 
444     if (m_frame_base_error.Success())
445         frame_base = m_frame_base;
446 
447     if (error_ptr)
448         *error_ptr = m_frame_base_error;
449     return m_frame_base_error.Success();
450 }
451 
452 RegisterContext *
453 StackFrame::GetRegisterContext ()
454 {
455     if (m_reg_context_sp.get() == NULL)
456         m_reg_context_sp.reset (m_thread.CreateRegisterContextForFrame (this));
457     return m_reg_context_sp.get();
458 }
459 
460 bool
461 StackFrame::HasDebugInformation ()
462 {
463     GetSymbolContext (eSymbolContextLineEntry);
464     return m_sc.line_entry.IsValid();
465 }
466 
467 ValueObjectList &
468 StackFrame::GetValueObjectList()
469 {
470     return m_value_object_list;
471 }
472 
473 Target *
474 StackFrame::CalculateTarget ()
475 {
476     return m_thread.CalculateTarget();
477 }
478 
479 Process *
480 StackFrame::CalculateProcess ()
481 {
482     return m_thread.CalculateProcess();
483 }
484 
485 Thread *
486 StackFrame::CalculateThread ()
487 {
488     return &m_thread;
489 }
490 
491 StackFrame *
492 StackFrame::CalculateStackFrame ()
493 {
494     return this;
495 }
496 
497 
498 void
499 StackFrame::Calculate (ExecutionContext &exe_ctx)
500 {
501     m_thread.Calculate (exe_ctx);
502     exe_ctx.frame = this;
503 }
504 
505 void
506 StackFrame::Dump (Stream *strm, bool show_frame_index)
507 {
508     if (strm == NULL)
509         return;
510 
511     if (show_frame_index)
512         strm->Printf("frame #%u: ", m_frame_index);
513     strm->Printf("0x%0*llx", m_thread.GetProcess().GetAddressByteSize() * 2, GetFrameCodeAddress().GetLoadAddress(&m_thread.GetProcess()));
514     GetSymbolContext(eSymbolContextEverything);
515     strm->PutCString(", where = ");
516     // TODO: need to get the
517     const bool show_module = true;
518     const bool show_inline = true;
519     m_sc.DumpStopContext(strm, &m_thread.GetProcess(), GetFrameCodeAddress(), show_module, show_inline);
520 }
521 
522