diff options
-rw-r--r-- | lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp index 8eb4c612bdf..5382489aa6a 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp @@ -978,12 +978,14 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat UnwindPlan::RowSP active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset); unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind (); uint32_t row_regnum; + bool row_register_rewritten_to_return_address_reg = false; // If we're fetching the saved pc and this UnwindPlan defines a ReturnAddress register (e.g. lr on arm), // look for the return address register number in the UnwindPlan's row. if (lldb_regnum == pc_regnum && m_full_unwind_plan_sp->GetReturnAddressRegister() != LLDB_INVALID_REGNUM) { row_regnum = m_full_unwind_plan_sp->GetReturnAddressRegister(); + row_register_rewritten_to_return_address_reg = true; UnwindLogMsg ("requested caller's saved PC but this UnwindPlan uses a RA reg; getting reg %d instead", row_regnum); } @@ -1007,6 +1009,28 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat m_full_unwind_plan_sp->GetSourceName().GetCString()); } + // This is frame 0 and we're retrieving the PC and it's saved in a Return Address register and + // it hasn't been saved anywhere yet -- that is, it's still live in the actual register. + // Handle this specially. + + if (have_unwindplan_regloc == false + && row_register_rewritten_to_return_address_reg == true + && IsFrameZero() + && row_regnum != LLDB_INVALID_REGNUM) + { + uint32_t ra_regnum_in_lldb_reg_numbering; + if (m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (unwindplan_registerkind, row_regnum, eRegisterKindLLDB, ra_regnum_in_lldb_reg_numbering)) + { + lldb_private::UnwindLLDB::RegisterLocation new_regloc; + new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister; + new_regloc.location.register_number = ra_regnum_in_lldb_reg_numbering; + m_registers[lldb_regnum] = new_regloc; + regloc = new_regloc; + UnwindLogMsg ("supplying caller's register %d from the live RegisterContext at frame 0, saved in %d", lldb_regnum, ra_regnum_in_lldb_reg_numbering); + return UnwindLLDB::RegisterSearchResult::eRegisterFound; + } + } + // If this architecture stores the return address in a register (it defines a Return Address register) // and we're on a non-zero stack frame and the Full UnwindPlan says that the pc is stored in the // RA registers (e.g. lr on arm), then we know that the full unwindplan is not trustworthy -- this |