samply 0.13.1

A command line profiler for macOS and Linux.
use mach2::kern_return::*;
use mach2::message::*;
use thiserror::Error;

pub const KERN_INSUFFICIENT_BUFFER_SIZE: kern_return_t = 52;
pub const MACH_SEND_INVALID_CONTEXT: kern_return_t = 0x10000012;
pub const MACH_SEND_NO_GRANT_DEST: kern_return_t = 0x10000016;
pub const MACH_RCV_INVALID_REPLY: kern_return_t = 0x10004012;

pub trait IntoResult {
    type Value;
    type Error;

    fn into_result(self) -> std::result::Result<Self::Value, Self::Error>;
}

impl IntoResult for kern_return_t {
    type Value = ();
    type Error = KernelError;

    fn into_result(self) -> std::result::Result<(), KernelError> {
        if self == KERN_SUCCESS {
            Ok(())
        } else {
            Err(KernelError::from(self))
        }
    }
}

pub type Result<T> = std::result::Result<T, KernelError>;

#[derive(Error, Debug, Clone, PartialEq, Eq)]
pub enum KernelError {
    #[error("Specified address is not currently valid.")]
    InvalidAddress,

    #[error("Specified memory is valid, but does not permit the required forms of access.")]
    ProtectionFailure,

    #[error("The address range specified is already in use, or no address range of the size specified could be found.")]
    NoSpace,

    #[error("The function requested was not applicable to this type of argument, or an argument is invalid")]
    InvalidArgument,

    #[error("The function could not be performed.  A catch-all.")]
    Failure,

    #[error("A system resource could not be allocated to fulfill this request.  This failure may not be permanent.")]
    ResourceShortage,

    #[error("The task in question does not hold receive rights for the port argument.")]
    NotReceiver,

    #[error("Bogus access restriction.")]
    NoAccess,

    #[error("During a page fault, the target address refers to a memory object that has been destroyed.  This failure is permanent.")]
    MemoryFailure,

    #[error("During a page fault, the memory object indicated that the data could not be returned.  This failure may be temporary; future attempts to access this same data may succeed, as defined by the memory object.")]
    MemoryError,

    #[error("The receive right is already a member of the portset.")]
    AlreadyInSet,

    #[error("The receive right is not a member of a port set.")]
    NotInSet,

    #[error("The name already denotes a right in the task.")]
    NameExists,

