diff --git a/libc-test/build.rs b/libc-test/build.rs index a4f65ba0e9247..b2bc6740f70e7 100755 --- a/libc-test/build.rs +++ b/libc-test/build.rs @@ -1744,6 +1744,7 @@ fn test_freebsd(target: &str) { "limits.h", "link.h", "locale.h", + "machine/elf.h", "machine/reg.h", "malloc_np.h", "mqueue.h", @@ -1818,7 +1819,8 @@ fn test_freebsd(target: &str) { cfg.type_name(move |ty, is_struct, is_union| { match ty { // Just pass all these through, no need for a "struct" prefix - "FILE" | "fd_set" | "Dl_info" | "DIR" | "Elf32_Phdr" | "Elf64_Phdr" => ty.to_string(), + "FILE" | "fd_set" | "Dl_info" | "DIR" | "Elf32_Phdr" | "Elf64_Phdr" + | "Elf32_Auxinfo" | "Elf64_Auxinfo" => ty.to_string(), // FIXME: https://github.com/rust-lang/libc/issues/1273 "sighandler_t" => "sig_t".to_string(), @@ -2036,6 +2038,9 @@ fn test_freebsd(target: &str) { // is PATH_MAX long but tests can't accept multi array as equivalent. ("kinfo_vmentry", "kve_path") => true, + // a_un field is a union + ("Elf32_Auxinfo", "a_un") => true, + ("Elf64_Auxinfo", "a_un") => true, _ => false, } }); diff --git a/libc-test/semver/freebsd-x86_64.txt b/libc-test/semver/freebsd-x86_64.txt index 2b170e7d6ae00..8edfb525633db 100644 --- a/libc-test/semver/freebsd-x86_64.txt +++ b/libc-test/semver/freebsd-x86_64.txt @@ -1,3 +1,4 @@ +Elf64_Auxinfo MAP_32BIT _MC_FLAG_MASK _MC_FPFMT_NODEV diff --git a/libc-test/semver/freebsd.txt b/libc-test/semver/freebsd.txt index 497687a0e49d3..f353baf2e9f84 100644 --- a/libc-test/semver/freebsd.txt +++ b/libc-test/semver/freebsd.txt @@ -76,11 +76,25 @@ ATF_COM ATF_PERM ATF_PUBL ATF_USETRAILERS +AT_BASE AT_EACCESS +AT_EGID +AT_ENTRY +AT_EUID +AT_EXECPATH AT_FDCWD +AT_FLAGS +AT_GID +AT_NOTELF +AT_NULL +AT_PAGESZ +AT_PHDR +AT_PHENT +AT_PHNUM AT_REMOVEDIR AT_SYMLINK_FOLLOW AT_SYMLINK_NOFOLLOW +AT_UID B14400 B28800 B460800 @@ -269,6 +283,7 @@ EXTATTR_NAMESPACE_USER EXTB EXTPROC Elf32_Addr +Elf32_Auxinfo Elf32_Half Elf32_Lword Elf32_Off diff --git a/src/unix/bsd/freebsdlike/freebsd/mod.rs b/src/unix/bsd/freebsdlike/freebsd/mod.rs index f75970ed5c0b0..51b1fa074d903 100644 --- a/src/unix/bsd/freebsdlike/freebsd/mod.rs +++ b/src/unix/bsd/freebsdlike/freebsd/mod.rs @@ -266,6 +266,17 @@ s_no_extra_traits! { __unused1: ::c_int, __unused2: [::c_long; 7] } + + #[cfg(libc_union)] + pub union __c_anonymous_elf32_auxv_union { + pub a_val: ::c_int, + } + + pub struct Elf32_Auxinfo { + pub a_type: ::c_int, + #[cfg(libc_union)] + pub a_un: __c_anonymous_elf32_auxv_union, + } } cfg_if! { @@ -486,6 +497,37 @@ cfg_if! { self.sigev_notify_thread_id.hash(state); } } + #[cfg(libc_union)] + impl PartialEq for __c_anonymous_elf32_auxv_union { + fn eq(&self, other: &__c_anonymous_elf32_auxv_union) -> bool { + unsafe { self.a_val == other.a_val} + } + } + #[cfg(libc_union)] + impl Eq for __c_anonymous_elf32_auxv_union {} + #[cfg(libc_union)] + impl ::fmt::Debug for __c_anonymous_elf32_auxv_union { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("a_val") + .field("a_val", unsafe { &self.a_val }) + .finish() + } + } + impl PartialEq for Elf32_Auxinfo { + fn eq(&self, other: &Elf32_Auxinfo) -> bool { + self.a_type == other.a_type + && self.a_un == other.a_un + } + } + impl Eq for Elf32_Auxinfo {} + impl ::fmt::Debug for Elf32_Auxinfo { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("Elf32_Auxinfo") + .field("a_type", &self.a_type) + .field("a_un", &self.a_un) + .finish() + } + } } } @@ -1266,6 +1308,23 @@ pub const AT_SYMLINK_NOFOLLOW: ::c_int = 0x200; pub const AT_SYMLINK_FOLLOW: ::c_int = 0x400; pub const AT_REMOVEDIR: ::c_int = 0x800; +pub const AT_NULL: ::c_int = 0; +pub const AT_IGNORE: ::c_int = 1; +pub const AT_EXECFD: ::c_int = 2; +pub const AT_PHDR: ::c_int = 3; +pub const AT_PHENT: ::c_int = 4; +pub const AT_PHNUM: ::c_int = 5; +pub const AT_PAGESZ: ::c_int = 6; +pub const AT_BASE: ::c_int = 7; +pub const AT_FLAGS: ::c_int = 8; +pub const AT_ENTRY: ::c_int = 9; +pub const AT_NOTELF: ::c_int = 10; +pub const AT_UID: ::c_int = 11; +pub const AT_EUID: ::c_int = 12; +pub const AT_GID: ::c_int = 13; +pub const AT_EGID: ::c_int = 14; +pub const AT_EXECPATH: ::c_int = 15; + pub const TABDLY: ::tcflag_t = 0x00000004; pub const TAB0: ::tcflag_t = 0x00000000; pub const TAB3: ::tcflag_t = 0x00000004; diff --git a/src/unix/bsd/freebsdlike/freebsd/x86_64/mod.rs b/src/unix/bsd/freebsdlike/freebsd/x86_64/mod.rs index d3333c8b11aea..98777a028c2ac 100644 --- a/src/unix/bsd/freebsdlike/freebsd/x86_64/mod.rs +++ b/src/unix/bsd/freebsdlike/freebsd/x86_64/mod.rs @@ -80,6 +80,19 @@ s_no_extra_traits! { pub xmm_reg: [[u8; 16]; 8], pub xmm_pad: [u8; 224], } + + #[cfg(libc_union)] + pub union __c_anonymous_elf64_auxv_union { + pub a_val: ::c_long, + pub a_ptr: *mut ::c_void, + pub a_fcn: extern "C" fn(), + } + + pub struct Elf64_Auxinfo { + pub a_type: ::c_long, + #[cfg(libc_union)] + pub a_un: __c_anonymous_elf64_auxv_union, + } } cfg_if! { @@ -173,6 +186,43 @@ cfg_if! { self.xmm_pad.hash(state); } } + + #[cfg(libc_union)] + impl PartialEq for __c_anonymous_elf64_auxv_union { + fn eq(&self, other: &__c_anonymous_elf64_auxv_union) -> bool { + unsafe { self.a_val == other.a_val + || self.a_ptr == other.a_ptr + || self.a_fcn == other.a_fcn } + } + } + #[cfg(libc_union)] + impl Eq for __c_anonymous_elf64_auxv_union {} + #[cfg(libc_union)] + impl ::fmt::Debug for __c_anonymous_elf64_auxv_union { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("a_val") + .field("a_val", unsafe { &self.a_val }) + .finish() + } + } + #[cfg(target_pointer_width = "64")] + impl PartialEq for Elf64_Auxinfo { + fn eq(&self, other: &Elf64_Auxinfo) -> bool { + self.a_type == other.a_type + && self.a_un == other.a_un + } + } + #[cfg(target_pointer_width = "64")] + impl Eq for Elf64_Auxinfo {} + #[cfg(target_pointer_width = "64")] + impl ::fmt::Debug for Elf64_Auxinfo { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("Elf64_Auxinfo") + .field("a_type", &self.a_type) + .field("a_un", &self.a_un) + .finish() + } + } } }