From 8f7839f41bb58eefc7aa64a3eadf1486e4cf171d Mon Sep 17 00:00:00 2001 From: Steven Fackler <sfackler@gmail.com> Date: Fri, 10 Nov 2017 19:58:04 -0800 Subject: [PATCH] Add dl_iterate_phdr and related types A lot of this is more broadly supported than just Linux, but support for those can be added later. --- libc-test/build.rs | 6 ++- src/unix/notbsd/linux/mod.rs | 82 ++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 1 deletion(-) diff --git a/libc-test/build.rs b/libc-test/build.rs index 7b93f2d6..ce3c6f5f 100644 --- a/libc-test/build.rs +++ b/libc-test/build.rs @@ -256,6 +256,8 @@ fn main() { if linux { cfg.header("linux/random.h"); + cfg.header("elf.h"); + cfg.header("link.h"); } if freebsd { @@ -301,7 +303,9 @@ fn main() { "FILE" | "fd_set" | "Dl_info" | - "DIR" => ty.to_string(), + "DIR" | + "Elf32_Phdr" | + "Elf64_Phdr" => ty.to_string(), // Fixup a few types on windows that don't actually exist. "time64_t" if windows => "__time64_t".to_string(), diff --git a/src/unix/notbsd/linux/mod.rs b/src/unix/notbsd/linux/mod.rs index fb9299bb..46cf538f 100644 --- a/src/unix/notbsd/linux/mod.rs +++ b/src/unix/notbsd/linux/mod.rs @@ -23,6 +23,17 @@ pub type __s16 = ::c_short; pub type __u32 = ::c_uint; pub type __s32 = ::c_int; +pub type Elf32_Half = u16; +pub type Elf32_Word = u32; +pub type Elf32_Off = u32; +pub type Elf32_Addr = u32; + +pub type Elf64_Half = u16; +pub type Elf64_Word = u32; +pub type Elf64_Off = u64; +pub type Elf64_Addr = u64; +pub type Elf64_Xword = u64; + pub enum fpos64_t {} // TODO: fill this out with a struct s! { @@ -391,6 +402,52 @@ s! { #[cfg(target_pointer_width = "32")] pub u: [u32; 7], } + + pub struct dl_phdr_info { + #[cfg(target_pointer_width = "64")] + pub dlpi_addr: Elf64_Addr, + #[cfg(target_pointer_width = "32")] + pub dlpi_addr: Elf32_Addr, + + pub dlpi_name: *const ::c_char, + + #[cfg(target_pointer_width = "64")] + pub dlpi_phdr: *const Elf64_Phdr, + #[cfg(target_pointer_width = "32")] + pub dlpi_phdr: *const Elf32_Phdr, + + #[cfg(target_pointer_width = "64")] + pub dlpi_phnum: Elf64_Half, + #[cfg(target_pointer_width = "32")] + pub dlpi_phnum: Elf32_Half, + + pub dlpi_adds: ::c_ulonglong, + pub dlpi_subs: ::c_ulonglong, + pub dlpi_tls_modid: ::size_t, + pub dlpi_tls_data: *mut ::c_void, + } + + 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, + } } pub const ABDAY_1: ::nl_item = 0x20000; @@ -1031,6 +1088,23 @@ pub const CMSPAR: ::tcflag_t = 0o10000000000; pub const MFD_CLOEXEC: ::c_uint = 0x0001; pub const MFD_ALLOW_SEALING: ::c_uint = 0x0002; +// these are used in the p_type field of Elf32_Phdr and Elf64_Phdr, which has +// the type Elf32Word and Elf64Word respectively. Luckily, both of those are u32 +// so we can use that type here to avoid having to cast. +pub const PT_NULL: u32 = 0; +pub const PT_LOAD: u32 = 1; +pub const PT_DYNAMIC: u32 = 2; +pub const PT_INTERP: u32 = 3; +pub const PT_NOTE: u32 = 4; +pub const PT_SHLIB: u32 = 5; +pub const PT_PHDR: u32 = 6; +pub const PT_TLS: u32 = 7; +pub const PT_NUM: u32 = 8; +pub const PT_LOOS: u32 = 0x60000000; +pub const PT_GNU_EH_FRAME: u32 = 0x6474e550; +pub const PT_GNU_STACK: u32 = 0x6474e551; +pub const PT_GNU_RELRO: u32 = 0x6474e552; + f! { pub fn CPU_ZERO(cpuset: &mut cpu_set_t) -> () { for slot in cpuset.bits.iter_mut() { @@ -1488,6 +1562,14 @@ extern { attr: *const ::pthread_attr_t, f: extern fn(*mut ::c_void) -> *mut ::c_void, value: *mut ::c_void) -> ::c_int; + pub fn dl_iterate_phdr( + callback: Option<unsafe extern fn( + info: *mut ::dl_phdr_info, + size: ::size_t, + data: *mut ::c_void + ) -> ::c_int>, + data: *mut ::c_void + ) -> ::c_int; } cfg_if! { -- GitLab