diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 31fdb8ed4..21df08597 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -54,6 +54,7 @@ jobs: cargo update --package=half --precise=2.2.1 cargo update --package=flate2 --precise=1.0.35 cargo update --package=serde --precise=1.0.228 + cargo update --package=web-sys --precise=0.3.104 cargo update --package=syn --precise=2.0.106 cargo update --package=textwrap --precise=0.16.1 cargo update --package=parking_lot --precise=0.12.4 @@ -596,6 +597,7 @@ jobs: cargo update --package=half --precise=2.2.1 cargo update --package=flate2 --precise=1.0.35 cargo update --package=serde --precise=1.0.228 + cargo update --package=web-sys --precise=0.3.104 cargo update --package=syn --precise=2.0.106 cargo update --package=textwrap --precise=0.16.1 cargo update --package=parking_lot --precise=0.12.4 diff --git a/src/backend/libc/fs/dir.rs b/src/backend/libc/fs/dir.rs index 65742876a..19a909078 100644 --- a/src/backend/libc/fs/dir.rs +++ b/src/backend/libc/fs/dir.rs @@ -30,6 +30,8 @@ use crate::io; #[cfg(not(any(target_os = "fuchsia", target_os = "vita", target_os = "wasi")))] #[cfg(feature = "process")] use crate::process::fchdir; +#[cfg(target_os = "openbsd")] +use crate::types::Padding; use alloc::borrow::ToOwned as _; #[cfg(not(any(linux_like, target_os = "hurd")))] use c::readdir as libc_readdir; @@ -408,7 +410,7 @@ struct libc_dirent { d_reclen: u16, d_type: u8, d_namlen: u8, - __d_padding: [u8; 4], + __d_padding: Padding<[u8; 4]>, d_name: [c::c_char; 256], } @@ -434,7 +436,7 @@ fn check_dirent_layout(dirent: &c::dirent) { d_reclen: 0_u16, d_type: 0_u8, d_namlen: 0_u8, - __d_padding: [0_u8; 4], + __d_padding: Default::default(), d_name: [0 as c::c_char; 256], }; let base = as_ptr(&z) as usize; diff --git a/src/backend/libc/fs/types.rs b/src/backend/libc/fs/types.rs index 4e5bcbc6a..2b0c9cc5e 100644 --- a/src/backend/libc/fs/types.rs +++ b/src/backend/libc/fs/types.rs @@ -1,5 +1,7 @@ use crate::backend::c; use crate::ffi; +#[cfg(target_os = "netbsd")] +use crate::types::Padding; use bitflags::bitflags; #[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))] @@ -1054,7 +1056,7 @@ pub struct Stat { pub st_blksize: c::blksize_t, pub st_flags: u32, pub st_gen: u32, - pub st_spare: [u32; 2], + pub(crate) st_spare: Padding<[u32; 2]>, } /// `struct statfs` for use with [`statfs`] and [`fstatfs`]. diff --git a/src/backend/linux_raw/fs/types.rs b/src/backend/linux_raw/fs/types.rs index 7abd66539..aaa82defa 100644 --- a/src/backend/linux_raw/fs/types.rs +++ b/src/backend/linux_raw/fs/types.rs @@ -1,4 +1,6 @@ use crate::ffi; +#[allow(unused_imports)] +use crate::types::Padding; use bitflags::bitflags; bitflags! { @@ -640,7 +642,7 @@ pub struct Stat { pub st_mode: ffi::c_uint, pub st_uid: ffi::c_uint, pub st_gid: ffi::c_uint, - pub(crate) __pad0: ffi::c_uint, + pub(crate) __pad0: Padding, pub st_rdev: ffi::c_ulong, pub st_size: ffi::c_long, pub st_blksize: ffi::c_long, @@ -651,7 +653,7 @@ pub struct Stat { pub st_mtime_nsec: ffi::c_ulong, pub st_ctime: ffi::c_long, pub st_ctime_nsec: ffi::c_ulong, - pub(crate) __unused: [ffi::c_long; 3], + pub(crate) __unused: Padding<[ffi::c_long; 3]>, } #[repr(C)] #[derive(Debug, Copy, Clone)] @@ -666,10 +668,10 @@ pub struct Stat { pub st_uid: ffi::c_uint, pub st_gid: ffi::c_uint, pub st_rdev: ffi::c_ulong, - pub(crate) __pad1: ffi::c_ulong, + pub(crate) __pad1: Padding, pub st_size: ffi::c_long, pub st_blksize: ffi::c_int, - pub(crate) __pad2: ffi::c_int, + pub(crate) __pad2: Padding, pub st_blocks: ffi::c_long, pub st_atime: ffi::c_long, pub st_atime_nsec: ffi::c_ulong, @@ -677,8 +679,8 @@ pub struct Stat { pub st_mtime_nsec: ffi::c_ulong, pub st_ctime: ffi::c_long, pub st_ctime_nsec: ffi::c_ulong, - pub(crate) __unused4: ffi::c_uint, - pub(crate) __unused5: ffi::c_uint, + pub(crate) __unused4: Padding, + pub(crate) __unused5: Padding, } #[repr(C)] #[derive(Debug, Copy, Clone)] @@ -693,10 +695,10 @@ pub struct Stat { pub st_uid: ffi::c_uint, pub st_gid: ffi::c_uint, pub st_rdev: ffi::c_ulong, - pub(crate) __pad1: ffi::c_ulong, + pub(crate) __pad1: Padding, pub st_size: ffi::c_long, pub st_blksize: ffi::c_int, - pub(crate) __pad2: ffi::c_int, + pub(crate) __pad2: Padding, pub st_blocks: ffi::c_long, pub st_atime: ffi::c_long, pub st_atime_nsec: ffi::c_ulong, @@ -704,8 +706,8 @@ pub struct Stat { pub st_mtime_nsec: ffi::c_ulong, pub st_ctime: ffi::c_long, pub st_ctime_nsec: ffi::c_ulong, - pub(crate) __unused4: ffi::c_uint, - pub(crate) __unused5: ffi::c_uint, + pub(crate) __unused4: Padding, + pub(crate) __unused5: Padding, } // This follows `stat`. powerpc64 defines a `stat64` but it's not used. #[repr(C)] @@ -730,9 +732,9 @@ pub struct Stat { pub st_mtime_nsec: ffi::c_ulong, pub st_ctime: ffi::c_long, pub st_ctime_nsec: ffi::c_ulong, - pub(crate) __unused4: ffi::c_ulong, - pub(crate) __unused5: ffi::c_ulong, - pub(crate) __unused6: ffi::c_ulong, + pub(crate) __unused4: Padding, + pub(crate) __unused5: Padding, + pub(crate) __unused6: Padding, } #[repr(C)] #[derive(Debug, Copy, Clone)] @@ -746,7 +748,7 @@ pub struct Stat { pub st_mode: ffi::c_uint, pub st_uid: ffi::c_uint, pub st_gid: ffi::c_uint, - pub(crate) __pad1: ffi::c_uint, + pub(crate) __pad1: Padding, pub st_rdev: ffi::c_ulong, pub st_size: ffi::c_long, // Linux has `c_ulong` but we make it signed. pub st_atime: ffi::c_long, @@ -757,7 +759,7 @@ pub struct Stat { pub st_ctime_nsec: ffi::c_ulong, pub st_blksize: ffi::c_ulong, pub st_blocks: ffi::c_long, - pub(crate) __unused: [ffi::c_ulong; 3], + pub(crate) __unused: Padding<[ffi::c_ulong; 3]>, } /// `struct statfs` for use with [`statfs`] and [`fstatfs`]. @@ -795,9 +797,9 @@ pub struct StatFs { #[cfg(any(target_arch = "arm", target_arch = "s390x"))] pub f_flags: ffi::c_uint, #[cfg(not(target_arch = "s390x"))] - pub(crate) f_spare: [ffi::c_long; 4], + pub(crate) f_spare: Padding<[ffi::c_long; 4]>, #[cfg(target_arch = "s390x")] - pub(crate) f_spare: [ffi::c_uint; 5], + pub(crate) f_spare: Padding<[ffi::c_uint; 5]>, } /// `fsid_t` for use with [`StatFs`]. diff --git a/src/event/epoll.rs b/src/event/epoll.rs index 839f05de6..2a747be5d 100644 --- a/src/event/epoll.rs +++ b/src/event/epoll.rs @@ -80,6 +80,8 @@ use crate::buffer::Buffer; use crate::fd::{AsFd, OwnedFd}; use crate::io; use crate::timespec::Timespec; +#[cfg(target_pointer_width = "32")] +use crate::types::Padding; use core::ffi::c_void; use core::hash::{Hash, Hasher}; @@ -276,7 +278,7 @@ impl EventData { sixty_four_bit_pointer: SixtyFourBitPointer { pointer: value, #[cfg(target_pointer_width = "32")] - _padding: 0, + _padding: Padding::new(0), }, } } @@ -321,13 +323,13 @@ impl Hash for EventData { struct SixtyFourBitPointer { #[cfg(target_endian = "big")] #[cfg(target_pointer_width = "32")] - _padding: u32, + _padding: Padding, pointer: *mut c_void, #[cfg(target_endian = "little")] #[cfg(target_pointer_width = "32")] - _padding: u32, + _padding: Padding, } #[cfg(test)] diff --git a/src/fs/statx.rs b/src/fs/statx.rs index f8be29f7d..b03cfac39 100644 --- a/src/fs/statx.rs +++ b/src/fs/statx.rs @@ -2,6 +2,7 @@ use crate::fd::AsFd; use crate::fs::AtFlags; +use crate::types::Padding; use crate::{backend, io, path}; use backend::c; use bitflags::bitflags; @@ -24,7 +25,7 @@ pub struct Statx { pub stx_uid: u32, pub stx_gid: u32, pub stx_mode: u16, - pub(crate) __spare0: [u16; 1], + pub(crate) __spare0: Padding<[u16; 1]>, pub stx_ino: u64, pub stx_size: u64, pub stx_blocks: u64, @@ -46,8 +47,8 @@ pub struct Statx { pub stx_atomic_write_segments_max: u32, pub stx_dio_read_offset_align: u32, pub stx_atomic_write_unit_max_opt: u32, - pub __spare2: [u32; 1usize], - pub __spare3: [u64; 8usize], + pub(crate) __spare2: Padding<[u32; 1usize]>, + pub(crate) __spare3: Padding<[u64; 8usize]>, } /// `struct statx_timestamp` for use with [`Statx`]. @@ -61,7 +62,7 @@ pub struct StatxTimestamp { /// Nanoseconds. Must be less than 1_000_000_000. pub tv_nsec: u32, - pub(crate) __reserved: i32, + pub(crate) __reserved: Padding, } bitflags! { diff --git a/src/lib.rs b/src/lib.rs index c8d000332..5711115d8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -178,6 +178,8 @@ pub(crate) mod bitcast; #[cfg(sanitize_memory)] pub(crate) mod msan; +mod types; + // linux_raw: Weak symbols are used by the use-libc-auxv feature for // glibc 2.15 support. // diff --git a/src/termios/types.rs b/src/termios/types.rs index 71d9fb80b..dfc6eed86 100644 --- a/src/termios/types.rs +++ b/src/termios/types.rs @@ -2,6 +2,8 @@ use crate::backend::c; use crate::backend::termios::types; #[cfg(target_os = "nto")] use crate::ffi; +#[cfg(target_os = "nto")] +use crate::types::Padding; use crate::{backend, io}; use bitflags::bitflags; @@ -46,7 +48,7 @@ pub struct Termios { pub special_codes: SpecialCodes, #[cfg(target_os = "nto")] - pub(crate) __reserved: [ffi::c_uint; 3], + pub(crate) __reserved: Padding<[ffi::c_uint; 3]>, /// Line discipline. // On PowerPC, this field comes after `c_cc`. diff --git a/src/thread/futex.rs b/src/thread/futex.rs index 9862997d4..4d55bb5fb 100644 --- a/src/thread/futex.rs +++ b/src/thread/futex.rs @@ -34,6 +34,7 @@ use core::sync::atomic::AtomicU32; use crate::backend::thread::futex::Operation; use crate::backend::thread::syscalls::{futex_timeout, futex_val2}; use crate::fd::{FromRawFd as _, OwnedFd, RawFd}; +use crate::types::Padding; use crate::{backend, io}; pub use crate::clockid::ClockId; @@ -532,7 +533,7 @@ pub struct Wait { pub flags: WaitFlags, /// Reserved for future use. - pub(crate) __reserved: u32, + pub(crate) __reserved: Padding, } impl Wait { @@ -543,7 +544,7 @@ impl Wait { val: 0, uaddr: WaitPtr::new(ptr::null_mut()), flags: WaitFlags::empty(), - __reserved: 0, + __reserved: Padding::new(0), } } } diff --git a/src/types.rs b/src/types.rs new file mode 100644 index 000000000..edaf17eb2 --- /dev/null +++ b/src/types.rs @@ -0,0 +1,40 @@ +//! Platform-agnostic support types. +//! +//! Copied from https://github.com/rust-lang/libc/blob/008f905256d27eb5dd416d0976678ee6c2855554/src/types.rs + +use core::fmt; +use core::mem::MaybeUninit; + +/// A transparent wrapper over `MaybeUninit` to represent uninitialized padding +/// while providing `Default`. +// This is restricted to `Copy` types since that's a loose indicator that zeros is actually +// a valid bitpattern. There is no technical reason this is required, though, so it could be +// lifted in the future if it becomes a problem. +#[allow(dead_code)] +#[repr(transparent)] +#[derive(Clone, Copy)] +pub(crate) struct Padding(MaybeUninit); + +impl Default for Padding { + fn default() -> Self { + Self(MaybeUninit::zeroed()) + } +} + +impl Padding { + /// Create a `Padding` initialized with the given value. + #[allow(dead_code)] + pub(crate) const fn new(val: T) -> Self { + Self(MaybeUninit::new(val)) + } +} + +impl fmt::Debug for Padding { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // Taken from `MaybeUninit`'s debug implementation + // NB: there is no `.pad_fmt` so we can't use a simpler `format_args!("Padding<{..}>"). + let full_name = core::any::type_name::(); + let prefix_len = full_name.find("Padding").unwrap(); + f.pad(&full_name[prefix_len..]) + } +}