1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
use {Error, Result}; use errno::Errno; use libc::{pid_t, c_void, c_long}; #[cfg(all(target_os = "linux", any(target_arch = "x86", target_arch = "x86_64", target_arch = "arm")), )] pub mod ptrace { use libc::c_int; pub type PtraceRequest = c_int; pub const PTRACE_TRACEME: PtraceRequest = 0; pub const PTRACE_PEEKTEXT: PtraceRequest = 1; pub const PTRACE_PEEKDATA: PtraceRequest = 2; pub const PTRACE_PEEKUSER: PtraceRequest = 3; pub const PTRACE_POKETEXT: PtraceRequest = 4; pub const PTRACE_POKEDATA: PtraceRequest = 5; pub const PTRACE_POKEUSER: PtraceRequest = 6; pub const PTRACE_CONT: PtraceRequest = 7; pub const PTRACE_KILL: PtraceRequest = 8; pub const PTRACE_SINGLESTEP: PtraceRequest = 9; pub const PTRACE_GETREGS: PtraceRequest = 12; pub const PTRACE_SETREGS: PtraceRequest = 13; pub const PTRACE_GETFPREGS: PtraceRequest = 14; pub const PTRACE_SETFPREGS: PtraceRequest = 15; pub const PTRACE_ATTACH: PtraceRequest = 16; pub const PTRACE_DETACH: PtraceRequest = 17; pub const PTRACE_GETFPXREGS: PtraceRequest = 18; pub const PTRACE_SETFPXREGS: PtraceRequest = 19; pub const PTRACE_SYSCALL: PtraceRequest = 24; pub const PTRACE_SETOPTIONS: PtraceRequest = 0x4200; pub const PTRACE_GETEVENTMSG: PtraceRequest = 0x4201; pub const PTRACE_GETSIGINFO: PtraceRequest = 0x4202; pub const PTRACE_SETSIGINFO: PtraceRequest = 0x4203; pub const PTRACE_GETREGSET: PtraceRequest = 0x4204; pub const PTRACE_SETREGSET: PtraceRequest = 0x4205; pub const PTRACE_SEIZE: PtraceRequest = 0x4206; pub const PTRACE_INTERRUPT: PtraceRequest = 0x4207; pub const PTRACE_LISTEN: PtraceRequest = 0x4208; pub const PTRACE_PEEKSIGINFO: PtraceRequest = 0x4209; } mod ffi { use libc::{pid_t, c_int, c_long, c_void}; extern { pub fn ptrace(request: c_int, pid: pid_t, addr: * const c_void, data: * const c_void) -> c_long; } } pub fn ptrace(request: ptrace::PtraceRequest, pid: pid_t, addr: *mut c_void, data: *mut c_void) -> Result<c_long> { use self::ptrace::*; match request { PTRACE_PEEKTEXT | PTRACE_PEEKDATA | PTRACE_PEEKUSER => ptrace_peek(request, pid, addr, data), _ => ptrace_other(request, pid, addr, data) } } fn ptrace_peek(request: ptrace::PtraceRequest, pid: pid_t, addr: *mut c_void, data: *mut c_void) -> Result<c_long> { let ret = unsafe { Errno::clear(); ffi::ptrace(request, pid, addr, data) }; if ret == -1 && Errno::last() != Errno::UnknownErrno { return Err(Error::Sys(Errno::last())); } Ok::<c_long, Error>(ret) } fn ptrace_other(request: ptrace::PtraceRequest, pid: pid_t, addr: *mut c_void, data: *mut c_void) -> Result<c_long> { match unsafe { ffi::ptrace(request, pid, addr, data) } { -1 => Err(Error::Sys(Errno::last())), _ => Ok(0) } }