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/Core/ValueObjectVariable.h"
20 #include "lldb/Symbol/Function.h"
21 #include "lldb/Symbol/VariableList.h"
22 #include "lldb/Target/ExecutionContext.h"
23 #include "lldb/Target/Process.h"
24 #include "lldb/Target/RegisterContext.h"
25 #include "lldb/Target/Target.h"
26 #include "lldb/Target/Thread.h"
27 
28 using namespace lldb;
29 using namespace lldb_private;
30 
31 // The first bits in the flags are reserved for the SymbolContext::Scope bits
32 // so we know if we have tried to look up information in our internal symbol
33 // context (m_sc) already.
34 #define RESOLVED_FRAME_CODE_ADDR        (uint32_t(eSymbolContextEverything + 1))
35 #define RESOLVED_FRAME_ID_SYMBOL_SCOPE  (RESOLVED_FRAME_CODE_ADDR << 1)
36 #define GOT_FRAME_BASE                  (RESOLVED_FRAME_ID_SYMBOL_SCOPE << 1)
37 #define RESOLVED_VARIABLES              (GOT_FRAME_BASE << 1)
38 
39 StackFrame::StackFrame
40 (
41     lldb::user_id_t frame_idx,
42     lldb::user_id_t unwind_frame_index,
43     Thread &thread,
44     lldb::addr_t cfa,
45     lldb::addr_t pc,
46     const SymbolContext *sc_ptr
47 ) :
48     m_frame_index (frame_idx),
49     m_unwind_frame_index (unwind_frame_index),
50     m_thread (thread),
51     m_reg_context_sp (),
52     m_id (pc, cfa, NULL),
53     m_frame_code_addr (NULL, pc),
54     m_sc (),
55     m_flags (),
56     m_frame_base (),
57     m_frame_base_error (),
58     m_variable_list_sp (),
59     m_variable_list_value_objects ()
60 {
61     if (sc_ptr != NULL)
62     {
63         m_sc = *sc_ptr;
64         m_flags.Set(m_sc.GetResolvedMask ());
65     }
66 }
67 
68 StackFrame::StackFrame
69 (
70     lldb::user_id_t frame_idx,
71     lldb::user_id_t unwind_frame_index,
72     Thread &thread,
73     const RegisterContextSP &reg_context_sp,
74     lldb::addr_t cfa,
75     lldb::addr_t pc,
76     const SymbolContext *sc_ptr
77 ) :
78     m_frame_index (frame_idx),
79     m_unwind_frame_index (unwind_frame_index),
80     m_thread (thread),
81     m_reg_context_sp (reg_context_sp),
82     m_id (pc, cfa, NULL),
83     m_frame_code_addr (NULL, pc),
84     m_sc (),
85     m_flags (),
86     m_frame_base (),
87     m_frame_base_error (),
88     m_variable_list_sp (),
89     m_variable_list_value_objects ()
90 {
91     if (sc_ptr != NULL)
92     {
93         m_sc = *sc_ptr;
94         m_flags.Set(m_sc.GetResolvedMask ());
95     }
96 
97     if (reg_context_sp && !m_sc.target_sp)
98     {
99         m_sc.target_sp = reg_context_sp->GetThread().GetProcess().GetTarget().GetSP();
100         m_flags.Set (eSymbolContextTarget);
101     }
102 }
103 
104 StackFrame::StackFrame
105 (
106     lldb::user_id_t frame_idx,
107     lldb::user_id_t unwind_frame_index,
108     Thread &thread,
109     const RegisterContextSP &reg_context_sp,
110     lldb::addr_t cfa,
111     const Address& pc_addr,
112     const SymbolContext *sc_ptr
113 ) :
114     m_frame_index (frame_idx),
115     m_unwind_frame_index (unwind_frame_index),
116     m_thread (thread),
117     m_reg_context_sp (reg_context_sp),
118     m_id (pc_addr.GetLoadAddress (&thread.GetProcess()), cfa, NULL),
119     m_frame_code_addr (pc_addr),
120     m_sc (),
121     m_flags (),
122     m_frame_base (),
123     m_frame_base_error (),
124     m_variable_list_sp (),
125     m_variable_list_value_objects ()
126 {
127     if (sc_ptr != NULL)
128     {
129         m_sc = *sc_ptr;
130         m_flags.Set(m_sc.GetResolvedMask ());
131     }
132 
133     if (m_sc.target_sp.get() == NULL && reg_context_sp)
134     {
135         m_sc.target_sp = reg_context_sp->GetThread().GetProcess().GetTarget().GetSP();
136         m_flags.Set (eSymbolContextTarget);
137     }
138 
139     if (m_sc.module_sp.get() == NULL && pc_addr.GetSection())
140     {
141         Module *pc_module = pc_addr.GetSection()->GetModule();
142         if (pc_module)
143         {
144             m_sc.module_sp = pc_module->GetSP();
145             m_flags.Set (eSymbolContextModule);
146         }
147     }
148 }
149 
150 
151 //----------------------------------------------------------------------
152 // Destructor
153 //----------------------------------------------------------------------
154 StackFrame::~StackFrame()
155 {
156 }
157 
158 StackID&
159 StackFrame::GetStackID()
160 {
161     // Make sure we have resolved the StackID object's symbol context scope if
162     // we already haven't looked it up.
163 
164     if (m_flags.IsClear (RESOLVED_FRAME_ID_SYMBOL_SCOPE))
165     {
166         if (m_id.GetSymbolContextScope ())
167         {
168             m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE);
169         }
170         else
171         {
172             GetSymbolContext (eSymbolContextFunction | eSymbolContextBlock);
173 
174             if (m_sc.block)
175             {
176                 Block *inline_block = m_sc.block->GetContainingInlinedBlock();
177                 if (inline_block)
178                 {
179                     // Use the block with the inlined function info
180                     // as the symbol context since we want this frame
181                     // to have only the variables for the inlined function
182                     SetSymbolContextScope (inline_block);
183                 }
184                 else
185                 {
186                     // This block is not inlined with means it has no
187                     // inlined parents either, so we want to use the top
188                     // most function block.
189                     SetSymbolContextScope (&m_sc.function->GetBlock(false));
190                 }
191             }
192             else
193             {
194                 // The current stack frame doesn't have a block. Check to see
195                 // if it has a symbol. If it does we will use this as the
196                 // symbol scope. It is ok if "m_sc.symbol" is NULL below as
197                 // it will set the symbol context to NULL and set the
198                 // RESOLVED_FRAME_ID_SYMBOL_SCOPE flag bit.
199                 GetSymbolContext (eSymbolContextSymbol);
200                 SetSymbolContextScope (m_sc.symbol);
201             }
202         }
203     }
204     return m_id;
205 }
206 
207 void
208 StackFrame::SetSymbolContextScope (SymbolContextScope *symbol_scope)
209 {
210     m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE);
211     m_id.SetSymbolContextScope (symbol_scope);
212 }
213 
214 Address&
215 StackFrame::GetFrameCodeAddress()
216 {
217     if (m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR) && !m_frame_code_addr.IsSectionOffset())
218     {
219         m_flags.Set (RESOLVED_FRAME_CODE_ADDR);
220 
221         // Resolve the PC into a temporary address because if ResolveLoadAddress
222         // fails to resolve the address, it will clear the address object...
223         Address resolved_pc;
224         if (m_thread.GetProcess().ResolveLoadAddress(m_frame_code_addr.GetOffset(), resolved_pc))
225         {
226             m_frame_code_addr = resolved_pc;
227             const Section *section = m_frame_code_addr.GetSection();
228             if (section)
229             {
230                 Module *module = section->GetModule();
231                 if (module)
232                 {
233                     m_sc.module_sp = module->GetSP();
234                     if (m_sc.module_sp)
235                         m_flags.Set(eSymbolContextModule);
236                 }
237             }
238         }
239     }
240     return m_frame_code_addr;
241 }
242 
243 void
244 StackFrame::ChangePC (addr_t pc)
245 {
246     m_frame_code_addr.SetOffset(pc);
247     m_frame_code_addr.SetSection(NULL);
248     m_sc.Clear();
249     m_flags.SetAllFlagBits(0);
250     m_thread.ClearStackFrames ();
251 }
252 
253 const char *
254 StackFrame::Disassemble ()
255 {
256     if (m_disassembly.GetSize() == 0)
257     {
258         ExecutionContext exe_ctx;
259         Calculate(exe_ctx);
260         Target &target = m_thread.GetProcess().GetTarget();
261         Disassembler::Disassemble (target.GetDebugger(),
262                                    target.GetArchitecture(),
263                                    exe_ctx,
264                                    0,
265                                    false,
266                                    m_disassembly);
267         if (m_disassembly.GetSize() == 0)
268             return NULL;
269     }
270     return m_disassembly.GetData();
271 }
272 
273 //----------------------------------------------------------------------
274 // Get the symbol context if we already haven't done so by resolving the
275 // PC address as much as possible. This way when we pass around a
276 // StackFrame object, everyone will have as much information as
277 // possible and no one will ever have to look things up manually.
278 //----------------------------------------------------------------------
279 const SymbolContext&
280 StackFrame::GetSymbolContext (uint32_t resolve_scope)
281 {
282     // Copy our internal symbol context into "sc".
283     if ((m_flags.GetAllFlagBits() & resolve_scope) != resolve_scope)
284     {
285         // Resolve our PC to section offset if we haven't alreday done so
286         // and if we don't have a module. The resolved address section will
287         // contain the module to which it belongs
288         if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR))
289             GetFrameCodeAddress();
290 
291         // If this is not frame zero, then we need to subtract 1 from the PC
292         // value when doing address lookups since the PC will be on the
293         // instruction following the function call instruction...
294 
295         Address lookup_addr(GetFrameCodeAddress());
296         if (m_frame_index > 0 && lookup_addr.IsValid())
297         {
298             addr_t offset = lookup_addr.GetOffset();
299             if (offset > 0)
300                 lookup_addr.SetOffset(offset - 1);
301         }
302 
303 
304         uint32_t resolved = 0;
305         if (m_sc.module_sp)
306         {
307             // We have something in our stack frame symbol context, lets check
308             // if we haven't already tried to lookup one of those things. If we
309             // haven't then we will do the query.
310 
311             uint32_t actual_resolve_scope = 0;
312 
313             if (resolve_scope & eSymbolContextCompUnit)
314             {
315                 if (m_flags.IsClear (eSymbolContextCompUnit))
316                 {
317                     if (m_sc.comp_unit)
318                         resolved |= eSymbolContextCompUnit;
319                     else
320                         actual_resolve_scope |= eSymbolContextCompUnit;
321                 }
322             }
323 
324             if (resolve_scope & eSymbolContextFunction)
325             {
326                 if (m_flags.IsClear (eSymbolContextFunction))
327                 {
328                     if (m_sc.function)
329                         resolved |= eSymbolContextFunction;
330                     else
331                         actual_resolve_scope |= eSymbolContextFunction;
332                 }
333             }
334 
335             if (resolve_scope & eSymbolContextBlock)
336             {
337                 if (m_flags.IsClear (eSymbolContextBlock))
338                 {
339                     if (m_sc.block)
340                         resolved |= eSymbolContextBlock;
341                     else
342                         actual_resolve_scope |= eSymbolContextBlock;
343                 }
344             }
345 
346             if (resolve_scope & eSymbolContextSymbol)
347             {
348                 if (m_flags.IsClear (eSymbolContextSymbol))
349                 {
350                     if (m_sc.symbol)
351                         resolved |= eSymbolContextSymbol;
352                     else
353                         actual_resolve_scope |= eSymbolContextSymbol;
354                 }
355             }
356 
357             if (resolve_scope & eSymbolContextLineEntry)
358             {
359                 if (m_flags.IsClear (eSymbolContextLineEntry))
360                 {
361                     if (m_sc.line_entry.IsValid())
362                         resolved |= eSymbolContextLineEntry;
363                     else
364                         actual_resolve_scope |= eSymbolContextLineEntry;
365                 }
366             }
367 
368             if (actual_resolve_scope)
369             {
370                 // We might be resolving less information than what is already
371                 // in our current symbol context so resolve into a temporary
372                 // symbol context "sc" so we don't clear out data we have
373                 // already found in "m_sc"
374                 SymbolContext sc;
375                 // Set flags that indicate what we have tried to resolve
376                 resolved |= m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, actual_resolve_scope, sc);
377                 // Only replace what we didn't already have as we may have
378                 // information for an inlined function scope that won't match
379                 // what a standard lookup by address would match
380                 if ((resolved & eSymbolContextCompUnit)  && m_sc.comp_unit == NULL)
381                     m_sc.comp_unit = sc.comp_unit;
382                 if ((resolved & eSymbolContextFunction)  && m_sc.function == NULL)
383                     m_sc.function = sc.function;
384                 if ((resolved & eSymbolContextBlock)     && m_sc.block == NULL)
385                     m_sc.block = sc.block;
386                 if ((resolved & eSymbolContextSymbol)    && m_sc.symbol == NULL)
387                     m_sc.symbol = sc.symbol;
388                 if ((resolved & eSymbolContextLineEntry) && !m_sc.line_entry.IsValid())
389                     m_sc.line_entry = sc.line_entry;
390 
391             }
392         }
393         else
394         {
395             // If we don't have a module, then we can't have the compile unit,
396             // function, block, line entry or symbol, so we can safely call
397             // ResolveSymbolContextForAddress with our symbol context member m_sc.
398             resolved |= m_thread.GetProcess().GetTarget().GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc);
399         }
400 
401         // If the target was requested add that:
402         if (m_sc.target_sp.get() == NULL)
403         {
404             m_sc.target_sp = CalculateProcess()->GetTarget().GetSP();
405             if (m_sc.target_sp)
406                 resolved |= eSymbolContextTarget;
407         }
408 
409         // Update our internal flags so we remember what we have tried to locate so
410         // we don't have to keep trying when more calls to this function are made.
411         // We might have dug up more information that was requested (for example
412         // if we were asked to only get the block, we will have gotten the
413         // compile unit, and function) so set any additional bits that we resolved
414         m_flags.Set (resolve_scope | resolved);
415     }
416 
417     // Return the symbol context with everything that was possible to resolve
418     // resolved.
419     return m_sc;
420 }
421 
422 
423 VariableList *
424 StackFrame::GetVariableList (bool get_file_globals)
425 {
426     if (m_flags.IsClear(RESOLVED_VARIABLES))
427     {
428         m_flags.Set(RESOLVED_VARIABLES);
429 
430         GetSymbolContext (eSymbolContextCompUnit |
431                           eSymbolContextFunction |
432                           eSymbolContextBlock);
433 
434         if (m_sc.block)
435         {
436             bool get_child_variables = true;
437             bool can_create = true;
438             m_variable_list_sp = m_sc.function->GetBlock (can_create).GetVariableList (get_child_variables, can_create);
439         }
440 
441         if (get_file_globals && m_sc.comp_unit)
442         {
443             VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true));
444             if (m_variable_list_sp)
445                 m_variable_list_sp->AddVariables (global_variable_list_sp.get());
446             else
447                 m_variable_list_sp = global_variable_list_sp;
448         }
449     }
450     return m_variable_list_sp.get();
451 }
452 
453 
454 bool
455 StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr)
456 {
457     if (m_flags.IsClear(GOT_FRAME_BASE))
458     {
459         if (m_sc.function)
460         {
461             m_frame_base.Clear();
462             m_frame_base_error.Clear();
463 
464             m_flags.Set(GOT_FRAME_BASE);
465             ExecutionContext exe_ctx (&m_thread.GetProcess(), &m_thread, this);
466             Value expr_value;
467             if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, NULL, expr_value, &m_frame_base_error) < 0)
468             {
469                 // We should really have an error if evaluate returns, but in case
470                 // we don't, lets set the error to something at least.
471                 if (m_frame_base_error.Success())
472                     m_frame_base_error.SetErrorString("Evaluation of the frame base expression failed.");
473             }
474             else
475             {
476                 m_frame_base = expr_value.ResolveValue(&exe_ctx, NULL);
477             }
478         }
479         else
480         {
481             m_frame_base_error.SetErrorString ("No function in symbol context.");
482         }
483     }
484 
485     if (m_frame_base_error.Success())
486         frame_base = m_frame_base;
487 
488     if (error_ptr)
489         *error_ptr = m_frame_base_error;
490     return m_frame_base_error.Success();
491 }
492 
493 RegisterContext *
494 StackFrame::GetRegisterContext ()
495 {
496     if (m_reg_context_sp.get() == NULL)
497         m_reg_context_sp.reset (m_thread.CreateRegisterContextForFrame (this));
498     return m_reg_context_sp.get();
499 }
500 
501 bool
502 StackFrame::HasDebugInformation ()
503 {
504     GetSymbolContext (eSymbolContextLineEntry);
505     return m_sc.line_entry.IsValid();
506 }
507 
508 
509 ValueObjectSP
510 StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp)
511 {
512     ValueObjectSP valobj_sp;
513     VariableList *var_list = GetVariableList (true);
514     if (var_list)
515     {
516         // Make sure the variable is a frame variable
517         const uint32_t var_idx = var_list->FindIndexForVariable (variable_sp.get());
518         const uint32_t num_variables = var_list->GetSize();
519         if (var_idx < num_variables)
520         {
521             valobj_sp = m_variable_list_value_objects.GetValueObjectAtIndex (var_idx);
522             if (valobj_sp.get() == NULL)
523             {
524                 if (m_variable_list_value_objects.GetSize() < num_variables)
525                     m_variable_list_value_objects.Resize(num_variables);
526                 valobj_sp.reset (new ValueObjectVariable (variable_sp));
527                 m_variable_list_value_objects.SetValueObjectAtIndex (var_idx, valobj_sp);
528             }
529         }
530     }
531     return valobj_sp;
532 }
533 
534 ValueObjectSP
535 StackFrame::TrackGlobalVariable (const VariableSP &variable_sp)
536 {
537     // Check to make sure we aren't already tracking this variable?
538     ValueObjectSP valobj_sp (GetValueObjectForFrameVariable (variable_sp));
539     if (!valobj_sp)
540     {
541         // We aren't already tracking this global
542         VariableList *var_list = GetVariableList (true);
543         // If this frame has no variables, create a new list
544         if (var_list == NULL)
545             m_variable_list_sp.reset (new VariableList());
546 
547         // Add the global/static variable to this frame
548         m_variable_list_sp->AddVariable (variable_sp);
549 
550         // Now make a value object for it so we can track its changes
551         valobj_sp = GetValueObjectForFrameVariable (variable_sp);
552     }
553     return valobj_sp;
554 }
555 
556 bool
557 StackFrame::IsInlined ()
558 {
559     if (m_sc.block == NULL)
560         GetSymbolContext (eSymbolContextBlock);
561     if (m_sc.block)
562         return m_sc.block->GetContainingInlinedBlock() != NULL;
563     return false;
564 }
565 
566 Target *
567 StackFrame::CalculateTarget ()
568 {
569     return m_thread.CalculateTarget();
570 }
571 
572 Process *
573 StackFrame::CalculateProcess ()
574 {
575     return m_thread.CalculateProcess();
576 }
577 
578 Thread *
579 StackFrame::CalculateThread ()
580 {
581     return &m_thread;
582 }
583 
584 StackFrame *
585 StackFrame::CalculateStackFrame ()
586 {
587     return this;
588 }
589 
590 
591 void
592 StackFrame::Calculate (ExecutionContext &exe_ctx)
593 {
594     m_thread.Calculate (exe_ctx);
595     exe_ctx.frame = this;
596 }
597 
598 void
599 StackFrame::Dump (Stream *strm, bool show_frame_index, bool show_fullpaths)
600 {
601     if (strm == NULL)
602         return;
603 
604     if (show_frame_index)
605         strm->Printf("frame #%u: ", m_frame_index);
606     strm->Printf("0x%0*llx ", m_thread.GetProcess().GetAddressByteSize() * 2, GetFrameCodeAddress().GetLoadAddress(&m_thread.GetProcess()));
607     GetSymbolContext(eSymbolContextEverything);
608     const bool show_module = true;
609     const bool show_inline = true;
610     m_sc.DumpStopContext(strm, &m_thread.GetProcess(), GetFrameCodeAddress(), show_fullpaths, show_module, show_inline);
611 }
612 
613 void
614 StackFrame::UpdateCurrentFrameFromPreviousFrame (StackFrame &prev_frame)
615 {
616     assert (GetStackID() == prev_frame.GetStackID());    // TODO: remove this after some testing
617     m_variable_list_sp = prev_frame.m_variable_list_sp;
618     m_variable_list_value_objects.Swap (prev_frame.m_variable_list_value_objects);
619     if (!m_disassembly.GetString().empty())
620         m_disassembly.GetString().swap (m_disassembly.GetString());
621 }
622 
623 
624 void
625 StackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame)
626 {
627     assert (GetStackID() == curr_frame.GetStackID());        // TODO: remove this after some testing
628     m_id.SetPC (curr_frame.m_id.GetPC());       // Update the Stack ID PC value
629     assert (&m_thread == &curr_frame.m_thread);
630     m_frame_index = curr_frame.m_frame_index;
631     m_unwind_frame_index = curr_frame.m_unwind_frame_index;
632     m_reg_context_sp = curr_frame.m_reg_context_sp;
633     m_frame_code_addr = curr_frame.m_frame_code_addr;
634     assert (m_sc.target_sp.get() == NULL || curr_frame.m_sc.target_sp.get() == NULL || m_sc.target_sp.get() == curr_frame.m_sc.target_sp.get());
635     assert (m_sc.module_sp.get() == NULL || curr_frame.m_sc.module_sp.get() == NULL || m_sc.module_sp.get() == curr_frame.m_sc.module_sp.get());
636     assert (m_sc.comp_unit == NULL || curr_frame.m_sc.comp_unit == NULL || m_sc.comp_unit == curr_frame.m_sc.comp_unit);
637     assert (m_sc.function == NULL || curr_frame.m_sc.function == NULL || m_sc.function == curr_frame.m_sc.function);
638     m_sc = curr_frame.m_sc;
639     m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything);
640     m_flags.Set (m_sc.GetResolvedMask());
641     m_frame_base.Clear();
642     m_frame_base_error.Clear();
643 }
644 
645 
646 bool
647 StackFrame::HasCachedData () const
648 {
649     if (m_variable_list_sp.get())
650         return true;
651     if (m_variable_list_value_objects.GetSize() > 0)
652         return true;
653     if (!m_disassembly.GetString().empty())
654         return true;
655     return false;
656 }