UnwindLLDB.cpp revision 321369
1254721Semaste//===-- UnwindLLDB.cpp -------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/Core/Module.h" 11254721Semaste#include "lldb/Symbol/FuncUnwinders.h" 12254721Semaste#include "lldb/Symbol/Function.h" 13254721Semaste#include "lldb/Symbol/UnwindPlan.h" 14288943Sdim#include "lldb/Target/ABI.h" 15254721Semaste#include "lldb/Target/Process.h" 16254721Semaste#include "lldb/Target/RegisterContext.h" 17314564Sdim#include "lldb/Target/Target.h" 18314564Sdim#include "lldb/Target/Thread.h" 19321369Sdim#include "lldb/Utility/Log.h" 20254721Semaste 21314564Sdim#include "RegisterContextLLDB.h" 22254721Semaste#include "UnwindLLDB.h" 23254721Semaste 24254721Semasteusing namespace lldb; 25254721Semasteusing namespace lldb_private; 26254721Semaste 27314564SdimUnwindLLDB::UnwindLLDB(Thread &thread) 28314564Sdim : Unwind(thread), m_frames(), m_unwind_complete(false), 29314564Sdim m_user_supplied_trap_handler_functions() { 30314564Sdim ProcessSP process_sp(thread.GetProcess()); 31314564Sdim if (process_sp) { 32314564Sdim Args args; 33314564Sdim process_sp->GetTarget().GetUserSpecifiedTrapHandlerNames(args); 34314564Sdim size_t count = args.GetArgumentCount(); 35314564Sdim for (size_t i = 0; i < count; i++) { 36314564Sdim const char *func_name = args.GetArgumentAtIndex(i); 37314564Sdim m_user_supplied_trap_handler_functions.push_back(ConstString(func_name)); 38262528Semaste } 39314564Sdim } 40254721Semaste} 41254721Semaste 42314564Sdimuint32_t UnwindLLDB::DoGetFrameCount() { 43314564Sdim if (!m_unwind_complete) { 44254721Semaste//#define DEBUG_FRAME_SPEED 1 45254721Semaste#if DEBUG_FRAME_SPEED 46254721Semaste#define FRAME_COUNT 10000 47314564Sdim using namespace std::chrono; 48314564Sdim auto time_value = steady_clock::now(); 49254721Semaste#endif 50314564Sdim if (!AddFirstFrame()) 51314564Sdim return 0; 52254721Semaste 53314564Sdim ProcessSP process_sp(m_thread.GetProcess()); 54314564Sdim ABI *abi = process_sp ? process_sp->GetABI().get() : NULL; 55254721Semaste 56314564Sdim while (AddOneMoreFrame(abi)) { 57254721Semaste#if DEBUG_FRAME_SPEED 58314564Sdim if ((m_frames.size() % FRAME_COUNT) == 0) { 59314564Sdim const auto now = steady_clock::now(); 60314564Sdim const auto delta_t = now - time_value; 61314564Sdim printf("%u frames in %.9f ms (%g frames/sec)\n", FRAME_COUNT, 62314564Sdim duration<double, std::milli>(delta_t).count(), 63314564Sdim (float)FRAME_COUNT / duration<double>(delta_t).count()); 64314564Sdim time_value = now; 65314564Sdim } 66254721Semaste#endif 67254721Semaste } 68314564Sdim } 69314564Sdim return m_frames.size(); 70254721Semaste} 71254721Semaste 72314564Sdimbool UnwindLLDB::AddFirstFrame() { 73314564Sdim if (m_frames.size() > 0) 74314564Sdim return true; 75296417Sdim 76314564Sdim ProcessSP process_sp(m_thread.GetProcess()); 77314564Sdim ABI *abi = process_sp ? process_sp->GetABI().get() : NULL; 78254721Semaste 79314564Sdim // First, set up the 0th (initial) frame 80314564Sdim CursorSP first_cursor_sp(new Cursor()); 81314564Sdim RegisterContextLLDBSP reg_ctx_sp(new RegisterContextLLDB( 82314564Sdim m_thread, RegisterContextLLDBSP(), first_cursor_sp->sctx, 0, *this)); 83314564Sdim if (reg_ctx_sp.get() == NULL) 84314564Sdim goto unwind_done; 85254721Semaste 86314564Sdim if (!reg_ctx_sp->IsValid()) 87314564Sdim goto unwind_done; 88254721Semaste 89314564Sdim if (!reg_ctx_sp->GetCFA(first_cursor_sp->cfa)) 90314564Sdim goto unwind_done; 91296417Sdim 92314564Sdim if (!reg_ctx_sp->ReadPC(first_cursor_sp->start_pc)) 93314564Sdim goto unwind_done; 94296417Sdim 95314564Sdim // Everything checks out, so release the auto pointer value and let the 96314564Sdim // cursor own it in its shared pointer 97314564Sdim first_cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp; 98314564Sdim m_frames.push_back(first_cursor_sp); 99262528Semaste 100314564Sdim // Update the Full Unwind Plan for this frame if not valid 101314564Sdim UpdateUnwindPlanForFirstFrameIfInvalid(abi); 102314564Sdim 103314564Sdim return true; 104314564Sdim 105254721Semasteunwind_done: 106314564Sdim Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); 107314564Sdim if (log) { 108314564Sdim log->Printf("th%d Unwind of this thread is complete.", 109314564Sdim m_thread.GetIndexID()); 110314564Sdim } 111314564Sdim m_unwind_complete = true; 112314564Sdim return false; 113254721Semaste} 114254721Semaste 115314564SdimUnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) { 116314564Sdim assert(m_frames.size() != 0 && 117314564Sdim "Get one more frame called with empty frame list"); 118288943Sdim 119314564Sdim // If we've already gotten to the end of the stack, don't bother to try 120314564Sdim // again... 121314564Sdim if (m_unwind_complete) 122314564Sdim return nullptr; 123254721Semaste 124314564Sdim Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); 125254721Semaste 126314564Sdim CursorSP prev_frame = m_frames.back(); 127314564Sdim uint32_t cur_idx = m_frames.size(); 128254721Semaste 129314564Sdim CursorSP cursor_sp(new Cursor()); 130314564Sdim RegisterContextLLDBSP reg_ctx_sp(new RegisterContextLLDB( 131314564Sdim m_thread, prev_frame->reg_ctx_lldb_sp, cursor_sp->sctx, cur_idx, *this)); 132254721Semaste 133314564Sdim // We want to detect an unwind that cycles erroneously and stop backtracing. 134314564Sdim // Don't want this maximum unwind limit to be too low -- if you have a 135314564Sdim // backtrace 136314564Sdim // with an "infinitely recursing" bug, it will crash when the stack blows out 137314564Sdim // and the first 35,000 frames are uninteresting - it's the top most 5 frames 138314564Sdim // that 139314564Sdim // you actually care about. So you can't just cap the unwind at 10,000 or 140314564Sdim // something. 141314564Sdim // Realistically anything over around 200,000 is going to blow out the stack 142314564Sdim // space. 143314564Sdim // If we're still unwinding at that point, we're probably never going to 144314564Sdim // finish. 145314564Sdim if (cur_idx > 300000) { 146314564Sdim if (log) 147314564Sdim log->Printf("%*sFrame %d unwound too many frames, assuming unwind has " 148314564Sdim "gone astray, stopping.", 149314564Sdim cur_idx < 100 ? cur_idx : 100, "", cur_idx); 150314564Sdim return nullptr; 151314564Sdim } 152296417Sdim 153314564Sdim if (reg_ctx_sp.get() == NULL) { 154314564Sdim // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to 155314564Sdim // that and return 156314564Sdim // true. Subsequent calls to TryFallbackUnwindPlan() will return false. 157314564Sdim if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { 158314564Sdim // TryFallbackUnwindPlan for prev_frame succeeded and updated 159314564Sdim // reg_ctx_lldb_sp field of 160314564Sdim // prev_frame. However, cfa field of prev_frame still needs to be updated. 161314564Sdim // Hence updating it. 162314564Sdim if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) 163314564Sdim return nullptr; 164288943Sdim 165314564Sdim return GetOneMoreFrame(abi); 166262528Semaste } 167254721Semaste 168314564Sdim if (log) 169314564Sdim log->Printf("%*sFrame %d did not get a RegisterContext, stopping.", 170314564Sdim cur_idx < 100 ? cur_idx : 100, "", cur_idx); 171314564Sdim return nullptr; 172314564Sdim } 173296417Sdim 174314564Sdim if (!reg_ctx_sp->IsValid()) { 175314564Sdim // We failed to get a valid RegisterContext. 176314564Sdim // See if the regctx below this on the stack has a fallback unwind plan it 177314564Sdim // can use. 178314564Sdim // Subsequent calls to TryFallbackUnwindPlan() will return false. 179314564Sdim if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { 180314564Sdim // TryFallbackUnwindPlan for prev_frame succeeded and updated 181314564Sdim // reg_ctx_lldb_sp field of 182314564Sdim // prev_frame. However, cfa field of prev_frame still needs to be updated. 183314564Sdim // Hence updating it. 184314564Sdim if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) 185314564Sdim return nullptr; 186288943Sdim 187314564Sdim return GetOneMoreFrame(abi); 188254721Semaste } 189296417Sdim 190314564Sdim if (log) 191314564Sdim log->Printf("%*sFrame %d invalid RegisterContext for this frame, " 192314564Sdim "stopping stack walk", 193314564Sdim cur_idx < 100 ? cur_idx : 100, "", cur_idx); 194314564Sdim return nullptr; 195314564Sdim } 196314564Sdim if (!reg_ctx_sp->GetCFA(cursor_sp->cfa)) { 197314564Sdim // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to 198314564Sdim // that and return 199314564Sdim // true. Subsequent calls to TryFallbackUnwindPlan() will return false. 200314564Sdim if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { 201314564Sdim // TryFallbackUnwindPlan for prev_frame succeeded and updated 202314564Sdim // reg_ctx_lldb_sp field of 203314564Sdim // prev_frame. However, cfa field of prev_frame still needs to be updated. 204314564Sdim // Hence updating it. 205314564Sdim if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) 206314564Sdim return nullptr; 207288943Sdim 208314564Sdim return GetOneMoreFrame(abi); 209254721Semaste } 210296417Sdim 211314564Sdim if (log) 212314564Sdim log->Printf( 213314564Sdim "%*sFrame %d did not get CFA for this frame, stopping stack walk", 214314564Sdim cur_idx < 100 ? cur_idx : 100, "", cur_idx); 215314564Sdim return nullptr; 216314564Sdim } 217314564Sdim if (abi && !abi->CallFrameAddressIsValid(cursor_sp->cfa)) { 218314564Sdim // On Mac OS X, the _sigtramp asynchronous signal trampoline frame may not 219314564Sdim // have 220314564Sdim // its (constructed) CFA aligned correctly -- don't do the abi alignment 221314564Sdim // check for 222314564Sdim // these. 223314564Sdim if (reg_ctx_sp->IsTrapHandlerFrame() == false) { 224314564Sdim // See if we can find a fallback unwind plan for THIS frame. It may be 225314564Sdim // that the UnwindPlan we're using for THIS frame was bad and gave us a 226314564Sdim // bad CFA. 227314564Sdim // If that's not it, then see if we can change the UnwindPlan for the 228314564Sdim // frame 229314564Sdim // below us ("NEXT") -- see if using that other UnwindPlan gets us a 230314564Sdim // better 231314564Sdim // unwind state. 232314564Sdim if (reg_ctx_sp->TryFallbackUnwindPlan() == false || 233314564Sdim reg_ctx_sp->GetCFA(cursor_sp->cfa) == false || 234314564Sdim abi->CallFrameAddressIsValid(cursor_sp->cfa) == false) { 235314564Sdim if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { 236314564Sdim // TryFallbackUnwindPlan for prev_frame succeeded and updated 237314564Sdim // reg_ctx_lldb_sp field of 238314564Sdim // prev_frame. However, cfa field of prev_frame still needs to be 239314564Sdim // updated. Hence updating it. 240314564Sdim if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) 241314564Sdim return nullptr; 242288943Sdim 243314564Sdim return GetOneMoreFrame(abi); 244254721Semaste } 245296417Sdim 246254721Semaste if (log) 247314564Sdim log->Printf("%*sFrame %d did not get a valid CFA for this frame, " 248314564Sdim "stopping stack walk", 249314564Sdim cur_idx < 100 ? cur_idx : 100, "", cur_idx); 250288943Sdim return nullptr; 251314564Sdim } else { 252314564Sdim if (log) 253314564Sdim log->Printf("%*sFrame %d had a bad CFA value but we switched the " 254314564Sdim "UnwindPlan being used and got one that looks more " 255314564Sdim "realistic.", 256314564Sdim cur_idx < 100 ? cur_idx : 100, "", cur_idx); 257314564Sdim } 258254721Semaste } 259314564Sdim } 260314564Sdim if (!reg_ctx_sp->ReadPC(cursor_sp->start_pc)) { 261314564Sdim // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to 262314564Sdim // that and return 263314564Sdim // true. Subsequent calls to TryFallbackUnwindPlan() will return false. 264314564Sdim if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { 265314564Sdim // TryFallbackUnwindPlan for prev_frame succeeded and updated 266314564Sdim // reg_ctx_lldb_sp field of 267314564Sdim // prev_frame. However, cfa field of prev_frame still needs to be updated. 268314564Sdim // Hence updating it. 269314564Sdim if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) 270314564Sdim return nullptr; 271296417Sdim 272314564Sdim return GetOneMoreFrame(abi); 273314564Sdim } 274288943Sdim 275314564Sdim if (log) 276314564Sdim log->Printf( 277314564Sdim "%*sFrame %d did not get PC for this frame, stopping stack walk", 278314564Sdim cur_idx < 100 ? cur_idx : 100, "", cur_idx); 279314564Sdim return nullptr; 280314564Sdim } 281314564Sdim if (abi && !abi->CodeAddressIsValid(cursor_sp->start_pc)) { 282314564Sdim // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to 283314564Sdim // that and return 284314564Sdim // true. Subsequent calls to TryFallbackUnwindPlan() will return false. 285314564Sdim if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { 286314564Sdim // TryFallbackUnwindPlan for prev_frame succeeded and updated 287314564Sdim // reg_ctx_lldb_sp field of 288314564Sdim // prev_frame. However, cfa field of prev_frame still needs to be updated. 289314564Sdim // Hence updating it. 290314564Sdim if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) 291288943Sdim return nullptr; 292314564Sdim 293314564Sdim return GetOneMoreFrame(abi); 294254721Semaste } 295258054Semaste 296314564Sdim if (log) 297314564Sdim log->Printf("%*sFrame %d did not get a valid PC, stopping stack walk", 298314564Sdim cur_idx < 100 ? cur_idx : 100, "", cur_idx); 299314564Sdim return nullptr; 300314564Sdim } 301314564Sdim // Infinite loop where the current cursor is the same as the previous one... 302314564Sdim if (prev_frame->start_pc == cursor_sp->start_pc && 303314564Sdim prev_frame->cfa == cursor_sp->cfa) { 304314564Sdim if (log) 305314564Sdim log->Printf("th%d pc of this frame is the same as the previous frame and " 306314564Sdim "CFAs for both frames are identical -- stopping unwind", 307314564Sdim m_thread.GetIndexID()); 308314564Sdim return nullptr; 309314564Sdim } 310314564Sdim 311314564Sdim cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp; 312314564Sdim return cursor_sp; 313288943Sdim} 314288943Sdim 315314564Sdimvoid UnwindLLDB::UpdateUnwindPlanForFirstFrameIfInvalid(ABI *abi) { 316314564Sdim // This function is called for First Frame only. 317314564Sdim assert(m_frames.size() == 1 && "No. of cursor frames are not 1"); 318296417Sdim 319314564Sdim bool old_m_unwind_complete = m_unwind_complete; 320314564Sdim CursorSP old_m_candidate_frame = m_candidate_frame; 321296417Sdim 322314564Sdim // Try to unwind 2 more frames using the Unwinder. It uses Full UnwindPlan 323314564Sdim // and if Full UnwindPlan fails, then uses FallBack UnwindPlan. Also 324314564Sdim // update the cfa of Frame 0 (if required). 325314564Sdim AddOneMoreFrame(abi); 326296417Sdim 327314564Sdim // Remove all the frames added by above function as the purpose of 328314564Sdim // using above function was just to check whether Unwinder of Frame 0 329314564Sdim // works or not. 330314564Sdim for (uint32_t i = 1; i < m_frames.size(); i++) 331314564Sdim m_frames.pop_back(); 332296417Sdim 333314564Sdim // Restore status after calling AddOneMoreFrame 334314564Sdim m_unwind_complete = old_m_unwind_complete; 335314564Sdim m_candidate_frame = old_m_candidate_frame; 336314564Sdim return; 337296417Sdim} 338296417Sdim 339314564Sdimbool UnwindLLDB::AddOneMoreFrame(ABI *abi) { 340314564Sdim Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); 341296417Sdim 342314564Sdim // Frame zero is a little different 343314564Sdim if (m_frames.empty()) 344314564Sdim return false; 345288943Sdim 346314564Sdim // If we've already gotten to the end of the stack, don't bother to try 347314564Sdim // again... 348314564Sdim if (m_unwind_complete) 349314564Sdim return false; 350288943Sdim 351314564Sdim CursorSP new_frame = m_candidate_frame; 352314564Sdim if (new_frame == nullptr) 353314564Sdim new_frame = GetOneMoreFrame(abi); 354288943Sdim 355314564Sdim if (new_frame == nullptr) { 356314564Sdim if (log) 357314564Sdim log->Printf("th%d Unwind of this thread is complete.", 358314564Sdim m_thread.GetIndexID()); 359314564Sdim m_unwind_complete = true; 360314564Sdim return false; 361314564Sdim } 362288943Sdim 363314564Sdim m_frames.push_back(new_frame); 364288943Sdim 365314564Sdim // If we can get one more frame further then accept that we get back a correct 366314564Sdim // frame. 367314564Sdim m_candidate_frame = GetOneMoreFrame(abi); 368314564Sdim if (m_candidate_frame) 369314564Sdim return true; 370288943Sdim 371314564Sdim // We can't go further from the frame returned by GetOneMore frame. Lets try 372314564Sdim // to get a 373314564Sdim // different frame with using the fallback unwind plan. 374314564Sdim if (!m_frames[m_frames.size() - 2] 375314564Sdim ->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { 376314564Sdim // We don't have a valid fallback unwind plan. Accept the frame as it is. 377314564Sdim // This is a 378314564Sdim // valid situation when we are at the bottom of the stack. 379314564Sdim return true; 380314564Sdim } 381288943Sdim 382314564Sdim // Remove the possibly incorrect frame from the frame list and try to add a 383314564Sdim // different one with 384314564Sdim // the newly selected fallback unwind plan. 385314564Sdim m_frames.pop_back(); 386314564Sdim CursorSP new_frame_v2 = GetOneMoreFrame(abi); 387314564Sdim if (new_frame_v2 == nullptr) { 388314564Sdim // We haven't got a new frame from the fallback unwind plan. Accept the 389314564Sdim // frame from the 390314564Sdim // original unwind plan. This is a valid situation when we are at the bottom 391314564Sdim // of the stack. 392314564Sdim m_frames.push_back(new_frame); 393314564Sdim return true; 394314564Sdim } 395288943Sdim 396314564Sdim // Push the new frame to the list and try to continue from this frame. If we 397314564Sdim // can get a new frame 398314564Sdim // then accept it as the correct one. 399314564Sdim m_frames.push_back(new_frame_v2); 400314564Sdim m_candidate_frame = GetOneMoreFrame(abi); 401314564Sdim if (m_candidate_frame) { 402314564Sdim // If control reached here then TryFallbackUnwindPlan had succeeded for 403314564Sdim // Cursor::m_frames[m_frames.size() - 2]. 404314564Sdim // It also succeeded to Unwind next 2 frames i.e. m_frames[m_frames.size() - 405314564Sdim // 1] and a frame after that. 406314564Sdim // For Cursor::m_frames[m_frames.size() - 2], reg_ctx_lldb_sp field was 407314564Sdim // already updated during TryFallbackUnwindPlan 408314564Sdim // call above. However, cfa field still needs to be updated. Hence updating 409314564Sdim // it here and then returning. 410314564Sdim if (!(m_frames[m_frames.size() - 2]->reg_ctx_lldb_sp->GetCFA( 411314564Sdim m_frames[m_frames.size() - 2]->cfa))) 412314564Sdim return false; 413314564Sdim return true; 414314564Sdim } 415288943Sdim 416314564Sdim // The new frame hasn't helped in unwinding. Fall back to the original one as 417314564Sdim // the default unwind 418314564Sdim // plan is usually more reliable then the fallback one. 419314564Sdim m_frames.pop_back(); 420314564Sdim m_frames.push_back(new_frame); 421314564Sdim return true; 422254721Semaste} 423254721Semaste 424314564Sdimbool UnwindLLDB::DoGetFrameInfoAtIndex(uint32_t idx, addr_t &cfa, addr_t &pc) { 425314564Sdim if (m_frames.size() == 0) { 426314564Sdim if (!AddFirstFrame()) 427314564Sdim return false; 428314564Sdim } 429254721Semaste 430314564Sdim ProcessSP process_sp(m_thread.GetProcess()); 431314564Sdim ABI *abi = process_sp ? process_sp->GetABI().get() : NULL; 432254721Semaste 433314564Sdim while (idx >= m_frames.size() && AddOneMoreFrame(abi)) 434314564Sdim ; 435254721Semaste 436314564Sdim if (idx < m_frames.size()) { 437314564Sdim cfa = m_frames[idx]->cfa; 438314564Sdim pc = m_frames[idx]->start_pc; 439314564Sdim return true; 440314564Sdim } 441314564Sdim return false; 442254721Semaste} 443254721Semaste 444254721Semastelldb::RegisterContextSP 445314564SdimUnwindLLDB::DoCreateRegisterContextForFrame(StackFrame *frame) { 446314564Sdim lldb::RegisterContextSP reg_ctx_sp; 447314564Sdim uint32_t idx = frame->GetConcreteFrameIndex(); 448254721Semaste 449314564Sdim if (idx == 0) { 450314564Sdim return m_thread.GetRegisterContext(); 451314564Sdim } 452254721Semaste 453314564Sdim if (m_frames.size() == 0) { 454314564Sdim if (!AddFirstFrame()) 455314564Sdim return reg_ctx_sp; 456314564Sdim } 457254721Semaste 458314564Sdim ProcessSP process_sp(m_thread.GetProcess()); 459314564Sdim ABI *abi = process_sp ? process_sp->GetABI().get() : NULL; 460254721Semaste 461314564Sdim while (idx >= m_frames.size()) { 462314564Sdim if (!AddOneMoreFrame(abi)) 463314564Sdim break; 464314564Sdim } 465254721Semaste 466314564Sdim const uint32_t num_frames = m_frames.size(); 467314564Sdim if (idx < num_frames) { 468314564Sdim Cursor *frame_cursor = m_frames[idx].get(); 469314564Sdim reg_ctx_sp = frame_cursor->reg_ctx_lldb_sp; 470314564Sdim } 471314564Sdim return reg_ctx_sp; 472254721Semaste} 473254721Semaste 474254721SemasteUnwindLLDB::RegisterContextLLDBSP 475314564SdimUnwindLLDB::GetRegisterContextForFrameNum(uint32_t frame_num) { 476314564Sdim RegisterContextLLDBSP reg_ctx_sp; 477314564Sdim if (frame_num < m_frames.size()) 478314564Sdim reg_ctx_sp = m_frames[frame_num]->reg_ctx_lldb_sp; 479314564Sdim return reg_ctx_sp; 480254721Semaste} 481254721Semaste 482314564Sdimbool UnwindLLDB::SearchForSavedLocationForRegister( 483314564Sdim uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation ®loc, 484314564Sdim uint32_t starting_frame_num, bool pc_reg) { 485314564Sdim int64_t frame_num = starting_frame_num; 486314564Sdim if (static_cast<size_t>(frame_num) >= m_frames.size()) 487314564Sdim return false; 488254721Semaste 489314564Sdim // Never interrogate more than one level while looking for the saved pc value. 490314564Sdim // If the value 491314564Sdim // isn't saved by frame_num, none of the frames lower on the stack will have a 492314564Sdim // useful value. 493314564Sdim if (pc_reg) { 494314564Sdim UnwindLLDB::RegisterSearchResult result; 495314564Sdim result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister( 496314564Sdim lldb_regnum, regloc); 497314564Sdim if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound) 498314564Sdim return true; 499314564Sdim else 500314564Sdim return false; 501314564Sdim } 502314564Sdim while (frame_num >= 0) { 503314564Sdim UnwindLLDB::RegisterSearchResult result; 504314564Sdim result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister( 505314564Sdim lldb_regnum, regloc); 506314564Sdim 507314564Sdim // We descended down to the live register context aka stack frame 0 and are 508314564Sdim // reading the value 509314564Sdim // out of a live register. 510314564Sdim if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound && 511314564Sdim regloc.type == 512314564Sdim UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext) { 513314564Sdim return true; 514254721Semaste } 515254721Semaste 516314564Sdim // If we have unwind instructions saying that register N is saved in 517314564Sdim // register M in the middle of 518314564Sdim // the stack (and N can equal M here, meaning the register was not used in 519314564Sdim // this function), then 520314564Sdim // change the register number we're looking for to M and keep looking for a 521314564Sdim // concrete location 522314564Sdim // down the stack, or an actual value from a live RegisterContext at frame 523314564Sdim // 0. 524314564Sdim if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound && 525314564Sdim regloc.type == UnwindLLDB::RegisterLocation::eRegisterInRegister && 526314564Sdim frame_num > 0) { 527314564Sdim result = UnwindLLDB::RegisterSearchResult::eRegisterNotFound; 528314564Sdim lldb_regnum = regloc.location.register_number; 529314564Sdim } 530280031Sdim 531314564Sdim if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound) 532314564Sdim return true; 533314564Sdim if (result == UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile) 534314564Sdim return false; 535314564Sdim frame_num--; 536314564Sdim } 537314564Sdim return false; 538254721Semaste} 539