1d00dff88SPavel Labath //===-- RegisterContextUnwind.cpp -----------------------------------------===// 2d00dff88SPavel Labath // 3d00dff88SPavel Labath // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4d00dff88SPavel Labath // See https://llvm.org/LICENSE.txt for license information. 5d00dff88SPavel Labath // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6d00dff88SPavel Labath // 7d00dff88SPavel Labath //===----------------------------------------------------------------------===// 8d00dff88SPavel Labath 9d00dff88SPavel Labath #include "lldb/Target/RegisterContextUnwind.h" 10d00dff88SPavel Labath #include "lldb/Core/Address.h" 11d00dff88SPavel Labath #include "lldb/Core/AddressRange.h" 12d00dff88SPavel Labath #include "lldb/Core/Module.h" 13d00dff88SPavel Labath #include "lldb/Core/Value.h" 14b74a01a8SZequan Wu #include "lldb/Expression/DWARFExpressionList.h" 15d00dff88SPavel Labath #include "lldb/Symbol/ArmUnwindInfo.h" 16d00dff88SPavel Labath #include "lldb/Symbol/CallFrameInfo.h" 17d00dff88SPavel Labath #include "lldb/Symbol/DWARFCallFrameInfo.h" 18d00dff88SPavel Labath #include "lldb/Symbol/FuncUnwinders.h" 19d00dff88SPavel Labath #include "lldb/Symbol/Function.h" 20d00dff88SPavel Labath #include "lldb/Symbol/ObjectFile.h" 21d00dff88SPavel Labath #include "lldb/Symbol/Symbol.h" 22d00dff88SPavel Labath #include "lldb/Symbol/SymbolContext.h" 23d00dff88SPavel Labath #include "lldb/Symbol/SymbolFile.h" 24d00dff88SPavel Labath #include "lldb/Target/ABI.h" 25d00dff88SPavel Labath #include "lldb/Target/DynamicLoader.h" 26d00dff88SPavel Labath #include "lldb/Target/ExecutionContext.h" 27d82ecb0aSJason Molenda #include "lldb/Target/LanguageRuntime.h" 28d00dff88SPavel Labath #include "lldb/Target/Platform.h" 29d00dff88SPavel Labath #include "lldb/Target/Process.h" 30d00dff88SPavel Labath #include "lldb/Target/SectionLoadList.h" 31d00dff88SPavel Labath #include "lldb/Target/StackFrame.h" 32d00dff88SPavel Labath #include "lldb/Target/Target.h" 33d00dff88SPavel Labath #include "lldb/Target/Thread.h" 34d00dff88SPavel Labath #include "lldb/Utility/DataBufferHeap.h" 35c34698a8SPavel Labath #include "lldb/Utility/LLDBLog.h" 36d00dff88SPavel Labath #include "lldb/Utility/Log.h" 37d00dff88SPavel Labath #include "lldb/Utility/RegisterValue.h" 381410a486SPavel Labath #include "lldb/Utility/VASPrintf.h" 39d00dff88SPavel Labath #include "lldb/lldb-private.h" 40701030c3SJason Molenda 41701030c3SJason Molenda #include <cassert> 42d00dff88SPavel Labath #include <memory> 43d00dff88SPavel Labath 44d00dff88SPavel Labath using namespace lldb; 45d00dff88SPavel Labath using namespace lldb_private; 46d00dff88SPavel Labath 47d00dff88SPavel Labath static ConstString GetSymbolOrFunctionName(const SymbolContext &sym_ctx) { 48d00dff88SPavel Labath if (sym_ctx.symbol) 49d00dff88SPavel Labath return sym_ctx.symbol->GetName(); 50d00dff88SPavel Labath else if (sym_ctx.function) 51d00dff88SPavel Labath return sym_ctx.function->GetName(); 52d00dff88SPavel Labath return ConstString(); 53d00dff88SPavel Labath } 54d00dff88SPavel Labath 55d00dff88SPavel Labath RegisterContextUnwind::RegisterContextUnwind(Thread &thread, 56d00dff88SPavel Labath const SharedPtr &next_frame, 57d00dff88SPavel Labath SymbolContext &sym_ctx, 58d00dff88SPavel Labath uint32_t frame_number, 59d00dff88SPavel Labath UnwindLLDB &unwind_lldb) 60d00dff88SPavel Labath : RegisterContext(thread, frame_number), m_thread(thread), 61d00dff88SPavel Labath m_fast_unwind_plan_sp(), m_full_unwind_plan_sp(), 62d00dff88SPavel Labath m_fallback_unwind_plan_sp(), m_all_registers_available(false), 63d00dff88SPavel Labath m_frame_type(-1), m_cfa(LLDB_INVALID_ADDRESS), 64266bb78fSJason Molenda m_afa(LLDB_INVALID_ADDRESS), m_start_pc(), m_current_pc(), 65266bb78fSJason Molenda m_current_offset(0), m_current_offset_backed_up_one(0), 66266bb78fSJason Molenda m_behaves_like_zeroth_frame(false), m_sym_ctx(sym_ctx), 67266bb78fSJason Molenda m_sym_ctx_valid(false), m_frame_number(frame_number), m_registers(), 68266bb78fSJason Molenda m_parent_unwind(unwind_lldb) { 69d00dff88SPavel Labath m_sym_ctx.Clear(false); 70d00dff88SPavel Labath m_sym_ctx_valid = false; 71d00dff88SPavel Labath 72d00dff88SPavel Labath if (IsFrameZero()) { 73d00dff88SPavel Labath InitializeZerothFrame(); 74d00dff88SPavel Labath } else { 75d00dff88SPavel Labath InitializeNonZerothFrame(); 76d00dff88SPavel Labath } 77d00dff88SPavel Labath 78d00dff88SPavel Labath // This same code exists over in the GetFullUnwindPlanForFrame() but it may 79d00dff88SPavel Labath // not have been executed yet 80d00dff88SPavel Labath if (IsFrameZero() || next_frame->m_frame_type == eTrapHandlerFrame || 81d00dff88SPavel Labath next_frame->m_frame_type == eDebuggerFrame) { 82d00dff88SPavel Labath m_all_registers_available = true; 83d00dff88SPavel Labath } 84d00dff88SPavel Labath } 85d00dff88SPavel Labath 86d00dff88SPavel Labath bool RegisterContextUnwind::IsUnwindPlanValidForCurrentPC( 87b6388e4aSJason Molenda lldb::UnwindPlanSP unwind_plan_sp) { 88d00dff88SPavel Labath if (!unwind_plan_sp) 89d00dff88SPavel Labath return false; 90d00dff88SPavel Labath 91d00dff88SPavel Labath // check if m_current_pc is valid 92d00dff88SPavel Labath if (unwind_plan_sp->PlanValidAtAddress(m_current_pc)) { 93d00dff88SPavel Labath // yes - current offset can be used as is 94d00dff88SPavel Labath return true; 95d00dff88SPavel Labath } 96d00dff88SPavel Labath 97d00dff88SPavel Labath // if m_current_offset <= 0, we've got nothing else to try 98d00dff88SPavel Labath if (m_current_offset <= 0) 99d00dff88SPavel Labath return false; 100d00dff88SPavel Labath 101d00dff88SPavel Labath // check pc - 1 to see if it's valid 102d00dff88SPavel Labath Address pc_minus_one(m_current_pc); 103d00dff88SPavel Labath pc_minus_one.SetOffset(m_current_pc.GetOffset() - 1); 104d00dff88SPavel Labath if (unwind_plan_sp->PlanValidAtAddress(pc_minus_one)) { 105d00dff88SPavel Labath return true; 106d00dff88SPavel Labath } 107d00dff88SPavel Labath 108d00dff88SPavel Labath return false; 109d00dff88SPavel Labath } 110d00dff88SPavel Labath 111d00dff88SPavel Labath // Initialize a RegisterContextUnwind which is the first frame of a stack -- the 112d00dff88SPavel Labath // zeroth frame or currently executing frame. 113d00dff88SPavel Labath 114d00dff88SPavel Labath void RegisterContextUnwind::InitializeZerothFrame() { 115a007a6d8SPavel Labath Log *log = GetLog(LLDBLog::Unwind); 116d00dff88SPavel Labath ExecutionContext exe_ctx(m_thread.shared_from_this()); 117d00dff88SPavel Labath RegisterContextSP reg_ctx_sp = m_thread.GetRegisterContext(); 118d00dff88SPavel Labath 119d00dff88SPavel Labath if (reg_ctx_sp.get() == nullptr) { 120d00dff88SPavel Labath m_frame_type = eNotAValidFrame; 121d00dff88SPavel Labath UnwindLogMsg("frame does not have a register context"); 122d00dff88SPavel Labath return; 123d00dff88SPavel Labath } 124d00dff88SPavel Labath 125d00dff88SPavel Labath addr_t current_pc = reg_ctx_sp->GetPC(); 126d00dff88SPavel Labath 127d00dff88SPavel Labath if (current_pc == LLDB_INVALID_ADDRESS) { 128d00dff88SPavel Labath m_frame_type = eNotAValidFrame; 129d00dff88SPavel Labath UnwindLogMsg("frame does not have a pc"); 130d00dff88SPavel Labath return; 131d00dff88SPavel Labath } 132d00dff88SPavel Labath 133d00dff88SPavel Labath Process *process = exe_ctx.GetProcessPtr(); 134d00dff88SPavel Labath 135d00dff88SPavel Labath // Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs 136d00dff88SPavel Labath // this will strip bit zero in case we read a PC from memory or from the LR. 137d00dff88SPavel Labath // (which would be a no-op in frame 0 where we get it from the register set, 138d00dff88SPavel Labath // but still a good idea to make the call here for other ABIs that may 139d00dff88SPavel Labath // exist.) 1400ce7037bSJason Molenda if (ABISP abi_sp = process->GetABI()) 1410ce7037bSJason Molenda current_pc = abi_sp->FixCodeAddress(current_pc); 142d00dff88SPavel Labath 143266bb78fSJason Molenda UnwindPlanSP lang_runtime_plan_sp = LanguageRuntime::GetRuntimeUnwindPlan( 144266bb78fSJason Molenda m_thread, this, m_behaves_like_zeroth_frame); 145266bb78fSJason Molenda if (lang_runtime_plan_sp.get()) { 146266bb78fSJason Molenda UnwindLogMsg("This is an async frame"); 147266bb78fSJason Molenda } 148266bb78fSJason Molenda 149d00dff88SPavel Labath // Initialize m_current_pc, an Address object, based on current_pc, an 150d00dff88SPavel Labath // addr_t. 151d00dff88SPavel Labath m_current_pc.SetLoadAddress(current_pc, &process->GetTarget()); 152d00dff88SPavel Labath 153d00dff88SPavel Labath // If we don't have a Module for some reason, we're not going to find 154d00dff88SPavel Labath // symbol/function information - just stick in some reasonable defaults and 155d00dff88SPavel Labath // hope we can unwind past this frame. 156d00dff88SPavel Labath ModuleSP pc_module_sp(m_current_pc.GetModule()); 157d00dff88SPavel Labath if (!m_current_pc.IsValid() || !pc_module_sp) { 158d00dff88SPavel Labath UnwindLogMsg("using architectural default unwind method"); 159d00dff88SPavel Labath } 160d00dff88SPavel Labath 161d00dff88SPavel Labath AddressRange addr_range; 162d00dff88SPavel Labath m_sym_ctx_valid = m_current_pc.ResolveFunctionScope(m_sym_ctx, &addr_range); 163d00dff88SPavel Labath 164d00dff88SPavel Labath if (m_sym_ctx.symbol) { 165d00dff88SPavel Labath UnwindLogMsg("with pc value of 0x%" PRIx64 ", symbol name is '%s'", 166d00dff88SPavel Labath current_pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString("")); 167d00dff88SPavel Labath } else if (m_sym_ctx.function) { 168d00dff88SPavel Labath UnwindLogMsg("with pc value of 0x%" PRIx64 ", function name is '%s'", 169d00dff88SPavel Labath current_pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString("")); 170d00dff88SPavel Labath } else { 171d00dff88SPavel Labath UnwindLogMsg("with pc value of 0x%" PRIx64 172d00dff88SPavel Labath ", no symbol/function name is known.", 173d00dff88SPavel Labath current_pc); 174d00dff88SPavel Labath } 175d00dff88SPavel Labath 176d00dff88SPavel Labath if (IsTrapHandlerSymbol(process, m_sym_ctx)) { 177d00dff88SPavel Labath m_frame_type = eTrapHandlerFrame; 178d00dff88SPavel Labath } else { 179d00dff88SPavel Labath // FIXME: Detect eDebuggerFrame here. 180d00dff88SPavel Labath m_frame_type = eNormalFrame; 181d00dff88SPavel Labath } 182d00dff88SPavel Labath 183d00dff88SPavel Labath // If we were able to find a symbol/function, set addr_range to the bounds of 184d00dff88SPavel Labath // that symbol/function. else treat the current pc value as the start_pc and 185d00dff88SPavel Labath // record no offset. 186d00dff88SPavel Labath if (addr_range.GetBaseAddress().IsValid()) { 187d00dff88SPavel Labath m_start_pc = addr_range.GetBaseAddress(); 188d00dff88SPavel Labath if (m_current_pc.GetSection() == m_start_pc.GetSection()) { 189d00dff88SPavel Labath m_current_offset = m_current_pc.GetOffset() - m_start_pc.GetOffset(); 190d00dff88SPavel Labath } else if (m_current_pc.GetModule() == m_start_pc.GetModule()) { 191d00dff88SPavel Labath // This means that whatever symbol we kicked up isn't really correct --- 192d00dff88SPavel Labath // we should not cross section boundaries ... We really should NULL out 193d00dff88SPavel Labath // the function/symbol in this case unless there is a bad assumption here 194d00dff88SPavel Labath // due to inlined functions? 195d00dff88SPavel Labath m_current_offset = 196d00dff88SPavel Labath m_current_pc.GetFileAddress() - m_start_pc.GetFileAddress(); 197d00dff88SPavel Labath } 198d00dff88SPavel Labath m_current_offset_backed_up_one = m_current_offset; 199d00dff88SPavel Labath } else { 200d00dff88SPavel Labath m_start_pc = m_current_pc; 201d00dff88SPavel Labath m_current_offset = -1; 202d00dff88SPavel Labath m_current_offset_backed_up_one = -1; 203d00dff88SPavel Labath } 204d00dff88SPavel Labath 205d00dff88SPavel Labath // We've set m_frame_type and m_sym_ctx before these calls. 206d00dff88SPavel Labath 207d00dff88SPavel Labath m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame(); 208d00dff88SPavel Labath m_full_unwind_plan_sp = GetFullUnwindPlanForFrame(); 209d00dff88SPavel Labath 210d00dff88SPavel Labath UnwindPlan::RowSP active_row; 211d00dff88SPavel Labath lldb::RegisterKind row_register_kind = eRegisterKindGeneric; 212266bb78fSJason Molenda 213266bb78fSJason Molenda // If we have LanguageRuntime UnwindPlan for this unwind, use those 214266bb78fSJason Molenda // rules to find the caller frame instead of the function's normal 215266bb78fSJason Molenda // UnwindPlans. The full unwind plan for this frame will be 216266bb78fSJason Molenda // the LanguageRuntime-provided unwind plan, and there will not be a 217266bb78fSJason Molenda // fast unwind plan. 218266bb78fSJason Molenda if (lang_runtime_plan_sp.get()) { 219266bb78fSJason Molenda active_row = 220266bb78fSJason Molenda lang_runtime_plan_sp->GetRowForFunctionOffset(m_current_offset); 221266bb78fSJason Molenda row_register_kind = lang_runtime_plan_sp->GetRegisterKind(); 222266bb78fSJason Molenda if (!ReadFrameAddress(row_register_kind, active_row->GetCFAValue(), 223266bb78fSJason Molenda m_cfa)) { 224266bb78fSJason Molenda UnwindLogMsg("Cannot set cfa"); 225266bb78fSJason Molenda } else { 226266bb78fSJason Molenda m_full_unwind_plan_sp = lang_runtime_plan_sp; 227266bb78fSJason Molenda if (log) { 228266bb78fSJason Molenda StreamString active_row_strm; 229266bb78fSJason Molenda active_row->Dump(active_row_strm, lang_runtime_plan_sp.get(), &m_thread, 230266bb78fSJason Molenda m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr())); 231266bb78fSJason Molenda UnwindLogMsg("async active row: %s", active_row_strm.GetData()); 232266bb78fSJason Molenda } 233266bb78fSJason Molenda UnwindLogMsg("m_cfa = 0x%" PRIx64 " m_afa = 0x%" PRIx64, m_cfa, m_afa); 234266bb78fSJason Molenda UnwindLogMsg( 235266bb78fSJason Molenda "initialized async frame current pc is 0x%" PRIx64 236266bb78fSJason Molenda " cfa is 0x%" PRIx64 " afa is 0x%" PRIx64, 237266bb78fSJason Molenda (uint64_t)m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr()), 238266bb78fSJason Molenda (uint64_t)m_cfa, (uint64_t)m_afa); 239266bb78fSJason Molenda 240266bb78fSJason Molenda return; 241266bb78fSJason Molenda } 242266bb78fSJason Molenda } 243266bb78fSJason Molenda 244d00dff88SPavel Labath if (m_full_unwind_plan_sp && 245d00dff88SPavel Labath m_full_unwind_plan_sp->PlanValidAtAddress(m_current_pc)) { 246d00dff88SPavel Labath active_row = 247d00dff88SPavel Labath m_full_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset); 248d00dff88SPavel Labath row_register_kind = m_full_unwind_plan_sp->GetRegisterKind(); 249d00dff88SPavel Labath if (active_row.get() && log) { 250d00dff88SPavel Labath StreamString active_row_strm; 251d00dff88SPavel Labath active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, 252d00dff88SPavel Labath m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr())); 253d00dff88SPavel Labath UnwindLogMsg("%s", active_row_strm.GetData()); 254d00dff88SPavel Labath } 255d00dff88SPavel Labath } 256d00dff88SPavel Labath 257d00dff88SPavel Labath if (!active_row.get()) { 258d00dff88SPavel Labath UnwindLogMsg("could not find an unwindplan row for this frame's pc"); 259d00dff88SPavel Labath m_frame_type = eNotAValidFrame; 260d00dff88SPavel Labath return; 261d00dff88SPavel Labath } 262d00dff88SPavel Labath 263d00dff88SPavel Labath if (!ReadFrameAddress(row_register_kind, active_row->GetCFAValue(), m_cfa)) { 264d00dff88SPavel Labath // Try the fall back unwind plan since the 265d00dff88SPavel Labath // full unwind plan failed. 266d00dff88SPavel Labath FuncUnwindersSP func_unwinders_sp; 267d00dff88SPavel Labath UnwindPlanSP call_site_unwind_plan; 268d00dff88SPavel Labath bool cfa_status = false; 269d00dff88SPavel Labath 270d00dff88SPavel Labath if (m_sym_ctx_valid) { 271d00dff88SPavel Labath func_unwinders_sp = 272d00dff88SPavel Labath pc_module_sp->GetUnwindTable().GetFuncUnwindersContainingAddress( 273d00dff88SPavel Labath m_current_pc, m_sym_ctx); 274d00dff88SPavel Labath } 275d00dff88SPavel Labath 276d00dff88SPavel Labath if (func_unwinders_sp.get() != nullptr) 277d00dff88SPavel Labath call_site_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite( 278d00dff88SPavel Labath process->GetTarget(), m_thread); 279d00dff88SPavel Labath 280d00dff88SPavel Labath if (call_site_unwind_plan.get() != nullptr) { 281d00dff88SPavel Labath m_fallback_unwind_plan_sp = call_site_unwind_plan; 282d00dff88SPavel Labath if (TryFallbackUnwindPlan()) 283d00dff88SPavel Labath cfa_status = true; 284d00dff88SPavel Labath } 285d00dff88SPavel Labath if (!cfa_status) { 286d00dff88SPavel Labath UnwindLogMsg("could not read CFA value for first frame."); 287d00dff88SPavel Labath m_frame_type = eNotAValidFrame; 288d00dff88SPavel Labath return; 289d00dff88SPavel Labath } 290d00dff88SPavel Labath } else 291d00dff88SPavel Labath ReadFrameAddress(row_register_kind, active_row->GetAFAValue(), m_afa); 292d00dff88SPavel Labath 293701030c3SJason Molenda if (m_cfa == LLDB_INVALID_ADDRESS && m_afa == LLDB_INVALID_ADDRESS) { 294701030c3SJason Molenda UnwindLogMsg( 295701030c3SJason Molenda "could not read CFA or AFA values for first frame, not valid."); 296701030c3SJason Molenda m_frame_type = eNotAValidFrame; 297701030c3SJason Molenda return; 298701030c3SJason Molenda } 299701030c3SJason Molenda 300d00dff88SPavel Labath UnwindLogMsg("initialized frame current pc is 0x%" PRIx64 " cfa is 0x%" PRIx64 301d00dff88SPavel Labath " afa is 0x%" PRIx64 " using %s UnwindPlan", 302d00dff88SPavel Labath (uint64_t)m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr()), 303d00dff88SPavel Labath (uint64_t)m_cfa, 304d00dff88SPavel Labath (uint64_t)m_afa, 305d00dff88SPavel Labath m_full_unwind_plan_sp->GetSourceName().GetCString()); 306d00dff88SPavel Labath } 307d00dff88SPavel Labath 308d00dff88SPavel Labath // Initialize a RegisterContextUnwind for the non-zeroth frame -- rely on the 309d00dff88SPavel Labath // RegisterContextUnwind "below" it to provide things like its current pc value. 310d00dff88SPavel Labath 311d00dff88SPavel Labath void RegisterContextUnwind::InitializeNonZerothFrame() { 312a007a6d8SPavel Labath Log *log = GetLog(LLDBLog::Unwind); 313d00dff88SPavel Labath if (IsFrameZero()) { 314d00dff88SPavel Labath m_frame_type = eNotAValidFrame; 315d00dff88SPavel Labath UnwindLogMsg("non-zeroth frame tests positive for IsFrameZero -- that " 316d00dff88SPavel Labath "shouldn't happen."); 317d00dff88SPavel Labath return; 318d00dff88SPavel Labath } 319d00dff88SPavel Labath 320d00dff88SPavel Labath if (!GetNextFrame().get() || !GetNextFrame()->IsValid()) { 321d00dff88SPavel Labath m_frame_type = eNotAValidFrame; 322d00dff88SPavel Labath UnwindLogMsg("Could not get next frame, marking this frame as invalid."); 323d00dff88SPavel Labath return; 324d00dff88SPavel Labath } 325d00dff88SPavel Labath if (!m_thread.GetRegisterContext()) { 326d00dff88SPavel Labath m_frame_type = eNotAValidFrame; 327d00dff88SPavel Labath UnwindLogMsg("Could not get register context for this thread, marking this " 328d00dff88SPavel Labath "frame as invalid."); 329d00dff88SPavel Labath return; 330d00dff88SPavel Labath } 331d00dff88SPavel Labath 332d82ecb0aSJason Molenda ExecutionContext exe_ctx(m_thread.shared_from_this()); 333d82ecb0aSJason Molenda Process *process = exe_ctx.GetProcessPtr(); 334d82ecb0aSJason Molenda 335d82ecb0aSJason Molenda // Some languages may have a logical parent stack frame which is 336d82ecb0aSJason Molenda // not a real stack frame, but the programmer would consider it to 337d82ecb0aSJason Molenda // be the caller of the frame, e.g. Swift asynchronous frames. 338d82ecb0aSJason Molenda // 339d82ecb0aSJason Molenda // A LanguageRuntime may provide an UnwindPlan that is used in this 340d82ecb0aSJason Molenda // stack trace base on the RegisterContext contents, intsead 341d82ecb0aSJason Molenda // of the normal UnwindPlans we would use for the return-pc. 342266bb78fSJason Molenda UnwindPlanSP lang_runtime_plan_sp = LanguageRuntime::GetRuntimeUnwindPlan( 343266bb78fSJason Molenda m_thread, this, m_behaves_like_zeroth_frame); 344d82ecb0aSJason Molenda if (lang_runtime_plan_sp.get()) { 345d82ecb0aSJason Molenda UnwindLogMsg("This is an async frame"); 346d82ecb0aSJason Molenda } 347d82ecb0aSJason Molenda 348d00dff88SPavel Labath addr_t pc; 349d00dff88SPavel Labath if (!ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc)) { 350d00dff88SPavel Labath UnwindLogMsg("could not get pc value"); 351d00dff88SPavel Labath m_frame_type = eNotAValidFrame; 352d00dff88SPavel Labath return; 353d00dff88SPavel Labath } 354d00dff88SPavel Labath 355d00dff88SPavel Labath // Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs 356d00dff88SPavel Labath // this will strip bit zero in case we read a PC from memory or from the LR. 3570ce7037bSJason Molenda ABISP abi_sp = process->GetABI(); 3580ce7037bSJason Molenda if (abi_sp) 3590ce7037bSJason Molenda pc = abi_sp->FixCodeAddress(pc); 360d00dff88SPavel Labath 361d00dff88SPavel Labath if (log) { 362d00dff88SPavel Labath UnwindLogMsg("pc = 0x%" PRIx64, pc); 363d00dff88SPavel Labath addr_t reg_val; 3640ce7037bSJason Molenda if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP, reg_val)) { 3650ce7037bSJason Molenda if (abi_sp) 3660ce7037bSJason Molenda reg_val = abi_sp->FixDataAddress(reg_val); 367d00dff88SPavel Labath UnwindLogMsg("fp = 0x%" PRIx64, reg_val); 3680ce7037bSJason Molenda } 3690ce7037bSJason Molenda if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, reg_val)) { 3700ce7037bSJason Molenda if (abi_sp) 3710ce7037bSJason Molenda reg_val = abi_sp->FixDataAddress(reg_val); 372d00dff88SPavel Labath UnwindLogMsg("sp = 0x%" PRIx64, reg_val); 373d00dff88SPavel Labath } 3740ce7037bSJason Molenda } 375d00dff88SPavel Labath 376d00dff88SPavel Labath // A pc of 0x0 means it's the end of the stack crawl unless we're above a trap 377d00dff88SPavel Labath // handler function 378d00dff88SPavel Labath bool above_trap_handler = false; 379d00dff88SPavel Labath if (GetNextFrame().get() && GetNextFrame()->IsValid() && 380d00dff88SPavel Labath GetNextFrame()->IsTrapHandlerFrame()) 381d00dff88SPavel Labath above_trap_handler = true; 382d00dff88SPavel Labath 383d00dff88SPavel Labath if (pc == 0 || pc == 0x1) { 384d00dff88SPavel Labath if (!above_trap_handler) { 385d00dff88SPavel Labath m_frame_type = eNotAValidFrame; 386d00dff88SPavel Labath UnwindLogMsg("this frame has a pc of 0x0"); 387d00dff88SPavel Labath return; 388d00dff88SPavel Labath } 389d00dff88SPavel Labath } 390d00dff88SPavel Labath 391d00dff88SPavel Labath const bool allow_section_end = true; 392d00dff88SPavel Labath m_current_pc.SetLoadAddress(pc, &process->GetTarget(), allow_section_end); 393d00dff88SPavel Labath 394d00dff88SPavel Labath // If we don't have a Module for some reason, we're not going to find 395d00dff88SPavel Labath // symbol/function information - just stick in some reasonable defaults and 396d00dff88SPavel Labath // hope we can unwind past this frame. If we're above a trap handler, 397d00dff88SPavel Labath // we may be at a bogus address because we jumped through a bogus function 398d00dff88SPavel Labath // pointer and trapped, so don't force the arch default unwind plan in that 399d00dff88SPavel Labath // case. 400d00dff88SPavel Labath ModuleSP pc_module_sp(m_current_pc.GetModule()); 401d00dff88SPavel Labath if ((!m_current_pc.IsValid() || !pc_module_sp) && 402d00dff88SPavel Labath above_trap_handler == false) { 403d00dff88SPavel Labath UnwindLogMsg("using architectural default unwind method"); 404d00dff88SPavel Labath 405d00dff88SPavel Labath // Test the pc value to see if we know it's in an unmapped/non-executable 406d00dff88SPavel Labath // region of memory. 407d00dff88SPavel Labath uint32_t permissions; 408d00dff88SPavel Labath if (process->GetLoadAddressPermissions(pc, permissions) && 409d00dff88SPavel Labath (permissions & ePermissionsExecutable) == 0) { 410d00dff88SPavel Labath // If this is the second frame off the stack, we may have unwound the 411d00dff88SPavel Labath // first frame incorrectly. But using the architecture default unwind 412d00dff88SPavel Labath // plan may get us back on track -- albeit possibly skipping a real 413d00dff88SPavel Labath // frame. Give this frame a clearly-invalid pc and see if we can get any 414d00dff88SPavel Labath // further. 415d00dff88SPavel Labath if (GetNextFrame().get() && GetNextFrame()->IsValid() && 416d00dff88SPavel Labath GetNextFrame()->IsFrameZero()) { 417d00dff88SPavel Labath UnwindLogMsg("had a pc of 0x%" PRIx64 " which is not in executable " 418d00dff88SPavel Labath "memory but on frame 1 -- " 419d00dff88SPavel Labath "allowing it once.", 420d00dff88SPavel Labath (uint64_t)pc); 421d00dff88SPavel Labath m_frame_type = eSkipFrame; 422d00dff88SPavel Labath } else { 423d00dff88SPavel Labath // anywhere other than the second frame, a non-executable pc means 424d00dff88SPavel Labath // we're off in the weeds -- stop now. 425d00dff88SPavel Labath m_frame_type = eNotAValidFrame; 426d00dff88SPavel Labath UnwindLogMsg("pc is in a non-executable section of memory and this " 427d00dff88SPavel Labath "isn't the 2nd frame in the stack walk."); 428d00dff88SPavel Labath return; 429d00dff88SPavel Labath } 430d00dff88SPavel Labath } 431d00dff88SPavel Labath 4320ce7037bSJason Molenda if (abi_sp) { 433d00dff88SPavel Labath m_fast_unwind_plan_sp.reset(); 434d00dff88SPavel Labath m_full_unwind_plan_sp = 435d00dff88SPavel Labath std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric); 4360ce7037bSJason Molenda abi_sp->CreateDefaultUnwindPlan(*m_full_unwind_plan_sp); 437d00dff88SPavel Labath if (m_frame_type != eSkipFrame) // don't override eSkipFrame 438d00dff88SPavel Labath { 439d00dff88SPavel Labath m_frame_type = eNormalFrame; 440d00dff88SPavel Labath } 441d00dff88SPavel Labath m_all_registers_available = false; 442d00dff88SPavel Labath m_current_offset = -1; 443d00dff88SPavel Labath m_current_offset_backed_up_one = -1; 444d00dff88SPavel Labath RegisterKind row_register_kind = m_full_unwind_plan_sp->GetRegisterKind(); 445d00dff88SPavel Labath UnwindPlan::RowSP row = m_full_unwind_plan_sp->GetRowForFunctionOffset(0); 446d00dff88SPavel Labath if (row.get()) { 447d00dff88SPavel Labath if (!ReadFrameAddress(row_register_kind, row->GetCFAValue(), m_cfa)) { 448d00dff88SPavel Labath UnwindLogMsg("failed to get cfa value"); 449d00dff88SPavel Labath if (m_frame_type != eSkipFrame) // don't override eSkipFrame 450d00dff88SPavel Labath { 451d00dff88SPavel Labath m_frame_type = eNotAValidFrame; 452d00dff88SPavel Labath } 453d00dff88SPavel Labath return; 454d00dff88SPavel Labath } 455d00dff88SPavel Labath 456d00dff88SPavel Labath ReadFrameAddress(row_register_kind, row->GetAFAValue(), m_afa); 457d00dff88SPavel Labath 458d00dff88SPavel Labath // A couple of sanity checks.. 459d00dff88SPavel Labath if (m_cfa == LLDB_INVALID_ADDRESS || m_cfa == 0 || m_cfa == 1) { 460d00dff88SPavel Labath UnwindLogMsg("could not find a valid cfa address"); 461d00dff88SPavel Labath m_frame_type = eNotAValidFrame; 462d00dff88SPavel Labath return; 463d00dff88SPavel Labath } 464d00dff88SPavel Labath 465d00dff88SPavel Labath // m_cfa should point into the stack memory; if we can query memory 466d00dff88SPavel Labath // region permissions, see if the memory is allocated & readable. 467d00dff88SPavel Labath if (process->GetLoadAddressPermissions(m_cfa, permissions) && 468d00dff88SPavel Labath (permissions & ePermissionsReadable) == 0) { 469d00dff88SPavel Labath m_frame_type = eNotAValidFrame; 470d00dff88SPavel Labath UnwindLogMsg( 471d00dff88SPavel Labath "the CFA points to a region of memory that is not readable"); 472d00dff88SPavel Labath return; 473d00dff88SPavel Labath } 474d00dff88SPavel Labath } else { 475d00dff88SPavel Labath UnwindLogMsg("could not find a row for function offset zero"); 476d00dff88SPavel Labath m_frame_type = eNotAValidFrame; 477d00dff88SPavel Labath return; 478d00dff88SPavel Labath } 479d00dff88SPavel Labath 480d00dff88SPavel Labath if (CheckIfLoopingStack()) { 481d00dff88SPavel Labath TryFallbackUnwindPlan(); 482d00dff88SPavel Labath if (CheckIfLoopingStack()) { 483d00dff88SPavel Labath UnwindLogMsg("same CFA address as next frame, assuming the unwind is " 484d00dff88SPavel Labath "looping - stopping"); 485d00dff88SPavel Labath m_frame_type = eNotAValidFrame; 486d00dff88SPavel Labath return; 487d00dff88SPavel Labath } 488d00dff88SPavel Labath } 489d00dff88SPavel Labath 490d00dff88SPavel Labath UnwindLogMsg("initialized frame cfa is 0x%" PRIx64 " afa is 0x%" PRIx64, 491d00dff88SPavel Labath (uint64_t)m_cfa, (uint64_t)m_afa); 492d00dff88SPavel Labath return; 493d00dff88SPavel Labath } 494d00dff88SPavel Labath m_frame_type = eNotAValidFrame; 495d00dff88SPavel Labath UnwindLogMsg("could not find any symbol for this pc, or a default unwind " 496d00dff88SPavel Labath "plan, to continue unwind."); 497d00dff88SPavel Labath return; 498d00dff88SPavel Labath } 499d00dff88SPavel Labath 500d00dff88SPavel Labath AddressRange addr_range; 501d00dff88SPavel Labath m_sym_ctx_valid = m_current_pc.ResolveFunctionScope(m_sym_ctx, &addr_range); 502d00dff88SPavel Labath 503d00dff88SPavel Labath if (m_sym_ctx.symbol) { 504d00dff88SPavel Labath UnwindLogMsg("with pc value of 0x%" PRIx64 ", symbol name is '%s'", pc, 505d00dff88SPavel Labath GetSymbolOrFunctionName(m_sym_ctx).AsCString("")); 506d00dff88SPavel Labath } else if (m_sym_ctx.function) { 507d00dff88SPavel Labath UnwindLogMsg("with pc value of 0x%" PRIx64 ", function name is '%s'", pc, 508d00dff88SPavel Labath GetSymbolOrFunctionName(m_sym_ctx).AsCString("")); 509d00dff88SPavel Labath } else { 510d00dff88SPavel Labath UnwindLogMsg("with pc value of 0x%" PRIx64 511d00dff88SPavel Labath ", no symbol/function name is known.", 512d00dff88SPavel Labath pc); 513d00dff88SPavel Labath } 514d00dff88SPavel Labath 515d00dff88SPavel Labath bool decr_pc_and_recompute_addr_range; 516d00dff88SPavel Labath 517d00dff88SPavel Labath if (!m_sym_ctx_valid) { 518d00dff88SPavel Labath // Always decrement and recompute if the symbol lookup failed 519d00dff88SPavel Labath decr_pc_and_recompute_addr_range = true; 520d00dff88SPavel Labath } else if (GetNextFrame()->m_frame_type == eTrapHandlerFrame || 521d00dff88SPavel Labath GetNextFrame()->m_frame_type == eDebuggerFrame) { 522d00dff88SPavel Labath // Don't decrement if we're "above" an asynchronous event like 523d00dff88SPavel Labath // sigtramp. 524d00dff88SPavel Labath decr_pc_and_recompute_addr_range = false; 525d00dff88SPavel Labath } else if (!addr_range.GetBaseAddress().IsValid() || 526d00dff88SPavel Labath addr_range.GetBaseAddress().GetSection() != m_current_pc.GetSection() || 527d00dff88SPavel Labath addr_range.GetBaseAddress().GetOffset() != m_current_pc.GetOffset()) { 528b6388e4aSJason Molenda // If our "current" pc isn't the start of a function, decrement the pc 529b6388e4aSJason Molenda // if we're up the stack. 530b6388e4aSJason Molenda if (m_behaves_like_zeroth_frame) 531d00dff88SPavel Labath decr_pc_and_recompute_addr_range = false; 532b6388e4aSJason Molenda else 533b6388e4aSJason Molenda decr_pc_and_recompute_addr_range = true; 534d00dff88SPavel Labath } else if (IsTrapHandlerSymbol(process, m_sym_ctx)) { 535d00dff88SPavel Labath // Signal dispatch may set the return address of the handler it calls to 536d00dff88SPavel Labath // point to the first byte of a return trampoline (like __kernel_rt_sigreturn), 537d00dff88SPavel Labath // so do not decrement and recompute if the symbol we already found is a trap 538d00dff88SPavel Labath // handler. 539d00dff88SPavel Labath decr_pc_and_recompute_addr_range = false; 540266bb78fSJason Molenda } else if (m_behaves_like_zeroth_frame) { 541266bb78fSJason Molenda decr_pc_and_recompute_addr_range = false; 542d00dff88SPavel Labath } else { 543d00dff88SPavel Labath // Decrement to find the function containing the call. 544d00dff88SPavel Labath decr_pc_and_recompute_addr_range = true; 545d00dff88SPavel Labath } 546d00dff88SPavel Labath 547d00dff88SPavel Labath // We need to back up the pc by 1 byte and re-search for the Symbol to handle 548d00dff88SPavel Labath // the case where the "saved pc" value is pointing to the next function, e.g. 549d00dff88SPavel Labath // if a function ends with a CALL instruction. 550d00dff88SPavel Labath // FIXME this may need to be an architectural-dependent behavior; if so we'll 551d00dff88SPavel Labath // need to add a member function 552d00dff88SPavel Labath // to the ABI plugin and consult that. 553d00dff88SPavel Labath if (decr_pc_and_recompute_addr_range) { 554d00dff88SPavel Labath UnwindLogMsg("Backing up the pc value of 0x%" PRIx64 555d00dff88SPavel Labath " by 1 and re-doing symbol lookup; old symbol was %s", 556d00dff88SPavel Labath pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString("")); 557d00dff88SPavel Labath Address temporary_pc; 558d00dff88SPavel Labath temporary_pc.SetLoadAddress(pc - 1, &process->GetTarget()); 559d00dff88SPavel Labath m_sym_ctx.Clear(false); 560d00dff88SPavel Labath m_sym_ctx_valid = temporary_pc.ResolveFunctionScope(m_sym_ctx, &addr_range); 561d00dff88SPavel Labath 562d00dff88SPavel Labath UnwindLogMsg("Symbol is now %s", 563d00dff88SPavel Labath GetSymbolOrFunctionName(m_sym_ctx).AsCString("")); 564d00dff88SPavel Labath } 565d00dff88SPavel Labath 566d00dff88SPavel Labath // If we were able to find a symbol/function, set addr_range_ptr to the 567d00dff88SPavel Labath // bounds of that symbol/function. else treat the current pc value as the 568d00dff88SPavel Labath // start_pc and record no offset. 569d00dff88SPavel Labath if (addr_range.GetBaseAddress().IsValid()) { 570d00dff88SPavel Labath m_start_pc = addr_range.GetBaseAddress(); 571d00dff88SPavel Labath m_current_offset = pc - m_start_pc.GetLoadAddress(&process->GetTarget()); 572d00dff88SPavel Labath m_current_offset_backed_up_one = m_current_offset; 573d00dff88SPavel Labath if (decr_pc_and_recompute_addr_range && 574d00dff88SPavel Labath m_current_offset_backed_up_one > 0) { 575d00dff88SPavel Labath m_current_offset_backed_up_one--; 576d00dff88SPavel Labath if (m_sym_ctx_valid) { 577d00dff88SPavel Labath m_current_pc.SetLoadAddress(pc - 1, &process->GetTarget()); 578d00dff88SPavel Labath } 579d00dff88SPavel Labath } 580d00dff88SPavel Labath } else { 581d00dff88SPavel Labath m_start_pc = m_current_pc; 582d00dff88SPavel Labath m_current_offset = -1; 583d00dff88SPavel Labath m_current_offset_backed_up_one = -1; 584d00dff88SPavel Labath } 585d00dff88SPavel Labath 586d00dff88SPavel Labath if (IsTrapHandlerSymbol(process, m_sym_ctx)) { 587d00dff88SPavel Labath m_frame_type = eTrapHandlerFrame; 588d00dff88SPavel Labath } else { 589d00dff88SPavel Labath // FIXME: Detect eDebuggerFrame here. 590d00dff88SPavel Labath if (m_frame_type != eSkipFrame) // don't override eSkipFrame 591d00dff88SPavel Labath { 592d00dff88SPavel Labath m_frame_type = eNormalFrame; 593d00dff88SPavel Labath } 594d00dff88SPavel Labath } 595d00dff88SPavel Labath 596d00dff88SPavel Labath UnwindPlan::RowSP active_row; 597d00dff88SPavel Labath RegisterKind row_register_kind = eRegisterKindGeneric; 598d00dff88SPavel Labath 599d82ecb0aSJason Molenda // If we have LanguageRuntime UnwindPlan for this unwind, use those 600d82ecb0aSJason Molenda // rules to find the caller frame instead of the function's normal 601d82ecb0aSJason Molenda // UnwindPlans. The full unwind plan for this frame will be 602d82ecb0aSJason Molenda // the LanguageRuntime-provided unwind plan, and there will not be a 603d82ecb0aSJason Molenda // fast unwind plan. 604d82ecb0aSJason Molenda if (lang_runtime_plan_sp.get()) { 605d82ecb0aSJason Molenda active_row = 606d82ecb0aSJason Molenda lang_runtime_plan_sp->GetRowForFunctionOffset(m_current_offset); 607d82ecb0aSJason Molenda row_register_kind = lang_runtime_plan_sp->GetRegisterKind(); 608d82ecb0aSJason Molenda if (!ReadFrameAddress(row_register_kind, active_row->GetCFAValue(), 609d82ecb0aSJason Molenda m_cfa)) { 610d82ecb0aSJason Molenda UnwindLogMsg("Cannot set cfa"); 611d82ecb0aSJason Molenda } else { 612d82ecb0aSJason Molenda m_full_unwind_plan_sp = lang_runtime_plan_sp; 613d82ecb0aSJason Molenda if (log) { 614d82ecb0aSJason Molenda StreamString active_row_strm; 615d82ecb0aSJason Molenda active_row->Dump(active_row_strm, lang_runtime_plan_sp.get(), &m_thread, 616d82ecb0aSJason Molenda m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr())); 617d82ecb0aSJason Molenda UnwindLogMsg("async active row: %s", active_row_strm.GetData()); 618d82ecb0aSJason Molenda } 619d82ecb0aSJason Molenda UnwindLogMsg("m_cfa = 0x%" PRIx64 " m_afa = 0x%" PRIx64, m_cfa, m_afa); 620d82ecb0aSJason Molenda UnwindLogMsg( 621d82ecb0aSJason Molenda "initialized async frame current pc is 0x%" PRIx64 622d82ecb0aSJason Molenda " cfa is 0x%" PRIx64 " afa is 0x%" PRIx64, 623d82ecb0aSJason Molenda (uint64_t)m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr()), 624d82ecb0aSJason Molenda (uint64_t)m_cfa, (uint64_t)m_afa); 625d82ecb0aSJason Molenda 626d82ecb0aSJason Molenda return; 627d82ecb0aSJason Molenda } 628d82ecb0aSJason Molenda } 629d82ecb0aSJason Molenda 630d82ecb0aSJason Molenda // We've set m_frame_type and m_sym_ctx before this call. 631d82ecb0aSJason Molenda m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame(); 632d82ecb0aSJason Molenda 633d00dff88SPavel Labath // Try to get by with just the fast UnwindPlan if possible - the full 634d00dff88SPavel Labath // UnwindPlan may be expensive to get (e.g. if we have to parse the entire 635d00dff88SPavel Labath // eh_frame section of an ObjectFile for the first time.) 636d00dff88SPavel Labath 637d00dff88SPavel Labath if (m_fast_unwind_plan_sp && 638d00dff88SPavel Labath m_fast_unwind_plan_sp->PlanValidAtAddress(m_current_pc)) { 639d00dff88SPavel Labath active_row = 640d00dff88SPavel Labath m_fast_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset); 641d00dff88SPavel Labath row_register_kind = m_fast_unwind_plan_sp->GetRegisterKind(); 642d00dff88SPavel Labath PropagateTrapHandlerFlagFromUnwindPlan(m_fast_unwind_plan_sp); 643d00dff88SPavel Labath if (active_row.get() && log) { 644d00dff88SPavel Labath StreamString active_row_strm; 645d00dff88SPavel Labath active_row->Dump(active_row_strm, m_fast_unwind_plan_sp.get(), &m_thread, 646d00dff88SPavel Labath m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr())); 647fcdef15dSJason Molenda UnwindLogMsg("Using fast unwind plan '%s'", 648fcdef15dSJason Molenda m_fast_unwind_plan_sp->GetSourceName().AsCString()); 649d00dff88SPavel Labath UnwindLogMsg("active row: %s", active_row_strm.GetData()); 650d00dff88SPavel Labath } 651d00dff88SPavel Labath } else { 652d00dff88SPavel Labath m_full_unwind_plan_sp = GetFullUnwindPlanForFrame(); 653b6388e4aSJason Molenda if (IsUnwindPlanValidForCurrentPC(m_full_unwind_plan_sp)) { 654b6388e4aSJason Molenda active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset( 655b6388e4aSJason Molenda m_current_offset_backed_up_one); 656d00dff88SPavel Labath row_register_kind = m_full_unwind_plan_sp->GetRegisterKind(); 657d00dff88SPavel Labath PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp); 658d00dff88SPavel Labath if (active_row.get() && log) { 659d00dff88SPavel Labath StreamString active_row_strm; 660d00dff88SPavel Labath active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), 661d00dff88SPavel Labath &m_thread, 662d00dff88SPavel Labath m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr())); 663fcdef15dSJason Molenda UnwindLogMsg("Using full unwind plan '%s'", 664fcdef15dSJason Molenda m_full_unwind_plan_sp->GetSourceName().AsCString()); 665d00dff88SPavel Labath UnwindLogMsg("active row: %s", active_row_strm.GetData()); 666d00dff88SPavel Labath } 667d00dff88SPavel Labath } 668d00dff88SPavel Labath } 669d00dff88SPavel Labath 670d00dff88SPavel Labath if (!active_row.get()) { 671d00dff88SPavel Labath m_frame_type = eNotAValidFrame; 672d00dff88SPavel Labath UnwindLogMsg("could not find unwind row for this pc"); 673d00dff88SPavel Labath return; 674d00dff88SPavel Labath } 675d00dff88SPavel Labath 676d00dff88SPavel Labath if (!ReadFrameAddress(row_register_kind, active_row->GetCFAValue(), m_cfa)) { 677d00dff88SPavel Labath UnwindLogMsg("failed to get cfa"); 678d00dff88SPavel Labath m_frame_type = eNotAValidFrame; 679d00dff88SPavel Labath return; 680d00dff88SPavel Labath } 681d00dff88SPavel Labath 682d00dff88SPavel Labath ReadFrameAddress(row_register_kind, active_row->GetAFAValue(), m_afa); 683d00dff88SPavel Labath 684d00dff88SPavel Labath UnwindLogMsg("m_cfa = 0x%" PRIx64 " m_afa = 0x%" PRIx64, m_cfa, m_afa); 685d00dff88SPavel Labath 686d00dff88SPavel Labath if (CheckIfLoopingStack()) { 687d00dff88SPavel Labath TryFallbackUnwindPlan(); 688d00dff88SPavel Labath if (CheckIfLoopingStack()) { 689d00dff88SPavel Labath UnwindLogMsg("same CFA address as next frame, assuming the unwind is " 690d00dff88SPavel Labath "looping - stopping"); 691d00dff88SPavel Labath m_frame_type = eNotAValidFrame; 692d00dff88SPavel Labath return; 693d00dff88SPavel Labath } 694d00dff88SPavel Labath } 695d00dff88SPavel Labath 696d00dff88SPavel Labath UnwindLogMsg("initialized frame current pc is 0x%" PRIx64 697d00dff88SPavel Labath " cfa is 0x%" PRIx64 " afa is 0x%" PRIx64, 698d00dff88SPavel Labath (uint64_t)m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr()), 699d00dff88SPavel Labath (uint64_t)m_cfa, 700d00dff88SPavel Labath (uint64_t)m_afa); 701d00dff88SPavel Labath } 702d00dff88SPavel Labath 703d00dff88SPavel Labath bool RegisterContextUnwind::CheckIfLoopingStack() { 704d00dff88SPavel Labath // If we have a bad stack setup, we can get the same CFA value multiple times 705d00dff88SPavel Labath // -- or even more devious, we can actually oscillate between two CFA values. 706d00dff88SPavel Labath // Detect that here and break out to avoid a possible infinite loop in lldb 707d00dff88SPavel Labath // trying to unwind the stack. To detect when we have the same CFA value 708d00dff88SPavel Labath // multiple times, we compare the 709d00dff88SPavel Labath // CFA of the current 710d00dff88SPavel Labath // frame with the 2nd next frame because in some specail case (e.g. signal 711e9264b74SKazuaki Ishizaki // hanlders, hand written assembly without ABI compliance) we can have 2 712d00dff88SPavel Labath // frames with the same 713d00dff88SPavel Labath // CFA (in theory we 714d00dff88SPavel Labath // can have arbitrary number of frames with the same CFA, but more then 2 is 715678e3ee1SFangrui Song // very unlikely) 716d00dff88SPavel Labath 717d00dff88SPavel Labath RegisterContextUnwind::SharedPtr next_frame = GetNextFrame(); 718d00dff88SPavel Labath if (next_frame) { 719d00dff88SPavel Labath RegisterContextUnwind::SharedPtr next_next_frame = 720d00dff88SPavel Labath next_frame->GetNextFrame(); 721d00dff88SPavel Labath addr_t next_next_frame_cfa = LLDB_INVALID_ADDRESS; 722d00dff88SPavel Labath if (next_next_frame && next_next_frame->GetCFA(next_next_frame_cfa)) { 723d00dff88SPavel Labath if (next_next_frame_cfa == m_cfa) { 724d00dff88SPavel Labath // We have a loop in the stack unwind 725d00dff88SPavel Labath return true; 726d00dff88SPavel Labath } 727d00dff88SPavel Labath } 728d00dff88SPavel Labath } 729d00dff88SPavel Labath return false; 730d00dff88SPavel Labath } 731d00dff88SPavel Labath 732d00dff88SPavel Labath bool RegisterContextUnwind::IsFrameZero() const { return m_frame_number == 0; } 733d00dff88SPavel Labath 734266bb78fSJason Molenda bool RegisterContextUnwind::BehavesLikeZerothFrame() const { 735266bb78fSJason Molenda if (m_frame_number == 0) 736266bb78fSJason Molenda return true; 737266bb78fSJason Molenda if (m_behaves_like_zeroth_frame) 738266bb78fSJason Molenda return true; 739266bb78fSJason Molenda return false; 740266bb78fSJason Molenda } 741266bb78fSJason Molenda 742d00dff88SPavel Labath // Find a fast unwind plan for this frame, if possible. 743d00dff88SPavel Labath // 744d00dff88SPavel Labath // On entry to this method, 745d00dff88SPavel Labath // 746d00dff88SPavel Labath // 1. m_frame_type should already be set to eTrapHandlerFrame/eDebuggerFrame 747d00dff88SPavel Labath // if either of those are correct, 748d00dff88SPavel Labath // 2. m_sym_ctx should already be filled in, and 749d00dff88SPavel Labath // 3. m_current_pc should have the current pc value for this frame 750d00dff88SPavel Labath // 4. m_current_offset_backed_up_one should have the current byte offset into 751d00dff88SPavel Labath // the function, maybe backed up by 1, -1 if unknown 752d00dff88SPavel Labath 753d00dff88SPavel Labath UnwindPlanSP RegisterContextUnwind::GetFastUnwindPlanForFrame() { 754d00dff88SPavel Labath UnwindPlanSP unwind_plan_sp; 755d00dff88SPavel Labath ModuleSP pc_module_sp(m_current_pc.GetModule()); 756d00dff88SPavel Labath 757d00dff88SPavel Labath if (!m_current_pc.IsValid() || !pc_module_sp || 758d00dff88SPavel Labath pc_module_sp->GetObjectFile() == nullptr) 759d00dff88SPavel Labath return unwind_plan_sp; 760d00dff88SPavel Labath 761d00dff88SPavel Labath if (IsFrameZero()) 762d00dff88SPavel Labath return unwind_plan_sp; 763d00dff88SPavel Labath 764d00dff88SPavel Labath FuncUnwindersSP func_unwinders_sp( 765d00dff88SPavel Labath pc_module_sp->GetUnwindTable().GetFuncUnwindersContainingAddress( 766d00dff88SPavel Labath m_current_pc, m_sym_ctx)); 767d00dff88SPavel Labath if (!func_unwinders_sp) 768d00dff88SPavel Labath return unwind_plan_sp; 769d00dff88SPavel Labath 770d00dff88SPavel Labath // If we're in _sigtramp(), unwinding past this frame requires special 771d00dff88SPavel Labath // knowledge. 772d00dff88SPavel Labath if (m_frame_type == eTrapHandlerFrame || m_frame_type == eDebuggerFrame) 773d00dff88SPavel Labath return unwind_plan_sp; 774d00dff88SPavel Labath 775d00dff88SPavel Labath unwind_plan_sp = func_unwinders_sp->GetUnwindPlanFastUnwind( 776d00dff88SPavel Labath *m_thread.CalculateTarget(), m_thread); 777d00dff88SPavel Labath if (unwind_plan_sp) { 778d00dff88SPavel Labath if (unwind_plan_sp->PlanValidAtAddress(m_current_pc)) { 779d00dff88SPavel Labath m_frame_type = eNormalFrame; 780d00dff88SPavel Labath return unwind_plan_sp; 781d00dff88SPavel Labath } else { 782d00dff88SPavel Labath unwind_plan_sp.reset(); 783d00dff88SPavel Labath } 784d00dff88SPavel Labath } 785d00dff88SPavel Labath return unwind_plan_sp; 786d00dff88SPavel Labath } 787d00dff88SPavel Labath 788d00dff88SPavel Labath // On entry to this method, 789d00dff88SPavel Labath // 790d00dff88SPavel Labath // 1. m_frame_type should already be set to eTrapHandlerFrame/eDebuggerFrame 791d00dff88SPavel Labath // if either of those are correct, 792d00dff88SPavel Labath // 2. m_sym_ctx should already be filled in, and 793d00dff88SPavel Labath // 3. m_current_pc should have the current pc value for this frame 794d00dff88SPavel Labath // 4. m_current_offset_backed_up_one should have the current byte offset into 795d00dff88SPavel Labath // the function, maybe backed up by 1, -1 if unknown 796d00dff88SPavel Labath 797d00dff88SPavel Labath UnwindPlanSP RegisterContextUnwind::GetFullUnwindPlanForFrame() { 798d00dff88SPavel Labath UnwindPlanSP unwind_plan_sp; 799d00dff88SPavel Labath UnwindPlanSP arch_default_unwind_plan_sp; 800d00dff88SPavel Labath ExecutionContext exe_ctx(m_thread.shared_from_this()); 801d00dff88SPavel Labath Process *process = exe_ctx.GetProcessPtr(); 802d00dff88SPavel Labath ABI *abi = process ? process->GetABI().get() : nullptr; 803d00dff88SPavel Labath if (abi) { 804d00dff88SPavel Labath arch_default_unwind_plan_sp = 805d00dff88SPavel Labath std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric); 806d00dff88SPavel Labath abi->CreateDefaultUnwindPlan(*arch_default_unwind_plan_sp); 807d00dff88SPavel Labath } else { 808d00dff88SPavel Labath UnwindLogMsg( 809d00dff88SPavel Labath "unable to get architectural default UnwindPlan from ABI plugin"); 810d00dff88SPavel Labath } 811d00dff88SPavel Labath 812d00dff88SPavel Labath if (IsFrameZero() || GetNextFrame()->m_frame_type == eTrapHandlerFrame || 813d00dff88SPavel Labath GetNextFrame()->m_frame_type == eDebuggerFrame) { 814266bb78fSJason Molenda m_behaves_like_zeroth_frame = true; 815d00dff88SPavel Labath // If this frame behaves like a 0th frame (currently executing or 816d00dff88SPavel Labath // interrupted asynchronously), all registers can be retrieved. 817d00dff88SPavel Labath m_all_registers_available = true; 818d00dff88SPavel Labath } 819d00dff88SPavel Labath 820d00dff88SPavel Labath // If we've done a jmp 0x0 / bl 0x0 (called through a null function pointer) 821d00dff88SPavel Labath // so the pc is 0x0 in the zeroth frame, we need to use the "unwind at first 822d00dff88SPavel Labath // instruction" arch default UnwindPlan Also, if this Process can report on 823d00dff88SPavel Labath // memory region attributes, any non-executable region means we jumped 824d00dff88SPavel Labath // through a bad function pointer - handle the same way as 0x0. Note, if we 825d00dff88SPavel Labath // have a symbol context & a symbol, we don't want to follow this code path. 826d00dff88SPavel Labath // This is for jumping to memory regions without any information available. 827d00dff88SPavel Labath 828d00dff88SPavel Labath if ((!m_sym_ctx_valid || 829d00dff88SPavel Labath (m_sym_ctx.function == nullptr && m_sym_ctx.symbol == nullptr)) && 830266bb78fSJason Molenda m_behaves_like_zeroth_frame && m_current_pc.IsValid()) { 831d00dff88SPavel Labath uint32_t permissions; 832d00dff88SPavel Labath addr_t current_pc_addr = 833d00dff88SPavel Labath m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr()); 834d00dff88SPavel Labath if (current_pc_addr == 0 || 835d00dff88SPavel Labath (process && 836d00dff88SPavel Labath process->GetLoadAddressPermissions(current_pc_addr, permissions) && 837d00dff88SPavel Labath (permissions & ePermissionsExecutable) == 0)) { 838d00dff88SPavel Labath if (abi) { 839d00dff88SPavel Labath unwind_plan_sp = 840d00dff88SPavel Labath std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric); 841d00dff88SPavel Labath abi->CreateFunctionEntryUnwindPlan(*unwind_plan_sp); 842d00dff88SPavel Labath m_frame_type = eNormalFrame; 843d00dff88SPavel Labath return unwind_plan_sp; 844d00dff88SPavel Labath } 845d00dff88SPavel Labath } 846d00dff88SPavel Labath } 847d00dff88SPavel Labath 848d00dff88SPavel Labath // No Module for the current pc, try using the architecture default unwind. 849d00dff88SPavel Labath ModuleSP pc_module_sp(m_current_pc.GetModule()); 850d00dff88SPavel Labath if (!m_current_pc.IsValid() || !pc_module_sp || 851d00dff88SPavel Labath pc_module_sp->GetObjectFile() == nullptr) { 852d00dff88SPavel Labath m_frame_type = eNormalFrame; 853d00dff88SPavel Labath return arch_default_unwind_plan_sp; 854d00dff88SPavel Labath } 855d00dff88SPavel Labath 856d00dff88SPavel Labath FuncUnwindersSP func_unwinders_sp; 857d00dff88SPavel Labath if (m_sym_ctx_valid) { 858d00dff88SPavel Labath func_unwinders_sp = 859d00dff88SPavel Labath pc_module_sp->GetUnwindTable().GetFuncUnwindersContainingAddress( 860d00dff88SPavel Labath m_current_pc, m_sym_ctx); 861d00dff88SPavel Labath } 862d00dff88SPavel Labath 863d00dff88SPavel Labath // No FuncUnwinders available for this pc (stripped function symbols, lldb 864d00dff88SPavel Labath // could not augment its function table with another source, like 865d00dff88SPavel Labath // LC_FUNCTION_STARTS or eh_frame in ObjectFileMachO). See if eh_frame or the 866d00dff88SPavel Labath // .ARM.exidx tables have unwind information for this address, else fall back 867d00dff88SPavel Labath // to the architectural default unwind. 868d00dff88SPavel Labath if (!func_unwinders_sp) { 869d00dff88SPavel Labath m_frame_type = eNormalFrame; 870d00dff88SPavel Labath 871d00dff88SPavel Labath if (!pc_module_sp || !pc_module_sp->GetObjectFile() || 872d00dff88SPavel Labath !m_current_pc.IsValid()) 873d00dff88SPavel Labath return arch_default_unwind_plan_sp; 874d00dff88SPavel Labath 875d00dff88SPavel Labath // Even with -fomit-frame-pointer, we can try eh_frame to get back on 876d00dff88SPavel Labath // track. 877d00dff88SPavel Labath DWARFCallFrameInfo *eh_frame = 878d00dff88SPavel Labath pc_module_sp->GetUnwindTable().GetEHFrameInfo(); 879d00dff88SPavel Labath if (eh_frame) { 880d00dff88SPavel Labath unwind_plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric); 881d00dff88SPavel Labath if (eh_frame->GetUnwindPlan(m_current_pc, *unwind_plan_sp)) 882d00dff88SPavel Labath return unwind_plan_sp; 883d00dff88SPavel Labath else 884d00dff88SPavel Labath unwind_plan_sp.reset(); 885d00dff88SPavel Labath } 886d00dff88SPavel Labath 887d00dff88SPavel Labath ArmUnwindInfo *arm_exidx = 888d00dff88SPavel Labath pc_module_sp->GetUnwindTable().GetArmUnwindInfo(); 889d00dff88SPavel Labath if (arm_exidx) { 890d00dff88SPavel Labath unwind_plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric); 891d00dff88SPavel Labath if (arm_exidx->GetUnwindPlan(exe_ctx.GetTargetRef(), m_current_pc, 892d00dff88SPavel Labath *unwind_plan_sp)) 893d00dff88SPavel Labath return unwind_plan_sp; 894d00dff88SPavel Labath else 895d00dff88SPavel Labath unwind_plan_sp.reset(); 896d00dff88SPavel Labath } 897d00dff88SPavel Labath 898d00dff88SPavel Labath CallFrameInfo *object_file_unwind = 899d00dff88SPavel Labath pc_module_sp->GetUnwindTable().GetObjectFileUnwindInfo(); 900d00dff88SPavel Labath if (object_file_unwind) { 901d00dff88SPavel Labath unwind_plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric); 902d00dff88SPavel Labath if (object_file_unwind->GetUnwindPlan(m_current_pc, *unwind_plan_sp)) 903d00dff88SPavel Labath return unwind_plan_sp; 904d00dff88SPavel Labath else 905d00dff88SPavel Labath unwind_plan_sp.reset(); 906d00dff88SPavel Labath } 907d00dff88SPavel Labath 908d00dff88SPavel Labath return arch_default_unwind_plan_sp; 909d00dff88SPavel Labath } 910d00dff88SPavel Labath 911d00dff88SPavel Labath if (m_frame_type == eTrapHandlerFrame && process) { 912d00dff88SPavel Labath m_fast_unwind_plan_sp.reset(); 9139db2541dSDavid Spickett 9149db2541dSDavid Spickett // On some platforms the unwind information for signal handlers is not 9159db2541dSDavid Spickett // present or correct. Give the platform plugins a chance to provide 9169db2541dSDavid Spickett // substitute plan. Otherwise, use eh_frame. 9179db2541dSDavid Spickett if (m_sym_ctx_valid) { 9189db2541dSDavid Spickett lldb::PlatformSP platform = process->GetTarget().GetPlatform(); 9199db2541dSDavid Spickett unwind_plan_sp = platform->GetTrapHandlerUnwindPlan( 9209db2541dSDavid Spickett process->GetTarget().GetArchitecture().GetTriple(), 9219db2541dSDavid Spickett GetSymbolOrFunctionName(m_sym_ctx)); 9229db2541dSDavid Spickett 9239db2541dSDavid Spickett if (unwind_plan_sp) 9249db2541dSDavid Spickett return unwind_plan_sp; 9259db2541dSDavid Spickett } 9269db2541dSDavid Spickett 927d00dff88SPavel Labath unwind_plan_sp = 928d00dff88SPavel Labath func_unwinders_sp->GetEHFrameUnwindPlan(process->GetTarget()); 929d00dff88SPavel Labath if (!unwind_plan_sp) 930d00dff88SPavel Labath unwind_plan_sp = 931d00dff88SPavel Labath func_unwinders_sp->GetObjectFileUnwindPlan(process->GetTarget()); 932d00dff88SPavel Labath if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc) && 933d00dff88SPavel Labath unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes) { 934d00dff88SPavel Labath return unwind_plan_sp; 935d00dff88SPavel Labath } 936d00dff88SPavel Labath } 937d00dff88SPavel Labath 938d00dff88SPavel Labath // Ask the DynamicLoader if the eh_frame CFI should be trusted in this frame 939d00dff88SPavel Labath // even when it's frame zero This comes up if we have hand-written functions 940d00dff88SPavel Labath // in a Module and hand-written eh_frame. The assembly instruction 941d00dff88SPavel Labath // inspection may fail and the eh_frame CFI were probably written with some 942d00dff88SPavel Labath // care to do the right thing. It'd be nice if there was a way to ask the 943d00dff88SPavel Labath // eh_frame directly if it is asynchronous (can be trusted at every 944d00dff88SPavel Labath // instruction point) or synchronous (the normal case - only at call sites). 945d00dff88SPavel Labath // But there is not. 946d00dff88SPavel Labath if (process && process->GetDynamicLoader() && 947d00dff88SPavel Labath process->GetDynamicLoader()->AlwaysRelyOnEHUnwindInfo(m_sym_ctx)) { 948d00dff88SPavel Labath // We must specifically call the GetEHFrameUnwindPlan() method here -- 949d00dff88SPavel Labath // normally we would call GetUnwindPlanAtCallSite() -- because CallSite may 950d00dff88SPavel Labath // return an unwind plan sourced from either eh_frame (that's what we 951d00dff88SPavel Labath // intend) or compact unwind (this won't work) 952d00dff88SPavel Labath unwind_plan_sp = 953d00dff88SPavel Labath func_unwinders_sp->GetEHFrameUnwindPlan(process->GetTarget()); 954d00dff88SPavel Labath if (!unwind_plan_sp) 955d00dff88SPavel Labath unwind_plan_sp = 956d00dff88SPavel Labath func_unwinders_sp->GetObjectFileUnwindPlan(process->GetTarget()); 957d00dff88SPavel Labath if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc)) { 958d00dff88SPavel Labath UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because the " 959d00dff88SPavel Labath "DynamicLoader suggested we prefer it", 960d00dff88SPavel Labath unwind_plan_sp->GetSourceName().GetCString()); 961d00dff88SPavel Labath return unwind_plan_sp; 962d00dff88SPavel Labath } 963d00dff88SPavel Labath } 964d00dff88SPavel Labath 965d00dff88SPavel Labath // Typically the NonCallSite UnwindPlan is the unwind created by inspecting 966d00dff88SPavel Labath // the assembly language instructions 967266bb78fSJason Molenda if (m_behaves_like_zeroth_frame && process) { 968d00dff88SPavel Labath unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite( 969d00dff88SPavel Labath process->GetTarget(), m_thread); 970d00dff88SPavel Labath if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc)) { 971d00dff88SPavel Labath if (unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolNo) { 972d00dff88SPavel Labath // We probably have an UnwindPlan created by inspecting assembly 973d00dff88SPavel Labath // instructions. The assembly profilers work really well with compiler- 974d00dff88SPavel Labath // generated functions but hand- written assembly can be problematic. 975d00dff88SPavel Labath // We set the eh_frame based unwind plan as our fallback unwind plan if 976d00dff88SPavel Labath // instruction emulation doesn't work out even for non call sites if it 977d00dff88SPavel Labath // is available and use the architecture default unwind plan if it is 978d00dff88SPavel Labath // not available. The eh_frame unwind plan is more reliable even on non 979d00dff88SPavel Labath // call sites then the architecture default plan and for hand written 980d00dff88SPavel Labath // assembly code it is often written in a way that it valid at all 981d00dff88SPavel Labath // location what helps in the most common cases when the instruction 982d00dff88SPavel Labath // emulation fails. 983d00dff88SPavel Labath UnwindPlanSP call_site_unwind_plan = 984d00dff88SPavel Labath func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget(), 985d00dff88SPavel Labath m_thread); 986d00dff88SPavel Labath if (call_site_unwind_plan && 987d00dff88SPavel Labath call_site_unwind_plan.get() != unwind_plan_sp.get() && 988d00dff88SPavel Labath call_site_unwind_plan->GetSourceName() != 989d00dff88SPavel Labath unwind_plan_sp->GetSourceName()) { 990d00dff88SPavel Labath m_fallback_unwind_plan_sp = call_site_unwind_plan; 991d00dff88SPavel Labath } else { 992d00dff88SPavel Labath m_fallback_unwind_plan_sp = arch_default_unwind_plan_sp; 993d00dff88SPavel Labath } 994d00dff88SPavel Labath } 995d00dff88SPavel Labath UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because this " 996d00dff88SPavel Labath "is the non-call site unwind plan and this is a " 997d00dff88SPavel Labath "zeroth frame", 998d00dff88SPavel Labath unwind_plan_sp->GetSourceName().GetCString()); 999d00dff88SPavel Labath return unwind_plan_sp; 1000d00dff88SPavel Labath } 1001d00dff88SPavel Labath 1002d00dff88SPavel Labath // If we're on the first instruction of a function, and we have an 1003d00dff88SPavel Labath // architectural default UnwindPlan for the initial instruction of a 1004d00dff88SPavel Labath // function, use that. 1005d00dff88SPavel Labath if (m_current_offset == 0) { 1006d00dff88SPavel Labath unwind_plan_sp = 1007d00dff88SPavel Labath func_unwinders_sp->GetUnwindPlanArchitectureDefaultAtFunctionEntry( 1008d00dff88SPavel Labath m_thread); 1009d00dff88SPavel Labath if (unwind_plan_sp) { 1010d00dff88SPavel Labath UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because we are at " 1011d00dff88SPavel Labath "the first instruction of a function", 1012d00dff88SPavel Labath unwind_plan_sp->GetSourceName().GetCString()); 1013d00dff88SPavel Labath return unwind_plan_sp; 1014d00dff88SPavel Labath } 1015d00dff88SPavel Labath } 1016d00dff88SPavel Labath } 1017d00dff88SPavel Labath 1018d00dff88SPavel Labath // Typically this is unwind info from an eh_frame section intended for 1019d00dff88SPavel Labath // exception handling; only valid at call sites 1020d00dff88SPavel Labath if (process) { 1021d00dff88SPavel Labath unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite( 1022d00dff88SPavel Labath process->GetTarget(), m_thread); 1023d00dff88SPavel Labath } 1024b6388e4aSJason Molenda if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp)) { 1025d00dff88SPavel Labath UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because this " 1026d00dff88SPavel Labath "is the call-site unwind plan", 1027d00dff88SPavel Labath unwind_plan_sp->GetSourceName().GetCString()); 1028d00dff88SPavel Labath return unwind_plan_sp; 1029d00dff88SPavel Labath } 1030d00dff88SPavel Labath 1031d00dff88SPavel Labath // We'd prefer to use an UnwindPlan intended for call sites when we're at a 1032d00dff88SPavel Labath // call site but if we've struck out on that, fall back to using the non- 1033d00dff88SPavel Labath // call-site assembly inspection UnwindPlan if possible. 1034d00dff88SPavel Labath if (process) { 1035d00dff88SPavel Labath unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite( 1036d00dff88SPavel Labath process->GetTarget(), m_thread); 1037d00dff88SPavel Labath } 1038d00dff88SPavel Labath if (unwind_plan_sp && 1039d00dff88SPavel Labath unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolNo) { 1040d00dff88SPavel Labath // We probably have an UnwindPlan created by inspecting assembly 1041d00dff88SPavel Labath // instructions. The assembly profilers work really well with compiler- 1042d00dff88SPavel Labath // generated functions but hand- written assembly can be problematic. We 1043d00dff88SPavel Labath // set the eh_frame based unwind plan as our fallback unwind plan if 1044d00dff88SPavel Labath // instruction emulation doesn't work out even for non call sites if it is 1045d00dff88SPavel Labath // available and use the architecture default unwind plan if it is not 1046d00dff88SPavel Labath // available. The eh_frame unwind plan is more reliable even on non call 1047d00dff88SPavel Labath // sites then the architecture default plan and for hand written assembly 1048d00dff88SPavel Labath // code it is often written in a way that it valid at all location what 1049d00dff88SPavel Labath // helps in the most common cases when the instruction emulation fails. 1050d00dff88SPavel Labath UnwindPlanSP call_site_unwind_plan = 1051d00dff88SPavel Labath func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget(), 1052d00dff88SPavel Labath m_thread); 1053d00dff88SPavel Labath if (call_site_unwind_plan && 1054d00dff88SPavel Labath call_site_unwind_plan.get() != unwind_plan_sp.get() && 1055d00dff88SPavel Labath call_site_unwind_plan->GetSourceName() != 1056d00dff88SPavel Labath unwind_plan_sp->GetSourceName()) { 1057d00dff88SPavel Labath m_fallback_unwind_plan_sp = call_site_unwind_plan; 1058d00dff88SPavel Labath } else { 1059d00dff88SPavel Labath m_fallback_unwind_plan_sp = arch_default_unwind_plan_sp; 1060d00dff88SPavel Labath } 1061d00dff88SPavel Labath } 1062d00dff88SPavel Labath 1063b6388e4aSJason Molenda if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp)) { 1064d00dff88SPavel Labath UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because we " 1065d00dff88SPavel Labath "failed to find a call-site unwind plan that would work", 1066d00dff88SPavel Labath unwind_plan_sp->GetSourceName().GetCString()); 1067d00dff88SPavel Labath return unwind_plan_sp; 1068d00dff88SPavel Labath } 1069d00dff88SPavel Labath 1070d00dff88SPavel Labath // If nothing else, use the architectural default UnwindPlan and hope that 1071d00dff88SPavel Labath // does the job. 1072d00dff88SPavel Labath if (arch_default_unwind_plan_sp) 1073d00dff88SPavel Labath UnwindLogMsgVerbose( 1074d00dff88SPavel Labath "frame uses %s for full UnwindPlan because we are falling back " 1075d00dff88SPavel Labath "to the arch default plan", 1076d00dff88SPavel Labath arch_default_unwind_plan_sp->GetSourceName().GetCString()); 1077d00dff88SPavel Labath else 1078d00dff88SPavel Labath UnwindLogMsg( 1079d00dff88SPavel Labath "Unable to find any UnwindPlan for full unwind of this frame."); 1080d00dff88SPavel Labath 1081d00dff88SPavel Labath return arch_default_unwind_plan_sp; 1082d00dff88SPavel Labath } 1083d00dff88SPavel Labath 1084d00dff88SPavel Labath void RegisterContextUnwind::InvalidateAllRegisters() { 1085d00dff88SPavel Labath m_frame_type = eNotAValidFrame; 1086d00dff88SPavel Labath } 1087d00dff88SPavel Labath 1088d00dff88SPavel Labath size_t RegisterContextUnwind::GetRegisterCount() { 1089d00dff88SPavel Labath return m_thread.GetRegisterContext()->GetRegisterCount(); 1090d00dff88SPavel Labath } 1091d00dff88SPavel Labath 1092d00dff88SPavel Labath const RegisterInfo *RegisterContextUnwind::GetRegisterInfoAtIndex(size_t reg) { 1093d00dff88SPavel Labath return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex(reg); 1094d00dff88SPavel Labath } 1095d00dff88SPavel Labath 1096d00dff88SPavel Labath size_t RegisterContextUnwind::GetRegisterSetCount() { 1097d00dff88SPavel Labath return m_thread.GetRegisterContext()->GetRegisterSetCount(); 1098d00dff88SPavel Labath } 1099d00dff88SPavel Labath 1100d00dff88SPavel Labath const RegisterSet *RegisterContextUnwind::GetRegisterSet(size_t reg_set) { 1101d00dff88SPavel Labath return m_thread.GetRegisterContext()->GetRegisterSet(reg_set); 1102d00dff88SPavel Labath } 1103d00dff88SPavel Labath 1104d00dff88SPavel Labath uint32_t RegisterContextUnwind::ConvertRegisterKindToRegisterNumber( 1105d00dff88SPavel Labath lldb::RegisterKind kind, uint32_t num) { 1106d00dff88SPavel Labath return m_thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber( 1107d00dff88SPavel Labath kind, num); 1108d00dff88SPavel Labath } 1109d00dff88SPavel Labath 1110d00dff88SPavel Labath bool RegisterContextUnwind::ReadRegisterValueFromRegisterLocation( 11113336d731SJason Molenda lldb_private::UnwindLLDB::ConcreteRegisterLocation regloc, 1112d00dff88SPavel Labath const RegisterInfo *reg_info, RegisterValue &value) { 1113d00dff88SPavel Labath if (!IsValid()) 1114d00dff88SPavel Labath return false; 1115d00dff88SPavel Labath bool success = false; 1116d00dff88SPavel Labath 1117d00dff88SPavel Labath switch (regloc.type) { 11183336d731SJason Molenda case UnwindLLDB::ConcreteRegisterLocation::eRegisterInLiveRegisterContext: { 1119d00dff88SPavel Labath const RegisterInfo *other_reg_info = 1120d00dff88SPavel Labath GetRegisterInfoAtIndex(regloc.location.register_number); 1121d00dff88SPavel Labath 1122d00dff88SPavel Labath if (!other_reg_info) 1123d00dff88SPavel Labath return false; 1124d00dff88SPavel Labath 1125d00dff88SPavel Labath success = 1126d00dff88SPavel Labath m_thread.GetRegisterContext()->ReadRegister(other_reg_info, value); 1127d00dff88SPavel Labath } break; 11283336d731SJason Molenda case UnwindLLDB::ConcreteRegisterLocation::eRegisterInRegister: { 1129d00dff88SPavel Labath const RegisterInfo *other_reg_info = 1130d00dff88SPavel Labath GetRegisterInfoAtIndex(regloc.location.register_number); 1131d00dff88SPavel Labath 1132d00dff88SPavel Labath if (!other_reg_info) 1133d00dff88SPavel Labath return false; 1134d00dff88SPavel Labath 1135d00dff88SPavel Labath if (IsFrameZero()) { 1136d00dff88SPavel Labath success = 1137d00dff88SPavel Labath m_thread.GetRegisterContext()->ReadRegister(other_reg_info, value); 1138d00dff88SPavel Labath } else { 1139d00dff88SPavel Labath success = GetNextFrame()->ReadRegister(other_reg_info, value); 1140d00dff88SPavel Labath } 1141d00dff88SPavel Labath } break; 11423336d731SJason Molenda case UnwindLLDB::ConcreteRegisterLocation::eRegisterValueInferred: 1143d00dff88SPavel Labath success = 1144d00dff88SPavel Labath value.SetUInt(regloc.location.inferred_value, reg_info->byte_size); 1145d00dff88SPavel Labath break; 1146d00dff88SPavel Labath 11473336d731SJason Molenda case UnwindLLDB::ConcreteRegisterLocation::eRegisterNotSaved: 1148d00dff88SPavel Labath break; 11493336d731SJason Molenda case UnwindLLDB::ConcreteRegisterLocation::eRegisterSavedAtHostMemoryLocation: 1150d00dff88SPavel Labath llvm_unreachable("FIXME debugger inferior function call unwind"); 11513336d731SJason Molenda case UnwindLLDB::ConcreteRegisterLocation::eRegisterSavedAtMemoryLocation: { 1152d00dff88SPavel Labath Status error(ReadRegisterValueFromMemory( 1153d00dff88SPavel Labath reg_info, regloc.location.target_memory_location, reg_info->byte_size, 1154d00dff88SPavel Labath value)); 1155d00dff88SPavel Labath success = error.Success(); 1156d00dff88SPavel Labath } break; 1157d00dff88SPavel Labath default: 11583336d731SJason Molenda llvm_unreachable("Unknown ConcreteRegisterLocation type."); 1159d00dff88SPavel Labath } 1160d00dff88SPavel Labath return success; 1161d00dff88SPavel Labath } 1162d00dff88SPavel Labath 1163d00dff88SPavel Labath bool RegisterContextUnwind::WriteRegisterValueToRegisterLocation( 11643336d731SJason Molenda lldb_private::UnwindLLDB::ConcreteRegisterLocation regloc, 1165d00dff88SPavel Labath const RegisterInfo *reg_info, const RegisterValue &value) { 1166d00dff88SPavel Labath if (!IsValid()) 1167d00dff88SPavel Labath return false; 1168d00dff88SPavel Labath 1169d00dff88SPavel Labath bool success = false; 1170d00dff88SPavel Labath 1171d00dff88SPavel Labath switch (regloc.type) { 11723336d731SJason Molenda case UnwindLLDB::ConcreteRegisterLocation::eRegisterInLiveRegisterContext: { 1173d00dff88SPavel Labath const RegisterInfo *other_reg_info = 1174d00dff88SPavel Labath GetRegisterInfoAtIndex(regloc.location.register_number); 1175d00dff88SPavel Labath success = 1176d00dff88SPavel Labath m_thread.GetRegisterContext()->WriteRegister(other_reg_info, value); 1177d00dff88SPavel Labath } break; 11783336d731SJason Molenda case UnwindLLDB::ConcreteRegisterLocation::eRegisterInRegister: { 1179d00dff88SPavel Labath const RegisterInfo *other_reg_info = 1180d00dff88SPavel Labath GetRegisterInfoAtIndex(regloc.location.register_number); 1181d00dff88SPavel Labath if (IsFrameZero()) { 1182d00dff88SPavel Labath success = 1183d00dff88SPavel Labath m_thread.GetRegisterContext()->WriteRegister(other_reg_info, value); 1184d00dff88SPavel Labath } else { 1185d00dff88SPavel Labath success = GetNextFrame()->WriteRegister(other_reg_info, value); 1186d00dff88SPavel Labath } 1187d00dff88SPavel Labath } break; 11883336d731SJason Molenda case UnwindLLDB::ConcreteRegisterLocation::eRegisterValueInferred: 11893336d731SJason Molenda case UnwindLLDB::ConcreteRegisterLocation::eRegisterNotSaved: 1190d00dff88SPavel Labath break; 11913336d731SJason Molenda case UnwindLLDB::ConcreteRegisterLocation::eRegisterSavedAtHostMemoryLocation: 1192d00dff88SPavel Labath llvm_unreachable("FIXME debugger inferior function call unwind"); 11933336d731SJason Molenda case UnwindLLDB::ConcreteRegisterLocation::eRegisterSavedAtMemoryLocation: { 1194d00dff88SPavel Labath Status error(WriteRegisterValueToMemory( 1195d00dff88SPavel Labath reg_info, regloc.location.target_memory_location, reg_info->byte_size, 1196d00dff88SPavel Labath value)); 1197d00dff88SPavel Labath success = error.Success(); 1198d00dff88SPavel Labath } break; 1199d00dff88SPavel Labath default: 12003336d731SJason Molenda llvm_unreachable("Unknown ConcreteRegisterLocation type."); 1201d00dff88SPavel Labath } 1202d00dff88SPavel Labath return success; 1203d00dff88SPavel Labath } 1204d00dff88SPavel Labath 1205d00dff88SPavel Labath bool RegisterContextUnwind::IsValid() const { 1206d00dff88SPavel Labath return m_frame_type != eNotAValidFrame; 1207d00dff88SPavel Labath } 1208d00dff88SPavel Labath 1209d00dff88SPavel Labath // After the final stack frame in a stack walk we'll get one invalid 1210d00dff88SPavel Labath // (eNotAValidFrame) stack frame -- one past the end of the stack walk. But 1211e9264b74SKazuaki Ishizaki // higher-level code will need to tell the difference between "the unwind plan 1212d00dff88SPavel Labath // below this frame failed" versus "we successfully completed the stack walk" 1213d00dff88SPavel Labath // so this method helps to disambiguate that. 1214d00dff88SPavel Labath 1215d00dff88SPavel Labath bool RegisterContextUnwind::IsTrapHandlerFrame() const { 1216d00dff88SPavel Labath return m_frame_type == eTrapHandlerFrame; 1217d00dff88SPavel Labath } 1218d00dff88SPavel Labath 1219d00dff88SPavel Labath // A skip frame is a bogus frame on the stack -- but one where we're likely to 1220d00dff88SPavel Labath // find a real frame farther 1221d00dff88SPavel Labath // up the stack if we keep looking. It's always the second frame in an unwind 1222d00dff88SPavel Labath // (i.e. the first frame after frame zero) where unwinding can be the 1223d00dff88SPavel Labath // trickiest. Ideally we'll mark up this frame in some way so the user knows 1224d00dff88SPavel Labath // we're displaying bad data and we may have skipped one frame of their real 1225d00dff88SPavel Labath // program in the process of getting back on track. 1226d00dff88SPavel Labath 1227d00dff88SPavel Labath bool RegisterContextUnwind::IsSkipFrame() const { 1228d00dff88SPavel Labath return m_frame_type == eSkipFrame; 1229d00dff88SPavel Labath } 1230d00dff88SPavel Labath 1231d00dff88SPavel Labath bool RegisterContextUnwind::IsTrapHandlerSymbol( 1232d00dff88SPavel Labath lldb_private::Process *process, 1233d00dff88SPavel Labath const lldb_private::SymbolContext &m_sym_ctx) const { 1234d00dff88SPavel Labath PlatformSP platform_sp(process->GetTarget().GetPlatform()); 1235d00dff88SPavel Labath if (platform_sp) { 1236d00dff88SPavel Labath const std::vector<ConstString> trap_handler_names( 1237d00dff88SPavel Labath platform_sp->GetTrapHandlerSymbolNames()); 1238d00dff88SPavel Labath for (ConstString name : trap_handler_names) { 1239d00dff88SPavel Labath if ((m_sym_ctx.function && m_sym_ctx.function->GetName() == name) || 1240d00dff88SPavel Labath (m_sym_ctx.symbol && m_sym_ctx.symbol->GetName() == name)) { 1241d00dff88SPavel Labath return true; 1242d00dff88SPavel Labath } 1243d00dff88SPavel Labath } 1244d00dff88SPavel Labath } 1245d00dff88SPavel Labath const std::vector<ConstString> user_specified_trap_handler_names( 1246d00dff88SPavel Labath m_parent_unwind.GetUserSpecifiedTrapHandlerFunctionNames()); 1247d00dff88SPavel Labath for (ConstString name : user_specified_trap_handler_names) { 1248d00dff88SPavel Labath if ((m_sym_ctx.function && m_sym_ctx.function->GetName() == name) || 1249d00dff88SPavel Labath (m_sym_ctx.symbol && m_sym_ctx.symbol->GetName() == name)) { 1250d00dff88SPavel Labath return true; 1251d00dff88SPavel Labath } 1252d00dff88SPavel Labath } 1253d00dff88SPavel Labath 1254d00dff88SPavel Labath return false; 1255d00dff88SPavel Labath } 1256d00dff88SPavel Labath 1257d00dff88SPavel Labath // Answer the question: Where did THIS frame save the CALLER frame ("previous" 1258d00dff88SPavel Labath // frame)'s register value? 1259d00dff88SPavel Labath 1260d00dff88SPavel Labath enum UnwindLLDB::RegisterSearchResult 1261d00dff88SPavel Labath RegisterContextUnwind::SavedLocationForRegister( 12623336d731SJason Molenda uint32_t lldb_regnum, 12633336d731SJason Molenda lldb_private::UnwindLLDB::ConcreteRegisterLocation ®loc) { 1264d00dff88SPavel Labath RegisterNumber regnum(m_thread, eRegisterKindLLDB, lldb_regnum); 1265a007a6d8SPavel Labath Log *log = GetLog(LLDBLog::Unwind); 1266d00dff88SPavel Labath 1267d00dff88SPavel Labath // Have we already found this register location? 1268d00dff88SPavel Labath if (!m_registers.empty()) { 1269d00dff88SPavel Labath std::map<uint32_t, 12703336d731SJason Molenda lldb_private::UnwindLLDB::ConcreteRegisterLocation>::const_iterator 1271d00dff88SPavel Labath iterator; 1272d00dff88SPavel Labath iterator = m_registers.find(regnum.GetAsKind(eRegisterKindLLDB)); 1273d00dff88SPavel Labath if (iterator != m_registers.end()) { 1274d00dff88SPavel Labath regloc = iterator->second; 1275d00dff88SPavel Labath UnwindLogMsg("supplying caller's saved %s (%d)'s location, cached", 1276d00dff88SPavel Labath regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); 1277d00dff88SPavel Labath return UnwindLLDB::RegisterSearchResult::eRegisterFound; 1278d00dff88SPavel Labath } 1279d00dff88SPavel Labath } 1280d00dff88SPavel Labath 1281d00dff88SPavel Labath // Look through the available UnwindPlans for the register location. 1282d00dff88SPavel Labath 12833336d731SJason Molenda UnwindPlan::Row::AbstractRegisterLocation unwindplan_regloc; 1284d00dff88SPavel Labath bool have_unwindplan_regloc = false; 1285d00dff88SPavel Labath RegisterKind unwindplan_registerkind = kNumRegisterKinds; 1286d00dff88SPavel Labath 1287d00dff88SPavel Labath if (m_fast_unwind_plan_sp) { 1288d00dff88SPavel Labath UnwindPlan::RowSP active_row = 1289d00dff88SPavel Labath m_fast_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset); 1290d00dff88SPavel Labath unwindplan_registerkind = m_fast_unwind_plan_sp->GetRegisterKind(); 1291d00dff88SPavel Labath if (regnum.GetAsKind(unwindplan_registerkind) == LLDB_INVALID_REGNUM) { 1292d00dff88SPavel Labath UnwindLogMsg("could not convert lldb regnum %s (%d) into %d RegisterKind " 1293d00dff88SPavel Labath "reg numbering scheme", 1294d00dff88SPavel Labath regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), 1295d00dff88SPavel Labath (int)unwindplan_registerkind); 1296d00dff88SPavel Labath return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; 1297d00dff88SPavel Labath } 1298fcdef15dSJason Molenda // The architecture default unwind plan marks unknown registers as 1299fcdef15dSJason Molenda // Undefined so that we don't forward them up the stack when a 1300fcdef15dSJason Molenda // jitted stack frame may have overwritten them. But when the 1301fcdef15dSJason Molenda // arch default unwind plan is used as the Fast Unwind Plan, we 1302fcdef15dSJason Molenda // need to recognize this & switch over to the Full Unwind Plan 1303fcdef15dSJason Molenda // to see what unwind rule that (more knoweldgeable, probably) 1304fcdef15dSJason Molenda // UnwindPlan has. If the full UnwindPlan says the register 1305fcdef15dSJason Molenda // location is Undefined, then it really is. 1306d00dff88SPavel Labath if (active_row->GetRegisterInfo(regnum.GetAsKind(unwindplan_registerkind), 1307fcdef15dSJason Molenda unwindplan_regloc) && 1308fcdef15dSJason Molenda !unwindplan_regloc.IsUndefined()) { 1309d00dff88SPavel Labath UnwindLogMsg( 1310d00dff88SPavel Labath "supplying caller's saved %s (%d)'s location using FastUnwindPlan", 1311d00dff88SPavel Labath regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); 1312d00dff88SPavel Labath have_unwindplan_regloc = true; 1313d00dff88SPavel Labath } 1314d00dff88SPavel Labath } 1315d00dff88SPavel Labath 1316d00dff88SPavel Labath if (!have_unwindplan_regloc) { 1317d00dff88SPavel Labath // m_full_unwind_plan_sp being NULL means that we haven't tried to find a 1318d00dff88SPavel Labath // full UnwindPlan yet 1319fcdef15dSJason Molenda bool got_new_full_unwindplan = false; 1320fcdef15dSJason Molenda if (!m_full_unwind_plan_sp) { 1321d00dff88SPavel Labath m_full_unwind_plan_sp = GetFullUnwindPlanForFrame(); 1322fcdef15dSJason Molenda got_new_full_unwindplan = true; 1323fcdef15dSJason Molenda } 1324d00dff88SPavel Labath 1325d00dff88SPavel Labath if (m_full_unwind_plan_sp) { 1326d00dff88SPavel Labath RegisterNumber pc_regnum(m_thread, eRegisterKindGeneric, 1327d00dff88SPavel Labath LLDB_REGNUM_GENERIC_PC); 1328d00dff88SPavel Labath 1329d00dff88SPavel Labath UnwindPlan::RowSP active_row = 1330b6388e4aSJason Molenda m_full_unwind_plan_sp->GetRowForFunctionOffset( 1331b6388e4aSJason Molenda m_current_offset_backed_up_one); 1332d00dff88SPavel Labath unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind(); 1333d00dff88SPavel Labath 1334fcdef15dSJason Molenda if (got_new_full_unwindplan && active_row.get() && log) { 1335fcdef15dSJason Molenda StreamString active_row_strm; 1336fcdef15dSJason Molenda ExecutionContext exe_ctx(m_thread.shared_from_this()); 1337fcdef15dSJason Molenda active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), 1338fcdef15dSJason Molenda &m_thread, 1339fcdef15dSJason Molenda m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr())); 1340fcdef15dSJason Molenda UnwindLogMsg("Using full unwind plan '%s'", 1341fcdef15dSJason Molenda m_full_unwind_plan_sp->GetSourceName().AsCString()); 1342fcdef15dSJason Molenda UnwindLogMsg("active row: %s", active_row_strm.GetData()); 1343fcdef15dSJason Molenda } 1344d00dff88SPavel Labath RegisterNumber return_address_reg; 1345d00dff88SPavel Labath 1346d00dff88SPavel Labath // If we're fetching the saved pc and this UnwindPlan defines a 1347d00dff88SPavel Labath // ReturnAddress register (e.g. lr on arm), look for the return address 1348d00dff88SPavel Labath // register number in the UnwindPlan's row. 1349d00dff88SPavel Labath if (pc_regnum.IsValid() && pc_regnum == regnum && 1350d00dff88SPavel Labath m_full_unwind_plan_sp->GetReturnAddressRegister() != 1351d00dff88SPavel Labath LLDB_INVALID_REGNUM) { 1352d00dff88SPavel Labath // If this is a trap handler frame, we should have access to 1353d00dff88SPavel Labath // the complete register context when the interrupt/async 1354d00dff88SPavel Labath // signal was received, we should fetch the actual saved $pc 1355d00dff88SPavel Labath // value instead of the Return Address register. 1356d00dff88SPavel Labath // If $pc is not available, fall back to the RA reg. 13573336d731SJason Molenda UnwindPlan::Row::AbstractRegisterLocation scratch; 1358d00dff88SPavel Labath if (m_frame_type == eTrapHandlerFrame && 1359d00dff88SPavel Labath active_row->GetRegisterInfo 1360d00dff88SPavel Labath (pc_regnum.GetAsKind (unwindplan_registerkind), scratch)) { 1361d00dff88SPavel Labath UnwindLogMsg("Providing pc register instead of rewriting to " 1362d00dff88SPavel Labath "RA reg because this is a trap handler and there is " 1363d00dff88SPavel Labath "a location for the saved pc register value."); 1364d00dff88SPavel Labath } else { 1365d00dff88SPavel Labath return_address_reg.init( 1366d00dff88SPavel Labath m_thread, m_full_unwind_plan_sp->GetRegisterKind(), 1367d00dff88SPavel Labath m_full_unwind_plan_sp->GetReturnAddressRegister()); 1368d00dff88SPavel Labath regnum = return_address_reg; 1369d00dff88SPavel Labath UnwindLogMsg("requested caller's saved PC but this UnwindPlan uses a " 1370d00dff88SPavel Labath "RA reg; getting %s (%d) instead", 1371d00dff88SPavel Labath return_address_reg.GetName(), 1372d00dff88SPavel Labath return_address_reg.GetAsKind(eRegisterKindLLDB)); 1373d00dff88SPavel Labath } 1374d00dff88SPavel Labath } else { 1375d00dff88SPavel Labath if (regnum.GetAsKind(unwindplan_registerkind) == LLDB_INVALID_REGNUM) { 1376d00dff88SPavel Labath if (unwindplan_registerkind == eRegisterKindGeneric) { 1377d00dff88SPavel Labath UnwindLogMsg("could not convert lldb regnum %s (%d) into " 1378d00dff88SPavel Labath "eRegisterKindGeneric reg numbering scheme", 1379d00dff88SPavel Labath regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); 1380d00dff88SPavel Labath } else { 1381d00dff88SPavel Labath UnwindLogMsg("could not convert lldb regnum %s (%d) into %d " 1382d00dff88SPavel Labath "RegisterKind reg numbering scheme", 1383d00dff88SPavel Labath regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), 1384d00dff88SPavel Labath (int)unwindplan_registerkind); 1385d00dff88SPavel Labath } 1386d00dff88SPavel Labath return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; 1387d00dff88SPavel Labath } 1388d00dff88SPavel Labath } 1389d00dff88SPavel Labath 1390d00dff88SPavel Labath if (regnum.IsValid() && 1391d00dff88SPavel Labath active_row->GetRegisterInfo(regnum.GetAsKind(unwindplan_registerkind), 1392d00dff88SPavel Labath unwindplan_regloc)) { 1393d00dff88SPavel Labath have_unwindplan_regloc = true; 1394d00dff88SPavel Labath UnwindLogMsg( 1395d00dff88SPavel Labath "supplying caller's saved %s (%d)'s location using %s UnwindPlan", 1396d00dff88SPavel Labath regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), 1397d00dff88SPavel Labath m_full_unwind_plan_sp->GetSourceName().GetCString()); 1398d00dff88SPavel Labath } 1399d00dff88SPavel Labath 1400d00dff88SPavel Labath // This is frame 0 and we're retrieving the PC and it's saved in a Return 1401d00dff88SPavel Labath // Address register and it hasn't been saved anywhere yet -- that is, 1402d00dff88SPavel Labath // it's still live in the actual register. Handle this specially. 1403d00dff88SPavel Labath 1404d00dff88SPavel Labath if (!have_unwindplan_regloc && return_address_reg.IsValid() && 1405*d29a50f3SJason Molenda IsFrameZero()) { 1406d00dff88SPavel Labath if (return_address_reg.GetAsKind(eRegisterKindLLDB) != 1407d00dff88SPavel Labath LLDB_INVALID_REGNUM) { 14083336d731SJason Molenda lldb_private::UnwindLLDB::ConcreteRegisterLocation new_regloc; 14093336d731SJason Molenda new_regloc.type = UnwindLLDB::ConcreteRegisterLocation:: 14103336d731SJason Molenda eRegisterInLiveRegisterContext; 1411d00dff88SPavel Labath new_regloc.location.register_number = 1412d00dff88SPavel Labath return_address_reg.GetAsKind(eRegisterKindLLDB); 1413d00dff88SPavel Labath m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = new_regloc; 1414d00dff88SPavel Labath regloc = new_regloc; 1415d00dff88SPavel Labath UnwindLogMsg("supplying caller's register %s (%d) from the live " 1416d00dff88SPavel Labath "RegisterContext at frame 0, saved in %d", 1417d00dff88SPavel Labath return_address_reg.GetName(), 1418d00dff88SPavel Labath return_address_reg.GetAsKind(eRegisterKindLLDB), 1419d00dff88SPavel Labath return_address_reg.GetAsKind(eRegisterKindLLDB)); 1420d00dff88SPavel Labath return UnwindLLDB::RegisterSearchResult::eRegisterFound; 1421d00dff88SPavel Labath } 1422d00dff88SPavel Labath } 1423d00dff88SPavel Labath 1424d00dff88SPavel Labath // If this architecture stores the return address in a register (it 1425d00dff88SPavel Labath // defines a Return Address register) and we're on a non-zero stack frame 1426d00dff88SPavel Labath // and the Full UnwindPlan says that the pc is stored in the 1427d00dff88SPavel Labath // RA registers (e.g. lr on arm), then we know that the full unwindplan is 1428d00dff88SPavel Labath // not trustworthy -- this 1429d00dff88SPavel Labath // is an impossible situation and the instruction emulation code has 1430d00dff88SPavel Labath // likely been misled. If this stack frame meets those criteria, we need 1431d00dff88SPavel Labath // to throw away the Full UnwindPlan that the instruction emulation came 1432d00dff88SPavel Labath // up with and fall back to the architecture's Default UnwindPlan so the 1433d00dff88SPavel Labath // stack walk can get past this point. 1434d00dff88SPavel Labath 1435d00dff88SPavel Labath // Special note: If the Full UnwindPlan was generated from the compiler, 1436d00dff88SPavel Labath // don't second-guess it when we're at a call site location. 1437d00dff88SPavel Labath 1438d00dff88SPavel Labath // arch_default_ra_regnum is the return address register # in the Full 1439d00dff88SPavel Labath // UnwindPlan register numbering 1440d00dff88SPavel Labath RegisterNumber arch_default_ra_regnum(m_thread, eRegisterKindGeneric, 1441d00dff88SPavel Labath LLDB_REGNUM_GENERIC_RA); 1442d00dff88SPavel Labath 1443d00dff88SPavel Labath if (arch_default_ra_regnum.GetAsKind(unwindplan_registerkind) != 1444d00dff88SPavel Labath LLDB_INVALID_REGNUM && 1445d00dff88SPavel Labath pc_regnum == regnum && unwindplan_regloc.IsInOtherRegister() && 1446d00dff88SPavel Labath unwindplan_regloc.GetRegisterNumber() == 1447d00dff88SPavel Labath arch_default_ra_regnum.GetAsKind(unwindplan_registerkind) && 1448d00dff88SPavel Labath m_full_unwind_plan_sp->GetSourcedFromCompiler() != eLazyBoolYes && 1449d00dff88SPavel Labath !m_all_registers_available) { 1450d00dff88SPavel Labath UnwindLogMsg("%s UnwindPlan tried to restore the pc from the link " 1451d00dff88SPavel Labath "register but this is a non-zero frame", 1452d00dff88SPavel Labath m_full_unwind_plan_sp->GetSourceName().GetCString()); 1453d00dff88SPavel Labath 1454d00dff88SPavel Labath // Throw away the full unwindplan; install the arch default unwindplan 1455d00dff88SPavel Labath if (ForceSwitchToFallbackUnwindPlan()) { 1456d00dff88SPavel Labath // Update for the possibly new unwind plan 1457d00dff88SPavel Labath unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind(); 1458d00dff88SPavel Labath UnwindPlan::RowSP active_row = 1459d00dff88SPavel Labath m_full_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset); 1460d00dff88SPavel Labath 1461d00dff88SPavel Labath // Sanity check: Verify that we can fetch a pc value and CFA value 1462d00dff88SPavel Labath // with this unwind plan 1463d00dff88SPavel Labath 1464d00dff88SPavel Labath RegisterNumber arch_default_pc_reg(m_thread, eRegisterKindGeneric, 1465d00dff88SPavel Labath LLDB_REGNUM_GENERIC_PC); 1466d00dff88SPavel Labath bool can_fetch_pc_value = false; 1467d00dff88SPavel Labath bool can_fetch_cfa = false; 1468d00dff88SPavel Labath addr_t cfa_value; 1469d00dff88SPavel Labath if (active_row) { 1470d00dff88SPavel Labath if (arch_default_pc_reg.GetAsKind(unwindplan_registerkind) != 1471d00dff88SPavel Labath LLDB_INVALID_REGNUM && 1472d00dff88SPavel Labath active_row->GetRegisterInfo( 1473d00dff88SPavel Labath arch_default_pc_reg.GetAsKind(unwindplan_registerkind), 1474d00dff88SPavel Labath unwindplan_regloc)) { 1475d00dff88SPavel Labath can_fetch_pc_value = true; 1476d00dff88SPavel Labath } 1477d00dff88SPavel Labath if (ReadFrameAddress(unwindplan_registerkind, 1478d00dff88SPavel Labath active_row->GetCFAValue(), cfa_value)) { 1479d00dff88SPavel Labath can_fetch_cfa = true; 1480d00dff88SPavel Labath } 1481d00dff88SPavel Labath } 1482d00dff88SPavel Labath 1483d00dff88SPavel Labath have_unwindplan_regloc = can_fetch_pc_value && can_fetch_cfa; 1484d00dff88SPavel Labath } else { 1485d00dff88SPavel Labath // We were unable to fall back to another unwind plan 1486d00dff88SPavel Labath have_unwindplan_regloc = false; 1487d00dff88SPavel Labath } 1488d00dff88SPavel Labath } 1489d00dff88SPavel Labath } 1490d00dff88SPavel Labath } 1491d00dff88SPavel Labath 1492d00dff88SPavel Labath ExecutionContext exe_ctx(m_thread.shared_from_this()); 1493d00dff88SPavel Labath Process *process = exe_ctx.GetProcessPtr(); 1494d00dff88SPavel Labath if (!have_unwindplan_regloc) { 1495d00dff88SPavel Labath // If the UnwindPlan failed to give us an unwind location for this 1496d00dff88SPavel Labath // register, we may be able to fall back to some ABI-defined default. For 1497d00dff88SPavel Labath // example, some ABIs allow to determine the caller's SP via the CFA. Also, 1498d00dff88SPavel Labath // the ABI may set volatile registers to the undefined state. 1499d00dff88SPavel Labath ABI *abi = process ? process->GetABI().get() : nullptr; 1500d00dff88SPavel Labath if (abi) { 1501d00dff88SPavel Labath const RegisterInfo *reg_info = 1502d00dff88SPavel Labath GetRegisterInfoAtIndex(regnum.GetAsKind(eRegisterKindLLDB)); 1503d00dff88SPavel Labath if (reg_info && 1504d00dff88SPavel Labath abi->GetFallbackRegisterLocation(reg_info, unwindplan_regloc)) { 1505d00dff88SPavel Labath UnwindLogMsg( 1506d00dff88SPavel Labath "supplying caller's saved %s (%d)'s location using ABI default", 1507d00dff88SPavel Labath regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); 1508d00dff88SPavel Labath have_unwindplan_regloc = true; 1509d00dff88SPavel Labath } 1510d00dff88SPavel Labath } 1511d00dff88SPavel Labath } 1512d00dff88SPavel Labath 1513d00dff88SPavel Labath if (!have_unwindplan_regloc) { 1514d00dff88SPavel Labath if (IsFrameZero()) { 1515d00dff88SPavel Labath // This is frame 0 - we should return the actual live register context 1516d00dff88SPavel Labath // value 15173336d731SJason Molenda lldb_private::UnwindLLDB::ConcreteRegisterLocation new_regloc; 1518d00dff88SPavel Labath new_regloc.type = 15193336d731SJason Molenda UnwindLLDB::ConcreteRegisterLocation::eRegisterInLiveRegisterContext; 1520d00dff88SPavel Labath new_regloc.location.register_number = regnum.GetAsKind(eRegisterKindLLDB); 1521d00dff88SPavel Labath m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = new_regloc; 1522d00dff88SPavel Labath regloc = new_regloc; 1523d00dff88SPavel Labath UnwindLogMsg("supplying caller's register %s (%d) from the live " 1524d00dff88SPavel Labath "RegisterContext at frame 0", 1525d00dff88SPavel Labath regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); 1526d00dff88SPavel Labath return UnwindLLDB::RegisterSearchResult::eRegisterFound; 1527d00dff88SPavel Labath } else { 15280542d152SKazu Hirata std::string unwindplan_name; 1529d00dff88SPavel Labath if (m_full_unwind_plan_sp) { 1530d00dff88SPavel Labath unwindplan_name += "via '"; 1531d00dff88SPavel Labath unwindplan_name += m_full_unwind_plan_sp->GetSourceName().AsCString(); 1532d00dff88SPavel Labath unwindplan_name += "'"; 1533d00dff88SPavel Labath } 1534d00dff88SPavel Labath UnwindLogMsg("no save location for %s (%d) %s", regnum.GetName(), 1535d00dff88SPavel Labath regnum.GetAsKind(eRegisterKindLLDB), 1536d00dff88SPavel Labath unwindplan_name.c_str()); 1537d00dff88SPavel Labath } 1538d00dff88SPavel Labath return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; 1539d00dff88SPavel Labath } 1540d00dff88SPavel Labath 1541d00dff88SPavel Labath // unwindplan_regloc has valid contents about where to retrieve the register 1542d00dff88SPavel Labath if (unwindplan_regloc.IsUnspecified()) { 15433336d731SJason Molenda lldb_private::UnwindLLDB::ConcreteRegisterLocation new_regloc = {}; 15443336d731SJason Molenda new_regloc.type = UnwindLLDB::ConcreteRegisterLocation::eRegisterNotSaved; 1545d00dff88SPavel Labath m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = new_regloc; 1546d00dff88SPavel Labath UnwindLogMsg("save location for %s (%d) is unspecified, continue searching", 1547d00dff88SPavel Labath regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); 1548d00dff88SPavel Labath return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; 1549d00dff88SPavel Labath } 1550d00dff88SPavel Labath 1551d00dff88SPavel Labath if (unwindplan_regloc.IsUndefined()) { 1552d00dff88SPavel Labath UnwindLogMsg( 1553d00dff88SPavel Labath "did not supply reg location for %s (%d) because it is volatile", 1554d00dff88SPavel Labath regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); 1555d00dff88SPavel Labath return UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile; 1556d00dff88SPavel Labath } 1557d00dff88SPavel Labath 1558d00dff88SPavel Labath if (unwindplan_regloc.IsSame()) { 1559bbd54e08SPavel Labath if (!m_all_registers_available && 1560d00dff88SPavel Labath (regnum.GetAsKind(eRegisterKindGeneric) == LLDB_REGNUM_GENERIC_PC || 1561d00dff88SPavel Labath regnum.GetAsKind(eRegisterKindGeneric) == LLDB_REGNUM_GENERIC_RA)) { 1562d00dff88SPavel Labath UnwindLogMsg("register %s (%d) is marked as 'IsSame' - it is a pc or " 1563bbd54e08SPavel Labath "return address reg on a frame which does not have all " 1564bbd54e08SPavel Labath "registers available -- treat as if we have no information", 1565d00dff88SPavel Labath regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); 1566d00dff88SPavel Labath return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; 1567d00dff88SPavel Labath } else { 15683336d731SJason Molenda regloc.type = UnwindLLDB::ConcreteRegisterLocation::eRegisterInRegister; 1569d00dff88SPavel Labath regloc.location.register_number = regnum.GetAsKind(eRegisterKindLLDB); 1570d00dff88SPavel Labath m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc; 1571d00dff88SPavel Labath UnwindLogMsg( 1572d00dff88SPavel Labath "supplying caller's register %s (%d), saved in register %s (%d)", 1573d00dff88SPavel Labath regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), 1574d00dff88SPavel Labath regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); 1575d00dff88SPavel Labath return UnwindLLDB::RegisterSearchResult::eRegisterFound; 1576d00dff88SPavel Labath } 1577d00dff88SPavel Labath } 1578d00dff88SPavel Labath 1579d00dff88SPavel Labath if (unwindplan_regloc.IsCFAPlusOffset()) { 1580d00dff88SPavel Labath int offset = unwindplan_regloc.GetOffset(); 15813336d731SJason Molenda regloc.type = UnwindLLDB::ConcreteRegisterLocation::eRegisterValueInferred; 1582d00dff88SPavel Labath regloc.location.inferred_value = m_cfa + offset; 1583d00dff88SPavel Labath m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc; 1584d00dff88SPavel Labath UnwindLogMsg("supplying caller's register %s (%d), value is CFA plus " 1585d00dff88SPavel Labath "offset %d [value is 0x%" PRIx64 "]", 1586d00dff88SPavel Labath regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), offset, 1587d00dff88SPavel Labath regloc.location.inferred_value); 1588d00dff88SPavel Labath return UnwindLLDB::RegisterSearchResult::eRegisterFound; 1589d00dff88SPavel Labath } 1590d00dff88SPavel Labath 1591d00dff88SPavel Labath if (unwindplan_regloc.IsAtCFAPlusOffset()) { 1592d00dff88SPavel Labath int offset = unwindplan_regloc.GetOffset(); 15933336d731SJason Molenda regloc.type = 15943336d731SJason Molenda UnwindLLDB::ConcreteRegisterLocation::eRegisterSavedAtMemoryLocation; 1595d00dff88SPavel Labath regloc.location.target_memory_location = m_cfa + offset; 1596d00dff88SPavel Labath m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc; 1597d00dff88SPavel Labath UnwindLogMsg("supplying caller's register %s (%d) from the stack, saved at " 1598d00dff88SPavel Labath "CFA plus offset %d [saved at 0x%" PRIx64 "]", 1599d00dff88SPavel Labath regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), offset, 1600d00dff88SPavel Labath regloc.location.target_memory_location); 1601d00dff88SPavel Labath return UnwindLLDB::RegisterSearchResult::eRegisterFound; 1602d00dff88SPavel Labath } 1603d00dff88SPavel Labath 1604d00dff88SPavel Labath if (unwindplan_regloc.IsAFAPlusOffset()) { 1605d00dff88SPavel Labath if (m_afa == LLDB_INVALID_ADDRESS) 1606d00dff88SPavel Labath return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; 1607d00dff88SPavel Labath 1608d00dff88SPavel Labath int offset = unwindplan_regloc.GetOffset(); 16093336d731SJason Molenda regloc.type = UnwindLLDB::ConcreteRegisterLocation::eRegisterValueInferred; 1610d00dff88SPavel Labath regloc.location.inferred_value = m_afa + offset; 1611d00dff88SPavel Labath m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc; 1612d00dff88SPavel Labath UnwindLogMsg("supplying caller's register %s (%d), value is AFA plus " 1613d00dff88SPavel Labath "offset %d [value is 0x%" PRIx64 "]", 1614d00dff88SPavel Labath regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), offset, 1615d00dff88SPavel Labath regloc.location.inferred_value); 1616d00dff88SPavel Labath return UnwindLLDB::RegisterSearchResult::eRegisterFound; 1617d00dff88SPavel Labath } 1618d00dff88SPavel Labath 1619d00dff88SPavel Labath if (unwindplan_regloc.IsAtAFAPlusOffset()) { 1620d00dff88SPavel Labath if (m_afa == LLDB_INVALID_ADDRESS) 1621d00dff88SPavel Labath return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; 1622d00dff88SPavel Labath 1623d00dff88SPavel Labath int offset = unwindplan_regloc.GetOffset(); 16243336d731SJason Molenda regloc.type = 16253336d731SJason Molenda UnwindLLDB::ConcreteRegisterLocation::eRegisterSavedAtMemoryLocation; 1626d00dff88SPavel Labath regloc.location.target_memory_location = m_afa + offset; 1627d00dff88SPavel Labath m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc; 1628d00dff88SPavel Labath UnwindLogMsg("supplying caller's register %s (%d) from the stack, saved at " 1629d00dff88SPavel Labath "AFA plus offset %d [saved at 0x%" PRIx64 "]", 1630d00dff88SPavel Labath regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), offset, 1631d00dff88SPavel Labath regloc.location.target_memory_location); 1632d00dff88SPavel Labath return UnwindLLDB::RegisterSearchResult::eRegisterFound; 1633d00dff88SPavel Labath } 1634d00dff88SPavel Labath 1635d00dff88SPavel Labath if (unwindplan_regloc.IsInOtherRegister()) { 1636d00dff88SPavel Labath uint32_t unwindplan_regnum = unwindplan_regloc.GetRegisterNumber(); 1637d00dff88SPavel Labath RegisterNumber row_regnum(m_thread, unwindplan_registerkind, 1638d00dff88SPavel Labath unwindplan_regnum); 1639d00dff88SPavel Labath if (row_regnum.GetAsKind(eRegisterKindLLDB) == LLDB_INVALID_REGNUM) { 1640d00dff88SPavel Labath UnwindLogMsg("could not supply caller's %s (%d) location - was saved in " 1641d00dff88SPavel Labath "another reg but couldn't convert that regnum", 1642d00dff88SPavel Labath regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); 1643d00dff88SPavel Labath return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; 1644d00dff88SPavel Labath } 16453336d731SJason Molenda regloc.type = UnwindLLDB::ConcreteRegisterLocation::eRegisterInRegister; 1646d00dff88SPavel Labath regloc.location.register_number = row_regnum.GetAsKind(eRegisterKindLLDB); 1647d00dff88SPavel Labath m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc; 1648d00dff88SPavel Labath UnwindLogMsg( 1649d00dff88SPavel Labath "supplying caller's register %s (%d), saved in register %s (%d)", 1650d00dff88SPavel Labath regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), 1651d00dff88SPavel Labath row_regnum.GetName(), row_regnum.GetAsKind(eRegisterKindLLDB)); 1652d00dff88SPavel Labath return UnwindLLDB::RegisterSearchResult::eRegisterFound; 1653d00dff88SPavel Labath } 1654d00dff88SPavel Labath 1655d00dff88SPavel Labath if (unwindplan_regloc.IsDWARFExpression() || 1656d00dff88SPavel Labath unwindplan_regloc.IsAtDWARFExpression()) { 1657d00dff88SPavel Labath DataExtractor dwarfdata(unwindplan_regloc.GetDWARFExpressionBytes(), 1658d00dff88SPavel Labath unwindplan_regloc.GetDWARFExpressionLength(), 1659d00dff88SPavel Labath process->GetByteOrder(), 1660d00dff88SPavel Labath process->GetAddressByteSize()); 1661d00dff88SPavel Labath ModuleSP opcode_ctx; 1662b74a01a8SZequan Wu DWARFExpressionList dwarfexpr(opcode_ctx, dwarfdata, nullptr); 1663b74a01a8SZequan Wu dwarfexpr.GetMutableExpressionAtAddress()->SetRegisterKind( 1664b74a01a8SZequan Wu unwindplan_registerkind); 1665d00dff88SPavel Labath Value cfa_val = Scalar(m_cfa); 1666057efa99SAdrian Prantl cfa_val.SetValueType(Value::ValueType::LoadAddress); 1667539b72f2SJonas Devlieghere llvm::Expected<Value> result = 1668539b72f2SJonas Devlieghere dwarfexpr.Evaluate(&exe_ctx, this, 0, &cfa_val, nullptr); 1669539b72f2SJonas Devlieghere if (!result) { 1670539b72f2SJonas Devlieghere LLDB_LOG_ERROR(log, result.takeError(), 1671539b72f2SJonas Devlieghere "DWARF expression failed to evaluate: {0}"); 1672539b72f2SJonas Devlieghere } else { 1673d00dff88SPavel Labath addr_t val; 1674539b72f2SJonas Devlieghere val = result->GetScalar().ULongLong(); 1675d00dff88SPavel Labath if (unwindplan_regloc.IsDWARFExpression()) { 16763336d731SJason Molenda regloc.type = 16773336d731SJason Molenda UnwindLLDB::ConcreteRegisterLocation::eRegisterValueInferred; 1678d00dff88SPavel Labath regloc.location.inferred_value = val; 1679d00dff88SPavel Labath m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc; 1680d00dff88SPavel Labath UnwindLogMsg("supplying caller's register %s (%d) via DWARF expression " 1681d00dff88SPavel Labath "(IsDWARFExpression)", 1682d00dff88SPavel Labath regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); 1683d00dff88SPavel Labath return UnwindLLDB::RegisterSearchResult::eRegisterFound; 1684d00dff88SPavel Labath } else { 16853336d731SJason Molenda regloc.type = UnwindLLDB::ConcreteRegisterLocation:: 16863336d731SJason Molenda eRegisterSavedAtMemoryLocation; 1687d00dff88SPavel Labath regloc.location.target_memory_location = val; 1688d00dff88SPavel Labath m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc; 1689d00dff88SPavel Labath UnwindLogMsg("supplying caller's register %s (%d) via DWARF expression " 1690d00dff88SPavel Labath "(IsAtDWARFExpression)", 1691d00dff88SPavel Labath regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); 1692d00dff88SPavel Labath return UnwindLLDB::RegisterSearchResult::eRegisterFound; 1693d00dff88SPavel Labath } 1694d00dff88SPavel Labath } 1695d00dff88SPavel Labath UnwindLogMsg("tried to use IsDWARFExpression or IsAtDWARFExpression for %s " 1696d00dff88SPavel Labath "(%d) but failed", 1697d00dff88SPavel Labath regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); 1698d00dff88SPavel Labath return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; 1699d00dff88SPavel Labath } 1700d00dff88SPavel Labath 17019fe455fdSFelipe de Azevedo Piovezan if (unwindplan_regloc.IsConstant()) { 17023336d731SJason Molenda regloc.type = UnwindLLDB::ConcreteRegisterLocation::eRegisterValueInferred; 17039fe455fdSFelipe de Azevedo Piovezan regloc.location.inferred_value = unwindplan_regloc.GetConstant(); 17049fe455fdSFelipe de Azevedo Piovezan m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc; 17059fe455fdSFelipe de Azevedo Piovezan UnwindLogMsg("supplying caller's register %s (%d) via constant value", 17069fe455fdSFelipe de Azevedo Piovezan regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); 17079fe455fdSFelipe de Azevedo Piovezan return UnwindLLDB::RegisterSearchResult::eRegisterFound; 17089fe455fdSFelipe de Azevedo Piovezan } 17099fe455fdSFelipe de Azevedo Piovezan 1710d00dff88SPavel Labath UnwindLogMsg("no save location for %s (%d) in this stack frame", 1711d00dff88SPavel Labath regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); 1712d00dff88SPavel Labath 1713d00dff88SPavel Labath // FIXME UnwindPlan::Row types atDWARFExpression and isDWARFExpression are 1714d00dff88SPavel Labath // unsupported. 1715d00dff88SPavel Labath 1716d00dff88SPavel Labath return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; 1717d00dff88SPavel Labath } 1718d00dff88SPavel Labath 1719d00dff88SPavel Labath // TryFallbackUnwindPlan() -- this method is a little tricky. 1720d00dff88SPavel Labath // 1721d00dff88SPavel Labath // When this is called, the frame above -- the caller frame, the "previous" 1722d00dff88SPavel Labath // frame -- is invalid or bad. 1723d00dff88SPavel Labath // 1724d00dff88SPavel Labath // Instead of stopping the stack walk here, we'll try a different UnwindPlan 1725d00dff88SPavel Labath // and see if we can get a valid frame above us. 1726d00dff88SPavel Labath // 1727d00dff88SPavel Labath // This most often happens when an unwind plan based on assembly instruction 1728d00dff88SPavel Labath // inspection is not correct -- mostly with hand-written assembly functions or 1729d00dff88SPavel Labath // functions where the stack frame is set up "out of band", e.g. the kernel 1730d00dff88SPavel Labath // saved the register context and then called an asynchronous trap handler like 1731d00dff88SPavel Labath // _sigtramp. 1732d00dff88SPavel Labath // 1733d00dff88SPavel Labath // Often in these cases, if we just do a dumb stack walk we'll get past this 1734d00dff88SPavel Labath // tricky frame and our usual techniques can continue to be used. 1735d00dff88SPavel Labath 1736d00dff88SPavel Labath bool RegisterContextUnwind::TryFallbackUnwindPlan() { 1737d00dff88SPavel Labath if (m_fallback_unwind_plan_sp.get() == nullptr) 1738d00dff88SPavel Labath return false; 1739d00dff88SPavel Labath 1740d00dff88SPavel Labath if (m_full_unwind_plan_sp.get() == nullptr) 1741d00dff88SPavel Labath return false; 1742d00dff88SPavel Labath 1743d00dff88SPavel Labath if (m_full_unwind_plan_sp.get() == m_fallback_unwind_plan_sp.get() || 1744d00dff88SPavel Labath m_full_unwind_plan_sp->GetSourceName() == 1745d00dff88SPavel Labath m_fallback_unwind_plan_sp->GetSourceName()) { 1746d00dff88SPavel Labath return false; 1747d00dff88SPavel Labath } 1748d00dff88SPavel Labath 1749d00dff88SPavel Labath // If a compiler generated unwind plan failed, trying the arch default 1750d00dff88SPavel Labath // unwindplan isn't going to do any better. 1751d00dff88SPavel Labath if (m_full_unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes) 1752d00dff88SPavel Labath return false; 1753d00dff88SPavel Labath 1754d00dff88SPavel Labath // Get the caller's pc value and our own CFA value. Swap in the fallback 1755d00dff88SPavel Labath // unwind plan, re-fetch the caller's pc value and CFA value. If they're the 1756d00dff88SPavel Labath // same, then the fallback unwind plan provides no benefit. 1757d00dff88SPavel Labath 1758d00dff88SPavel Labath RegisterNumber pc_regnum(m_thread, eRegisterKindGeneric, 1759d00dff88SPavel Labath LLDB_REGNUM_GENERIC_PC); 1760d00dff88SPavel Labath 1761d00dff88SPavel Labath addr_t old_caller_pc_value = LLDB_INVALID_ADDRESS; 1762d00dff88SPavel Labath addr_t new_caller_pc_value = LLDB_INVALID_ADDRESS; 17633336d731SJason Molenda UnwindLLDB::ConcreteRegisterLocation regloc = {}; 1764d00dff88SPavel Labath if (SavedLocationForRegister(pc_regnum.GetAsKind(eRegisterKindLLDB), 1765d00dff88SPavel Labath regloc) == 1766d00dff88SPavel Labath UnwindLLDB::RegisterSearchResult::eRegisterFound) { 1767d00dff88SPavel Labath const RegisterInfo *reg_info = 1768d00dff88SPavel Labath GetRegisterInfoAtIndex(pc_regnum.GetAsKind(eRegisterKindLLDB)); 1769d00dff88SPavel Labath if (reg_info) { 1770d00dff88SPavel Labath RegisterValue reg_value; 1771d00dff88SPavel Labath if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) { 1772d00dff88SPavel Labath old_caller_pc_value = reg_value.GetAsUInt64(); 17738770b4ecSJonas Devlieghere if (ProcessSP process_sp = m_thread.GetProcess()) { 17740ce7037bSJason Molenda if (ABISP abi_sp = process_sp->GetABI()) 17750ce7037bSJason Molenda old_caller_pc_value = abi_sp->FixCodeAddress(old_caller_pc_value); 17768770b4ecSJonas Devlieghere } 1777d00dff88SPavel Labath } 1778d00dff88SPavel Labath } 1779d00dff88SPavel Labath } 1780d00dff88SPavel Labath 1781d00dff88SPavel Labath // This is a tricky wrinkle! If SavedLocationForRegister() detects a really 1782d00dff88SPavel Labath // impossible register location for the full unwind plan, it may call 1783d00dff88SPavel Labath // ForceSwitchToFallbackUnwindPlan() which in turn replaces the full 1784d00dff88SPavel Labath // unwindplan with the fallback... in short, we're done, we're using the 1785d00dff88SPavel Labath // fallback UnwindPlan. We checked if m_fallback_unwind_plan_sp was nullptr 1786d00dff88SPavel Labath // at the top -- the only way it became nullptr since then is via 1787d00dff88SPavel Labath // SavedLocationForRegister(). 1788d00dff88SPavel Labath if (m_fallback_unwind_plan_sp.get() == nullptr) 1789d00dff88SPavel Labath return true; 1790d00dff88SPavel Labath 1791d00dff88SPavel Labath // Switch the full UnwindPlan to be the fallback UnwindPlan. If we decide 1792d00dff88SPavel Labath // this isn't working, we need to restore. We'll also need to save & restore 1793d00dff88SPavel Labath // the value of the m_cfa ivar. Save is down below a bit in 'old_cfa'. 1794d00dff88SPavel Labath UnwindPlanSP original_full_unwind_plan_sp = m_full_unwind_plan_sp; 1795d00dff88SPavel Labath addr_t old_cfa = m_cfa; 1796d00dff88SPavel Labath addr_t old_afa = m_afa; 1797d00dff88SPavel Labath 1798d00dff88SPavel Labath m_registers.clear(); 1799d00dff88SPavel Labath 1800d00dff88SPavel Labath m_full_unwind_plan_sp = m_fallback_unwind_plan_sp; 1801d00dff88SPavel Labath 1802d00dff88SPavel Labath UnwindPlan::RowSP active_row = 1803b6388e4aSJason Molenda m_fallback_unwind_plan_sp->GetRowForFunctionOffset( 1804b6388e4aSJason Molenda m_current_offset_backed_up_one); 1805d00dff88SPavel Labath 1806d00dff88SPavel Labath if (active_row && 1807d00dff88SPavel Labath active_row->GetCFAValue().GetValueType() != 1808d00dff88SPavel Labath UnwindPlan::Row::FAValue::unspecified) { 1809d00dff88SPavel Labath addr_t new_cfa; 1810d00dff88SPavel Labath if (!ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(), 1811d00dff88SPavel Labath active_row->GetCFAValue(), new_cfa) || 1812d00dff88SPavel Labath new_cfa == 0 || new_cfa == 1 || new_cfa == LLDB_INVALID_ADDRESS) { 1813d00dff88SPavel Labath UnwindLogMsg("failed to get cfa with fallback unwindplan"); 1814d00dff88SPavel Labath m_fallback_unwind_plan_sp.reset(); 1815d00dff88SPavel Labath m_full_unwind_plan_sp = original_full_unwind_plan_sp; 1816d00dff88SPavel Labath return false; 1817d00dff88SPavel Labath } 1818d00dff88SPavel Labath m_cfa = new_cfa; 1819d00dff88SPavel Labath 1820d00dff88SPavel Labath ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(), 1821d00dff88SPavel Labath active_row->GetAFAValue(), m_afa); 1822d00dff88SPavel Labath 1823d00dff88SPavel Labath if (SavedLocationForRegister(pc_regnum.GetAsKind(eRegisterKindLLDB), 1824d00dff88SPavel Labath regloc) == 1825d00dff88SPavel Labath UnwindLLDB::RegisterSearchResult::eRegisterFound) { 1826d00dff88SPavel Labath const RegisterInfo *reg_info = 1827d00dff88SPavel Labath GetRegisterInfoAtIndex(pc_regnum.GetAsKind(eRegisterKindLLDB)); 1828d00dff88SPavel Labath if (reg_info) { 1829d00dff88SPavel Labath RegisterValue reg_value; 1830d00dff88SPavel Labath if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, 1831d00dff88SPavel Labath reg_value)) { 1832d00dff88SPavel Labath new_caller_pc_value = reg_value.GetAsUInt64(); 18338770b4ecSJonas Devlieghere if (ProcessSP process_sp = m_thread.GetProcess()) { 18340ce7037bSJason Molenda if (ABISP abi_sp = process_sp->GetABI()) 18350ce7037bSJason Molenda new_caller_pc_value = abi_sp->FixCodeAddress(new_caller_pc_value); 18368770b4ecSJonas Devlieghere } 1837d00dff88SPavel Labath } 1838d00dff88SPavel Labath } 1839d00dff88SPavel Labath } 1840d00dff88SPavel Labath 1841d00dff88SPavel Labath if (new_caller_pc_value == LLDB_INVALID_ADDRESS) { 1842d00dff88SPavel Labath UnwindLogMsg("failed to get a pc value for the caller frame with the " 1843d00dff88SPavel Labath "fallback unwind plan"); 1844d00dff88SPavel Labath m_fallback_unwind_plan_sp.reset(); 1845d00dff88SPavel Labath m_full_unwind_plan_sp = original_full_unwind_plan_sp; 1846d00dff88SPavel Labath m_cfa = old_cfa; 1847d00dff88SPavel Labath m_afa = old_afa; 1848d00dff88SPavel Labath return false; 1849d00dff88SPavel Labath } 1850d00dff88SPavel Labath 1851d00dff88SPavel Labath if (old_caller_pc_value == new_caller_pc_value && 1852d00dff88SPavel Labath m_cfa == old_cfa && 1853d00dff88SPavel Labath m_afa == old_afa) { 1854d00dff88SPavel Labath UnwindLogMsg("fallback unwind plan got the same values for this frame " 1855d00dff88SPavel Labath "CFA and caller frame pc, not using"); 1856d00dff88SPavel Labath m_fallback_unwind_plan_sp.reset(); 1857d00dff88SPavel Labath m_full_unwind_plan_sp = original_full_unwind_plan_sp; 1858d00dff88SPavel Labath return false; 1859d00dff88SPavel Labath } 1860d00dff88SPavel Labath 1861d00dff88SPavel Labath UnwindLogMsg("trying to unwind from this function with the UnwindPlan '%s' " 1862d00dff88SPavel Labath "because UnwindPlan '%s' failed.", 1863d00dff88SPavel Labath m_fallback_unwind_plan_sp->GetSourceName().GetCString(), 1864d00dff88SPavel Labath original_full_unwind_plan_sp->GetSourceName().GetCString()); 1865d00dff88SPavel Labath 1866d00dff88SPavel Labath // We've copied the fallback unwind plan into the full - now clear the 1867d00dff88SPavel Labath // fallback. 1868d00dff88SPavel Labath m_fallback_unwind_plan_sp.reset(); 1869d00dff88SPavel Labath PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp); 1870d00dff88SPavel Labath } 1871d00dff88SPavel Labath 1872d00dff88SPavel Labath return true; 1873d00dff88SPavel Labath } 1874d00dff88SPavel Labath 1875d00dff88SPavel Labath bool RegisterContextUnwind::ForceSwitchToFallbackUnwindPlan() { 1876d00dff88SPavel Labath if (m_fallback_unwind_plan_sp.get() == nullptr) 1877d00dff88SPavel Labath return false; 1878d00dff88SPavel Labath 1879d00dff88SPavel Labath if (m_full_unwind_plan_sp.get() == nullptr) 1880d00dff88SPavel Labath return false; 1881d00dff88SPavel Labath 1882d00dff88SPavel Labath if (m_full_unwind_plan_sp.get() == m_fallback_unwind_plan_sp.get() || 1883d00dff88SPavel Labath m_full_unwind_plan_sp->GetSourceName() == 1884d00dff88SPavel Labath m_fallback_unwind_plan_sp->GetSourceName()) { 1885d00dff88SPavel Labath return false; 1886d00dff88SPavel Labath } 1887d00dff88SPavel Labath 1888d00dff88SPavel Labath UnwindPlan::RowSP active_row = 1889d00dff88SPavel Labath m_fallback_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset); 1890d00dff88SPavel Labath 1891d00dff88SPavel Labath if (active_row && 1892d00dff88SPavel Labath active_row->GetCFAValue().GetValueType() != 1893d00dff88SPavel Labath UnwindPlan::Row::FAValue::unspecified) { 1894d00dff88SPavel Labath addr_t new_cfa; 1895d00dff88SPavel Labath if (!ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(), 1896d00dff88SPavel Labath active_row->GetCFAValue(), new_cfa) || 1897d00dff88SPavel Labath new_cfa == 0 || new_cfa == 1 || new_cfa == LLDB_INVALID_ADDRESS) { 1898d00dff88SPavel Labath UnwindLogMsg("failed to get cfa with fallback unwindplan"); 1899d00dff88SPavel Labath m_fallback_unwind_plan_sp.reset(); 1900d00dff88SPavel Labath return false; 1901d00dff88SPavel Labath } 1902d00dff88SPavel Labath 1903d00dff88SPavel Labath ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(), 1904d00dff88SPavel Labath active_row->GetAFAValue(), m_afa); 1905d00dff88SPavel Labath 1906d00dff88SPavel Labath m_full_unwind_plan_sp = m_fallback_unwind_plan_sp; 1907d00dff88SPavel Labath m_fallback_unwind_plan_sp.reset(); 1908d00dff88SPavel Labath 1909d00dff88SPavel Labath m_registers.clear(); 1910d00dff88SPavel Labath 1911d00dff88SPavel Labath m_cfa = new_cfa; 1912d00dff88SPavel Labath 1913d00dff88SPavel Labath PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp); 1914d00dff88SPavel Labath 1915d00dff88SPavel Labath UnwindLogMsg("switched unconditionally to the fallback unwindplan %s", 1916d00dff88SPavel Labath m_full_unwind_plan_sp->GetSourceName().GetCString()); 1917d00dff88SPavel Labath return true; 1918d00dff88SPavel Labath } 1919d00dff88SPavel Labath return false; 1920d00dff88SPavel Labath } 1921d00dff88SPavel Labath 1922d00dff88SPavel Labath void RegisterContextUnwind::PropagateTrapHandlerFlagFromUnwindPlan( 1923d00dff88SPavel Labath lldb::UnwindPlanSP unwind_plan) { 1924d00dff88SPavel Labath if (unwind_plan->GetUnwindPlanForSignalTrap() != eLazyBoolYes) { 1925d00dff88SPavel Labath // Unwind plan does not indicate trap handler. Do nothing. We may 1926d00dff88SPavel Labath // already be flagged as trap handler flag due to the symbol being 1927d00dff88SPavel Labath // in the trap handler symbol list, and that should take precedence. 1928d00dff88SPavel Labath return; 1929d00dff88SPavel Labath } else if (m_frame_type != eNormalFrame) { 1930d00dff88SPavel Labath // If this is already a trap handler frame, nothing to do. 1931d00dff88SPavel Labath // If this is a skip or debug or invalid frame, don't override that. 1932d00dff88SPavel Labath return; 1933d00dff88SPavel Labath } 1934d00dff88SPavel Labath 1935d00dff88SPavel Labath m_frame_type = eTrapHandlerFrame; 1936d00dff88SPavel Labath 1937d00dff88SPavel Labath if (m_current_offset_backed_up_one != m_current_offset) { 1938d00dff88SPavel Labath // We backed up the pc by 1 to compute the symbol context, but 1939d00dff88SPavel Labath // now need to undo that because the pc of the trap handler 1940d00dff88SPavel Labath // frame may in fact be the first instruction of a signal return 1941d00dff88SPavel Labath // trampoline, rather than the instruction after a call. This 1942d00dff88SPavel Labath // happens on systems where the signal handler dispatch code, rather 1943d00dff88SPavel Labath // than calling the handler and being returned to, jumps to the 1944d00dff88SPavel Labath // handler after pushing the address of a return trampoline on the 1945d00dff88SPavel Labath // stack -- on these systems, when the handler returns, control will 1946d00dff88SPavel Labath // be transferred to the return trampoline, so that's the best 1947d00dff88SPavel Labath // symbol we can present in the callstack. 1948d00dff88SPavel Labath UnwindLogMsg("Resetting current offset and re-doing symbol lookup; " 1949d00dff88SPavel Labath "old symbol was %s", 1950d00dff88SPavel Labath GetSymbolOrFunctionName(m_sym_ctx).AsCString("")); 1951d00dff88SPavel Labath m_current_offset_backed_up_one = m_current_offset; 1952d00dff88SPavel Labath 1953d00dff88SPavel Labath AddressRange addr_range; 1954d00dff88SPavel Labath m_sym_ctx_valid = m_current_pc.ResolveFunctionScope(m_sym_ctx, &addr_range); 1955d00dff88SPavel Labath 1956d00dff88SPavel Labath UnwindLogMsg("Symbol is now %s", 1957d00dff88SPavel Labath GetSymbolOrFunctionName(m_sym_ctx).AsCString("")); 1958d00dff88SPavel Labath 1959d00dff88SPavel Labath ExecutionContext exe_ctx(m_thread.shared_from_this()); 1960d00dff88SPavel Labath Process *process = exe_ctx.GetProcessPtr(); 1961d00dff88SPavel Labath Target *target = &process->GetTarget(); 1962d00dff88SPavel Labath 1963d00dff88SPavel Labath m_start_pc = addr_range.GetBaseAddress(); 1964d00dff88SPavel Labath m_current_offset = 1965d00dff88SPavel Labath m_current_pc.GetLoadAddress(target) - m_start_pc.GetLoadAddress(target); 1966d00dff88SPavel Labath } 1967d00dff88SPavel Labath } 1968d00dff88SPavel Labath 1969d00dff88SPavel Labath bool RegisterContextUnwind::ReadFrameAddress( 1970d00dff88SPavel Labath lldb::RegisterKind row_register_kind, UnwindPlan::Row::FAValue &fa, 1971d00dff88SPavel Labath addr_t &address) { 1972d00dff88SPavel Labath RegisterValue reg_value; 1973d00dff88SPavel Labath 1974d00dff88SPavel Labath address = LLDB_INVALID_ADDRESS; 1975d00dff88SPavel Labath addr_t cfa_reg_contents; 19760ce7037bSJason Molenda ABISP abi_sp = m_thread.GetProcess()->GetABI(); 1977d00dff88SPavel Labath 1978d00dff88SPavel Labath switch (fa.GetValueType()) { 1979d00dff88SPavel Labath case UnwindPlan::Row::FAValue::isRegisterDereferenced: { 1980d00dff88SPavel Labath RegisterNumber cfa_reg(m_thread, row_register_kind, 1981d00dff88SPavel Labath fa.GetRegisterNumber()); 1982d00dff88SPavel Labath if (ReadGPRValue(cfa_reg, cfa_reg_contents)) { 1983d00dff88SPavel Labath const RegisterInfo *reg_info = 1984d00dff88SPavel Labath GetRegisterInfoAtIndex(cfa_reg.GetAsKind(eRegisterKindLLDB)); 1985d00dff88SPavel Labath RegisterValue reg_value; 1986d00dff88SPavel Labath if (reg_info) { 19870ce7037bSJason Molenda if (abi_sp) 19880ce7037bSJason Molenda cfa_reg_contents = abi_sp->FixDataAddress(cfa_reg_contents); 1989d00dff88SPavel Labath Status error = ReadRegisterValueFromMemory( 1990d00dff88SPavel Labath reg_info, cfa_reg_contents, reg_info->byte_size, reg_value); 1991d00dff88SPavel Labath if (error.Success()) { 1992d00dff88SPavel Labath address = reg_value.GetAsUInt64(); 19930ce7037bSJason Molenda if (abi_sp) 1994ce12b52dSJonas Devlieghere address = abi_sp->FixCodeAddress(address); 1995d00dff88SPavel Labath UnwindLogMsg( 1996d00dff88SPavel Labath "CFA value via dereferencing reg %s (%d): reg has val 0x%" PRIx64 1997d00dff88SPavel Labath ", CFA value is 0x%" PRIx64, 1998d00dff88SPavel Labath cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB), 1999d00dff88SPavel Labath cfa_reg_contents, address); 2000d00dff88SPavel Labath return true; 2001d00dff88SPavel Labath } else { 2002d00dff88SPavel Labath UnwindLogMsg("Tried to deref reg %s (%d) [0x%" PRIx64 2003d00dff88SPavel Labath "] but memory read failed.", 2004d00dff88SPavel Labath cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB), 2005d00dff88SPavel Labath cfa_reg_contents); 2006d00dff88SPavel Labath } 2007d00dff88SPavel Labath } 2008d00dff88SPavel Labath } 2009d00dff88SPavel Labath break; 2010d00dff88SPavel Labath } 2011d00dff88SPavel Labath case UnwindPlan::Row::FAValue::isRegisterPlusOffset: { 2012d00dff88SPavel Labath RegisterNumber cfa_reg(m_thread, row_register_kind, 2013d00dff88SPavel Labath fa.GetRegisterNumber()); 2014d00dff88SPavel Labath if (ReadGPRValue(cfa_reg, cfa_reg_contents)) { 20150ce7037bSJason Molenda if (abi_sp) 20160ce7037bSJason Molenda cfa_reg_contents = abi_sp->FixDataAddress(cfa_reg_contents); 2017d00dff88SPavel Labath if (cfa_reg_contents == LLDB_INVALID_ADDRESS || cfa_reg_contents == 0 || 2018d00dff88SPavel Labath cfa_reg_contents == 1) { 2019d00dff88SPavel Labath UnwindLogMsg( 2020d00dff88SPavel Labath "Got an invalid CFA register value - reg %s (%d), value 0x%" PRIx64, 2021d00dff88SPavel Labath cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB), 2022d00dff88SPavel Labath cfa_reg_contents); 2023d00dff88SPavel Labath cfa_reg_contents = LLDB_INVALID_ADDRESS; 2024d00dff88SPavel Labath return false; 2025d00dff88SPavel Labath } 2026d00dff88SPavel Labath address = cfa_reg_contents + fa.GetOffset(); 2027d00dff88SPavel Labath UnwindLogMsg( 2028d00dff88SPavel Labath "CFA is 0x%" PRIx64 ": Register %s (%d) contents are 0x%" PRIx64 2029d00dff88SPavel Labath ", offset is %d", 2030d00dff88SPavel Labath address, cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB), 2031d00dff88SPavel Labath cfa_reg_contents, fa.GetOffset()); 2032d00dff88SPavel Labath return true; 2033d00dff88SPavel Labath } 2034d00dff88SPavel Labath break; 2035d00dff88SPavel Labath } 2036d00dff88SPavel Labath case UnwindPlan::Row::FAValue::isDWARFExpression: { 2037d00dff88SPavel Labath ExecutionContext exe_ctx(m_thread.shared_from_this()); 2038d00dff88SPavel Labath Process *process = exe_ctx.GetProcessPtr(); 2039d00dff88SPavel Labath DataExtractor dwarfdata(fa.GetDWARFExpressionBytes(), 2040d00dff88SPavel Labath fa.GetDWARFExpressionLength(), 2041d00dff88SPavel Labath process->GetByteOrder(), 2042d00dff88SPavel Labath process->GetAddressByteSize()); 2043d00dff88SPavel Labath ModuleSP opcode_ctx; 2044b74a01a8SZequan Wu DWARFExpressionList dwarfexpr(opcode_ctx, dwarfdata, nullptr); 2045b74a01a8SZequan Wu dwarfexpr.GetMutableExpressionAtAddress()->SetRegisterKind( 2046b74a01a8SZequan Wu row_register_kind); 2047539b72f2SJonas Devlieghere llvm::Expected<Value> result = 2048539b72f2SJonas Devlieghere dwarfexpr.Evaluate(&exe_ctx, this, 0, nullptr, nullptr); 2049539b72f2SJonas Devlieghere if (result) { 2050539b72f2SJonas Devlieghere address = result->GetScalar().ULongLong(); 2051ce12b52dSJonas Devlieghere if (ABISP abi_sp = m_thread.GetProcess()->GetABI()) 2052ce12b52dSJonas Devlieghere address = abi_sp->FixCodeAddress(address); 2053d00dff88SPavel Labath 2054d00dff88SPavel Labath UnwindLogMsg("CFA value set by DWARF expression is 0x%" PRIx64, 2055d00dff88SPavel Labath address); 2056d00dff88SPavel Labath return true; 2057d00dff88SPavel Labath } 2058d00dff88SPavel Labath UnwindLogMsg("Failed to set CFA value via DWARF expression: %s", 2059539b72f2SJonas Devlieghere llvm::toString(result.takeError()).c_str()); 2060d00dff88SPavel Labath break; 2061d00dff88SPavel Labath } 2062d00dff88SPavel Labath case UnwindPlan::Row::FAValue::isRaSearch: { 2063d00dff88SPavel Labath Process &process = *m_thread.GetProcess(); 2064d00dff88SPavel Labath lldb::addr_t return_address_hint = GetReturnAddressHint(fa.GetOffset()); 2065d00dff88SPavel Labath if (return_address_hint == LLDB_INVALID_ADDRESS) 2066d00dff88SPavel Labath return false; 2067d00dff88SPavel Labath const unsigned max_iterations = 256; 2068d00dff88SPavel Labath for (unsigned i = 0; i < max_iterations; ++i) { 2069d00dff88SPavel Labath Status st; 2070d00dff88SPavel Labath lldb::addr_t candidate_addr = 2071d00dff88SPavel Labath return_address_hint + i * process.GetAddressByteSize(); 2072d00dff88SPavel Labath lldb::addr_t candidate = 2073d00dff88SPavel Labath process.ReadPointerFromMemory(candidate_addr, st); 2074d00dff88SPavel Labath if (st.Fail()) { 2075d00dff88SPavel Labath UnwindLogMsg("Cannot read memory at 0x%" PRIx64 ": %s", candidate_addr, 2076d00dff88SPavel Labath st.AsCString()); 2077d00dff88SPavel Labath return false; 2078d00dff88SPavel Labath } 2079d00dff88SPavel Labath Address addr; 2080d00dff88SPavel Labath uint32_t permissions; 2081d00dff88SPavel Labath if (process.GetLoadAddressPermissions(candidate, permissions) && 2082d00dff88SPavel Labath permissions & lldb::ePermissionsExecutable) { 2083d00dff88SPavel Labath address = candidate_addr; 2084d00dff88SPavel Labath UnwindLogMsg("Heuristically found CFA: 0x%" PRIx64, address); 2085d00dff88SPavel Labath return true; 2086d00dff88SPavel Labath } 2087d00dff88SPavel Labath } 2088d00dff88SPavel Labath UnwindLogMsg("No suitable CFA found"); 2089d00dff88SPavel Labath break; 2090d00dff88SPavel Labath } 20916294679fSFelipe de Azevedo Piovezan case UnwindPlan::Row::FAValue::isConstant: { 20926294679fSFelipe de Azevedo Piovezan address = fa.GetConstant(); 20936294679fSFelipe de Azevedo Piovezan address = m_thread.GetProcess()->FixDataAddress(address); 20946294679fSFelipe de Azevedo Piovezan UnwindLogMsg("CFA value set by constant is 0x%" PRIx64, address); 20956294679fSFelipe de Azevedo Piovezan return true; 20966294679fSFelipe de Azevedo Piovezan } 2097d00dff88SPavel Labath default: 2098d00dff88SPavel Labath return false; 2099d00dff88SPavel Labath } 2100d00dff88SPavel Labath return false; 2101d00dff88SPavel Labath } 2102d00dff88SPavel Labath 2103d00dff88SPavel Labath lldb::addr_t RegisterContextUnwind::GetReturnAddressHint(int32_t plan_offset) { 2104d00dff88SPavel Labath addr_t hint; 2105d00dff88SPavel Labath if (!ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, hint)) 2106d00dff88SPavel Labath return LLDB_INVALID_ADDRESS; 2107d00dff88SPavel Labath if (!m_sym_ctx.module_sp || !m_sym_ctx.symbol) 2108d00dff88SPavel Labath return LLDB_INVALID_ADDRESS; 21090ce7037bSJason Molenda if (ABISP abi_sp = m_thread.GetProcess()->GetABI()) 21100ce7037bSJason Molenda hint = abi_sp->FixCodeAddress(hint); 2111d00dff88SPavel Labath 2112d00dff88SPavel Labath hint += plan_offset; 2113d00dff88SPavel Labath 2114d00dff88SPavel Labath if (auto next = GetNextFrame()) { 2115d00dff88SPavel Labath if (!next->m_sym_ctx.module_sp || !next->m_sym_ctx.symbol) 2116d00dff88SPavel Labath return LLDB_INVALID_ADDRESS; 2117d00dff88SPavel Labath if (auto expected_size = 2118d00dff88SPavel Labath next->m_sym_ctx.module_sp->GetSymbolFile()->GetParameterStackSize( 2119d00dff88SPavel Labath *next->m_sym_ctx.symbol)) 2120d00dff88SPavel Labath hint += *expected_size; 2121d00dff88SPavel Labath else { 2122d00dff88SPavel Labath UnwindLogMsgVerbose("Could not retrieve parameter size: %s", 2123d00dff88SPavel Labath llvm::toString(expected_size.takeError()).c_str()); 2124d00dff88SPavel Labath return LLDB_INVALID_ADDRESS; 2125d00dff88SPavel Labath } 2126d00dff88SPavel Labath } 2127d00dff88SPavel Labath return hint; 2128d00dff88SPavel Labath } 2129d00dff88SPavel Labath 2130d00dff88SPavel Labath // Retrieve a general purpose register value for THIS frame, as saved by the 2131d00dff88SPavel Labath // NEXT frame, i.e. the frame that 2132d00dff88SPavel Labath // this frame called. e.g. 2133d00dff88SPavel Labath // 2134d00dff88SPavel Labath // foo () { } 2135d00dff88SPavel Labath // bar () { foo (); } 2136d00dff88SPavel Labath // main () { bar (); } 2137d00dff88SPavel Labath // 2138d00dff88SPavel Labath // stopped in foo() so 2139d00dff88SPavel Labath // frame 0 - foo 2140d00dff88SPavel Labath // frame 1 - bar 2141d00dff88SPavel Labath // frame 2 - main 2142d00dff88SPavel Labath // and this RegisterContext is for frame 1 (bar) - if we want to get the pc 2143d00dff88SPavel Labath // value for frame 1, we need to ask 2144d00dff88SPavel Labath // where frame 0 (the "next" frame) saved that and retrieve the value. 2145d00dff88SPavel Labath 2146d00dff88SPavel Labath bool RegisterContextUnwind::ReadGPRValue(lldb::RegisterKind register_kind, 2147d00dff88SPavel Labath uint32_t regnum, addr_t &value) { 2148d00dff88SPavel Labath if (!IsValid()) 2149d00dff88SPavel Labath return false; 2150d00dff88SPavel Labath 2151d00dff88SPavel Labath uint32_t lldb_regnum; 2152d00dff88SPavel Labath if (register_kind == eRegisterKindLLDB) { 2153d00dff88SPavel Labath lldb_regnum = regnum; 2154d00dff88SPavel Labath } else if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds( 2155d00dff88SPavel Labath register_kind, regnum, eRegisterKindLLDB, lldb_regnum)) { 2156d00dff88SPavel Labath return false; 2157d00dff88SPavel Labath } 2158d00dff88SPavel Labath 2159d00dff88SPavel Labath const RegisterInfo *reg_info = GetRegisterInfoAtIndex(lldb_regnum); 2160701030c3SJason Molenda assert(reg_info); 2161701030c3SJason Molenda if (!reg_info) { 2162701030c3SJason Molenda UnwindLogMsg( 2163701030c3SJason Molenda "Could not find RegisterInfo definition for lldb register number %d", 2164701030c3SJason Molenda lldb_regnum); 2165701030c3SJason Molenda return false; 2166701030c3SJason Molenda } 2167701030c3SJason Molenda 21680ce7037bSJason Molenda uint32_t generic_regnum = LLDB_INVALID_REGNUM; 21690ce7037bSJason Molenda if (register_kind == eRegisterKindGeneric) 21700ce7037bSJason Molenda generic_regnum = regnum; 21710ce7037bSJason Molenda else 21720ce7037bSJason Molenda m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds( 21730ce7037bSJason Molenda register_kind, regnum, eRegisterKindGeneric, generic_regnum); 21740ce7037bSJason Molenda ABISP abi_sp = m_thread.GetProcess()->GetABI(); 21750ce7037bSJason Molenda 2176d00dff88SPavel Labath RegisterValue reg_value; 2177d00dff88SPavel Labath // if this is frame 0 (currently executing frame), get the requested reg 2178d00dff88SPavel Labath // contents from the actual thread registers 2179d00dff88SPavel Labath if (IsFrameZero()) { 2180d00dff88SPavel Labath if (m_thread.GetRegisterContext()->ReadRegister(reg_info, reg_value)) { 2181d00dff88SPavel Labath value = reg_value.GetAsUInt64(); 21820ce7037bSJason Molenda if (abi_sp && generic_regnum != LLDB_INVALID_REGNUM) { 21830ce7037bSJason Molenda if (generic_regnum == LLDB_REGNUM_GENERIC_PC || 21840ce7037bSJason Molenda generic_regnum == LLDB_REGNUM_GENERIC_RA) 21850ce7037bSJason Molenda value = abi_sp->FixCodeAddress(value); 21860ce7037bSJason Molenda if (generic_regnum == LLDB_REGNUM_GENERIC_SP || 21870ce7037bSJason Molenda generic_regnum == LLDB_REGNUM_GENERIC_FP) 21880ce7037bSJason Molenda value = abi_sp->FixDataAddress(value); 21890ce7037bSJason Molenda } 2190d00dff88SPavel Labath return true; 2191d00dff88SPavel Labath } 2192d00dff88SPavel Labath return false; 2193d00dff88SPavel Labath } 2194d00dff88SPavel Labath 2195d00dff88SPavel Labath bool pc_register = false; 21960ce7037bSJason Molenda if (generic_regnum != LLDB_INVALID_REGNUM && 2197d00dff88SPavel Labath (generic_regnum == LLDB_REGNUM_GENERIC_PC || 21980ce7037bSJason Molenda generic_regnum == LLDB_REGNUM_GENERIC_RA)) 2199d00dff88SPavel Labath pc_register = true; 2200d00dff88SPavel Labath 22013336d731SJason Molenda lldb_private::UnwindLLDB::ConcreteRegisterLocation regloc; 2202d00dff88SPavel Labath if (!m_parent_unwind.SearchForSavedLocationForRegister( 2203d00dff88SPavel Labath lldb_regnum, regloc, m_frame_number - 1, pc_register)) { 2204d00dff88SPavel Labath return false; 2205d00dff88SPavel Labath } 2206d00dff88SPavel Labath if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) { 2207d00dff88SPavel Labath value = reg_value.GetAsUInt64(); 22088770b4ecSJonas Devlieghere if (pc_register) { 22090ce7037bSJason Molenda if (ABISP abi_sp = m_thread.GetProcess()->GetABI()) { 22100ce7037bSJason Molenda value = abi_sp->FixCodeAddress(value); 22118770b4ecSJonas Devlieghere } 22128770b4ecSJonas Devlieghere } 2213d00dff88SPavel Labath return true; 2214d00dff88SPavel Labath } 2215d00dff88SPavel Labath return false; 2216d00dff88SPavel Labath } 2217d00dff88SPavel Labath 2218d00dff88SPavel Labath bool RegisterContextUnwind::ReadGPRValue(const RegisterNumber ®num, 2219d00dff88SPavel Labath addr_t &value) { 2220d00dff88SPavel Labath return ReadGPRValue(regnum.GetRegisterKind(), regnum.GetRegisterNumber(), 2221d00dff88SPavel Labath value); 2222d00dff88SPavel Labath } 2223d00dff88SPavel Labath 2224d00dff88SPavel Labath // Find the value of a register in THIS frame 2225d00dff88SPavel Labath 2226d00dff88SPavel Labath bool RegisterContextUnwind::ReadRegister(const RegisterInfo *reg_info, 2227d00dff88SPavel Labath RegisterValue &value) { 2228d00dff88SPavel Labath if (!IsValid()) 2229d00dff88SPavel Labath return false; 2230d00dff88SPavel Labath 2231d00dff88SPavel Labath const uint32_t lldb_regnum = reg_info->kinds[eRegisterKindLLDB]; 2232d00dff88SPavel Labath UnwindLogMsgVerbose("looking for register saved location for reg %d", 2233d00dff88SPavel Labath lldb_regnum); 2234d00dff88SPavel Labath 2235d00dff88SPavel Labath // If this is the 0th frame, hand this over to the live register context 2236d00dff88SPavel Labath if (IsFrameZero()) { 2237d00dff88SPavel Labath UnwindLogMsgVerbose("passing along to the live register context for reg %d", 2238d00dff88SPavel Labath lldb_regnum); 2239d00dff88SPavel Labath return m_thread.GetRegisterContext()->ReadRegister(reg_info, value); 2240d00dff88SPavel Labath } 2241d00dff88SPavel Labath 2242d00dff88SPavel Labath bool is_pc_regnum = false; 2243d00dff88SPavel Labath if (reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_PC || 2244d00dff88SPavel Labath reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_RA) { 2245d00dff88SPavel Labath is_pc_regnum = true; 2246d00dff88SPavel Labath } 2247d00dff88SPavel Labath 22483336d731SJason Molenda lldb_private::UnwindLLDB::ConcreteRegisterLocation regloc; 2249d00dff88SPavel Labath // Find out where the NEXT frame saved THIS frame's register contents 2250d00dff88SPavel Labath if (!m_parent_unwind.SearchForSavedLocationForRegister( 2251d00dff88SPavel Labath lldb_regnum, regloc, m_frame_number - 1, is_pc_regnum)) 2252d00dff88SPavel Labath return false; 2253d00dff88SPavel Labath 22548770b4ecSJonas Devlieghere bool result = ReadRegisterValueFromRegisterLocation(regloc, reg_info, value); 22558770b4ecSJonas Devlieghere if (result) { 22568770b4ecSJonas Devlieghere if (is_pc_regnum && value.GetType() == RegisterValue::eTypeUInt64) { 22578770b4ecSJonas Devlieghere addr_t reg_value = value.GetAsUInt64(LLDB_INVALID_ADDRESS); 22588770b4ecSJonas Devlieghere if (reg_value != LLDB_INVALID_ADDRESS) { 22590ce7037bSJason Molenda if (ABISP abi_sp = m_thread.GetProcess()->GetABI()) 22600ce7037bSJason Molenda value = abi_sp->FixCodeAddress(reg_value); 22618770b4ecSJonas Devlieghere } 22628770b4ecSJonas Devlieghere } 22638770b4ecSJonas Devlieghere } 22648770b4ecSJonas Devlieghere return result; 2265d00dff88SPavel Labath } 2266d00dff88SPavel Labath 2267d00dff88SPavel Labath bool RegisterContextUnwind::WriteRegister(const RegisterInfo *reg_info, 2268d00dff88SPavel Labath const RegisterValue &value) { 2269d00dff88SPavel Labath if (!IsValid()) 2270d00dff88SPavel Labath return false; 2271d00dff88SPavel Labath 2272d00dff88SPavel Labath const uint32_t lldb_regnum = reg_info->kinds[eRegisterKindLLDB]; 2273d00dff88SPavel Labath UnwindLogMsgVerbose("looking for register saved location for reg %d", 2274d00dff88SPavel Labath lldb_regnum); 2275d00dff88SPavel Labath 2276d00dff88SPavel Labath // If this is the 0th frame, hand this over to the live register context 2277d00dff88SPavel Labath if (IsFrameZero()) { 2278d00dff88SPavel Labath UnwindLogMsgVerbose("passing along to the live register context for reg %d", 2279d00dff88SPavel Labath lldb_regnum); 2280d00dff88SPavel Labath return m_thread.GetRegisterContext()->WriteRegister(reg_info, value); 2281d00dff88SPavel Labath } 2282d00dff88SPavel Labath 22833336d731SJason Molenda lldb_private::UnwindLLDB::ConcreteRegisterLocation regloc; 2284d00dff88SPavel Labath // Find out where the NEXT frame saved THIS frame's register contents 2285d00dff88SPavel Labath if (!m_parent_unwind.SearchForSavedLocationForRegister( 2286d00dff88SPavel Labath lldb_regnum, regloc, m_frame_number - 1, false)) 2287d00dff88SPavel Labath return false; 2288d00dff88SPavel Labath 2289d00dff88SPavel Labath return WriteRegisterValueToRegisterLocation(regloc, reg_info, value); 2290d00dff88SPavel Labath } 2291d00dff88SPavel Labath 2292d00dff88SPavel Labath // Don't need to implement this one 2293fc54427eSJonas Devlieghere bool RegisterContextUnwind::ReadAllRegisterValues( 2294fc54427eSJonas Devlieghere lldb::WritableDataBufferSP &data_sp) { 2295d00dff88SPavel Labath return false; 2296d00dff88SPavel Labath } 2297d00dff88SPavel Labath 2298d00dff88SPavel Labath // Don't need to implement this one 2299d00dff88SPavel Labath bool RegisterContextUnwind::WriteAllRegisterValues( 2300d00dff88SPavel Labath const lldb::DataBufferSP &data_sp) { 2301d00dff88SPavel Labath return false; 2302d00dff88SPavel Labath } 2303d00dff88SPavel Labath 2304d00dff88SPavel Labath // Retrieve the pc value for THIS from 2305d00dff88SPavel Labath 2306d00dff88SPavel Labath bool RegisterContextUnwind::GetCFA(addr_t &cfa) { 2307d00dff88SPavel Labath if (!IsValid()) { 2308d00dff88SPavel Labath return false; 2309d00dff88SPavel Labath } 2310d00dff88SPavel Labath if (m_cfa == LLDB_INVALID_ADDRESS) { 2311d00dff88SPavel Labath return false; 2312d00dff88SPavel Labath } 2313d00dff88SPavel Labath cfa = m_cfa; 2314d00dff88SPavel Labath return true; 2315d00dff88SPavel Labath } 2316d00dff88SPavel Labath 2317d00dff88SPavel Labath RegisterContextUnwind::SharedPtr RegisterContextUnwind::GetNextFrame() const { 2318d00dff88SPavel Labath RegisterContextUnwind::SharedPtr regctx; 2319d00dff88SPavel Labath if (m_frame_number == 0) 2320d00dff88SPavel Labath return regctx; 2321d00dff88SPavel Labath return m_parent_unwind.GetRegisterContextForFrameNum(m_frame_number - 1); 2322d00dff88SPavel Labath } 2323d00dff88SPavel Labath 2324d00dff88SPavel Labath RegisterContextUnwind::SharedPtr RegisterContextUnwind::GetPrevFrame() const { 2325d00dff88SPavel Labath RegisterContextUnwind::SharedPtr regctx; 2326d00dff88SPavel Labath return m_parent_unwind.GetRegisterContextForFrameNum(m_frame_number + 1); 2327d00dff88SPavel Labath } 2328d00dff88SPavel Labath 2329d00dff88SPavel Labath // Retrieve the address of the start of the function of THIS frame 2330d00dff88SPavel Labath 2331d00dff88SPavel Labath bool RegisterContextUnwind::GetStartPC(addr_t &start_pc) { 2332d00dff88SPavel Labath if (!IsValid()) 2333d00dff88SPavel Labath return false; 2334d00dff88SPavel Labath 2335d00dff88SPavel Labath if (!m_start_pc.IsValid()) { 2336d00dff88SPavel Labath bool read_successfully = ReadPC (start_pc); 2337d00dff88SPavel Labath if (read_successfully) 2338d00dff88SPavel Labath { 2339d00dff88SPavel Labath ProcessSP process_sp (m_thread.GetProcess()); 2340d00dff88SPavel Labath if (process_sp) 2341d00dff88SPavel Labath { 23420ce7037bSJason Molenda if (ABISP abi_sp = process_sp->GetABI()) 23430ce7037bSJason Molenda start_pc = abi_sp->FixCodeAddress(start_pc); 2344d00dff88SPavel Labath } 2345d00dff88SPavel Labath } 2346d00dff88SPavel Labath return read_successfully; 2347d00dff88SPavel Labath } 2348d00dff88SPavel Labath start_pc = m_start_pc.GetLoadAddress(CalculateTarget().get()); 2349d00dff88SPavel Labath return true; 2350d00dff88SPavel Labath } 2351d00dff88SPavel Labath 2352d00dff88SPavel Labath // Retrieve the current pc value for THIS frame, as saved by the NEXT frame. 2353d00dff88SPavel Labath 2354d00dff88SPavel Labath bool RegisterContextUnwind::ReadPC(addr_t &pc) { 2355d00dff88SPavel Labath if (!IsValid()) 2356d00dff88SPavel Labath return false; 2357d00dff88SPavel Labath 2358d00dff88SPavel Labath bool above_trap_handler = false; 2359d00dff88SPavel Labath if (GetNextFrame().get() && GetNextFrame()->IsValid() && 2360d00dff88SPavel Labath GetNextFrame()->IsTrapHandlerFrame()) 2361d00dff88SPavel Labath above_trap_handler = true; 2362d00dff88SPavel Labath 2363d00dff88SPavel Labath if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc)) { 2364d00dff88SPavel Labath // A pc value of 0 or 1 is impossible in the middle of the stack -- it 2365d00dff88SPavel Labath // indicates the end of a stack walk. 2366d00dff88SPavel Labath // On the currently executing frame (or such a frame interrupted 2367d00dff88SPavel Labath // asynchronously by sigtramp et al) this may occur if code has jumped 2368d00dff88SPavel Labath // through a NULL pointer -- we want to be able to unwind past that frame 2369d00dff88SPavel Labath // to help find the bug. 2370d00dff88SPavel Labath 23710ce7037bSJason Molenda if (ABISP abi_sp = m_thread.GetProcess()->GetABI()) 23720ce7037bSJason Molenda pc = abi_sp->FixCodeAddress(pc); 2373d00dff88SPavel Labath 2374d00dff88SPavel Labath return !(m_all_registers_available == false && 2375d00dff88SPavel Labath above_trap_handler == false && (pc == 0 || pc == 1)); 2376d00dff88SPavel Labath } else { 2377d00dff88SPavel Labath return false; 2378d00dff88SPavel Labath } 2379d00dff88SPavel Labath } 2380d00dff88SPavel Labath 2381d00dff88SPavel Labath void RegisterContextUnwind::UnwindLogMsg(const char *fmt, ...) { 2382a007a6d8SPavel Labath Log *log = GetLog(LLDBLog::Unwind); 23831410a486SPavel Labath if (!log) 23841410a486SPavel Labath return; 23851410a486SPavel Labath 2386d00dff88SPavel Labath va_list args; 2387d00dff88SPavel Labath va_start(args, fmt); 2388d00dff88SPavel Labath 23891410a486SPavel Labath llvm::SmallString<0> logmsg; 23901410a486SPavel Labath if (VASprintf(logmsg, fmt, args)) { 2391d00dff88SPavel Labath LLDB_LOGF(log, "%*sth%d/fr%u %s", 2392d00dff88SPavel Labath m_frame_number < 100 ? m_frame_number : 100, "", 23931410a486SPavel Labath m_thread.GetIndexID(), m_frame_number, logmsg.c_str()); 2394d00dff88SPavel Labath } 23951410a486SPavel Labath va_end(args); 2396d00dff88SPavel Labath } 2397d00dff88SPavel Labath 2398d00dff88SPavel Labath void RegisterContextUnwind::UnwindLogMsgVerbose(const char *fmt, ...) { 2399a007a6d8SPavel Labath Log *log = GetLog(LLDBLog::Unwind); 24001410a486SPavel Labath if (!log || !log->GetVerbose()) 24011410a486SPavel Labath return; 24021410a486SPavel Labath 2403d00dff88SPavel Labath va_list args; 2404d00dff88SPavel Labath va_start(args, fmt); 2405d00dff88SPavel Labath 24061410a486SPavel Labath llvm::SmallString<0> logmsg; 24071410a486SPavel Labath if (VASprintf(logmsg, fmt, args)) { 2408d00dff88SPavel Labath LLDB_LOGF(log, "%*sth%d/fr%u %s", 2409d00dff88SPavel Labath m_frame_number < 100 ? m_frame_number : 100, "", 24101410a486SPavel Labath m_thread.GetIndexID(), m_frame_number, logmsg.c_str()); 2411d00dff88SPavel Labath } 24121410a486SPavel Labath va_end(args); 2413d00dff88SPavel Labath } 2414