1254721Semaste//===-- RegisterContextLLDB.cpp --------------------------------*- C++ -*-===//
2254721Semaste//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6254721Semaste//
7254721Semaste//===----------------------------------------------------------------------===//
8254721Semaste
9254721Semaste#include "lldb/Core/Address.h"
10254721Semaste#include "lldb/Core/AddressRange.h"
11254721Semaste#include "lldb/Core/Module.h"
12254721Semaste#include "lldb/Core/Value.h"
13254721Semaste#include "lldb/Expression/DWARFExpression.h"
14296417Sdim#include "lldb/Symbol/ArmUnwindInfo.h"
15360784Sdim#include "lldb/Symbol/CallFrameInfo.h"
16254721Semaste#include "lldb/Symbol/DWARFCallFrameInfo.h"
17254721Semaste#include "lldb/Symbol/FuncUnwinders.h"
18254721Semaste#include "lldb/Symbol/Function.h"
19254721Semaste#include "lldb/Symbol/ObjectFile.h"
20262528Semaste#include "lldb/Symbol/Symbol.h"
21254721Semaste#include "lldb/Symbol/SymbolContext.h"
22360784Sdim#include "lldb/Symbol/SymbolFile.h"
23254721Semaste#include "lldb/Target/ABI.h"
24262528Semaste#include "lldb/Target/DynamicLoader.h"
25254721Semaste#include "lldb/Target/ExecutionContext.h"
26262528Semaste#include "lldb/Target/Platform.h"
27254721Semaste#include "lldb/Target/Process.h"
28262528Semaste#include "lldb/Target/SectionLoadList.h"
29254721Semaste#include "lldb/Target/StackFrame.h"
30254721Semaste#include "lldb/Target/Target.h"
31254721Semaste#include "lldb/Target/Thread.h"
32321369Sdim#include "lldb/Utility/DataBufferHeap.h"
33321369Sdim#include "lldb/Utility/Log.h"
34344779Sdim#include "lldb/Utility/RegisterValue.h"
35314564Sdim#include "lldb/lldb-private.h"
36254721Semaste
37254721Semaste#include "RegisterContextLLDB.h"
38254721Semaste
39353358Sdim#include <memory>
40353358Sdim
41254721Semasteusing namespace lldb;
42254721Semasteusing namespace lldb_private;
43254721Semaste
44314564Sdimstatic ConstString GetSymbolOrFunctionName(const SymbolContext &sym_ctx) {
45314564Sdim  if (sym_ctx.symbol)
46314564Sdim    return sym_ctx.symbol->GetName();
47314564Sdim  else if (sym_ctx.function)
48314564Sdim    return sym_ctx.function->GetName();
49314564Sdim  return ConstString();
50288943Sdim}
51288943Sdim
52314564SdimRegisterContextLLDB::RegisterContextLLDB(Thread &thread,
53314564Sdim                                         const SharedPtr &next_frame,
54314564Sdim                                         SymbolContext &sym_ctx,
55314564Sdim                                         uint32_t frame_number,
56314564Sdim                                         UnwindLLDB &unwind_lldb)
57314564Sdim    : RegisterContext(thread, frame_number), m_thread(thread),
58314564Sdim      m_fast_unwind_plan_sp(), m_full_unwind_plan_sp(),
59314564Sdim      m_fallback_unwind_plan_sp(), m_all_registers_available(false),
60344779Sdim      m_frame_type(-1), m_cfa(LLDB_INVALID_ADDRESS),
61344779Sdim      m_afa(LLDB_INVALID_ADDRESS), m_start_pc(),
62314564Sdim      m_current_pc(), m_current_offset(0), m_current_offset_backed_up_one(0),
63314564Sdim      m_sym_ctx(sym_ctx), m_sym_ctx_valid(false), m_frame_number(frame_number),
64314564Sdim      m_registers(), m_parent_unwind(unwind_lldb) {
65314564Sdim  m_sym_ctx.Clear(false);
66314564Sdim  m_sym_ctx_valid = false;
67254721Semaste
68314564Sdim  if (IsFrameZero()) {
69314564Sdim    InitializeZerothFrame();
70314564Sdim  } else {
71314564Sdim    InitializeNonZerothFrame();
72314564Sdim  }
73254721Semaste
74314564Sdim  // This same code exists over in the GetFullUnwindPlanForFrame() but it may
75314564Sdim  // not have been executed yet
76314564Sdim  if (IsFrameZero() || next_frame->m_frame_type == eTrapHandlerFrame ||
77314564Sdim      next_frame->m_frame_type == eDebuggerFrame) {
78314564Sdim    m_all_registers_available = true;
79314564Sdim  }
80254721Semaste}
81254721Semaste
82314564Sdimbool RegisterContextLLDB::IsUnwindPlanValidForCurrentPC(
83314564Sdim    lldb::UnwindPlanSP unwind_plan_sp, int &valid_pc_offset) {
84314564Sdim  if (!unwind_plan_sp)
85314564Sdim    return false;
86262528Semaste
87314564Sdim  // check if m_current_pc is valid
88314564Sdim  if (unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
89314564Sdim    // yes - current offset can be used as is
90314564Sdim    valid_pc_offset = m_current_offset;
91314564Sdim    return true;
92314564Sdim  }
93262528Semaste
94314564Sdim  // if m_current_offset <= 0, we've got nothing else to try
95314564Sdim  if (m_current_offset <= 0)
96314564Sdim    return false;
97262528Semaste
98314564Sdim  // check pc - 1 to see if it's valid
99314564Sdim  Address pc_minus_one(m_current_pc);
100314564Sdim  pc_minus_one.SetOffset(m_current_pc.GetOffset() - 1);
101314564Sdim  if (unwind_plan_sp->PlanValidAtAddress(pc_minus_one)) {
102314564Sdim    // *valid_pc_offset = m_current_offset - 1;
103314564Sdim    valid_pc_offset = m_current_pc.GetOffset() - 1;
104314564Sdim    return true;
105314564Sdim  }
106262528Semaste
107314564Sdim  return false;
108262528Semaste}
109262528Semaste
110314564Sdim// Initialize a RegisterContextLLDB which is the first frame of a stack -- the
111341825Sdim// zeroth frame or currently executing frame.
112254721Semaste
113314564Sdimvoid RegisterContextLLDB::InitializeZerothFrame() {
114314564Sdim  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
115314564Sdim  ExecutionContext exe_ctx(m_thread.shared_from_this());
116314564Sdim  RegisterContextSP reg_ctx_sp = m_thread.GetRegisterContext();
117254721Semaste
118353358Sdim  if (reg_ctx_sp.get() == nullptr) {
119314564Sdim    m_frame_type = eNotAValidFrame;
120314564Sdim    UnwindLogMsg("frame does not have a register context");
121314564Sdim    return;
122314564Sdim  }
123254721Semaste
124314564Sdim  addr_t current_pc = reg_ctx_sp->GetPC();
125254721Semaste
126314564Sdim  if (current_pc == LLDB_INVALID_ADDRESS) {
127314564Sdim    m_frame_type = eNotAValidFrame;
128314564Sdim    UnwindLogMsg("frame does not have a pc");
129314564Sdim    return;
130314564Sdim  }
131254721Semaste
132314564Sdim  Process *process = exe_ctx.GetProcessPtr();
133254721Semaste
134314564Sdim  // Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs
135314564Sdim  // this will strip bit zero in case we read a PC from memory or from the LR.
136314564Sdim  // (which would be a no-op in frame 0 where we get it from the register set,
137341825Sdim  // but still a good idea to make the call here for other ABIs that may
138341825Sdim  // exist.)
139314564Sdim  ABI *abi = process->GetABI().get();
140314564Sdim  if (abi)
141314564Sdim    current_pc = abi->FixCodeAddress(current_pc);
142254721Semaste
143341825Sdim  // Initialize m_current_pc, an Address object, based on current_pc, an
144341825Sdim  // addr_t.
145314564Sdim  m_current_pc.SetLoadAddress(current_pc, &process->GetTarget());
146254721Semaste
147314564Sdim  // If we don't have a Module for some reason, we're not going to find
148341825Sdim  // symbol/function information - just stick in some reasonable defaults and
149341825Sdim  // hope we can unwind past this frame.
150314564Sdim  ModuleSP pc_module_sp(m_current_pc.GetModule());
151314564Sdim  if (!m_current_pc.IsValid() || !pc_module_sp) {
152314564Sdim    UnwindLogMsg("using architectural default unwind method");
153314564Sdim  }
154254721Semaste
155360784Sdim  AddressRange addr_range;
156360784Sdim  m_sym_ctx_valid = m_current_pc.ResolveFunctionScope(m_sym_ctx, &addr_range);
157254721Semaste
158314564Sdim  if (m_sym_ctx.symbol) {
159314564Sdim    UnwindLogMsg("with pc value of 0x%" PRIx64 ", symbol name is '%s'",
160314564Sdim                 current_pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
161314564Sdim  } else if (m_sym_ctx.function) {
162314564Sdim    UnwindLogMsg("with pc value of 0x%" PRIx64 ", function name is '%s'",
163314564Sdim                 current_pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
164314564Sdim  } else {
165314564Sdim    UnwindLogMsg("with pc value of 0x%" PRIx64
166314564Sdim                 ", no symbol/function name is known.",
167314564Sdim                 current_pc);
168314564Sdim  }
169280031Sdim
170314564Sdim  if (IsTrapHandlerSymbol(process, m_sym_ctx)) {
171314564Sdim    m_frame_type = eTrapHandlerFrame;
172314564Sdim  } else {
173314564Sdim    // FIXME:  Detect eDebuggerFrame here.
174314564Sdim    m_frame_type = eNormalFrame;
175314564Sdim  }
176254721Semaste
177314564Sdim  // If we were able to find a symbol/function, set addr_range to the bounds of
178341825Sdim  // that symbol/function. else treat the current pc value as the start_pc and
179341825Sdim  // record no offset.
180314564Sdim  if (addr_range.GetBaseAddress().IsValid()) {
181314564Sdim    m_start_pc = addr_range.GetBaseAddress();
182314564Sdim    if (m_current_pc.GetSection() == m_start_pc.GetSection()) {
183314564Sdim      m_current_offset = m_current_pc.GetOffset() - m_start_pc.GetOffset();
184314564Sdim    } else if (m_current_pc.GetModule() == m_start_pc.GetModule()) {
185341825Sdim      // This means that whatever symbol we kicked up isn't really correct ---
186341825Sdim      // we should not cross section boundaries ... We really should NULL out
187341825Sdim      // the function/symbol in this case unless there is a bad assumption here
188341825Sdim      // due to inlined functions?
189314564Sdim      m_current_offset =
190314564Sdim          m_current_pc.GetFileAddress() - m_start_pc.GetFileAddress();
191254721Semaste    }
192314564Sdim    m_current_offset_backed_up_one = m_current_offset;
193314564Sdim  } else {
194314564Sdim    m_start_pc = m_current_pc;
195314564Sdim    m_current_offset = -1;
196314564Sdim    m_current_offset_backed_up_one = -1;
197314564Sdim  }
198254721Semaste
199314564Sdim  // We've set m_frame_type and m_sym_ctx before these calls.
200254721Semaste
201314564Sdim  m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame();
202314564Sdim  m_full_unwind_plan_sp = GetFullUnwindPlanForFrame();
203254721Semaste
204314564Sdim  UnwindPlan::RowSP active_row;
205314564Sdim  lldb::RegisterKind row_register_kind = eRegisterKindGeneric;
206314564Sdim  if (m_full_unwind_plan_sp &&
207314564Sdim      m_full_unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
208314564Sdim    active_row =
209314564Sdim        m_full_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
210314564Sdim    row_register_kind = m_full_unwind_plan_sp->GetRegisterKind();
211314564Sdim    if (active_row.get() && log) {
212314564Sdim      StreamString active_row_strm;
213314564Sdim      active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread,
214314564Sdim                       m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
215314564Sdim      UnwindLogMsg("%s", active_row_strm.GetData());
216254721Semaste    }
217314564Sdim  }
218254721Semaste
219314564Sdim  if (!active_row.get()) {
220314564Sdim    UnwindLogMsg("could not find an unwindplan row for this frame's pc");
221314564Sdim    m_frame_type = eNotAValidFrame;
222314564Sdim    return;
223314564Sdim  }
224254721Semaste
225344779Sdim  if (!ReadFrameAddress(row_register_kind, active_row->GetCFAValue(), m_cfa)) {
226314564Sdim    // Try the fall back unwind plan since the
227314564Sdim    // full unwind plan failed.
228314564Sdim    FuncUnwindersSP func_unwinders_sp;
229314564Sdim    UnwindPlanSP call_site_unwind_plan;
230314564Sdim    bool cfa_status = false;
231254721Semaste
232314564Sdim    if (m_sym_ctx_valid) {
233314564Sdim      func_unwinders_sp =
234353358Sdim          pc_module_sp->GetUnwindTable().GetFuncUnwindersContainingAddress(
235353358Sdim              m_current_pc, m_sym_ctx);
236314564Sdim    }
237296417Sdim
238314564Sdim    if (func_unwinders_sp.get() != nullptr)
239314564Sdim      call_site_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(
240353358Sdim          process->GetTarget(), m_thread);
241296417Sdim
242314564Sdim    if (call_site_unwind_plan.get() != nullptr) {
243314564Sdim      m_fallback_unwind_plan_sp = call_site_unwind_plan;
244314564Sdim      if (TryFallbackUnwindPlan())
245314564Sdim        cfa_status = true;
246254721Semaste    }
247314564Sdim    if (!cfa_status) {
248314564Sdim      UnwindLogMsg("could not read CFA value for first frame.");
249314564Sdim      m_frame_type = eNotAValidFrame;
250314564Sdim      return;
251314564Sdim    }
252344779Sdim  } else
253344779Sdim    ReadFrameAddress(row_register_kind, active_row->GetAFAValue(), m_afa);
254254721Semaste
255314564Sdim  UnwindLogMsg("initialized frame current pc is 0x%" PRIx64 " cfa is 0x%" PRIx64
256344779Sdim               " afa is 0x%" PRIx64 " using %s UnwindPlan",
257314564Sdim               (uint64_t)m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr()),
258314564Sdim               (uint64_t)m_cfa,
259344779Sdim               (uint64_t)m_afa,
260314564Sdim               m_full_unwind_plan_sp->GetSourceName().GetCString());
261254721Semaste}
262254721Semaste
263314564Sdim// Initialize a RegisterContextLLDB for the non-zeroth frame -- rely on the
264341825Sdim// RegisterContextLLDB "below" it to provide things like its current pc value.
265254721Semaste
266314564Sdimvoid RegisterContextLLDB::InitializeNonZerothFrame() {
267314564Sdim  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
268314564Sdim  if (IsFrameZero()) {
269314564Sdim    m_frame_type = eNotAValidFrame;
270314564Sdim    UnwindLogMsg("non-zeroth frame tests positive for IsFrameZero -- that "
271314564Sdim                 "shouldn't happen.");
272314564Sdim    return;
273314564Sdim  }
274254721Semaste
275314564Sdim  if (!GetNextFrame().get() || !GetNextFrame()->IsValid()) {
276314564Sdim    m_frame_type = eNotAValidFrame;
277314564Sdim    UnwindLogMsg("Could not get next frame, marking this frame as invalid.");
278314564Sdim    return;
279314564Sdim  }
280314564Sdim  if (!m_thread.GetRegisterContext()) {
281314564Sdim    m_frame_type = eNotAValidFrame;
282314564Sdim    UnwindLogMsg("Could not get register context for this thread, marking this "
283314564Sdim                 "frame as invalid.");
284314564Sdim    return;
285314564Sdim  }
286254721Semaste
287314564Sdim  addr_t pc;
288314564Sdim  if (!ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc)) {
289314564Sdim    UnwindLogMsg("could not get pc value");
290314564Sdim    m_frame_type = eNotAValidFrame;
291314564Sdim    return;
292314564Sdim  }
293254721Semaste
294321369Sdim  ExecutionContext exe_ctx(m_thread.shared_from_this());
295321369Sdim  Process *process = exe_ctx.GetProcessPtr();
296321369Sdim  // Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs
297321369Sdim  // this will strip bit zero in case we read a PC from memory or from the LR.
298321369Sdim  ABI *abi = process->GetABI().get();
299321369Sdim  if (abi)
300321369Sdim    pc = abi->FixCodeAddress(pc);
301321369Sdim
302314564Sdim  if (log) {
303314564Sdim    UnwindLogMsg("pc = 0x%" PRIx64, pc);
304314564Sdim    addr_t reg_val;
305314564Sdim    if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP, reg_val))
306314564Sdim      UnwindLogMsg("fp = 0x%" PRIx64, reg_val);
307314564Sdim    if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, reg_val))
308314564Sdim      UnwindLogMsg("sp = 0x%" PRIx64, reg_val);
309314564Sdim  }
310254721Semaste
311314564Sdim  // A pc of 0x0 means it's the end of the stack crawl unless we're above a trap
312314564Sdim  // handler function
313314564Sdim  bool above_trap_handler = false;
314314564Sdim  if (GetNextFrame().get() && GetNextFrame()->IsValid() &&
315314564Sdim      GetNextFrame()->IsTrapHandlerFrame())
316314564Sdim    above_trap_handler = true;
317280031Sdim
318314564Sdim  if (pc == 0 || pc == 0x1) {
319344779Sdim    if (!above_trap_handler) {
320314564Sdim      m_frame_type = eNotAValidFrame;
321314564Sdim      UnwindLogMsg("this frame has a pc of 0x0");
322314564Sdim      return;
323254721Semaste    }
324314564Sdim  }
325254721Semaste
326321369Sdim  const bool allow_section_end = true;
327321369Sdim  m_current_pc.SetLoadAddress(pc, &process->GetTarget(), allow_section_end);
328254721Semaste
329314564Sdim  // If we don't have a Module for some reason, we're not going to find
330341825Sdim  // symbol/function information - just stick in some reasonable defaults and
331341825Sdim  // hope we can unwind past this frame.
332314564Sdim  ModuleSP pc_module_sp(m_current_pc.GetModule());
333314564Sdim  if (!m_current_pc.IsValid() || !pc_module_sp) {
334314564Sdim    UnwindLogMsg("using architectural default unwind method");
335254721Semaste
336314564Sdim    // Test the pc value to see if we know it's in an unmapped/non-executable
337314564Sdim    // region of memory.
338314564Sdim    uint32_t permissions;
339314564Sdim    if (process->GetLoadAddressPermissions(pc, permissions) &&
340314564Sdim        (permissions & ePermissionsExecutable) == 0) {
341314564Sdim      // If this is the second frame off the stack, we may have unwound the
342341825Sdim      // first frame incorrectly.  But using the architecture default unwind
343341825Sdim      // plan may get us back on track -- albeit possibly skipping a real
344341825Sdim      // frame.  Give this frame a clearly-invalid pc and see if we can get any
345341825Sdim      // further.
346314564Sdim      if (GetNextFrame().get() && GetNextFrame()->IsValid() &&
347314564Sdim          GetNextFrame()->IsFrameZero()) {
348314564Sdim        UnwindLogMsg("had a pc of 0x%" PRIx64 " which is not in executable "
349314564Sdim                                              "memory but on frame 1 -- "
350314564Sdim                                              "allowing it once.",
351314564Sdim                     (uint64_t)pc);
352314564Sdim        m_frame_type = eSkipFrame;
353314564Sdim      } else {
354341825Sdim        // anywhere other than the second frame, a non-executable pc means
355341825Sdim        // we're off in the weeds -- stop now.
356314564Sdim        m_frame_type = eNotAValidFrame;
357314564Sdim        UnwindLogMsg("pc is in a non-executable section of memory and this "
358314564Sdim                     "isn't the 2nd frame in the stack walk.");
359314564Sdim        return;
360314564Sdim      }
361314564Sdim    }
362314564Sdim
363314564Sdim    if (abi) {
364314564Sdim      m_fast_unwind_plan_sp.reset();
365353358Sdim      m_full_unwind_plan_sp =
366353358Sdim          std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
367314564Sdim      abi->CreateDefaultUnwindPlan(*m_full_unwind_plan_sp);
368314564Sdim      if (m_frame_type != eSkipFrame) // don't override eSkipFrame
369314564Sdim      {
370314564Sdim        m_frame_type = eNormalFrame;
371314564Sdim      }
372314564Sdim      m_all_registers_available = false;
373314564Sdim      m_current_offset = -1;
374314564Sdim      m_current_offset_backed_up_one = -1;
375314564Sdim      RegisterKind row_register_kind = m_full_unwind_plan_sp->GetRegisterKind();
376314564Sdim      UnwindPlan::RowSP row = m_full_unwind_plan_sp->GetRowForFunctionOffset(0);
377314564Sdim      if (row.get()) {
378344779Sdim        if (!ReadFrameAddress(row_register_kind, row->GetCFAValue(), m_cfa)) {
379314564Sdim          UnwindLogMsg("failed to get cfa value");
380314564Sdim          if (m_frame_type != eSkipFrame) // don't override eSkipFrame
381314564Sdim          {
382314564Sdim            m_frame_type = eNotAValidFrame;
383314564Sdim          }
384314564Sdim          return;
385254721Semaste        }
386254721Semaste
387344779Sdim        ReadFrameAddress(row_register_kind, row->GetAFAValue(), m_afa);
388344779Sdim
389314564Sdim        // A couple of sanity checks..
390314564Sdim        if (m_cfa == LLDB_INVALID_ADDRESS || m_cfa == 0 || m_cfa == 1) {
391314564Sdim          UnwindLogMsg("could not find a valid cfa address");
392314564Sdim          m_frame_type = eNotAValidFrame;
393314564Sdim          return;
394314564Sdim        }
395254721Semaste
396314564Sdim        // m_cfa should point into the stack memory; if we can query memory
397341825Sdim        // region permissions, see if the memory is allocated & readable.
398314564Sdim        if (process->GetLoadAddressPermissions(m_cfa, permissions) &&
399314564Sdim            (permissions & ePermissionsReadable) == 0) {
400314564Sdim          m_frame_type = eNotAValidFrame;
401314564Sdim          UnwindLogMsg(
402314564Sdim              "the CFA points to a region of memory that is not readable");
403314564Sdim          return;
404254721Semaste        }
405314564Sdim      } else {
406314564Sdim        UnwindLogMsg("could not find a row for function offset zero");
407254721Semaste        m_frame_type = eNotAValidFrame;
408254721Semaste        return;
409314564Sdim      }
410254721Semaste
411314564Sdim      if (CheckIfLoopingStack()) {
412314564Sdim        TryFallbackUnwindPlan();
413314564Sdim        if (CheckIfLoopingStack()) {
414314564Sdim          UnwindLogMsg("same CFA address as next frame, assuming the unwind is "
415314564Sdim                       "looping - stopping");
416314564Sdim          m_frame_type = eNotAValidFrame;
417314564Sdim          return;
418314564Sdim        }
419314564Sdim      }
420258054Semaste
421344779Sdim      UnwindLogMsg("initialized frame cfa is 0x%" PRIx64 " afa is 0x%" PRIx64,
422344779Sdim                   (uint64_t)m_cfa, (uint64_t)m_afa);
423314564Sdim      return;
424254721Semaste    }
425314564Sdim    m_frame_type = eNotAValidFrame;
426314564Sdim    UnwindLogMsg("could not find any symbol for this pc, or a default unwind "
427314564Sdim                 "plan, to continue unwind.");
428314564Sdim    return;
429314564Sdim  }
430254721Semaste
431360784Sdim  AddressRange addr_range;
432360784Sdim  m_sym_ctx_valid = m_current_pc.ResolveFunctionScope(m_sym_ctx, &addr_range);
433280031Sdim
434314564Sdim  if (m_sym_ctx.symbol) {
435314564Sdim    UnwindLogMsg("with pc value of 0x%" PRIx64 ", symbol name is '%s'", pc,
436314564Sdim                 GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
437314564Sdim  } else if (m_sym_ctx.function) {
438314564Sdim    UnwindLogMsg("with pc value of 0x%" PRIx64 ", function name is '%s'", pc,
439314564Sdim                 GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
440314564Sdim  } else {
441314564Sdim    UnwindLogMsg("with pc value of 0x%" PRIx64
442314564Sdim                 ", no symbol/function name is known.",
443314564Sdim                 pc);
444314564Sdim  }
445254721Semaste
446360784Sdim  bool decr_pc_and_recompute_addr_range;
447254721Semaste
448360784Sdim  if (!m_sym_ctx_valid) {
449360784Sdim    // Always decrement and recompute if the symbol lookup failed
450314564Sdim    decr_pc_and_recompute_addr_range = true;
451360784Sdim  } else if (GetNextFrame()->m_frame_type == eTrapHandlerFrame ||
452360784Sdim             GetNextFrame()->m_frame_type == eDebuggerFrame) {
453360784Sdim    // Don't decrement if we're "above" an asynchronous event like
454360784Sdim    // sigtramp.
455360784Sdim    decr_pc_and_recompute_addr_range = false;
456360784Sdim  } else if (!addr_range.GetBaseAddress().IsValid() ||
457360784Sdim             addr_range.GetBaseAddress().GetSection() != m_current_pc.GetSection() ||
458360784Sdim             addr_range.GetBaseAddress().GetOffset() != m_current_pc.GetOffset()) {
459360784Sdim    // If our "current" pc isn't the start of a function, no need
460360784Sdim    // to decrement and recompute.
461360784Sdim    decr_pc_and_recompute_addr_range = false;
462360784Sdim  } else if (IsTrapHandlerSymbol(process, m_sym_ctx)) {
463360784Sdim    // Signal dispatch may set the return address of the handler it calls to
464360784Sdim    // point to the first byte of a return trampoline (like __kernel_rt_sigreturn),
465360784Sdim    // so do not decrement and recompute if the symbol we already found is a trap
466360784Sdim    // handler.
467360784Sdim    decr_pc_and_recompute_addr_range = false;
468360784Sdim  } else {
469360784Sdim    // Decrement to find the function containing the call.
470314564Sdim    decr_pc_and_recompute_addr_range = true;
471314564Sdim  }
472314564Sdim
473314564Sdim  // We need to back up the pc by 1 byte and re-search for the Symbol to handle
474341825Sdim  // the case where the "saved pc" value is pointing to the next function, e.g.
475341825Sdim  // if a function ends with a CALL instruction.
476314564Sdim  // FIXME this may need to be an architectural-dependent behavior; if so we'll
477314564Sdim  // need to add a member function
478314564Sdim  // to the ABI plugin and consult that.
479314564Sdim  if (decr_pc_and_recompute_addr_range) {
480314564Sdim    UnwindLogMsg("Backing up the pc value of 0x%" PRIx64
481314564Sdim                 " by 1 and re-doing symbol lookup; old symbol was %s",
482314564Sdim                 pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
483314564Sdim    Address temporary_pc;
484314564Sdim    temporary_pc.SetLoadAddress(pc - 1, &process->GetTarget());
485314564Sdim    m_sym_ctx.Clear(false);
486360784Sdim    m_sym_ctx_valid = temporary_pc.ResolveFunctionScope(m_sym_ctx, &addr_range);
487314564Sdim
488314564Sdim    UnwindLogMsg("Symbol is now %s",
489314564Sdim                 GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
490314564Sdim  }
491254721Semaste
492341825Sdim  // If we were able to find a symbol/function, set addr_range_ptr to the
493341825Sdim  // bounds of that symbol/function. else treat the current pc value as the
494341825Sdim  // start_pc and record no offset.
495314564Sdim  if (addr_range.GetBaseAddress().IsValid()) {
496314564Sdim    m_start_pc = addr_range.GetBaseAddress();
497314564Sdim    m_current_offset = pc - m_start_pc.GetLoadAddress(&process->GetTarget());
498314564Sdim    m_current_offset_backed_up_one = m_current_offset;
499314564Sdim    if (decr_pc_and_recompute_addr_range &&
500314564Sdim        m_current_offset_backed_up_one > 0) {
501314564Sdim      m_current_offset_backed_up_one--;
502314564Sdim      if (m_sym_ctx_valid) {
503314564Sdim        m_current_pc.SetLoadAddress(pc - 1, &process->GetTarget());
504314564Sdim      }
505254721Semaste    }
506314564Sdim  } else {
507314564Sdim    m_start_pc = m_current_pc;
508314564Sdim    m_current_offset = -1;
509314564Sdim    m_current_offset_backed_up_one = -1;
510314564Sdim  }
511254721Semaste
512314564Sdim  if (IsTrapHandlerSymbol(process, m_sym_ctx)) {
513314564Sdim    m_frame_type = eTrapHandlerFrame;
514314564Sdim  } else {
515314564Sdim    // FIXME:  Detect eDebuggerFrame here.
516314564Sdim    if (m_frame_type != eSkipFrame) // don't override eSkipFrame
517254721Semaste    {
518314564Sdim      m_frame_type = eNormalFrame;
519254721Semaste    }
520314564Sdim  }
521254721Semaste
522314564Sdim  // We've set m_frame_type and m_sym_ctx before this call.
523314564Sdim  m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame();
524254721Semaste
525314564Sdim  UnwindPlan::RowSP active_row;
526314564Sdim  RegisterKind row_register_kind = eRegisterKindGeneric;
527254721Semaste
528314564Sdim  // Try to get by with just the fast UnwindPlan if possible - the full
529341825Sdim  // UnwindPlan may be expensive to get (e.g. if we have to parse the entire
530341825Sdim  // eh_frame section of an ObjectFile for the first time.)
531254721Semaste
532314564Sdim  if (m_fast_unwind_plan_sp &&
533314564Sdim      m_fast_unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
534314564Sdim    active_row =
535314564Sdim        m_fast_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
536314564Sdim    row_register_kind = m_fast_unwind_plan_sp->GetRegisterKind();
537360784Sdim    PropagateTrapHandlerFlagFromUnwindPlan(m_fast_unwind_plan_sp);
538314564Sdim    if (active_row.get() && log) {
539314564Sdim      StreamString active_row_strm;
540314564Sdim      active_row->Dump(active_row_strm, m_fast_unwind_plan_sp.get(), &m_thread,
541314564Sdim                       m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
542314564Sdim      UnwindLogMsg("active row: %s", active_row_strm.GetData());
543254721Semaste    }
544314564Sdim  } else {
545314564Sdim    m_full_unwind_plan_sp = GetFullUnwindPlanForFrame();
546314564Sdim    int valid_offset = -1;
547314564Sdim    if (IsUnwindPlanValidForCurrentPC(m_full_unwind_plan_sp, valid_offset)) {
548314564Sdim      active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset(valid_offset);
549314564Sdim      row_register_kind = m_full_unwind_plan_sp->GetRegisterKind();
550360784Sdim      PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp);
551314564Sdim      if (active_row.get() && log) {
552314564Sdim        StreamString active_row_strm;
553314564Sdim        active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(),
554314564Sdim                         &m_thread,
555314564Sdim                         m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
556314564Sdim        UnwindLogMsg("active row: %s", active_row_strm.GetData());
557314564Sdim      }
558254721Semaste    }
559314564Sdim  }
560254721Semaste
561314564Sdim  if (!active_row.get()) {
562314564Sdim    m_frame_type = eNotAValidFrame;
563314564Sdim    UnwindLogMsg("could not find unwind row for this pc");
564314564Sdim    return;
565314564Sdim  }
566254721Semaste
567344779Sdim  if (!ReadFrameAddress(row_register_kind, active_row->GetCFAValue(), m_cfa)) {
568314564Sdim    UnwindLogMsg("failed to get cfa");
569314564Sdim    m_frame_type = eNotAValidFrame;
570314564Sdim    return;
571314564Sdim  }
572254721Semaste
573344779Sdim  ReadFrameAddress(row_register_kind, active_row->GetAFAValue(), m_afa);
574254721Semaste
575344779Sdim  UnwindLogMsg("m_cfa = 0x%" PRIx64 " m_afa = 0x%" PRIx64, m_cfa, m_afa);
576344779Sdim
577314564Sdim  if (CheckIfLoopingStack()) {
578314564Sdim    TryFallbackUnwindPlan();
579314564Sdim    if (CheckIfLoopingStack()) {
580314564Sdim      UnwindLogMsg("same CFA address as next frame, assuming the unwind is "
581314564Sdim                   "looping - stopping");
582314564Sdim      m_frame_type = eNotAValidFrame;
583314564Sdim      return;
584254721Semaste    }
585314564Sdim  }
586254721Semaste
587314564Sdim  UnwindLogMsg("initialized frame current pc is 0x%" PRIx64
588344779Sdim               " cfa is 0x%" PRIx64 " afa is 0x%" PRIx64,
589314564Sdim               (uint64_t)m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr()),
590344779Sdim               (uint64_t)m_cfa,
591344779Sdim               (uint64_t)m_afa);
592280031Sdim}
593280031Sdim
594314564Sdimbool RegisterContextLLDB::CheckIfLoopingStack() {
595314564Sdim  // If we have a bad stack setup, we can get the same CFA value multiple times
596341825Sdim  // -- or even more devious, we can actually oscillate between two CFA values.
597341825Sdim  // Detect that here and break out to avoid a possible infinite loop in lldb
598341825Sdim  // trying to unwind the stack. To detect when we have the same CFA value
599341825Sdim  // multiple times, we compare the
600314564Sdim  // CFA of the current
601314564Sdim  // frame with the 2nd next frame because in some specail case (e.g. signal
602341825Sdim  // hanlders, hand written assembly without ABI compiance) we can have 2
603341825Sdim  // frames with the same
604314564Sdim  // CFA (in theory we
605314564Sdim  // can have arbitrary number of frames with the same CFA, but more then 2 is
606314564Sdim  // very very unlikely)
607296417Sdim
608314564Sdim  RegisterContextLLDB::SharedPtr next_frame = GetNextFrame();
609314564Sdim  if (next_frame) {
610314564Sdim    RegisterContextLLDB::SharedPtr next_next_frame = next_frame->GetNextFrame();
611314564Sdim    addr_t next_next_frame_cfa = LLDB_INVALID_ADDRESS;
612314564Sdim    if (next_next_frame && next_next_frame->GetCFA(next_next_frame_cfa)) {
613314564Sdim      if (next_next_frame_cfa == m_cfa) {
614314564Sdim        // We have a loop in the stack unwind
615314564Sdim        return true;
616314564Sdim      }
617254721Semaste    }
618314564Sdim  }
619314564Sdim  return false;
620254721Semaste}
621254721Semaste
622314564Sdimbool RegisterContextLLDB::IsFrameZero() const { return m_frame_number == 0; }
623254721Semaste
624254721Semaste// Find a fast unwind plan for this frame, if possible.
625254721Semaste//
626254721Semaste// On entry to this method,
627254721Semaste//
628314564Sdim//   1. m_frame_type should already be set to eTrapHandlerFrame/eDebuggerFrame
629314564Sdim//   if either of those are correct,
630254721Semaste//   2. m_sym_ctx should already be filled in, and
631254721Semaste//   3. m_current_pc should have the current pc value for this frame
632314564Sdim//   4. m_current_offset_backed_up_one should have the current byte offset into
633314564Sdim//   the function, maybe backed up by 1, -1 if unknown
634254721Semaste
635314564SdimUnwindPlanSP RegisterContextLLDB::GetFastUnwindPlanForFrame() {
636314564Sdim  UnwindPlanSP unwind_plan_sp;
637314564Sdim  ModuleSP pc_module_sp(m_current_pc.GetModule());
638254721Semaste
639314564Sdim  if (!m_current_pc.IsValid() || !pc_module_sp ||
640353358Sdim      pc_module_sp->GetObjectFile() == nullptr)
641314564Sdim    return unwind_plan_sp;
642254721Semaste
643314564Sdim  if (IsFrameZero())
644314564Sdim    return unwind_plan_sp;
645254721Semaste
646314564Sdim  FuncUnwindersSP func_unwinders_sp(
647353358Sdim      pc_module_sp->GetUnwindTable().GetFuncUnwindersContainingAddress(
648353358Sdim          m_current_pc, m_sym_ctx));
649314564Sdim  if (!func_unwinders_sp)
650314564Sdim    return unwind_plan_sp;
651254721Semaste
652314564Sdim  // If we're in _sigtramp(), unwinding past this frame requires special
653314564Sdim  // knowledge.
654314564Sdim  if (m_frame_type == eTrapHandlerFrame || m_frame_type == eDebuggerFrame)
655314564Sdim    return unwind_plan_sp;
656254721Semaste
657314564Sdim  unwind_plan_sp = func_unwinders_sp->GetUnwindPlanFastUnwind(
658314564Sdim      *m_thread.CalculateTarget(), m_thread);
659314564Sdim  if (unwind_plan_sp) {
660314564Sdim    if (unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
661314564Sdim      Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
662314564Sdim      if (log && log->GetVerbose()) {
663314564Sdim        if (m_fast_unwind_plan_sp)
664314564Sdim          UnwindLogMsgVerbose("frame, and has a fast UnwindPlan");
665254721Semaste        else
666314564Sdim          UnwindLogMsgVerbose("frame");
667314564Sdim      }
668314564Sdim      m_frame_type = eNormalFrame;
669314564Sdim      return unwind_plan_sp;
670314564Sdim    } else {
671314564Sdim      unwind_plan_sp.reset();
672254721Semaste    }
673314564Sdim  }
674314564Sdim  return unwind_plan_sp;
675254721Semaste}
676254721Semaste
677254721Semaste// On entry to this method,
678254721Semaste//
679314564Sdim//   1. m_frame_type should already be set to eTrapHandlerFrame/eDebuggerFrame
680314564Sdim//   if either of those are correct,
681254721Semaste//   2. m_sym_ctx should already be filled in, and
682254721Semaste//   3. m_current_pc should have the current pc value for this frame
683314564Sdim//   4. m_current_offset_backed_up_one should have the current byte offset into
684314564Sdim//   the function, maybe backed up by 1, -1 if unknown
685254721Semaste
686314564SdimUnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame() {
687314564Sdim  UnwindPlanSP unwind_plan_sp;
688314564Sdim  UnwindPlanSP arch_default_unwind_plan_sp;
689314564Sdim  ExecutionContext exe_ctx(m_thread.shared_from_this());
690314564Sdim  Process *process = exe_ctx.GetProcessPtr();
691353358Sdim  ABI *abi = process ? process->GetABI().get() : nullptr;
692314564Sdim  if (abi) {
693353358Sdim    arch_default_unwind_plan_sp =
694353358Sdim        std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
695314564Sdim    abi->CreateDefaultUnwindPlan(*arch_default_unwind_plan_sp);
696314564Sdim  } else {
697314564Sdim    UnwindLogMsg(
698314564Sdim        "unable to get architectural default UnwindPlan from ABI plugin");
699314564Sdim  }
700254721Semaste
701314564Sdim  bool behaves_like_zeroth_frame = false;
702314564Sdim  if (IsFrameZero() || GetNextFrame()->m_frame_type == eTrapHandlerFrame ||
703314564Sdim      GetNextFrame()->m_frame_type == eDebuggerFrame) {
704314564Sdim    behaves_like_zeroth_frame = true;
705314564Sdim    // If this frame behaves like a 0th frame (currently executing or
706314564Sdim    // interrupted asynchronously), all registers can be retrieved.
707314564Sdim    m_all_registers_available = true;
708314564Sdim  }
709254721Semaste
710314564Sdim  // If we've done a jmp 0x0 / bl 0x0 (called through a null function pointer)
711341825Sdim  // so the pc is 0x0 in the zeroth frame, we need to use the "unwind at first
712341825Sdim  // instruction" arch default UnwindPlan Also, if this Process can report on
713341825Sdim  // memory region attributes, any non-executable region means we jumped
714341825Sdim  // through a bad function pointer - handle the same way as 0x0. Note, if we
715341825Sdim  // have a symbol context & a symbol, we don't want to follow this code path.
716341825Sdim  // This is for jumping to memory regions without any information available.
717254721Semaste
718314564Sdim  if ((!m_sym_ctx_valid ||
719353358Sdim       (m_sym_ctx.function == nullptr && m_sym_ctx.symbol == nullptr)) &&
720314564Sdim      behaves_like_zeroth_frame && m_current_pc.IsValid()) {
721314564Sdim    uint32_t permissions;
722314564Sdim    addr_t current_pc_addr =
723314564Sdim        m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr());
724314564Sdim    if (current_pc_addr == 0 ||
725314564Sdim        (process &&
726314564Sdim         process->GetLoadAddressPermissions(current_pc_addr, permissions) &&
727314564Sdim         (permissions & ePermissionsExecutable) == 0)) {
728314564Sdim      if (abi) {
729353358Sdim        unwind_plan_sp =
730353358Sdim            std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
731314564Sdim        abi->CreateFunctionEntryUnwindPlan(*unwind_plan_sp);
732254721Semaste        m_frame_type = eNormalFrame;
733314564Sdim        return unwind_plan_sp;
734314564Sdim      }
735254721Semaste    }
736314564Sdim  }
737254721Semaste
738314564Sdim  // No Module for the current pc, try using the architecture default unwind.
739314564Sdim  ModuleSP pc_module_sp(m_current_pc.GetModule());
740314564Sdim  if (!m_current_pc.IsValid() || !pc_module_sp ||
741353358Sdim      pc_module_sp->GetObjectFile() == nullptr) {
742314564Sdim    m_frame_type = eNormalFrame;
743314564Sdim    return arch_default_unwind_plan_sp;
744314564Sdim  }
745254721Semaste
746314564Sdim  FuncUnwindersSP func_unwinders_sp;
747314564Sdim  if (m_sym_ctx_valid) {
748314564Sdim    func_unwinders_sp =
749353358Sdim        pc_module_sp->GetUnwindTable().GetFuncUnwindersContainingAddress(
750353358Sdim            m_current_pc, m_sym_ctx);
751314564Sdim  }
752254721Semaste
753314564Sdim  // No FuncUnwinders available for this pc (stripped function symbols, lldb
754341825Sdim  // could not augment its function table with another source, like
755341825Sdim  // LC_FUNCTION_STARTS or eh_frame in ObjectFileMachO). See if eh_frame or the
756341825Sdim  // .ARM.exidx tables have unwind information for this address, else fall back
757341825Sdim  // to the architectural default unwind.
758314564Sdim  if (!func_unwinders_sp) {
759314564Sdim    m_frame_type = eNormalFrame;
760296417Sdim
761314564Sdim    if (!pc_module_sp || !pc_module_sp->GetObjectFile() ||
762314564Sdim        !m_current_pc.IsValid())
763314564Sdim      return arch_default_unwind_plan_sp;
764296417Sdim
765341825Sdim    // Even with -fomit-frame-pointer, we can try eh_frame to get back on
766341825Sdim    // track.
767314564Sdim    DWARFCallFrameInfo *eh_frame =
768353358Sdim        pc_module_sp->GetUnwindTable().GetEHFrameInfo();
769314564Sdim    if (eh_frame) {
770353358Sdim      unwind_plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
771314564Sdim      if (eh_frame->GetUnwindPlan(m_current_pc, *unwind_plan_sp))
772314564Sdim        return unwind_plan_sp;
773314564Sdim      else
774314564Sdim        unwind_plan_sp.reset();
775254721Semaste    }
776254721Semaste
777314564Sdim    ArmUnwindInfo *arm_exidx =
778353358Sdim        pc_module_sp->GetUnwindTable().GetArmUnwindInfo();
779314564Sdim    if (arm_exidx) {
780353358Sdim      unwind_plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
781314564Sdim      if (arm_exidx->GetUnwindPlan(exe_ctx.GetTargetRef(), m_current_pc,
782314564Sdim                                   *unwind_plan_sp))
783314564Sdim        return unwind_plan_sp;
784314564Sdim      else
785314564Sdim        unwind_plan_sp.reset();
786254721Semaste    }
787254721Semaste
788360784Sdim    CallFrameInfo *object_file_unwind =
789360784Sdim        pc_module_sp->GetUnwindTable().GetObjectFileUnwindInfo();
790360784Sdim    if (object_file_unwind) {
791360784Sdim      unwind_plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
792360784Sdim      if (object_file_unwind->GetUnwindPlan(m_current_pc, *unwind_plan_sp))
793360784Sdim        return unwind_plan_sp;
794360784Sdim      else
795360784Sdim        unwind_plan_sp.reset();
796360784Sdim    }
797360784Sdim
798314564Sdim    return arch_default_unwind_plan_sp;
799314564Sdim  }
800254721Semaste
801314564Sdim  // If we're in _sigtramp(), unwinding past this frame requires special
802341825Sdim  // knowledge.  On Mac OS X this knowledge is properly encoded in the eh_frame
803341825Sdim  // section, so prefer that if available. On other platforms we may need to
804341825Sdim  // provide a platform-specific UnwindPlan which encodes the details of how to
805341825Sdim  // unwind out of sigtramp.
806314564Sdim  if (m_frame_type == eTrapHandlerFrame && process) {
807314564Sdim    m_fast_unwind_plan_sp.reset();
808353358Sdim    unwind_plan_sp =
809353358Sdim        func_unwinders_sp->GetEHFrameUnwindPlan(process->GetTarget());
810360784Sdim    if (!unwind_plan_sp)
811360784Sdim      unwind_plan_sp =
812360784Sdim          func_unwinders_sp->GetObjectFileUnwindPlan(process->GetTarget());
813314564Sdim    if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc) &&
814314564Sdim        unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes) {
815314564Sdim      return unwind_plan_sp;
816254721Semaste    }
817314564Sdim  }
818254721Semaste
819314564Sdim  // Ask the DynamicLoader if the eh_frame CFI should be trusted in this frame
820341825Sdim  // even when it's frame zero This comes up if we have hand-written functions
821341825Sdim  // in a Module and hand-written eh_frame.  The assembly instruction
822341825Sdim  // inspection may fail and the eh_frame CFI were probably written with some
823341825Sdim  // care to do the right thing.  It'd be nice if there was a way to ask the
824341825Sdim  // eh_frame directly if it is asynchronous (can be trusted at every
825341825Sdim  // instruction point) or synchronous (the normal case - only at call sites).
826314564Sdim  // But there is not.
827314564Sdim  if (process && process->GetDynamicLoader() &&
828314564Sdim      process->GetDynamicLoader()->AlwaysRelyOnEHUnwindInfo(m_sym_ctx)) {
829314564Sdim    // We must specifically call the GetEHFrameUnwindPlan() method here --
830341825Sdim    // normally we would call GetUnwindPlanAtCallSite() -- because CallSite may
831341825Sdim    // return an unwind plan sourced from either eh_frame (that's what we
832341825Sdim    // intend) or compact unwind (this won't work)
833353358Sdim    unwind_plan_sp =
834353358Sdim        func_unwinders_sp->GetEHFrameUnwindPlan(process->GetTarget());
835360784Sdim    if (!unwind_plan_sp)
836360784Sdim      unwind_plan_sp =
837360784Sdim          func_unwinders_sp->GetObjectFileUnwindPlan(process->GetTarget());
838314564Sdim    if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
839314564Sdim      UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because the "
840314564Sdim                          "DynamicLoader suggested we prefer it",
841314564Sdim                          unwind_plan_sp->GetSourceName().GetCString());
842314564Sdim      return unwind_plan_sp;
843280031Sdim    }
844314564Sdim  }
845254721Semaste
846314564Sdim  // Typically the NonCallSite UnwindPlan is the unwind created by inspecting
847314564Sdim  // the assembly language instructions
848314564Sdim  if (behaves_like_zeroth_frame && process) {
849314564Sdim    unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite(
850353358Sdim        process->GetTarget(), m_thread);
851314564Sdim    if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
852314564Sdim      if (unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolNo) {
853314564Sdim        // We probably have an UnwindPlan created by inspecting assembly
854341825Sdim        // instructions. The assembly profilers work really well with compiler-
855341825Sdim        // generated functions but hand- written assembly can be problematic.
856341825Sdim        // We set the eh_frame based unwind plan as our fallback unwind plan if
857341825Sdim        // instruction emulation doesn't work out even for non call sites if it
858341825Sdim        // is available and use the architecture default unwind plan if it is
859314564Sdim        // not available. The eh_frame unwind plan is more reliable even on non
860341825Sdim        // call sites then the architecture default plan and for hand written
861341825Sdim        // assembly code it is often written in a way that it valid at all
862341825Sdim        // location what helps in the most common cases when the instruction
863341825Sdim        // emulation fails.
864314564Sdim        UnwindPlanSP call_site_unwind_plan =
865353358Sdim            func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget(),
866353358Sdim                                                       m_thread);
867296417Sdim        if (call_site_unwind_plan &&
868296417Sdim            call_site_unwind_plan.get() != unwind_plan_sp.get() &&
869314564Sdim            call_site_unwind_plan->GetSourceName() !=
870314564Sdim                unwind_plan_sp->GetSourceName()) {
871314564Sdim          m_fallback_unwind_plan_sp = call_site_unwind_plan;
872314564Sdim        } else {
873314564Sdim          m_fallback_unwind_plan_sp = arch_default_unwind_plan_sp;
874288943Sdim        }
875314564Sdim      }
876353358Sdim      UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because this "
877353358Sdim                          "is the non-call site unwind plan and this is a "
878353358Sdim                          "zeroth frame",
879314564Sdim                          unwind_plan_sp->GetSourceName().GetCString());
880314564Sdim      return unwind_plan_sp;
881262528Semaste    }
882353358Sdim
883353358Sdim    // If we're on the first instruction of a function, and we have an
884353358Sdim    // architectural default UnwindPlan for the initial instruction of a
885353358Sdim    // function, use that.
886353358Sdim    if (m_current_offset == 0) {
887353358Sdim      unwind_plan_sp =
888353358Sdim          func_unwinders_sp->GetUnwindPlanArchitectureDefaultAtFunctionEntry(
889353358Sdim              m_thread);
890353358Sdim      if (unwind_plan_sp) {
891353358Sdim        UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because we are at "
892353358Sdim                            "the first instruction of a function",
893353358Sdim                            unwind_plan_sp->GetSourceName().GetCString());
894353358Sdim        return unwind_plan_sp;
895353358Sdim      }
896353358Sdim    }
897314564Sdim  }
898262528Semaste
899314564Sdim  // Typically this is unwind info from an eh_frame section intended for
900314564Sdim  // exception handling; only valid at call sites
901314564Sdim  if (process) {
902314564Sdim    unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite(
903353358Sdim        process->GetTarget(), m_thread);
904314564Sdim  }
905314564Sdim  int valid_offset = -1;
906314564Sdim  if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp, valid_offset)) {
907353358Sdim    UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because this "
908353358Sdim                        "is the call-site unwind plan",
909314564Sdim                        unwind_plan_sp->GetSourceName().GetCString());
910314564Sdim    return unwind_plan_sp;
911314564Sdim  }
912314564Sdim
913314564Sdim  // We'd prefer to use an UnwindPlan intended for call sites when we're at a
914341825Sdim  // call site but if we've struck out on that, fall back to using the non-
915341825Sdim  // call-site assembly inspection UnwindPlan if possible.
916314564Sdim  if (process) {
917314564Sdim    unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite(
918353358Sdim        process->GetTarget(), m_thread);
919314564Sdim  }
920314564Sdim  if (unwind_plan_sp &&
921314564Sdim      unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolNo) {
922314564Sdim    // We probably have an UnwindPlan created by inspecting assembly
923341825Sdim    // instructions. The assembly profilers work really well with compiler-
924341825Sdim    // generated functions but hand- written assembly can be problematic. We
925341825Sdim    // set the eh_frame based unwind plan as our fallback unwind plan if
926314564Sdim    // instruction emulation doesn't work out even for non call sites if it is
927341825Sdim    // available and use the architecture default unwind plan if it is not
928341825Sdim    // available. The eh_frame unwind plan is more reliable even on non call
929341825Sdim    // sites then the architecture default plan and for hand written assembly
930341825Sdim    // code it is often written in a way that it valid at all location what
931314564Sdim    // helps in the most common cases when the instruction emulation fails.
932314564Sdim    UnwindPlanSP call_site_unwind_plan =
933353358Sdim        func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget(),
934353358Sdim                                                   m_thread);
935314564Sdim    if (call_site_unwind_plan &&
936314564Sdim        call_site_unwind_plan.get() != unwind_plan_sp.get() &&
937314564Sdim        call_site_unwind_plan->GetSourceName() !=
938314564Sdim            unwind_plan_sp->GetSourceName()) {
939314564Sdim      m_fallback_unwind_plan_sp = call_site_unwind_plan;
940314564Sdim    } else {
941314564Sdim      m_fallback_unwind_plan_sp = arch_default_unwind_plan_sp;
942254721Semaste    }
943314564Sdim  }
944254721Semaste
945314564Sdim  if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp, valid_offset)) {
946353358Sdim    UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because we "
947353358Sdim                        "failed to find a call-site unwind plan that would work",
948314564Sdim                        unwind_plan_sp->GetSourceName().GetCString());
949314564Sdim    return unwind_plan_sp;
950314564Sdim  }
951314564Sdim
952314564Sdim  // If nothing else, use the architectural default UnwindPlan and hope that
953314564Sdim  // does the job.
954314564Sdim  if (arch_default_unwind_plan_sp)
955314564Sdim    UnwindLogMsgVerbose(
956353358Sdim        "frame uses %s for full UnwindPlan because we are falling back "
957353358Sdim        "to the arch default plan",
958314564Sdim        arch_default_unwind_plan_sp->GetSourceName().GetCString());
959314564Sdim  else
960314564Sdim    UnwindLogMsg(
961314564Sdim        "Unable to find any UnwindPlan for full unwind of this frame.");
962258054Semaste
963314564Sdim  return arch_default_unwind_plan_sp;
964254721Semaste}
965254721Semaste
966314564Sdimvoid RegisterContextLLDB::InvalidateAllRegisters() {
967314564Sdim  m_frame_type = eNotAValidFrame;
968254721Semaste}
969254721Semaste
970314564Sdimsize_t RegisterContextLLDB::GetRegisterCount() {
971314564Sdim  return m_thread.GetRegisterContext()->GetRegisterCount();
972254721Semaste}
973254721Semaste
974314564Sdimconst RegisterInfo *RegisterContextLLDB::GetRegisterInfoAtIndex(size_t reg) {
975314564Sdim  return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex(reg);
976254721Semaste}
977254721Semaste
978314564Sdimsize_t RegisterContextLLDB::GetRegisterSetCount() {
979314564Sdim  return m_thread.GetRegisterContext()->GetRegisterSetCount();
980254721Semaste}
981254721Semaste
982314564Sdimconst RegisterSet *RegisterContextLLDB::GetRegisterSet(size_t reg_set) {
983314564Sdim  return m_thread.GetRegisterContext()->GetRegisterSet(reg_set);
984254721Semaste}
985254721Semaste
986314564Sdimuint32_t RegisterContextLLDB::ConvertRegisterKindToRegisterNumber(
987314564Sdim    lldb::RegisterKind kind, uint32_t num) {
988314564Sdim  return m_thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber(
989314564Sdim      kind, num);
990254721Semaste}
991254721Semaste
992314564Sdimbool RegisterContextLLDB::ReadRegisterValueFromRegisterLocation(
993314564Sdim    lldb_private::UnwindLLDB::RegisterLocation regloc,
994314564Sdim    const RegisterInfo *reg_info, RegisterValue &value) {
995314564Sdim  if (!IsValid())
996314564Sdim    return false;
997314564Sdim  bool success = false;
998254721Semaste
999314564Sdim  switch (regloc.type) {
1000314564Sdim  case UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext: {
1001314564Sdim    const RegisterInfo *other_reg_info =
1002314564Sdim        GetRegisterInfoAtIndex(regloc.location.register_number);
1003280031Sdim
1004314564Sdim    if (!other_reg_info)
1005314564Sdim      return false;
1006280031Sdim
1007314564Sdim    success =
1008314564Sdim        m_thread.GetRegisterContext()->ReadRegister(other_reg_info, value);
1009314564Sdim  } break;
1010314564Sdim  case UnwindLLDB::RegisterLocation::eRegisterInRegister: {
1011314564Sdim    const RegisterInfo *other_reg_info =
1012314564Sdim        GetRegisterInfoAtIndex(regloc.location.register_number);
1013254721Semaste
1014314564Sdim    if (!other_reg_info)
1015314564Sdim      return false;
1016254721Semaste
1017314564Sdim    if (IsFrameZero()) {
1018314564Sdim      success =
1019314564Sdim          m_thread.GetRegisterContext()->ReadRegister(other_reg_info, value);
1020314564Sdim    } else {
1021314564Sdim      success = GetNextFrame()->ReadRegister(other_reg_info, value);
1022314564Sdim    }
1023314564Sdim  } break;
1024314564Sdim  case UnwindLLDB::RegisterLocation::eRegisterValueInferred:
1025314564Sdim    success =
1026314564Sdim        value.SetUInt(regloc.location.inferred_value, reg_info->byte_size);
1027314564Sdim    break;
1028254721Semaste
1029314564Sdim  case UnwindLLDB::RegisterLocation::eRegisterNotSaved:
1030314564Sdim    break;
1031314564Sdim  case UnwindLLDB::RegisterLocation::eRegisterSavedAtHostMemoryLocation:
1032314564Sdim    llvm_unreachable("FIXME debugger inferior function call unwind");
1033314564Sdim  case UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation: {
1034321369Sdim    Status error(ReadRegisterValueFromMemory(
1035314564Sdim        reg_info, regloc.location.target_memory_location, reg_info->byte_size,
1036314564Sdim        value));
1037314564Sdim    success = error.Success();
1038314564Sdim  } break;
1039314564Sdim  default:
1040314564Sdim    llvm_unreachable("Unknown RegisterLocation type.");
1041314564Sdim  }
1042314564Sdim  return success;
1043254721Semaste}
1044254721Semaste
1045314564Sdimbool RegisterContextLLDB::WriteRegisterValueToRegisterLocation(
1046314564Sdim    lldb_private::UnwindLLDB::RegisterLocation regloc,
1047314564Sdim    const RegisterInfo *reg_info, const RegisterValue &value) {
1048314564Sdim  if (!IsValid())
1049314564Sdim    return false;
1050254721Semaste
1051314564Sdim  bool success = false;
1052254721Semaste
1053314564Sdim  switch (regloc.type) {
1054314564Sdim  case UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext: {
1055314564Sdim    const RegisterInfo *other_reg_info =
1056314564Sdim        GetRegisterInfoAtIndex(regloc.location.register_number);
1057314564Sdim    success =
1058314564Sdim        m_thread.GetRegisterContext()->WriteRegister(other_reg_info, value);
1059314564Sdim  } break;
1060314564Sdim  case UnwindLLDB::RegisterLocation::eRegisterInRegister: {
1061314564Sdim    const RegisterInfo *other_reg_info =
1062314564Sdim        GetRegisterInfoAtIndex(regloc.location.register_number);
1063314564Sdim    if (IsFrameZero()) {
1064314564Sdim      success =
1065314564Sdim          m_thread.GetRegisterContext()->WriteRegister(other_reg_info, value);
1066314564Sdim    } else {
1067314564Sdim      success = GetNextFrame()->WriteRegister(other_reg_info, value);
1068254721Semaste    }
1069314564Sdim  } break;
1070314564Sdim  case UnwindLLDB::RegisterLocation::eRegisterValueInferred:
1071314564Sdim  case UnwindLLDB::RegisterLocation::eRegisterNotSaved:
1072314564Sdim    break;
1073314564Sdim  case UnwindLLDB::RegisterLocation::eRegisterSavedAtHostMemoryLocation:
1074314564Sdim    llvm_unreachable("FIXME debugger inferior function call unwind");
1075314564Sdim  case UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation: {
1076321369Sdim    Status error(WriteRegisterValueToMemory(
1077314564Sdim        reg_info, regloc.location.target_memory_location, reg_info->byte_size,
1078314564Sdim        value));
1079314564Sdim    success = error.Success();
1080314564Sdim  } break;
1081314564Sdim  default:
1082314564Sdim    llvm_unreachable("Unknown RegisterLocation type.");
1083314564Sdim  }
1084314564Sdim  return success;
1085254721Semaste}
1086254721Semaste
1087314564Sdimbool RegisterContextLLDB::IsValid() const {
1088314564Sdim  return m_frame_type != eNotAValidFrame;
1089254721Semaste}
1090254721Semaste
1091314564Sdim// After the final stack frame in a stack walk we'll get one invalid
1092341825Sdim// (eNotAValidFrame) stack frame -- one past the end of the stack walk.  But
1093341825Sdim// higher-level code will need to tell the differnece between "the unwind plan
1094341825Sdim// below this frame failed" versus "we successfully completed the stack walk"
1095341825Sdim// so this method helps to disambiguate that.
1096280031Sdim
1097314564Sdimbool RegisterContextLLDB::IsTrapHandlerFrame() const {
1098314564Sdim  return m_frame_type == eTrapHandlerFrame;
1099262528Semaste}
1100262528Semaste
1101314564Sdim// A skip frame is a bogus frame on the stack -- but one where we're likely to
1102314564Sdim// find a real frame farther
1103314564Sdim// up the stack if we keep looking.  It's always the second frame in an unwind
1104341825Sdim// (i.e. the first frame after frame zero) where unwinding can be the
1105341825Sdim// trickiest.  Ideally we'll mark up this frame in some way so the user knows
1106341825Sdim// we're displaying bad data and we may have skipped one frame of their real
1107341825Sdim// program in the process of getting back on track.
1108254721Semaste
1109314564Sdimbool RegisterContextLLDB::IsSkipFrame() const {
1110314564Sdim  return m_frame_type == eSkipFrame;
1111254721Semaste}
1112254721Semaste
1113314564Sdimbool RegisterContextLLDB::IsTrapHandlerSymbol(
1114314564Sdim    lldb_private::Process *process,
1115314564Sdim    const lldb_private::SymbolContext &m_sym_ctx) const {
1116314564Sdim  PlatformSP platform_sp(process->GetTarget().GetPlatform());
1117314564Sdim  if (platform_sp) {
1118314564Sdim    const std::vector<ConstString> trap_handler_names(
1119314564Sdim        platform_sp->GetTrapHandlerSymbolNames());
1120314564Sdim    for (ConstString name : trap_handler_names) {
1121314564Sdim      if ((m_sym_ctx.function && m_sym_ctx.function->GetName() == name) ||
1122314564Sdim          (m_sym_ctx.symbol && m_sym_ctx.symbol->GetName() == name)) {
1123314564Sdim        return true;
1124314564Sdim      }
1125262528Semaste    }
1126314564Sdim  }
1127314564Sdim  const std::vector<ConstString> user_specified_trap_handler_names(
1128314564Sdim      m_parent_unwind.GetUserSpecifiedTrapHandlerFunctionNames());
1129314564Sdim  for (ConstString name : user_specified_trap_handler_names) {
1130314564Sdim    if ((m_sym_ctx.function && m_sym_ctx.function->GetName() == name) ||
1131314564Sdim        (m_sym_ctx.symbol && m_sym_ctx.symbol->GetName() == name)) {
1132314564Sdim      return true;
1133314564Sdim    }
1134314564Sdim  }
1135262528Semaste
1136314564Sdim  return false;
1137262528Semaste}
1138262528Semaste
1139314564Sdim// Answer the question: Where did THIS frame save the CALLER frame ("previous"
1140314564Sdim// frame)'s register value?
1141254721Semaste
1142254721Semasteenum UnwindLLDB::RegisterSearchResult
1143314564SdimRegisterContextLLDB::SavedLocationForRegister(
1144314564Sdim    uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc) {
1145314564Sdim  RegisterNumber regnum(m_thread, eRegisterKindLLDB, lldb_regnum);
1146280031Sdim
1147314564Sdim  // Have we already found this register location?
1148314564Sdim  if (!m_registers.empty()) {
1149314564Sdim    std::map<uint32_t,
1150314564Sdim             lldb_private::UnwindLLDB::RegisterLocation>::const_iterator
1151314564Sdim        iterator;
1152314564Sdim    iterator = m_registers.find(regnum.GetAsKind(eRegisterKindLLDB));
1153314564Sdim    if (iterator != m_registers.end()) {
1154314564Sdim      regloc = iterator->second;
1155314564Sdim      UnwindLogMsg("supplying caller's saved %s (%d)'s location, cached",
1156314564Sdim                   regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
1157314564Sdim      return UnwindLLDB::RegisterSearchResult::eRegisterFound;
1158254721Semaste    }
1159314564Sdim  }
1160254721Semaste
1161314564Sdim  // Look through the available UnwindPlans for the register location.
1162254721Semaste
1163314564Sdim  UnwindPlan::Row::RegisterLocation unwindplan_regloc;
1164314564Sdim  bool have_unwindplan_regloc = false;
1165314564Sdim  RegisterKind unwindplan_registerkind = kNumRegisterKinds;
1166254721Semaste
1167314564Sdim  if (m_fast_unwind_plan_sp) {
1168314564Sdim    UnwindPlan::RowSP active_row =
1169314564Sdim        m_fast_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
1170314564Sdim    unwindplan_registerkind = m_fast_unwind_plan_sp->GetRegisterKind();
1171314564Sdim    if (regnum.GetAsKind(unwindplan_registerkind) == LLDB_INVALID_REGNUM) {
1172314564Sdim      UnwindLogMsg("could not convert lldb regnum %s (%d) into %d RegisterKind "
1173314564Sdim                   "reg numbering scheme",
1174314564Sdim                   regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB),
1175314564Sdim                   (int)unwindplan_registerkind);
1176314564Sdim      return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
1177254721Semaste    }
1178314564Sdim    if (active_row->GetRegisterInfo(regnum.GetAsKind(unwindplan_registerkind),
1179314564Sdim                                    unwindplan_regloc)) {
1180314564Sdim      UnwindLogMsg(
1181314564Sdim          "supplying caller's saved %s (%d)'s location using FastUnwindPlan",
1182314564Sdim          regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
1183314564Sdim      have_unwindplan_regloc = true;
1184314564Sdim    }
1185314564Sdim  }
1186254721Semaste
1187314564Sdim  if (!have_unwindplan_regloc) {
1188314564Sdim    // m_full_unwind_plan_sp being NULL means that we haven't tried to find a
1189314564Sdim    // full UnwindPlan yet
1190314564Sdim    if (!m_full_unwind_plan_sp)
1191314564Sdim      m_full_unwind_plan_sp = GetFullUnwindPlanForFrame();
1192254721Semaste
1193314564Sdim    if (m_full_unwind_plan_sp) {
1194314564Sdim      RegisterNumber pc_regnum(m_thread, eRegisterKindGeneric,
1195314564Sdim                               LLDB_REGNUM_GENERIC_PC);
1196280031Sdim
1197314564Sdim      UnwindPlan::RowSP active_row =
1198314564Sdim          m_full_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
1199314564Sdim      unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind();
1200254721Semaste
1201314564Sdim      RegisterNumber return_address_reg;
1202280031Sdim
1203314564Sdim      // If we're fetching the saved pc and this UnwindPlan defines a
1204341825Sdim      // ReturnAddress register (e.g. lr on arm), look for the return address
1205341825Sdim      // register number in the UnwindPlan's row.
1206314564Sdim      if (pc_regnum.IsValid() && pc_regnum == regnum &&
1207314564Sdim          m_full_unwind_plan_sp->GetReturnAddressRegister() !=
1208314564Sdim              LLDB_INVALID_REGNUM) {
1209254721Semaste
1210314564Sdim        return_address_reg.init(
1211314564Sdim            m_thread, m_full_unwind_plan_sp->GetRegisterKind(),
1212314564Sdim            m_full_unwind_plan_sp->GetReturnAddressRegister());
1213314564Sdim        regnum = return_address_reg;
1214314564Sdim        UnwindLogMsg("requested caller's saved PC but this UnwindPlan uses a "
1215314564Sdim                     "RA reg; getting %s (%d) instead",
1216314564Sdim                     return_address_reg.GetName(),
1217314564Sdim                     return_address_reg.GetAsKind(eRegisterKindLLDB));
1218314564Sdim      } else {
1219314564Sdim        if (regnum.GetAsKind(unwindplan_registerkind) == LLDB_INVALID_REGNUM) {
1220314564Sdim          if (unwindplan_registerkind == eRegisterKindGeneric) {
1221314564Sdim            UnwindLogMsg("could not convert lldb regnum %s (%d) into "
1222314564Sdim                         "eRegisterKindGeneric reg numbering scheme",
1223314564Sdim                         regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
1224314564Sdim          } else {
1225314564Sdim            UnwindLogMsg("could not convert lldb regnum %s (%d) into %d "
1226314564Sdim                         "RegisterKind reg numbering scheme",
1227314564Sdim                         regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB),
1228314564Sdim                         (int)unwindplan_registerkind);
1229314564Sdim          }
1230314564Sdim          return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
1231314564Sdim        }
1232314564Sdim      }
1233254721Semaste
1234314564Sdim      if (regnum.IsValid() &&
1235314564Sdim          active_row->GetRegisterInfo(regnum.GetAsKind(unwindplan_registerkind),
1236314564Sdim                                      unwindplan_regloc)) {
1237314564Sdim        have_unwindplan_regloc = true;
1238314564Sdim        UnwindLogMsg(
1239314564Sdim            "supplying caller's saved %s (%d)'s location using %s UnwindPlan",
1240314564Sdim            regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB),
1241314564Sdim            m_full_unwind_plan_sp->GetSourceName().GetCString());
1242314564Sdim      }
1243254721Semaste
1244314564Sdim      // This is frame 0 and we're retrieving the PC and it's saved in a Return
1245341825Sdim      // Address register and it hasn't been saved anywhere yet -- that is,
1246341825Sdim      // it's still live in the actual register. Handle this specially.
1247254721Semaste
1248344779Sdim      if (!have_unwindplan_regloc && return_address_reg.IsValid() &&
1249314564Sdim          IsFrameZero()) {
1250314564Sdim        if (return_address_reg.GetAsKind(eRegisterKindLLDB) !=
1251314564Sdim            LLDB_INVALID_REGNUM) {
1252314564Sdim          lldb_private::UnwindLLDB::RegisterLocation new_regloc;
1253314564Sdim          new_regloc.type =
1254314564Sdim              UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext;
1255314564Sdim          new_regloc.location.register_number =
1256314564Sdim              return_address_reg.GetAsKind(eRegisterKindLLDB);
1257314564Sdim          m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = new_regloc;
1258314564Sdim          regloc = new_regloc;
1259314564Sdim          UnwindLogMsg("supplying caller's register %s (%d) from the live "
1260314564Sdim                       "RegisterContext at frame 0, saved in %d",
1261314564Sdim                       return_address_reg.GetName(),
1262314564Sdim                       return_address_reg.GetAsKind(eRegisterKindLLDB),
1263314564Sdim                       return_address_reg.GetAsKind(eRegisterKindLLDB));
1264314564Sdim          return UnwindLLDB::RegisterSearchResult::eRegisterFound;
1265314564Sdim        }
1266314564Sdim      }
1267254721Semaste
1268314564Sdim      // If this architecture stores the return address in a register (it
1269341825Sdim      // defines a Return Address register) and we're on a non-zero stack frame
1270341825Sdim      // and the Full UnwindPlan says that the pc is stored in the
1271314564Sdim      // RA registers (e.g. lr on arm), then we know that the full unwindplan is
1272314564Sdim      // not trustworthy -- this
1273314564Sdim      // is an impossible situation and the instruction emulation code has
1274341825Sdim      // likely been misled. If this stack frame meets those criteria, we need
1275341825Sdim      // to throw away the Full UnwindPlan that the instruction emulation came
1276341825Sdim      // up with and fall back to the architecture's Default UnwindPlan so the
1277341825Sdim      // stack walk can get past this point.
1278254721Semaste
1279314564Sdim      // Special note:  If the Full UnwindPlan was generated from the compiler,
1280341825Sdim      // don't second-guess it when we're at a call site location.
1281280031Sdim
1282314564Sdim      // arch_default_ra_regnum is the return address register # in the Full
1283314564Sdim      // UnwindPlan register numbering
1284314564Sdim      RegisterNumber arch_default_ra_regnum(m_thread, eRegisterKindGeneric,
1285314564Sdim                                            LLDB_REGNUM_GENERIC_RA);
1286254721Semaste
1287314564Sdim      if (arch_default_ra_regnum.GetAsKind(unwindplan_registerkind) !=
1288314564Sdim              LLDB_INVALID_REGNUM &&
1289314564Sdim          pc_regnum == regnum && unwindplan_regloc.IsInOtherRegister() &&
1290314564Sdim          unwindplan_regloc.GetRegisterNumber() ==
1291314564Sdim              arch_default_ra_regnum.GetAsKind(unwindplan_registerkind) &&
1292314564Sdim          m_full_unwind_plan_sp->GetSourcedFromCompiler() != eLazyBoolYes &&
1293314564Sdim          !m_all_registers_available) {
1294314564Sdim        UnwindLogMsg("%s UnwindPlan tried to restore the pc from the link "
1295314564Sdim                     "register but this is a non-zero frame",
1296314564Sdim                     m_full_unwind_plan_sp->GetSourceName().GetCString());
1297280031Sdim
1298314564Sdim        // Throw away the full unwindplan; install the arch default unwindplan
1299314564Sdim        if (ForceSwitchToFallbackUnwindPlan()) {
1300314564Sdim          // Update for the possibly new unwind plan
1301314564Sdim          unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind();
1302314564Sdim          UnwindPlan::RowSP active_row =
1303314564Sdim              m_full_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
1304280031Sdim
1305314564Sdim          // Sanity check: Verify that we can fetch a pc value and CFA value
1306314564Sdim          // with this unwind plan
1307280031Sdim
1308314564Sdim          RegisterNumber arch_default_pc_reg(m_thread, eRegisterKindGeneric,
1309314564Sdim                                             LLDB_REGNUM_GENERIC_PC);
1310314564Sdim          bool can_fetch_pc_value = false;
1311314564Sdim          bool can_fetch_cfa = false;
1312314564Sdim          addr_t cfa_value;
1313314564Sdim          if (active_row) {
1314314564Sdim            if (arch_default_pc_reg.GetAsKind(unwindplan_registerkind) !=
1315314564Sdim                    LLDB_INVALID_REGNUM &&
1316314564Sdim                active_row->GetRegisterInfo(
1317314564Sdim                    arch_default_pc_reg.GetAsKind(unwindplan_registerkind),
1318314564Sdim                    unwindplan_regloc)) {
1319314564Sdim              can_fetch_pc_value = true;
1320254721Semaste            }
1321344779Sdim            if (ReadFrameAddress(unwindplan_registerkind,
1322344779Sdim                                 active_row->GetCFAValue(), cfa_value)) {
1323314564Sdim              can_fetch_cfa = true;
1324314564Sdim            }
1325314564Sdim          }
1326254721Semaste
1327344779Sdim          have_unwindplan_regloc = can_fetch_pc_value && can_fetch_cfa;
1328314564Sdim        } else {
1329314564Sdim          // We were unable to fall back to another unwind plan
1330314564Sdim          have_unwindplan_regloc = false;
1331254721Semaste        }
1332314564Sdim      }
1333309124Sdim    }
1334314564Sdim  }
1335254721Semaste
1336314564Sdim  ExecutionContext exe_ctx(m_thread.shared_from_this());
1337314564Sdim  Process *process = exe_ctx.GetProcessPtr();
1338344779Sdim  if (!have_unwindplan_regloc) {
1339341825Sdim    // If the UnwindPlan failed to give us an unwind location for this
1340341825Sdim    // register, we may be able to fall back to some ABI-defined default.  For
1341341825Sdim    // example, some ABIs allow to determine the caller's SP via the CFA. Also,
1342341825Sdim    // the ABI may set volatile registers to the undefined state.
1343353358Sdim    ABI *abi = process ? process->GetABI().get() : nullptr;
1344314564Sdim    if (abi) {
1345314564Sdim      const RegisterInfo *reg_info =
1346314564Sdim          GetRegisterInfoAtIndex(regnum.GetAsKind(eRegisterKindLLDB));
1347314564Sdim      if (reg_info &&
1348314564Sdim          abi->GetFallbackRegisterLocation(reg_info, unwindplan_regloc)) {
1349314564Sdim        UnwindLogMsg(
1350314564Sdim            "supplying caller's saved %s (%d)'s location using ABI default",
1351314564Sdim            regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
1352314564Sdim        have_unwindplan_regloc = true;
1353314564Sdim      }
1354254721Semaste    }
1355314564Sdim  }
1356254721Semaste
1357344779Sdim  if (!have_unwindplan_regloc) {
1358314564Sdim    if (IsFrameZero()) {
1359314564Sdim      // This is frame 0 - we should return the actual live register context
1360314564Sdim      // value
1361314564Sdim      lldb_private::UnwindLLDB::RegisterLocation new_regloc;
1362314564Sdim      new_regloc.type =
1363314564Sdim          UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext;
1364314564Sdim      new_regloc.location.register_number = regnum.GetAsKind(eRegisterKindLLDB);
1365314564Sdim      m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = new_regloc;
1366314564Sdim      regloc = new_regloc;
1367314564Sdim      UnwindLogMsg("supplying caller's register %s (%d) from the live "
1368314564Sdim                   "RegisterContext at frame 0",
1369314564Sdim                   regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
1370314564Sdim      return UnwindLLDB::RegisterSearchResult::eRegisterFound;
1371314564Sdim    } else {
1372314564Sdim      std::string unwindplan_name("");
1373314564Sdim      if (m_full_unwind_plan_sp) {
1374314564Sdim        unwindplan_name += "via '";
1375314564Sdim        unwindplan_name += m_full_unwind_plan_sp->GetSourceName().AsCString();
1376314564Sdim        unwindplan_name += "'";
1377314564Sdim      }
1378314564Sdim      UnwindLogMsg("no save location for %s (%d) %s", regnum.GetName(),
1379314564Sdim                   regnum.GetAsKind(eRegisterKindLLDB),
1380314564Sdim                   unwindplan_name.c_str());
1381254721Semaste    }
1382314564Sdim    return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
1383314564Sdim  }
1384254721Semaste
1385314564Sdim  // unwindplan_regloc has valid contents about where to retrieve the register
1386314564Sdim  if (unwindplan_regloc.IsUnspecified()) {
1387314564Sdim    lldb_private::UnwindLLDB::RegisterLocation new_regloc;
1388314564Sdim    new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterNotSaved;
1389314564Sdim    m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = new_regloc;
1390314564Sdim    UnwindLogMsg("save location for %s (%d) is unspecified, continue searching",
1391314564Sdim                 regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
1392314564Sdim    return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
1393314564Sdim  }
1394314564Sdim
1395314564Sdim  if (unwindplan_regloc.IsUndefined()) {
1396314564Sdim    UnwindLogMsg(
1397314564Sdim        "did not supply reg location for %s (%d) because it is volatile",
1398314564Sdim        regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
1399314564Sdim    return UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile;
1400314564Sdim  }
1401314564Sdim
1402314564Sdim  if (unwindplan_regloc.IsSame()) {
1403344779Sdim    if (!IsFrameZero() &&
1404314564Sdim        (regnum.GetAsKind(eRegisterKindGeneric) == LLDB_REGNUM_GENERIC_PC ||
1405314564Sdim         regnum.GetAsKind(eRegisterKindGeneric) == LLDB_REGNUM_GENERIC_RA)) {
1406314564Sdim      UnwindLogMsg("register %s (%d) is marked as 'IsSame' - it is a pc or "
1407314564Sdim                   "return address reg on a non-zero frame -- treat as if we "
1408314564Sdim                   "have no information",
1409314564Sdim                   regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
1410314564Sdim      return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
1411314564Sdim    } else {
1412314564Sdim      regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister;
1413314564Sdim      regloc.location.register_number = regnum.GetAsKind(eRegisterKindLLDB);
1414314564Sdim      m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
1415314564Sdim      UnwindLogMsg(
1416314564Sdim          "supplying caller's register %s (%d), saved in register %s (%d)",
1417314564Sdim          regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB),
1418314564Sdim          regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
1419314564Sdim      return UnwindLLDB::RegisterSearchResult::eRegisterFound;
1420309124Sdim    }
1421314564Sdim  }
1422309124Sdim
1423314564Sdim  if (unwindplan_regloc.IsCFAPlusOffset()) {
1424314564Sdim    int offset = unwindplan_regloc.GetOffset();
1425314564Sdim    regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred;
1426314564Sdim    regloc.location.inferred_value = m_cfa + offset;
1427314564Sdim    m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
1428314564Sdim    UnwindLogMsg("supplying caller's register %s (%d), value is CFA plus "
1429314564Sdim                 "offset %d [value is 0x%" PRIx64 "]",
1430314564Sdim                 regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), offset,
1431314564Sdim                 regloc.location.inferred_value);
1432314564Sdim    return UnwindLLDB::RegisterSearchResult::eRegisterFound;
1433314564Sdim  }
1434314564Sdim
1435314564Sdim  if (unwindplan_regloc.IsAtCFAPlusOffset()) {
1436314564Sdim    int offset = unwindplan_regloc.GetOffset();
1437314564Sdim    regloc.type = UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation;
1438314564Sdim    regloc.location.target_memory_location = m_cfa + offset;
1439314564Sdim    m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
1440314564Sdim    UnwindLogMsg("supplying caller's register %s (%d) from the stack, saved at "
1441314564Sdim                 "CFA plus offset %d [saved at 0x%" PRIx64 "]",
1442314564Sdim                 regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), offset,
1443314564Sdim                 regloc.location.target_memory_location);
1444314564Sdim    return UnwindLLDB::RegisterSearchResult::eRegisterFound;
1445314564Sdim  }
1446314564Sdim
1447344779Sdim  if (unwindplan_regloc.IsAFAPlusOffset()) {
1448344779Sdim    if (m_afa == LLDB_INVALID_ADDRESS)
1449344779Sdim        return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
1450344779Sdim
1451344779Sdim    int offset = unwindplan_regloc.GetOffset();
1452344779Sdim    regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred;
1453344779Sdim    regloc.location.inferred_value = m_afa + offset;
1454344779Sdim    m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
1455344779Sdim    UnwindLogMsg("supplying caller's register %s (%d), value is AFA plus "
1456344779Sdim                 "offset %d [value is 0x%" PRIx64 "]",
1457344779Sdim                 regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), offset,
1458344779Sdim                 regloc.location.inferred_value);
1459344779Sdim    return UnwindLLDB::RegisterSearchResult::eRegisterFound;
1460344779Sdim  }
1461344779Sdim
1462344779Sdim  if (unwindplan_regloc.IsAtAFAPlusOffset()) {
1463344779Sdim    if (m_afa == LLDB_INVALID_ADDRESS)
1464344779Sdim        return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
1465344779Sdim
1466344779Sdim    int offset = unwindplan_regloc.GetOffset();
1467344779Sdim    regloc.type = UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation;
1468344779Sdim    regloc.location.target_memory_location = m_afa + offset;
1469344779Sdim    m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
1470344779Sdim    UnwindLogMsg("supplying caller's register %s (%d) from the stack, saved at "
1471344779Sdim                 "AFA plus offset %d [saved at 0x%" PRIx64 "]",
1472344779Sdim                 regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), offset,
1473344779Sdim                 regloc.location.target_memory_location);
1474344779Sdim    return UnwindLLDB::RegisterSearchResult::eRegisterFound;
1475344779Sdim  }
1476344779Sdim
1477314564Sdim  if (unwindplan_regloc.IsInOtherRegister()) {
1478314564Sdim    uint32_t unwindplan_regnum = unwindplan_regloc.GetRegisterNumber();
1479314564Sdim    RegisterNumber row_regnum(m_thread, unwindplan_registerkind,
1480314564Sdim                              unwindplan_regnum);
1481314564Sdim    if (row_regnum.GetAsKind(eRegisterKindLLDB) == LLDB_INVALID_REGNUM) {
1482314564Sdim      UnwindLogMsg("could not supply caller's %s (%d) location - was saved in "
1483314564Sdim                   "another reg but couldn't convert that regnum",
1484314564Sdim                   regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
1485314564Sdim      return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
1486254721Semaste    }
1487314564Sdim    regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister;
1488314564Sdim    regloc.location.register_number = row_regnum.GetAsKind(eRegisterKindLLDB);
1489314564Sdim    m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
1490314564Sdim    UnwindLogMsg(
1491314564Sdim        "supplying caller's register %s (%d), saved in register %s (%d)",
1492314564Sdim        regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB),
1493314564Sdim        row_regnum.GetName(), row_regnum.GetAsKind(eRegisterKindLLDB));
1494314564Sdim    return UnwindLLDB::RegisterSearchResult::eRegisterFound;
1495314564Sdim  }
1496254721Semaste
1497314564Sdim  if (unwindplan_regloc.IsDWARFExpression() ||
1498314564Sdim      unwindplan_regloc.IsAtDWARFExpression()) {
1499314564Sdim    DataExtractor dwarfdata(unwindplan_regloc.GetDWARFExpressionBytes(),
1500314564Sdim                            unwindplan_regloc.GetDWARFExpressionLength(),
1501314564Sdim                            process->GetByteOrder(),
1502314564Sdim                            process->GetAddressByteSize());
1503314564Sdim    ModuleSP opcode_ctx;
1504360784Sdim    DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr);
1505314564Sdim    dwarfexpr.SetRegisterKind(unwindplan_registerkind);
1506353358Sdim    Value cfa_val = Scalar(m_cfa);
1507353358Sdim    cfa_val.SetValueType(Value::eValueTypeLoadAddress);
1508314564Sdim    Value result;
1509321369Sdim    Status error;
1510353358Sdim    if (dwarfexpr.Evaluate(&exe_ctx, this, 0, &cfa_val, nullptr, result,
1511327952Sdim                           &error)) {
1512314564Sdim      addr_t val;
1513314564Sdim      val = result.GetScalar().ULongLong();
1514314564Sdim      if (unwindplan_regloc.IsDWARFExpression()) {
1515254721Semaste        regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred;
1516314564Sdim        regloc.location.inferred_value = val;
1517314564Sdim        m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
1518314564Sdim        UnwindLogMsg("supplying caller's register %s (%d) via DWARF expression "
1519314564Sdim                     "(IsDWARFExpression)",
1520314564Sdim                     regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
1521254721Semaste        return UnwindLLDB::RegisterSearchResult::eRegisterFound;
1522314564Sdim      } else {
1523314564Sdim        regloc.type =
1524314564Sdim            UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation;
1525314564Sdim        regloc.location.target_memory_location = val;
1526314564Sdim        m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
1527314564Sdim        UnwindLogMsg("supplying caller's register %s (%d) via DWARF expression "
1528314564Sdim                     "(IsAtDWARFExpression)",
1529314564Sdim                     regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
1530254721Semaste        return UnwindLLDB::RegisterSearchResult::eRegisterFound;
1531314564Sdim      }
1532254721Semaste    }
1533314564Sdim    UnwindLogMsg("tried to use IsDWARFExpression or IsAtDWARFExpression for %s "
1534314564Sdim                 "(%d) but failed",
1535314564Sdim                 regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
1536314564Sdim    return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
1537314564Sdim  }
1538254721Semaste
1539314564Sdim  UnwindLogMsg("no save location for %s (%d) in this stack frame",
1540314564Sdim               regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
1541254721Semaste
1542314564Sdim  // FIXME UnwindPlan::Row types atDWARFExpression and isDWARFExpression are
1543314564Sdim  // unsupported.
1544254721Semaste
1545314564Sdim  return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
1546254721Semaste}
1547254721Semaste
1548280031Sdim// TryFallbackUnwindPlan() -- this method is a little tricky.
1549280031Sdim//
1550314564Sdim// When this is called, the frame above -- the caller frame, the "previous"
1551341825Sdim// frame -- is invalid or bad.
1552280031Sdim//
1553341825Sdim// Instead of stopping the stack walk here, we'll try a different UnwindPlan
1554341825Sdim// and see if we can get a valid frame above us.
1555314564Sdim//
1556314564Sdim// This most often happens when an unwind plan based on assembly instruction
1557341825Sdim// inspection is not correct -- mostly with hand-written assembly functions or
1558341825Sdim// functions where the stack frame is set up "out of band", e.g. the kernel
1559341825Sdim// saved the register context and then called an asynchronous trap handler like
1560341825Sdim// _sigtramp.
1561280031Sdim//
1562314564Sdim// Often in these cases, if we just do a dumb stack walk we'll get past this
1563341825Sdim// tricky frame and our usual techniques can continue to be used.
1564254721Semaste
1565314564Sdimbool RegisterContextLLDB::TryFallbackUnwindPlan() {
1566314564Sdim  if (m_fallback_unwind_plan_sp.get() == nullptr)
1567314564Sdim    return false;
1568262528Semaste
1569314564Sdim  if (m_full_unwind_plan_sp.get() == nullptr)
1570314564Sdim    return false;
1571280031Sdim
1572314564Sdim  if (m_full_unwind_plan_sp.get() == m_fallback_unwind_plan_sp.get() ||
1573314564Sdim      m_full_unwind_plan_sp->GetSourceName() ==
1574314564Sdim          m_fallback_unwind_plan_sp->GetSourceName()) {
1575314564Sdim    return false;
1576314564Sdim  }
1577280031Sdim
1578314564Sdim  // If a compiler generated unwind plan failed, trying the arch default
1579341825Sdim  // unwindplan isn't going to do any better.
1580314564Sdim  if (m_full_unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes)
1581314564Sdim    return false;
1582280031Sdim
1583341825Sdim  // Get the caller's pc value and our own CFA value. Swap in the fallback
1584341825Sdim  // unwind plan, re-fetch the caller's pc value and CFA value. If they're the
1585341825Sdim  // same, then the fallback unwind plan provides no benefit.
1586280031Sdim
1587314564Sdim  RegisterNumber pc_regnum(m_thread, eRegisterKindGeneric,
1588314564Sdim                           LLDB_REGNUM_GENERIC_PC);
1589280031Sdim
1590314564Sdim  addr_t old_caller_pc_value = LLDB_INVALID_ADDRESS;
1591314564Sdim  addr_t new_caller_pc_value = LLDB_INVALID_ADDRESS;
1592314564Sdim  UnwindLLDB::RegisterLocation regloc;
1593314564Sdim  if (SavedLocationForRegister(pc_regnum.GetAsKind(eRegisterKindLLDB),
1594314564Sdim                               regloc) ==
1595314564Sdim      UnwindLLDB::RegisterSearchResult::eRegisterFound) {
1596314564Sdim    const RegisterInfo *reg_info =
1597314564Sdim        GetRegisterInfoAtIndex(pc_regnum.GetAsKind(eRegisterKindLLDB));
1598314564Sdim    if (reg_info) {
1599314564Sdim      RegisterValue reg_value;
1600314564Sdim      if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) {
1601314564Sdim        old_caller_pc_value = reg_value.GetAsUInt64();
1602314564Sdim      }
1603280031Sdim    }
1604314564Sdim  }
1605280031Sdim
1606314564Sdim  // This is a tricky wrinkle!  If SavedLocationForRegister() detects a really
1607341825Sdim  // impossible register location for the full unwind plan, it may call
1608341825Sdim  // ForceSwitchToFallbackUnwindPlan() which in turn replaces the full
1609341825Sdim  // unwindplan with the fallback... in short, we're done, we're using the
1610341825Sdim  // fallback UnwindPlan. We checked if m_fallback_unwind_plan_sp was nullptr
1611341825Sdim  // at the top -- the only way it became nullptr since then is via
1612341825Sdim  // SavedLocationForRegister().
1613314564Sdim  if (m_fallback_unwind_plan_sp.get() == nullptr)
1614314564Sdim    return true;
1615280031Sdim
1616314564Sdim  // Switch the full UnwindPlan to be the fallback UnwindPlan.  If we decide
1617341825Sdim  // this isn't working, we need to restore. We'll also need to save & restore
1618341825Sdim  // the value of the m_cfa ivar.  Save is down below a bit in 'old_cfa'.
1619314564Sdim  UnwindPlanSP original_full_unwind_plan_sp = m_full_unwind_plan_sp;
1620314564Sdim  addr_t old_cfa = m_cfa;
1621344779Sdim  addr_t old_afa = m_afa;
1622280031Sdim
1623314564Sdim  m_registers.clear();
1624280031Sdim
1625314564Sdim  m_full_unwind_plan_sp = m_fallback_unwind_plan_sp;
1626280031Sdim
1627314564Sdim  UnwindPlan::RowSP active_row =
1628314564Sdim      m_fallback_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
1629280031Sdim
1630314564Sdim  if (active_row &&
1631314564Sdim      active_row->GetCFAValue().GetValueType() !=
1632344779Sdim          UnwindPlan::Row::FAValue::unspecified) {
1633314564Sdim    addr_t new_cfa;
1634344779Sdim    if (!ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(),
1635344779Sdim                            active_row->GetCFAValue(), new_cfa) ||
1636314564Sdim        new_cfa == 0 || new_cfa == 1 || new_cfa == LLDB_INVALID_ADDRESS) {
1637314564Sdim      UnwindLogMsg("failed to get cfa with fallback unwindplan");
1638314564Sdim      m_fallback_unwind_plan_sp.reset();
1639314564Sdim      m_full_unwind_plan_sp = original_full_unwind_plan_sp;
1640314564Sdim      return false;
1641314564Sdim    }
1642314564Sdim    m_cfa = new_cfa;
1643280031Sdim
1644344779Sdim    ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(),
1645344779Sdim                     active_row->GetAFAValue(), m_afa);
1646344779Sdim
1647314564Sdim    if (SavedLocationForRegister(pc_regnum.GetAsKind(eRegisterKindLLDB),
1648314564Sdim                                 regloc) ==
1649314564Sdim        UnwindLLDB::RegisterSearchResult::eRegisterFound) {
1650314564Sdim      const RegisterInfo *reg_info =
1651314564Sdim          GetRegisterInfoAtIndex(pc_regnum.GetAsKind(eRegisterKindLLDB));
1652314564Sdim      if (reg_info) {
1653314564Sdim        RegisterValue reg_value;
1654314564Sdim        if (ReadRegisterValueFromRegisterLocation(regloc, reg_info,
1655314564Sdim                                                  reg_value)) {
1656314564Sdim          new_caller_pc_value = reg_value.GetAsUInt64();
1657254721Semaste        }
1658314564Sdim      }
1659314564Sdim    }
1660280031Sdim
1661314564Sdim    if (new_caller_pc_value == LLDB_INVALID_ADDRESS) {
1662314564Sdim      UnwindLogMsg("failed to get a pc value for the caller frame with the "
1663314564Sdim                   "fallback unwind plan");
1664314564Sdim      m_fallback_unwind_plan_sp.reset();
1665314564Sdim      m_full_unwind_plan_sp = original_full_unwind_plan_sp;
1666314564Sdim      m_cfa = old_cfa;
1667344779Sdim      m_afa = old_afa;
1668314564Sdim      return false;
1669314564Sdim    }
1670280031Sdim
1671344779Sdim    if (old_caller_pc_value == new_caller_pc_value &&
1672344779Sdim        m_cfa == old_cfa &&
1673344779Sdim        m_afa == old_afa) {
1674344779Sdim      UnwindLogMsg("fallback unwind plan got the same values for this frame "
1675344779Sdim                   "CFA and caller frame pc, not using");
1676344779Sdim      m_fallback_unwind_plan_sp.reset();
1677344779Sdim      m_full_unwind_plan_sp = original_full_unwind_plan_sp;
1678344779Sdim      return false;
1679314564Sdim    }
1680262528Semaste
1681314564Sdim    UnwindLogMsg("trying to unwind from this function with the UnwindPlan '%s' "
1682314564Sdim                 "because UnwindPlan '%s' failed.",
1683314564Sdim                 m_fallback_unwind_plan_sp->GetSourceName().GetCString(),
1684314564Sdim                 original_full_unwind_plan_sp->GetSourceName().GetCString());
1685280031Sdim
1686314564Sdim    // We've copied the fallback unwind plan into the full - now clear the
1687314564Sdim    // fallback.
1688314564Sdim    m_fallback_unwind_plan_sp.reset();
1689360784Sdim    PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp);
1690314564Sdim  }
1691280031Sdim
1692314564Sdim  return true;
1693254721Semaste}
1694254721Semaste
1695314564Sdimbool RegisterContextLLDB::ForceSwitchToFallbackUnwindPlan() {
1696353358Sdim  if (m_fallback_unwind_plan_sp.get() == nullptr)
1697314564Sdim    return false;
1698280031Sdim
1699353358Sdim  if (m_full_unwind_plan_sp.get() == nullptr)
1700314564Sdim    return false;
1701280031Sdim
1702314564Sdim  if (m_full_unwind_plan_sp.get() == m_fallback_unwind_plan_sp.get() ||
1703314564Sdim      m_full_unwind_plan_sp->GetSourceName() ==
1704314564Sdim          m_fallback_unwind_plan_sp->GetSourceName()) {
1705314564Sdim    return false;
1706314564Sdim  }
1707314564Sdim
1708314564Sdim  UnwindPlan::RowSP active_row =
1709314564Sdim      m_fallback_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
1710314564Sdim
1711314564Sdim  if (active_row &&
1712314564Sdim      active_row->GetCFAValue().GetValueType() !=
1713344779Sdim          UnwindPlan::Row::FAValue::unspecified) {
1714314564Sdim    addr_t new_cfa;
1715344779Sdim    if (!ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(),
1716344779Sdim                            active_row->GetCFAValue(), new_cfa) ||
1717314564Sdim        new_cfa == 0 || new_cfa == 1 || new_cfa == LLDB_INVALID_ADDRESS) {
1718314564Sdim      UnwindLogMsg("failed to get cfa with fallback unwindplan");
1719314564Sdim      m_fallback_unwind_plan_sp.reset();
1720314564Sdim      return false;
1721280031Sdim    }
1722280031Sdim
1723344779Sdim    ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(),
1724344779Sdim                     active_row->GetAFAValue(), m_afa);
1725344779Sdim
1726314564Sdim    m_full_unwind_plan_sp = m_fallback_unwind_plan_sp;
1727314564Sdim    m_fallback_unwind_plan_sp.reset();
1728280031Sdim
1729314564Sdim    m_registers.clear();
1730280031Sdim
1731314564Sdim    m_cfa = new_cfa;
1732280031Sdim
1733360784Sdim    PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp);
1734360784Sdim
1735314564Sdim    UnwindLogMsg("switched unconditionally to the fallback unwindplan %s",
1736314564Sdim                 m_full_unwind_plan_sp->GetSourceName().GetCString());
1737314564Sdim    return true;
1738314564Sdim  }
1739314564Sdim  return false;
1740280031Sdim}
1741280031Sdim
1742360784Sdimvoid RegisterContextLLDB::PropagateTrapHandlerFlagFromUnwindPlan(
1743360784Sdim    lldb::UnwindPlanSP unwind_plan) {
1744360784Sdim  if (unwind_plan->GetUnwindPlanForSignalTrap() != eLazyBoolYes) {
1745360784Sdim    // Unwind plan does not indicate trap handler.  Do nothing.  We may
1746360784Sdim    // already be flagged as trap handler flag due to the symbol being
1747360784Sdim    // in the trap handler symbol list, and that should take precedence.
1748360784Sdim    return;
1749360784Sdim  } else if (m_frame_type != eNormalFrame) {
1750360784Sdim    // If this is already a trap handler frame, nothing to do.
1751360784Sdim    // If this is a skip or debug or invalid frame, don't override that.
1752360784Sdim    return;
1753360784Sdim  }
1754360784Sdim
1755360784Sdim  m_frame_type = eTrapHandlerFrame;
1756360784Sdim
1757360784Sdim  if (m_current_offset_backed_up_one != m_current_offset) {
1758360784Sdim    // We backed up the pc by 1 to compute the symbol context, but
1759360784Sdim    // now need to undo that because the pc of the trap handler
1760360784Sdim    // frame may in fact be the first instruction of a signal return
1761360784Sdim    // trampoline, rather than the instruction after a call.  This
1762360784Sdim    // happens on systems where the signal handler dispatch code, rather
1763360784Sdim    // than calling the handler and being returned to, jumps to the
1764360784Sdim    // handler after pushing the address of a return trampoline on the
1765360784Sdim    // stack -- on these systems, when the handler returns, control will
1766360784Sdim    // be transferred to the return trampoline, so that's the best
1767360784Sdim    // symbol we can present in the callstack.
1768360784Sdim    UnwindLogMsg("Resetting current offset and re-doing symbol lookup; "
1769360784Sdim                 "old symbol was %s",
1770360784Sdim                 GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
1771360784Sdim    m_current_offset_backed_up_one = m_current_offset;
1772360784Sdim
1773360784Sdim    AddressRange addr_range;
1774360784Sdim    m_sym_ctx_valid = m_current_pc.ResolveFunctionScope(m_sym_ctx, &addr_range);
1775360784Sdim
1776360784Sdim    UnwindLogMsg("Symbol is now %s",
1777360784Sdim                 GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
1778360784Sdim
1779360784Sdim    ExecutionContext exe_ctx(m_thread.shared_from_this());
1780360784Sdim    Process *process = exe_ctx.GetProcessPtr();
1781360784Sdim    Target *target = &process->GetTarget();
1782360784Sdim
1783360784Sdim    m_start_pc = addr_range.GetBaseAddress();
1784360784Sdim    m_current_offset =
1785360784Sdim        m_current_pc.GetLoadAddress(target) - m_start_pc.GetLoadAddress(target);
1786360784Sdim  }
1787360784Sdim}
1788360784Sdim
1789344779Sdimbool RegisterContextLLDB::ReadFrameAddress(
1790344779Sdim    lldb::RegisterKind row_register_kind, UnwindPlan::Row::FAValue &fa,
1791344779Sdim    addr_t &address) {
1792314564Sdim  RegisterValue reg_value;
1793280031Sdim
1794344779Sdim  address = LLDB_INVALID_ADDRESS;
1795314564Sdim  addr_t cfa_reg_contents;
1796280031Sdim
1797344779Sdim  switch (fa.GetValueType()) {
1798344779Sdim  case UnwindPlan::Row::FAValue::isRegisterDereferenced: {
1799314564Sdim    RegisterNumber cfa_reg(m_thread, row_register_kind,
1800344779Sdim                           fa.GetRegisterNumber());
1801314564Sdim    if (ReadGPRValue(cfa_reg, cfa_reg_contents)) {
1802314564Sdim      const RegisterInfo *reg_info =
1803314564Sdim          GetRegisterInfoAtIndex(cfa_reg.GetAsKind(eRegisterKindLLDB));
1804314564Sdim      RegisterValue reg_value;
1805314564Sdim      if (reg_info) {
1806321369Sdim        Status error = ReadRegisterValueFromMemory(
1807314564Sdim            reg_info, cfa_reg_contents, reg_info->byte_size, reg_value);
1808314564Sdim        if (error.Success()) {
1809344779Sdim          address = reg_value.GetAsUInt64();
1810314564Sdim          UnwindLogMsg(
1811314564Sdim              "CFA value via dereferencing reg %s (%d): reg has val 0x%" PRIx64
1812314564Sdim              ", CFA value is 0x%" PRIx64,
1813314564Sdim              cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB),
1814344779Sdim              cfa_reg_contents, address);
1815314564Sdim          return true;
1816314564Sdim        } else {
1817314564Sdim          UnwindLogMsg("Tried to deref reg %s (%d) [0x%" PRIx64
1818314564Sdim                       "] but memory read failed.",
1819314564Sdim                       cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB),
1820314564Sdim                       cfa_reg_contents);
1821288943Sdim        }
1822314564Sdim      }
1823314564Sdim    }
1824314564Sdim    break;
1825314564Sdim  }
1826344779Sdim  case UnwindPlan::Row::FAValue::isRegisterPlusOffset: {
1827314564Sdim    RegisterNumber cfa_reg(m_thread, row_register_kind,
1828344779Sdim                           fa.GetRegisterNumber());
1829314564Sdim    if (ReadGPRValue(cfa_reg, cfa_reg_contents)) {
1830314564Sdim      if (cfa_reg_contents == LLDB_INVALID_ADDRESS || cfa_reg_contents == 0 ||
1831314564Sdim          cfa_reg_contents == 1) {
1832314564Sdim        UnwindLogMsg(
1833314564Sdim            "Got an invalid CFA register value - reg %s (%d), value 0x%" PRIx64,
1834314564Sdim            cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB),
1835314564Sdim            cfa_reg_contents);
1836314564Sdim        cfa_reg_contents = LLDB_INVALID_ADDRESS;
1837288943Sdim        return false;
1838314564Sdim      }
1839344779Sdim      address = cfa_reg_contents + fa.GetOffset();
1840314564Sdim      UnwindLogMsg(
1841314564Sdim          "CFA is 0x%" PRIx64 ": Register %s (%d) contents are 0x%" PRIx64
1842314564Sdim          ", offset is %d",
1843344779Sdim          address, cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB),
1844344779Sdim          cfa_reg_contents, fa.GetOffset());
1845314564Sdim      return true;
1846280031Sdim    }
1847314564Sdim    break;
1848314564Sdim  }
1849344779Sdim  case UnwindPlan::Row::FAValue::isDWARFExpression: {
1850314564Sdim    ExecutionContext exe_ctx(m_thread.shared_from_this());
1851314564Sdim    Process *process = exe_ctx.GetProcessPtr();
1852344779Sdim    DataExtractor dwarfdata(fa.GetDWARFExpressionBytes(),
1853344779Sdim                            fa.GetDWARFExpressionLength(),
1854314564Sdim                            process->GetByteOrder(),
1855314564Sdim                            process->GetAddressByteSize());
1856314564Sdim    ModuleSP opcode_ctx;
1857360784Sdim    DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr);
1858314564Sdim    dwarfexpr.SetRegisterKind(row_register_kind);
1859314564Sdim    Value result;
1860321369Sdim    Status error;
1861327952Sdim    if (dwarfexpr.Evaluate(&exe_ctx, this, 0, nullptr, nullptr, result,
1862327952Sdim                           &error)) {
1863344779Sdim      address = result.GetScalar().ULongLong();
1864314564Sdim
1865314564Sdim      UnwindLogMsg("CFA value set by DWARF expression is 0x%" PRIx64,
1866344779Sdim                   address);
1867314564Sdim      return true;
1868314564Sdim    }
1869314564Sdim    UnwindLogMsg("Failed to set CFA value via DWARF expression: %s",
1870314564Sdim                 error.AsCString());
1871314564Sdim    break;
1872314564Sdim  }
1873360784Sdim  case UnwindPlan::Row::FAValue::isRaSearch: {
1874360784Sdim    Process &process = *m_thread.GetProcess();
1875360784Sdim    lldb::addr_t return_address_hint = GetReturnAddressHint(fa.GetOffset());
1876360784Sdim    if (return_address_hint == LLDB_INVALID_ADDRESS)
1877360784Sdim      return false;
1878360784Sdim    const unsigned max_iterations = 256;
1879360784Sdim    for (unsigned i = 0; i < max_iterations; ++i) {
1880360784Sdim      Status st;
1881360784Sdim      lldb::addr_t candidate_addr =
1882360784Sdim          return_address_hint + i * process.GetAddressByteSize();
1883360784Sdim      lldb::addr_t candidate =
1884360784Sdim          process.ReadPointerFromMemory(candidate_addr, st);
1885360784Sdim      if (st.Fail()) {
1886360784Sdim        UnwindLogMsg("Cannot read memory at 0x%" PRIx64 ": %s", candidate_addr,
1887360784Sdim                     st.AsCString());
1888360784Sdim        return false;
1889360784Sdim      }
1890360784Sdim      Address addr;
1891360784Sdim      uint32_t permissions;
1892360784Sdim      if (process.GetLoadAddressPermissions(candidate, permissions) &&
1893360784Sdim          permissions & lldb::ePermissionsExecutable) {
1894360784Sdim        address = candidate_addr;
1895360784Sdim        UnwindLogMsg("Heuristically found CFA: 0x%" PRIx64, address);
1896360784Sdim        return true;
1897360784Sdim      }
1898360784Sdim    }
1899360784Sdim    UnwindLogMsg("No suitable CFA found");
1900360784Sdim    break;
1901360784Sdim  }
1902314564Sdim  default:
1903280031Sdim    return false;
1904314564Sdim  }
1905314564Sdim  return false;
1906280031Sdim}
1907280031Sdim
1908360784Sdimlldb::addr_t RegisterContextLLDB::GetReturnAddressHint(int32_t plan_offset) {
1909360784Sdim  addr_t hint;
1910360784Sdim  if (!ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, hint))
1911360784Sdim    return LLDB_INVALID_ADDRESS;
1912360784Sdim  if (!m_sym_ctx.module_sp || !m_sym_ctx.symbol)
1913360784Sdim    return LLDB_INVALID_ADDRESS;
1914360784Sdim
1915360784Sdim  hint += plan_offset;
1916360784Sdim
1917360784Sdim  if (auto next = GetNextFrame()) {
1918360784Sdim    if (!next->m_sym_ctx.module_sp || !next->m_sym_ctx.symbol)
1919360784Sdim      return LLDB_INVALID_ADDRESS;
1920360784Sdim    if (auto expected_size =
1921360784Sdim            next->m_sym_ctx.module_sp->GetSymbolFile()->GetParameterStackSize(
1922360784Sdim                *next->m_sym_ctx.symbol))
1923360784Sdim      hint += *expected_size;
1924360784Sdim    else {
1925360784Sdim      UnwindLogMsgVerbose("Could not retrieve parameter size: %s",
1926360784Sdim                          llvm::toString(expected_size.takeError()).c_str());
1927360784Sdim      return LLDB_INVALID_ADDRESS;
1928360784Sdim    }
1929360784Sdim  }
1930360784Sdim  return hint;
1931360784Sdim}
1932360784Sdim
1933314564Sdim// Retrieve a general purpose register value for THIS frame, as saved by the
1934314564Sdim// NEXT frame, i.e. the frame that
1935254721Semaste// this frame called.  e.g.
1936254721Semaste//
1937254721Semaste//  foo () { }
1938254721Semaste//  bar () { foo (); }
1939254721Semaste//  main () { bar (); }
1940254721Semaste//
1941254721Semaste//  stopped in foo() so
1942254721Semaste//     frame 0 - foo
1943254721Semaste//     frame 1 - bar
1944254721Semaste//     frame 2 - main
1945314564Sdim//  and this RegisterContext is for frame 1 (bar) - if we want to get the pc
1946314564Sdim//  value for frame 1, we need to ask
1947254721Semaste//  where frame 0 (the "next" frame) saved that and retrieve the value.
1948254721Semaste
1949314564Sdimbool RegisterContextLLDB::ReadGPRValue(lldb::RegisterKind register_kind,
1950314564Sdim                                       uint32_t regnum, addr_t &value) {
1951314564Sdim  if (!IsValid())
1952314564Sdim    return false;
1953254721Semaste
1954314564Sdim  uint32_t lldb_regnum;
1955314564Sdim  if (register_kind == eRegisterKindLLDB) {
1956314564Sdim    lldb_regnum = regnum;
1957314564Sdim  } else if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds(
1958314564Sdim                 register_kind, regnum, eRegisterKindLLDB, lldb_regnum)) {
1959314564Sdim    return false;
1960314564Sdim  }
1961254721Semaste
1962314564Sdim  const RegisterInfo *reg_info = GetRegisterInfoAtIndex(lldb_regnum);
1963314564Sdim  RegisterValue reg_value;
1964314564Sdim  // if this is frame 0 (currently executing frame), get the requested reg
1965314564Sdim  // contents from the actual thread registers
1966314564Sdim  if (IsFrameZero()) {
1967314564Sdim    if (m_thread.GetRegisterContext()->ReadRegister(reg_info, reg_value)) {
1968314564Sdim      value = reg_value.GetAsUInt64();
1969314564Sdim      return true;
1970254721Semaste    }
1971314564Sdim    return false;
1972314564Sdim  }
1973254721Semaste
1974314564Sdim  bool pc_register = false;
1975314564Sdim  uint32_t generic_regnum;
1976314564Sdim  if (register_kind == eRegisterKindGeneric &&
1977314564Sdim      (regnum == LLDB_REGNUM_GENERIC_PC || regnum == LLDB_REGNUM_GENERIC_RA)) {
1978314564Sdim    pc_register = true;
1979314564Sdim  } else if (m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds(
1980314564Sdim                 register_kind, regnum, eRegisterKindGeneric, generic_regnum) &&
1981314564Sdim             (generic_regnum == LLDB_REGNUM_GENERIC_PC ||
1982314564Sdim              generic_regnum == LLDB_REGNUM_GENERIC_RA)) {
1983314564Sdim    pc_register = true;
1984314564Sdim  }
1985254721Semaste
1986314564Sdim  lldb_private::UnwindLLDB::RegisterLocation regloc;
1987314564Sdim  if (!m_parent_unwind.SearchForSavedLocationForRegister(
1988314564Sdim          lldb_regnum, regloc, m_frame_number - 1, pc_register)) {
1989254721Semaste    return false;
1990314564Sdim  }
1991314564Sdim  if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) {
1992314564Sdim    value = reg_value.GetAsUInt64();
1993314564Sdim    return true;
1994314564Sdim  }
1995314564Sdim  return false;
1996254721Semaste}
1997254721Semaste
1998314564Sdimbool RegisterContextLLDB::ReadGPRValue(const RegisterNumber &regnum,
1999314564Sdim                                       addr_t &value) {
2000314564Sdim  return ReadGPRValue(regnum.GetRegisterKind(), regnum.GetRegisterNumber(),
2001314564Sdim                      value);
2002280031Sdim}
2003280031Sdim
2004254721Semaste// Find the value of a register in THIS frame
2005254721Semaste
2006314564Sdimbool RegisterContextLLDB::ReadRegister(const RegisterInfo *reg_info,
2007314564Sdim                                       RegisterValue &value) {
2008314564Sdim  if (!IsValid())
2009314564Sdim    return false;
2010254721Semaste
2011314564Sdim  const uint32_t lldb_regnum = reg_info->kinds[eRegisterKindLLDB];
2012314564Sdim  UnwindLogMsgVerbose("looking for register saved location for reg %d",
2013314564Sdim                      lldb_regnum);
2014254721Semaste
2015314564Sdim  // If this is the 0th frame, hand this over to the live register context
2016314564Sdim  if (IsFrameZero()) {
2017314564Sdim    UnwindLogMsgVerbose("passing along to the live register context for reg %d",
2018314564Sdim                        lldb_regnum);
2019314564Sdim    return m_thread.GetRegisterContext()->ReadRegister(reg_info, value);
2020314564Sdim  }
2021254721Semaste
2022314564Sdim  bool is_pc_regnum = false;
2023314564Sdim  if (reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_PC ||
2024314564Sdim      reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_RA) {
2025314564Sdim    is_pc_regnum = true;
2026314564Sdim  }
2027309124Sdim
2028314564Sdim  lldb_private::UnwindLLDB::RegisterLocation regloc;
2029314564Sdim  // Find out where the NEXT frame saved THIS frame's register contents
2030314564Sdim  if (!m_parent_unwind.SearchForSavedLocationForRegister(
2031314564Sdim          lldb_regnum, regloc, m_frame_number - 1, is_pc_regnum))
2032314564Sdim    return false;
2033254721Semaste
2034314564Sdim  return ReadRegisterValueFromRegisterLocation(regloc, reg_info, value);
2035254721Semaste}
2036254721Semaste
2037314564Sdimbool RegisterContextLLDB::WriteRegister(const RegisterInfo *reg_info,
2038314564Sdim                                        const RegisterValue &value) {
2039314564Sdim  if (!IsValid())
2040314564Sdim    return false;
2041254721Semaste
2042314564Sdim  const uint32_t lldb_regnum = reg_info->kinds[eRegisterKindLLDB];
2043314564Sdim  UnwindLogMsgVerbose("looking for register saved location for reg %d",
2044314564Sdim                      lldb_regnum);
2045254721Semaste
2046314564Sdim  // If this is the 0th frame, hand this over to the live register context
2047314564Sdim  if (IsFrameZero()) {
2048314564Sdim    UnwindLogMsgVerbose("passing along to the live register context for reg %d",
2049314564Sdim                        lldb_regnum);
2050314564Sdim    return m_thread.GetRegisterContext()->WriteRegister(reg_info, value);
2051314564Sdim  }
2052254721Semaste
2053314564Sdim  lldb_private::UnwindLLDB::RegisterLocation regloc;
2054314564Sdim  // Find out where the NEXT frame saved THIS frame's register contents
2055314564Sdim  if (!m_parent_unwind.SearchForSavedLocationForRegister(
2056314564Sdim          lldb_regnum, regloc, m_frame_number - 1, false))
2057314564Sdim    return false;
2058254721Semaste
2059314564Sdim  return WriteRegisterValueToRegisterLocation(regloc, reg_info, value);
2060254721Semaste}
2061254721Semaste
2062254721Semaste// Don't need to implement this one
2063314564Sdimbool RegisterContextLLDB::ReadAllRegisterValues(lldb::DataBufferSP &data_sp) {
2064314564Sdim  return false;
2065254721Semaste}
2066254721Semaste
2067254721Semaste// Don't need to implement this one
2068314564Sdimbool RegisterContextLLDB::WriteAllRegisterValues(
2069314564Sdim    const lldb::DataBufferSP &data_sp) {
2070314564Sdim  return false;
2071254721Semaste}
2072254721Semaste
2073254721Semaste// Retrieve the pc value for THIS from
2074254721Semaste
2075314564Sdimbool RegisterContextLLDB::GetCFA(addr_t &cfa) {
2076314564Sdim  if (!IsValid()) {
2077314564Sdim    return false;
2078314564Sdim  }
2079314564Sdim  if (m_cfa == LLDB_INVALID_ADDRESS) {
2080314564Sdim    return false;
2081314564Sdim  }
2082314564Sdim  cfa = m_cfa;
2083314564Sdim  return true;
2084254721Semaste}
2085254721Semaste
2086314564SdimRegisterContextLLDB::SharedPtr RegisterContextLLDB::GetNextFrame() const {
2087314564Sdim  RegisterContextLLDB::SharedPtr regctx;
2088314564Sdim  if (m_frame_number == 0)
2089314564Sdim    return regctx;
2090314564Sdim  return m_parent_unwind.GetRegisterContextForFrameNum(m_frame_number - 1);
2091254721Semaste}
2092254721Semaste
2093314564SdimRegisterContextLLDB::SharedPtr RegisterContextLLDB::GetPrevFrame() const {
2094314564Sdim  RegisterContextLLDB::SharedPtr regctx;
2095314564Sdim  return m_parent_unwind.GetRegisterContextForFrameNum(m_frame_number + 1);
2096254721Semaste}
2097254721Semaste
2098254721Semaste// Retrieve the address of the start of the function of THIS frame
2099254721Semaste
2100314564Sdimbool RegisterContextLLDB::GetStartPC(addr_t &start_pc) {
2101314564Sdim  if (!IsValid())
2102314564Sdim    return false;
2103254721Semaste
2104314564Sdim  if (!m_start_pc.IsValid()) {
2105321369Sdim        bool read_successfully = ReadPC (start_pc);
2106321369Sdim        if (read_successfully)
2107321369Sdim        {
2108321369Sdim            ProcessSP process_sp (m_thread.GetProcess());
2109321369Sdim            if (process_sp)
2110321369Sdim            {
2111321369Sdim                ABI *abi = process_sp->GetABI().get();
2112321369Sdim                if (abi)
2113321369Sdim                    start_pc = abi->FixCodeAddress(start_pc);
2114321369Sdim            }
2115321369Sdim        }
2116321369Sdim        return read_successfully;
2117314564Sdim  }
2118314564Sdim  start_pc = m_start_pc.GetLoadAddress(CalculateTarget().get());
2119314564Sdim  return true;
2120254721Semaste}
2121254721Semaste
2122254721Semaste// Retrieve the current pc value for THIS frame, as saved by the NEXT frame.
2123254721Semaste
2124314564Sdimbool RegisterContextLLDB::ReadPC(addr_t &pc) {
2125314564Sdim  if (!IsValid())
2126314564Sdim    return false;
2127254721Semaste
2128314564Sdim  bool above_trap_handler = false;
2129314564Sdim  if (GetNextFrame().get() && GetNextFrame()->IsValid() &&
2130314564Sdim      GetNextFrame()->IsTrapHandlerFrame())
2131314564Sdim    above_trap_handler = true;
2132280031Sdim
2133314564Sdim  if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc)) {
2134314564Sdim    // A pc value of 0 or 1 is impossible in the middle of the stack -- it
2135314564Sdim    // indicates the end of a stack walk.
2136314564Sdim    // On the currently executing frame (or such a frame interrupted
2137341825Sdim    // asynchronously by sigtramp et al) this may occur if code has jumped
2138341825Sdim    // through a NULL pointer -- we want to be able to unwind past that frame
2139341825Sdim    // to help find the bug.
2140254721Semaste
2141321369Sdim    ProcessSP process_sp (m_thread.GetProcess());
2142321369Sdim    if (process_sp)
2143321369Sdim    {
2144321369Sdim        ABI *abi = process_sp->GetABI().get();
2145321369Sdim        if (abi)
2146321369Sdim            pc = abi->FixCodeAddress(pc);
2147321369Sdim    }
2148321369Sdim
2149344779Sdim    return !(m_all_registers_available == false &&
2150344779Sdim             above_trap_handler == false && (pc == 0 || pc == 1));
2151314564Sdim  } else {
2152314564Sdim    return false;
2153314564Sdim  }
2154254721Semaste}
2155254721Semaste
2156314564Sdimvoid RegisterContextLLDB::UnwindLogMsg(const char *fmt, ...) {
2157314564Sdim  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
2158314564Sdim  if (log) {
2159314564Sdim    va_list args;
2160314564Sdim    va_start(args, fmt);
2161254721Semaste
2162314564Sdim    char *logmsg;
2163353358Sdim    if (vasprintf(&logmsg, fmt, args) == -1 || logmsg == nullptr) {
2164314564Sdim      if (logmsg)
2165314564Sdim        free(logmsg);
2166314564Sdim      va_end(args);
2167314564Sdim      return;
2168314564Sdim    }
2169314564Sdim    va_end(args);
2170254721Semaste
2171360784Sdim    LLDB_LOGF(log, "%*sth%d/fr%u %s",
2172360784Sdim              m_frame_number < 100 ? m_frame_number : 100, "",
2173360784Sdim              m_thread.GetIndexID(), m_frame_number, logmsg);
2174314564Sdim    free(logmsg);
2175314564Sdim  }
2176254721Semaste}
2177254721Semaste
2178314564Sdimvoid RegisterContextLLDB::UnwindLogMsgVerbose(const char *fmt, ...) {
2179314564Sdim  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
2180314564Sdim  if (log && log->GetVerbose()) {
2181314564Sdim    va_list args;
2182314564Sdim    va_start(args, fmt);
2183254721Semaste
2184314564Sdim    char *logmsg;
2185353358Sdim    if (vasprintf(&logmsg, fmt, args) == -1 || logmsg == nullptr) {
2186314564Sdim      if (logmsg)
2187314564Sdim        free(logmsg);
2188314564Sdim      va_end(args);
2189314564Sdim      return;
2190314564Sdim    }
2191314564Sdim    va_end(args);
2192254721Semaste
2193360784Sdim    LLDB_LOGF(log, "%*sth%d/fr%u %s",
2194360784Sdim              m_frame_number < 100 ? m_frame_number : 100, "",
2195360784Sdim              m_thread.GetIndexID(), m_frame_number, logmsg);
2196314564Sdim    free(logmsg);
2197314564Sdim  }
2198254721Semaste}
2199