diff --git a/libc-test/build.rs b/libc-test/build.rs index 552642fe..35a04200 100755 --- a/libc-test/build.rs +++ b/libc-test/build.rs @@ -287,9 +287,11 @@ fn test_openbsd(target: &str) { cfg.flag("-Wno-deprecated-declarations"); headers! { cfg: + "elf.h", "errno.h", "fcntl.h", "limits.h", + "link.h", "locale.h", "stddef.h", "stdint.h", @@ -387,7 +389,9 @@ fn test_openbsd(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" | "DIR" | "Dl_info" => ty.to_string(), + "FILE" | "DIR" | "Dl_info" | "Elf32_Phdr" | "Elf64_Phdr" => { + ty.to_string() + } // OSX calls this something else "sighandler_t" => "sig_t".to_string(), @@ -418,6 +422,15 @@ fn test_openbsd(target: &str) { struct_ == "siginfo_t" && field == "si_addr" }); + cfg.skip_field(|struct_, field| { + match (struct_, field) { + // conflicting with `p_type` macro from . + ("Elf32_Phdr", "p_type") => true, + ("Elf64_Phdr", "p_type") => true, + _ => false, + } + }); + cfg.generate("../src/lib.rs", "main.rs"); } @@ -870,9 +883,11 @@ fn test_netbsd(target: &str) { headers! { cfg: + "elf.h", "errno.h", "fcntl.h", "limits.h", + "link.h", "locale.h", "stddef.h", "stdint.h", @@ -1061,6 +1076,15 @@ fn test_netbsd(target: &str) { (struct_ == "aiocb" && field == "aio_buf") }); + cfg.skip_field(|struct_, field| { + match (struct_, field) { + // conflicting with `p_type` macro from . + ("Elf32_Phdr", "p_type") => true, + ("Elf64_Phdr", "p_type") => true, + _ => false, + } + }); + cfg.generate("../src/lib.rs", "main.rs"); } @@ -1633,6 +1657,7 @@ fn test_freebsd(target: &str) { "ctype.h", "dirent.h", "dlfcn.h", + "elf.h", "errno.h", "fcntl.h", "glob.h", @@ -1641,6 +1666,7 @@ fn test_freebsd(target: &str) { "langinfo.h", "libutil.h", "limits.h", + "link.h", "locale.h", "machine/reg.h", "mqueue.h", @@ -1709,7 +1735,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" => ty.to_string(), + "FILE" | "fd_set" | "Dl_info" | "DIR" | "Elf32_Phdr" + | "Elf64_Phdr" => ty.to_string(), // FIXME: https://github.com/rust-lang/libc/issues/1273 "sighandler_t" => "sig_t".to_string(), @@ -1909,6 +1936,10 @@ fn test_freebsd(target: &str) { // `void*`: ("stack_t", "ss_sp") if Some(10) == freebsd_ver => true, + // conflicting with `p_type` macro from . + ("Elf32_Phdr", "p_type") => true, + ("Elf64_Phdr", "p_type") => true, + _ => false, } }); diff --git a/src/unix/bsd/freebsdlike/freebsd/mod.rs b/src/unix/bsd/freebsdlike/freebsd/mod.rs index bfd60636..e65c048d 100644 --- a/src/unix/bsd/freebsdlike/freebsd/mod.rs +++ b/src/unix/bsd/freebsdlike/freebsd/mod.rs @@ -1502,7 +1502,7 @@ extern "C" { pub fn nmount( iov: *mut ::iovec, niov: ::c_uint, - flags: ::c_int + flags: ::c_int, ) -> ::c_int; } diff --git a/src/unix/bsd/freebsdlike/mod.rs b/src/unix/bsd/freebsdlike/mod.rs index 7bf9399d..a9b0149a 100644 --- a/src/unix/bsd/freebsdlike/mod.rs +++ b/src/unix/bsd/freebsdlike/mod.rs @@ -14,6 +14,38 @@ pub type nl_item = ::c_int; pub type id_t = i64; pub type vm_size_t = ::uintptr_t; +// elf.h + +pub type Elf32_Addr = u32; +pub type Elf32_Half = u16; +pub type Elf32_Lword = u64; +pub type Elf32_Off = u32; +pub type Elf32_Sword = i32; +pub type Elf32_Word = u32; + +pub type Elf64_Addr = u64; +pub type Elf64_Half = u16; +pub type Elf64_Lword = u64; +pub type Elf64_Off = u64; +pub type Elf64_Sword = i32; +pub type Elf64_Sxword = i64; +pub type Elf64_Word = u32; +pub type Elf64_Xword = u64; + +cfg_if! { + if #[cfg(target_pointer_width = "64")] { + type Elf_Addr = Elf64_Addr; + type Elf_Half = Elf64_Half; + type Elf_Phdr = Elf64_Phdr; + } else if #[cfg(target_pointer_width = "32")] { + type Elf_Addr = Elf32_Addr; + type Elf_Half = Elf32_Half; + type Elf_Phdr = Elf32_Phdr; + } +} + +// link.h + #[cfg_attr(feature = "extra_traits", derive(Debug))] pub enum timezone {} impl ::Copy for timezone {} @@ -233,6 +265,43 @@ s! { pub piod_addr: *mut ::c_void, pub piod_len: ::size_t, } + + // elf.h + + pub struct Elf32_Phdr { + pub p_type: Elf32_Word, + pub p_offset: Elf32_Off, + pub p_vaddr: Elf32_Addr, + pub p_paddr: Elf32_Addr, + pub p_filesz: Elf32_Word, + pub p_memsz: Elf32_Word, + pub p_flags: Elf32_Word, + pub p_align: Elf32_Word, + } + + pub struct Elf64_Phdr { + pub p_type: Elf64_Word, + pub p_flags: Elf64_Word, + pub p_offset: Elf64_Off, + pub p_vaddr: Elf64_Addr, + pub p_paddr: Elf64_Addr, + pub p_filesz: Elf64_Xword, + pub p_memsz: Elf64_Xword, + pub p_align: Elf64_Xword, + } + + // link.h + + pub struct dl_phdr_info { + pub dlpi_addr: Elf_Addr, + pub dlpi_name: *const ::c_char, + pub dlpi_phdr: *const Elf_Phdr, + pub dlpi_phnum: Elf_Half, + pub dlpi_adds: ::c_ulonglong, + pub dlpi_subs: ::c_ulonglong, + pub dlpi_tls_modid: usize, + pub dlpi_tls_data: *mut ::c_void, + } } s_no_extra_traits! { @@ -1514,6 +1583,18 @@ extern "C" { pub fn ntp_adjtime(buf: *mut timex) -> ::c_int; pub fn ntp_gettime(buf: *mut ntptimeval) -> ::c_int; + + // #include + pub fn dl_iterate_phdr( + callback: ::Option< + unsafe extern "C" fn( + info: *mut dl_phdr_info, + size: usize, + data: *mut ::c_void, + ) -> ::c_int, + >, + data: *mut ::c_void, + ) -> ::c_int; } #[link(name = "rt")] diff --git a/src/unix/bsd/netbsdlike/netbsd/mod.rs b/src/unix/bsd/netbsdlike/netbsd/mod.rs index ee9cda24..4b7dbafc 100644 --- a/src/unix/bsd/netbsdlike/netbsd/mod.rs +++ b/src/unix/bsd/netbsdlike/netbsd/mod.rs @@ -11,6 +11,36 @@ pub type vm_size_t = ::uintptr_t; pub type lwpid_t = ::c_uint; pub type shmatt_t = ::c_uint; +// elf.h + +pub type Elf32_Addr = u32; +pub type Elf32_Half = u16; +pub type Elf32_Lword = u64; +pub type Elf32_Off = u32; +pub type Elf32_Sword = i32; +pub type Elf32_Word = u32; + +pub type Elf64_Addr = u64; +pub type Elf64_Half = u16; +pub type Elf64_Lword = u64; +pub type Elf64_Off = u64; +pub type Elf64_Sword = i32; +pub type Elf64_Sxword = i64; +pub type Elf64_Word = u32; +pub type Elf64_Xword = u64; + +cfg_if! { + if #[cfg(target_pointer_width = "64")] { + type Elf_Addr = Elf64_Addr; + type Elf_Half = Elf64_Half; + type Elf_Phdr = Elf64_Phdr; + } else if #[cfg(target_pointer_width = "32")] { + type Elf_Addr = Elf32_Addr; + type Elf_Half = Elf32_Half; + type Elf_Phdr = Elf32_Phdr; + } +} + impl siginfo_t { pub unsafe fn si_value(&self) -> ::sigval { #[repr(C)] @@ -341,6 +371,42 @@ s! { pub time_state: ::c_int, } + // elf.h + + pub struct Elf32_Phdr { + pub p_type: Elf32_Word, + pub p_offset: Elf32_Off, + pub p_vaddr: Elf32_Addr, + pub p_paddr: Elf32_Addr, + pub p_filesz: Elf32_Word, + pub p_memsz: Elf32_Word, + pub p_flags: Elf32_Word, + pub p_align: Elf32_Word, + } + + pub struct Elf64_Phdr { + pub p_type: Elf64_Word, + pub p_flags: Elf64_Word, + pub p_offset: Elf64_Off, + pub p_vaddr: Elf64_Addr, + pub p_paddr: Elf64_Addr, + pub p_filesz: Elf64_Xword, + pub p_memsz: Elf64_Xword, + pub p_align: Elf64_Xword, + } + + // link.h + + pub struct dl_phdr_info { + pub dlpi_addr: Elf_Addr, + pub dlpi_name: *const ::c_char, + pub dlpi_phdr: *const Elf_Phdr, + pub dlpi_phnum: Elf_Half, + pub dlpi_adds: ::c_ulonglong, + pub dlpi_subs: ::c_ulonglong, + pub dlpi_tls_modid: usize, + pub dlpi_tls_data: *mut ::c_void, + } } s_no_extra_traits! { @@ -2002,6 +2068,19 @@ extern "C" { needle: *const ::c_void, needlelen: ::size_t, ) -> *mut ::c_void; + + // link.h + + pub fn dl_iterate_phdr( + callback: ::Option< + unsafe extern "C" fn( + info: *mut dl_phdr_info, + size: usize, + data: *mut ::c_void, + ) -> ::c_int, + >, + data: *mut ::c_void, + ) -> ::c_int; } #[link(name = "util")] diff --git a/src/unix/bsd/netbsdlike/openbsd/mod.rs b/src/unix/bsd/netbsdlike/openbsd/mod.rs index 4fe134ee..c46f3a41 100644 --- a/src/unix/bsd/netbsdlike/openbsd/mod.rs +++ b/src/unix/bsd/netbsdlike/openbsd/mod.rs @@ -16,6 +16,36 @@ pub type pthread_rwlock_t = *mut ::c_void; pub type pthread_rwlockattr_t = *mut ::c_void; pub type caddr_t = *mut ::c_char; +// elf.h + +pub type Elf32_Addr = u32; +pub type Elf32_Half = u16; +pub type Elf32_Lword = u64; +pub type Elf32_Off = u32; +pub type Elf32_Sword = i32; +pub type Elf32_Word = u32; + +pub type Elf64_Addr = u64; +pub type Elf64_Half = u16; +pub type Elf64_Lword = u64; +pub type Elf64_Off = u64; +pub type Elf64_Sword = i32; +pub type Elf64_Sxword = i64; +pub type Elf64_Word = u32; +pub type Elf64_Xword = u64; + +cfg_if! { + if #[cfg(target_pointer_width = "64")] { + type Elf_Addr = Elf64_Addr; + type Elf_Half = Elf64_Half; + type Elf_Phdr = Elf64_Phdr; + } else if #[cfg(target_pointer_width = "32")] { + type Elf_Addr = Elf32_Addr; + type Elf_Half = Elf32_Half; + type Elf_Phdr = Elf32_Phdr; + } +} + s! { pub struct glob_t { pub gl_pathc: ::size_t, @@ -321,6 +351,38 @@ s! { __shm_ctimensec: c_long, pub shm_internal: *mut ::c_void, } + + // elf.h + pub struct Elf32_Phdr { + pub p_type: Elf32_Word, + pub p_offset: Elf32_Off, + pub p_vaddr: Elf32_Addr, + pub p_paddr: Elf32_Addr, + pub p_filesz: Elf32_Word, + pub p_memsz: Elf32_Word, + pub p_flags: Elf32_Word, + pub p_align: Elf32_Word, + } + + pub struct Elf64_Phdr { + pub p_type: Elf64_Word, + pub p_flags: Elf64_Word, + pub p_offset: Elf64_Off, + pub p_vaddr: Elf64_Addr, + pub p_paddr: Elf64_Addr, + pub p_filesz: Elf64_Xword, + pub p_memsz: Elf64_Xword, + pub p_align: Elf64_Xword, + } + + // link.h + + pub struct dl_phdr_info { + pub dlpi_addr: Elf_Addr, + pub dlpi_name: *const ::c_char, + pub dlpi_phdr: *const Elf_Phdr, + pub dlpi_phnum: Elf_Half, + } } impl siginfo_t { @@ -1482,6 +1544,17 @@ extern "C" { needle: *const ::c_void, needlelen: ::size_t, ) -> *mut ::c_void; + // #include + pub fn dl_iterate_phdr( + callback: ::Option< + unsafe extern "C" fn( + info: *mut dl_phdr_info, + size: usize, + data: *mut ::c_void, + ) -> ::c_int, + >, + data: *mut ::c_void, + ) -> ::c_int; } cfg_if! {