blob: 178144ad84b427b775dec3bbe3b3d1f9bf8df1d7 [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,
44 uint32_t inline_height,
45 lldb::addr_t pc,
46 const SymbolContext *sc_ptr
47) :
48 m_frame_index (frame_idx),
49 m_concrete_frame_index (concrete_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 (),
52 m_id (cfa, inline_height),
53 m_pc (NULL, pc),
54 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 (),
59 m_value_object_list ()
60{
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,
71 lldb::user_id_t concrete_frame_index,
72 Thread &thread,
73 const RegisterContextSP &reg_context_sp,
74 lldb::addr_t cfa,
75 uint32_t inline_height,
76 lldb::addr_t pc,
77 const SymbolContext *sc_ptr
78) :
79 m_frame_index (frame_idx),
80 m_concrete_frame_index (concrete_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),
83 m_id (cfa, inline_height),
84 m_pc (NULL, pc),
85 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 (),
90 m_value_object_list ()
91{
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,
108 lldb::user_id_t concrete_frame_index,
109 Thread &thread,
110 const RegisterContextSP &reg_context_sp,
111 lldb::addr_t cfa,
112 uint32_t inline_height,
113 const Address& pc_addr,
114 const SymbolContext *sc_ptr
115) :
116 m_frame_index (frame_idx),
117 m_concrete_frame_index (concrete_frame_index),
118 m_thread (thread),
119 m_reg_context_sp (reg_context_sp),
120 m_id (cfa, inline_height),
121 m_pc (pc_addr),
122 m_sc (),
123 m_flags (),
124 m_frame_base (),
125 m_frame_base_error (),
126 m_variable_list_sp (),
127 m_value_object_list ()
128{
129 if (sc_ptr != NULL)
130 {
131 m_sc = *sc_ptr;
132 m_flags.Set(m_sc.GetResolvedMask ());
133 }
134
135 if (m_sc.target_sp.get() == NULL && reg_context_sp)
136 {
137 m_sc.target_sp = reg_context_sp->GetThread().GetProcess().GetTarget().GetSP();
138 m_flags.Set (eSymbolContextTarget);
139 }
140
141 if (m_sc.module_sp.get() == NULL && pc_addr.GetSection())
142 {
143 Module *pc_module = pc_addr.GetSection()->GetModule();
144 if (pc_module)
145 {
146 m_sc.module_sp = pc_module->GetSP();
147 m_flags.Set (eSymbolContextModule);
148 }
149 }
Chris Lattner24943d22010-06-08 16:52:24 +0000150}
151
152
153//----------------------------------------------------------------------
154// Destructor
155//----------------------------------------------------------------------
156StackFrame::~StackFrame()
157{
158}
159
160StackID&
161StackFrame::GetStackID()
162{
163 // Make sure we have resolved our stack ID's address range before we give
164 // it out to any external clients
165 if (m_id.GetStartAddress().IsValid() == 0 && m_flags.IsClear(RESOLVED_FRAME_ID))
166 {
167 m_flags.Set (RESOLVED_FRAME_ID);
168
169 // Resolve our PC to section offset if we haven't alreday done so
170 // and if we don't have a module. The resolved address section will
171 // contain the module to which it belongs.
Greg Claytonb04e7a82010-08-24 21:05:24 +0000172 if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_ADDR))
173 GetFrameCodeAddress();
Chris Lattner24943d22010-06-08 16:52:24 +0000174
Greg Claytonb04e7a82010-08-24 21:05:24 +0000175 if (GetSymbolContext (eSymbolContextFunction).function)
Chris Lattner24943d22010-06-08 16:52:24 +0000176 {
Greg Claytonb04e7a82010-08-24 21:05:24 +0000177 m_id.SetStartAddress (m_sc.function->GetAddressRange().GetBaseAddress());
Chris Lattner24943d22010-06-08 16:52:24 +0000178 }
Greg Claytonb04e7a82010-08-24 21:05:24 +0000179 else if (GetSymbolContext (eSymbolContextSymbol).symbol)
180 {
181 AddressRange *symbol_range_ptr = m_sc.symbol->GetAddressRangePtr();
182 if (symbol_range_ptr)
183 m_id.SetStartAddress(symbol_range_ptr->GetBaseAddress());
184 }
Chris Lattner24943d22010-06-08 16:52:24 +0000185 }
186 return m_id;
187}
188
189Address&
Greg Claytonb04e7a82010-08-24 21:05:24 +0000190StackFrame::GetFrameCodeAddress()
Chris Lattner24943d22010-06-08 16:52:24 +0000191{
Greg Claytonb04e7a82010-08-24 21:05:24 +0000192 if (m_flags.IsClear(RESOLVED_FRAME_ADDR) && !m_pc.IsSectionOffset())
Chris Lattner24943d22010-06-08 16:52:24 +0000193 {
Greg Claytonb04e7a82010-08-24 21:05:24 +0000194 m_flags.Set (RESOLVED_FRAME_ADDR);
Chris Lattner24943d22010-06-08 16:52:24 +0000195
196 // Resolve the PC into a temporary address because if ResolveLoadAddress
197 // fails to resolve the address, it will clear the address object...
198 Address resolved_pc;
199 if (m_thread.GetProcess().ResolveLoadAddress(m_pc.GetOffset(), resolved_pc))
200 {
201 m_pc = resolved_pc;
202 const Section *section = m_pc.GetSection();
203 if (section)
204 {
205 Module *module = section->GetModule();
206 if (module)
207 {
208 m_sc.module_sp = module->GetSP();
209 if (m_sc.module_sp)
210 m_flags.Set(eSymbolContextModule);
211 }
212 }
213 }
214 }
215 return m_pc;
216}
217
218void
219StackFrame::ChangePC (addr_t pc)
220{
221 m_pc.SetOffset(pc);
222 m_pc.SetSection(NULL);
223 m_sc.Clear();
224 m_flags.SetAllFlagBits(0);
225 m_thread.ClearStackFrames ();
226}
227
228const char *
229StackFrame::Disassemble ()
230{
231 if (m_disassembly.GetSize() == 0)
232 {
233 ExecutionContext exe_ctx;
234 Calculate(exe_ctx);
Greg Clayton63094e02010-06-23 01:19:29 +0000235 Target &target = m_thread.GetProcess().GetTarget();
236 Disassembler::Disassemble (target.GetDebugger(),
237 target.GetArchitecture(),
Chris Lattner24943d22010-06-08 16:52:24 +0000238 exe_ctx,
239 0,
Greg Clayton70436352010-06-30 23:03:03 +0000240 false,
Chris Lattner24943d22010-06-08 16:52:24 +0000241 m_disassembly);
242 if (m_disassembly.GetSize() == 0)
243 return NULL;
244 }
245 return m_disassembly.GetData();
246}
247
248//----------------------------------------------------------------------
249// Get the symbol context if we already haven't done so by resolving the
250// PC address as much as possible. This way when we pass around a
251// StackFrame object, everyone will have as much information as
252// possible and no one will ever have to look things up manually.
253//----------------------------------------------------------------------
254const SymbolContext&
255StackFrame::GetSymbolContext (uint32_t resolve_scope)
256{
257 // Copy our internal symbol context into "sc".
Chris Lattner24943d22010-06-08 16:52:24 +0000258 if ((m_flags.GetAllFlagBits() & resolve_scope) != resolve_scope)
259 {
260 // Resolve our PC to section offset if we haven't alreday done so
261 // and if we don't have a module. The resolved address section will
262 // contain the module to which it belongs
Greg Claytonb04e7a82010-08-24 21:05:24 +0000263 if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_ADDR))
264 GetFrameCodeAddress();
Chris Lattner24943d22010-06-08 16:52:24 +0000265
266 // If this is not frame zero, then we need to subtract 1 from the PC
267 // value when doing address lookups since the PC will be on the
268 // instruction following the function call instruction...
269
Greg Claytonb04e7a82010-08-24 21:05:24 +0000270 Address lookup_addr(GetFrameCodeAddress());
Greg Clayton33ed1702010-08-24 00:45:41 +0000271 if (m_frame_index > 0 && lookup_addr.IsValid())
Chris Lattner24943d22010-06-08 16:52:24 +0000272 {
273 addr_t offset = lookup_addr.GetOffset();
274 if (offset > 0)
275 lookup_addr.SetOffset(offset - 1);
276 }
277
Greg Claytonb04e7a82010-08-24 21:05:24 +0000278
279 uint32_t resolved = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000280 if (m_sc.module_sp)
281 {
282 // We have something in our stack frame symbol context, lets check
283 // if we haven't already tried to lookup one of those things. If we
284 // haven't then we will do the query.
Greg Clayton33ed1702010-08-24 00:45:41 +0000285
286 uint32_t actual_resolve_scope = 0;
287
288 if (resolve_scope & eSymbolContextCompUnit)
289 {
290 if (m_flags.IsClear (eSymbolContextCompUnit))
291 {
292 if (m_sc.comp_unit)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000293 resolved |= eSymbolContextCompUnit;
Greg Clayton33ed1702010-08-24 00:45:41 +0000294 else
295 actual_resolve_scope |= eSymbolContextCompUnit;
296 }
297 }
298
299 if (resolve_scope & eSymbolContextFunction)
300 {
301 if (m_flags.IsClear (eSymbolContextFunction))
302 {
303 if (m_sc.function)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000304 resolved |= eSymbolContextFunction;
Greg Clayton33ed1702010-08-24 00:45:41 +0000305 else
306 actual_resolve_scope |= eSymbolContextFunction;
307 }
308 }
309
310 if (resolve_scope & eSymbolContextBlock)
311 {
312 if (m_flags.IsClear (eSymbolContextBlock))
313 {
314 if (m_sc.block)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000315 resolved |= eSymbolContextBlock;
Greg Clayton33ed1702010-08-24 00:45:41 +0000316 else
317 actual_resolve_scope |= eSymbolContextBlock;
318 }
319 }
320
321 if (resolve_scope & eSymbolContextSymbol)
322 {
323 if (m_flags.IsClear (eSymbolContextSymbol))
324 {
325 if (m_sc.symbol)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000326 resolved |= eSymbolContextSymbol;
Greg Clayton33ed1702010-08-24 00:45:41 +0000327 else
328 actual_resolve_scope |= eSymbolContextSymbol;
329 }
330 }
331
332 if (resolve_scope & eSymbolContextLineEntry)
333 {
334 if (m_flags.IsClear (eSymbolContextLineEntry))
335 {
336 if (m_sc.line_entry.IsValid())
Greg Claytonb04e7a82010-08-24 21:05:24 +0000337 resolved |= eSymbolContextLineEntry;
Greg Clayton33ed1702010-08-24 00:45:41 +0000338 else
339 actual_resolve_scope |= eSymbolContextLineEntry;
340 }
341 }
342
343 if (actual_resolve_scope)
Chris Lattner24943d22010-06-08 16:52:24 +0000344 {
345 // We might be resolving less information than what is already
346 // in our current symbol context so resolve into a temporary
347 // symbol context "sc" so we don't clear out data we have
348 // already found in "m_sc"
349 SymbolContext sc;
350 // Set flags that indicate what we have tried to resolve
Greg Claytonb04e7a82010-08-24 21:05:24 +0000351 resolved |= m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, actual_resolve_scope, sc);
Greg Clayton33ed1702010-08-24 00:45:41 +0000352 // Only replace what we didn't already have as we may have
353 // information for an inlined function scope that won't match
354 // what a standard lookup by address would match
Greg Claytonb04e7a82010-08-24 21:05:24 +0000355 if ((resolved & eSymbolContextCompUnit) && m_sc.comp_unit == NULL)
356 m_sc.comp_unit = sc.comp_unit;
357 if ((resolved & eSymbolContextFunction) && m_sc.function == NULL)
358 m_sc.function = sc.function;
359 if ((resolved & eSymbolContextBlock) && m_sc.block == NULL)
360 m_sc.block = sc.block;
361 if ((resolved & eSymbolContextSymbol) && m_sc.symbol == NULL)
362 m_sc.symbol = sc.symbol;
363 if ((resolved & eSymbolContextLineEntry) && !m_sc.line_entry.IsValid())
364 m_sc.line_entry = sc.line_entry;
365
Chris Lattner24943d22010-06-08 16:52:24 +0000366 }
367 }
368 else
369 {
370 // If we don't have a module, then we can't have the compile unit,
371 // function, block, line entry or symbol, so we can safely call
372 // ResolveSymbolContextForAddress with our symbol context member m_sc.
Greg Claytonb04e7a82010-08-24 21:05:24 +0000373 resolved |= m_thread.GetProcess().GetTarget().GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc);
Chris Lattner24943d22010-06-08 16:52:24 +0000374 }
375
376 // If the target was requested add that:
377 if (m_sc.target_sp.get() == NULL)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000378 {
Chris Lattner24943d22010-06-08 16:52:24 +0000379 m_sc.target_sp = CalculateProcess()->GetTarget().GetSP();
Greg Claytonb04e7a82010-08-24 21:05:24 +0000380 if (m_sc.target_sp)
381 resolved |= eSymbolContextTarget;
382 }
Chris Lattner24943d22010-06-08 16:52:24 +0000383
384 // Update our internal flags so we remember what we have tried to locate so
385 // we don't have to keep trying when more calls to this function are made.
Greg Claytonb04e7a82010-08-24 21:05:24 +0000386 // We might have dug up more information that was requested (for example
387 // if we were asked to only get the block, we will have gotten the
388 // compile unit, and function) so set any additional bits that we resolved
389 m_flags.Set (resolve_scope | resolved);
Chris Lattner24943d22010-06-08 16:52:24 +0000390 }
391
392 // Return the symbol context with everything that was possible to resolve
393 // resolved.
394 return m_sc;
395}
396
397
398VariableList *
399StackFrame::GetVariableList ()
400{
401 if (m_flags.IsClear(RESOLVED_VARIABLES))
402 {
403 m_flags.Set(RESOLVED_VARIABLES);
404
Greg Claytonb04e7a82010-08-24 21:05:24 +0000405 if (GetSymbolContext (eSymbolContextFunction).function)
Chris Lattner24943d22010-06-08 16:52:24 +0000406 {
407 bool get_child_variables = true;
408 bool can_create = true;
Greg Clayton75ccf502010-08-21 02:22:51 +0000409 m_variable_list_sp = m_sc.function->GetBlock (can_create).GetVariableList (get_child_variables, can_create);
Chris Lattner24943d22010-06-08 16:52:24 +0000410 }
411 }
412 return m_variable_list_sp.get();
413}
414
415
416bool
417StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr)
418{
419 if (m_flags.IsClear(GOT_FRAME_BASE))
420 {
421 if (m_sc.function)
422 {
423 m_frame_base.Clear();
424 m_frame_base_error.Clear();
425
426 m_flags.Set(GOT_FRAME_BASE);
427 ExecutionContext exe_ctx (&m_thread.GetProcess(), &m_thread, this);
428 Value expr_value;
429 if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, NULL, expr_value, &m_frame_base_error) < 0)
430 {
431 // We should really have an error if evaluate returns, but in case
432 // we don't, lets set the error to something at least.
433 if (m_frame_base_error.Success())
434 m_frame_base_error.SetErrorString("Evaluation of the frame base expression failed.");
435 }
436 else
437 {
438 m_frame_base = expr_value.ResolveValue(&exe_ctx, NULL);
439 }
440 }
441 else
442 {
443 m_frame_base_error.SetErrorString ("No function in symbol context.");
444 }
445 }
446
447 if (m_frame_base_error.Success())
448 frame_base = m_frame_base;
449
450 if (error_ptr)
451 *error_ptr = m_frame_base_error;
452 return m_frame_base_error.Success();
453}
454
455RegisterContext *
456StackFrame::GetRegisterContext ()
457{
458 if (m_reg_context_sp.get() == NULL)
459 m_reg_context_sp.reset (m_thread.CreateRegisterContextForFrame (this));
460 return m_reg_context_sp.get();
461}
462
463bool
464StackFrame::HasDebugInformation ()
465{
Greg Claytonb04e7a82010-08-24 21:05:24 +0000466 GetSymbolContext (eSymbolContextLineEntry);
Chris Lattner24943d22010-06-08 16:52:24 +0000467 return m_sc.line_entry.IsValid();
468}
469
470ValueObjectList &
471StackFrame::GetValueObjectList()
472{
473 return m_value_object_list;
474}
475
476
477Target *
478StackFrame::CalculateTarget ()
479{
480 return m_thread.CalculateTarget();
481}
482
483Process *
484StackFrame::CalculateProcess ()
485{
486 return m_thread.CalculateProcess();
487}
488
489Thread *
490StackFrame::CalculateThread ()
491{
492 return &m_thread;
493}
494
495StackFrame *
496StackFrame::CalculateStackFrame ()
497{
498 return this;
499}
500
501
502void
503StackFrame::Calculate (ExecutionContext &exe_ctx)
504{
505 m_thread.Calculate (exe_ctx);
506 exe_ctx.frame = this;
507}
508
509void
510StackFrame::Dump (Stream *strm, bool show_frame_index)
511{
512 if (strm == NULL)
513 return;
514
515 if (show_frame_index)
Greg Clayton33ed1702010-08-24 00:45:41 +0000516 strm->Printf("frame #%u: ", m_frame_index);
Greg Claytonb04e7a82010-08-24 21:05:24 +0000517 strm->Printf("0x%0*llx", m_thread.GetProcess().GetAddressByteSize() * 2, GetFrameCodeAddress().GetLoadAddress(&m_thread.GetProcess()));
518 GetSymbolContext(eSymbolContextEverything);
Chris Lattner24943d22010-06-08 16:52:24 +0000519 strm->PutCString(", where = ");
Greg Clayton33ed1702010-08-24 00:45:41 +0000520 // TODO: need to get the
521 const bool show_module = true;
522 const bool show_inline = true;
Greg Claytonb04e7a82010-08-24 21:05:24 +0000523 m_sc.DumpStopContext(strm, &m_thread.GetProcess(), GetFrameCodeAddress(), show_module, show_inline);
Chris Lattner24943d22010-06-08 16:52:24 +0000524}
525