Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add definitions in ucontext.h in Android for ARM, x86, and x86_64 #1622

Merged
merged 4 commits into from
Feb 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions libc-test/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1300,6 +1300,7 @@ fn test_android(target: &str) {
"sys/time.h",
"sys/times.h",
"sys/types.h",
"sys/ucontext.h",
"sys/uio.h",
"sys/un.h",
"sys/utsname.h",
Expand Down Expand Up @@ -1390,10 +1391,15 @@ fn test_android(target: &str) {
});

cfg.skip_struct(move |ty| {
if ty.starts_with("__c_anonymous_") {
return true;
}
match ty {
// These are tested as part of the linux_fcntl tests since there are
// header conflicts when including them with all the other structs.
"termios2" => true,
// uc_sigmask and uc_sigmask64 of ucontext_t are an anonymous union
"ucontext_t" => true,

_ => false,
}
Expand Down
166 changes: 166 additions & 0 deletions src/unix/linux_like/android/b32/arm.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,151 @@
pub type c_char = u8;
pub type wchar_t = u32;
pub type greg_t = i32;
pub type mcontext_t = sigcontext;

s! {
pub struct sigcontext {
pub trap_no: ::c_ulong,
pub error_code: ::c_ulong,
pub oldmask: ::c_ulong,
pub arm_r0: ::c_ulong,
pub arm_r1: ::c_ulong,
pub arm_r2: ::c_ulong,
pub arm_r3: ::c_ulong,
pub arm_r4: ::c_ulong,
pub arm_r5: ::c_ulong,
pub arm_r6: ::c_ulong,
pub arm_r7: ::c_ulong,
pub arm_r8: ::c_ulong,
pub arm_r9: ::c_ulong,
pub arm_r10: ::c_ulong,
pub arm_fp: ::c_ulong,
pub arm_ip: ::c_ulong,
pub arm_sp: ::c_ulong,
pub arm_lr: ::c_ulong,
pub arm_pc: ::c_ulong,
pub arm_cpsr: ::c_ulong,
pub fault_address: ::c_ulong,
}
}

cfg_if! {
if #[cfg(libc_union)] {
s_no_extra_traits! {
pub struct __c_anonymous_uc_sigmask_with_padding {
pub uc_sigmask: ::sigset_t,
/* Android has a wrong (smaller) sigset_t on x86. */
__padding_rt_sigset: u32,
}

pub union __c_anonymous_uc_sigmask {
uc_sigmask: __c_anonymous_uc_sigmask_with_padding,
uc_sigmask64: ::sigset64_t,
}

pub struct ucontext_t {
pub uc_flags: ::c_ulong,
pub uc_link: *mut ucontext_t,
pub uc_stack: ::stack_t,
pub uc_mcontext: mcontext_t,
pub uc_sigmask__c_anonymous_union: __c_anonymous_uc_sigmask,
/* The kernel adds extra padding after uc_sigmask to match
* glibc sigset_t on ARM. */
__padding: [c_char; 120],
__align: [::c_longlong; 0],
uc_regspace: [::c_ulong; 128],
}
}

cfg_if! {
if #[cfg(feature = "extra_traits")] {
impl PartialEq for __c_anonymous_uc_sigmask_with_padding {
fn eq(
&self, other: &__c_anonymous_uc_sigmask_with_padding
) -> bool {
self.uc_sigmask == other.uc_sigmask
// Ignore padding
}
}
impl Eq for __c_anonymous_uc_sigmask_with_padding {}
impl ::fmt::Debug for __c_anonymous_uc_sigmask_with_padding {
fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
f.debug_struct("uc_sigmask_with_padding")
.field("uc_sigmask_with_padding", &self.uc_sigmask)
// Ignore padding
.finish()
}
}
impl ::hash::Hash for __c_anonymous_uc_sigmask_with_padding {
fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
self.uc_sigmask.hash(state)
// Ignore padding
}
}

impl PartialEq for __c_anonymous_uc_sigmask {
fn eq(&self, other: &__c_anonymous_uc_sigmask) -> bool {
unsafe { self.uc_sigmask == other.uc_sigmask }
}
}
impl Eq for __c_anonymous_uc_sigmask {}
impl ::fmt::Debug for __c_anonymous_uc_sigmask {
fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
f.debug_struct("uc_sigmask")
.field("uc_sigmask", unsafe { &self.uc_sigmask })
.finish()
}
}
impl ::hash::Hash for __c_anonymous_uc_sigmask {
fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
unsafe { self.uc_sigmask.hash(state) }
}
}

