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