Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 20 additions & 9 deletions lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,19 +77,28 @@ static void DescribeAddressBriefly(Stream &strm, const Address &addr,
strm.Printf(".\n");
}

std::optional<addr_t> StopInfoMachException::GetTagFaultAddress() const {
const bool bad_access =
(m_value == 1 || m_value == 12); // EXC_BAD_ACCESS or EXC_GUARD
const bool tag_fault = (m_exc_code == 0x106); // EXC_ARM_MTE_TAG_FAULT
// Whether the subcode (m_exc_subcode) holds the fault address.
const bool has_fault_addr = (m_exc_data_count >= 2);

if (bad_access && tag_fault && has_fault_addr)
return m_exc_subcode; // The subcode is the 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() {
std::optional<addr_t> 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
Expand Down Expand Up @@ -295,7 +304,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;

Expand Down Expand Up @@ -490,6 +499,8 @@ const char *StopInfoMachException::GetDescription() {
#endif
break;
case 12:
if (DetermineTagMismatch())
return m_description.c_str();
exc_desc = "EXC_GUARD";
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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<lldb::addr_t> GetTagFaultAddress() const;

#if defined(__APPLE__)
struct MachException {
static const char *Name(exception_type_t exc_type);
Expand Down
Loading