impl PartialEq for ucontext_t {
fn eq(&self, other: &Self) -> bool {
self.uc_flags == other.uc_flags
&& self.uc_link == other.uc_link
&& self.uc_stack == other.uc_stack
&& self.uc_mcontext == other.uc_mcontext
&& self.uc_sigmask__c_anonymous_union
== other.uc_sigmask__c_anonymous_union
&& &self.uc_regspace[..] == &other.uc_regspace[..]
// Ignore padding field
}
}
impl Eq for ucontext_t {}
impl ::fmt::Debug for ucontext_t {
fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
f.debug_struct("ucontext_t")
.field("uc_flags", &self.uc_flags)
.field("uc_link", &self.uc_link)
.field("uc_stack", &self.uc_stack)
.field("uc_mcontext", &self.uc_mcontext)
.field(
"uc_sigmask__c_anonymous_union",
&self.uc_sigmask__c_anonymous_union
)
.field("uc_regspace", &&self.uc_regspace[..])
// Ignore padding field
.finish()
}
}
impl ::hash::Hash for ucontext_t {
fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
self.uc_flags.hash(state);
self.uc_link.hash(state);
self.uc_stack.hash(state);
self.uc_mcontext.hash(state);
self.uc_sigmask__c_anonymous_union.hash(state);
&self.uc_regspace[..].hash(state);
// Ignore padding field
}
}
}
}
}
}

pub const O_DIRECT: ::c_int = 0x10000;
pub const O_DIRECTORY: ::c_int = 0x4000;
Expand Down Expand Up @@ -355,3 +501,23 @@ pub const SYS_pwritev2: ::c_long = 393;
pub const SYS_pkey_mprotect: ::c_long = 394;
pub const SYS_pkey_alloc: ::c_long = 395;
pub const SYS_pkey_free: ::c_long = 396;

// offsets in mcontext_t.gregs from sys/ucontext.h
pub const REG_R0: ::c_int = 0;
pub const REG_R1: ::c_int = 1;
pub const REG_R2: ::c_int = 2;
pub const REG_R3: ::c_int = 3;
pub const REG_R4: ::c_int = 4;
pub const REG_R5: ::c_int = 5;
pub const REG_R6: ::c_int = 6;
pub const REG_R7: ::c_int = 7;
pub const REG_R8: ::c_int = 8;
pub const REG_R9: ::c_int = 9;
pub const REG_R10: ::c_int = 10;
pub const REG_R11: ::c_int = 11;
pub const REG_R12: ::c_int = 12;
pub const REG_R13: ::c_int = 13;
pub const REG_R14: ::c_int = 14;
pub const REG_R15: ::c_int = 15;

pub const NGREG: ::c_int = 18;
18 changes: 18 additions & 0 deletions src/unix/linux_like/android/b32/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,24 @@ s! {
}
}

s_no_extra_traits! {
pub struct sigset64_t {
__bits: [::c_ulong; 2]
}
}

cfg_if! {
if #[cfg(feature = "extra_traits")] {
impl ::fmt::Debug for sigset64_t {
fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
f.debug_struct("sigset64_t")
.field("__bits", &self.__bits)
.finish()
}
}
}
}

// These constants must be of the same type of sigaction.sa_flags
pub const SA_NOCLDSTOP: ::c_int = 0x00000001;
pub const SA_NOCLDWAIT: ::c_int = 0x00000002;
Expand Down
160 changes: 160 additions & 0 deletions src/unix/linux_like/android/b32/x86/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,144 @@
pub type c_char = i8;
pub type wchar_t = i32;
pub type greg_t = i32;

s! {
pub struct _libc_fpreg {
pub significand: [u16; 4],
pub exponent: u16,
}

pub struct _libc_fpstate {
pub cw: ::c_ulong,
pub sw: ::c_ulong,
pub tag: ::c_ulong,
pub ipoff: ::c_ulong,
pub cssel: ::c_ulong,
pub dataoff: ::c_ulong,
pub datasel: ::c_ulong,
pub _st: [_libc_fpreg; 8],
pub status: ::c_ulong,
}

pub struct mcontext_t {
pub gregs: [greg_t; 19],
pub fpregs: *mut _libc_fpstate,
pub oldmask: ::c_ulong,
pub cr2: ::c_ulong,
}
}

