nix
nix copied to clipboard
arm64 android missing a bunch of ptrace apis?
I'm on a bit of a yakshave here, but hopefully this is comprehensible.
I'm working on porting minidump_writer_linux to ARM64 Android.
One of its primary jobs is to grab the registers of every thread and dump them to a file. It currently uses the ptrace::getregs and (getfpregs) call to get them on x64.
Unfortunately, nix seems to explicitly if-def around this possibility:
/// Get user registers, as with `ptrace(PTRACE_GETREGS, ...)`
#[cfg(all(
target_os = "linux",
any(all(target_arch = "x86_64",
any(target_env = "gnu", target_env = "musl")),
all(target_arch = "x86", target_env = "gnu"))
))]
pub fn getregs(pid: Pid) -> Result<user_regs_struct> {
ptrace_get_data::<user_regs_struct>(Request::PTRACE_GETREGS, pid)
}
I expect part of the reason for this is because the ARM64 simd registers are defined in terms of __int128 which is known to not be FFI-safe in rust due to a long-standing llvm bug (that also makes clang and gcc have incompatible ABIs for SysV x64 __int128-passed-on-stack)!
However I have recently demonstrated that this isn't actually an issue on ARM64, where llvm uses the right definition everywhere (and rust and clang both inherit it).
I have a PR in place to introduce conditional typedefs in libc so there is in some sense a "higher authority" you can rely on for where these types are safe, and use the kernel definitions for the register save structs.
Is all of this sufficient to properly add getregs/getfpregs for ARM64 android/linux, or are there other outstanding issues? I'm not really sure how to "look up" what parts of ptrace work specifically on specific linux/android targets -- the ptrace docs note that getregs/getfpregs aren't actually available on all platforms, and it looks like getregset exists as the "new" replacement? It's fine if we just need to expose that instead.
Alternatively if Android is just really weird and has none of this: what are you supposed to use for this functionality?
You can certainly try implementing that stuff for arm64. The main reason that Nix doesn't already is simply because ptrace is complicated and non-portable, so nobody's done it yet. Plus, we didn't use to have any CI for aarch64, but now we do!
Some investigation running this test file on ARM64 android via termux:
- ptrace GETREGS/GETFPREGS doesn't exist
- ptrace GETREGSET (NT_PRSTATUS, NT_PRFPREG) does exist
And emits:
- NT_PRSTATUS: user_regs_struct (actually user_pt_regs, but identical layout)
- NT_PRFPREG: user_fpsimd_state (actually fxregs_state, but identical layout)
Brain completely fried by how terrible linux docs/headers are to dig through, will look at this more later...
I am interested in implementing nix::ptrace::getregset()
. But it seems that this function should be unsafe
and I didn't find any other pub unsafe
functions under the ptrace
mod.
My plan is to write a function:
pub unsafe fn getregset(pid: Pid, addr: libc::size_t, data: *mut c_void) -> Result<()>
But it doesn't look rusty enough. Any advice to get me started?