From 1ab8c0d710c7ff96e9a927e7d94a00aede4cda66 Mon Sep 17 00:00:00 2001 From: David Hou Date: Sun, 6 Nov 2016 14:02:05 -0800 Subject: [PATCH] Move Ptrace{Request, Event, Options} into enums and bitflags. --- src/sys/ptrace.rs | 139 ++++++++++++++++++++++++++-------------------- 1 file changed, 80 insertions(+), 59 deletions(-) diff --git a/src/sys/ptrace.rs b/src/sys/ptrace.rs index edbc973478..c9446d56b1 100644 --- a/src/sys/ptrace.rs +++ b/src/sys/ptrace.rs @@ -1,66 +1,87 @@ use {Errno, Error, Result}; -use libc::{pid_t, c_void, c_long}; +use libc::{pid_t, c_int, c_void, c_long}; -#[cfg(all(target_os = "linux", - any(target_arch = "x86", - target_arch = "x86_64", - target_arch = "arm")), - )] +#[cfg(any(target_os = "linux", target_os = "android"))] pub mod ptrace { - use libc::c_int; + use libc; - pub type PtraceRequest = c_int; + #[repr(u32)] + pub enum PtraceRequest { + PTRACE_TRACEME = libc::PTRACE_TRACEME, + PTRACE_PEEKTEXT = libc::PTRACE_PEEKTEXT, + PTRACE_PEEKDATA = libc::PTRACE_PEEKDATA, + PTRACE_PEEKUSER = libc::PTRACE_PEEKUSER, + PTRACE_POKETEXT = libc::PTRACE_POKETEXT, + PTRACE_POKEDATA = libc::PTRACE_POKEDATA, + PTRACE_POKEUSER = libc::PTRACE_POKEUSER, + PTRACE_CONT = libc::PTRACE_CONT, + PTRACE_KILL = libc::PTRACE_KILL, + PTRACE_SINGLESTEP = libc::PTRACE_SINGLESTEP, + PTRACE_GETREGS = libc::PTRACE_GETREGS, + PTRACE_SETREGS = libc::PTRACE_SETREGS, + PTRACE_GETFPREGS = libc::PTRACE_GETFPREGS, + PTRACE_SETFPREGS = libc::PTRACE_SETFPREGS, + PTRACE_ATTACH = libc::PTRACE_ATTACH, + PTRACE_DETACH = libc::PTRACE_DETACH, + PTRACE_GETFPXREGS = libc::PTRACE_GETFPXREGS, + PTRACE_SETFPXREGS = libc::PTRACE_SETFPXREGS, + PTRACE_SYSCALL = libc::PTRACE_SYSCALL, + PTRACE_SETOPTIONS = libc::PTRACE_SETOPTIONS, + PTRACE_GETEVENTMSG = libc::PTRACE_GETEVENTMSG, + PTRACE_GETSIGINFO = libc::PTRACE_GETSIGINFO, + PTRACE_SETSIGINFO = libc::PTRACE_SETSIGINFO, + PTRACE_GETREGSET = libc::PTRACE_GETREGSET, + PTRACE_SETREGSET = libc::PTRACE_SETREGSET, + PTRACE_SEIZE = libc::PTRACE_SEIZE, + PTRACE_INTERRUPT = libc::PTRACE_INTERRUPT, + PTRACE_LISTEN = libc::PTRACE_LISTEN, + PTRACE_PEEKSIGINFO = libc::PTRACE_PEEKSIGINFO, + } - 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; + // These aren't currently in libc. + #[cfg(any(target_os = "linux", target_os = "android"))] + #[derive(Eq, PartialEq, Clone, Copy, Debug)] + #[repr(u32)] + pub enum PtraceEvent { + PTRACE_EVENT_FORK = 1, + PTRACE_EVENT_VFORK = 2, + PTRACE_EVENT_CLONE = 3, + PTRACE_EVENT_EXEC = 4, + PTRACE_EVENT_VFORK_DONE = 5, + PTRACE_EVENT_EXIT = 6, + PTRACE_EVENT_SECCOMP = 7, + PTRACE_EVENT_STOP = 128, + } - pub type PtraceEvent = c_int; + #[cfg(any(target_os = "linux", target_os = "android"))] + impl PtraceEvent { + /// Creates a PtraceEvent from the extra bits of a wait status (status >> 16) + #[inline] + pub fn from_c_int(event: libc::c_uint) -> Option { + use std::mem; - pub const PTRACE_EVENT_FORK: PtraceEvent = 1; - pub const PTRACE_EVENT_VFORK: PtraceEvent = 2; - pub const PTRACE_EVENT_CLONE: PtraceEvent = 3; - pub const PTRACE_EVENT_EXEC: PtraceEvent = 4; - pub const PTRACE_EVENT_VFORK_DONE: PtraceEvent = 5; - pub const PTRACE_EVENT_EXIT: PtraceEvent = 6; - pub const PTRACE_EVENT_SECCOMP: PtraceEvent = 6; - pub const PTRACE_EVENT_STOP: PtraceEvent = 128; + if (event >= PtraceEvent::PTRACE_EVENT_FORK as u32 && + event <= PtraceEvent::PTRACE_EVENT_SECCOMP as u32) + || event == PtraceEvent::PTRACE_EVENT_STOP as u32 { + Some(unsafe { mem::transmute(event) }) + } else { + None + } + } + } - pub type PtraceOptions = c_int; - pub const PTRACE_O_TRACESYSGOOD: PtraceOptions = 1; - pub const PTRACE_O_TRACEFORK: PtraceOptions = (1 << PTRACE_EVENT_FORK); - pub const PTRACE_O_TRACEVFORK: PtraceOptions = (1 << PTRACE_EVENT_VFORK); - pub const PTRACE_O_TRACECLONE: PtraceOptions = (1 << PTRACE_EVENT_CLONE); - pub const PTRACE_O_TRACEEXEC: PtraceOptions = (1 << PTRACE_EVENT_EXEC); - pub const PTRACE_O_TRACEVFORKDONE: PtraceOptions = (1 << PTRACE_EVENT_VFORK_DONE); - pub const PTRACE_O_TRACEEXIT: PtraceOptions = (1 << PTRACE_EVENT_EXIT); - pub const PTRACE_O_TRACESECCOMP: PtraceOptions = (1 << PTRACE_EVENT_SECCOMP); + bitflags! { + flags PtraceOptions: libc::c_uint { + const PTRACE_O_TRACESYSGOOD = libc::PTRACE_O_TRACESYSGOOD, + const PTRACE_O_TRACEFORK = libc::PTRACE_O_TRACEFORK, + const PTRACE_O_TRACEVFORK = libc::PTRACE_O_TRACEVFORK, + const PTRACE_O_TRACECLONE = libc::PTRACE_O_TRACECLONE, + const PTRACE_O_TRACEEXEC = libc::PTRACE_O_TRACEEXEC, + const PTRACE_O_TRACEVFORKDONE = libc::PTRACE_O_TRACEVFORKDONE, + const PTRACE_O_TRACEEXIT = libc::PTRACE_O_TRACEEXIT, + const PTRACE_O_TRACESECCOMP = libc::PTRACE_O_TRACESECCOMP, + } + } } mod ffi { @@ -75,7 +96,7 @@ pub fn ptrace(request: ptrace::PtraceRequest, pid: pid_t, addr: *mut c_void, dat use self::ptrace::*; match request { - PTRACE_PEEKTEXT | PTRACE_PEEKDATA | PTRACE_PEEKUSER => ptrace_peek(request, pid, addr, data), + PtraceRequest::PTRACE_PEEKTEXT | PtraceRequest::PTRACE_PEEKDATA | PtraceRequest::PTRACE_PEEKUSER => ptrace_peek(request, pid, addr, data), _ => ptrace_other(request, pid, addr, data) } } @@ -83,7 +104,7 @@ pub fn ptrace(request: ptrace::PtraceRequest, pid: pid_t, addr: *mut c_void, dat fn ptrace_peek(request: ptrace::PtraceRequest, pid: pid_t, addr: *mut c_void, data: *mut c_void) -> Result { let ret = unsafe { Errno::clear(); - ffi::ptrace(request, pid, addr, data) + ffi::ptrace(request as c_int, pid, addr, data) }; match Errno::result(ret) { Ok(..) | Err(Error::Sys(Errno::UnknownErrno)) => Ok(ret), @@ -92,7 +113,7 @@ fn ptrace_peek(request: ptrace::PtraceRequest, pid: pid_t, addr: *mut c_void, da } fn ptrace_other(request: ptrace::PtraceRequest, pid: pid_t, addr: *mut c_void, data: *mut c_void) -> Result { - Errno::result(unsafe { ffi::ptrace(request, pid, addr, data) }).map(|_| 0) + Errno::result(unsafe { ffi::ptrace(request as c_int, pid, addr, data) }).map(|_| 0) } /// Set options, as with `ptrace(PTRACE_SETOPTIONS,...)`. @@ -100,5 +121,5 @@ pub fn ptrace_setoptions(pid: pid_t, options: ptrace::PtraceOptions) -> Result<( use self::ptrace::*; use std::ptr; - ptrace(PTRACE_SETOPTIONS, pid, ptr::null_mut(), options as *mut c_void).map(drop) + ptrace(PtraceRequest::PTRACE_SETOPTIONS, pid, ptr::null_mut(), options.bits() as *mut c_void).map(drop) }