blob: e90c73895ca75ee2e49384d7bb4f418e4718522f [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
Greg Claytone2c5e452010-09-13 04:34:30 +0000139 Module *pc_module = pc_addr.GetModule();
140 if (m_sc.module_sp.get() == NULL || m_sc.module_sp.get() != pc_module)
Greg Clayton33ed1702010-08-24 00:45:41 +0000141 {
Greg Clayton33ed1702010-08-24 00:45:41 +0000142 if (pc_module)
143 {
144 m_sc.module_sp = pc_module->GetSP();
145 m_flags.Set (eSymbolContextModule);
146 }
Greg Claytone2c5e452010-09-13 04:34:30 +0000147 else
148 {
149 m_sc.module_sp.reset();
150 }
151
Greg Clayton33ed1702010-08-24 00:45:41 +0000152 }
Chris Lattner24943d22010-06-08 16:52:24 +0000153}
154
155
156//----------------------------------------------------------------------
157// Destructor
158//----------------------------------------------------------------------
159StackFrame::~StackFrame()
160{
161}
162
163StackID&
164StackFrame::GetStackID()
165{
Greg Clayton72b71582010-09-02 21:44:10 +0000166 // Make sure we have resolved the StackID object's symbol context scope if
167 // we already haven't looked it up.
Chris Lattner24943d22010-06-08 16:52:24 +0000168
Greg Clayton4fb08152010-08-30 18:11:35 +0000169 if (m_flags.IsClear (RESOLVED_FRAME_ID_SYMBOL_SCOPE))
170 {
Greg Clayton5205f0b2010-09-03 17:10:42 +0000171 if (m_id.GetSymbolContextScope ())
Greg Clayton4fb08152010-08-30 18:11:35 +0000172 {
Greg Clayton69aa5d92010-09-07 04:20:48 +0000173 // We already have a symbol context scope, we just don't have our
174 // flag bit set.
Greg Clayton4fb08152010-08-30 18:11:35 +0000175 m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE);
176 }
177 else
178 {
Greg Clayton69aa5d92010-09-07 04:20:48 +0000179 // Calculate the frame block and use this for the stack ID symbol
180 // context scope if we have one.
181 SymbolContextScope *scope = GetFrameBlock ();
182 if (scope == NULL)
Greg Clayton4fb08152010-08-30 18:11:35 +0000183 {
Greg Clayton69aa5d92010-09-07 04:20:48 +0000184 // We don't have a block, so use the symbol
185 if (m_flags.IsClear (eSymbolContextSymbol))
186 GetSymbolContext (eSymbolContextSymbol);
187
188 // It is ok if m_sc.symbol is NULL here
189 scope = m_sc.symbol;
Greg Clayton4fb08152010-08-30 18:11:35 +0000190 }
Greg Clayton69aa5d92010-09-07 04:20:48 +0000191 // Set the symbol context scope (the accessor will set the
192 // RESOLVED_FRAME_ID_SYMBOL_SCOPE bit in m_flags).
193 SetSymbolContextScope (scope);
Greg Clayton4fb08152010-08-30 18:11:35 +0000194 }
Chris Lattner24943d22010-06-08 16:52:24 +0000195 }
196 return m_id;
197}
198
Greg Clayton4fb08152010-08-30 18:11:35 +0000199void
200StackFrame::SetSymbolContextScope (SymbolContextScope *symbol_scope)
201{
202 m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE);
203 m_id.SetSymbolContextScope (symbol_scope);
204}
205
Chris Lattner24943d22010-06-08 16:52:24 +0000206Address&
Greg Claytonb04e7a82010-08-24 21:05:24 +0000207StackFrame::GetFrameCodeAddress()
Chris Lattner24943d22010-06-08 16:52:24 +0000208{
Greg Clayton4fb08152010-08-30 18:11:35 +0000209 if (m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR) && !m_frame_code_addr.IsSectionOffset())
Chris Lattner24943d22010-06-08 16:52:24 +0000210 {
Greg Clayton4fb08152010-08-30 18:11:35 +0000211 m_flags.Set (RESOLVED_FRAME_CODE_ADDR);
Chris Lattner24943d22010-06-08 16:52:24 +0000212
213 // Resolve the PC into a temporary address because if ResolveLoadAddress
214 // fails to resolve the address, it will clear the address object...
215 Address resolved_pc;
Greg Clayton65124ea2010-08-26 22:05:43 +0000216 if (m_thread.GetProcess().ResolveLoadAddress(m_frame_code_addr.GetOffset(), resolved_pc))
Chris Lattner24943d22010-06-08 16:52:24 +0000217 {
Greg Clayton65124ea2010-08-26 22:05:43 +0000218 m_frame_code_addr = resolved_pc;
219 const Section *section = m_frame_code_addr.GetSection();
Chris Lattner24943d22010-06-08 16:52:24 +0000220 if (section)
221 {
222 Module *module = section->GetModule();
223 if (module)
224 {
225 m_sc.module_sp = module->GetSP();
226 if (m_sc.module_sp)
227 m_flags.Set(eSymbolContextModule);
228 }
229 }
230 }
231 }
Greg Clayton65124ea2010-08-26 22:05:43 +0000232 return m_frame_code_addr;
Chris Lattner24943d22010-06-08 16:52:24 +0000233}
234
235void
236StackFrame::ChangePC (addr_t pc)
237{
Greg Clayton65124ea2010-08-26 22:05:43 +0000238 m_frame_code_addr.SetOffset(pc);
239 m_frame_code_addr.SetSection(NULL);
Chris Lattner24943d22010-06-08 16:52:24 +0000240 m_sc.Clear();
241 m_flags.SetAllFlagBits(0);
242 m_thread.ClearStackFrames ();
243}
244
245const char *
246StackFrame::Disassemble ()
247{
248 if (m_disassembly.GetSize() == 0)
249 {
250 ExecutionContext exe_ctx;
251 Calculate(exe_ctx);
Greg Clayton63094e02010-06-23 01:19:29 +0000252 Target &target = m_thread.GetProcess().GetTarget();
253 Disassembler::Disassemble (target.GetDebugger(),
254 target.GetArchitecture(),
Chris Lattner24943d22010-06-08 16:52:24 +0000255 exe_ctx,
256 0,
Greg Clayton70436352010-06-30 23:03:03 +0000257 false,
Chris Lattner24943d22010-06-08 16:52:24 +0000258 m_disassembly);
259 if (m_disassembly.GetSize() == 0)
260 return NULL;
261 }
262 return m_disassembly.GetData();
263}
264
Greg Clayton69aa5d92010-09-07 04:20:48 +0000265Block *
266StackFrame::GetFrameBlock ()
267{
268 if (m_sc.block == NULL && m_flags.IsClear (eSymbolContextBlock))
269 GetSymbolContext (eSymbolContextBlock);
270
271 if (m_sc.block)
272 {
273 Block *inline_block = m_sc.block->GetContainingInlinedBlock();
274 if (inline_block)
275 {
276 // Use the block with the inlined function info
277 // as the frame block we want this frame to have only the variables
278 // for the inlined function and its non-inlined block child blocks.
279 return inline_block;
280 }
281 else
282 {
283 // This block is not contained withing any inlined function blocks
284 // with so we want to use the top most function block.
285 return &m_sc.function->GetBlock (false);
286 }
287 }
288 return NULL;
289}
290
Chris Lattner24943d22010-06-08 16:52:24 +0000291//----------------------------------------------------------------------
292// Get the symbol context if we already haven't done so by resolving the
293// PC address as much as possible. This way when we pass around a
294// StackFrame object, everyone will have as much information as
295// possible and no one will ever have to look things up manually.
296//----------------------------------------------------------------------
297const SymbolContext&
298StackFrame::GetSymbolContext (uint32_t resolve_scope)
299{
300 // Copy our internal symbol context into "sc".
Chris Lattner24943d22010-06-08 16:52:24 +0000301 if ((m_flags.GetAllFlagBits() & resolve_scope) != resolve_scope)
302 {
303 // Resolve our PC to section offset if we haven't alreday done so
304 // and if we don't have a module. The resolved address section will
305 // contain the module to which it belongs
Greg Clayton4fb08152010-08-30 18:11:35 +0000306 if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR))
Greg Claytonb04e7a82010-08-24 21:05:24 +0000307 GetFrameCodeAddress();
Chris Lattner24943d22010-06-08 16:52:24 +0000308
309 // If this is not frame zero, then we need to subtract 1 from the PC
310 // value when doing address lookups since the PC will be on the
311 // instruction following the function call instruction...
312
Greg Claytonb04e7a82010-08-24 21:05:24 +0000313 Address lookup_addr(GetFrameCodeAddress());
Greg Clayton33ed1702010-08-24 00:45:41 +0000314 if (m_frame_index > 0 && lookup_addr.IsValid())
Chris Lattner24943d22010-06-08 16:52:24 +0000315 {
316 addr_t offset = lookup_addr.GetOffset();
317 if (offset > 0)
318 lookup_addr.SetOffset(offset - 1);
319 }
320
Greg Claytonb04e7a82010-08-24 21:05:24 +0000321
322 uint32_t resolved = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000323 if (m_sc.module_sp)
324 {
325 // We have something in our stack frame symbol context, lets check
326 // if we haven't already tried to lookup one of those things. If we
327 // haven't then we will do the query.
Greg Clayton33ed1702010-08-24 00:45:41 +0000328
329 uint32_t actual_resolve_scope = 0;
330
331 if (resolve_scope & eSymbolContextCompUnit)
332 {
333 if (m_flags.IsClear (eSymbolContextCompUnit))
334 {
335 if (m_sc.comp_unit)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000336 resolved |= eSymbolContextCompUnit;
Greg Clayton33ed1702010-08-24 00:45:41 +0000337 else
338 actual_resolve_scope |= eSymbolContextCompUnit;
339 }
340 }
341
342 if (resolve_scope & eSymbolContextFunction)
343 {
344 if (m_flags.IsClear (eSymbolContextFunction))
345 {
346 if (m_sc.function)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000347 resolved |= eSymbolContextFunction;
Greg Clayton33ed1702010-08-24 00:45:41 +0000348 else
349 actual_resolve_scope |= eSymbolContextFunction;
350 }
351 }
352
353 if (resolve_scope & eSymbolContextBlock)
354 {
355 if (m_flags.IsClear (eSymbolContextBlock))
356 {
357 if (m_sc.block)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000358 resolved |= eSymbolContextBlock;
Greg Clayton33ed1702010-08-24 00:45:41 +0000359 else
360 actual_resolve_scope |= eSymbolContextBlock;
361 }
362 }
363
364 if (resolve_scope & eSymbolContextSymbol)
365 {
366 if (m_flags.IsClear (eSymbolContextSymbol))
367 {
368 if (m_sc.symbol)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000369 resolved |= eSymbolContextSymbol;
Greg Clayton33ed1702010-08-24 00:45:41 +0000370 else
371 actual_resolve_scope |= eSymbolContextSymbol;
372 }
373 }
374
375 if (resolve_scope & eSymbolContextLineEntry)
376 {
377 if (m_flags.IsClear (eSymbolContextLineEntry))
378 {
379 if (m_sc.line_entry.IsValid())
Greg Claytonb04e7a82010-08-24 21:05:24 +0000380 resolved |= eSymbolContextLineEntry;
Greg Clayton33ed1702010-08-24 00:45:41 +0000381 else
382 actual_resolve_scope |= eSymbolContextLineEntry;
383 }
384 }
385
386 if (actual_resolve_scope)
Chris Lattner24943d22010-06-08 16:52:24 +0000387 {
388 // We might be resolving less information than what is already
389 // in our current symbol context so resolve into a temporary
390 // symbol context "sc" so we don't clear out data we have
391 // already found in "m_sc"
392 SymbolContext sc;
393 // Set flags that indicate what we have tried to resolve
Greg Claytonb04e7a82010-08-24 21:05:24 +0000394 resolved |= m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, actual_resolve_scope, sc);
Greg Clayton33ed1702010-08-24 00:45:41 +0000395 // Only replace what we didn't already have as we may have
396 // information for an inlined function scope that won't match
397 // what a standard lookup by address would match
Greg Claytonb04e7a82010-08-24 21:05:24 +0000398 if ((resolved & eSymbolContextCompUnit) && m_sc.comp_unit == NULL)
399 m_sc.comp_unit = sc.comp_unit;
400 if ((resolved & eSymbolContextFunction) && m_sc.function == NULL)
401 m_sc.function = sc.function;
402 if ((resolved & eSymbolContextBlock) && m_sc.block == NULL)
403 m_sc.block = sc.block;
404 if ((resolved & eSymbolContextSymbol) && m_sc.symbol == NULL)
405 m_sc.symbol = sc.symbol;
406 if ((resolved & eSymbolContextLineEntry) && !m_sc.line_entry.IsValid())
407 m_sc.line_entry = sc.line_entry;
408
Chris Lattner24943d22010-06-08 16:52:24 +0000409 }
410 }
411 else
412 {
413 // If we don't have a module, then we can't have the compile unit,
414 // function, block, line entry or symbol, so we can safely call
415 // ResolveSymbolContextForAddress with our symbol context member m_sc.
Greg Claytonb04e7a82010-08-24 21:05:24 +0000416 resolved |= m_thread.GetProcess().GetTarget().GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc);
Chris Lattner24943d22010-06-08 16:52:24 +0000417 }
418
419 // If the target was requested add that:
420 if (m_sc.target_sp.get() == NULL)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000421 {
Chris Lattner24943d22010-06-08 16:52:24 +0000422 m_sc.target_sp = CalculateProcess()->GetTarget().GetSP();
Greg Claytonb04e7a82010-08-24 21:05:24 +0000423 if (m_sc.target_sp)
424 resolved |= eSymbolContextTarget;
425 }
Chris Lattner24943d22010-06-08 16:52:24 +0000426
427 // Update our internal flags so we remember what we have tried to locate so
428 // we don't have to keep trying when more calls to this function are made.
Greg Claytonb04e7a82010-08-24 21:05:24 +0000429 // We might have dug up more information that was requested (for example
430 // if we were asked to only get the block, we will have gotten the
431 // compile unit, and function) so set any additional bits that we resolved
432 m_flags.Set (resolve_scope | resolved);
Chris Lattner24943d22010-06-08 16:52:24 +0000433 }
434
435 // Return the symbol context with everything that was possible to resolve
436 // resolved.
437 return m_sc;
438}
439
440
441VariableList *
Greg Clayton17dae082010-09-02 02:59:18 +0000442StackFrame::GetVariableList (bool get_file_globals)
Chris Lattner24943d22010-06-08 16:52:24 +0000443{
444 if (m_flags.IsClear(RESOLVED_VARIABLES))
445 {
446 m_flags.Set(RESOLVED_VARIABLES);
447
Greg Clayton69aa5d92010-09-07 04:20:48 +0000448 Block *frame_block = GetFrameBlock();
449
450 if (frame_block)
Chris Lattner24943d22010-06-08 16:52:24 +0000451 {
Greg Clayton69aa5d92010-09-07 04:20:48 +0000452 const bool get_child_variables = true;
453 const bool can_create = true;
454 m_variable_list_sp = frame_block->GetVariableList (get_child_variables, can_create);
Chris Lattner24943d22010-06-08 16:52:24 +0000455 }
Greg Clayton17dae082010-09-02 02:59:18 +0000456
Greg Clayton69aa5d92010-09-07 04:20:48 +0000457 if (get_file_globals)
Greg Clayton17dae082010-09-02 02:59:18 +0000458 {
Greg Clayton69aa5d92010-09-07 04:20:48 +0000459 if (m_flags.IsClear (eSymbolContextCompUnit))
460 GetSymbolContext (eSymbolContextCompUnit);
461
462 if (m_sc.comp_unit)
463 {
464 VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true));
465 if (m_variable_list_sp)
466 m_variable_list_sp->AddVariables (global_variable_list_sp.get());
467 else
468 m_variable_list_sp = global_variable_list_sp;
469 }
Greg Clayton17dae082010-09-02 02:59:18 +0000470 }
Chris Lattner24943d22010-06-08 16:52:24 +0000471 }
472 return m_variable_list_sp.get();
473}
474
475
476bool
477StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr)
478{
479 if (m_flags.IsClear(GOT_FRAME_BASE))
480 {
481 if (m_sc.function)
482 {
483 m_frame_base.Clear();
484 m_frame_base_error.Clear();
485
486 m_flags.Set(GOT_FRAME_BASE);
487 ExecutionContext exe_ctx (&m_thread.GetProcess(), &m_thread, this);
488 Value expr_value;
Greg Clayton178710c2010-09-14 02:20:48 +0000489 addr_t loclist_base_addr = LLDB_INVALID_ADDRESS;
490 if (m_sc.function->GetFrameBaseExpression().IsLocationList())
491 loclist_base_addr = m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (&m_thread.GetProcess());
492
493 if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, loclist_base_addr, NULL, expr_value, &m_frame_base_error) == false)
Chris Lattner24943d22010-06-08 16:52:24 +0000494 {
495 // We should really have an error if evaluate returns, but in case
496 // we don't, lets set the error to something at least.
497 if (m_frame_base_error.Success())
498 m_frame_base_error.SetErrorString("Evaluation of the frame base expression failed.");
499 }
500 else
501 {
502 m_frame_base = expr_value.ResolveValue(&exe_ctx, NULL);
503 }
504 }
505 else
506 {
507 m_frame_base_error.SetErrorString ("No function in symbol context.");
508 }
509 }
510
511 if (m_frame_base_error.Success())
512 frame_base = m_frame_base;
513
514 if (error_ptr)
515 *error_ptr = m_frame_base_error;
516 return m_frame_base_error.Success();
517}
518
519RegisterContext *
520StackFrame::GetRegisterContext ()
521{
522 if (m_reg_context_sp.get() == NULL)
523 m_reg_context_sp.reset (m_thread.CreateRegisterContextForFrame (this));
524 return m_reg_context_sp.get();
525}
526
527bool
528StackFrame::HasDebugInformation ()
529{
Greg Claytonb04e7a82010-08-24 21:05:24 +0000530 GetSymbolContext (eSymbolContextLineEntry);
Chris Lattner24943d22010-06-08 16:52:24 +0000531 return m_sc.line_entry.IsValid();
532}
533
Greg Clayton17dae082010-09-02 02:59:18 +0000534
535ValueObjectSP
536StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000537{
Greg Clayton17dae082010-09-02 02:59:18 +0000538 ValueObjectSP valobj_sp;
539 VariableList *var_list = GetVariableList (true);
540 if (var_list)
541 {
542 // Make sure the variable is a frame variable
543 const uint32_t var_idx = var_list->FindIndexForVariable (variable_sp.get());
544 const uint32_t num_variables = var_list->GetSize();
545 if (var_idx < num_variables)
546 {
547 valobj_sp = m_variable_list_value_objects.GetValueObjectAtIndex (var_idx);
548 if (valobj_sp.get() == NULL)
549 {
550 if (m_variable_list_value_objects.GetSize() < num_variables)
551 m_variable_list_value_objects.Resize(num_variables);
552 valobj_sp.reset (new ValueObjectVariable (variable_sp));
553 m_variable_list_value_objects.SetValueObjectAtIndex (var_idx, valobj_sp);
554 }
555 }
556 }
557 return valobj_sp;
558}
559
560ValueObjectSP
561StackFrame::TrackGlobalVariable (const VariableSP &variable_sp)
562{
563 // Check to make sure we aren't already tracking this variable?
564 ValueObjectSP valobj_sp (GetValueObjectForFrameVariable (variable_sp));
565 if (!valobj_sp)
566 {
567 // We aren't already tracking this global
568 VariableList *var_list = GetVariableList (true);
569 // If this frame has no variables, create a new list
570 if (var_list == NULL)
571 m_variable_list_sp.reset (new VariableList());
572
573 // Add the global/static variable to this frame
574 m_variable_list_sp->AddVariable (variable_sp);
575
576 // Now make a value object for it so we can track its changes
577 valobj_sp = GetValueObjectForFrameVariable (variable_sp);
578 }
579 return valobj_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000580}
581
Jim Ingham2154da42010-08-26 20:44:45 +0000582bool
583StackFrame::IsInlined ()
584{
Greg Clayton4fb08152010-08-30 18:11:35 +0000585 if (m_sc.block == NULL)
586 GetSymbolContext (eSymbolContextBlock);
587 if (m_sc.block)
588 return m_sc.block->GetContainingInlinedBlock() != NULL;
589 return false;
Jim Ingham2154da42010-08-26 20:44:45 +0000590}
591
Chris Lattner24943d22010-06-08 16:52:24 +0000592Target *
593StackFrame::CalculateTarget ()
594{
595 return m_thread.CalculateTarget();
596}
597
598Process *
599StackFrame::CalculateProcess ()
600{
601 return m_thread.CalculateProcess();
602}
603
604Thread *
605StackFrame::CalculateThread ()
606{
607 return &m_thread;
608}
609
610StackFrame *
611StackFrame::CalculateStackFrame ()
612{
613 return this;
614}
615
616
617void
618StackFrame::Calculate (ExecutionContext &exe_ctx)
619{
620 m_thread.Calculate (exe_ctx);
621 exe_ctx.frame = this;
622}
623
624void
Greg Clayton72b71582010-09-02 21:44:10 +0000625StackFrame::Dump (Stream *strm, bool show_frame_index, bool show_fullpaths)
Chris Lattner24943d22010-06-08 16:52:24 +0000626{
627 if (strm == NULL)
628 return;
629
630 if (show_frame_index)
Greg Clayton33ed1702010-08-24 00:45:41 +0000631 strm->Printf("frame #%u: ", m_frame_index);
Greg Clayton72b71582010-09-02 21:44:10 +0000632 strm->Printf("0x%0*llx ", m_thread.GetProcess().GetAddressByteSize() * 2, GetFrameCodeAddress().GetLoadAddress(&m_thread.GetProcess()));
Greg Claytonb04e7a82010-08-24 21:05:24 +0000633 GetSymbolContext(eSymbolContextEverything);
Greg Clayton33ed1702010-08-24 00:45:41 +0000634 const bool show_module = true;
635 const bool show_inline = true;
Greg Clayton72b71582010-09-02 21:44:10 +0000636 m_sc.DumpStopContext(strm, &m_thread.GetProcess(), GetFrameCodeAddress(), show_fullpaths, show_module, show_inline);
Chris Lattner24943d22010-06-08 16:52:24 +0000637}
638
Greg Clayton1d66ef52010-08-27 18:24:16 +0000639void
Greg Clayton4fb08152010-08-30 18:11:35 +0000640StackFrame::UpdateCurrentFrameFromPreviousFrame (StackFrame &prev_frame)
Greg Clayton1d66ef52010-08-27 18:24:16 +0000641{
Greg Clayton4fb08152010-08-30 18:11:35 +0000642 assert (GetStackID() == prev_frame.GetStackID()); // TODO: remove this after some testing
643 m_variable_list_sp = prev_frame.m_variable_list_sp;
Greg Clayton17dae082010-09-02 02:59:18 +0000644 m_variable_list_value_objects.Swap (prev_frame.m_variable_list_value_objects);
Greg Clayton870a1cd2010-08-27 21:47:54 +0000645 if (!m_disassembly.GetString().empty())
646 m_disassembly.GetString().swap (m_disassembly.GetString());
Greg Clayton1d66ef52010-08-27 18:24:16 +0000647}
Greg Clayton870a1cd2010-08-27 21:47:54 +0000648
649
Greg Clayton4fb08152010-08-30 18:11:35 +0000650void
651StackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame)
652{
Greg Clayton5205f0b2010-09-03 17:10:42 +0000653 assert (GetStackID() == curr_frame.GetStackID()); // TODO: remove this after some testing
654 m_id.SetPC (curr_frame.m_id.GetPC()); // Update the Stack ID PC value
Greg Clayton4fb08152010-08-30 18:11:35 +0000655 assert (&m_thread == &curr_frame.m_thread);
656 m_frame_index = curr_frame.m_frame_index;
657 m_unwind_frame_index = curr_frame.m_unwind_frame_index;
658 m_reg_context_sp = curr_frame.m_reg_context_sp;
659 m_frame_code_addr = curr_frame.m_frame_code_addr;
660 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());
661 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());
662 assert (m_sc.comp_unit == NULL || curr_frame.m_sc.comp_unit == NULL || m_sc.comp_unit == curr_frame.m_sc.comp_unit);
663 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 +0000664 m_sc = curr_frame.m_sc;
665 m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything);
666 m_flags.Set (m_sc.GetResolvedMask());
667 m_frame_base.Clear();
668 m_frame_base_error.Clear();
669}
670
671
Greg Clayton5205f0b2010-09-03 17:10:42 +0000672bool
673StackFrame::HasCachedData () const
674{
675 if (m_variable_list_sp.get())
676 return true;
677 if (m_variable_list_value_objects.GetSize() > 0)
678 return true;
679 if (!m_disassembly.GetString().empty())
680 return true;
681 return false;
682}