[lldb] Recognize MTE fault Mach exceptions (#159117)

Recognize an MTE tag fault Mach exception. A tag fault is an error
reported by Arm's Memory Tagging Extension (MTE) when a memory access
attempts to use a pointer with a tag that doesn't match the tag stored
with the memory. LLDB will print the tag and address to make the issue
easier to diagnose.

This was hand tested by debugging an MTE enabled binary on an iPhone 17
running iOS 26.

rdar://113575216
This commit is contained in:
Jonas Devlieghere
2025-09-17 11:20:52 -07:00
committed by GitHub
parent f549bb2ddc
commit def2020485
2 changed files with 33 additions and 0 deletions

View File

@@ -77,6 +77,35 @@ static void DescribeAddressBriefly(Stream &strm, const Address &addr,
strm.Printf(".\n");
}
static constexpr uint8_t g_mte_tag_shift = 64 - 8;
static constexpr uintptr_t g_mte_tag_mask = (uintptr_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)
return false;
const uint64_t bad_address = m_exc_subcode;
StreamString strm;
strm.Printf("EXC_ARM_MTE_TAG_FAULT (code=%" PRIu64 ", address=0x%" PRIx64
")\n",
m_exc_code, bad_address);
const uint8_t tag = (bad_address & g_mte_tag_mask) >> g_mte_tag_shift;
const uint64_t canonical_addr = bad_address & ~g_mte_tag_mask;
strm.Printf(
"Note: MTE tag mismatch detected: pointer tag=%d, address=0x%" PRIx64,
tag, canonical_addr);
m_description = std::string(strm.GetString());
return true;
}
bool StopInfoMachException::DeterminePtrauthFailure(ExecutionContext &exe_ctx) {
bool IsBreakpoint = m_value == 6; // EXC_BREAKPOINT
bool IsBadAccess = m_value == 1; // EXC_BAD_ACCESS
@@ -266,6 +295,8 @@ const char *StopInfoMachException::GetDescription() {
case llvm::Triple::aarch64:
if (DeterminePtrauthFailure(exe_ctx))
return m_description.c_str();
if (DetermineTagMismatch(exe_ctx))
return m_description.c_str();
break;
default:

View File

@@ -27,6 +27,8 @@ class StopInfoMachException : public StopInfo {
/// is auth-related failure, and returns false otherwise.
bool DeterminePtrauthFailure(ExecutionContext &exe_ctx);
bool DetermineTagMismatch(ExecutionContext &exe_ctx);
public:
// Constructors and Destructors
StopInfoMachException(Thread &thread, uint32_t exc_type,