blob: f5422dbb45ed41bda449d6ff0969f697c6f6d3f2 [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"
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
26using namespace lldb;
27using 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.
Greg Claytonb04e7a82010-08-24 21:05:24 +000032#define RESOLVED_FRAME_ADDR (uint32_t(eSymbolContextEverything + 1))
33#define RESOLVED_FRAME_ID (RESOLVED_FRAME_ADDR << 1)
Chris Lattner24943d22010-06-08 16:52:24 +000034#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
Greg Clayton33ed1702010-08-24 00:45:41 +000038StackFrame::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,
Greg Clayton33ed1702010-08-24 00:45:41 +000044 lldb::addr_t pc,
45 const SymbolContext *sc_ptr
46) :
47 m_frame_index (frame_idx),
48 m_concrete_frame_index (concrete_frame_index),
Chris Lattner24943d22010-06-08 16:52:24 +000049 m_thread (thread),
Greg Clayton33ed1702010-08-24 00:45:41 +000050 m_reg_context_sp (),
Greg Claytonf40e3082010-08-26 02:28:22 +000051 m_id (cfa, 0),
Greg Clayton33ed1702010-08-24 00:45:41 +000052 m_pc (NULL, pc),
53 m_sc (),
54 m_flags (),
55 m_frame_base (),
56 m_frame_base_error (),
Chris Lattner24943d22010-06-08 16:52:24 +000057 m_variable_list_sp (),
58 m_value_object_list ()
59{
60 if (sc_ptr != NULL)
Greg Clayton33ed1702010-08-24 00:45:41 +000061 {
Chris Lattner24943d22010-06-08 16:52:24 +000062 m_sc = *sc_ptr;
Greg Clayton33ed1702010-08-24 00:45:41 +000063 m_flags.Set(m_sc.GetResolvedMask ());
64 }
Chris Lattner24943d22010-06-08 16:52:24 +000065}
66
Greg Clayton33ed1702010-08-24 00:45:41 +000067StackFrame::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,
Greg Clayton33ed1702010-08-24 00:45:41 +000074 lldb::addr_t pc,
75 const SymbolContext *sc_ptr
76) :
77 m_frame_index (frame_idx),
78 m_concrete_frame_index (concrete_frame_index),
Chris Lattner24943d22010-06-08 16:52:24 +000079 m_thread (thread),
Greg Clayton33ed1702010-08-24 00:45:41 +000080 m_reg_context_sp (reg_context_sp),
Greg Claytonf40e3082010-08-26 02:28:22 +000081 m_id (cfa, 0),
Greg Clayton33ed1702010-08-24 00:45:41 +000082 m_pc (NULL, pc),
83 m_sc (),
84 m_flags (),
85 m_frame_base (),
86 m_frame_base_error (),
Chris Lattner24943d22010-06-08 16:52:24 +000087 m_variable_list_sp (),
88 m_value_object_list ()
89{
90 if (sc_ptr != NULL)
Greg Clayton33ed1702010-08-24 00:45:41 +000091 {
Chris Lattner24943d22010-06-08 16:52:24 +000092 m_sc = *sc_ptr;
Greg Clayton33ed1702010-08-24 00:45:41 +000093 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
103StackFrame::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,
Greg Clayton33ed1702010-08-24 00:45:41 +0000110 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),
Greg Claytonf40e3082010-08-26 02:28:22 +0000117 m_id (cfa, 0),
Greg Clayton33ed1702010-08-24 00:45:41 +0000118 m_pc (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 }
Chris Lattner24943d22010-06-08 16:52:24 +0000147}
148
149
150//----------------------------------------------------------------------
151// Destructor
152//----------------------------------------------------------------------
153StackFrame::~StackFrame()
154{
155}
156
157StackID&
158StackFrame::GetStackID()
159{
160 // Make sure we have resolved our stack ID's address range before we give
161 // it out to any external clients
162 if (m_id.GetStartAddress().IsValid() == 0 && m_flags.IsClear(RESOLVED_FRAME_ID))
163 {
164 m_flags.Set (RESOLVED_FRAME_ID);
165
166 // Resolve our PC to section offset if we haven't alreday done so
167 // and if we don't have a module. The resolved address section will
168 // contain the module to which it belongs.
Greg Claytonb04e7a82010-08-24 21:05:24 +0000169 if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_ADDR))
170 GetFrameCodeAddress();
Chris Lattner24943d22010-06-08 16:52:24 +0000171
Greg Claytonb04e7a82010-08-24 21:05:24 +0000172 if (GetSymbolContext (eSymbolContextFunction).function)
Chris Lattner24943d22010-06-08 16:52:24 +0000173 {
Greg Claytonb04e7a82010-08-24 21:05:24 +0000174 m_id.SetStartAddress (m_sc.function->GetAddressRange().GetBaseAddress());
Chris Lattner24943d22010-06-08 16:52:24 +0000175 }
Greg Claytonb04e7a82010-08-24 21:05:24 +0000176 else if (GetSymbolContext (eSymbolContextSymbol).symbol)
177 {
178 AddressRange *symbol_range_ptr = m_sc.symbol->GetAddressRangePtr();
179 if (symbol_range_ptr)
180 m_id.SetStartAddress(symbol_range_ptr->GetBaseAddress());
181 }
Chris Lattner24943d22010-06-08 16:52:24 +0000182 }
183 return m_id;
184}
185
186Address&
Greg Claytonb04e7a82010-08-24 21:05:24 +0000187StackFrame::GetFrameCodeAddress()
Chris Lattner24943d22010-06-08 16:52:24 +0000188{
Greg Claytonb04e7a82010-08-24 21:05:24 +0000189 if (m_flags.IsClear(RESOLVED_FRAME_ADDR) && !m_pc.IsSectionOffset())
Chris Lattner24943d22010-06-08 16:52:24 +0000190 {
Greg Claytonb04e7a82010-08-24 21:05:24 +0000191 m_flags.Set (RESOLVED_FRAME_ADDR);
Chris Lattner24943d22010-06-08 16:52:24 +0000192
193 // Resolve the PC into a temporary address because if ResolveLoadAddress
194 // fails to resolve the address, it will clear the address object...
195 Address resolved_pc;
196 if (m_thread.GetProcess().ResolveLoadAddress(m_pc.GetOffset(), resolved_pc))
197 {
198 m_pc = resolved_pc;
199 const Section *section = m_pc.GetSection();
200 if (section)
201 {
202 Module *module = section->GetModule();
203 if (module)
204 {
205 m_sc.module_sp = module->GetSP();
206 if (m_sc.module_sp)
207 m_flags.Set(eSymbolContextModule);
208 }
209 }
210 }
211 }
212 return m_pc;
213}
214
215void
216StackFrame::ChangePC (addr_t pc)
217{
218 m_pc.SetOffset(pc);
219 m_pc.SetSection(NULL);
220 m_sc.Clear();
221 m_flags.SetAllFlagBits(0);
222 m_thread.ClearStackFrames ();
223}
224
225const char *
226StackFrame::Disassemble ()
227{
228 if (m_disassembly.GetSize() == 0)
229 {
230 ExecutionContext exe_ctx;
231 Calculate(exe_ctx);
Greg Clayton63094e02010-06-23 01:19:29 +0000232 Target &target = m_thread.GetProcess().GetTarget();
233 Disassembler::Disassemble (target.GetDebugger(),
234 target.GetArchitecture(),
Chris Lattner24943d22010-06-08 16:52:24 +0000235 exe_ctx,
236 0,
Greg Clayton70436352010-06-30 23:03:03 +0000237 false,
Chris Lattner24943d22010-06-08 16:52:24 +0000238 m_disassembly);
239 if (m_disassembly.GetSize() == 0)
240 return NULL;
241 }
242 return m_disassembly.GetData();
243}
244
245//----------------------------------------------------------------------
246// Get the symbol context if we already haven't done so by resolving the
247// PC address as much as possible. This way when we pass around a
248// StackFrame object, everyone will have as much information as
249// possible and no one will ever have to look things up manually.
250//----------------------------------------------------------------------
251const SymbolContext&
252StackFrame::GetSymbolContext (uint32_t resolve_scope)
253{
254 // Copy our internal symbol context into "sc".
Chris Lattner24943d22010-06-08 16:52:24 +0000255 if ((m_flags.GetAllFlagBits() & resolve_scope) != resolve_scope)
256 {
257 // Resolve our PC to section offset if we haven't alreday done so
258 // and if we don't have a module. The resolved address section will
259 // contain the module to which it belongs
Greg Claytonb04e7a82010-08-24 21:05:24 +0000260 if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_ADDR))
261 GetFrameCodeAddress();
Chris Lattner24943d22010-06-08 16:52:24 +0000262
263 // If this is not frame zero, then we need to subtract 1 from the PC
264 // value when doing address lookups since the PC will be on the
265 // instruction following the function call instruction...
266
Greg Claytonb04e7a82010-08-24 21:05:24 +0000267 Address lookup_addr(GetFrameCodeAddress());
Greg Clayton33ed1702010-08-24 00:45:41 +0000268 if (m_frame_index > 0 && lookup_addr.IsValid())
Chris Lattner24943d22010-06-08 16:52:24 +0000269 {
270 addr_t offset = lookup_addr.GetOffset();
271 if (offset > 0)
272 lookup_addr.SetOffset(offset - 1);
273 }
274
Greg Claytonb04e7a82010-08-24 21:05:24 +0000275
276 uint32_t resolved = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000277 if (m_sc.module_sp)
278 {
279 // We have something in our stack frame symbol context, lets check
280 // if we haven't already tried to lookup one of those things. If we
281 // haven't then we will do the query.
Greg Clayton33ed1702010-08-24 00:45:41 +0000282
283 uint32_t actual_resolve_scope = 0;
284
285 if (resolve_scope & eSymbolContextCompUnit)
286 {
287 if (m_flags.IsClear (eSymbolContextCompUnit))
288 {
289 if (m_sc.comp_unit)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000290 resolved |= eSymbolContextCompUnit;
Greg Clayton33ed1702010-08-24 00:45:41 +0000291 else
292 actual_resolve_scope |= eSymbolContextCompUnit;
293 }
294 }
295
296 if (resolve_scope & eSymbolContextFunction)
297 {
298 if (m_flags.IsClear (eSymbolContextFunction))
299 {
300 if (m_sc.function)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000301 resolved |= eSymbolContextFunction;
Greg Clayton33ed1702010-08-24 00:45:41 +0000302 else
303 actual_resolve_scope |= eSymbolContextFunction;
304 }
305 }
306
307 if (resolve_scope & eSymbolContextBlock)
308 {
309 if (m_flags.IsClear (eSymbolContextBlock))
310 {
311 if (m_sc.block)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000312 resolved |= eSymbolContextBlock;
Greg Clayton33ed1702010-08-24 00:45:41 +0000313 else
314 actual_resolve_scope |= eSymbolContextBlock;
315 }
316 }
317
318 if (resolve_scope & eSymbolContextSymbol)
319 {
320 if (m_flags.IsClear (eSymbolContextSymbol))
321 {
322 if (m_sc.symbol)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000323 resolved |= eSymbolContextSymbol;
Greg Clayton33ed1702010-08-24 00:45:41 +0000324 else
325 actual_resolve_scope |= eSymbolContextSymbol;
326 }
327 }
328
329 if (resolve_scope & eSymbolContextLineEntry)
330 {
331 if (m_flags.IsClear (eSymbolContextLineEntry))
332 {
333 if (m_sc.line_entry.IsValid())
Greg Claytonb04e7a82010-08-24 21:05:24 +0000334 resolved |= eSymbolContextLineEntry;
Greg Clayton33ed1702010-08-24 00:45:41 +0000335 else
336 actual_resolve_scope |= eSymbolContextLineEntry;
337 }
338 }
339
340 if (actual_resolve_scope)
Chris Lattner24943d22010-06-08 16:52:24 +0000341 {
342 // We might be resolving less information than what is already
343 // in our current symbol context so resolve into a temporary
344 // symbol context "sc" so we don't clear out data we have
345 // already found in "m_sc"
346 SymbolContext sc;
347 // Set flags that indicate what we have tried to resolve
Greg Claytonb04e7a82010-08-24 21:05:24 +0000348 resolved |= m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, actual_resolve_scope, sc);
Greg Clayton33ed1702010-08-24 00:45:41 +0000349 // Only replace what we didn't already have as we may have
350 // information for an inlined function scope that won't match
351 // what a standard lookup by address would match
Greg Claytonb04e7a82010-08-24 21:05:24 +0000352 if ((resolved & eSymbolContextCompUnit) && m_sc.comp_unit == NULL)
353 m_sc.comp_unit = sc.comp_unit;
354 if ((resolved & eSymbolContextFunction) && m_sc.function == NULL)
355 m_sc.function = sc.function;
356 if ((resolved & eSymbolContextBlock) && m_sc.block == NULL)
357 m_sc.block = sc.block;
358 if ((resolved & eSymbolContextSymbol) && m_sc.symbol == NULL)
359 m_sc.symbol = sc.symbol;
360 if ((resolved & eSymbolContextLineEntry) && !m_sc.line_entry.IsValid())
361 m_sc.line_entry = sc.line_entry;
362
Chris Lattner24943d22010-06-08 16:52:24 +0000363 }
364 }
365 else
366 {
367 // If we don't have a module, then we can't have the compile unit,
368 // function, block, line entry or symbol, so we can safely call
369 // ResolveSymbolContextForAddress with our symbol context member m_sc.
Greg Claytonb04e7a82010-08-24 21:05:24 +0000370 resolved |= m_thread.GetProcess().GetTarget().GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc);
Chris Lattner24943d22010-06-08 16:52:24 +0000371 }
372
373 // If the target was requested add that:
374 if (m_sc.target_sp.get() == NULL)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000375 {
Chris Lattner24943d22010-06-08 16:52:24 +0000376 m_sc.target_sp = CalculateProcess()->GetTarget().GetSP();
Greg Claytonb04e7a82010-08-24 21:05:24 +0000377 if (m_sc.target_sp)
378 resolved |= eSymbolContextTarget;
379 }
Chris Lattner24943d22010-06-08 16:52:24 +0000380
381 // Update our internal flags so we remember what we have tried to locate so
382 // we don't have to keep trying when more calls to this function are made.
Greg Claytonb04e7a82010-08-24 21:05:24 +0000383 // We might have dug up more information that was requested (for example
384 // if we were asked to only get the block, we will have gotten the
385 // compile unit, and function) so set any additional bits that we resolved
386 m_flags.Set (resolve_scope | resolved);
Chris Lattner24943d22010-06-08 16:52:24 +0000387 }
388
389 // Return the symbol context with everything that was possible to resolve
390 // resolved.
391 return m_sc;
392}
393
394
395VariableList *
396StackFrame::GetVariableList ()
397{
398 if (m_flags.IsClear(RESOLVED_VARIABLES))
399 {
400 m_flags.Set(RESOLVED_VARIABLES);
401
Greg Claytonb04e7a82010-08-24 21:05:24 +0000402 if (GetSymbolContext (eSymbolContextFunction).function)
Chris Lattner24943d22010-06-08 16:52:24 +0000403 {
404 bool get_child_variables = true;
405 bool can_create = true;
Greg Clayton75ccf502010-08-21 02:22:51 +0000406 m_variable_list_sp = m_sc.function->GetBlock (can_create).GetVariableList (get_child_variables, can_create);
Chris Lattner24943d22010-06-08 16:52:24 +0000407 }
408 }
409 return m_variable_list_sp.get();
410}
411
412
413bool
414StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr)
415{
416 if (m_flags.IsClear(GOT_FRAME_BASE))
417 {
418 if (m_sc.function)
419 {
420 m_frame_base.Clear();
421 m_frame_base_error.Clear();
422
423 m_flags.Set(GOT_FRAME_BASE);
424 ExecutionContext exe_ctx (&m_thread.GetProcess(), &m_thread, this);
425 Value expr_value;
426 if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, NULL, expr_value, &m_frame_base_error) < 0)
427 {
428 // We should really have an error if evaluate returns, but in case
429 // we don't, lets set the error to something at least.
430 if (m_frame_base_error.Success())
431 m_frame_base_error.SetErrorString("Evaluation of the frame base expression failed.");
432 }
433 else
434 {
435 m_frame_base = expr_value.ResolveValue(&exe_ctx, NULL);
436 }
437 }
438 else
439 {
440 m_frame_base_error.SetErrorString ("No function in symbol context.");
441 }
442 }
443
444 if (m_frame_base_error.Success())
445 frame_base = m_frame_base;
446
447 if (error_ptr)
448 *error_ptr = m_frame_base_error;
449 return m_frame_base_error.Success();
450}
451
452RegisterContext *
453StackFrame::GetRegisterContext ()
454{
455 if (m_reg_context_sp.get() == NULL)
456 m_reg_context_sp.reset (m_thread.CreateRegisterContextForFrame (this));
457 return m_reg_context_sp.get();
458}
459
460bool
461StackFrame::HasDebugInformation ()
462{
Greg Claytonb04e7a82010-08-24 21:05:24 +0000463 GetSymbolContext (eSymbolContextLineEntry);
Chris Lattner24943d22010-06-08 16:52:24 +0000464 return m_sc.line_entry.IsValid();
465}
466
467ValueObjectList &
468StackFrame::GetValueObjectList()
469{
470 return m_value_object_list;
471}
472
Jim Ingham2154da42010-08-26 20:44:45 +0000473bool
474StackFrame::IsInlined ()
475{
476 Block *block = GetSymbolContext (eSymbolContextBlock).block;
477 if (block)
478 return block->GetContainingInlinedBlock() != NULL;
479 else
480 return false;
481}
482
Chris Lattner24943d22010-06-08 16:52:24 +0000483Target *
484StackFrame::CalculateTarget ()
485{
486 return m_thread.CalculateTarget();
487}
488
489Process *
490StackFrame::CalculateProcess ()
491{
492 return m_thread.CalculateProcess();
493}
494
495Thread *
496StackFrame::CalculateThread ()
497{
498 return &m_thread;
499}
500
501StackFrame *
502StackFrame::CalculateStackFrame ()
503{
504 return this;
505}
506
507
508void
509StackFrame::Calculate (ExecutionContext &exe_ctx)
510{
511 m_thread.Calculate (exe_ctx);
512 exe_ctx.frame = this;
513}
514
515void
516StackFrame::Dump (Stream *strm, bool show_frame_index)
517{
518 if (strm == NULL)
519 return;
520
521 if (show_frame_index)
Greg Clayton33ed1702010-08-24 00:45:41 +0000522 strm->Printf("frame #%u: ", m_frame_index);
Greg Claytonb04e7a82010-08-24 21:05:24 +0000523 strm->Printf("0x%0*llx", m_thread.GetProcess().GetAddressByteSize() * 2, GetFrameCodeAddress().GetLoadAddress(&m_thread.GetProcess()));
524 GetSymbolContext(eSymbolContextEverything);
Chris Lattner24943d22010-06-08 16:52:24 +0000525 strm->PutCString(", where = ");
Greg Clayton33ed1702010-08-24 00:45:41 +0000526 // TODO: need to get the
527 const bool show_module = true;
528 const bool show_inline = true;
Greg Claytonb04e7a82010-08-24 21:05:24 +0000529 m_sc.DumpStopContext(strm, &m_thread.GetProcess(), GetFrameCodeAddress(), show_module, show_inline);
Chris Lattner24943d22010-06-08 16:52:24 +0000530}
531