[Lldb-commits] [lldb] 0ce7037 - Clear non-addressable bits from pc/fp/sp in unwinds
Jason Molenda via lldb-commits
lldb-commits at lists.llvm.org
Wed Jun 14 13:49:35 PDT 2023
Author: Jason Molenda
Date: 2023-06-14T13:49:26-07:00
New Revision: 0ce7037b5edd0f1937c9d9572ab12528d26091ed
URL: https://github.com/llvm/llvm-project/commit/0ce7037b5edd0f1937c9d9572ab12528d26091ed
DIFF: https://github.com/llvm/llvm-project/commit/0ce7037b5edd0f1937c9d9572ab12528d26091ed.diff
LOG: Clear non-addressable bits from pc/fp/sp in unwinds
Some Darwin corefiles can have the pc/fp/sp/lr in the
live register context signed with pointer authentication;
this patch changes RegisterContextUnwind to strip those
bits off of those values as we try to walk the stack.
Differential Revision: https://reviews.llvm.org/D152861
rdar://109185291
Added:
Modified:
lldb/source/Target/RegisterContextUnwind.cpp
Removed:
################################################################################
diff --git a/lldb/source/Target/RegisterContextUnwind.cpp b/lldb/source/Target/RegisterContextUnwind.cpp
index bf31ebbd858ae..242c7d3f6b945 100644
--- a/lldb/source/Target/RegisterContextUnwind.cpp
+++ b/lldb/source/Target/RegisterContextUnwind.cpp
@@ -137,9 +137,8 @@ void RegisterContextUnwind::InitializeZerothFrame() {
// (which would be a no-op in frame 0 where we get it from the register set,
// but still a good idea to make the call here for other ABIs that may
// exist.)
- ABI *abi = process->GetABI().get();
- if (abi)
- current_pc = abi->FixCodeAddress(current_pc);
+ if (ABISP abi_sp = process->GetABI())
+ current_pc = abi_sp->FixCodeAddress(current_pc);
UnwindPlanSP lang_runtime_plan_sp = LanguageRuntime::GetRuntimeUnwindPlan(
m_thread, this, m_behaves_like_zeroth_frame);
@@ -355,17 +354,23 @@ void RegisterContextUnwind::InitializeNonZerothFrame() {
// Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs
// this will strip bit zero in case we read a PC from memory or from the LR.
- ABI *abi = process->GetABI().get();
- if (abi)
- pc = abi->FixCodeAddress(pc);
+ ABISP abi_sp = process->GetABI();
+ if (abi_sp)
+ pc = abi_sp->FixCodeAddress(pc);
if (log) {
UnwindLogMsg("pc = 0x%" PRIx64, pc);
addr_t reg_val;
- if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP, reg_val))
+ if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP, reg_val)) {
+ if (abi_sp)
+ reg_val = abi_sp->FixDataAddress(reg_val);
UnwindLogMsg("fp = 0x%" PRIx64, reg_val);
- if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, reg_val))
+ }
+ if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, reg_val)) {
+ if (abi_sp)
+ reg_val = abi_sp->FixDataAddress(reg_val);
UnwindLogMsg("sp = 0x%" PRIx64, reg_val);
+ }
}
// A pc of 0x0 means it's the end of the stack crawl unless we're above a trap
@@ -424,11 +429,11 @@ void RegisterContextUnwind::InitializeNonZerothFrame() {
}
}
- if (abi) {
+ if (abi_sp) {
m_fast_unwind_plan_sp.reset();
m_full_unwind_plan_sp =
std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
- abi->CreateDefaultUnwindPlan(*m_full_unwind_plan_sp);
+ abi_sp->CreateDefaultUnwindPlan(*m_full_unwind_plan_sp);
if (m_frame_type != eSkipFrame) // don't override eSkipFrame
{
m_frame_type = eNormalFrame;
@@ -1751,8 +1756,8 @@ bool RegisterContextUnwind::TryFallbackUnwindPlan() {
if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) {
old_caller_pc_value = reg_value.GetAsUInt64();
if (ProcessSP process_sp = m_thread.GetProcess()) {
- if (ABISP abi = process_sp->GetABI())
- old_caller_pc_value = abi->FixCodeAddress(old_caller_pc_value);
+ if (ABISP abi_sp = process_sp->GetABI())
+ old_caller_pc_value = abi_sp->FixCodeAddress(old_caller_pc_value);
}
}
}
@@ -1811,8 +1816,8 @@ bool RegisterContextUnwind::TryFallbackUnwindPlan() {
reg_value)) {
new_caller_pc_value = reg_value.GetAsUInt64();
if (ProcessSP process_sp = m_thread.GetProcess()) {
- if (ABISP abi = process_sp->GetABI())
- new_caller_pc_value = abi->FixCodeAddress(new_caller_pc_value);
+ if (ABISP abi_sp = process_sp->GetABI())
+ new_caller_pc_value = abi_sp->FixCodeAddress(new_caller_pc_value);
}
}
}
@@ -1953,6 +1958,7 @@ bool RegisterContextUnwind::ReadFrameAddress(
address = LLDB_INVALID_ADDRESS;
addr_t cfa_reg_contents;
+ ABISP abi_sp = m_thread.GetProcess()->GetABI();
switch (fa.GetValueType()) {
case UnwindPlan::Row::FAValue::isRegisterDereferenced: {
@@ -1963,11 +1969,13 @@ bool RegisterContextUnwind::ReadFrameAddress(
GetRegisterInfoAtIndex(cfa_reg.GetAsKind(eRegisterKindLLDB));
RegisterValue reg_value;
if (reg_info) {
+ if (abi_sp)
+ cfa_reg_contents = abi_sp->FixDataAddress(cfa_reg_contents);
Status error = ReadRegisterValueFromMemory(
reg_info, cfa_reg_contents, reg_info->byte_size, reg_value);
if (error.Success()) {
address = reg_value.GetAsUInt64();
- if (ABISP abi_sp = m_thread.GetProcess()->GetABI())
+ if (abi_sp)
address = abi_sp->FixCodeAddress(address);
UnwindLogMsg(
"CFA value via dereferencing reg %s (%d): reg has val 0x%" PRIx64
@@ -1989,6 +1997,8 @@ bool RegisterContextUnwind::ReadFrameAddress(
RegisterNumber cfa_reg(m_thread, row_register_kind,
fa.GetRegisterNumber());
if (ReadGPRValue(cfa_reg, cfa_reg_contents)) {
+ if (abi_sp)
+ cfa_reg_contents = abi_sp->FixDataAddress(cfa_reg_contents);
if (cfa_reg_contents == LLDB_INVALID_ADDRESS || cfa_reg_contents == 0 ||
cfa_reg_contents == 1) {
UnwindLogMsg(
@@ -2076,6 +2086,8 @@ lldb::addr_t RegisterContextUnwind::GetReturnAddressHint(int32_t plan_offset) {
return LLDB_INVALID_ADDRESS;
if (!m_sym_ctx.module_sp || !m_sym_ctx.symbol)
return LLDB_INVALID_ADDRESS;
+ if (ABISP abi_sp = m_thread.GetProcess()->GetABI())
+ hint = abi_sp->FixCodeAddress(hint);
hint += plan_offset;
@@ -2133,28 +2145,38 @@ bool RegisterContextUnwind::ReadGPRValue(lldb::RegisterKind register_kind,
return false;
}
+ uint32_t generic_regnum = LLDB_INVALID_REGNUM;
+ if (register_kind == eRegisterKindGeneric)
+ generic_regnum = regnum;
+ else
+ m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds(
+ register_kind, regnum, eRegisterKindGeneric, generic_regnum);
+ ABISP abi_sp = m_thread.GetProcess()->GetABI();
+
RegisterValue reg_value;
// if this is frame 0 (currently executing frame), get the requested reg
// contents from the actual thread registers
if (IsFrameZero()) {
if (m_thread.GetRegisterContext()->ReadRegister(reg_info, reg_value)) {
value = reg_value.GetAsUInt64();
+ if (abi_sp && generic_regnum != LLDB_INVALID_REGNUM) {
+ if (generic_regnum == LLDB_REGNUM_GENERIC_PC ||
+ generic_regnum == LLDB_REGNUM_GENERIC_RA)
+ value = abi_sp->FixCodeAddress(value);
+ if (generic_regnum == LLDB_REGNUM_GENERIC_SP ||
+ generic_regnum == LLDB_REGNUM_GENERIC_FP)
+ value = abi_sp->FixDataAddress(value);
+ }
return true;
}
return false;
}
bool pc_register = false;
- uint32_t generic_regnum;
- if (register_kind == eRegisterKindGeneric &&
- (regnum == LLDB_REGNUM_GENERIC_PC || regnum == LLDB_REGNUM_GENERIC_RA)) {
+ if (generic_regnum != LLDB_INVALID_REGNUM &&
+ (generic_regnum == LLDB_REGNUM_GENERIC_PC ||
+ generic_regnum == LLDB_REGNUM_GENERIC_RA))
pc_register = true;
- } else if (m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds(
- register_kind, regnum, eRegisterKindGeneric, generic_regnum) &&
- (generic_regnum == LLDB_REGNUM_GENERIC_PC ||
- generic_regnum == LLDB_REGNUM_GENERIC_RA)) {
- pc_register = true;
- }
lldb_private::UnwindLLDB::RegisterLocation regloc;
if (!m_parent_unwind.SearchForSavedLocationForRegister(
@@ -2164,9 +2186,8 @@ bool RegisterContextUnwind::ReadGPRValue(lldb::RegisterKind register_kind,
if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) {
value = reg_value.GetAsUInt64();
if (pc_register) {
- if (ProcessSP process_sp = m_thread.GetProcess()) {
- if (ABISP abi = process_sp->GetABI())
- value = abi->FixCodeAddress(value);
+ if (ABISP abi_sp = m_thread.GetProcess()->GetABI()) {
+ value = abi_sp->FixCodeAddress(value);
}
}
return true;
@@ -2215,10 +2236,8 @@ bool RegisterContextUnwind::ReadRegister(const RegisterInfo *reg_info,
if (is_pc_regnum && value.GetType() == RegisterValue::eTypeUInt64) {
addr_t reg_value = value.GetAsUInt64(LLDB_INVALID_ADDRESS);
if (reg_value != LLDB_INVALID_ADDRESS) {
- if(ProcessSP process_sp = m_thread.GetProcess()) {
- if (ABISP abi = process_sp->GetABI())
- value = abi->FixCodeAddress(reg_value);
- }
+ if (ABISP abi_sp = m_thread.GetProcess()->GetABI())
+ value = abi_sp->FixCodeAddress(reg_value);
}
}
}
@@ -2300,9 +2319,8 @@ bool RegisterContextUnwind::GetStartPC(addr_t &start_pc) {
ProcessSP process_sp (m_thread.GetProcess());
if (process_sp)
{
- ABI *abi = process_sp->GetABI().get();
- if (abi)
- start_pc = abi->FixCodeAddress(start_pc);
+ if (ABISP abi_sp = process_sp->GetABI())
+ start_pc = abi_sp->FixCodeAddress(start_pc);
}
}
return read_successfully;
@@ -2330,13 +2348,8 @@ bool RegisterContextUnwind::ReadPC(addr_t &pc) {
// through a NULL pointer -- we want to be able to unwind past that frame
// to help find the bug.
- ProcessSP process_sp (m_thread.GetProcess());
- if (process_sp)
- {
- ABI *abi = process_sp->GetABI().get();
- if (abi)
- pc = abi->FixCodeAddress(pc);
- }
+ if (ABISP abi_sp = m_thread.GetProcess()->GetABI())
+ pc = abi_sp->FixCodeAddress(pc);
return !(m_all_registers_available == false &&
above_trap_handler == false && (pc == 0 || pc == 1));
More information about the lldb-commits
mailing list