blob: 5ed15099612ba58f9becb970c5386decff926ea6 [file] [log] [blame]
Chris Lattner30fdc8d2010-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
Chris Lattner30fdc8d2010-06-08 16:52:24 +000010// C Includes
11// C++ Includes
12// Other libraries and framework includes
13// Project includes
Eugene Zelenkod70a6e72016-02-18 18:52:47 +000014#include "lldb/Target/StackFrame.h"
Greg Clayton0603aa92010-10-04 01:05:56 +000015#include "lldb/Core/Debugger.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000016#include "lldb/Core/Disassembler.h"
Greg Clayton554f68d2015-02-04 22:00:53 +000017#include "lldb/Core/FormatEntity.h"
Enrico Granata592afe72016-03-15 21:50:51 +000018#include "lldb/Core/Mangled.h"
19#include "lldb/Core/Module.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000020#include "lldb/Core/Value.h"
Greg Clayton54979cd2010-12-15 05:08:08 +000021#include "lldb/Core/ValueObjectConstResult.h"
Sean Callanan4740a732016-09-06 04:48:36 +000022#include "lldb/Core/ValueObjectMemory.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000023#include "lldb/Core/ValueObjectVariable.h"
Greg Clayton1f746072012-08-29 21:13:06 +000024#include "lldb/Symbol/CompileUnit.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000025#include "lldb/Symbol/Function.h"
Greg Clayton1f746072012-08-29 21:13:06 +000026#include "lldb/Symbol/Symbol.h"
27#include "lldb/Symbol/SymbolContextScope.h"
Enrico Granata46252392015-11-19 22:28:58 +000028#include "lldb/Symbol/Type.h"
Greg Clayton288bdf92010-09-02 02:59:18 +000029#include "lldb/Symbol/VariableList.h"
Sean Callanan4740a732016-09-06 04:48:36 +000030#include "lldb/Target/ABI.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031#include "lldb/Target/ExecutionContext.h"
32#include "lldb/Target/Process.h"
33#include "lldb/Target/RegisterContext.h"
34#include "lldb/Target/Target.h"
35#include "lldb/Target/Thread.h"
Pavel Labathd821c992018-08-07 11:07:21 +000036#include "lldb/Utility/RegisterValue.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000037
38using namespace lldb;
39using namespace lldb_private;
40
41// The first bits in the flags are reserved for the SymbolContext::Scope bits
42// so we know if we have tried to look up information in our internal symbol
43// context (m_sc) already.
Kate Stoneb9c1b512016-09-06 20:57:50 +000044#define RESOLVED_FRAME_CODE_ADDR (uint32_t(eSymbolContextEverything + 1))
45#define RESOLVED_FRAME_ID_SYMBOL_SCOPE (RESOLVED_FRAME_CODE_ADDR << 1)
46#define GOT_FRAME_BASE (RESOLVED_FRAME_ID_SYMBOL_SCOPE << 1)
47#define RESOLVED_VARIABLES (GOT_FRAME_BASE << 1)
48#define RESOLVED_GLOBAL_VARIABLES (RESOLVED_VARIABLES << 1)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000049
Kate Stoneb9c1b512016-09-06 20:57:50 +000050StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx,
51 user_id_t unwind_frame_index, addr_t cfa,
Vedant Kumar4b36f792018-10-05 23:23:15 +000052 bool cfa_is_valid, addr_t pc, StackFrame::Kind kind,
Saleem Abdulrasoolbb19a132016-05-19 05:13:57 +000053 const SymbolContext *sc_ptr)
Kate Stoneb9c1b512016-09-06 20:57:50 +000054 : m_thread_wp(thread_sp), m_frame_index(frame_idx),
55 m_concrete_frame_index(unwind_frame_index), m_reg_context_sp(),
56 m_id(pc, cfa, nullptr), m_frame_code_addr(pc), m_sc(), m_flags(),
57 m_frame_base(), m_frame_base_error(), m_cfa_is_valid(cfa_is_valid),
Vedant Kumar4b36f792018-10-05 23:23:15 +000058 m_stack_frame_kind(kind), m_variable_list_sp(),
Kate Stoneb9c1b512016-09-06 20:57:50 +000059 m_variable_list_value_objects(), m_disassembly(), m_mutex() {
60 // If we don't have a CFA value, use the frame index for our StackID so that
Adrian Prantl05097242018-04-30 16:49:04 +000061 // recursive functions properly aren't confused with one another on a history
62 // stack.
Vedant Kumar4b36f792018-10-05 23:23:15 +000063 if (IsHistorical() && !m_cfa_is_valid) {
Kate Stoneb9c1b512016-09-06 20:57:50 +000064 m_id.SetCFA(m_frame_index);
65 }
Jason Molenda99618472013-11-04 11:02:52 +000066
Kate Stoneb9c1b512016-09-06 20:57:50 +000067 if (sc_ptr != nullptr) {
68 m_sc = *sc_ptr;
69 m_flags.Set(m_sc.GetResolvedMask());
70 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000071}
72
Kate Stoneb9c1b512016-09-06 20:57:50 +000073StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx,
74 user_id_t unwind_frame_index,
75 const RegisterContextSP &reg_context_sp, addr_t cfa,
76 addr_t pc, const SymbolContext *sc_ptr)
77 : m_thread_wp(thread_sp), m_frame_index(frame_idx),
Saleem Abdulrasoolbb19a132016-05-19 05:13:57 +000078 m_concrete_frame_index(unwind_frame_index),
Kate Stoneb9c1b512016-09-06 20:57:50 +000079 m_reg_context_sp(reg_context_sp), m_id(pc, cfa, nullptr),
80 m_frame_code_addr(pc), m_sc(), m_flags(), m_frame_base(),
Vedant Kumar4b36f792018-10-05 23:23:15 +000081 m_frame_base_error(), m_cfa_is_valid(true),
82 m_stack_frame_kind(StackFrame::Kind::Regular), m_variable_list_sp(),
83 m_variable_list_value_objects(), m_disassembly(), m_mutex() {
Kate Stoneb9c1b512016-09-06 20:57:50 +000084 if (sc_ptr != nullptr) {
85 m_sc = *sc_ptr;
86 m_flags.Set(m_sc.GetResolvedMask());
87 }
Saleem Abdulrasoolbb19a132016-05-19 05:13:57 +000088
Kate Stoneb9c1b512016-09-06 20:57:50 +000089 if (reg_context_sp && !m_sc.target_sp) {
90 m_sc.target_sp = reg_context_sp->CalculateTarget();
91 if (m_sc.target_sp)
92 m_flags.Set(eSymbolContextTarget);
93 }
Greg Clayton1b72fcb2010-08-24 00:45:41 +000094}
95
Kate Stoneb9c1b512016-09-06 20:57:50 +000096StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx,
97 user_id_t unwind_frame_index,
98 const RegisterContextSP &reg_context_sp, addr_t cfa,
99 const Address &pc_addr, const SymbolContext *sc_ptr)
100 : m_thread_wp(thread_sp), m_frame_index(frame_idx),
Saleem Abdulrasoolbb19a132016-05-19 05:13:57 +0000101 m_concrete_frame_index(unwind_frame_index),
102 m_reg_context_sp(reg_context_sp),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000103 m_id(pc_addr.GetLoadAddress(thread_sp->CalculateTarget().get()), cfa,
104 nullptr),
105 m_frame_code_addr(pc_addr), m_sc(), m_flags(), m_frame_base(),
Vedant Kumar4b36f792018-10-05 23:23:15 +0000106 m_frame_base_error(), m_cfa_is_valid(true),
107 m_stack_frame_kind(StackFrame::Kind::Regular), m_variable_list_sp(),
108 m_variable_list_value_objects(), m_disassembly(), m_mutex() {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000109 if (sc_ptr != nullptr) {
110 m_sc = *sc_ptr;
111 m_flags.Set(m_sc.GetResolvedMask());
112 }
Saleem Abdulrasoolbb19a132016-05-19 05:13:57 +0000113
Kate Stoneb9c1b512016-09-06 20:57:50 +0000114 if (!m_sc.target_sp && reg_context_sp) {
115 m_sc.target_sp = reg_context_sp->CalculateTarget();
116 if (m_sc.target_sp)
117 m_flags.Set(eSymbolContextTarget);
118 }
Saleem Abdulrasoolbb19a132016-05-19 05:13:57 +0000119
Kate Stoneb9c1b512016-09-06 20:57:50 +0000120 ModuleSP pc_module_sp(pc_addr.GetModule());
121 if (!m_sc.module_sp || m_sc.module_sp != pc_module_sp) {
122 if (pc_module_sp) {
123 m_sc.module_sp = pc_module_sp;
124 m_flags.Set(eSymbolContextModule);
125 } else {
126 m_sc.module_sp.reset();
Greg Clayton1b72fcb2010-08-24 00:45:41 +0000127 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000128 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000129}
130
Eugene Zelenkod70a6e72016-02-18 18:52:47 +0000131StackFrame::~StackFrame() = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000132
Kate Stoneb9c1b512016-09-06 20:57:50 +0000133StackID &StackFrame::GetStackID() {
134 std::lock_guard<std::recursive_mutex> guard(m_mutex);
Adrian Prantl05097242018-04-30 16:49:04 +0000135 // Make sure we have resolved the StackID object's symbol context scope if we
136 // already haven't looked it up.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000137
Kate Stoneb9c1b512016-09-06 20:57:50 +0000138 if (m_flags.IsClear(RESOLVED_FRAME_ID_SYMBOL_SCOPE)) {
139 if (m_id.GetSymbolContextScope()) {
Adrian Prantl05097242018-04-30 16:49:04 +0000140 // We already have a symbol context scope, we just don't have our flag
141 // bit set.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000142 m_flags.Set(RESOLVED_FRAME_ID_SYMBOL_SCOPE);
143 } else {
Adrian Prantl05097242018-04-30 16:49:04 +0000144 // Calculate the frame block and use this for the stack ID symbol context
145 // scope if we have one.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000146 SymbolContextScope *scope = GetFrameBlock();
147 if (scope == nullptr) {
148 // We don't have a block, so use the symbol
149 if (m_flags.IsClear(eSymbolContextSymbol))
150 GetSymbolContext(eSymbolContextSymbol);
151
152 // It is ok if m_sc.symbol is nullptr here
153 scope = m_sc.symbol;
154 }
155 // Set the symbol context scope (the accessor will set the
156 // RESOLVED_FRAME_ID_SYMBOL_SCOPE bit in m_flags).
157 SetSymbolContextScope(scope);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000158 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000159 }
160 return m_id;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000161}
162
Kate Stoneb9c1b512016-09-06 20:57:50 +0000163uint32_t StackFrame::GetFrameIndex() const {
164 ThreadSP thread_sp = GetThread();
165 if (thread_sp)
166 return thread_sp->GetStackFrameList()->GetVisibleStackFrameIndex(
167 m_frame_index);
168 else
169 return m_frame_index;
Jim Ingham513c6bb2012-09-01 01:02:41 +0000170}
171
Kate Stoneb9c1b512016-09-06 20:57:50 +0000172void StackFrame::SetSymbolContextScope(SymbolContextScope *symbol_scope) {
173 std::lock_guard<std::recursive_mutex> guard(m_mutex);
174 m_flags.Set(RESOLVED_FRAME_ID_SYMBOL_SCOPE);
175 m_id.SetSymbolContextScope(symbol_scope);
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000176}
177
Kate Stoneb9c1b512016-09-06 20:57:50 +0000178const Address &StackFrame::GetFrameCodeAddress() {
179 std::lock_guard<std::recursive_mutex> guard(m_mutex);
180 if (m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR) &&
181 !m_frame_code_addr.IsSectionOffset()) {
182 m_flags.Set(RESOLVED_FRAME_CODE_ADDR);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000183
Kate Stoneb9c1b512016-09-06 20:57:50 +0000184 // Resolve the PC into a temporary address because if ResolveLoadAddress
185 // fails to resolve the address, it will clear the address object...
186 ThreadSP thread_sp(GetThread());
187 if (thread_sp) {
188 TargetSP target_sp(thread_sp->CalculateTarget());
189 if (target_sp) {
Pavel Labathc3c72122017-06-08 13:26:35 +0000190 const bool allow_section_end = true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000191 if (m_frame_code_addr.SetOpcodeLoadAddress(
192 m_frame_code_addr.GetOffset(), target_sp.get(),
Tatyana Krasnukha04803b32018-06-26 13:06:54 +0000193 AddressClass::eCode, allow_section_end)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000194 ModuleSP module_sp(m_frame_code_addr.GetModule());
195 if (module_sp) {
196 m_sc.module_sp = module_sp;
197 m_flags.Set(eSymbolContextModule);
198 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000199 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000200 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000201 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000202 }
203 return m_frame_code_addr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000204}
205
Kate Stoneb9c1b512016-09-06 20:57:50 +0000206bool StackFrame::ChangePC(addr_t pc) {
207 std::lock_guard<std::recursive_mutex> guard(m_mutex);
208 // We can't change the pc value of a history stack frame - it is immutable.
Vedant Kumar4b36f792018-10-05 23:23:15 +0000209 if (IsHistorical())
Kate Stoneb9c1b512016-09-06 20:57:50 +0000210 return false;
211 m_frame_code_addr.SetRawAddress(pc);
212 m_sc.Clear(false);
213 m_flags.Reset(0);
214 ThreadSP thread_sp(GetThread());
215 if (thread_sp)
216 thread_sp->ClearStackFrames();
217 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000218}
219
Kate Stoneb9c1b512016-09-06 20:57:50 +0000220const char *StackFrame::Disassemble() {
221 std::lock_guard<std::recursive_mutex> guard(m_mutex);
Zachary Turner8b3f2162017-02-28 17:59:59 +0000222 if (m_disassembly.Empty()) {
223 ExecutionContext exe_ctx(shared_from_this());
224 Target *target = exe_ctx.GetTargetPtr();
225 if (target) {
226 const char *plugin_name = nullptr;
227 const char *flavor = nullptr;
228 Disassembler::Disassemble(target->GetDebugger(),
229 target->GetArchitecture(), plugin_name, flavor,
230 exe_ctx, 0, false, 0, 0, m_disassembly);
231 }
232 if (m_disassembly.Empty())
233 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000234 }
Zachary Turner8b3f2162017-02-28 17:59:59 +0000235
Kate Stoneb9c1b512016-09-06 20:57:50 +0000236 return m_disassembly.GetData();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000237}
238
Kate Stoneb9c1b512016-09-06 20:57:50 +0000239Block *StackFrame::GetFrameBlock() {
240 if (m_sc.block == nullptr && m_flags.IsClear(eSymbolContextBlock))
241 GetSymbolContext(eSymbolContextBlock);
Greg Clayton95897c62010-09-07 04:20:48 +0000242
Kate Stoneb9c1b512016-09-06 20:57:50 +0000243 if (m_sc.block) {
244 Block *inline_block = m_sc.block->GetContainingInlinedBlock();
245 if (inline_block) {
Adrian Prantl05097242018-04-30 16:49:04 +0000246 // Use the block with the inlined function info as the frame block we
247 // want this frame to have only the variables for the inlined function
248 // and its non-inlined block child blocks.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000249 return inline_block;
250 } else {
Adrian Prantl05097242018-04-30 16:49:04 +0000251 // This block is not contained within any inlined function blocks with so
252 // we want to use the top most function block.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000253 return &m_sc.function->GetBlock(false);
254 }
255 }
256 return nullptr;
Greg Clayton95897c62010-09-07 04:20:48 +0000257}
258
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000259//----------------------------------------------------------------------
260// Get the symbol context if we already haven't done so by resolving the
261// PC address as much as possible. This way when we pass around a
Adrian Prantl05097242018-04-30 16:49:04 +0000262// StackFrame object, everyone will have as much information as possible and no
263// one will ever have to look things up manually.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000264//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000265const SymbolContext &StackFrame::GetSymbolContext(uint32_t resolve_scope) {
266 std::lock_guard<std::recursive_mutex> guard(m_mutex);
267 // Copy our internal symbol context into "sc".
268 if ((m_flags.Get() & resolve_scope) != resolve_scope) {
269 uint32_t resolved = 0;
Greg Clayton75a03332012-11-29 00:53:06 +0000270
Kate Stoneb9c1b512016-09-06 20:57:50 +0000271 // If the target was requested add that:
272 if (!m_sc.target_sp) {
273 m_sc.target_sp = CalculateTarget();
274 if (m_sc.target_sp)
275 resolved |= eSymbolContextTarget;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000276 }
277
Adrian Prantl05097242018-04-30 16:49:04 +0000278 // Resolve our PC to section offset if we haven't already done so and if we
279 // don't have a module. The resolved address section will contain the
280 // module to which it belongs
Kate Stoneb9c1b512016-09-06 20:57:50 +0000281 if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR))
282 GetFrameCodeAddress();
283
Adrian Prantl05097242018-04-30 16:49:04 +0000284 // If this is not frame zero, then we need to subtract 1 from the PC value
285 // when doing address lookups since the PC will be on the instruction
286 // following the function call instruction...
Kate Stoneb9c1b512016-09-06 20:57:50 +0000287
288 Address lookup_addr(GetFrameCodeAddress());
289 if (m_frame_index > 0 && lookup_addr.IsValid()) {
290 addr_t offset = lookup_addr.GetOffset();
291 if (offset > 0) {
292 lookup_addr.SetOffset(offset - 1);
293
294 } else {
Adrian Prantl05097242018-04-30 16:49:04 +0000295 // lookup_addr is the start of a section. We need do the math on the
296 // actual load address and re-compute the section. We're working with
297 // a 'noreturn' function at the end of a section.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000298 ThreadSP thread_sp(GetThread());
299 if (thread_sp) {
300 TargetSP target_sp(thread_sp->CalculateTarget());
301 if (target_sp) {
302 addr_t addr_minus_one =
303 lookup_addr.GetLoadAddress(target_sp.get()) - 1;
304 lookup_addr.SetLoadAddress(addr_minus_one, target_sp.get());
305 } else {
306 lookup_addr.SetOffset(offset - 1);
307 }
308 }
309 }
310 }
311
312 if (m_sc.module_sp) {
Adrian Prantl05097242018-04-30 16:49:04 +0000313 // We have something in our stack frame symbol context, lets check if we
314 // haven't already tried to lookup one of those things. If we haven't
315 // then we will do the query.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000316
317 uint32_t actual_resolve_scope = 0;
318
319 if (resolve_scope & eSymbolContextCompUnit) {
320 if (m_flags.IsClear(eSymbolContextCompUnit)) {
321 if (m_sc.comp_unit)
322 resolved |= eSymbolContextCompUnit;
323 else
324 actual_resolve_scope |= eSymbolContextCompUnit;
325 }
326 }
327
328 if (resolve_scope & eSymbolContextFunction) {
329 if (m_flags.IsClear(eSymbolContextFunction)) {
330 if (m_sc.function)
331 resolved |= eSymbolContextFunction;
332 else
333 actual_resolve_scope |= eSymbolContextFunction;
334 }
335 }
336
337 if (resolve_scope & eSymbolContextBlock) {
338 if (m_flags.IsClear(eSymbolContextBlock)) {
339 if (m_sc.block)
340 resolved |= eSymbolContextBlock;
341 else
342 actual_resolve_scope |= eSymbolContextBlock;
343 }
344 }
345
346 if (resolve_scope & eSymbolContextSymbol) {
347 if (m_flags.IsClear(eSymbolContextSymbol)) {
348 if (m_sc.symbol)
349 resolved |= eSymbolContextSymbol;
350 else
351 actual_resolve_scope |= eSymbolContextSymbol;
352 }
353 }
354
355 if (resolve_scope & eSymbolContextLineEntry) {
356 if (m_flags.IsClear(eSymbolContextLineEntry)) {
357 if (m_sc.line_entry.IsValid())
358 resolved |= eSymbolContextLineEntry;
359 else
360 actual_resolve_scope |= eSymbolContextLineEntry;
361 }
362 }
363
364 if (actual_resolve_scope) {
Adrian Prantl05097242018-04-30 16:49:04 +0000365 // We might be resolving less information than what is already in our
366 // current symbol context so resolve into a temporary symbol context
367 // "sc" so we don't clear out data we have already found in "m_sc"
Kate Stoneb9c1b512016-09-06 20:57:50 +0000368 SymbolContext sc;
369 // Set flags that indicate what we have tried to resolve
370 resolved |= m_sc.module_sp->ResolveSymbolContextForAddress(
371 lookup_addr, actual_resolve_scope, sc);
Adrian Prantl05097242018-04-30 16:49:04 +0000372 // Only replace what we didn't already have as we may have information
373 // for an inlined function scope that won't match what a standard
374 // lookup by address would match
Kate Stoneb9c1b512016-09-06 20:57:50 +0000375 if ((resolved & eSymbolContextCompUnit) && m_sc.comp_unit == nullptr)
376 m_sc.comp_unit = sc.comp_unit;
377 if ((resolved & eSymbolContextFunction) && m_sc.function == nullptr)
378 m_sc.function = sc.function;
379 if ((resolved & eSymbolContextBlock) && m_sc.block == nullptr)
380 m_sc.block = sc.block;
381 if ((resolved & eSymbolContextSymbol) && m_sc.symbol == nullptr)
382 m_sc.symbol = sc.symbol;
383 if ((resolved & eSymbolContextLineEntry) &&
384 !m_sc.line_entry.IsValid()) {
385 m_sc.line_entry = sc.line_entry;
386 m_sc.line_entry.ApplyFileMappings(m_sc.target_sp);
387 }
388 }
389 } else {
390 // If we don't have a module, then we can't have the compile unit,
391 // function, block, line entry or symbol, so we can safely call
392 // ResolveSymbolContextForAddress with our symbol context member m_sc.
393 if (m_sc.target_sp) {
394 resolved |= m_sc.target_sp->GetImages().ResolveSymbolContextForAddress(
395 lookup_addr, resolve_scope, m_sc);
396 }
397 }
398
399 // Update our internal flags so we remember what we have tried to locate so
400 // we don't have to keep trying when more calls to this function are made.
Adrian Prantl05097242018-04-30 16:49:04 +0000401 // We might have dug up more information that was requested (for example if
402 // we were asked to only get the block, we will have gotten the compile
403 // unit, and function) so set any additional bits that we resolved
Kate Stoneb9c1b512016-09-06 20:57:50 +0000404 m_flags.Set(resolve_scope | resolved);
405 }
406
407 // Return the symbol context with everything that was possible to resolve
408 // resolved.
409 return m_sc;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000410}
411
Kate Stoneb9c1b512016-09-06 20:57:50 +0000412VariableList *StackFrame::GetVariableList(bool get_file_globals) {
413 std::lock_guard<std::recursive_mutex> guard(m_mutex);
414 if (m_flags.IsClear(RESOLVED_VARIABLES)) {
415 m_flags.Set(RESOLVED_VARIABLES);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000416
Kate Stoneb9c1b512016-09-06 20:57:50 +0000417 Block *frame_block = GetFrameBlock();
418
419 if (frame_block) {
420 const bool get_child_variables = true;
421 const bool can_create = true;
422 const bool stop_if_child_block_is_inlined_function = true;
423 m_variable_list_sp.reset(new VariableList());
424 frame_block->AppendBlockVariables(can_create, get_child_variables,
425 stop_if_child_block_is_inlined_function,
Zachary Turner3bc714b2017-03-02 00:05:25 +0000426 [](Variable *v) { return true; },
Kate Stoneb9c1b512016-09-06 20:57:50 +0000427 m_variable_list_sp.get());
Sean Callanan7c0962d2010-11-01 04:38:59 +0000428 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000429 }
430
431 if (m_flags.IsClear(RESOLVED_GLOBAL_VARIABLES) && get_file_globals) {
432 m_flags.Set(RESOLVED_GLOBAL_VARIABLES);
433
434 if (m_flags.IsClear(eSymbolContextCompUnit))
435 GetSymbolContext(eSymbolContextCompUnit);
436
437 if (m_sc.comp_unit) {
438 VariableListSP global_variable_list_sp(
439 m_sc.comp_unit->GetVariableList(true));
440 if (m_variable_list_sp)
441 m_variable_list_sp->AddVariables(global_variable_list_sp.get());
442 else
443 m_variable_list_sp = global_variable_list_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000444 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000445 }
446
447 return m_variable_list_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000448}
449
Greg Claytond41f0322011-08-02 23:35:43 +0000450VariableListSP
Kate Stoneb9c1b512016-09-06 20:57:50 +0000451StackFrame::GetInScopeVariableList(bool get_file_globals,
452 bool must_have_valid_location) {
453 std::lock_guard<std::recursive_mutex> guard(m_mutex);
454 // We can't fetch variable information for a history stack frame.
Vedant Kumar4b36f792018-10-05 23:23:15 +0000455 if (IsHistorical())
Kate Stoneb9c1b512016-09-06 20:57:50 +0000456 return VariableListSP();
Jason Molenda99618472013-11-04 11:02:52 +0000457
Kate Stoneb9c1b512016-09-06 20:57:50 +0000458 VariableListSP var_list_sp(new VariableList);
459 GetSymbolContext(eSymbolContextCompUnit | eSymbolContextBlock);
Greg Claytond41f0322011-08-02 23:35:43 +0000460
Kate Stoneb9c1b512016-09-06 20:57:50 +0000461 if (m_sc.block) {
462 const bool can_create = true;
463 const bool get_parent_variables = true;
464 const bool stop_if_block_is_inlined_function = true;
465 m_sc.block->AppendVariables(
466 can_create, get_parent_variables, stop_if_block_is_inlined_function,
467 [this, must_have_valid_location](Variable *v) {
468 return v->IsInScope(this) && (!must_have_valid_location ||
469 v->LocationIsValidForFrame(this));
470 },
471 var_list_sp.get());
472 }
473
474 if (m_sc.comp_unit && get_file_globals) {
475 VariableListSP global_variable_list_sp(
476 m_sc.comp_unit->GetVariableList(true));
477 if (global_variable_list_sp)
478 var_list_sp->AddVariables(global_variable_list_sp.get());
479 }
480
481 return var_list_sp;
Greg Claytond41f0322011-08-02 23:35:43 +0000482}
483
Kate Stoneb9c1b512016-09-06 20:57:50 +0000484ValueObjectSP StackFrame::GetValueForVariableExpressionPath(
Zachary Turner0eb31a12016-11-17 05:14:32 +0000485 llvm::StringRef var_expr, DynamicValueType use_dynamic, uint32_t options,
Zachary Turner97206d52017-05-12 04:51:55 +0000486 VariableSP &var_sp, Status &error) {
Zachary Turner0eb31a12016-11-17 05:14:32 +0000487 llvm::StringRef original_var_expr = var_expr;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000488 // We can't fetch variable information for a history stack frame.
Vedant Kumar4b36f792018-10-05 23:23:15 +0000489 if (IsHistorical())
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000490 return ValueObjectSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000491
Zachary Turner0eb31a12016-11-17 05:14:32 +0000492 if (var_expr.empty()) {
493 error.SetErrorStringWithFormat("invalid variable path '%s'",
494 var_expr.str().c_str());
Zachary Turner24bd3172016-11-17 01:37:52 +0000495 return ValueObjectSP();
496 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000497
Zachary Turner24bd3172016-11-17 01:37:52 +0000498 const bool check_ptr_vs_member =
499 (options & eExpressionPathOptionCheckPtrVsMember) != 0;
500 const bool no_fragile_ivar =
501 (options & eExpressionPathOptionsNoFragileObjcIvar) != 0;
502 const bool no_synth_child =
503 (options & eExpressionPathOptionsNoSyntheticChildren) != 0;
504 // const bool no_synth_array = (options &
505 // eExpressionPathOptionsNoSyntheticArrayRange) != 0;
506 error.Clear();
507 bool deref = false;
508 bool address_of = false;
509 ValueObjectSP valobj_sp;
510 const bool get_file_globals = true;
511 // When looking up a variable for an expression, we need only consider the
512 // variables that are in scope.
513 VariableListSP var_list_sp(GetInScopeVariableList(get_file_globals));
514 VariableList *variable_list = var_list_sp.get();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000515
Zachary Turner24bd3172016-11-17 01:37:52 +0000516 if (!variable_list)
517 return ValueObjectSP();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000518
Zachary Turner24bd3172016-11-17 01:37:52 +0000519 // If first character is a '*', then show pointer contents
Zachary Turner24bd3172016-11-17 01:37:52 +0000520 std::string var_expr_storage;
521 if (var_expr[0] == '*') {
522 deref = true;
523 var_expr = var_expr.drop_front(); // Skip the '*'
524 } else if (var_expr[0] == '&') {
525 address_of = true;
526 var_expr = var_expr.drop_front(); // Skip the '&'
527 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000528
Zachary Turner24bd3172016-11-17 01:37:52 +0000529 size_t separator_idx = var_expr.find_first_of(".-[=+~|&^%#@!/?,<>{}");
530 StreamString var_expr_path_strm;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000531
Zachary Turner24bd3172016-11-17 01:37:52 +0000532 ConstString name_const_string(var_expr.substr(0, separator_idx));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000533
Zachary Turner24bd3172016-11-17 01:37:52 +0000534 var_sp = variable_list->FindVariable(name_const_string, false);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000535
Zachary Turner24bd3172016-11-17 01:37:52 +0000536 bool synthetically_added_instance_object = false;
537
538 if (var_sp) {
539 var_expr = var_expr.drop_front(name_const_string.GetLength());
540 }
541
542 if (!var_sp && (options & eExpressionPathOptionsAllowDirectIVarAccess)) {
Adrian Prantl05097242018-04-30 16:49:04 +0000543 // Check for direct ivars access which helps us with implicit access to
544 // ivars with the "this->" or "self->"
Zachary Turner24bd3172016-11-17 01:37:52 +0000545 GetSymbolContext(eSymbolContextFunction | eSymbolContextBlock);
546 lldb::LanguageType method_language = eLanguageTypeUnknown;
547 bool is_instance_method = false;
548 ConstString method_object_name;
549 if (m_sc.GetFunctionMethodInfo(method_language, is_instance_method,
550 method_object_name)) {
551 if (is_instance_method && method_object_name) {
552 var_sp = variable_list->FindVariable(method_object_name);
553 if (var_sp) {
554 separator_idx = 0;
555 var_expr_storage = "->";
556 var_expr_storage += var_expr;
557 var_expr = var_expr_storage;
558 synthetically_added_instance_object = true;
Greg Clayton288bdf92010-09-02 02:59:18 +0000559 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000560 }
Zachary Turner24bd3172016-11-17 01:37:52 +0000561 }
562 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000563
Zachary Turner24bd3172016-11-17 01:37:52 +0000564 if (!var_sp && (options & eExpressionPathOptionsInspectAnonymousUnions)) {
565 // Check if any anonymous unions are there which contain a variable with
566 // the name we need
567 for (size_t i = 0; i < variable_list->GetSize(); i++) {
568 VariableSP variable_sp = variable_list->GetVariableAtIndex(i);
569 if (!variable_sp)
570 continue;
571 if (!variable_sp->GetName().IsEmpty())
572 continue;
573
574 Type *var_type = variable_sp->GetType();
575 if (!var_type)
576 continue;
577
578 if (!var_type->GetForwardCompilerType().IsAnonymousType())
579 continue;
580 valobj_sp = GetValueObjectForFrameVariable(variable_sp, use_dynamic);
581 if (!valobj_sp)
582 return valobj_sp;
583 valobj_sp = valobj_sp->GetChildMemberWithName(name_const_string, true);
584 if (valobj_sp)
585 break;
586 }
587 }
588
589 if (var_sp && !valobj_sp) {
590 valobj_sp = GetValueObjectForFrameVariable(var_sp, use_dynamic);
591 if (!valobj_sp)
592 return valobj_sp;
593 }
594 if (!valobj_sp) {
595 error.SetErrorStringWithFormat("no variable named '%s' found in this frame",
596 name_const_string.GetCString());
597 return ValueObjectSP();
598 }
599
600 // We are dumping at least one child
601 while (separator_idx != std::string::npos) {
602 // Calculate the next separator index ahead of time
603 ValueObjectSP child_valobj_sp;
604 const char separator_type = var_expr[0];
Tamas Berghammer4c08fe22017-03-31 20:23:22 +0000605 bool expr_is_ptr = false;
Zachary Turner24bd3172016-11-17 01:37:52 +0000606 switch (separator_type) {
607 case '-':
Tamas Berghammer4c08fe22017-03-31 20:23:22 +0000608 expr_is_ptr = true;
Zachary Turner24bd3172016-11-17 01:37:52 +0000609 if (var_expr.size() >= 2 && var_expr[1] != '>')
610 return ValueObjectSP();
611
612 if (no_fragile_ivar) {
613 // Make sure we aren't trying to deref an objective
614 // C ivar if this is not allowed
615 const uint32_t pointer_type_flags =
616 valobj_sp->GetCompilerType().GetTypeInfo(nullptr);
617 if ((pointer_type_flags & eTypeIsObjC) &&
618 (pointer_type_flags & eTypeIsPointer)) {
Adrian Prantl05097242018-04-30 16:49:04 +0000619 // This was an objective C object pointer and it was requested we
620 // skip any fragile ivars so return nothing here
Zachary Turner24bd3172016-11-17 01:37:52 +0000621 return ValueObjectSP();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000622 }
623 }
Tamas Berghammer4c08fe22017-03-31 20:23:22 +0000624
625 // If we have a non pointer type with a sythetic value then lets check if
626 // we have an sythetic dereference specified.
627 if (!valobj_sp->IsPointerType() && valobj_sp->HasSyntheticValue()) {
Zachary Turner97206d52017-05-12 04:51:55 +0000628 Status deref_error;
Tamas Berghammer4c08fe22017-03-31 20:23:22 +0000629 if (valobj_sp->GetCompilerType().IsReferenceType()) {
630 valobj_sp = valobj_sp->GetSyntheticValue()->Dereference(deref_error);
631 if (error.Fail()) {
632 error.SetErrorStringWithFormatv(
633 "Failed to dereference reference type: %s", deref_error);
634 return ValueObjectSP();
635 }
636 }
637
638 valobj_sp = valobj_sp->Dereference(deref_error);
639 if (error.Fail()) {
640 error.SetErrorStringWithFormatv(
641 "Failed to dereference sythetic value: %s", deref_error);
642 return ValueObjectSP();
643 }
644 expr_is_ptr = false;
645 }
646
Zachary Turner24bd3172016-11-17 01:37:52 +0000647 var_expr = var_expr.drop_front(); // Remove the '-'
648 LLVM_FALLTHROUGH;
649 case '.': {
Zachary Turner24bd3172016-11-17 01:37:52 +0000650 var_expr = var_expr.drop_front(); // Remove the '.' or '>'
651 separator_idx = var_expr.find_first_of(".-[");
652 ConstString child_name(var_expr.substr(0, var_expr.find_first_of(".-[")));
653
654 if (check_ptr_vs_member) {
Adrian Prantl05097242018-04-30 16:49:04 +0000655 // We either have a pointer type and need to verify valobj_sp is a
656 // pointer, or we have a member of a class/union/struct being accessed
657 // with the . syntax and need to verify we don't have a pointer.
Zachary Turner24bd3172016-11-17 01:37:52 +0000658 const bool actual_is_ptr = valobj_sp->IsPointerType();
659
660 if (actual_is_ptr != expr_is_ptr) {
Adrian Prantl05097242018-04-30 16:49:04 +0000661 // Incorrect use of "." with a pointer, or "->" with a
662 // class/union/struct instance or reference.
Zachary Turner24bd3172016-11-17 01:37:52 +0000663 valobj_sp->GetExpressionPath(var_expr_path_strm, false);
664 if (actual_is_ptr)
665 error.SetErrorStringWithFormat(
666 "\"%s\" is a pointer and . was used to attempt to access "
667 "\"%s\". Did you mean \"%s->%s\"?",
668 var_expr_path_strm.GetData(), child_name.GetCString(),
669 var_expr_path_strm.GetData(), var_expr.str().c_str());
670 else
671 error.SetErrorStringWithFormat(
672 "\"%s\" is not a pointer and -> was used to attempt to "
673 "access \"%s\". Did you mean \"%s.%s\"?",
674 var_expr_path_strm.GetData(), child_name.GetCString(),
675 var_expr_path_strm.GetData(), var_expr.str().c_str());
676 return ValueObjectSP();
677 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000678 }
Zachary Turner24bd3172016-11-17 01:37:52 +0000679 child_valobj_sp = valobj_sp->GetChildMemberWithName(child_name, true);
680 if (!child_valobj_sp) {
681 if (!no_synth_child) {
682 child_valobj_sp = valobj_sp->GetSyntheticValue();
683 if (child_valobj_sp)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000684 child_valobj_sp =
Zachary Turner24bd3172016-11-17 01:37:52 +0000685 child_valobj_sp->GetChildMemberWithName(child_name, true);
686 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000687
Zachary Turner24bd3172016-11-17 01:37:52 +0000688 if (no_synth_child || !child_valobj_sp) {
689 // No child member with name "child_name"
690 if (synthetically_added_instance_object) {
691 // We added a "this->" or "self->" to the beginning of the
Adrian Prantl05097242018-04-30 16:49:04 +0000692 // expression and this is the first pointer ivar access, so just
693 // return the normal error
Zachary Turner24bd3172016-11-17 01:37:52 +0000694 error.SetErrorStringWithFormat(
695 "no variable or instance variable named '%s' found in "
696 "this frame",
697 name_const_string.GetCString());
698 } else {
699 valobj_sp->GetExpressionPath(var_expr_path_strm, false);
700 if (child_name) {
701 error.SetErrorStringWithFormat(
702 "\"%s\" is not a member of \"(%s) %s\"",
703 child_name.GetCString(),
704 valobj_sp->GetTypeName().AsCString("<invalid type>"),
705 var_expr_path_strm.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000706 } else {
707 error.SetErrorStringWithFormat(
Zachary Turner24bd3172016-11-17 01:37:52 +0000708 "incomplete expression path after \"%s\" in \"%s\"",
Zachary Turner0eb31a12016-11-17 05:14:32 +0000709 var_expr_path_strm.GetData(),
710 original_var_expr.str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000711 }
Zachary Turner24bd3172016-11-17 01:37:52 +0000712 }
713 return ValueObjectSP();
714 }
715 }
716 synthetically_added_instance_object = false;
717 // Remove the child name from the path
718 var_expr = var_expr.drop_front(child_name.GetLength());
719 if (use_dynamic != eNoDynamicValues) {
720 ValueObjectSP dynamic_value_sp(
721 child_valobj_sp->GetDynamicValue(use_dynamic));
722 if (dynamic_value_sp)
723 child_valobj_sp = dynamic_value_sp;
724 }
725 } break;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000726
Zachary Turner24bd3172016-11-17 01:37:52 +0000727 case '[': {
Adrian Prantl05097242018-04-30 16:49:04 +0000728 // Array member access, or treating pointer as an array Need at least two
729 // brackets and a number
Zachary Turner24bd3172016-11-17 01:37:52 +0000730 if (var_expr.size() <= 2) {
731 error.SetErrorStringWithFormat(
732 "invalid square bracket encountered after \"%s\" in \"%s\"",
733 var_expr_path_strm.GetData(), var_expr.str().c_str());
734 return ValueObjectSP();
735 }
736
737 // Drop the open brace.
738 var_expr = var_expr.drop_front();
739 long child_index = 0;
740
741 // If there's no closing brace, this is an invalid expression.
742 size_t end_pos = var_expr.find_first_of(']');
743 if (end_pos == llvm::StringRef::npos) {
744 error.SetErrorStringWithFormat(
745 "missing closing square bracket in expression \"%s\"",
746 var_expr_path_strm.GetData());
747 return ValueObjectSP();
748 }
749 llvm::StringRef index_expr = var_expr.take_front(end_pos);
750 llvm::StringRef original_index_expr = index_expr;
751 // Drop all of "[index_expr]"
752 var_expr = var_expr.drop_front(end_pos + 1);
753
754 if (index_expr.consumeInteger(0, child_index)) {
755 // If there was no integer anywhere in the index expression, this is
756 // erroneous expression.
757 error.SetErrorStringWithFormat("invalid index expression \"%s\"",
758 index_expr.str().c_str());
759 return ValueObjectSP();
760 }
761
762 if (index_expr.empty()) {
763 // The entire index expression was a single integer.
764
765 if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref) {
766 // what we have is *ptr[low]. the most similar C++ syntax is to deref
767 // ptr and extract bit low out of it. reading array item low would be
768 // done by saying ptr[low], without a deref * sign
Zachary Turner97206d52017-05-12 04:51:55 +0000769 Status error;
Zachary Turner24bd3172016-11-17 01:37:52 +0000770 ValueObjectSP temp(valobj_sp->Dereference(error));
771 if (error.Fail()) {
772 valobj_sp->GetExpressionPath(var_expr_path_strm, false);
773 error.SetErrorStringWithFormat(
774 "could not dereference \"(%s) %s\"",
775 valobj_sp->GetTypeName().AsCString("<invalid type>"),
776 var_expr_path_strm.GetData());
777 return ValueObjectSP();
778 }
779 valobj_sp = temp;
780 deref = false;
781 } else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() &&
782 deref) {
Adrian Prantl05097242018-04-30 16:49:04 +0000783 // what we have is *arr[low]. the most similar C++ syntax is to get
784 // arr[0] (an operation that is equivalent to deref-ing arr) and
785 // extract bit low out of it. reading array item low would be done by
786 // saying arr[low], without a deref * sign
Zachary Turner97206d52017-05-12 04:51:55 +0000787 Status error;
Zachary Turner24bd3172016-11-17 01:37:52 +0000788 ValueObjectSP temp(valobj_sp->GetChildAtIndex(0, true));
789 if (error.Fail()) {
790 valobj_sp->GetExpressionPath(var_expr_path_strm, false);
791 error.SetErrorStringWithFormat(
792 "could not get item 0 for \"(%s) %s\"",
793 valobj_sp->GetTypeName().AsCString("<invalid type>"),
794 var_expr_path_strm.GetData());
795 return ValueObjectSP();
796 }
797 valobj_sp = temp;
798 deref = false;
799 }
800
801 bool is_incomplete_array = false;
802 if (valobj_sp->IsPointerType()) {
803 bool is_objc_pointer = true;
804
805 if (valobj_sp->GetCompilerType().GetMinimumLanguage() !=
806 eLanguageTypeObjC)
807 is_objc_pointer = false;
808 else if (!valobj_sp->GetCompilerType().IsPointerType())
809 is_objc_pointer = false;
810
811 if (no_synth_child && is_objc_pointer) {
812 error.SetErrorStringWithFormat(
813 "\"(%s) %s\" is an Objective-C pointer, and cannot be "
814 "subscripted",
815 valobj_sp->GetTypeName().AsCString("<invalid type>"),
816 var_expr_path_strm.GetData());
817
818 return ValueObjectSP();
819 } else if (is_objc_pointer) {
Adrian Prantl05097242018-04-30 16:49:04 +0000820 // dereferencing ObjC variables is not valid.. so let's try and
821 // recur to synthetic children
Zachary Turner24bd3172016-11-17 01:37:52 +0000822 ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
823 if (!synthetic /* no synthetic */
824 || synthetic == valobj_sp) /* synthetic is the same as
825 the original object */
Kate Stoneb9c1b512016-09-06 20:57:50 +0000826 {
827 valobj_sp->GetExpressionPath(var_expr_path_strm, false);
828 error.SetErrorStringWithFormat(
Zachary Turner24bd3172016-11-17 01:37:52 +0000829 "\"(%s) %s\" is not an array type",
830 valobj_sp->GetTypeName().AsCString("<invalid type>"),
831 var_expr_path_strm.GetData());
832 } else if (
833 static_cast<uint32_t>(child_index) >=
834 synthetic
835 ->GetNumChildren() /* synthetic does not have that many values */) {
836 valobj_sp->GetExpressionPath(var_expr_path_strm, false);
837 error.SetErrorStringWithFormat(
838 "array index %ld is not valid for \"(%s) %s\"", child_index,
839 valobj_sp->GetTypeName().AsCString("<invalid type>"),
840 var_expr_path_strm.GetData());
841 } else {
842 child_valobj_sp = synthetic->GetChildAtIndex(child_index, true);
843 if (!child_valobj_sp) {
844 valobj_sp->GetExpressionPath(var_expr_path_strm, false);
845 error.SetErrorStringWithFormat(
846 "array index %ld is not valid for \"(%s) %s\"", child_index,
847 valobj_sp->GetTypeName().AsCString("<invalid type>"),
848 var_expr_path_strm.GetData());
849 }
850 }
851 } else {
852 child_valobj_sp =
853 valobj_sp->GetSyntheticArrayMember(child_index, true);
854 if (!child_valobj_sp) {
855 valobj_sp->GetExpressionPath(var_expr_path_strm, false);
856 error.SetErrorStringWithFormat(
857 "failed to use pointer as array for index %ld for "
858 "\"(%s) %s\"",
859 child_index,
860 valobj_sp->GetTypeName().AsCString("<invalid type>"),
861 var_expr_path_strm.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000862 }
863 }
Zachary Turner24bd3172016-11-17 01:37:52 +0000864 } else if (valobj_sp->GetCompilerType().IsArrayType(
865 nullptr, nullptr, &is_incomplete_array)) {
Adrian Prantl05097242018-04-30 16:49:04 +0000866 // Pass false to dynamic_value here so we can tell the difference
867 // between no dynamic value and no member of this type...
Zachary Turner24bd3172016-11-17 01:37:52 +0000868 child_valobj_sp = valobj_sp->GetChildAtIndex(child_index, true);
869 if (!child_valobj_sp && (is_incomplete_array || !no_synth_child))
870 child_valobj_sp =
871 valobj_sp->GetSyntheticArrayMember(child_index, true);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000872
Zachary Turner24bd3172016-11-17 01:37:52 +0000873 if (!child_valobj_sp) {
874 valobj_sp->GetExpressionPath(var_expr_path_strm, false);
875 error.SetErrorStringWithFormat(
876 "array index %ld is not valid for \"(%s) %s\"", child_index,
877 valobj_sp->GetTypeName().AsCString("<invalid type>"),
878 var_expr_path_strm.GetData());
879 }
880 } else if (valobj_sp->GetCompilerType().IsScalarType()) {
881 // this is a bitfield asking to display just one bit
882 child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(
883 child_index, child_index, true);
884 if (!child_valobj_sp) {
885 valobj_sp->GetExpressionPath(var_expr_path_strm, false);
886 error.SetErrorStringWithFormat(
887 "bitfield range %ld-%ld is not valid for \"(%s) %s\"",
888 child_index, child_index,
889 valobj_sp->GetTypeName().AsCString("<invalid type>"),
890 var_expr_path_strm.GetData());
891 }
892 } else {
893 ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
894 if (no_synth_child /* synthetic is forbidden */ ||
895 !synthetic /* no synthetic */
896 || synthetic == valobj_sp) /* synthetic is the same as the
897 original object */
898 {
899 valobj_sp->GetExpressionPath(var_expr_path_strm, false);
900 error.SetErrorStringWithFormat(
901 "\"(%s) %s\" is not an array type",
902 valobj_sp->GetTypeName().AsCString("<invalid type>"),
903 var_expr_path_strm.GetData());
904 } else if (
905 static_cast<uint32_t>(child_index) >=
906 synthetic
907 ->GetNumChildren() /* synthetic does not have that many values */) {
908 valobj_sp->GetExpressionPath(var_expr_path_strm, false);
909 error.SetErrorStringWithFormat(
910 "array index %ld is not valid for \"(%s) %s\"", child_index,
911 valobj_sp->GetTypeName().AsCString("<invalid type>"),
912 var_expr_path_strm.GetData());
913 } else {
914 child_valobj_sp = synthetic->GetChildAtIndex(child_index, true);
915 if (!child_valobj_sp) {
916 valobj_sp->GetExpressionPath(var_expr_path_strm, false);
917 error.SetErrorStringWithFormat(
918 "array index %ld is not valid for \"(%s) %s\"", child_index,
919 valobj_sp->GetTypeName().AsCString("<invalid type>"),
920 var_expr_path_strm.GetData());
921 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000922 }
923 }
Zachary Turner24bd3172016-11-17 01:37:52 +0000924
925 if (!child_valobj_sp) {
926 // Invalid array index...
927 return ValueObjectSP();
928 }
929
930 separator_idx = var_expr.find_first_of(".-[");
931 if (use_dynamic != eNoDynamicValues) {
932 ValueObjectSP dynamic_value_sp(
933 child_valobj_sp->GetDynamicValue(use_dynamic));
934 if (dynamic_value_sp)
935 child_valobj_sp = dynamic_value_sp;
936 }
937 // Break out early from the switch since we were able to find the child
938 // member
939 break;
940 }
941
942 // this is most probably a BitField, let's take a look
943 if (index_expr.front() != '-') {
944 error.SetErrorStringWithFormat("invalid range expression \"'%s'\"",
945 original_index_expr.str().c_str());
946 return ValueObjectSP();
947 }
948
Zachary Turner7edc3a62016-11-21 23:18:13 +0000949 index_expr = index_expr.drop_front();
Zachary Turner24bd3172016-11-17 01:37:52 +0000950 long final_index = 0;
951 if (index_expr.getAsInteger(0, final_index)) {
952 error.SetErrorStringWithFormat("invalid range expression \"'%s'\"",
953 original_index_expr.str().c_str());
954 return ValueObjectSP();
955 }
956
957 // if the format given is [high-low], swap range
958 if (child_index > final_index) {
959 long temp = child_index;
960 child_index = final_index;
961 final_index = temp;
962 }
963
964 if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref) {
965 // what we have is *ptr[low-high]. the most similar C++ syntax is to
966 // deref ptr and extract bits low thru high out of it. reading array
Adrian Prantl05097242018-04-30 16:49:04 +0000967 // items low thru high would be done by saying ptr[low-high], without a
968 // deref * sign
Zachary Turner97206d52017-05-12 04:51:55 +0000969 Status error;
Zachary Turner24bd3172016-11-17 01:37:52 +0000970 ValueObjectSP temp(valobj_sp->Dereference(error));
971 if (error.Fail()) {
972 valobj_sp->GetExpressionPath(var_expr_path_strm, false);
973 error.SetErrorStringWithFormat(
974 "could not dereference \"(%s) %s\"",
975 valobj_sp->GetTypeName().AsCString("<invalid type>"),
976 var_expr_path_strm.GetData());
977 return ValueObjectSP();
978 }
979 valobj_sp = temp;
980 deref = false;
981 } else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() && deref) {
Adrian Prantl05097242018-04-30 16:49:04 +0000982 // what we have is *arr[low-high]. the most similar C++ syntax is to
983 // get arr[0] (an operation that is equivalent to deref-ing arr) and
984 // extract bits low thru high out of it. reading array items low thru
985 // high would be done by saying arr[low-high], without a deref * sign
Zachary Turner97206d52017-05-12 04:51:55 +0000986 Status error;
Zachary Turner24bd3172016-11-17 01:37:52 +0000987 ValueObjectSP temp(valobj_sp->GetChildAtIndex(0, true));
988 if (error.Fail()) {
989 valobj_sp->GetExpressionPath(var_expr_path_strm, false);
990 error.SetErrorStringWithFormat(
991 "could not get item 0 for \"(%s) %s\"",
992 valobj_sp->GetTypeName().AsCString("<invalid type>"),
993 var_expr_path_strm.GetData());
994 return ValueObjectSP();
995 }
996 valobj_sp = temp;
997 deref = false;
998 }
999
1000 child_valobj_sp =
1001 valobj_sp->GetSyntheticBitFieldChild(child_index, final_index, true);
1002 if (!child_valobj_sp) {
1003 valobj_sp->GetExpressionPath(var_expr_path_strm, false);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001004 error.SetErrorStringWithFormat(
Zachary Turner24bd3172016-11-17 01:37:52 +00001005 "bitfield range %ld-%ld is not valid for \"(%s) %s\"", child_index,
1006 final_index, valobj_sp->GetTypeName().AsCString("<invalid type>"),
1007 var_expr_path_strm.GetData());
1008 }
1009
1010 if (!child_valobj_sp) {
1011 // Invalid bitfield range...
1012 return ValueObjectSP();
1013 }
1014
1015 separator_idx = var_expr.find_first_of(".-[");
1016 if (use_dynamic != eNoDynamicValues) {
1017 ValueObjectSP dynamic_value_sp(
1018 child_valobj_sp->GetDynamicValue(use_dynamic));
1019 if (dynamic_value_sp)
1020 child_valobj_sp = dynamic_value_sp;
1021 }
1022 // Break out early from the switch since we were able to find the child
1023 // member
1024 break;
1025 }
1026 default:
1027 // Failure...
1028 {
1029 valobj_sp->GetExpressionPath(var_expr_path_strm, false);
1030 error.SetErrorStringWithFormat(
1031 "unexpected char '%c' encountered after \"%s\" in \"%s\"",
1032 separator_type, var_expr_path_strm.GetData(),
1033 var_expr.str().c_str());
1034
1035 return ValueObjectSP();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001036 }
Greg Clayton288bdf92010-09-02 02:59:18 +00001037 }
Zachary Turner24bd3172016-11-17 01:37:52 +00001038
1039 if (child_valobj_sp)
1040 valobj_sp = child_valobj_sp;
1041
1042 if (var_expr.empty())
1043 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001044 }
Zachary Turner24bd3172016-11-17 01:37:52 +00001045 if (valobj_sp) {
1046 if (deref) {
1047 ValueObjectSP deref_valobj_sp(valobj_sp->Dereference(error));
1048 valobj_sp = deref_valobj_sp;
1049 } else if (address_of) {
1050 ValueObjectSP address_of_valobj_sp(valobj_sp->AddressOf(error));
1051 valobj_sp = address_of_valobj_sp;
1052 }
1053 }
1054 return valobj_sp;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001055}
1056
Zachary Turner97206d52017-05-12 04:51:55 +00001057bool StackFrame::GetFrameBaseValue(Scalar &frame_base, Status *error_ptr) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001058 std::lock_guard<std::recursive_mutex> guard(m_mutex);
1059 if (!m_cfa_is_valid) {
1060 m_frame_base_error.SetErrorString(
1061 "No frame base available for this historical stack frame.");
1062 return false;
1063 }
1064
1065 if (m_flags.IsClear(GOT_FRAME_BASE)) {
1066 if (m_sc.function) {
1067 m_frame_base.Clear();
1068 m_frame_base_error.Clear();
1069
1070 m_flags.Set(GOT_FRAME_BASE);
1071 ExecutionContext exe_ctx(shared_from_this());
1072 Value expr_value;
1073 addr_t loclist_base_addr = LLDB_INVALID_ADDRESS;
1074 if (m_sc.function->GetFrameBaseExpression().IsLocationList())
1075 loclist_base_addr =
1076 m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress(
1077 exe_ctx.GetTargetPtr());
1078
1079 if (m_sc.function->GetFrameBaseExpression().Evaluate(
Tamas Berghammerbba2c832017-08-16 11:45:10 +00001080 &exe_ctx, nullptr, loclist_base_addr, nullptr, nullptr,
1081 expr_value, &m_frame_base_error) == false) {
Adrian Prantl05097242018-04-30 16:49:04 +00001082 // We should really have an error if evaluate returns, but in case we
1083 // don't, lets set the error to something at least.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001084 if (m_frame_base_error.Success())
1085 m_frame_base_error.SetErrorString(
1086 "Evaluation of the frame base expression failed.");
1087 } else {
1088 m_frame_base = expr_value.ResolveValue(&exe_ctx);
1089 }
1090 } else {
1091 m_frame_base_error.SetErrorString("No function in symbol context.");
Jim Ingham78a685a2011-04-16 00:01:13 +00001092 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001093 }
1094
1095 if (m_frame_base_error.Success())
1096 frame_base = m_frame_base;
1097
1098 if (error_ptr)
1099 *error_ptr = m_frame_base_error;
1100 return m_frame_base_error.Success();
1101}
1102
Zachary Turner97206d52017-05-12 04:51:55 +00001103DWARFExpression *StackFrame::GetFrameBaseExpression(Status *error_ptr) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001104 if (!m_sc.function) {
1105 if (error_ptr) {
1106 error_ptr->SetErrorString("No function in symbol context.");
1107 }
1108 return nullptr;
1109 }
1110
1111 return &m_sc.function->GetFrameBaseExpression();
1112}
1113
1114RegisterContextSP StackFrame::GetRegisterContext() {
1115 std::lock_guard<std::recursive_mutex> guard(m_mutex);
1116 if (!m_reg_context_sp) {
1117 ThreadSP thread_sp(GetThread());
1118 if (thread_sp)
1119 m_reg_context_sp = thread_sp->CreateRegisterContextForFrame(this);
1120 }
1121 return m_reg_context_sp;
1122}
1123
1124bool StackFrame::HasDebugInformation() {
1125 GetSymbolContext(eSymbolContextLineEntry);
1126 return m_sc.line_entry.IsValid();
Greg Clayton288bdf92010-09-02 02:59:18 +00001127}
1128
1129ValueObjectSP
Kate Stoneb9c1b512016-09-06 20:57:50 +00001130StackFrame::GetValueObjectForFrameVariable(const VariableSP &variable_sp,
1131 DynamicValueType use_dynamic) {
1132 std::lock_guard<std::recursive_mutex> guard(m_mutex);
1133 ValueObjectSP valobj_sp;
Vedant Kumar4b36f792018-10-05 23:23:15 +00001134 if (IsHistorical()) {
Greg Clayton288bdf92010-09-02 02:59:18 +00001135 return valobj_sp;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001136 }
1137 VariableList *var_list = GetVariableList(true);
1138 if (var_list) {
1139 // Make sure the variable is a frame variable
1140 const uint32_t var_idx = var_list->FindIndexForVariable(variable_sp.get());
1141 const uint32_t num_variables = var_list->GetSize();
1142 if (var_idx < num_variables) {
1143 valobj_sp = m_variable_list_value_objects.GetValueObjectAtIndex(var_idx);
1144 if (!valobj_sp) {
1145 if (m_variable_list_value_objects.GetSize() < num_variables)
1146 m_variable_list_value_objects.Resize(num_variables);
1147 valobj_sp = ValueObjectVariable::Create(this, variable_sp);
1148 m_variable_list_value_objects.SetValueObjectAtIndex(var_idx, valobj_sp);
1149 }
Enrico Granata592afe72016-03-15 21:50:51 +00001150 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001151 }
1152 if (use_dynamic != eNoDynamicValues && valobj_sp) {
1153 ValueObjectSP dynamic_sp = valobj_sp->GetDynamicValue(use_dynamic);
1154 if (dynamic_sp)
1155 return dynamic_sp;
1156 }
1157 return valobj_sp;
Enrico Granata592afe72016-03-15 21:50:51 +00001158}
1159
Kate Stoneb9c1b512016-09-06 20:57:50 +00001160ValueObjectSP StackFrame::TrackGlobalVariable(const VariableSP &variable_sp,
1161 DynamicValueType use_dynamic) {
1162 std::lock_guard<std::recursive_mutex> guard(m_mutex);
Vedant Kumar4b36f792018-10-05 23:23:15 +00001163 if (IsHistorical())
Kate Stoneb9c1b512016-09-06 20:57:50 +00001164 return ValueObjectSP();
1165
1166 // Check to make sure we aren't already tracking this variable?
1167 ValueObjectSP valobj_sp(
1168 GetValueObjectForFrameVariable(variable_sp, use_dynamic));
1169 if (!valobj_sp) {
1170 // We aren't already tracking this global
1171 VariableList *var_list = GetVariableList(true);
1172 // If this frame has no variables, create a new list
1173 if (var_list == nullptr)
1174 m_variable_list_sp.reset(new VariableList());
1175
1176 // Add the global/static variable to this frame
1177 m_variable_list_sp->AddVariable(variable_sp);
1178
1179 // Now make a value object for it so we can track its changes
1180 valobj_sp = GetValueObjectForFrameVariable(variable_sp, use_dynamic);
1181 }
1182 return valobj_sp;
1183}
1184
1185bool StackFrame::IsInlined() {
1186 if (m_sc.block == nullptr)
1187 GetSymbolContext(eSymbolContextBlock);
1188 if (m_sc.block)
1189 return m_sc.block->GetContainingInlinedBlock() != nullptr;
1190 return false;
1191}
1192
Vedant Kumar4b36f792018-10-05 23:23:15 +00001193bool StackFrame::IsHistorical() const {
1194 return m_stack_frame_kind == StackFrame::Kind::History;
1195}
1196
1197bool StackFrame::IsArtificial() const {
1198 return m_stack_frame_kind == StackFrame::Kind::Artificial;
1199}
1200
Kate Stoneb9c1b512016-09-06 20:57:50 +00001201lldb::LanguageType StackFrame::GetLanguage() {
1202 CompileUnit *cu = GetSymbolContext(eSymbolContextCompUnit).comp_unit;
1203 if (cu)
1204 return cu->GetLanguage();
1205 return lldb::eLanguageTypeUnknown;
1206}
1207
1208lldb::LanguageType StackFrame::GuessLanguage() {
1209 LanguageType lang_type = GetLanguage();
1210
1211 if (lang_type == eLanguageTypeUnknown) {
Jim Inghambdbdd222017-04-12 00:19:54 +00001212 SymbolContext sc = GetSymbolContext(eSymbolContextFunction
1213 | eSymbolContextSymbol);
1214 if (sc.function) {
1215 lang_type = sc.function->GetMangled().GuessLanguage();
1216 }
1217 else if (sc.symbol)
1218 {
1219 lang_type = sc.symbol->GetMangled().GuessLanguage();
Sean Callanan4740a732016-09-06 04:48:36 +00001220 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001221 }
1222
1223 return lang_type;
1224}
1225
1226namespace {
1227std::pair<const Instruction::Operand *, int64_t>
1228GetBaseExplainingValue(const Instruction::Operand &operand,
1229 RegisterContext &register_context, lldb::addr_t value) {
1230 switch (operand.m_type) {
1231 case Instruction::Operand::Type::Dereference:
1232 case Instruction::Operand::Type::Immediate:
1233 case Instruction::Operand::Type::Invalid:
1234 case Instruction::Operand::Type::Product:
1235 // These are not currently interesting
1236 return std::make_pair(nullptr, 0);
1237 case Instruction::Operand::Type::Sum: {
1238 const Instruction::Operand *immediate_child = nullptr;
1239 const Instruction::Operand *variable_child = nullptr;
1240 if (operand.m_children[0].m_type == Instruction::Operand::Type::Immediate) {
1241 immediate_child = &operand.m_children[0];
1242 variable_child = &operand.m_children[1];
1243 } else if (operand.m_children[1].m_type ==
1244 Instruction::Operand::Type::Immediate) {
1245 immediate_child = &operand.m_children[1];
1246 variable_child = &operand.m_children[0];
Sean Callanan4740a732016-09-06 04:48:36 +00001247 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001248 if (!immediate_child) {
1249 return std::make_pair(nullptr, 0);
1250 }
1251 lldb::addr_t adjusted_value = value;
1252 if (immediate_child->m_negative) {
1253 adjusted_value += immediate_child->m_immediate;
1254 } else {
1255 adjusted_value -= immediate_child->m_immediate;
1256 }
1257 std::pair<const Instruction::Operand *, int64_t> base_and_offset =
1258 GetBaseExplainingValue(*variable_child, register_context,
1259 adjusted_value);
1260 if (!base_and_offset.first) {
1261 return std::make_pair(nullptr, 0);
1262 }
1263 if (immediate_child->m_negative) {
1264 base_and_offset.second -= immediate_child->m_immediate;
1265 } else {
1266 base_and_offset.second += immediate_child->m_immediate;
1267 }
1268 return base_and_offset;
1269 }
1270 case Instruction::Operand::Type::Register: {
1271 const RegisterInfo *info =
1272 register_context.GetRegisterInfoByName(operand.m_register.AsCString());
1273 if (!info) {
1274 return std::make_pair(nullptr, 0);
1275 }
1276 RegisterValue reg_value;
1277 if (!register_context.ReadRegister(info, reg_value)) {
1278 return std::make_pair(nullptr, 0);
1279 }
1280 if (reg_value.GetAsUInt64() == value) {
1281 return std::make_pair(&operand, 0);
1282 } else {
1283 return std::make_pair(nullptr, 0);
1284 }
1285 }
1286 }
Zachary Turner5a8ad4592016-10-05 17:07:34 +00001287 return std::make_pair(nullptr, 0);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001288}
1289
1290std::pair<const Instruction::Operand *, int64_t>
1291GetBaseExplainingDereference(const Instruction::Operand &operand,
1292 RegisterContext &register_context,
1293 lldb::addr_t addr) {
1294 if (operand.m_type == Instruction::Operand::Type::Dereference) {
1295 return GetBaseExplainingValue(operand.m_children[0], register_context,
1296 addr);
1297 }
1298 return std::make_pair(nullptr, 0);
1299}
Ilia K4f730dc2016-09-12 05:25:33 +00001300}
Sean Callanan4740a732016-09-06 04:48:36 +00001301
Kate Stoneb9c1b512016-09-06 20:57:50 +00001302lldb::ValueObjectSP StackFrame::GuessValueForAddress(lldb::addr_t addr) {
1303 TargetSP target_sp = CalculateTarget();
Sean Callanan4740a732016-09-06 04:48:36 +00001304
Kate Stoneb9c1b512016-09-06 20:57:50 +00001305 const ArchSpec &target_arch = target_sp->GetArchitecture();
1306
1307 AddressRange pc_range;
1308 pc_range.GetBaseAddress() = GetFrameCodeAddress();
1309 pc_range.SetByteSize(target_arch.GetMaximumOpcodeByteSize());
1310
1311 ExecutionContext exe_ctx(shared_from_this());
1312
1313 const char *plugin_name = nullptr;
1314 const char *flavor = nullptr;
1315 const bool prefer_file_cache = false;
1316
1317 DisassemblerSP disassembler_sp = Disassembler::DisassembleRange(
1318 target_arch, plugin_name, flavor, exe_ctx, pc_range, prefer_file_cache);
1319
Jim Ingham99d1e282017-03-31 22:39:55 +00001320 if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) {
Sean Callanan4740a732016-09-06 04:48:36 +00001321 return ValueObjectSP();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001322 }
Sean Callanan4740a732016-09-06 04:48:36 +00001323
Kate Stoneb9c1b512016-09-06 20:57:50 +00001324 InstructionSP instruction_sp =
1325 disassembler_sp->GetInstructionList().GetInstructionAtIndex(0);
1326
1327 llvm::SmallVector<Instruction::Operand, 3> operands;
1328
1329 if (!instruction_sp->ParseOperands(operands)) {
1330 return ValueObjectSP();
1331 }
1332
1333 RegisterContextSP register_context_sp = GetRegisterContext();
1334
1335 if (!register_context_sp) {
1336 return ValueObjectSP();
1337 }
1338
1339 for (const Instruction::Operand &operand : operands) {
1340 std::pair<const Instruction::Operand *, int64_t> base_and_offset =
1341 GetBaseExplainingDereference(operand, *register_context_sp, addr);
1342
1343 if (!base_and_offset.first) {
1344 continue;
Sean Callanan4740a732016-09-06 04:48:36 +00001345 }
Sean Callanan4740a732016-09-06 04:48:36 +00001346
Kate Stoneb9c1b512016-09-06 20:57:50 +00001347 switch (base_and_offset.first->m_type) {
1348 case Instruction::Operand::Type::Immediate: {
1349 lldb_private::Address addr;
1350 if (target_sp->ResolveLoadAddress(base_and_offset.first->m_immediate +
1351 base_and_offset.second,
1352 addr)) {
1353 TypeSystem *c_type_system =
1354 target_sp->GetScratchTypeSystemForLanguage(nullptr, eLanguageTypeC);
1355 if (!c_type_system) {
1356 return ValueObjectSP();
1357 } else {
1358 CompilerType void_ptr_type =
1359 c_type_system
1360 ->GetBasicTypeFromAST(lldb::BasicType::eBasicTypeChar)
1361 .GetPointerType();
1362 return ValueObjectMemory::Create(this, "", addr, void_ptr_type);
Sean Callanan4740a732016-09-06 04:48:36 +00001363 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001364 } else {
Sean Callanan4740a732016-09-06 04:48:36 +00001365 return ValueObjectSP();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001366 }
1367 break;
Sean Callanan4740a732016-09-06 04:48:36 +00001368 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001369 case Instruction::Operand::Type::Register: {
1370 return GuessValueForRegisterAndOffset(base_and_offset.first->m_register,
1371 base_and_offset.second);
1372 }
1373 default:
1374 return ValueObjectSP();
1375 }
1376 }
1377
1378 return ValueObjectSP();
Sean Callanan4740a732016-09-06 04:48:36 +00001379}
1380
Kate Stoneb9c1b512016-09-06 20:57:50 +00001381namespace {
1382ValueObjectSP GetValueForOffset(StackFrame &frame, ValueObjectSP &parent,
1383 int64_t offset) {
1384 if (offset < 0 || uint64_t(offset) >= parent->GetByteSize()) {
1385 return ValueObjectSP();
1386 }
Sean Callanan4740a732016-09-06 04:48:36 +00001387
Kate Stoneb9c1b512016-09-06 20:57:50 +00001388 if (parent->IsPointerOrReferenceType()) {
1389 return parent;
1390 }
1391
1392 for (int ci = 0, ce = parent->GetNumChildren(); ci != ce; ++ci) {
1393 const bool can_create = true;
1394 ValueObjectSP child_sp = parent->GetChildAtIndex(ci, can_create);
1395
1396 if (!child_sp) {
1397 return ValueObjectSP();
Sean Callanan4740a732016-09-06 04:48:36 +00001398 }
1399
Kate Stoneb9c1b512016-09-06 20:57:50 +00001400 int64_t child_offset = child_sp->GetByteOffset();
1401 int64_t child_size = child_sp->GetByteSize();
1402
1403 if (offset >= child_offset && offset < (child_offset + child_size)) {
1404 return GetValueForOffset(frame, child_sp, offset - child_offset);
Sean Callanan4740a732016-09-06 04:48:36 +00001405 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001406 }
Sean Callanan4740a732016-09-06 04:48:36 +00001407
Kate Stoneb9c1b512016-09-06 20:57:50 +00001408 if (offset == 0) {
1409 return parent;
1410 } else {
1411 return ValueObjectSP();
1412 }
1413}
1414
1415ValueObjectSP GetValueForDereferincingOffset(StackFrame &frame,
1416 ValueObjectSP &base,
1417 int64_t offset) {
1418 // base is a pointer to something
Adrian Prantl05097242018-04-30 16:49:04 +00001419 // offset is the thing to add to the pointer We return the most sensible
1420 // ValueObject for the result of *(base+offset)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001421
1422 if (!base->IsPointerOrReferenceType()) {
1423 return ValueObjectSP();
1424 }
1425
Zachary Turner97206d52017-05-12 04:51:55 +00001426 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001427 ValueObjectSP pointee = base->Dereference(error);
Sean Callanana0a1d2d2016-09-29 00:16:37 +00001428
1429 if (!pointee) {
1430 return ValueObjectSP();
1431 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001432
Ilia K4f730dc2016-09-12 05:25:33 +00001433 if (offset >= 0 && uint64_t(offset) >= pointee->GetByteSize()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001434 int64_t index = offset / pointee->GetByteSize();
1435 offset = offset % pointee->GetByteSize();
1436 const bool can_create = true;
1437 pointee = base->GetSyntheticArrayMember(index, can_create);
1438 }
1439
1440 if (!pointee || error.Fail()) {
1441 return ValueObjectSP();
1442 }
1443
1444 return GetValueForOffset(frame, pointee, offset);
1445}
1446
1447//------------------------------------------------------------------
1448/// Attempt to reconstruct the ValueObject for the address contained in a
1449/// given register plus an offset.
1450///
1451/// @params [in] frame
1452/// The current stack frame.
1453///
1454/// @params [in] reg
1455/// The register.
1456///
1457/// @params [in] offset
1458/// The offset from the register.
1459///
1460/// @param [in] disassembler
1461/// A disassembler containing instructions valid up to the current PC.
1462///
1463/// @param [in] variables
1464/// The variable list from the current frame,
1465///
1466/// @param [in] pc
1467/// The program counter for the instruction considered the 'user'.
1468///
1469/// @return
1470/// A string describing the base for the ExpressionPath. This could be a
1471/// variable, a register value, an argument, or a function return value.
1472/// The ValueObject if found. If valid, it has a valid ExpressionPath.
1473//------------------------------------------------------------------
1474lldb::ValueObjectSP DoGuessValueAt(StackFrame &frame, ConstString reg,
1475 int64_t offset, Disassembler &disassembler,
1476 VariableList &variables, const Address &pc) {
1477 // Example of operation for Intel:
1478 //
1479 // +14: movq -0x8(%rbp), %rdi
1480 // +18: movq 0x8(%rdi), %rdi
1481 // +22: addl 0x4(%rdi), %eax
1482 //
1483 // f, a pointer to a struct, is known to be at -0x8(%rbp).
1484 //
Adrian Prantl05097242018-04-30 16:49:04 +00001485 // DoGuessValueAt(frame, rdi, 4, dis, vars, 0x22) finds the instruction at
1486 // +18 that assigns to rdi, and calls itself recursively for that dereference
Kate Stoneb9c1b512016-09-06 20:57:50 +00001487 // DoGuessValueAt(frame, rdi, 8, dis, vars, 0x18) finds the instruction at
1488 // +14 that assigns to rdi, and calls itself recursively for that
1489 // derefernece
1490 // DoGuessValueAt(frame, rbp, -8, dis, vars, 0x14) finds "f" in the
1491 // variable list.
1492 // Returns a ValueObject for f. (That's what was stored at rbp-8 at +14)
1493 // Returns a ValueObject for *(f+8) or f->b (That's what was stored at rdi+8
1494 // at +18)
1495 // Returns a ValueObject for *(f->b+4) or f->b->a (That's what was stored at
1496 // rdi+4 at +22)
1497
1498 // First, check the variable list to see if anything is at the specified
1499 // location.
Sean Callanan807ee2f2016-09-13 21:18:27 +00001500
Sean Callanan50857102016-09-14 00:48:19 +00001501 using namespace OperandMatchers;
1502
Sean Callanan0ac172d2016-09-14 20:29:57 +00001503 const RegisterInfo *reg_info =
1504 frame.GetRegisterContext()->GetRegisterInfoByName(reg.AsCString());
1505 if (!reg_info) {
1506 return ValueObjectSP();
1507 }
1508
Sean Callanan807ee2f2016-09-13 21:18:27 +00001509 Instruction::Operand op =
1510 offset ? Instruction::Operand::BuildDereference(
1511 Instruction::Operand::BuildSum(
1512 Instruction::Operand::BuildRegister(reg),
1513 Instruction::Operand::BuildImmediate(offset)))
1514 : Instruction::Operand::BuildDereference(
1515 Instruction::Operand::BuildRegister(reg));
1516
Kate Stoneb9c1b512016-09-06 20:57:50 +00001517 for (size_t vi = 0, ve = variables.GetSize(); vi != ve; ++vi) {
1518 VariableSP var_sp = variables.GetVariableAtIndex(vi);
Sean Callanan807ee2f2016-09-13 21:18:27 +00001519 if (var_sp->LocationExpression().MatchesOperand(frame, op)) {
1520 return frame.GetValueObjectForFrameVariable(var_sp, eNoDynamicValues);
Sean Callanan4740a732016-09-06 04:48:36 +00001521 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001522 }
1523
Kate Stoneb9c1b512016-09-06 20:57:50 +00001524 const uint32_t current_inst =
1525 disassembler.GetInstructionList().GetIndexOfInstructionAtAddress(pc);
1526 if (current_inst == UINT32_MAX) {
1527 return ValueObjectSP();
1528 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001529
Kate Stoneb9c1b512016-09-06 20:57:50 +00001530 for (uint32_t ii = current_inst - 1; ii != (uint32_t)-1; --ii) {
1531 // This is not an exact algorithm, and it sacrifices accuracy for
Adrian Prantl05097242018-04-30 16:49:04 +00001532 // generality. Recognizing "mov" and "ld" instructions –– and which
1533 // are their source and destination operands -- is something the
1534 // disassembler should do for us.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001535 InstructionSP instruction_sp =
1536 disassembler.GetInstructionList().GetInstructionAtIndex(ii);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001537
Sean Callanan50857102016-09-14 00:48:19 +00001538 if (instruction_sp->IsCall()) {
1539 ABISP abi_sp = frame.CalculateProcess()->GetABI();
1540 if (!abi_sp) {
1541 continue;
1542 }
1543
1544 const char *return_register_name;
1545 if (!abi_sp->GetPointerReturnRegister(return_register_name)) {
1546 continue;
1547 }
1548
1549 const RegisterInfo *return_register_info =
1550 frame.GetRegisterContext()->GetRegisterInfoByName(
1551 return_register_name);
1552 if (!return_register_info) {
1553 continue;
1554 }
1555
1556 int64_t offset = 0;
1557
1558 if (!MatchUnaryOp(MatchOpType(Instruction::Operand::Type::Dereference),
1559 MatchRegOp(*return_register_info))(op) &&
1560 !MatchUnaryOp(
1561 MatchOpType(Instruction::Operand::Type::Dereference),
1562 MatchBinaryOp(MatchOpType(Instruction::Operand::Type::Sum),
1563 MatchRegOp(*return_register_info),
1564 FetchImmOp(offset)))(op)) {
1565 continue;
1566 }
1567
Kate Stoneb9c1b512016-09-06 20:57:50 +00001568 llvm::SmallVector<Instruction::Operand, 1> operands;
1569 if (!instruction_sp->ParseOperands(operands) || operands.size() != 1) {
1570 continue;
1571 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001572
Kate Stoneb9c1b512016-09-06 20:57:50 +00001573 switch (operands[0].m_type) {
1574 default:
1575 break;
1576 case Instruction::Operand::Type::Immediate: {
1577 SymbolContext sc;
1578 Address load_address;
1579 if (!frame.CalculateTarget()->ResolveLoadAddress(
1580 operands[0].m_immediate, load_address)) {
1581 break;
Greg Clayton7260f622011-04-18 08:33:37 +00001582 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001583 frame.CalculateTarget()->GetImages().ResolveSymbolContextForAddress(
1584 load_address, eSymbolContextFunction, sc);
1585 if (!sc.function) {
1586 break;
1587 }
1588 CompilerType function_type = sc.function->GetCompilerType();
1589 if (!function_type.IsFunctionType()) {
1590 break;
1591 }
1592 CompilerType return_type = function_type.GetFunctionReturnType();
1593 RegisterValue return_value;
Sean Callanan50857102016-09-14 00:48:19 +00001594 if (!frame.GetRegisterContext()->ReadRegister(return_register_info,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001595 return_value)) {
1596 break;
1597 }
1598 std::string name_str(
1599 sc.function->GetName().AsCString("<unknown function>"));
1600 name_str.append("()");
1601 Address return_value_address(return_value.GetAsUInt64());
1602 ValueObjectSP return_value_sp = ValueObjectMemory::Create(
Zachary Turner22a26282016-11-12 18:17:36 +00001603 &frame, name_str, return_value_address, return_type);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001604 return GetValueForDereferincingOffset(frame, return_value_sp, offset);
1605 }
1606 }
1607
1608 continue;
Greg Clayton7260f622011-04-18 08:33:37 +00001609 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001610
1611 llvm::SmallVector<Instruction::Operand, 2> operands;
1612 if (!instruction_sp->ParseOperands(operands) || operands.size() != 2) {
1613 continue;
1614 }
1615
Kate Stoneb9c1b512016-09-06 20:57:50 +00001616 Instruction::Operand *origin_operand = nullptr;
Sean Callananaa4b44c2016-09-14 20:58:31 +00001617 auto clobbered_reg_matcher = [reg_info](const Instruction::Operand &op) {
1618 return MatchRegOp(*reg_info)(op) && op.m_clobbered;
1619 };
Sean Callanan0ac172d2016-09-14 20:29:57 +00001620
1621 if (clobbered_reg_matcher(operands[0])) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001622 origin_operand = &operands[1];
Sean Callanan0ac172d2016-09-14 20:29:57 +00001623 }
1624 else if (clobbered_reg_matcher(operands[1])) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001625 origin_operand = &operands[0];
Sean Callanan0ac172d2016-09-14 20:29:57 +00001626 }
1627 else {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001628 continue;
1629 }
1630
1631 // We have an origin operand. Can we track its value down?
Sean Callanan561a9bb2016-09-14 21:54:28 +00001632 ValueObjectSP source_path;
1633 ConstString origin_register;
1634 int64_t origin_offset = 0;
1635
1636 if (FetchRegOp(origin_register)(*origin_operand)) {
1637 source_path = DoGuessValueAt(frame, origin_register, 0, disassembler,
1638 variables, instruction_sp->GetAddress());
1639 } else if (MatchUnaryOp(
1640 MatchOpType(Instruction::Operand::Type::Dereference),
1641 FetchRegOp(origin_register))(*origin_operand) ||
1642 MatchUnaryOp(
1643 MatchOpType(Instruction::Operand::Type::Dereference),
1644 MatchBinaryOp(MatchOpType(Instruction::Operand::Type::Sum),
1645 FetchRegOp(origin_register),
1646 FetchImmOp(origin_offset)))(*origin_operand)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001647 source_path =
Sean Callanan561a9bb2016-09-14 21:54:28 +00001648 DoGuessValueAt(frame, origin_register, origin_offset, disassembler,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001649 variables, instruction_sp->GetAddress());
Sean Callanan561a9bb2016-09-14 21:54:28 +00001650 if (!source_path) {
1651 continue;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001652 }
Sean Callanan561a9bb2016-09-14 21:54:28 +00001653 source_path =
1654 GetValueForDereferincingOffset(frame, source_path, offset);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001655 }
1656
1657 if (source_path) {
1658 return source_path;
1659 }
1660 }
1661
1662 return ValueObjectSP();
1663}
1664}
1665
1666lldb::ValueObjectSP StackFrame::GuessValueForRegisterAndOffset(ConstString reg,
1667 int64_t offset) {
1668 TargetSP target_sp = CalculateTarget();
1669
1670 const ArchSpec &target_arch = target_sp->GetArchitecture();
1671
1672 Block *frame_block = GetFrameBlock();
1673
1674 if (!frame_block) {
1675 return ValueObjectSP();
1676 }
1677
1678 Function *function = frame_block->CalculateSymbolContextFunction();
1679 if (!function) {
1680 return ValueObjectSP();
1681 }
1682
1683 AddressRange pc_range = function->GetAddressRange();
1684
1685 if (GetFrameCodeAddress().GetFileAddress() <
1686 pc_range.GetBaseAddress().GetFileAddress() ||
1687 GetFrameCodeAddress().GetFileAddress() -
1688 pc_range.GetBaseAddress().GetFileAddress() >=
1689 pc_range.GetByteSize()) {
1690 return ValueObjectSP();
1691 }
1692
1693 ExecutionContext exe_ctx(shared_from_this());
1694
1695 const char *plugin_name = nullptr;
1696 const char *flavor = nullptr;
1697 const bool prefer_file_cache = false;
1698 DisassemblerSP disassembler_sp = Disassembler::DisassembleRange(
1699 target_arch, plugin_name, flavor, exe_ctx, pc_range, prefer_file_cache);
1700
1701 if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) {
1702 return ValueObjectSP();
1703 }
1704
1705 const bool get_file_globals = false;
1706 VariableList *variables = GetVariableList(get_file_globals);
1707
1708 if (!variables) {
1709 return ValueObjectSP();
1710 }
1711
1712 return DoGuessValueAt(*this, reg, offset, *disassembler_sp, *variables,
1713 GetFrameCodeAddress());
1714}
1715
Shafik Yaghmoure23d0b62018-09-20 17:06:34 +00001716lldb::ValueObjectSP StackFrame::FindVariable(ConstString name) {
1717 ValueObjectSP value_sp;
1718
1719 if (!name)
1720 return value_sp;
1721
1722 TargetSP target_sp = CalculateTarget();
1723 ProcessSP process_sp = CalculateProcess();
1724
1725 if (!target_sp && !process_sp)
1726 return value_sp;
1727
1728 VariableList variable_list;
1729 VariableSP var_sp;
1730 SymbolContext sc(GetSymbolContext(eSymbolContextBlock));
1731
1732 if (sc.block) {
1733 const bool can_create = true;
1734 const bool get_parent_variables = true;
1735 const bool stop_if_block_is_inlined_function = true;
1736
1737 if (sc.block->AppendVariables(
1738 can_create, get_parent_variables, stop_if_block_is_inlined_function,
1739 [this](Variable *v) { return v->IsInScope(this); },
1740 &variable_list)) {
1741 var_sp = variable_list.FindVariable(name);
1742 }
1743
1744 if (var_sp)
1745 value_sp = GetValueObjectForFrameVariable(var_sp, eNoDynamicValues);
1746 }
1747
1748 return value_sp;
1749}
1750
Kate Stoneb9c1b512016-09-06 20:57:50 +00001751TargetSP StackFrame::CalculateTarget() {
1752 TargetSP target_sp;
1753 ThreadSP thread_sp(GetThread());
1754 if (thread_sp) {
1755 ProcessSP process_sp(thread_sp->CalculateProcess());
1756 if (process_sp)
1757 target_sp = process_sp->CalculateTarget();
1758 }
1759 return target_sp;
1760}
1761
1762ProcessSP StackFrame::CalculateProcess() {
1763 ProcessSP process_sp;
1764 ThreadSP thread_sp(GetThread());
1765 if (thread_sp)
1766 process_sp = thread_sp->CalculateProcess();
1767 return process_sp;
1768}
1769
1770ThreadSP StackFrame::CalculateThread() { return GetThread(); }
1771
1772StackFrameSP StackFrame::CalculateStackFrame() { return shared_from_this(); }
1773
1774void StackFrame::CalculateExecutionContext(ExecutionContext &exe_ctx) {
1775 exe_ctx.SetContext(shared_from_this());
1776}
1777
Pavel Labath7f1c1212017-06-12 16:25:24 +00001778void StackFrame::DumpUsingSettingsFormat(Stream *strm, bool show_unique,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001779 const char *frame_marker) {
1780 if (strm == nullptr)
1781 return;
1782
1783 GetSymbolContext(eSymbolContextEverything);
1784 ExecutionContext exe_ctx(shared_from_this());
1785 StreamString s;
1786
1787 if (frame_marker)
1788 s.PutCString(frame_marker);
1789
1790 const FormatEntity::Entry *frame_format = nullptr;
1791 Target *target = exe_ctx.GetTargetPtr();
Pavel Labath7f1c1212017-06-12 16:25:24 +00001792 if (target) {
1793 if (show_unique) {
1794 frame_format = target->GetDebugger().GetFrameFormatUnique();
1795 } else {
1796 frame_format = target->GetDebugger().GetFrameFormat();
1797 }
1798 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001799 if (frame_format && FormatEntity::Format(*frame_format, s, &m_sc, &exe_ctx,
1800 nullptr, nullptr, false, false)) {
Zachary Turnerc1564272016-11-16 21:15:24 +00001801 strm->PutCString(s.GetString());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001802 } else {
1803 Dump(strm, true, false);
1804 strm->EOL();
1805 }
1806}
1807
1808void StackFrame::Dump(Stream *strm, bool show_frame_index,
1809 bool show_fullpaths) {
1810 if (strm == nullptr)
1811 return;
1812
1813 if (show_frame_index)
1814 strm->Printf("frame #%u: ", m_frame_index);
1815 ExecutionContext exe_ctx(shared_from_this());
1816 Target *target = exe_ctx.GetTargetPtr();
1817 strm->Printf("0x%0*" PRIx64 " ",
1818 target ? (target->GetArchitecture().GetAddressByteSize() * 2)
1819 : 16,
1820 GetFrameCodeAddress().GetLoadAddress(target));
1821 GetSymbolContext(eSymbolContextEverything);
1822 const bool show_module = true;
1823 const bool show_inline = true;
1824 const bool show_function_arguments = true;
1825 const bool show_function_name = true;
1826 m_sc.DumpStopContext(strm, exe_ctx.GetBestExecutionContextScope(),
1827 GetFrameCodeAddress(), show_fullpaths, show_module,
1828 show_inline, show_function_arguments,
1829 show_function_name);
1830}
1831
1832void StackFrame::UpdateCurrentFrameFromPreviousFrame(StackFrame &prev_frame) {
1833 std::lock_guard<std::recursive_mutex> guard(m_mutex);
1834 assert(GetStackID() ==
1835 prev_frame.GetStackID()); // TODO: remove this after some testing
1836 m_variable_list_sp = prev_frame.m_variable_list_sp;
1837 m_variable_list_value_objects.Swap(prev_frame.m_variable_list_value_objects);
Zachary Turnerc1564272016-11-16 21:15:24 +00001838 if (!m_disassembly.GetString().empty()) {
1839 m_disassembly.Clear();
1840 m_disassembly.PutCString(prev_frame.m_disassembly.GetString());
1841 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001842}
1843
1844void StackFrame::UpdatePreviousFrameFromCurrentFrame(StackFrame &curr_frame) {
1845 std::lock_guard<std::recursive_mutex> guard(m_mutex);
1846 assert(GetStackID() ==
1847 curr_frame.GetStackID()); // TODO: remove this after some testing
1848 m_id.SetPC(curr_frame.m_id.GetPC()); // Update the Stack ID PC value
1849 assert(GetThread() == curr_frame.GetThread());
1850 m_frame_index = curr_frame.m_frame_index;
1851 m_concrete_frame_index = curr_frame.m_concrete_frame_index;
1852 m_reg_context_sp = curr_frame.m_reg_context_sp;
1853 m_frame_code_addr = curr_frame.m_frame_code_addr;
1854 assert(!m_sc.target_sp || !curr_frame.m_sc.target_sp ||
1855 m_sc.target_sp.get() == curr_frame.m_sc.target_sp.get());
1856 assert(!m_sc.module_sp || !curr_frame.m_sc.module_sp ||
1857 m_sc.module_sp.get() == curr_frame.m_sc.module_sp.get());
1858 assert(m_sc.comp_unit == nullptr || curr_frame.m_sc.comp_unit == nullptr ||
1859 m_sc.comp_unit == curr_frame.m_sc.comp_unit);
1860 assert(m_sc.function == nullptr || curr_frame.m_sc.function == nullptr ||
1861 m_sc.function == curr_frame.m_sc.function);
1862 m_sc = curr_frame.m_sc;
1863 m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything);
1864 m_flags.Set(m_sc.GetResolvedMask());
1865 m_frame_base.Clear();
1866 m_frame_base_error.Clear();
1867}
1868
1869bool StackFrame::HasCachedData() const {
1870 if (m_variable_list_sp)
Greg Clayton7260f622011-04-18 08:33:37 +00001871 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001872 if (m_variable_list_value_objects.GetSize() > 0)
1873 return true;
1874 if (!m_disassembly.GetString().empty())
1875 return true;
1876 return false;
1877}
1878
1879bool StackFrame::GetStatus(Stream &strm, bool show_frame_info, bool show_source,
Pavel Labath7f1c1212017-06-12 16:25:24 +00001880 bool show_unique, const char *frame_marker) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001881 if (show_frame_info) {
1882 strm.Indent();
Pavel Labath7f1c1212017-06-12 16:25:24 +00001883 DumpUsingSettingsFormat(&strm, show_unique, frame_marker);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001884 }
1885
1886 if (show_source) {
1887 ExecutionContext exe_ctx(shared_from_this());
1888 bool have_source = false, have_debuginfo = false;
1889 Debugger::StopDisassemblyType disasm_display =
1890 Debugger::eStopDisassemblyTypeNever;
1891 Target *target = exe_ctx.GetTargetPtr();
1892 if (target) {
1893 Debugger &debugger = target->GetDebugger();
1894 const uint32_t source_lines_before =
1895 debugger.GetStopSourceLineCount(true);
1896 const uint32_t source_lines_after =
1897 debugger.GetStopSourceLineCount(false);
1898 disasm_display = debugger.GetStopDisassemblyDisplay();
1899
1900 GetSymbolContext(eSymbolContextCompUnit | eSymbolContextLineEntry);
1901 if (m_sc.comp_unit && m_sc.line_entry.IsValid()) {
1902 have_debuginfo = true;
1903 if (source_lines_before > 0 || source_lines_after > 0) {
1904 size_t num_lines =
1905 target->GetSourceManager().DisplaySourceLinesWithLineNumbers(
1906 m_sc.line_entry.file, m_sc.line_entry.line,
Todd Fiala9666ba72016-09-21 20:13:14 +00001907 m_sc.line_entry.column, source_lines_before,
1908 source_lines_after, "->", &strm);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001909 if (num_lines != 0)
1910 have_source = true;
1911 // TODO: Give here a one time warning if source file is missing.
1912 }
1913 }
1914 switch (disasm_display) {
1915 case Debugger::eStopDisassemblyTypeNever:
1916 break;
1917
1918 case Debugger::eStopDisassemblyTypeNoDebugInfo:
1919 if (have_debuginfo)
1920 break;
1921 LLVM_FALLTHROUGH;
1922
1923 case Debugger::eStopDisassemblyTypeNoSource:
1924 if (have_source)
1925 break;
1926 LLVM_FALLTHROUGH;
1927
1928 case Debugger::eStopDisassemblyTypeAlways:
1929 if (target) {
1930 const uint32_t disasm_lines = debugger.GetDisassemblyLineCount();
1931 if (disasm_lines > 0) {
1932 const ArchSpec &target_arch = target->GetArchitecture();
1933 AddressRange pc_range;
1934 pc_range.GetBaseAddress() = GetFrameCodeAddress();
1935 pc_range.SetByteSize(disasm_lines *
1936 target_arch.GetMaximumOpcodeByteSize());
1937 const char *plugin_name = nullptr;
1938 const char *flavor = nullptr;
Jason Molenda0b4c26b2016-09-08 05:12:41 +00001939 const bool mixed_source_and_assembly = false;
1940 Disassembler::Disassemble(
1941 target->GetDebugger(), target_arch, plugin_name, flavor,
1942 exe_ctx, pc_range, disasm_lines, mixed_source_and_assembly, 0,
1943 Disassembler::eOptionMarkPCAddress, strm);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001944 }
1945 }
1946 break;
1947 }
1948 }
1949 }
1950 return true;
Greg Clayton7260f622011-04-18 08:33:37 +00001951}