blob: f812285e775538aab7f00cb8ef805cce4819ece3 [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))
35#define RESOLVED_FRAME_ID_START_ADDR (RESOLVED_FRAME_CODE_ADDR << 1)
36#define RESOLVED_FRAME_ID_SYMBOL_SCOPE (RESOLVED_FRAME_ID_START_ADDR << 1)
37#define GOT_FRAME_BASE (RESOLVED_FRAME_ID_SYMBOL_SCOPE << 1)
38#define RESOLVED_VARIABLES (GOT_FRAME_BASE << 1)
Chris Lattner24943d22010-06-08 16:52:24 +000039
Greg Clayton33ed1702010-08-24 00:45:41 +000040StackFrame::StackFrame
41(
42 lldb::user_id_t frame_idx,
Greg Clayton4fb08152010-08-30 18:11:35 +000043 lldb::user_id_t unwind_frame_index,
Greg Clayton33ed1702010-08-24 00:45:41 +000044 Thread &thread,
45 lldb::addr_t cfa,
Greg Clayton33ed1702010-08-24 00:45:41 +000046 lldb::addr_t pc,
47 const SymbolContext *sc_ptr
48) :
49 m_frame_index (frame_idx),
Greg Clayton4fb08152010-08-30 18:11:35 +000050 m_unwind_frame_index (unwind_frame_index),
Chris Lattner24943d22010-06-08 16:52:24 +000051 m_thread (thread),
Greg Clayton33ed1702010-08-24 00:45:41 +000052 m_reg_context_sp (),
Greg Clayton4fb08152010-08-30 18:11:35 +000053 m_id (LLDB_INVALID_ADDRESS, cfa, NULL),
Greg Clayton65124ea2010-08-26 22:05:43 +000054 m_frame_code_addr (NULL, pc),
Greg Clayton33ed1702010-08-24 00:45:41 +000055 m_sc (),
56 m_flags (),
57 m_frame_base (),
58 m_frame_base_error (),
Chris Lattner24943d22010-06-08 16:52:24 +000059 m_variable_list_sp (),
Greg Clayton17dae082010-09-02 02:59:18 +000060 m_variable_list_value_objects ()
Chris Lattner24943d22010-06-08 16:52:24 +000061{
62 if (sc_ptr != NULL)
Greg Clayton33ed1702010-08-24 00:45:41 +000063 {
Chris Lattner24943d22010-06-08 16:52:24 +000064 m_sc = *sc_ptr;
Greg Clayton33ed1702010-08-24 00:45:41 +000065 m_flags.Set(m_sc.GetResolvedMask ());
66 }
Chris Lattner24943d22010-06-08 16:52:24 +000067}
68
Greg Clayton33ed1702010-08-24 00:45:41 +000069StackFrame::StackFrame
70(
71 lldb::user_id_t frame_idx,
Greg Clayton4fb08152010-08-30 18:11:35 +000072 lldb::user_id_t unwind_frame_index,
Greg Clayton33ed1702010-08-24 00:45:41 +000073 Thread &thread,
74 const RegisterContextSP &reg_context_sp,
75 lldb::addr_t cfa,
Greg Clayton33ed1702010-08-24 00:45:41 +000076 lldb::addr_t pc,
77 const SymbolContext *sc_ptr
78) :
79 m_frame_index (frame_idx),
Greg Clayton4fb08152010-08-30 18:11:35 +000080 m_unwind_frame_index (unwind_frame_index),
Chris Lattner24943d22010-06-08 16:52:24 +000081 m_thread (thread),
Greg Clayton33ed1702010-08-24 00:45:41 +000082 m_reg_context_sp (reg_context_sp),
Greg Clayton4fb08152010-08-30 18:11:35 +000083 m_id (LLDB_INVALID_ADDRESS, cfa, NULL),
Greg Clayton65124ea2010-08-26 22:05:43 +000084 m_frame_code_addr (NULL, pc),
Greg Clayton33ed1702010-08-24 00:45:41 +000085 m_sc (),
86 m_flags (),
87 m_frame_base (),
88 m_frame_base_error (),
Chris Lattner24943d22010-06-08 16:52:24 +000089 m_variable_list_sp (),
Greg Clayton17dae082010-09-02 02:59:18 +000090 m_variable_list_value_objects ()
Chris Lattner24943d22010-06-08 16:52:24 +000091{
92 if (sc_ptr != NULL)
Greg Clayton33ed1702010-08-24 00:45:41 +000093 {
Chris Lattner24943d22010-06-08 16:52:24 +000094 m_sc = *sc_ptr;
Greg Clayton33ed1702010-08-24 00:45:41 +000095 m_flags.Set(m_sc.GetResolvedMask ());
96 }
97
98 if (reg_context_sp && !m_sc.target_sp)
99 {
100 m_sc.target_sp = reg_context_sp->GetThread().GetProcess().GetTarget().GetSP();
101 m_flags.Set (eSymbolContextTarget);
102 }
103}
104
105StackFrame::StackFrame
106(
107 lldb::user_id_t frame_idx,
Greg Clayton4fb08152010-08-30 18:11:35 +0000108 lldb::user_id_t unwind_frame_index,
Greg Clayton33ed1702010-08-24 00:45:41 +0000109 Thread &thread,
110 const RegisterContextSP &reg_context_sp,
111 lldb::addr_t cfa,
Greg Clayton33ed1702010-08-24 00:45:41 +0000112 const Address& pc_addr,
113 const SymbolContext *sc_ptr
114) :
115 m_frame_index (frame_idx),
Greg Clayton4fb08152010-08-30 18:11:35 +0000116 m_unwind_frame_index (unwind_frame_index),
Greg Clayton33ed1702010-08-24 00:45:41 +0000117 m_thread (thread),
118 m_reg_context_sp (reg_context_sp),
Greg Clayton4fb08152010-08-30 18:11:35 +0000119 m_id (LLDB_INVALID_ADDRESS, cfa, NULL),
Greg Clayton65124ea2010-08-26 22:05:43 +0000120 m_frame_code_addr (pc_addr),
Greg Clayton33ed1702010-08-24 00:45:41 +0000121 m_sc (),
122 m_flags (),
123 m_frame_base (),
124 m_frame_base_error (),
125 m_variable_list_sp (),
Greg Clayton17dae082010-09-02 02:59:18 +0000126 m_variable_list_value_objects ()
Greg Clayton33ed1702010-08-24 00:45:41 +0000127{
128 if (sc_ptr != NULL)
129 {
130 m_sc = *sc_ptr;
131 m_flags.Set(m_sc.GetResolvedMask ());
132 }
133
134 if (m_sc.target_sp.get() == NULL && reg_context_sp)
135 {
136 m_sc.target_sp = reg_context_sp->GetThread().GetProcess().GetTarget().GetSP();
137 m_flags.Set (eSymbolContextTarget);
138 }
139
140 if (m_sc.module_sp.get() == NULL && pc_addr.GetSection())
141 {
142 Module *pc_module = pc_addr.GetSection()->GetModule();
143 if (pc_module)
144 {
145 m_sc.module_sp = pc_module->GetSP();
146 m_flags.Set (eSymbolContextModule);
147 }
148 }
Chris Lattner24943d22010-06-08 16:52:24 +0000149}
150
151
152//----------------------------------------------------------------------
153// Destructor
154//----------------------------------------------------------------------
155StackFrame::~StackFrame()
156{
157}
158
159StackID&
160StackFrame::GetStackID()
161{
Greg Clayton65124ea2010-08-26 22:05:43 +0000162 // Make sure we have resolved our stack ID's start PC before we give
163 // it out to any external clients. This allows us to not have to lookup
164 // this information if it is never asked for.
Greg Clayton4fb08152010-08-30 18:11:35 +0000165 if (m_flags.IsClear(RESOLVED_FRAME_ID_START_ADDR))
Chris Lattner24943d22010-06-08 16:52:24 +0000166 {
Greg Clayton4fb08152010-08-30 18:11:35 +0000167 m_flags.Set (RESOLVED_FRAME_ID_START_ADDR);
Chris Lattner24943d22010-06-08 16:52:24 +0000168
Greg Clayton65124ea2010-08-26 22:05:43 +0000169 if (m_id.GetStartAddress() == LLDB_INVALID_ADDRESS)
Greg Clayton4fb08152010-08-30 18:11:35 +0000170 {
171 // Resolve our PC to section offset if we haven't alreday done so
172 // and if we don't have a module. The resolved address section will
173 // contain the module to which it belongs.
174 if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR))
175 GetFrameCodeAddress();
176
177 if (GetSymbolContext (eSymbolContextFunction).function)
178 {
179 m_id.SetStartAddress (m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (&m_thread.GetProcess()));
180 }
181 else if (GetSymbolContext (eSymbolContextSymbol).symbol)
182 {
183 AddressRange *symbol_range_ptr = m_sc.symbol->GetAddressRangePtr();
184 if (symbol_range_ptr)
185 m_id.SetStartAddress(symbol_range_ptr->GetBaseAddress().GetLoadAddress (&m_thread.GetProcess()));
186 }
187
188 // We didn't find a function or symbol, just use the frame code address
189 // which will be the same as the PC in the frame.
190 if (m_id.GetStartAddress() == LLDB_INVALID_ADDRESS)
191 m_id.SetStartAddress (m_frame_code_addr.GetLoadAddress (&m_thread.GetProcess()));
192 }
193 }
194
195 if (m_flags.IsClear (RESOLVED_FRAME_ID_SYMBOL_SCOPE))
196 {
197 if (m_id.GetSymbolContextScope ())
198 {
199 m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE);
200 }
201 else
202 {
203 GetSymbolContext (eSymbolContextFunction | eSymbolContextBlock);
204
205 if (m_sc.block)
206 {
207 Block *inline_block = m_sc.block->GetContainingInlinedBlock();
208 if (inline_block)
209 {
210 // Use the block with the inlined function info
211 // as the symbol context since we want this frame
212 // to have only the variables for the inlined function
213 SetSymbolContextScope (inline_block);
214 }
215 else
216 {
217 // This block is not inlined with means it has no
218 // inlined parents either, so we want to use the top
219 // most function block.
220 SetSymbolContextScope (&m_sc.function->GetBlock(false));
221 }
222 }
223 else
224 {
225 // The current stack frame doesn't have a block. Check to see
226 // if it has a symbol. If it does we will use this as the
227 // symbol scope. It is ok if "m_sc.symbol" is NULL below as
228 // it will set the symbol context to NULL and set the
229 // RESOLVED_FRAME_ID_SYMBOL_SCOPE flag bit.
230 GetSymbolContext (eSymbolContextSymbol);
231 SetSymbolContextScope (m_sc.symbol);
232 }
233 }
Chris Lattner24943d22010-06-08 16:52:24 +0000234 }
235 return m_id;
236}
237
Greg Clayton4fb08152010-08-30 18:11:35 +0000238void
239StackFrame::SetSymbolContextScope (SymbolContextScope *symbol_scope)
240{
241 m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE);
242 m_id.SetSymbolContextScope (symbol_scope);
243}
244
Chris Lattner24943d22010-06-08 16:52:24 +0000245Address&
Greg Claytonb04e7a82010-08-24 21:05:24 +0000246StackFrame::GetFrameCodeAddress()
Chris Lattner24943d22010-06-08 16:52:24 +0000247{
Greg Clayton4fb08152010-08-30 18:11:35 +0000248 if (m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR) && !m_frame_code_addr.IsSectionOffset())
Chris Lattner24943d22010-06-08 16:52:24 +0000249 {
Greg Clayton4fb08152010-08-30 18:11:35 +0000250 m_flags.Set (RESOLVED_FRAME_CODE_ADDR);
Chris Lattner24943d22010-06-08 16:52:24 +0000251
252 // Resolve the PC into a temporary address because if ResolveLoadAddress
253 // fails to resolve the address, it will clear the address object...
254 Address resolved_pc;
Greg Clayton65124ea2010-08-26 22:05:43 +0000255 if (m_thread.GetProcess().ResolveLoadAddress(m_frame_code_addr.GetOffset(), resolved_pc))
Chris Lattner24943d22010-06-08 16:52:24 +0000256 {
Greg Clayton65124ea2010-08-26 22:05:43 +0000257 m_frame_code_addr = resolved_pc;
258 const Section *section = m_frame_code_addr.GetSection();
Chris Lattner24943d22010-06-08 16:52:24 +0000259 if (section)
260 {
261 Module *module = section->GetModule();
262 if (module)
263 {
264 m_sc.module_sp = module->GetSP();
265 if (m_sc.module_sp)
266 m_flags.Set(eSymbolContextModule);
267 }
268 }
269 }
270 }
Greg Clayton65124ea2010-08-26 22:05:43 +0000271 return m_frame_code_addr;
Chris Lattner24943d22010-06-08 16:52:24 +0000272}
273
274void
275StackFrame::ChangePC (addr_t pc)
276{
Greg Clayton65124ea2010-08-26 22:05:43 +0000277 m_frame_code_addr.SetOffset(pc);
278 m_frame_code_addr.SetSection(NULL);
Chris Lattner24943d22010-06-08 16:52:24 +0000279 m_sc.Clear();
280 m_flags.SetAllFlagBits(0);
281 m_thread.ClearStackFrames ();
282}
283
284const char *
285StackFrame::Disassemble ()
286{
287 if (m_disassembly.GetSize() == 0)
288 {
289 ExecutionContext exe_ctx;
290 Calculate(exe_ctx);
Greg Clayton63094e02010-06-23 01:19:29 +0000291 Target &target = m_thread.GetProcess().GetTarget();
292 Disassembler::Disassemble (target.GetDebugger(),
293 target.GetArchitecture(),
Chris Lattner24943d22010-06-08 16:52:24 +0000294 exe_ctx,
295 0,
Greg Clayton70436352010-06-30 23:03:03 +0000296 false,
Chris Lattner24943d22010-06-08 16:52:24 +0000297 m_disassembly);
298 if (m_disassembly.GetSize() == 0)
299 return NULL;
300 }
301 return m_disassembly.GetData();
302}
303
304//----------------------------------------------------------------------
305// Get the symbol context if we already haven't done so by resolving the
306// PC address as much as possible. This way when we pass around a
307// StackFrame object, everyone will have as much information as
308// possible and no one will ever have to look things up manually.
309//----------------------------------------------------------------------
310const SymbolContext&
311StackFrame::GetSymbolContext (uint32_t resolve_scope)
312{
313 // Copy our internal symbol context into "sc".
Chris Lattner24943d22010-06-08 16:52:24 +0000314 if ((m_flags.GetAllFlagBits() & resolve_scope) != resolve_scope)
315 {
316 // Resolve our PC to section offset if we haven't alreday done so
317 // and if we don't have a module. The resolved address section will
318 // contain the module to which it belongs
Greg Clayton4fb08152010-08-30 18:11:35 +0000319 if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR))
Greg Claytonb04e7a82010-08-24 21:05:24 +0000320 GetFrameCodeAddress();
Chris Lattner24943d22010-06-08 16:52:24 +0000321
322 // If this is not frame zero, then we need to subtract 1 from the PC
323 // value when doing address lookups since the PC will be on the
324 // instruction following the function call instruction...
325
Greg Claytonb04e7a82010-08-24 21:05:24 +0000326 Address lookup_addr(GetFrameCodeAddress());
Greg Clayton33ed1702010-08-24 00:45:41 +0000327 if (m_frame_index > 0 && lookup_addr.IsValid())
Chris Lattner24943d22010-06-08 16:52:24 +0000328 {
329 addr_t offset = lookup_addr.GetOffset();
330 if (offset > 0)
331 lookup_addr.SetOffset(offset - 1);
332 }
333
Greg Claytonb04e7a82010-08-24 21:05:24 +0000334
335 uint32_t resolved = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000336 if (m_sc.module_sp)
337 {
338 // We have something in our stack frame symbol context, lets check
339 // if we haven't already tried to lookup one of those things. If we
340 // haven't then we will do the query.
Greg Clayton33ed1702010-08-24 00:45:41 +0000341
342 uint32_t actual_resolve_scope = 0;
343
344 if (resolve_scope & eSymbolContextCompUnit)
345 {
346 if (m_flags.IsClear (eSymbolContextCompUnit))
347 {
348 if (m_sc.comp_unit)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000349 resolved |= eSymbolContextCompUnit;
Greg Clayton33ed1702010-08-24 00:45:41 +0000350 else
351 actual_resolve_scope |= eSymbolContextCompUnit;
352 }
353 }
354
355 if (resolve_scope & eSymbolContextFunction)
356 {
357 if (m_flags.IsClear (eSymbolContextFunction))
358 {
359 if (m_sc.function)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000360 resolved |= eSymbolContextFunction;
Greg Clayton33ed1702010-08-24 00:45:41 +0000361 else
362 actual_resolve_scope |= eSymbolContextFunction;
363 }
364 }
365
366 if (resolve_scope & eSymbolContextBlock)
367 {
368 if (m_flags.IsClear (eSymbolContextBlock))
369 {
370 if (m_sc.block)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000371 resolved |= eSymbolContextBlock;
Greg Clayton33ed1702010-08-24 00:45:41 +0000372 else
373 actual_resolve_scope |= eSymbolContextBlock;
374 }
375 }
376
377 if (resolve_scope & eSymbolContextSymbol)
378 {
379 if (m_flags.IsClear (eSymbolContextSymbol))
380 {
381 if (m_sc.symbol)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000382 resolved |= eSymbolContextSymbol;
Greg Clayton33ed1702010-08-24 00:45:41 +0000383 else
384 actual_resolve_scope |= eSymbolContextSymbol;
385 }
386 }
387
388 if (resolve_scope & eSymbolContextLineEntry)
389 {
390 if (m_flags.IsClear (eSymbolContextLineEntry))
391 {
392 if (m_sc.line_entry.IsValid())
Greg Claytonb04e7a82010-08-24 21:05:24 +0000393 resolved |= eSymbolContextLineEntry;
Greg Clayton33ed1702010-08-24 00:45:41 +0000394 else
395 actual_resolve_scope |= eSymbolContextLineEntry;
396 }
397 }
398
399 if (actual_resolve_scope)
Chris Lattner24943d22010-06-08 16:52:24 +0000400 {
401 // We might be resolving less information than what is already
402 // in our current symbol context so resolve into a temporary
403 // symbol context "sc" so we don't clear out data we have
404 // already found in "m_sc"
405 SymbolContext sc;
406 // Set flags that indicate what we have tried to resolve
Greg Claytonb04e7a82010-08-24 21:05:24 +0000407 resolved |= m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, actual_resolve_scope, sc);
Greg Clayton33ed1702010-08-24 00:45:41 +0000408 // Only replace what we didn't already have as we may have
409 // information for an inlined function scope that won't match
410 // what a standard lookup by address would match
Greg Claytonb04e7a82010-08-24 21:05:24 +0000411 if ((resolved & eSymbolContextCompUnit) && m_sc.comp_unit == NULL)
412 m_sc.comp_unit = sc.comp_unit;
413 if ((resolved & eSymbolContextFunction) && m_sc.function == NULL)
414 m_sc.function = sc.function;
415 if ((resolved & eSymbolContextBlock) && m_sc.block == NULL)
416 m_sc.block = sc.block;
417 if ((resolved & eSymbolContextSymbol) && m_sc.symbol == NULL)
418 m_sc.symbol = sc.symbol;
419 if ((resolved & eSymbolContextLineEntry) && !m_sc.line_entry.IsValid())
420 m_sc.line_entry = sc.line_entry;
421
Chris Lattner24943d22010-06-08 16:52:24 +0000422 }
423 }
424 else
425 {
426 // If we don't have a module, then we can't have the compile unit,
427 // function, block, line entry or symbol, so we can safely call
428 // ResolveSymbolContextForAddress with our symbol context member m_sc.
Greg Claytonb04e7a82010-08-24 21:05:24 +0000429 resolved |= m_thread.GetProcess().GetTarget().GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc);
Chris Lattner24943d22010-06-08 16:52:24 +0000430 }
431
432 // If the target was requested add that:
433 if (m_sc.target_sp.get() == NULL)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000434 {
Chris Lattner24943d22010-06-08 16:52:24 +0000435 m_sc.target_sp = CalculateProcess()->GetTarget().GetSP();
Greg Claytonb04e7a82010-08-24 21:05:24 +0000436 if (m_sc.target_sp)
437 resolved |= eSymbolContextTarget;
438 }
Chris Lattner24943d22010-06-08 16:52:24 +0000439
440 // Update our internal flags so we remember what we have tried to locate so
441 // we don't have to keep trying when more calls to this function are made.
Greg Claytonb04e7a82010-08-24 21:05:24 +0000442 // We might have dug up more information that was requested (for example
443 // if we were asked to only get the block, we will have gotten the
444 // compile unit, and function) so set any additional bits that we resolved
445 m_flags.Set (resolve_scope | resolved);
Chris Lattner24943d22010-06-08 16:52:24 +0000446 }
447
448 // Return the symbol context with everything that was possible to resolve
449 // resolved.
450 return m_sc;
451}
452
453
454VariableList *
Greg Clayton17dae082010-09-02 02:59:18 +0000455StackFrame::GetVariableList (bool get_file_globals)
Chris Lattner24943d22010-06-08 16:52:24 +0000456{
457 if (m_flags.IsClear(RESOLVED_VARIABLES))
458 {
459 m_flags.Set(RESOLVED_VARIABLES);
460
Greg Clayton17dae082010-09-02 02:59:18 +0000461 GetSymbolContext (eSymbolContextCompUnit |
462 eSymbolContextFunction |
463 eSymbolContextBlock);
464
465 if (m_sc.block)
Chris Lattner24943d22010-06-08 16:52:24 +0000466 {
467 bool get_child_variables = true;
468 bool can_create = true;
Greg Clayton75ccf502010-08-21 02:22:51 +0000469 m_variable_list_sp = m_sc.function->GetBlock (can_create).GetVariableList (get_child_variables, can_create);
Chris Lattner24943d22010-06-08 16:52:24 +0000470 }
Greg Clayton17dae082010-09-02 02:59:18 +0000471
472 if (get_file_globals && m_sc.comp_unit)
473 {
474 VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true));
475 if (m_variable_list_sp)
476 m_variable_list_sp->AddVariables (global_variable_list_sp.get());
477 else
478 m_variable_list_sp = global_variable_list_sp;
479 }
Chris Lattner24943d22010-06-08 16:52:24 +0000480 }
481 return m_variable_list_sp.get();
482}
483
484
485bool
486StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr)
487{
488 if (m_flags.IsClear(GOT_FRAME_BASE))
489 {
490 if (m_sc.function)
491 {
492 m_frame_base.Clear();
493 m_frame_base_error.Clear();
494
495 m_flags.Set(GOT_FRAME_BASE);
496 ExecutionContext exe_ctx (&m_thread.GetProcess(), &m_thread, this);
497 Value expr_value;
498 if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, NULL, expr_value, &m_frame_base_error) < 0)
499 {
500 // We should really have an error if evaluate returns, but in case
501 // we don't, lets set the error to something at least.
502 if (m_frame_base_error.Success())
503 m_frame_base_error.SetErrorString("Evaluation of the frame base expression failed.");
504 }
505 else
506 {
507 m_frame_base = expr_value.ResolveValue(&exe_ctx, NULL);
508 }
509 }
510 else
511 {
512 m_frame_base_error.SetErrorString ("No function in symbol context.");
513 }
514 }
515
516 if (m_frame_base_error.Success())
517 frame_base = m_frame_base;
518
519 if (error_ptr)
520 *error_ptr = m_frame_base_error;
521 return m_frame_base_error.Success();
522}
523
524RegisterContext *
525StackFrame::GetRegisterContext ()
526{
527 if (m_reg_context_sp.get() == NULL)
528 m_reg_context_sp.reset (m_thread.CreateRegisterContextForFrame (this));
529 return m_reg_context_sp.get();
530}
531
532bool
533StackFrame::HasDebugInformation ()
534{
Greg Claytonb04e7a82010-08-24 21:05:24 +0000535 GetSymbolContext (eSymbolContextLineEntry);
Chris Lattner24943d22010-06-08 16:52:24 +0000536 return m_sc.line_entry.IsValid();
537}
538
Greg Clayton17dae082010-09-02 02:59:18 +0000539
540ValueObjectSP
541StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000542{
Greg Clayton17dae082010-09-02 02:59:18 +0000543 ValueObjectSP valobj_sp;
544 VariableList *var_list = GetVariableList (true);
545 if (var_list)
546 {
547 // Make sure the variable is a frame variable
548 const uint32_t var_idx = var_list->FindIndexForVariable (variable_sp.get());
549 const uint32_t num_variables = var_list->GetSize();
550 if (var_idx < num_variables)
551 {
552 valobj_sp = m_variable_list_value_objects.GetValueObjectAtIndex (var_idx);
553 if (valobj_sp.get() == NULL)
554 {
555 if (m_variable_list_value_objects.GetSize() < num_variables)
556 m_variable_list_value_objects.Resize(num_variables);
557 valobj_sp.reset (new ValueObjectVariable (variable_sp));
558 m_variable_list_value_objects.SetValueObjectAtIndex (var_idx, valobj_sp);
559 }
560 }
561 }
562 return valobj_sp;
563}
564
565ValueObjectSP
566StackFrame::TrackGlobalVariable (const VariableSP &variable_sp)
567{
568 // Check to make sure we aren't already tracking this variable?
569 ValueObjectSP valobj_sp (GetValueObjectForFrameVariable (variable_sp));
570 if (!valobj_sp)
571 {
572 // We aren't already tracking this global
573 VariableList *var_list = GetVariableList (true);
574 // If this frame has no variables, create a new list
575 if (var_list == NULL)
576 m_variable_list_sp.reset (new VariableList());
577
578 // Add the global/static variable to this frame
579 m_variable_list_sp->AddVariable (variable_sp);
580
581 // Now make a value object for it so we can track its changes
582 valobj_sp = GetValueObjectForFrameVariable (variable_sp);
583 }
584 return valobj_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000585}
586
Jim Ingham2154da42010-08-26 20:44:45 +0000587bool
588StackFrame::IsInlined ()
589{
Greg Clayton4fb08152010-08-30 18:11:35 +0000590 if (m_sc.block == NULL)
591 GetSymbolContext (eSymbolContextBlock);
592 if (m_sc.block)
593 return m_sc.block->GetContainingInlinedBlock() != NULL;
594 return false;
Jim Ingham2154da42010-08-26 20:44:45 +0000595}
596
Chris Lattner24943d22010-06-08 16:52:24 +0000597Target *
598StackFrame::CalculateTarget ()
599{
600 return m_thread.CalculateTarget();
601}
602
603Process *
604StackFrame::CalculateProcess ()
605{
606 return m_thread.CalculateProcess();
607}
608
609Thread *
610StackFrame::CalculateThread ()
611{
612 return &m_thread;
613}
614
615StackFrame *
616StackFrame::CalculateStackFrame ()
617{
618 return this;
619}
620
621
622void
623StackFrame::Calculate (ExecutionContext &exe_ctx)
624{
625 m_thread.Calculate (exe_ctx);
626 exe_ctx.frame = this;
627}
628
629void
630StackFrame::Dump (Stream *strm, bool show_frame_index)
631{
632 if (strm == NULL)
633 return;
634
635 if (show_frame_index)
Greg Clayton33ed1702010-08-24 00:45:41 +0000636 strm->Printf("frame #%u: ", m_frame_index);
Greg Claytonb04e7a82010-08-24 21:05:24 +0000637 strm->Printf("0x%0*llx", m_thread.GetProcess().GetAddressByteSize() * 2, GetFrameCodeAddress().GetLoadAddress(&m_thread.GetProcess()));
638 GetSymbolContext(eSymbolContextEverything);
Chris Lattner24943d22010-06-08 16:52:24 +0000639 strm->PutCString(", where = ");
Greg Clayton33ed1702010-08-24 00:45:41 +0000640 // TODO: need to get the
641 const bool show_module = true;
642 const bool show_inline = true;
Greg Claytonb04e7a82010-08-24 21:05:24 +0000643 m_sc.DumpStopContext(strm, &m_thread.GetProcess(), GetFrameCodeAddress(), show_module, show_inline);
Chris Lattner24943d22010-06-08 16:52:24 +0000644}
645
Greg Clayton1d66ef52010-08-27 18:24:16 +0000646void
Greg Clayton4fb08152010-08-30 18:11:35 +0000647StackFrame::UpdateCurrentFrameFromPreviousFrame (StackFrame &prev_frame)
Greg Clayton1d66ef52010-08-27 18:24:16 +0000648{
Greg Clayton4fb08152010-08-30 18:11:35 +0000649 assert (GetStackID() == prev_frame.GetStackID()); // TODO: remove this after some testing
650 m_variable_list_sp = prev_frame.m_variable_list_sp;
Greg Clayton17dae082010-09-02 02:59:18 +0000651 m_variable_list_value_objects.Swap (prev_frame.m_variable_list_value_objects);
Greg Clayton870a1cd2010-08-27 21:47:54 +0000652 if (!m_disassembly.GetString().empty())
653 m_disassembly.GetString().swap (m_disassembly.GetString());
Greg Clayton1d66ef52010-08-27 18:24:16 +0000654}
Greg Clayton870a1cd2010-08-27 21:47:54 +0000655
656
Greg Clayton4fb08152010-08-30 18:11:35 +0000657void
658StackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame)
659{
660 assert (GetStackID() == curr_frame.GetStackID()); // TODO: remove this after some testing
661 assert (&m_thread == &curr_frame.m_thread);
662 m_frame_index = curr_frame.m_frame_index;
663 m_unwind_frame_index = curr_frame.m_unwind_frame_index;
664 m_reg_context_sp = curr_frame.m_reg_context_sp;
665 m_frame_code_addr = curr_frame.m_frame_code_addr;
666 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());
667 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());
668 assert (m_sc.comp_unit == NULL || curr_frame.m_sc.comp_unit == NULL || m_sc.comp_unit == curr_frame.m_sc.comp_unit);
669 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 +0000670 m_sc = curr_frame.m_sc;
671 m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything);
672 m_flags.Set (m_sc.GetResolvedMask());
673 m_frame_base.Clear();
674 m_frame_base_error.Clear();
675}
676
677