Auto merge of #2144 - kjvalencik:master, r=JohnTitor
Add dl_iterate_phdr to Android Adds the `dl_iterate_phdr` function for Android targets. This is required for Android support in `gimli` and by proxy, `backtrace`. I tested this in [`backtrace`](https://github.com/rust-lang/backtrace-rs/pull/415) both in an i686 emulator and a physical arm64 device. This API is only available on Version 21+. I'm not sure how that's typically handled in `libc`, so I added a doc comment. Let me know what else is needed!
This commit is contained in:
commit
d3ca6a751e
|
@ -1384,11 +1384,13 @@ fn test_android(target: &str) {
|
||||||
"ctype.h",
|
"ctype.h",
|
||||||
"dirent.h",
|
"dirent.h",
|
||||||
"dlfcn.h",
|
"dlfcn.h",
|
||||||
|
"elf.h",
|
||||||
"errno.h",
|
"errno.h",
|
||||||
"fcntl.h",
|
"fcntl.h",
|
||||||
"grp.h",
|
"grp.h",
|
||||||
"ifaddrs.h",
|
"ifaddrs.h",
|
||||||
"limits.h",
|
"limits.h",
|
||||||
|
"link.h",
|
||||||
"locale.h",
|
"locale.h",
|
||||||
"malloc.h",
|
"malloc.h",
|
||||||
"net/ethernet.h",
|
"net/ethernet.h",
|
||||||
|
@ -1469,6 +1471,7 @@ fn test_android(target: &str) {
|
||||||
"asm/mman.h",
|
"asm/mman.h",
|
||||||
"linux/auxvec.h",
|
"linux/auxvec.h",
|
||||||
"linux/dccp.h",
|
"linux/dccp.h",
|
||||||
|
"linux/elf.h",
|
||||||
"linux/errqueue.h",
|
"linux/errqueue.h",
|
||||||
"linux/falloc.h",
|
"linux/falloc.h",
|
||||||
"linux/futex.h",
|
"linux/futex.h",
|
||||||
|
@ -1507,7 +1510,7 @@ fn test_android(target: &str) {
|
||||||
cfg.type_name(move |ty, is_struct, is_union| {
|
cfg.type_name(move |ty, is_struct, is_union| {
|
||||||
match ty {
|
match ty {
|
||||||
// Just pass all these through, no need for a "struct" prefix
|
// Just pass all these through, no need for a "struct" prefix
|
||||||
"FILE" | "fd_set" | "Dl_info" => ty.to_string(),
|
"FILE" | "fd_set" | "Dl_info" | "Elf32_Phdr" | "Elf64_Phdr" => ty.to_string(),
|
||||||
|
|
||||||
t if is_union => format!("union {}", t),
|
t if is_union => format!("union {}", t),
|
||||||
|
|
||||||
|
@ -1610,7 +1613,12 @@ fn test_android(target: &str) {
|
||||||
// This is a weird union, don't check the type.
|
// This is a weird union, don't check the type.
|
||||||
(struct_ == "ifaddrs" && field == "ifa_ifu") ||
|
(struct_ == "ifaddrs" && field == "ifa_ifu") ||
|
||||||
// sigval is actually a union, but we pretend it's a struct
|
// sigval is actually a union, but we pretend it's a struct
|
||||||
(struct_ == "sigevent" && field == "sigev_value")
|
(struct_ == "sigevent" && field == "sigev_value") ||
|
||||||
|
// FIXME: `sa_sigaction` has type `sighandler_t` but that type is
|
||||||
|
// incorrect, see: https://github.com/rust-lang/libc/issues/1359
|
||||||
|
(struct_ == "sigaction" && field == "sa_sigaction") ||
|
||||||
|
// signalfd had SIGSYS fields added in Android 4.19, but CI does not have that version yet.
|
||||||
|
(struct_ == "signalfd_siginfo" && field == "ssi_call_addr")
|
||||||
});
|
});
|
||||||
|
|
||||||
cfg.skip_field(move |struct_, field| {
|
cfg.skip_field(move |struct_, field| {
|
||||||
|
@ -1628,6 +1636,20 @@ fn test_android(target: &str) {
|
||||||
field == "ssi_arch"))
|
field == "ssi_arch"))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
cfg.skip_field(|struct_, field| {
|
||||||
|
match (struct_, field) {
|
||||||
|
// conflicting with `p_type` macro from <resolve.h>.
|
||||||
|
("Elf32_Phdr", "p_type") => true,
|
||||||
|
("Elf64_Phdr", "p_type") => true,
|
||||||
|
|
||||||
|
// this is actually a union on linux, so we can't represent it well and
|
||||||
|
// just insert some padding.
|
||||||
|
("siginfo_t", "_pad") => true,
|
||||||
|
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
cfg.generate("../src/lib.rs", "main.rs");
|
cfg.generate("../src/lib.rs", "main.rs");
|
||||||
|
|
||||||
test_linux_like_apis(target);
|
test_linux_like_apis(target);
|
||||||
|
|
|
@ -26,6 +26,19 @@ pub type loff_t = ::c_longlong;
|
||||||
pub type __kernel_loff_t = ::c_longlong;
|
pub type __kernel_loff_t = ::c_longlong;
|
||||||
pub type __kernel_pid_t = ::c_int;
|
pub type __kernel_pid_t = ::c_int;
|
||||||
|
|
||||||
|
// linux/elf.h
|
||||||
|
|
||||||
|
pub type Elf32_Addr = u32;
|
||||||
|
pub type Elf32_Half = u16;
|
||||||
|
pub type Elf32_Off = u32;
|
||||||
|
pub type Elf32_Word = u32;
|
||||||
|
|
||||||
|
pub type Elf64_Addr = u64;
|
||||||
|
pub type Elf64_Half = u16;
|
||||||
|
pub type Elf64_Off = u64;
|
||||||
|
pub type Elf64_Word = u32;
|
||||||
|
pub type Elf64_Xword = u64;
|
||||||
|
|
||||||
s! {
|
s! {
|
||||||
pub struct stack_t {
|
pub struct stack_t {
|
||||||
pub ss_sp: *mut ::c_void,
|
pub ss_sp: *mut ::c_void,
|
||||||
|
@ -244,6 +257,57 @@ s! {
|
||||||
pub svm_cid: ::c_uint,
|
pub svm_cid: ::c_uint,
|
||||||
pub svm_zero: [u8; 4]
|
pub svm_zero: [u8; 4]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// linux/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 {
|
||||||
|
#[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,
|
||||||
|
|
||||||
|
// These fields were added in Android R
|
||||||
|
pub dlpi_adds: ::c_ulonglong,
|
||||||
|
pub dlpi_subs: ::c_ulonglong,
|
||||||
|
pub dlpi_tls_modid: ::size_t,
|
||||||
|
pub dlpi_tls_data: *mut ::c_void,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s_no_extra_traits! {
|
s_no_extra_traits! {
|
||||||
|
@ -2715,6 +2779,19 @@ extern "C" {
|
||||||
|
|
||||||
pub fn __system_property_set(__name: *const ::c_char, __value: *const ::c_char) -> ::c_int;
|
pub fn __system_property_set(__name: *const ::c_char, __value: *const ::c_char) -> ::c_int;
|
||||||
pub fn __system_property_get(__name: *const ::c_char, __value: *mut ::c_char) -> ::c_int;
|
pub fn __system_property_get(__name: *const ::c_char, __value: *mut ::c_char) -> ::c_int;
|
||||||
|
|
||||||
|
// #include <link.h>
|
||||||
|
/// Only available in API Version 21+
|
||||||
|
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! {
|
cfg_if! {
|
||||||
|
|
Loading…
Reference in New Issue