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