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