diff --git a/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp b/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp index 601cfdcb4e9f7..a361e68555042 100644 --- a/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp +++ b/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp @@ -77,19 +77,27 @@ static void DescribeAddressBriefly(Stream &strm, const Address &addr, strm.Printf(".\n"); } +std::optional StopInfoMachException::GetTagFaultAddress() const { + bool bad_access = + (m_value == 1 || m_value == 12); // EXC_BAD_ACCESS or EXC_GUARD + bool tag_fault = (m_exc_code == 0x106); // EXC_ARM_MTE_TAG_FAULT + bool has_fault_addr = (m_exc_data_count >= 2); // m_exc_subcode -> fault addr + + if (bad_access && tag_fault && has_fault_addr) + return m_exc_subcode; // Fault address + + return std::nullopt; +} + static constexpr uint8_t g_mte_tag_shift = 64 - 8; static constexpr addr_t g_mte_tag_mask = (addr_t)0x0f << g_mte_tag_shift; -bool StopInfoMachException::DetermineTagMismatch(ExecutionContext &exe_ctx) { - const bool IsBadAccess = m_value == 1; // EXC_BAD_ACCESS - const bool IsMTETagFault = (m_exc_code == 0x106); // EXC_ARM_MTE_TAG_FAULT - if (!IsBadAccess || !IsMTETagFault) - return false; - - if (m_exc_data_count < 2) +bool StopInfoMachException::DetermineTagMismatch() { + auto fault_address = GetTagFaultAddress(); + if (!fault_address) return false; - const uint64_t bad_address = m_exc_subcode; + const uint64_t bad_address = *fault_address; StreamString strm; strm.Printf("EXC_ARM_MTE_TAG_FAULT (code=%" PRIu64 ", address=0x%" PRIx64 @@ -295,7 +303,7 @@ const char *StopInfoMachException::GetDescription() { case llvm::Triple::aarch64: if (DeterminePtrauthFailure(exe_ctx)) return m_description.c_str(); - if (DetermineTagMismatch(exe_ctx)) + if (DetermineTagMismatch()) return m_description.c_str(); break; @@ -490,6 +498,8 @@ const char *StopInfoMachException::GetDescription() { #endif break; case 12: + if (DetermineTagMismatch()) + return m_description.c_str(); exc_desc = "EXC_GUARD"; break; } diff --git a/lldb/source/Plugins/Process/Utility/StopInfoMachException.h b/lldb/source/Plugins/Process/Utility/StopInfoMachException.h index c02389e5b3642..26f93e0bb348f 100644 --- a/lldb/source/Plugins/Process/Utility/StopInfoMachException.h +++ b/lldb/source/Plugins/Process/Utility/StopInfoMachException.h @@ -27,7 +27,7 @@ class StopInfoMachException : public StopInfo { /// is auth-related failure, and returns false otherwise. bool DeterminePtrauthFailure(ExecutionContext &exe_ctx); - bool DetermineTagMismatch(ExecutionContext &exe_ctx); + bool DetermineTagMismatch(); public: // Constructors and Destructors @@ -48,6 +48,9 @@ class StopInfoMachException : public StopInfo { const char *GetDescription() override; + // Returns the fault address, iff this is a EXC_ARM_MTE_TAG_FAULT. + std::optional GetTagFaultAddress() const; + #if defined(__APPLE__) struct MachException { static const char *Name(exception_type_t exc_type);