From 1b4cf9135eca34bfbc86e247860982787e65173a Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 12 Apr 2019 17:18:54 +0000 Subject: [PATCH] Expose si_addr on siginfo_t. Refs #716 --- src/unix/linux_like/linux/gnu/mod.rs | 133 ++++++++++++++++++++++++--- 1 file changed, 120 insertions(+), 13 deletions(-) diff --git a/src/unix/linux_like/linux/gnu/mod.rs b/src/unix/linux_like/linux/gnu/mod.rs index cbca5a32363ee..98e44df700c4f 100644 --- a/src/unix/linux_like/linux/gnu/mod.rs +++ b/src/unix/linux_like/linux/gnu/mod.rs @@ -2,6 +2,126 @@ pub type pthread_t = c_ulong; pub type __priority_which_t = ::c_uint; pub type __rlimit_resource_t = ::c_uint; +cfg_if! { + if #[cfg(libc_union)] { + #[repr(C)] + #[derive(Copy, Clone)] + struct addr_bnd_t { + lower: *mut ::c_void, + upper: *mut ::c_void, + } + + #[repr(C)] + #[derive(Copy, Clone)] + union sigfault_t_anonymous_union { + addr_bnd: addr_bnd_t, + pkey: u32, + } + + #[repr(C)] + #[derive(Copy, Clone)] + struct sigfault_t { + addr: *mut ::c_void, + #[cfg(target_arch = "sparc")] + trapno: ::c_int, + addr_lsb: ::c_short, + anonymous_union: sigfault_t_anonymous_union, + } + + cfg_if! { + if #[cfg(target_pointer_width = "64")] { + type SI_PADDING = [::c_int; 28]; + } else { + type SI_PADDING = [::c_int; 29]; + } + } + + #[repr(C)] + #[derive(Copy, Clone)] + union sifields_t { + _pad: SI_PADDING, + sigfault: sigfault_t, + } + + impl ::fmt::Debug for sigfault_t_anonymous_union { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + // Excludes the fields because we can't know which is valid + f.debug_struct("sigfault_t_anonymous_union") + .finish() + } + } + + impl ::fmt::Debug for sigfault_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + // TODO: include trapno on Sparc + f.debug_struct("sigfault_t") + .field("addr", &self.addr) + .field("addr_lsb", &self.addr_lsb) + .field("anonymous_union", &self.anonymous_union) + .finish() + } + } + + impl ::fmt::Debug for sifields_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + // No way to print anything more detailed without the + // discriminant from siginfo_t + f.debug_struct("sifields_t").finish() + } + } + } else { + type sifields_t = [::c_int; 29]; + } +} + +s_no_extra_traits! { + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + sifields: sifields_t, + + #[cfg(target_arch = "x86_64")] + _align: [u64; 0], + #[cfg(not(target_arch = "x86_64"))] + _align: [usize; 0], + } +} + +cfg_if! { + if #[cfg(libc_union)] { + impl siginfo_t { + pub unsafe fn si_addr(&self) -> *mut ::c_void { + self.sifields.sigfault.addr + } + } + } else { + impl siginfo_t { + pub unsafe fn si_addr(&self) -> *mut ::c_void { + #[repr(C)] + struct siginfo_sigfault { + _si_signo: ::c_int, + _si_errno: ::c_int, + _si_code: ::c_int, + si_addr: *mut ::c_void + } + (*(self as *const siginfo_t as *const siginfo_sigfault)).si_addr + } + } + } +} + +impl ::fmt::Debug for siginfo_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + // TODO: include fields from sifields + f.debug_struct("siginfo_t") + .field("si_signo", &self.si_signo) + .field("si_errno", &self.si_errno) + .field("si_code", &self.si_code) + .finish() + } +} + s! { pub struct statx { pub stx_mask: u32, @@ -182,19 +302,6 @@ s! { } } -impl siginfo_t { - pub unsafe fn si_addr(&self) -> *mut ::c_void { - #[repr(C)] - struct siginfo_sigfault { - _si_signo: ::c_int, - _si_errno: ::c_int, - _si_code: ::c_int, - si_addr: *mut ::c_void - } - (*(self as *const siginfo_t as *const siginfo_sigfault)).si_addr - } -} - s_no_extra_traits! { pub struct utmpx { pub ut_type: ::c_short,