blob: 5237bbe63be5c39d33696f422b9b11c2238a357e [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- 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"
Greg Clayton17dae082010-09-02 02:59:18 +000019#include "lldb/Core/ValueObjectVariable.h"
Chris Lattner24943d22010-06-08 16:52:24 +000020#include "lldb/Symbol/Function.h"
Greg Clayton17dae082010-09-02 02:59:18 +000021#include "lldb/Symbol/VariableList.h"
Chris Lattner24943d22010-06-08 16:52:24 +000022#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
28using namespace lldb;
29using 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.
Greg Clayton4fb08152010-08-30 18:11:35 +000034#define RESOLVED_FRAME_CODE_ADDR (uint32_t(eSymbolContextEverything + 1))
Greg Clayton72b71582010-09-02 21:44:10 +000035#define RESOLVED_FRAME_ID_SYMBOL_SCOPE (RESOLVED_FRAME_CODE_ADDR << 1)
Greg Clayton4fb08152010-08-30 18:11:35 +000036#define GOT_FRAME_BASE (RESOLVED_FRAME_ID_SYMBOL_SCOPE << 1)
37#define RESOLVED_VARIABLES (GOT_FRAME_BASE << 1)
Chris Lattner24943d22010-06-08 16:52:24 +000038
Greg Clayton33ed1702010-08-24 00:45:41 +000039StackFrame::StackFrame
40(
41 lldb::user_id_t frame_idx,
Greg Clayton4fb08152010-08-30 18:11:35 +000042 lldb::user_id_t unwind_frame_index,
Greg Clayton33ed1702010-08-24 00:45:41 +000043 Thread &thread,
44 lldb::addr_t cfa,
Greg Clayton33ed1702010-08-24 00:45:41 +000045 lldb::addr_t pc,
46 const SymbolContext *sc_ptr
47) :
48 m_frame_index (frame_idx),
Greg Clayton4fb08152010-08-30 18:11:35 +000049 m_unwind_frame_index (unwind_frame_index),
Chris Lattner24943d22010-06-08 16:52:24 +000050 m_thread (thread),
Greg Clayton33ed1702010-08-24 00:45:41 +000051 m_reg_context_sp (),
Greg Clayton72b71582010-09-02 21:44:10 +000052 m_id (pc, cfa, NULL),
Greg Clayton65124ea2010-08-26 22:05:43 +000053 m_frame_code_addr (NULL, pc),
Greg Clayton33ed1702010-08-24 00:45:41 +000054 m_sc (),
55 m_flags (),
56 m_frame_base (),
57 m_frame_base_error (),
Chris Lattner24943d22010-06-08 16:52:24 +000058 m_variable_list_sp (),
Greg Clayton17dae082010-09-02 02:59:18 +000059 m_variable_list_value_objects ()
Chris Lattner24943d22010-06-08 16:52:24 +000060{
61 if (sc_ptr != NULL)
Greg Clayton33ed1702010-08-24 00:45:41 +000062 {
Chris Lattner24943d22010-06-08 16:52:24 +000063 m_sc = *sc_ptr;
Greg Clayton33ed1702010-08-24 00:45:41 +000064 m_flags.Set(m_sc.GetResolvedMask ());
65 }
Chris Lattner24943d22010-06-08 16:52:24 +000066}
67
Greg Clayton33ed1702010-08-24 00:45:41 +000068StackFrame::StackFrame
69(
70 lldb::user_id_t frame_idx,
Greg Clayton4fb08152010-08-30 18:11:35 +000071 lldb::user_id_t unwind_frame_index,
Greg Clayton33ed1702010-08-24 00:45:41 +000072 Thread &thread,
73 const RegisterContextSP &reg_context_sp,
74 lldb::addr_t cfa,
Greg Clayton33ed1702010-08-24 00:45:41 +000075 lldb::addr_t pc,
76 const SymbolContext *sc_ptr
77) :
78 m_frame_index (frame_idx),
Greg Clayton4fb08152010-08-30 18:11:35 +000079 m_unwind_frame_index (unwind_frame_index),
Chris Lattner24943d22010-06-08 16:52:24 +000080 m_thread (thread),
Greg Clayton33ed1702010-08-24 00:45:41 +000081 m_reg_context_sp (reg_context_sp),
Greg Clayton72b71582010-09-02 21:44:10 +000082 m_id (pc, cfa, NULL),
Greg Clayton65124ea2010-08-26 22:05:43 +000083 m_frame_code_addr (NULL, pc),
Greg Clayton33ed1702010-08-24 00:45:41 +000084 m_sc (),
85 m_flags (),
86 m_frame_base (),
87 m_frame_base_error (),
Chris Lattner24943d22010-06-08 16:52:24 +000088 m_variable_list_sp (),
Greg Clayton17dae082010-09-02 02:59:18 +000089 m_variable_list_value_objects ()
Chris Lattner24943d22010-06-08 16:52:24 +000090{
91 if (sc_ptr != NULL)
Greg Clayton33ed1702010-08-24 00:45:41 +000092 {
Chris Lattner24943d22010-06-08 16:52:24 +000093 m_sc = *sc_ptr;
Greg Clayton33ed1702010-08-24 00:45:41 +000094 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
104StackFrame::StackFrame
105(
106 lldb::user_id_t frame_idx,
Greg Clayton4fb08152010-08-30 18:11:35 +0000107 lldb::user_id_t unwind_frame_index,
Greg Clayton33ed1702010-08-24 00:45:41 +0000108 Thread &thread,
109 const RegisterContextSP &reg_context_sp,
110 lldb::addr_t cfa,
Greg Clayton33ed1702010-08-24 00:45:41 +0000111 const Address& pc_addr,
112 const SymbolContext *sc_ptr
113) :
114 m_frame_index (frame_idx),
Greg Clayton4fb08152010-08-30 18:11:35 +0000115 m_unwind_frame_index (unwind_frame_index),
Greg Clayton33ed1702010-08-24 00:45:41 +0000116 m_thread (thread),
117 m_reg_context_sp (reg_context_sp),
Greg Clayton72b71582010-09-02 21:44:10 +0000118 m_id (pc_addr.GetLoadAddress (&thread.GetProcess()), cfa, NULL),
Greg Clayton65124ea2010-08-26 22:05:43 +0000119 m_frame_code_addr (pc_addr),
Greg Clayton33ed1702010-08-24 00:45:41 +0000120 m_sc (),
121 m_flags (),
122 m_frame_base (),
123 m_frame_base_error (),
124 m_variable_list_sp (),
Greg Clayton17dae082010-09-02 02:59:18 +0000125 m_variable_list_value_objects ()
Greg Clayton33ed1702010-08-24 00:45:41 +0000126{
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 }
Chris Lattner24943d22010-06-08 16:52:24 +0000148}
149
150
151//----------------------------------------------------------------------
152// Destructor
153//----------------------------------------------------------------------
154StackFrame::~StackFrame()
155{
156}
157
158StackID&
159StackFrame::GetStackID()
160{
Greg Clayton72b71582010-09-02 21:44:10 +0000161 // Make sure we have resolved the StackID object's symbol context scope if
162 // we already haven't looked it up.
Chris Lattner24943d22010-06-08 16:52:24 +0000163
Greg Clayton4fb08152010-08-30 18:11:35 +0000164 if (m_flags.IsClear (RESOLVED_FRAME_ID_SYMBOL_SCOPE))
165 {
Greg Clayton5205f0b2010-09-03 17:10:42 +0000166 if (m_id.GetSymbolContextScope ())
Greg Clayton4fb08152010-08-30 18:11:35 +0000167 {
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 }
Chris Lattner24943d22010-06-08 16:52:24 +0000203 }
204 return m_id;
205}
206
Greg Clayton4fb08152010-08-30 18:11:35 +0000207void
208StackFrame::SetSymbolContextScope (SymbolContextScope *symbol_scope)
209{
210 m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE);
211 m_id.SetSymbolContextScope (symbol_scope);
212}
213
Chris Lattner24943d22010-06-08 16:52:24 +0000214Address&
Greg Claytonb04e7a82010-08-24 21:05:24 +0000215StackFrame::GetFrameCodeAddress()
Chris Lattner24943d22010-06-08 16:52:24 +0000216{
Greg Clayton4fb08152010-08-30 18:11:35 +0000217 if (m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR) && !m_frame_code_addr.IsSectionOffset())
Chris Lattner24943d22010-06-08 16:52:24 +0000218 {
Greg Clayton4fb08152010-08-30 18:11:35 +0000219 m_flags.Set (RESOLVED_FRAME_CODE_ADDR);
Chris Lattner24943d22010-06-08 16:52:24 +0000220
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;
Greg Clayton65124ea2010-08-26 22:05:43 +0000224 if (m_thread.GetProcess().ResolveLoadAddress(m_frame_code_addr.GetOffset(), resolved_pc))
Chris Lattner24943d22010-06-08 16:52:24 +0000225 {
Greg Clayton65124ea2010-08-26 22:05:43 +0000226 m_frame_code_addr = resolved_pc;
227 const Section *section = m_frame_code_addr.GetSection();
Chris Lattner24943d22010-06-08 16:52:24 +0000228 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 }
Greg Clayton65124ea2010-08-26 22:05:43 +0000240 return m_frame_code_addr;
Chris Lattner24943d22010-06-08 16:52:24 +0000241}
242
243void
244StackFrame::ChangePC (addr_t pc)
245{
Greg Clayton65124ea2010-08-26 22:05:43 +0000246 m_frame_code_addr.SetOffset(pc);
247 m_frame_code_addr.SetSection(NULL);
Chris Lattner24943d22010-06-08 16:52:24 +0000248 m_sc.Clear();
249 m_flags.SetAllFlagBits(0);
250 m_thread.ClearStackFrames ();
251}
252
253const char *
254StackFrame::Disassemble ()
255{
256 if (m_disassembly.GetSize() == 0)
257 {
258 ExecutionContext exe_ctx;
259 Calculate(exe_ctx);
Greg Clayton63094e02010-06-23 01:19:29 +0000260 Target &target = m_thread.GetProcess().GetTarget();
261 Disassembler::Disassemble (target.GetDebugger(),
262 target.GetArchitecture(),
Chris Lattner24943d22010-06-08 16:52:24 +0000263 exe_ctx,
264 0,
Greg Clayton70436352010-06-30 23:03:03 +0000265 false,
Chris Lattner24943d22010-06-08 16:52:24 +0000266 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//----------------------------------------------------------------------
279const SymbolContext&
280StackFrame::GetSymbolContext (uint32_t resolve_scope)
281{
282 // Copy our internal symbol context into "sc".
Chris Lattner24943d22010-06-08 16:52:24 +0000283 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
Greg Clayton4fb08152010-08-30 18:11:35 +0000288 if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR))
Greg Claytonb04e7a82010-08-24 21:05:24 +0000289 GetFrameCodeAddress();
Chris Lattner24943d22010-06-08 16:52:24 +0000290
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
Greg Claytonb04e7a82010-08-24 21:05:24 +0000295 Address lookup_addr(GetFrameCodeAddress());
Greg Clayton33ed1702010-08-24 00:45:41 +0000296 if (m_frame_index > 0 && lookup_addr.IsValid())
Chris Lattner24943d22010-06-08 16:52:24 +0000297 {
298 addr_t offset = lookup_addr.GetOffset();
299 if (offset > 0)
300 lookup_addr.SetOffset(offset - 1);
301 }
302
Greg Claytonb04e7a82010-08-24 21:05:24 +0000303
304 uint32_t resolved = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000305 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.
Greg Clayton33ed1702010-08-24 00:45:41 +0000310
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)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000318 resolved |= eSymbolContextCompUnit;
Greg Clayton33ed1702010-08-24 00:45:41 +0000319 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)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000329 resolved |= eSymbolContextFunction;
Greg Clayton33ed1702010-08-24 00:45:41 +0000330 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)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000340 resolved |= eSymbolContextBlock;
Greg Clayton33ed1702010-08-24 00:45:41 +0000341 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)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000351 resolved |= eSymbolContextSymbol;
Greg Clayton33ed1702010-08-24 00:45:41 +0000352 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())
Greg Claytonb04e7a82010-08-24 21:05:24 +0000362 resolved |= eSymbolContextLineEntry;
Greg Clayton33ed1702010-08-24 00:45:41 +0000363 else
364 actual_resolve_scope |= eSymbolContextLineEntry;
365 }
366 }
367
368 if (actual_resolve_scope)
Chris Lattner24943d22010-06-08 16:52:24 +0000369 {
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
Greg Claytonb04e7a82010-08-24 21:05:24 +0000376 resolved |= m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, actual_resolve_scope, sc);
Greg Clayton33ed1702010-08-24 00:45:41 +0000377 // 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
Greg Claytonb04e7a82010-08-24 21:05:24 +0000380 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
Chris Lattner24943d22010-06-08 16:52:24 +0000391 }
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.
Greg Claytonb04e7a82010-08-24 21:05:24 +0000398 resolved |= m_thread.GetProcess().GetTarget().GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc);
Chris Lattner24943d22010-06-08 16:52:24 +0000399 }
400
401 // If the target was requested add that:
402 if (m_sc.target_sp.get() == NULL)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000403 {
Chris Lattner24943d22010-06-08 16:52:24 +0000404 m_sc.target_sp = CalculateProcess()->GetTarget().GetSP();
Greg Claytonb04e7a82010-08-24 21:05:24 +0000405 if (m_sc.target_sp)
406 resolved |= eSymbolContextTarget;
407 }
Chris Lattner24943d22010-06-08 16:52:24 +0000408
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.
Greg Claytonb04e7a82010-08-24 21:05:24 +0000411 // 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);
Chris Lattner24943d22010-06-08 16:52:24 +0000415 }
416
417 // Return the symbol context with everything that was possible to resolve
418 // resolved.
419 return m_sc;
420}
421
422
423VariableList *
Greg Clayton17dae082010-09-02 02:59:18 +0000424StackFrame::GetVariableList (bool get_file_globals)
Chris Lattner24943d22010-06-08 16:52:24 +0000425{
426 if (m_flags.IsClear(RESOLVED_VARIABLES))
427 {
428 m_flags.Set(RESOLVED_VARIABLES);
429
Greg Clayton17dae082010-09-02 02:59:18 +0000430 GetSymbolContext (eSymbolContextCompUnit |
431 eSymbolContextFunction |
432 eSymbolContextBlock);
433
434 if (m_sc.block)
Chris Lattner24943d22010-06-08 16:52:24 +0000435 {
436 bool get_child_variables = true;
437 bool can_create = true;
Greg Clayton75ccf502010-08-21 02:22:51 +0000438 m_variable_list_sp = m_sc.function->GetBlock (can_create).GetVariableList (get_child_variables, can_create);
Chris Lattner24943d22010-06-08 16:52:24 +0000439 }
Greg Clayton17dae082010-09-02 02:59:18 +0000440
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 }
Chris Lattner24943d22010-06-08 16:52:24 +0000449 }
450 return m_variable_list_sp.get();
451}
452
453
454bool
455StackFrame::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
493RegisterContext *
494StackFrame::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
501bool
502StackFrame::HasDebugInformation ()
503{
Greg Claytonb04e7a82010-08-24 21:05:24 +0000504 GetSymbolContext (eSymbolContextLineEntry);
Chris Lattner24943d22010-06-08 16:52:24 +0000505 return m_sc.line_entry.IsValid();
506}
507
Greg Clayton17dae082010-09-02 02:59:18 +0000508
509ValueObjectSP
510StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000511{
Greg Clayton17dae082010-09-02 02:59:18 +0000512 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
534ValueObjectSP
535StackFrame::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;
Chris Lattner24943d22010-06-08 16:52:24 +0000554}
555
Jim Ingham2154da42010-08-26 20:44:45 +0000556bool
557StackFrame::IsInlined ()
558{
Greg Clayton4fb08152010-08-30 18:11:35 +0000559 if (m_sc.block == NULL)
560 GetSymbolContext (eSymbolContextBlock);
561 if (m_sc.block)
562 return m_sc.block->GetContainingInlinedBlock() != NULL;
563 return false;
Jim Ingham2154da42010-08-26 20:44:45 +0000564}
565
Chris Lattner24943d22010-06-08 16:52:24 +0000566Target *
567StackFrame::CalculateTarget ()
568{
569 return m_thread.CalculateTarget();
570}
571
572Process *
573StackFrame::CalculateProcess ()
574{
575 return m_thread.CalculateProcess();
576}
577
578Thread *
579StackFrame::CalculateThread ()
580{
581 return &m_thread;
582}
583
584StackFrame *
585StackFrame::CalculateStackFrame ()
586{
587 return this;
588}
589
590
591void
592StackFrame::Calculate (ExecutionContext &exe_ctx)
593{
594 m_thread.Calculate (exe_ctx);
595 exe_ctx.frame = this;
596}
597
598void
Greg Clayton72b71582010-09-02 21:44:10 +0000599StackFrame::Dump (Stream *strm, bool show_frame_index, bool show_fullpaths)
Chris Lattner24943d22010-06-08 16:52:24 +0000600{
601 if (strm == NULL)
602 return;
603
604 if (show_frame_index)
Greg Clayton33ed1702010-08-24 00:45:41 +0000605 strm->Printf("frame #%u: ", m_frame_index);
Greg Clayton72b71582010-09-02 21:44:10 +0000606 strm->Printf("0x%0*llx ", m_thread.GetProcess().GetAddressByteSize() * 2, GetFrameCodeAddress().GetLoadAddress(&m_thread.GetProcess()));
Greg Claytonb04e7a82010-08-24 21:05:24 +0000607 GetSymbolContext(eSymbolContextEverything);
Greg Clayton33ed1702010-08-24 00:45:41 +0000608 const bool show_module = true;
609 const bool show_inline = true;
Greg Clayton72b71582010-09-02 21:44:10 +0000610 m_sc.DumpStopContext(strm, &m_thread.GetProcess(), GetFrameCodeAddress(), show_fullpaths, show_module, show_inline);
Chris Lattner24943d22010-06-08 16:52:24 +0000611}
612
Greg Clayton1d66ef52010-08-27 18:24:16 +0000613void
Greg Clayton4fb08152010-08-30 18:11:35 +0000614StackFrame::UpdateCurrentFrameFromPreviousFrame (StackFrame &prev_frame)
Greg Clayton1d66ef52010-08-27 18:24:16 +0000615{
Greg Clayton4fb08152010-08-30 18:11:35 +0000616 assert (GetStackID() == prev_frame.GetStackID()); // TODO: remove this after some testing
617 m_variable_list_sp = prev_frame.m_variable_list_sp;
Greg Clayton17dae082010-09-02 02:59:18 +0000618 m_variable_list_value_objects.Swap (prev_frame.m_variable_list_value_objects);
Greg Clayton870a1cd2010-08-27 21:47:54 +0000619 if (!m_disassembly.GetString().empty())
620 m_disassembly.GetString().swap (m_disassembly.GetString());
Greg Clayton1d66ef52010-08-27 18:24:16 +0000621}
Greg Clayton870a1cd2010-08-27 21:47:54 +0000622
623
Greg Clayton4fb08152010-08-30 18:11:35 +0000624void
625StackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame)
626{
Greg Clayton5205f0b2010-09-03 17:10:42 +0000627 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
Greg Clayton4fb08152010-08-30 18:11:35 +0000629 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);
Greg Clayton4fb08152010-08-30 18:11:35 +0000638 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
Greg Clayton5205f0b2010-09-03 17:10:42 +0000646bool
647StackFrame::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}