use libc::c_int;
use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SigHookError {
InvalidAddress,
HookNotFound,
UnsupportedPlatform,
UnsupportedArchitecture,
UnsupportedOperation,
PageSizeUnavailable,
UnexpectedSignalContext,
#[cfg(all(any(target_os = "macos", target_os = "ios"), target_arch = "aarch64"))]
ProtectWritableFailed {
kr: libc::kern_return_t,
errno: c_int,
},
#[cfg(all(any(target_os = "macos", target_os = "ios"), target_arch = "aarch64"))]
ProtectExecutableFailed {
kr: libc::kern_return_t,
errno: c_int,
},
#[cfg(all(target_os = "macos", target_arch = "x86_64"))]
ProtectWritableFailed {
kr: libc::kern_return_t,
errno: c_int,
},
#[cfg(all(target_os = "macos", target_arch = "x86_64"))]
ProtectExecutableFailed {
kr: libc::kern_return_t,
errno: c_int,
},
#[cfg(all(
any(target_os = "linux", target_os = "android"),
any(target_arch = "aarch64", target_arch = "x86_64")
))]
ProtectWritableFailed {
errno: c_int,
},
#[cfg(all(
any(target_os = "linux", target_os = "android"),
any(target_arch = "aarch64", target_arch = "x86_64")
))]
ProtectExecutableFailed {
errno: c_int,
},
SigEmptySetFailed {
signum: c_int,
errno: c_int,
},
SigActionFailed {
signum: c_int,
errno: c_int,
},
InstrumentSlotsFull,
BranchOutOfRange,
PatchTooLong {
patch_len: usize,
instruction_len: usize,
},
DecodeFailed,
AsmEmptyInput,
AsmAssembleFailed,
AsmSizeMismatch {
expected: usize,
actual: usize,
},
MmapFailed {
errno: c_int,
},
TrampolineProtectFailed {
errno: c_int,
},
}
impl fmt::Display for SigHookError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
SigHookError::InvalidAddress => write!(f, "invalid address"),
SigHookError::HookNotFound => write!(f, "hook not found at address"),
SigHookError::UnsupportedPlatform => write!(f, "unsupported platform"),
SigHookError::UnsupportedArchitecture => write!(f, "unsupported architecture"),
SigHookError::UnsupportedOperation => write!(f, "unsupported operation"),
SigHookError::PageSizeUnavailable => write!(f, "page size unavailable"),
SigHookError::UnexpectedSignalContext => write!(f, "unexpected signal context"),
#[cfg(all(any(target_os = "macos", target_os = "ios"), target_arch = "aarch64"))]
SigHookError::ProtectWritableFailed { kr, errno } => {
write!(
f,
"mach_vm_protect writable failed (kr={kr}, errno={errno})"
)
}
#[cfg(all(any(target_os = "macos", target_os = "ios"), target_arch = "aarch64"))]
SigHookError::ProtectExecutableFailed { kr, errno } => {
write!(
f,
"mach_vm_protect executable failed (kr={kr}, errno={errno})"
)
}
#[cfg(all(target_os = "macos", target_arch = "x86_64"))]
SigHookError::ProtectWritableFailed { kr, errno } => {
write!(
f,
"mach_vm_protect writable failed (kr={kr}, errno={errno})"
)
}
#[cfg(all(target_os = "macos", target_arch = "x86_64"))]
SigHookError::ProtectExecutableFailed { kr, errno } => {
write!(
f,
"mach_vm_protect executable failed (kr={kr}, errno={errno})"
)
}
#[cfg(all(
any(target_os = "linux", target_os = "android"),
any(target_arch = "aarch64", target_arch = "x86_64")
))]
SigHookError::ProtectWritableFailed { errno } => {
write!(f, "mprotect writable failed (errno={errno})")
}
#[cfg(all(
any(target_os = "linux", target_os = "android"),
any(target_arch = "aarch64", target_arch = "x86_64")
))]
SigHookError::ProtectExecutableFailed { errno } => {
write!(f, "mprotect executable failed (errno={errno})")
}
SigHookError::SigEmptySetFailed { signum, errno } => {
write!(f, "sigemptyset failed (signum={signum}, errno={errno})")
}
SigHookError::SigActionFailed { signum, errno } => {
write!(f, "sigaction failed (signum={signum}, errno={errno})")
}
SigHookError::InstrumentSlotsFull => write!(f, "instrument slots are full"),
SigHookError::BranchOutOfRange => write!(f, "branch target out of range"),
SigHookError::PatchTooLong {
patch_len,
instruction_len,
} => {
write!(
f,
"patch length ({patch_len}) exceeds instruction length ({instruction_len}); use patch_bytes for multi-instruction patching"
)
}
SigHookError::DecodeFailed => write!(f, "instruction decode failed"),
SigHookError::AsmEmptyInput => write!(f, "assembly input is empty"),
SigHookError::AsmAssembleFailed => write!(f, "assembly to machine code failed"),
SigHookError::AsmSizeMismatch { expected, actual } => {
write!(
f,
"assembled size mismatch (expected={expected}, actual={actual})"
)
}
SigHookError::MmapFailed { errno } => write!(f, "mmap failed (errno={errno})"),
SigHookError::TrampolineProtectFailed { errno } => {
write!(f, "trampoline mprotect failed (errno={errno})")
}
}
}
}
impl std::error::Error for SigHookError {}