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