diff --git a/lldb/include/lldb/Target/AppleArm64ExceptionClass.h b/lldb/include/lldb/Target/AppleArm64ExceptionClass.h new file mode 100644 --- /dev/null +++ b/lldb/include/lldb/Target/AppleArm64ExceptionClass.h @@ -0,0 +1,31 @@ +//===-- AppleArm64ExceptionClass.h ------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_TARGET_APPLEARM64EXCEPTIONCLASS_H +#define LLDB_TARGET_APPLEARM64EXCEPTIONCLASS_H + +namespace lldb_private { + +enum class AppleArm64ExceptionClass : unsigned { +#define APPLE_ARM64_EXCEPTION_CLASS(Name, Code) Name = Code, +#include "AppleArm64ExceptionClass.def" +}; + +inline const char *toString(AppleArm64ExceptionClass EC) { + switch (EC) { +#define APPLE_ARM64_EXCEPTION_CLASS(Name, Code) \ + case AppleArm64ExceptionClass::Name: \ + return #Name; +#include "AppleArm64ExceptionClass.def" + } + return "Unknown Exception Class"; +} + +} // namespace lldb_private + +#endif // LLDB_TARGET_APPLEARM64EXCEPTIONCLASS_H diff --git a/lldb/include/lldb/Target/AppleArm64ExceptionClass.def b/lldb/include/lldb/Target/AppleArm64ExceptionClass.def new file mode 100644 --- /dev/null +++ b/lldb/include/lldb/Target/AppleArm64ExceptionClass.def @@ -0,0 +1,51 @@ +#ifndef APPLE_ARM64_EXCEPTION_CLASS +#error "APPLE_ARM64_EXCEPTION_CLASS(Name, Code) not defined." +#endif + +/* + * Exception Syndrome Register + * + * 31 26 25 24 0 + * +------+--+------------------+ + * | EC |IL| ISS | + * +------+--+------------------+ + * + * EC - Exception Class + * IL - Instruction Length + * ISS - Instruction Specific Syndrome + */ + +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_UNCATEGORIZED, 0x00) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_WFI_WFE, 0x01) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_MCR_MRC_CP15_TRAP, 0x03) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_MCRR_MRRC_CP15_TRAP, 0x04) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_MCR_MRC_CP14_TRAP, 0x05) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_LDC_STC_CP14_TRAP, 0x06) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_TRAP_SIMD_FP, 0x07) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_PTRAUTH_INSTR_TRAP, 0x09) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_MCRR_MRRC_CP14_TRAP, 0x0c) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_ILLEGAL_INSTR_SET, 0x0e) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_SVC_32, 0x11) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_SVC_64, 0x15) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_MSR_TRAP, 0x18) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_PAC_FAIL, 0x1C) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_IABORT_EL0, 0x20) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_IABORT_EL1, 0x21) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_PC_ALIGN, 0x22) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_DABORT_EL0, 0x24) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_DABORT_EL1, 0x25) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_SP_ALIGN, 0x26) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_FLOATING_POINT_32, 0x28) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_FLOATING_POINT_64, 0x2C) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_SERROR_INTERRUPT, 0x2F) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_BKPT_REG_MATCH_EL0, 0x30) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_BKPT_REG_MATCH_EL1, 0x31) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_SW_STEP_DEBUG_EL0, 0x32) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_SW_STEP_DEBUG_EL1, 0x33) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_WATCHPT_MATCH_EL0, 0x34) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_WATCHPT_MATCH_EL1, 0x35) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_BKPT_AARCH32, 0x38) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_BRK_AARCH64, 0x3C) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_PRIV, 0x3F) + +#undef APPLE_ARM64_EXCEPTION_CLASS diff --git a/lldb/include/lldb/module.modulemap b/lldb/include/lldb/module.modulemap --- a/lldb/include/lldb/module.modulemap +++ b/lldb/include/lldb/module.modulemap @@ -119,6 +119,7 @@ requires cplusplus umbrella "Target" + textual header "Target/AppleArm64ExceptionClass.def" module * { export * } } } diff --git a/lldb/source/Plugins/Process/mach-core/ThreadMachCore.cpp b/lldb/source/Plugins/Process/mach-core/ThreadMachCore.cpp --- a/lldb/source/Plugins/Process/mach-core/ThreadMachCore.cpp +++ b/lldb/source/Plugins/Process/mach-core/ThreadMachCore.cpp @@ -9,7 +9,9 @@ #include "ThreadMachCore.h" #include "lldb/Breakpoint/Watchpoint.h" +#include "lldb/Host/SafeMachO.h" #include "lldb/Symbol/ObjectFile.h" +#include "lldb/Target/AppleArm64ExceptionClass.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/StopInfo.h" @@ -17,6 +19,7 @@ #include "lldb/Target/Unwind.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/State.h" #include "lldb/Utility/StreamString.h" @@ -91,7 +94,36 @@ bool ThreadMachCore::CalculateStopInfo() { ProcessSP process_sp(GetProcess()); if (process_sp) { - SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, SIGSTOP)); + StopInfoSP stop_info; + RegisterContextSP reg_ctx_sp = GetRegisterContext(); + + if (reg_ctx_sp) { + Target &target = process_sp->GetTarget(); + ArchSpec arch_spec = target.GetArchitecture(); + uint32_t cputype = arch_spec.GetMachOCPUType(); + + if (cputype == llvm::MachO::CPU_TYPE_ARM64 || + cputype == llvm::MachO::CPU_TYPE_ARM64_32) { + const RegisterInfo *esr_info = reg_ctx_sp->GetRegisterInfoByName("esr"); + RegisterValue esr; + if (reg_ctx_sp->ReadRegister(esr_info, esr)) { + uint32_t esr_val = esr.GetAsUInt32(); + auto exception_class = + static_cast(esr_val >> 26); + if (exception_class != + AppleArm64ExceptionClass::ESR_EC_UNCATEGORIZED) { + const char *exception_name = toString(exception_class); + stop_info = + StopInfo::CreateStopReasonWithException(*this, exception_name); + } + } + } + } + + if (!stop_info) + stop_info = StopInfo::CreateStopReasonWithSignal(*this, SIGSTOP); + + SetStopInfo(stop_info); return true; } return false;