diff --git a/CHANGELOG.md b/CHANGELOG.md index c29e7a165f..d4031b26f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). ([#972](https://github.com/nix-rust/nix/pull/972)) - Added `symlinkat` wrapper. ([#997](https://github.com/nix-rust/nix/pull/997)) +- Added `ptrace::{getregs, setregs}`. + ([#1010](https://github.com/nix-rust/nix/pull/1010)) ### Changed ### Fixed @@ -46,7 +48,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Added a `fchownat` wrapper. ([#955](https://github.com/nix-rust/nix/pull/955)) - Added support for `ptrace` on BSD operating systems ([#949](https://github.com/nix-rust/nix/pull/949)) -- Added `ptrace` functions for reads and writes to tracee memory and ptrace kill +- Added `ptrace` functions for reads and writes to tracee memory and ptrace kill ([#949](https://github.com/nix-rust/nix/pull/949)) ([#958](https://github.com/nix-rust/nix/pull/958)) - Added a `acct` wrapper module for enabling and disabling process accounting ([#952](https://github.com/nix-rust/nix/pull/952)) diff --git a/src/sys/ptrace/linux.rs b/src/sys/ptrace/linux.rs index f10c6d837c..54e453ba17 100644 --- a/src/sys/ptrace/linux.rs +++ b/src/sys/ptrace/linux.rs @@ -9,6 +9,12 @@ use sys::signal::Signal; pub type AddressType = *mut ::libc::c_void; +#[cfg(all(target_os = "linux", + any(target_arch = "x86_64", + target_arch = "x86"), + target_env = "gnu"))] +use libc::user_regs_struct; + cfg_if! { if #[cfg(any(all(target_os = "linux", target_arch = "s390x"), all(target_os = "linux", target_env = "gnu")))] { @@ -192,6 +198,30 @@ fn ptrace_peek(request: Request, pid: Pid, addr: AddressType, data: *mut c_void) } } +/// Get user registers, as with `ptrace(PTRACE_GETREGS, ...)` +#[cfg(all(target_os = "linux", + any(target_arch = "x86_64", + target_arch = "x86"), + target_env = "gnu"))] +pub fn getregs(pid: Pid) -> Result { + ptrace_get_data::(Request::PTRACE_GETREGS, pid) +} + +/// Set user registers, as with `ptrace(PTRACE_SETREGS, ...)` +#[cfg(all(target_os = "linux", + any(target_arch = "x86_64", + target_arch = "x86"), + target_env = "gnu"))] +pub fn setregs(pid: Pid, regs: user_regs_struct) -> Result<()> { + let res = unsafe { + libc::ptrace(Request::PTRACE_SETREGS as RequestType, + libc::pid_t::from(pid), + ptr::null_mut::(), + ®s as *const _ as *const c_void) + }; + Errno::result(res).map(drop) +} + /// Function for ptrace requests that return values from the data field. /// Some ptrace get requests populate structs or larger elements than `c_long` /// and therefore use the data field to return values. This function handles these @@ -215,8 +245,6 @@ unsafe fn ptrace_other(request: Request, pid: Pid, addr: AddressType, data: *mut /// Set options, as with `ptrace(PTRACE_SETOPTIONS,...)`. pub fn setoptions(pid: Pid, options: Options) -> Result<()> { - use std::ptr; - let res = unsafe { libc::ptrace(Request::PTRACE_SETOPTIONS as RequestType, libc::pid_t::from(pid),