Skip to content

Commit a0fc607

Browse files
joekaincarllerche
authored andcommitted
Add support for ptrace
Closes rust-lang#138
1 parent 90bbc63 commit a0fc607

File tree

3 files changed

+127
-31
lines changed

3 files changed

+127
-31
lines changed

src/errno.rs

Lines changed: 41 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,44 +3,50 @@ use libc::c_int;
33
pub use self::consts::*;
44
pub use self::consts::Errno::*;
55

6-
/// Returns the platform-specific value of errno
7-
pub fn errno() -> i32 {
8-
#[cfg(any(target_os = "macos",
9-
target_os = "ios",
10-
target_os = "freebsd"))]
11-
unsafe fn errno_location() -> *const c_int {
12-
extern { fn __error() -> *const c_int; }
13-
__error()
14-
}
156

16-
#[cfg(target_os = "bitrig")]
17-
fn errno_location() -> *const c_int {
18-
extern {
19-
fn __errno() -> *const c_int;
20-
}
21-
unsafe {
22-
__errno()
23-
}
24-
}
7+
#[cfg(any(target_os = "macos",
8+
target_os = "ios",
9+
target_os = "freebsd"))]
10+
unsafe fn errno_location() -> *mut c_int {
11+
extern { fn __error() -> *mut c_int; }
12+
__error()
13+
}
2514

26-
#[cfg(target_os = "dragonfly")]
27-
unsafe fn errno_location() -> *const c_int {
28-
extern { fn __dfly_error() -> *const c_int; }
29-
__dfly_error()
15+
#[cfg(target_os = "bitrig")]
16+
fn errno_location() -> *mut c_int {
17+
extern {
18+
fn __errno() -> *mut c_int;
3019
}
31-
32-
#[cfg(target_os = "openbsd")]
33-
unsafe fn errno_location() -> *const c_int {
34-
extern { fn __errno() -> *const c_int; }
20+
unsafe {
3521
__errno()
3622
}
23+
}
3724

38-
#[cfg(any(target_os = "linux", target_os = "android"))]
39-
unsafe fn errno_location() -> *const c_int {
40-
extern { fn __errno_location() -> *const c_int; }
41-
__errno_location()
42-
}
25+
#[cfg(target_os = "dragonfly")]
26+
unsafe fn errno_location() -> *mut c_int {
27+
extern { fn __dfly_error() -> *mut c_int; }
28+
__dfly_error()
29+
}
30+
31+
#[cfg(target_os = "openbsd")]
32+
unsafe fn errno_location() -> *mut c_int {
33+
extern { fn __errno() -> *mut c_int; }
34+
__errno()
35+
}
36+
37+
#[cfg(any(target_os = "linux", target_os = "android"))]
38+
unsafe fn errno_location() -> *mut c_int {
39+
extern { fn __errno_location() -> *mut c_int; }
40+
__errno_location()
41+
}
4342

43+
/// Sets the platform-specific errno to no-error
44+
unsafe fn clear() -> () {
45+
*errno_location() = 0;
46+
}
47+
48+
/// Returns the platform-specific value of errno
49+
pub fn errno() -> i32 {
4450
unsafe {
4551
(*errno_location()) as i32
4652
}
@@ -60,6 +66,10 @@ macro_rules! impl_errno {
6066
pub fn from_i32(err: i32) -> Errno {
6167
from_i32(err)
6268
}
69+
70+
pub unsafe fn clear() -> () {
71+
super::clear()
72+
}
6373
}
6474
}
6575
}

src/sys/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,10 @@ pub mod mman;
3434
pub mod uio;
3535

3636
pub mod time;
37+
38+
#[cfg(all(target_os = "linux",
39+
any(target_arch = "x86",
40+
target_arch = "x86_64",
41+
target_arch = "arm")),
42+
)]
43+
pub mod ptrace;

src/sys/ptrace.rs

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

0 commit comments

Comments
 (0)