cfg_if! {
if #[cfg(libc_union)] {
s_no_extra_traits! {
pub struct __c_anonymous_uc_sigmask_with_padding {
pub uc_sigmask: ::sigset_t,
/* Android has a wrong (smaller) sigset_t on x86. */
__padding_rt_sigset: u32,
}

pub union __c_anonymous_uc_sigmask {
uc_sigmask: __c_anonymous_uc_sigmask_with_padding,
uc_sigmask64: ::sigset64_t,
}

pub struct ucontext_t {
pub uc_flags: ::c_ulong,
pub uc_link: *mut ucontext_t,
pub uc_stack: ::stack_t,
pub uc_mcontext: mcontext_t,
pub uc_sigmask__c_anonymous_union: __c_anonymous_uc_sigmask,
__padding_rt_sigset: u32,
__fpregs_mem: _libc_fpstate,
}
}

cfg_if! {
if #[cfg(feature = "extra_traits")] {
impl PartialEq for __c_anonymous_uc_sigmask_with_padding {
fn eq(
&self, other: &__c_anonymous_uc_sigmask_with_padding
) -> bool {
self.uc_sigmask == other.uc_sigmask
// Ignore padding
}
}
impl Eq for __c_anonymous_uc_sigmask_with_padding {}
impl ::fmt::Debug for __c_anonymous_uc_sigmask_with_padding {
fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
f.debug_struct("uc_sigmask_with_padding")
.field("uc_sigmask_with_padding", &self.uc_sigmask)
// Ignore padding
.finish()
}
}
impl ::hash::Hash for __c_anonymous_uc_sigmask_with_padding {
fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
self.uc_sigmask.hash(state)
// Ignore padding
}
}

impl PartialEq for __c_anonymous_uc_sigmask {
fn eq(&self, other: &__c_anonymous_uc_sigmask) -> bool {
unsafe { self.uc_sigmask == other.uc_sigmask }
}
}
impl Eq for __c_anonymous_uc_sigmask {}
impl ::fmt::Debug for __c_anonymous_uc_sigmask {
fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
f.debug_struct("uc_sigmask")
.field("uc_sigmask", unsafe { &self.uc_sigmask })
.finish()
}
}
impl ::hash::Hash for __c_anonymous_uc_sigmask {
fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
unsafe { self.uc_sigmask.hash(state) }
}
}

impl PartialEq for ucontext_t {
fn eq(&self, other: &Self) -> bool {
self.uc_flags == other.uc_flags
&& self.uc_link == other.uc_link
&& self.uc_stack == other.uc_stack
&& self.uc_mcontext == other.uc_mcontext
&& self.uc_sigmask__c_anonymous_union
== other.uc_sigmask__c_anonymous_union
// Ignore padding field
}
}
impl Eq for ucontext_t {}
impl ::fmt::Debug for ucontext_t {
fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
f.debug_struct("ucontext_t")
.field("uc_flags", &self.uc_flags)
.field("uc_link", &self.uc_link)
.field("uc_stack", &self.uc_stack)
.field("uc_mcontext", &self.uc_mcontext)
.field(
"uc_sigmask__c_anonymous_union",
&self.uc_sigmask__c_anonymous_union
)
// Ignore padding field
.finish()
}
}
impl ::hash::Hash for ucontext_t {
fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
self.uc_flags.hash(state);
self.uc_link.hash(state);
self.uc_stack.hash(state);
self.uc_mcontext.hash(state);
self.uc_sigmask__c_anonymous_union.hash(state);
// Ignore padding field
}
}
}
}
}
}

pub const O_DIRECT: ::c_int = 0x4000;
pub const O_DIRECTORY: ::c_int = 0x10000;
Expand Down Expand Up @@ -414,6 +553,27 @@ pub const EFL: ::c_int = 14;
pub const UESP: ::c_int = 15;
pub const SS: ::c_int = 16;

// offsets in mcontext_t.gregs from sys/ucontext.h
pub const REG_GS: ::c_int = 0;
pub const REG_FS: ::c_int = 1;
pub const REG_ES: ::c_int = 2;
pub const REG_DS: ::c_int = 3;
pub const REG_EDI: ::c_int = 4;
pub const REG_ESI: ::c_int = 5;
pub const REG_EBP: ::c_int = 6;
pub const REG_ESP: ::c_int = 7;
pub const REG_EBX: ::c_int = 8;
pub const REG_EDX: ::c_int = 9;
pub const REG_ECX: ::c_int = 10;
pub const REG_EAX: ::c_int = 11;
pub const REG_TRAPNO: ::c_int = 12;
pub const REG_ERR: ::c_int = 13;
pub const REG_EIP: ::c_int = 14;
pub const REG_CS: ::c_int = 15;
pub const REG_EFL: ::c_int = 16;
pub const REG_UESP: ::c_int = 17;
pub const REG_SS: ::c_int = 18;

cfg_if! {
if #[cfg(libc_align)] {
mod align;
Expand Down
Loading