1254721Semaste//===-- UnwindLLDB.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/Module.h" 10254721Semaste#include "lldb/Symbol/FuncUnwinders.h" 11254721Semaste#include "lldb/Symbol/Function.h" 12254721Semaste#include "lldb/Symbol/UnwindPlan.h" 13288943Sdim#include "lldb/Target/ABI.h" 14254721Semaste#include "lldb/Target/Process.h" 15254721Semaste#include "lldb/Target/RegisterContext.h" 16314564Sdim#include "lldb/Target/Target.h" 17314564Sdim#include "lldb/Target/Thread.h" 18321369Sdim#include "lldb/Utility/Log.h" 19254721Semaste 20314564Sdim#include "RegisterContextLLDB.h" 21254721Semaste#include "UnwindLLDB.h" 22254721Semaste 23254721Semasteusing namespace lldb; 24254721Semasteusing namespace lldb_private; 25254721Semaste 26314564SdimUnwindLLDB::UnwindLLDB(Thread &thread) 27314564Sdim : Unwind(thread), m_frames(), m_unwind_complete(false), 28314564Sdim m_user_supplied_trap_handler_functions() { 29314564Sdim ProcessSP process_sp(thread.GetProcess()); 30314564Sdim if (process_sp) { 31314564Sdim Args args; 32314564Sdim process_sp->GetTarget().GetUserSpecifiedTrapHandlerNames(args); 33314564Sdim size_t count = args.GetArgumentCount(); 34314564Sdim for (size_t i = 0; i < count; i++) { 35314564Sdim const char *func_name = args.GetArgumentAtIndex(i); 36314564Sdim m_user_supplied_trap_handler_functions.push_back(ConstString(func_name)); 37262528Semaste } 38314564Sdim } 39254721Semaste} 40254721Semaste 41314564Sdimuint32_t UnwindLLDB::DoGetFrameCount() { 42314564Sdim if (!m_unwind_complete) { 43254721Semaste//#define DEBUG_FRAME_SPEED 1 44254721Semaste#if DEBUG_FRAME_SPEED 45254721Semaste#define FRAME_COUNT 10000 46314564Sdim using namespace std::chrono; 47314564Sdim auto time_value = steady_clock::now(); 48254721Semaste#endif 49314564Sdim if (!AddFirstFrame()) 50314564Sdim return 0; 51254721Semaste 52314564Sdim ProcessSP process_sp(m_thread.GetProcess()); 53353358Sdim ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr; 54254721Semaste 55314564Sdim while (AddOneMoreFrame(abi)) { 56254721Semaste#if DEBUG_FRAME_SPEED 57314564Sdim if ((m_frames.size() % FRAME_COUNT) == 0) { 58314564Sdim const auto now = steady_clock::now(); 59314564Sdim const auto delta_t = now - time_value; 60314564Sdim printf("%u frames in %.9f ms (%g frames/sec)\n", FRAME_COUNT, 61314564Sdim duration<double, std::milli>(delta_t).count(), 62314564Sdim (float)FRAME_COUNT / duration<double>(delta_t).count()); 63314564Sdim time_value = now; 64314564Sdim } 65254721Semaste#endif 66254721Semaste } 67314564Sdim } 68314564Sdim return m_frames.size(); 69254721Semaste} 70254721Semaste 71314564Sdimbool UnwindLLDB::AddFirstFrame() { 72314564Sdim if (m_frames.size() > 0) 73314564Sdim return true; 74296417Sdim 75314564Sdim ProcessSP process_sp(m_thread.GetProcess()); 76353358Sdim ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr; 77254721Semaste 78314564Sdim // First, set up the 0th (initial) frame 79314564Sdim CursorSP first_cursor_sp(new Cursor()); 80314564Sdim RegisterContextLLDBSP reg_ctx_sp(new RegisterContextLLDB( 81314564Sdim m_thread, RegisterContextLLDBSP(), first_cursor_sp->sctx, 0, *this)); 82353358Sdim if (reg_ctx_sp.get() == nullptr) 83314564Sdim goto unwind_done; 84254721Semaste 85314564Sdim if (!reg_ctx_sp->IsValid()) 86314564Sdim goto unwind_done; 87254721Semaste 88314564Sdim if (!reg_ctx_sp->GetCFA(first_cursor_sp->cfa)) 89314564Sdim goto unwind_done; 90296417Sdim 91314564Sdim if (!reg_ctx_sp->ReadPC(first_cursor_sp->start_pc)) 92314564Sdim goto unwind_done; 93296417Sdim 94314564Sdim // Everything checks out, so release the auto pointer value and let the 95314564Sdim // cursor own it in its shared pointer 96314564Sdim first_cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp; 97314564Sdim m_frames.push_back(first_cursor_sp); 98262528Semaste 99314564Sdim // Update the Full Unwind Plan for this frame if not valid 100314564Sdim UpdateUnwindPlanForFirstFrameIfInvalid(abi); 101314564Sdim 102314564Sdim return true; 103314564Sdim 104254721Semasteunwind_done: 105314564Sdim Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); 106314564Sdim if (log) { 107360784Sdim LLDB_LOGF(log, "th%d Unwind of this thread is complete.", 108360784Sdim m_thread.GetIndexID()); 109314564Sdim } 110314564Sdim m_unwind_complete = true; 111314564Sdim return false; 112254721Semaste} 113254721Semaste 114314564SdimUnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) { 115314564Sdim assert(m_frames.size() != 0 && 116314564Sdim "Get one more frame called with empty frame list"); 117288943Sdim 118314564Sdim // If we've already gotten to the end of the stack, don't bother to try 119314564Sdim // again... 120314564Sdim if (m_unwind_complete) 121314564Sdim return nullptr; 122254721Semaste 123314564Sdim Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); 124254721Semaste 125314564Sdim CursorSP prev_frame = m_frames.back(); 126314564Sdim uint32_t cur_idx = m_frames.size(); 127254721Semaste 128314564Sdim CursorSP cursor_sp(new Cursor()); 129314564Sdim RegisterContextLLDBSP reg_ctx_sp(new RegisterContextLLDB( 130314564Sdim m_thread, prev_frame->reg_ctx_lldb_sp, cursor_sp->sctx, cur_idx, *this)); 131254721Semaste 132344779Sdim uint64_t max_stack_depth = m_thread.GetMaxBacktraceDepth(); 133344779Sdim 134314564Sdim // We want to detect an unwind that cycles erroneously and stop backtracing. 135314564Sdim // Don't want this maximum unwind limit to be too low -- if you have a 136341825Sdim // backtrace with an "infinitely recursing" bug, it will crash when the stack 137341825Sdim // blows out and the first 35,000 frames are uninteresting - it's the top 138341825Sdim // most 5 frames that you actually care about. So you can't just cap the 139341825Sdim // unwind at 10,000 or something. Realistically anything over around 200,000 140341825Sdim // is going to blow out the stack space. If we're still unwinding at that 141341825Sdim // point, we're probably never going to finish. 142344779Sdim if (cur_idx >= max_stack_depth) { 143360784Sdim LLDB_LOGF(log, 144360784Sdim "%*sFrame %d unwound too many frames, assuming unwind has " 145360784Sdim "gone astray, stopping.", 146360784Sdim cur_idx < 100 ? cur_idx : 100, "", cur_idx); 147314564Sdim return nullptr; 148314564Sdim } 149296417Sdim 150353358Sdim if (reg_ctx_sp.get() == nullptr) { 151314564Sdim // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to 152341825Sdim // that and return true. Subsequent calls to TryFallbackUnwindPlan() will 153341825Sdim // return false. 154314564Sdim if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { 155314564Sdim // TryFallbackUnwindPlan for prev_frame succeeded and updated 156341825Sdim // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame 157341825Sdim // still needs to be updated. Hence updating it. 158314564Sdim if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) 159314564Sdim return nullptr; 160288943Sdim 161314564Sdim return GetOneMoreFrame(abi); 162262528Semaste } 163254721Semaste 164360784Sdim LLDB_LOGF(log, "%*sFrame %d did not get a RegisterContext, stopping.", 165360784Sdim cur_idx < 100 ? cur_idx : 100, "", cur_idx); 166314564Sdim return nullptr; 167314564Sdim } 168296417Sdim 169314564Sdim if (!reg_ctx_sp->IsValid()) { 170341825Sdim // We failed to get a valid RegisterContext. See if the regctx below this 171341825Sdim // on the stack has a fallback unwind plan it can use. Subsequent calls to 172341825Sdim // TryFallbackUnwindPlan() will return false. 173314564Sdim if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { 174314564Sdim // TryFallbackUnwindPlan for prev_frame succeeded and updated 175341825Sdim // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame 176341825Sdim // still needs to be updated. Hence updating it. 177314564Sdim if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) 178314564Sdim return nullptr; 179288943Sdim 180314564Sdim return GetOneMoreFrame(abi); 181254721Semaste } 182296417Sdim 183360784Sdim LLDB_LOGF(log, 184360784Sdim "%*sFrame %d invalid RegisterContext for this frame, " 185360784Sdim "stopping stack walk", 186360784Sdim cur_idx < 100 ? cur_idx : 100, "", cur_idx); 187314564Sdim return nullptr; 188314564Sdim } 189314564Sdim if (!reg_ctx_sp->GetCFA(cursor_sp->cfa)) { 190314564Sdim // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to 191341825Sdim // that and return true. Subsequent calls to TryFallbackUnwindPlan() will 192341825Sdim // return false. 193314564Sdim if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { 194314564Sdim // TryFallbackUnwindPlan for prev_frame succeeded and updated 195341825Sdim // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame 196341825Sdim // still needs to be updated. Hence updating it. 197314564Sdim if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) 198314564Sdim return nullptr; 199288943Sdim 200314564Sdim return GetOneMoreFrame(abi); 201254721Semaste } 202296417Sdim 203360784Sdim LLDB_LOGF(log, 204360784Sdim "%*sFrame %d did not get CFA for this frame, stopping stack walk", 205360784Sdim cur_idx < 100 ? cur_idx : 100, "", cur_idx); 206314564Sdim return nullptr; 207314564Sdim } 208314564Sdim if (abi && !abi->CallFrameAddressIsValid(cursor_sp->cfa)) { 209314564Sdim // On Mac OS X, the _sigtramp asynchronous signal trampoline frame may not 210341825Sdim // have its (constructed) CFA aligned correctly -- don't do the abi 211341825Sdim // alignment check for these. 212344779Sdim if (!reg_ctx_sp->IsTrapHandlerFrame()) { 213314564Sdim // See if we can find a fallback unwind plan for THIS frame. It may be 214314564Sdim // that the UnwindPlan we're using for THIS frame was bad and gave us a 215341825Sdim // bad CFA. If that's not it, then see if we can change the UnwindPlan 216341825Sdim // for the frame below us ("NEXT") -- see if using that other UnwindPlan 217341825Sdim // gets us a better unwind state. 218344779Sdim if (!reg_ctx_sp->TryFallbackUnwindPlan() || 219344779Sdim !reg_ctx_sp->GetCFA(cursor_sp->cfa) || 220344779Sdim !abi->CallFrameAddressIsValid(cursor_sp->cfa)) { 221314564Sdim if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { 222314564Sdim // TryFallbackUnwindPlan for prev_frame succeeded and updated 223341825Sdim // reg_ctx_lldb_sp field of prev_frame. However, cfa field of 224341825Sdim // prev_frame still needs to be updated. Hence updating it. 225314564Sdim if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) 226314564Sdim return nullptr; 227288943Sdim 228314564Sdim return GetOneMoreFrame(abi); 229254721Semaste } 230296417Sdim 231360784Sdim LLDB_LOGF(log, 232360784Sdim "%*sFrame %d did not get a valid CFA for this frame, " 233360784Sdim "stopping stack walk", 234360784Sdim cur_idx < 100 ? cur_idx : 100, "", cur_idx); 235288943Sdim return nullptr; 236314564Sdim } else { 237360784Sdim LLDB_LOGF(log, 238360784Sdim "%*sFrame %d had a bad CFA value but we switched the " 239360784Sdim "UnwindPlan being used and got one that looks more " 240360784Sdim "realistic.", 241360784Sdim cur_idx < 100 ? cur_idx : 100, "", cur_idx); 242314564Sdim } 243254721Semaste } 244314564Sdim } 245314564Sdim if (!reg_ctx_sp->ReadPC(cursor_sp->start_pc)) { 246314564Sdim // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to 247341825Sdim // that and return true. Subsequent calls to TryFallbackUnwindPlan() will 248341825Sdim // return false. 249314564Sdim if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { 250314564Sdim // TryFallbackUnwindPlan for prev_frame succeeded and updated 251341825Sdim // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame 252341825Sdim // still needs to be updated. Hence updating it. 253314564Sdim if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) 254314564Sdim return nullptr; 255296417Sdim 256314564Sdim return GetOneMoreFrame(abi); 257314564Sdim } 258288943Sdim 259360784Sdim LLDB_LOGF(log, 260360784Sdim "%*sFrame %d did not get PC for this frame, stopping stack walk", 261360784Sdim cur_idx < 100 ? cur_idx : 100, "", cur_idx); 262314564Sdim return nullptr; 263314564Sdim } 264314564Sdim if (abi && !abi->CodeAddressIsValid(cursor_sp->start_pc)) { 265314564Sdim // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to 266341825Sdim // that and return true. Subsequent calls to TryFallbackUnwindPlan() will 267341825Sdim // return false. 268314564Sdim if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { 269314564Sdim // TryFallbackUnwindPlan for prev_frame succeeded and updated 270341825Sdim // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame 271341825Sdim // still needs to be updated. Hence updating it. 272314564Sdim if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) 273288943Sdim return nullptr; 274314564Sdim 275314564Sdim return GetOneMoreFrame(abi); 276254721Semaste } 277258054Semaste 278360784Sdim LLDB_LOGF(log, "%*sFrame %d did not get a valid PC, stopping stack walk", 279360784Sdim cur_idx < 100 ? cur_idx : 100, "", cur_idx); 280314564Sdim return nullptr; 281314564Sdim } 282314564Sdim // Infinite loop where the current cursor is the same as the previous one... 283314564Sdim if (prev_frame->start_pc == cursor_sp->start_pc && 284314564Sdim prev_frame->cfa == cursor_sp->cfa) { 285360784Sdim LLDB_LOGF(log, 286360784Sdim "th%d pc of this frame is the same as the previous frame and " 287360784Sdim "CFAs for both frames are identical -- stopping unwind", 288360784Sdim m_thread.GetIndexID()); 289314564Sdim return nullptr; 290314564Sdim } 291314564Sdim 292314564Sdim cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp; 293314564Sdim return cursor_sp; 294288943Sdim} 295288943Sdim 296314564Sdimvoid UnwindLLDB::UpdateUnwindPlanForFirstFrameIfInvalid(ABI *abi) { 297314564Sdim // This function is called for First Frame only. 298314564Sdim assert(m_frames.size() == 1 && "No. of cursor frames are not 1"); 299296417Sdim 300314564Sdim bool old_m_unwind_complete = m_unwind_complete; 301314564Sdim CursorSP old_m_candidate_frame = m_candidate_frame; 302296417Sdim 303314564Sdim // Try to unwind 2 more frames using the Unwinder. It uses Full UnwindPlan 304341825Sdim // and if Full UnwindPlan fails, then uses FallBack UnwindPlan. Also update 305341825Sdim // the cfa of Frame 0 (if required). 306314564Sdim AddOneMoreFrame(abi); 307296417Sdim 308341825Sdim // Remove all the frames added by above function as the purpose of using 309341825Sdim // above function was just to check whether Unwinder of Frame 0 works or not. 310314564Sdim for (uint32_t i = 1; i < m_frames.size(); i++) 311314564Sdim m_frames.pop_back(); 312296417Sdim 313314564Sdim // Restore status after calling AddOneMoreFrame 314314564Sdim m_unwind_complete = old_m_unwind_complete; 315314564Sdim m_candidate_frame = old_m_candidate_frame; 316314564Sdim return; 317296417Sdim} 318296417Sdim 319314564Sdimbool UnwindLLDB::AddOneMoreFrame(ABI *abi) { 320314564Sdim Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); 321296417Sdim 322314564Sdim // Frame zero is a little different 323314564Sdim if (m_frames.empty()) 324314564Sdim return false; 325288943Sdim 326314564Sdim // If we've already gotten to the end of the stack, don't bother to try 327314564Sdim // again... 328314564Sdim if (m_unwind_complete) 329314564Sdim return false; 330288943Sdim 331314564Sdim CursorSP new_frame = m_candidate_frame; 332314564Sdim if (new_frame == nullptr) 333314564Sdim new_frame = GetOneMoreFrame(abi); 334288943Sdim 335314564Sdim if (new_frame == nullptr) { 336360784Sdim LLDB_LOGF(log, "th%d Unwind of this thread is complete.", 337360784Sdim m_thread.GetIndexID()); 338314564Sdim m_unwind_complete = true; 339314564Sdim return false; 340314564Sdim } 341288943Sdim 342314564Sdim m_frames.push_back(new_frame); 343288943Sdim 344341825Sdim // If we can get one more frame further then accept that we get back a 345341825Sdim // correct frame. 346314564Sdim m_candidate_frame = GetOneMoreFrame(abi); 347314564Sdim if (m_candidate_frame) 348314564Sdim return true; 349288943Sdim 350314564Sdim // We can't go further from the frame returned by GetOneMore frame. Lets try 351341825Sdim // to get a different frame with using the fallback unwind plan. 352314564Sdim if (!m_frames[m_frames.size() - 2] 353314564Sdim ->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { 354314564Sdim // We don't have a valid fallback unwind plan. Accept the frame as it is. 355341825Sdim // This is a valid situation when we are at the bottom of the stack. 356314564Sdim return true; 357314564Sdim } 358288943Sdim 359314564Sdim // Remove the possibly incorrect frame from the frame list and try to add a 360341825Sdim // different one with the newly selected fallback unwind plan. 361314564Sdim m_frames.pop_back(); 362314564Sdim CursorSP new_frame_v2 = GetOneMoreFrame(abi); 363314564Sdim if (new_frame_v2 == nullptr) { 364314564Sdim // We haven't got a new frame from the fallback unwind plan. Accept the 365341825Sdim // frame from the original unwind plan. This is a valid situation when we 366341825Sdim // are at the bottom of the stack. 367314564Sdim m_frames.push_back(new_frame); 368314564Sdim return true; 369314564Sdim } 370288943Sdim 371314564Sdim // Push the new frame to the list and try to continue from this frame. If we 372341825Sdim // can get a new frame then accept it as the correct one. 373314564Sdim m_frames.push_back(new_frame_v2); 374314564Sdim m_candidate_frame = GetOneMoreFrame(abi); 375314564Sdim if (m_candidate_frame) { 376314564Sdim // If control reached here then TryFallbackUnwindPlan had succeeded for 377341825Sdim // Cursor::m_frames[m_frames.size() - 2]. It also succeeded to Unwind next 378341825Sdim // 2 frames i.e. m_frames[m_frames.size() - 1] and a frame after that. For 379341825Sdim // Cursor::m_frames[m_frames.size() - 2], reg_ctx_lldb_sp field was already 380341825Sdim // updated during TryFallbackUnwindPlan call above. However, cfa field 381341825Sdim // still needs to be updated. Hence updating it here and then returning. 382344779Sdim return m_frames[m_frames.size() - 2]->reg_ctx_lldb_sp->GetCFA( 383344779Sdim m_frames[m_frames.size() - 2]->cfa); 384314564Sdim } 385288943Sdim 386314564Sdim // The new frame hasn't helped in unwinding. Fall back to the original one as 387341825Sdim // the default unwind plan is usually more reliable then the fallback one. 388314564Sdim m_frames.pop_back(); 389314564Sdim m_frames.push_back(new_frame); 390314564Sdim return true; 391254721Semaste} 392254721Semaste 393360784Sdimbool UnwindLLDB::DoGetFrameInfoAtIndex(uint32_t idx, addr_t &cfa, addr_t &pc, 394360784Sdim bool &behaves_like_zeroth_frame) { 395314564Sdim if (m_frames.size() == 0) { 396314564Sdim if (!AddFirstFrame()) 397314564Sdim return false; 398314564Sdim } 399254721Semaste 400314564Sdim ProcessSP process_sp(m_thread.GetProcess()); 401353358Sdim ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr; 402254721Semaste 403314564Sdim while (idx >= m_frames.size() && AddOneMoreFrame(abi)) 404314564Sdim ; 405254721Semaste 406314564Sdim if (idx < m_frames.size()) { 407314564Sdim cfa = m_frames[idx]->cfa; 408314564Sdim pc = m_frames[idx]->start_pc; 409360784Sdim if (idx == 0) { 410360784Sdim // Frame zero always behaves like it. 411360784Sdim behaves_like_zeroth_frame = true; 412360784Sdim } else if (m_frames[idx - 1]->reg_ctx_lldb_sp->IsTrapHandlerFrame()) { 413360784Sdim // This could be an asynchronous signal, thus the 414360784Sdim // pc might point to the interrupted instruction rather 415360784Sdim // than a post-call instruction 416360784Sdim behaves_like_zeroth_frame = true; 417360784Sdim } else if (m_frames[idx]->reg_ctx_lldb_sp->IsTrapHandlerFrame()) { 418360784Sdim // This frame may result from signal processing installing 419360784Sdim // a pointer to the first byte of a signal-return trampoline 420360784Sdim // in the return address slot of the frame below, so this 421360784Sdim // too behaves like the zeroth frame (i.e. the pc might not 422360784Sdim // be pointing just past a call in it) 423360784Sdim behaves_like_zeroth_frame = true; 424360784Sdim } else { 425360784Sdim behaves_like_zeroth_frame = false; 426360784Sdim } 427314564Sdim return true; 428314564Sdim } 429314564Sdim return false; 430254721Semaste} 431254721Semaste 432254721Semastelldb::RegisterContextSP 433314564SdimUnwindLLDB::DoCreateRegisterContextForFrame(StackFrame *frame) { 434314564Sdim lldb::RegisterContextSP reg_ctx_sp; 435314564Sdim uint32_t idx = frame->GetConcreteFrameIndex(); 436254721Semaste 437314564Sdim if (idx == 0) { 438314564Sdim return m_thread.GetRegisterContext(); 439314564Sdim } 440254721Semaste 441314564Sdim if (m_frames.size() == 0) { 442314564Sdim if (!AddFirstFrame()) 443314564Sdim return reg_ctx_sp; 444314564Sdim } 445254721Semaste 446314564Sdim ProcessSP process_sp(m_thread.GetProcess()); 447353358Sdim ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr; 448254721Semaste 449314564Sdim while (idx >= m_frames.size()) { 450314564Sdim if (!AddOneMoreFrame(abi)) 451314564Sdim break; 452314564Sdim } 453254721Semaste 454314564Sdim const uint32_t num_frames = m_frames.size(); 455314564Sdim if (idx < num_frames) { 456314564Sdim Cursor *frame_cursor = m_frames[idx].get(); 457314564Sdim reg_ctx_sp = frame_cursor->reg_ctx_lldb_sp; 458314564Sdim } 459314564Sdim return reg_ctx_sp; 460254721Semaste} 461254721Semaste 462254721SemasteUnwindLLDB::RegisterContextLLDBSP 463314564SdimUnwindLLDB::GetRegisterContextForFrameNum(uint32_t frame_num) { 464314564Sdim RegisterContextLLDBSP reg_ctx_sp; 465314564Sdim if (frame_num < m_frames.size()) 466314564Sdim reg_ctx_sp = m_frames[frame_num]->reg_ctx_lldb_sp; 467314564Sdim return reg_ctx_sp; 468254721Semaste} 469254721Semaste 470314564Sdimbool UnwindLLDB::SearchForSavedLocationForRegister( 471314564Sdim uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation ®loc, 472314564Sdim uint32_t starting_frame_num, bool pc_reg) { 473314564Sdim int64_t frame_num = starting_frame_num; 474314564Sdim if (static_cast<size_t>(frame_num) >= m_frames.size()) 475314564Sdim return false; 476254721Semaste 477341825Sdim // Never interrogate more than one level while looking for the saved pc 478341825Sdim // value. If the value isn't saved by frame_num, none of the frames lower on 479341825Sdim // the stack will have a useful value. 480314564Sdim if (pc_reg) { 481314564Sdim UnwindLLDB::RegisterSearchResult result; 482314564Sdim result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister( 483314564Sdim lldb_regnum, regloc); 484344779Sdim return result == UnwindLLDB::RegisterSearchResult::eRegisterFound; 485314564Sdim } 486314564Sdim while (frame_num >= 0) { 487314564Sdim UnwindLLDB::RegisterSearchResult result; 488314564Sdim result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister( 489314564Sdim lldb_regnum, regloc); 490314564Sdim 491314564Sdim // We descended down to the live register context aka stack frame 0 and are 492341825Sdim // reading the value out of a live register. 493314564Sdim if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound && 494314564Sdim regloc.type == 495314564Sdim UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext) { 496314564Sdim return true; 497254721Semaste } 498254721Semaste 499314564Sdim // If we have unwind instructions saying that register N is saved in 500341825Sdim // register M in the middle of the stack (and N can equal M here, meaning 501341825Sdim // the register was not used in this function), then change the register 502341825Sdim // number we're looking for to M and keep looking for a concrete location 503314564Sdim // down the stack, or an actual value from a live RegisterContext at frame 504314564Sdim // 0. 505314564Sdim if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound && 506314564Sdim regloc.type == UnwindLLDB::RegisterLocation::eRegisterInRegister && 507314564Sdim frame_num > 0) { 508314564Sdim result = UnwindLLDB::RegisterSearchResult::eRegisterNotFound; 509314564Sdim lldb_regnum = regloc.location.register_number; 510314564Sdim } 511280031Sdim 512314564Sdim if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound) 513314564Sdim return true; 514314564Sdim if (result == UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile) 515314564Sdim return false; 516314564Sdim frame_num--; 517314564Sdim } 518314564Sdim return false; 519254721Semaste} 520