    #[error(
        "The operation was aborted.  Ipc code will catch this and reflect it as a message error."
    )]
    Aborted,

    #[error("The name doesn't denote a right in the task.")]
    InvalidName,

    #[error("Target task isn't an active task.")]
    InvalidTask,

    #[error("The name denotes a right, but not an appropriate right.")]
    InvalidRight,

    #[error("A blatant range error.")]
    InvalidValue,

    #[error("Operation would overflow limit on user-references.")]
    UrefsOverflow,

    #[error("The supplied (port) capability is improper.")]
    InvalidCapability,

    #[error("The task already has send or receive rights for the port under another name.")]
    RightExists,

    #[error("Target host isn't actually a host.")]
    InvalidHost,

    #[error("An attempt was made to supply \"precious\" data for memory that is already present in a memory object.")]
    MemoryPresent,

    #[error("A page was requested of a memory manager via memory_object_data_request for an object using a MEMORY_OBJECT_COPY_CALL strategy, with the VM_PROT_WANTS_COPY flag being used to specify that the page desired is for a copy of the object, and the memory manager has detected the page was pushed into a copy of the object while the kernel was walking the shadow chain from the copy to the object. This error code is delivered via memory_object_data_error and is handled by the kernel (it forces the kernel to restart the fault). It will not be seen by users.")]
    MemoryDataMoved,

    #[error("A strategic copy was attempted of an object upon which a quicker copy is now possible. The caller should retry the copy using vm_object_copy_quickly. This error code is seen only by the kernel.")]
    MemoryRestartCopy,

    #[error("An argument applied to assert processor set privilege was not a processor set control port.")]
    InvalidProcessorSet,

    #[error("The specified scheduling attributes exceed the thread's limits.")]
    PolicyLimit,

    #[error("The specified scheduling policy is not currently enabled for the processor set.")]
    InvalidPolicy,

    #[error("The external memory manager failed to initialize the memory object.")]
    InvalidObject,

    #[error(
        "A thread is attempting to wait for an event for which there is already a waiting thread."
    )]
    AlreadyWaiting,

    #[error("An attempt was made to destroy the default processor set.")]
    DefaultSet,

    #[error("An attempt was made to fetch an exception port that is protected, or to abort a thread while processing a protected exception.")]
    ExceptionProtected,

    #[error("A ledger was required but not supplied.")]
    InvalidLedger,

    #[error("The port was not a memory cache control port.")]
    InvalidMemoryControl,

    #[error("An argument supplied to assert security privilege was not a host security port.")]
    InvalidSecurity,

    #[error("thread_depress_abort was called on a thread which was not currently depressed.")]
    NotDepressed,

    #[error("Object has been terminated and is no longer available")]
    Terminated,

    #[error("Lock set has been destroyed and is no longer available.")]
    LockSetDestroyed,

    #[error("The thread holding the lock terminated before releasing the lock")]
    LockUnstable,

    #[error("The lock is already owned by another thread")]
    LockOwned,

    #[error("The lock is already owned by the calling thread")]
    LockOwnedSelf,

    #[error("Semaphore has been destroyed and is no longer available.")]
    SemaphoreDestroyed,

    #[error("Return from RPC indicating the target server was terminated before it successfully replied")]
    RpcServerTerminated,

    #[error("Terminate an orphaned activation.")]
    RpcTerminateOrphan,

    #[error("Allow an orphaned activation to continue executing.")]
    RpcContinueOrphan,

    #[error("Empty thread activation (No thread linked to it)")]
    NotSupported,

    #[error("Remote node down or inaccessible.")]
    NodeDown,

    #[error("A signalled thread was not actually waiting")]
    NotWaiting,

    #[error("Some thread-oriented operation (semaphore_wait) timed out")]
    OperationTimedOut,

    #[error("During a page fault, indicates that the page was rejected as a result of a signature check.")]
    CodesignError,

    #[error("The requested property cannot be changed at this time.")]
    PolicyStatic,

    #[error("The provided buffer is of insufficient size for the requested data.")]
    InsufficientBufferSize,

    #[error("Thread is waiting to send.  (Internal use only.)")]
    MachSendInProgress,

    #[error("Bogus in-line data.")]
    MachSendInvalidData,

    #[error("Bogus destination port.")]
    MachSendInvalidDest,

    #[error("Message not sent before timeout expired.")]
    MachSendTimedOut,

    #[error("Bogus voucher port.")]
    MachSendInvalidVoucher,

    #[error("Software interrupt.")]
    MachSendInterrupted,

    #[error("Data doesn't contain a complete message.")]
    MachSendMsgTooSmall,

    #[error("Bogus reply port.")]
    MachSendInvalidReply,

    #[error("Bogus port rights in the message body.")]
    MachSendInvalidRight,

    #[error("Bogus notify port argument.")]
    MachSendInvalidNotify,

    #[error("Invalid out-of-line memory pointer.")]
    MachSendInvalidMemory,

    #[error("No message buffer is available.")]
    MachSendNoBuffer,

    #[error("Send is too large for port")]
    MachSendTooLarge,

    #[error("Invalid msg-type specification.")]
    MachSendInvalidType,

    #[error("A field in the header had a bad value.")]
    MachSendInvalidHeader,

    #[error("The trailer to be sent does not match kernel format.")]
    MachSendInvalidTrailer,

    #[error("The sending thread context did not match the context on the dest port")]
    MachSendInvalidContext,

    #[error("compatibility: no longer a returned error")]
    MachSendInvalidRtOolSize,

    #[error("The destination port doesn't accept ports in body")]
    MachSendNoGrantDest,

    #[error("Thread is waiting for receive.  (Internal use only.)")]
    MachRcvInProgress,

    #[error("Bogus name for receive port/port-set.")]
    MachRcvInvalidName,

    #[error("Didn't get a message within the timeout value.")]
    MachRcvTimedOut,

    #[error("Message buffer is not large enough for inline data.")]
    MachRcvTooLarge,

    #[error("Software interrupt.")]
    MachRcvInterrupted,

    #[error("compatibility: no longer a returned error")]
    MachRcvPortChanged,

    #[error("Bogus notify port argument.")]
    MachRcvInvalidNotify,

    #[error("Bogus message buffer for inline data.")]
    MachRcvInvalidData,

    #[error("Port/set was sent away/died during receive.")]
    MachRcvPortDied,

    #[error("compatibility: no longer a returned error")]
    MachRcvInSet,

    #[error("Error receiving message header.  See special bits.")]
    MachRcvHeaderError,

    #[error("Error receiving message body.  See special bits.")]
    MachRcvBodyError,

    #[error("Invalid msg-type specification in scatter list.")]
    MachRcvInvalidType,

    #[error("Out-of-line overwrite region is not large enough")]
    MachRcvScatterSmall,

    #[error("trailer type or number of trailer elements not supported")]
    MachRcvInvalidTrailer,

    #[error("Waiting for receive with timeout. (Internal use only.)")]
    MachRcvInProgressTimed,

    #[error("invalid reply port used in a STRICT_REPLY message")]
    MachRcvInvalidReply,

    #[error("Unknown kernel error {0}")]
    Unknown(kern_return_t),
}

