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