Index: lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h =================================================================== --- lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h +++ lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h @@ -62,6 +62,7 @@ return true; } + lldb::addr_t FixCodeAddress(lldb::addr_t pc) override; // Static Functions static void Initialize(); Index: lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp =================================================================== --- lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp +++ lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp @@ -815,6 +815,19 @@ return return_valobj_sp; } +lldb::addr_t ABIMacOSX_arm64::FixCodeAddress(addr_t pc) { + ProcessSP process_sp = GetProcessSP(); + if (!process_sp) + return pc; + + lldb::addr_t mask = process_sp->GetCodeAddressMask(); + if (mask == -1) + return pc; + + lldb::addr_t pac_sign_extension = 0x0080000000000000ULL; + return (pc & pac_sign_extension) ? pc | mask : pc & (~mask); +} + void ABIMacOSX_arm64::Initialize() { PluginManager::RegisterPlugin(GetPluginNameStatic(), pluginDesc, CreateInstance); Index: lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h =================================================================== --- lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h +++ lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h @@ -67,6 +67,7 @@ bool GetPointerReturnRegister(const char *&name) override; + lldb::addr_t FixCodeAddress(lldb::addr_t pc) override; // Static Functions static void Initialize(); Index: lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp =================================================================== --- lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp +++ lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp @@ -782,6 +782,19 @@ return return_valobj_sp; } +lldb::addr_t ABISysV_arm64::FixCodeAddress(addr_t pc) { + ProcessSP process_sp = GetProcessSP(); + if (!process_sp) + return pc; + + lldb::addr_t mask = process_sp->GetCodeAddressMask(); + if (mask == -1) + return pc; + + lldb::addr_t pac_sign_extension = 0x0080000000000000ULL; + return (pc & pac_sign_extension) ? pc | mask : pc & (~mask); +} + void ABISysV_arm64::Initialize() { PluginManager::RegisterPlugin(GetPluginNameStatic(), "SysV ABI for AArch64 targets", CreateInstance); Index: lldb/source/Target/RegisterContextUnwind.cpp =================================================================== --- lldb/source/Target/RegisterContextUnwind.cpp +++ lldb/source/Target/RegisterContextUnwind.cpp @@ -383,7 +383,7 @@ // symbol/function information - just stick in some reasonable defaults and // hope we can unwind past this frame. If we're above a trap handler, // we may be at a bogus address because we jumped through a bogus function - // pointer and trapped, so don't force the arch default unwind plan in that + // pointer and trapped, so don't force the arch default unwind plan in that // case. ModuleSP pc_module_sp(m_current_pc.GetModule()); if ((!m_current_pc.IsValid() || !pc_module_sp) && @@ -1277,7 +1277,7 @@ // arch default unwind plan is used as the Fast Unwind Plan, we // need to recognize this & switch over to the Full Unwind Plan // to see what unwind rule that (more knoweldgeable, probably) - // UnwindPlan has. If the full UnwindPlan says the register + // UnwindPlan has. If the full UnwindPlan says the register // location is Undefined, then it really is. if (active_row->GetRegisterInfo(regnum.GetAsKind(unwindplan_registerkind), unwindplan_regloc) && @@ -1325,14 +1325,14 @@ m_full_unwind_plan_sp->GetReturnAddressRegister() != LLDB_INVALID_REGNUM) { // If this is a trap handler frame, we should have access to - // the complete register context when the interrupt/async + // the complete register context when the interrupt/async // signal was received, we should fetch the actual saved $pc // value instead of the Return Address register. // If $pc is not available, fall back to the RA reg. UnwindPlan::Row::RegisterLocation scratch; if (m_frame_type == eTrapHandlerFrame && - active_row->GetRegisterInfo - (pc_regnum.GetAsKind (unwindplan_registerkind), scratch)) { + active_row->GetRegisterInfo( + pc_regnum.GetAsKind(unwindplan_registerkind), scratch)) { UnwindLogMsg("Providing pc register instead of rewriting to " "RA reg because this is a trap handler and there is " "a location for the saved pc register value."); @@ -1730,6 +1730,12 @@ RegisterValue reg_value; if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) { old_caller_pc_value = reg_value.GetAsUInt64(); + ProcessSP process_sp(m_thread.GetProcess()); + if (process_sp) { + ABI *abi = process_sp->GetABI().get(); + if (abi) + old_caller_pc_value = abi->FixCodeAddress(old_caller_pc_value); + } } } } @@ -1785,6 +1791,12 @@ if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) { new_caller_pc_value = reg_value.GetAsUInt64(); + ProcessSP process_sp(m_thread.GetProcess()); + if (process_sp) { + ABI *abi = process_sp->GetABI().get(); + if (abi) + new_caller_pc_value = abi->FixCodeAddress(new_caller_pc_value); + } } } } @@ -2121,6 +2133,14 @@ } if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) { value = reg_value.GetAsUInt64(); + if (pc_register) { + ProcessSP process_sp(m_thread.GetProcess()); + if (process_sp) { + ABI *abi = process_sp->GetABI().get(); + if (abi) + value = abi->FixCodeAddress(value); + } + } return true; } return false; @@ -2162,7 +2182,19 @@ lldb_regnum, regloc, m_frame_number - 1, is_pc_regnum)) return false; - return ReadRegisterValueFromRegisterLocation(regloc, reg_info, value); + bool result = ReadRegisterValueFromRegisterLocation(regloc, reg_info, value); + if (result) { + if (is_pc_regnum && value.GetType() == RegisterValue::eTypeUInt64) { + ProcessSP process_sp(m_thread.GetProcess()); + addr_t reg_value = value.GetAsUInt64(LLDB_INVALID_ADDRESS); + if (process_sp && reg_value != LLDB_INVALID_ADDRESS) { + ABI *abi = process_sp->GetABI().get(); + if (abi) + value = abi->FixCodeAddress(reg_value); + } + } + } + return result; } bool RegisterContextUnwind::WriteRegister(const RegisterInfo *reg_info,