impl From<kern_return_t> for KernelError {
    fn from(err: kern_return_t) -> KernelError {
        match err {
            KERN_INVALID_ADDRESS => KernelError::InvalidAddress,
            KERN_PROTECTION_FAILURE => KernelError::ProtectionFailure,
            KERN_NO_SPACE => KernelError::NoSpace,
            KERN_INVALID_ARGUMENT => KernelError::InvalidArgument,
            KERN_FAILURE => KernelError::Failure,
            KERN_RESOURCE_SHORTAGE => KernelError::ResourceShortage,
            KERN_NOT_RECEIVER => KernelError::NotReceiver,
            KERN_NO_ACCESS => KernelError::NoAccess,
            KERN_MEMORY_FAILURE => KernelError::MemoryFailure,
            KERN_MEMORY_ERROR => KernelError::MemoryError,
            KERN_ALREADY_IN_SET => KernelError::AlreadyInSet,
            KERN_NOT_IN_SET => KernelError::NotInSet,
            KERN_NAME_EXISTS => KernelError::NameExists,
            KERN_ABORTED => KernelError::Aborted,
            KERN_INVALID_NAME => KernelError::InvalidName,
            KERN_INVALID_TASK => KernelError::InvalidTask,
            KERN_INVALID_RIGHT => KernelError::InvalidRight,
            KERN_INVALID_VALUE => KernelError::InvalidValue,
            KERN_UREFS_OVERFLOW => KernelError::UrefsOverflow,
            KERN_INVALID_CAPABILITY => KernelError::InvalidCapability,
            KERN_RIGHT_EXISTS => KernelError::RightExists,
            KERN_INVALID_HOST => KernelError::InvalidHost,
            KERN_MEMORY_PRESENT => KernelError::MemoryPresent,
            KERN_MEMORY_DATA_MOVED => KernelError::MemoryDataMoved,
            KERN_MEMORY_RESTART_COPY => KernelError::MemoryRestartCopy,
            KERN_INVALID_PROCESSOR_SET => KernelError::InvalidProcessorSet,
            KERN_POLICY_LIMIT => KernelError::PolicyLimit,
            KERN_INVALID_POLICY => KernelError::InvalidPolicy,
            KERN_INVALID_OBJECT => KernelError::InvalidObject,
            KERN_ALREADY_WAITING => KernelError::AlreadyWaiting,
            KERN_DEFAULT_SET => KernelError::DefaultSet,
            KERN_EXCEPTION_PROTECTED => KernelError::ExceptionProtected,
            KERN_INVALID_LEDGER => KernelError::InvalidLedger,
            KERN_INVALID_MEMORY_CONTROL => KernelError::InvalidMemoryControl,
            KERN_INVALID_SECURITY => KernelError::InvalidSecurity,
            KERN_NOT_DEPRESSED => KernelError::NotDepressed,
            KERN_TERMINATED => KernelError::Terminated,
            KERN_LOCK_SET_DESTROYED => KernelError::LockSetDestroyed,
            KERN_LOCK_UNSTABLE => KernelError::LockUnstable,
            KERN_LOCK_OWNED => KernelError::LockOwned,
            KERN_LOCK_OWNED_SELF => KernelError::LockOwnedSelf,
            KERN_SEMAPHORE_DESTROYED => KernelError::SemaphoreDestroyed,
            KERN_RPC_SERVER_TERMINATED => KernelError::RpcServerTerminated,
            KERN_RPC_TERMINATE_ORPHAN => KernelError::RpcTerminateOrphan,
            KERN_RPC_CONTINUE_ORPHAN => KernelError::RpcContinueOrphan,
            KERN_NOT_SUPPORTED => KernelError::NotSupported,
            KERN_NODE_DOWN => KernelError::NodeDown,
            KERN_NOT_WAITING => KernelError::NotWaiting,
            KERN_OPERATION_TIMED_OUT => KernelError::OperationTimedOut,
            KERN_CODESIGN_ERROR => KernelError::CodesignError,
            KERN_POLICY_STATIC => KernelError::PolicyStatic,
            KERN_INSUFFICIENT_BUFFER_SIZE => KernelError::InsufficientBufferSize,
            MACH_SEND_IN_PROGRESS => KernelError::MachSendInProgress,
            MACH_SEND_INVALID_DATA => KernelError::MachSendInvalidData,
            MACH_SEND_INVALID_DEST => KernelError::MachSendInvalidDest,
            MACH_SEND_TIMED_OUT => KernelError::MachSendTimedOut,
            MACH_SEND_INVALID_VOUCHER => KernelError::MachSendInvalidVoucher,
            MACH_SEND_INTERRUPTED => KernelError::MachSendInterrupted,
            MACH_SEND_MSG_TOO_SMALL => KernelError::MachSendMsgTooSmall,
            MACH_SEND_INVALID_REPLY => KernelError::MachSendInvalidReply,
            MACH_SEND_INVALID_RIGHT => KernelError::MachSendInvalidRight,
            MACH_SEND_INVALID_NOTIFY => KernelError::MachSendInvalidNotify,
            MACH_SEND_INVALID_MEMORY => KernelError::MachSendInvalidMemory,
            MACH_SEND_NO_BUFFER => KernelError::MachSendNoBuffer,
            MACH_SEND_TOO_LARGE => KernelError::MachSendTooLarge,
            MACH_SEND_INVALID_TYPE => KernelError::MachSendInvalidType,
            MACH_SEND_INVALID_HEADER => KernelError::MachSendInvalidHeader,
            MACH_SEND_INVALID_TRAILER => KernelError::MachSendInvalidTrailer,
            MACH_SEND_INVALID_CONTEXT => KernelError::MachSendInvalidContext,
            MACH_SEND_INVALID_RT_OOL_SIZE => KernelError::MachSendInvalidRtOolSize,
            MACH_SEND_NO_GRANT_DEST => KernelError::MachSendNoGrantDest,
            MACH_RCV_IN_PROGRESS => KernelError::MachRcvInProgress,
            MACH_RCV_INVALID_NAME => KernelError::MachRcvInvalidName,
            MACH_RCV_TIMED_OUT => KernelError::MachRcvTimedOut,
            MACH_RCV_TOO_LARGE => KernelError::MachRcvTooLarge,
            MACH_RCV_INTERRUPTED => KernelError::MachRcvInterrupted,
            MACH_RCV_PORT_CHANGED => KernelError::MachRcvPortChanged,
            MACH_RCV_INVALID_NOTIFY => KernelError::MachRcvInvalidNotify,
            MACH_RCV_INVALID_DATA => KernelError::MachRcvInvalidData,
            MACH_RCV_PORT_DIED => KernelError::MachRcvPortDied,
            MACH_RCV_IN_SET => KernelError::MachRcvInSet,
            MACH_RCV_HEADER_ERROR => KernelError::MachRcvHeaderError,
            MACH_RCV_BODY_ERROR => KernelError::MachRcvBodyError,
            MACH_RCV_INVALID_TYPE => KernelError::MachRcvInvalidType,
            MACH_RCV_SCATTER_SMALL => KernelError::MachRcvScatterSmall,
            MACH_RCV_INVALID_TRAILER => KernelError::MachRcvInvalidTrailer,
            MACH_RCV_IN_PROGRESS_TIMED => KernelError::MachRcvInProgressTimed,
            MACH_RCV_INVALID_REPLY => KernelError::MachRcvInvalidReply,
            unknown => KernelError::Unknown(unknown),
        }
    }
}