#include "StopInfoMachException.h"
#include "lldb/lldb-forward.h"
#if defined(__APPLE__)
#include <kern/exc_resource.h>
#endif
#include "lldb/Breakpoint/Watchpoint.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlan.h"
#include "lldb/Target/UnixSignals.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/StreamString.h"
#include <optional>
usingnamespacelldb;
usingnamespacelldb_private;
struct PtrauthInstructionInfo { … };
static std::optional<PtrauthInstructionInfo>
GetPtrauthInstructionInfo(Target &target, const ArchSpec &arch,
const Address &at_addr) { … }
static void DescribeAddressBriefly(Stream &strm, const Address &addr,
Target &target) { … }
bool StopInfoMachException::DeterminePtrauthFailure(ExecutionContext &exe_ctx) { … }
const char *StopInfoMachException::GetDescription() { … }
static StopInfoSP GetStopInfoForHardwareBP(Thread &thread, Target *target,
uint32_t exc_data_count,
uint64_t exc_sub_code,
uint64_t exc_sub_sub_code) { … }
#if defined(__APPLE__)
const char *
StopInfoMachException::MachException::Name(exception_type_t exc_type) {
switch (exc_type) {
case EXC_BAD_ACCESS:
return "EXC_BAD_ACCESS";
case EXC_BAD_INSTRUCTION:
return "EXC_BAD_INSTRUCTION";
case EXC_ARITHMETIC:
return "EXC_ARITHMETIC";
case EXC_EMULATION:
return "EXC_EMULATION";
case EXC_SOFTWARE:
return "EXC_SOFTWARE";
case EXC_BREAKPOINT:
return "EXC_BREAKPOINT";
case EXC_SYSCALL:
return "EXC_SYSCALL";
case EXC_MACH_SYSCALL:
return "EXC_MACH_SYSCALL";
case EXC_RPC_ALERT:
return "EXC_RPC_ALERT";
#ifdef EXC_CRASH
case EXC_CRASH:
return "EXC_CRASH";
#endif
case EXC_RESOURCE:
return "EXC_RESOURCE";
#ifdef EXC_GUARD
case EXC_GUARD:
return "EXC_GUARD";
#endif
#ifdef EXC_CORPSE_NOTIFY
case EXC_CORPSE_NOTIFY:
return "EXC_CORPSE_NOTIFY";
#endif
#ifdef EXC_CORPSE_VARIANT_BIT
case EXC_CORPSE_VARIANT_BIT:
return "EXC_CORPSE_VARIANT_BIT";
#endif
default:
break;
}
return NULL;
}
std::optional<exception_type_t>
StopInfoMachException::MachException::ExceptionCode(const char *name) {
return llvm::StringSwitch<std::optional<exception_type_t>>(name)
.Case("EXC_BAD_ACCESS", EXC_BAD_ACCESS)
.Case("EXC_BAD_INSTRUCTION", EXC_BAD_INSTRUCTION)
.Case("EXC_ARITHMETIC", EXC_ARITHMETIC)
.Case("EXC_EMULATION", EXC_EMULATION)
.Case("EXC_SOFTWARE", EXC_SOFTWARE)
.Case("EXC_BREAKPOINT", EXC_BREAKPOINT)
.Case("EXC_SYSCALL", EXC_SYSCALL)
.Case("EXC_MACH_SYSCALL", EXC_MACH_SYSCALL)
.Case("EXC_RPC_ALERT", EXC_RPC_ALERT)
#ifdef EXC_CRASH
.Case("EXC_CRASH", EXC_CRASH)
#endif
.Case("EXC_RESOURCE", EXC_RESOURCE)
#ifdef EXC_GUARD
.Case("EXC_GUARD", EXC_GUARD)
#endif
#ifdef EXC_CORPSE_NOTIFY
.Case("EXC_CORPSE_NOTIFY", EXC_CORPSE_NOTIFY)
#endif
.Default(std::nullopt);
}
#endif
StopInfoSP StopInfoMachException::CreateStopReasonWithMachException(
Thread &thread, uint32_t exc_type, uint32_t exc_data_count,
uint64_t exc_code, uint64_t exc_sub_code, uint64_t exc_sub_sub_code,
bool pc_already_adjusted, bool adjust_pc_if_needed) { … }
bool StopInfoMachException::WasContinueInterrupted(Thread &thread) { … }