summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-11-11 09:49:47 +0000
committerbors <bors@rust-lang.org>2017-11-11 09:49:47 +0000
commit44458f5f480f52f86bc0fe9877899c355df0c454 (patch)
treee03bea382d09b8d9c6da093b4de92ace4c757974
parentecc3e010646ee6cde2cd0a4e70496507281400a3 (diff)
parent8f7839f41bb58eefc7aa64a3eadf1486e4cf171d (diff)
downloadrust-libc-44458f5f480f52f86bc0fe9877899c355df0c454.tar.gz
Auto merge of #842 - sfackler:dl_iterate_phdr, r=alexcrichton
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. r? @alexcrichton
-rw-r--r--libc-test/build.rs6
-rw-r--r--src/unix/notbsd/linux/mod.rs82
2 files changed, 87 insertions, 1 deletions
diff --git a/libc-test/build.rs b/libc-test/build.rs
index 7b93f2d63c..ce3c6f5f55 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 fb9299bb5b..46cf538f17 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! {