Skip to content

Commit 70d4c56

Browse files
authored
Merge pull request #1622 from igrep/android-ucontext
Add definitions in ucontext.h in Android for ARM, x86, and x86_64
2 parents 4ddd363 + 338dd7c commit 70d4c56

File tree

6 files changed

+600
-0
lines changed

6 files changed

+600
-0
lines changed

libc-test/build.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1300,6 +1300,7 @@ fn test_android(target: &str) {
13001300
"sys/time.h",
13011301
"sys/times.h",
13021302
"sys/types.h",
1303+
"sys/ucontext.h",
13031304
"sys/uio.h",
13041305
"sys/un.h",
13051306
"sys/utsname.h",
@@ -1390,10 +1391,15 @@ fn test_android(target: &str) {
13901391
});
13911392

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

13981404
_ => false,
13991405
}

src/unix/linux_like/android/b32/arm.rs

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,151 @@
11
pub type c_char = u8;
22
pub type wchar_t = u32;
3+
pub type greg_t = i32;
4+
pub type mcontext_t = sigcontext;
5+
6+
s! {
7+
pub struct sigcontext {
8+
pub trap_no: ::c_ulong,
9+
pub error_code: ::c_ulong,
10+
pub oldmask: ::c_ulong,
11+
pub arm_r0: ::c_ulong,
12+
pub arm_r1: ::c_ulong,
13+
pub arm_r2: ::c_ulong,
14+
pub arm_r3: ::c_ulong,
15+
pub arm_r4: ::c_ulong,
16+
pub arm_r5: ::c_ulong,
17+
pub arm_r6: ::c_ulong,
18+
pub arm_r7: ::c_ulong,
19+
pub arm_r8: ::c_ulong,
20+
pub arm_r9: ::c_ulong,
21+
pub arm_r10: ::c_ulong,
22+
pub arm_fp: ::c_ulong,
23+
pub arm_ip: ::c_ulong,
24+
pub arm_sp: ::c_ulong,
25+
pub arm_lr: ::c_ulong,
26+
pub arm_pc: ::c_ulong,
27+
pub arm_cpsr: ::c_ulong,
28+
pub fault_address: ::c_ulong,
29+
}
30+
}
31+
32+
cfg_if! {
33+
if #[cfg(libc_union)] {
34+
s_no_extra_traits! {
35+
pub struct __c_anonymous_uc_sigmask_with_padding {
36+
pub uc_sigmask: ::sigset_t,
37+
/* Android has a wrong (smaller) sigset_t on x86. */
38+
__padding_rt_sigset: u32,
39+
}
40+
41+
pub union __c_anonymous_uc_sigmask {
42+
uc_sigmask: __c_anonymous_uc_sigmask_with_padding,
43+
uc_sigmask64: ::sigset64_t,
44+
}
45+
46+
pub struct ucontext_t {
47+
pub uc_flags: ::c_ulong,
48+
pub uc_link: *mut ucontext_t,
49+
pub uc_stack: ::stack_t,
50+
pub uc_mcontext: mcontext_t,
51+
pub uc_sigmask__c_anonymous_union: __c_anonymous_uc_sigmask,
52+
/* The kernel adds extra padding after uc_sigmask to match
53+
* glibc sigset_t on ARM. */
54+
__padding: [c_char; 120],
55+
__align: [::c_longlong; 0],
56+
uc_regspace: [::c_ulong; 128],
57+
}
58+
}
59+
60+
cfg_if! {
61+
if #[cfg(feature = "extra_traits")] {
62+
impl PartialEq for __c_anonymous_uc_sigmask_with_padding {
63+
fn eq(
64+
&self, other: &__c_anonymous_uc_sigmask_with_padding
65+
) -> bool {
66+
self.uc_sigmask == other.uc_sigmask
67+
// Ignore padding
68+
}
69+
}
70+
impl Eq for __c_anonymous_uc_sigmask_with_padding {}
71+
impl ::fmt::Debug for __c_anonymous_uc_sigmask_with_padding {
72+
fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
73+
f.debug_struct("uc_sigmask_with_padding")
74+
.field("uc_sigmask_with_padding", &self.uc_sigmask)
75+
// Ignore padding
76+
.finish()
77+
}
78+
}
79+
impl ::hash::Hash for __c_anonymous_uc_sigmask_with_padding {
80+
fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
81+
self.uc_sigmask.hash(state)
82+
// Ignore padding
83+
}
84+
}
85+
86+
impl PartialEq for __c_anonymous_uc_sigmask {
87+
fn eq(&self, other: &__c_anonymous_uc_sigmask) -> bool {
88+
unsafe { self.uc_sigmask == other.uc_sigmask }
89+
}
90+
}
91+
impl Eq for __c_anonymous_uc_sigmask {}
92+
impl ::fmt::Debug for __c_anonymous_uc_sigmask {
93+
fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
94+
f.debug_struct("uc_sigmask")
95+
.field("uc_sigmask", unsafe { &self.uc_sigmask })
96+
.finish()
97+
}
98+
}
99+
impl ::hash::Hash for __c_anonymous_uc_sigmask {
100+
fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
101+
unsafe { self.uc_sigmask.hash(state) }
102+
}
103+
}
104+
105+
impl PartialEq for ucontext_t {
106+
fn eq(&self, other: &Self) -> bool {
107+
self.uc_flags == other.uc_flags
108+
&& self.uc_link == other.uc_link
109+
&& self.uc_stack == other.uc_stack
110+
&& self.uc_mcontext == other.uc_mcontext
111+
&& self.uc_sigmask__c_anonymous_union
112+
== other.uc_sigmask__c_anonymous_union
113+
&& &self.uc_regspace[..] == &other.uc_regspace[..]
114+
// Ignore padding field
115+
}
116+
}
117+
impl Eq for ucontext_t {}
118+
impl ::fmt::Debug for ucontext_t {
119+
fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
120+
f.debug_struct("ucontext_t")
121+
.field("uc_flags", &self.uc_flags)
122+
.field("uc_link", &self.uc_link)
123+
.field("uc_stack", &self.uc_stack)
124+
.field("uc_mcontext", &self.uc_mcontext)
125+
.field(
126+
"uc_sigmask__c_anonymous_union",
127+
&self.uc_sigmask__c_anonymous_union
128+
)
129+
.field("uc_regspace", &&self.uc_regspace[..])
130+
// Ignore padding field
131+
.finish()
132+
}
133+
}
134+
impl ::hash::Hash for ucontext_t {
135+
fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
136+
self.uc_flags.hash(state);
137+
self.uc_link.hash(state);
138+
self.uc_stack.hash(state);
139+
self.uc_mcontext.hash(state);
140+
self.uc_sigmask__c_anonymous_union.hash(state);
141+
&self.uc_regspace[..].hash(state);
142+
// Ignore padding field
143+
}
144+
}
145+
}
146+
}
147+
}
148+
}
3149

4150
pub const O_DIRECT: ::c_int = 0x10000;
5151
pub const O_DIRECTORY: ::c_int = 0x4000;
@@ -355,3 +501,23 @@ pub const SYS_pwritev2: ::c_long = 393;
355501
pub const SYS_pkey_mprotect: ::c_long = 394;
356502
pub const SYS_pkey_alloc: ::c_long = 395;
357503
pub const SYS_pkey_free: ::c_long = 396;
504+
505+
// offsets in mcontext_t.gregs from sys/ucontext.h
506+
pub const REG_R0: ::c_int = 0;
507+
pub const REG_R1: ::c_int = 1;
508+
pub const REG_R2: ::c_int = 2;
509+
pub const REG_R3: ::c_int = 3;
510+
pub const REG_R4: ::c_int = 4;
511+
pub const REG_R5: ::c_int = 5;
512+
pub const REG_R6: ::c_int = 6;
513+
pub const REG_R7: ::c_int = 7;
514+
pub const REG_R8: ::c_int = 8;
515+
pub const REG_R9: ::c_int = 9;
516+
pub const REG_R10: ::c_int = 10;
517+
pub const REG_R11: ::c_int = 11;
518+
pub const REG_R12: ::c_int = 12;
519+
pub const REG_R13: ::c_int = 13;
520+
pub const REG_R14: ::c_int = 14;
521+
pub const REG_R15: ::c_int = 15;
522+
523+
pub const NGREG: ::c_int = 18;

src/unix/linux_like/android/b32/mod.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,24 @@ s! {
161161
}
162162
}
163163

164+
s_no_extra_traits! {
165+
pub struct sigset64_t {
166+
__bits: [::c_ulong; 2]
167+
}
168+
}
169+
170+
cfg_if! {
171+
if #[cfg(feature = "extra_traits")] {
172+
impl ::fmt::Debug for sigset64_t {
173+
fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
174+
f.debug_struct("sigset64_t")
175+
.field("__bits", &self.__bits)
176+
.finish()
177+
}
178+
}
179+
}
180+
}
181+
164182
// These constants must be of the same type of sigaction.sa_flags
165183
pub const SA_NOCLDSTOP: ::c_int = 0x00000001;
166184
pub const SA_NOCLDWAIT: ::c_int = 0x00000002;

src/unix/linux_like/android/b32/x86/mod.rs

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,144 @@
11
pub type c_char = i8;
22
pub type wchar_t = i32;
3+
pub type greg_t = i32;
4+
5+
s! {
6+
pub struct _libc_fpreg {
7+
pub significand: [u16; 4],
8+
pub exponent: u16,
9+
}
10+
11+
pub struct _libc_fpstate {
12+
pub cw: ::c_ulong,
13+
pub sw: ::c_ulong,
14+
pub tag: ::c_ulong,
15+
pub ipoff: ::c_ulong,
16+
pub cssel: ::c_ulong,
17+
pub dataoff: ::c_ulong,
18+
pub datasel: ::c_ulong,
19+
pub _st: [_libc_fpreg; 8],
20+
pub status: ::c_ulong,
21+
}
22+
23+
pub struct mcontext_t {
24+
pub gregs: [greg_t; 19],
25+
pub fpregs: *mut _libc_fpstate,
26+
pub oldmask: ::c_ulong,
27+
pub cr2: ::c_ulong,
28+
}
29+
}
30+
31+
cfg_if! {
32+
if #[cfg(libc_union)] {
33+
s_no_extra_traits! {
34+
pub struct __c_anonymous_uc_sigmask_with_padding {
35+
pub uc_sigmask: ::sigset_t,
36+
/* Android has a wrong (smaller) sigset_t on x86. */
37+
__padding_rt_sigset: u32,
38+
}
39+
40+
pub union __c_anonymous_uc_sigmask {
41+
uc_sigmask: __c_anonymous_uc_sigmask_with_padding,
42+
uc_sigmask64: ::sigset64_t,
43+
}
44+
45+
pub struct ucontext_t {
46+
pub uc_flags: ::c_ulong,
47+
pub uc_link: *mut ucontext_t,
48+
pub uc_stack: ::stack_t,
49+
pub uc_mcontext: mcontext_t,
50+
pub uc_sigmask__c_anonymous_union: __c_anonymous_uc_sigmask,
51+
__padding_rt_sigset: u32,
52+
__fpregs_mem: _libc_fpstate,
53+
}
54+
}
55+
56+
cfg_if! {
57+
if #[cfg(feature = "extra_traits")] {
58+
impl PartialEq for __c_anonymous_uc_sigmask_with_padding {
59+
fn eq(
60+
&self, other: &__c_anonymous_uc_sigmask_with_padding
61+
) -> bool {
62+
self.uc_sigmask == other.uc_sigmask
63+
// Ignore padding
64+
}
65+
}
66+
impl Eq for __c_anonymous_uc_sigmask_with_padding {}
67+
impl ::fmt::Debug for __c_anonymous_uc_sigmask_with_padding {
68+
fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
69+
f.debug_struct("uc_sigmask_with_padding")
70+
.field("uc_sigmask_with_padding", &self.uc_sigmask)
71+
// Ignore padding
72+
.finish()
73+
}
74+
}
75+
impl ::hash::Hash for __c_anonymous_uc_sigmask_with_padding {
76+
fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
77+
self.uc_sigmask.hash(state)
78+
// Ignore padding
79+
}
80+
}
81+
82+
impl PartialEq for __c_anonymous_uc_sigmask {
83+
fn eq(&self, other: &__c_anonymous_uc_sigmask) -> bool {
84+
unsafe { self.uc_sigmask == other.uc_sigmask }
85+
}
86+
}
87+
impl Eq for __c_anonymous_uc_sigmask {}
88+
impl ::fmt::Debug for __c_anonymous_uc_sigmask {
89+
fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
90+
f.debug_struct("uc_sigmask")
91+
.field("uc_sigmask", unsafe { &self.uc_sigmask })
92+
.finish()
93+
}
94+
}
95+
impl ::hash::Hash for __c_anonymous_uc_sigmask {
96+
fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
97+
unsafe { self.uc_sigmask.hash(state) }
98+
}
99+
}
100+
101+
impl PartialEq for ucontext_t {
102+
fn eq(&self, other: &Self) -> bool {
103+
self.uc_flags == other.uc_flags
104+
&& self.uc_link == other.uc_link
105+
&& self.uc_stack == other.uc_stack
106+
&& self.uc_mcontext == other.uc_mcontext
107+
&& self.uc_sigmask__c_anonymous_union
108+
== other.uc_sigmask__c_anonymous_union
109+
// Ignore padding field
110+
}
111+
}
112+
impl Eq for ucontext_t {}
113+
impl ::fmt::Debug for ucontext_t {
114+
fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
115+
f.debug_struct("ucontext_t")
116+
.field("uc_flags", &self.uc_flags)
117+
.field("uc_link", &self.uc_link)
118+
.field("uc_stack", &self.uc_stack)
119+
.field("uc_mcontext", &self.uc_mcontext)
120+
.field(
121+
"uc_sigmask__c_anonymous_union",
122+
&self.uc_sigmask__c_anonymous_union
123+
)
124+
// Ignore padding field
125+
.finish()
126+
}
127+
}
128+
impl ::hash::Hash for ucontext_t {
129+
fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
130+
self.uc_flags.hash(state);
131+
self.uc_link.hash(state);
132+
self.uc_stack.hash(state);
133+
self.uc_mcontext.hash(state);
134+
self.uc_sigmask__c_anonymous_union.hash(state);
135+
// Ignore padding field
136+
}
137+
}
138+
}
139+
}
140+
}
141+
}
3142

4143
pub const O_DIRECT: ::c_int = 0x4000;
5144
pub const O_DIRECTORY: ::c_int = 0x10000;
@@ -414,6 +553,27 @@ pub const EFL: ::c_int = 14;
414553
pub const UESP: ::c_int = 15;
415554
pub const SS: ::c_int = 16;
416555

556+
// offsets in mcontext_t.gregs from sys/ucontext.h
557+
pub const REG_GS: ::c_int = 0;
558+
pub const REG_FS: ::c_int = 1;
559+
pub const REG_ES: ::c_int = 2;
560+
pub const REG_DS: ::c_int = 3;
561+
pub const REG_EDI: ::c_int = 4;
562+
pub const REG_ESI: ::c_int = 5;
563+
pub const REG_EBP: ::c_int = 6;
564+
pub const REG_ESP: ::c_int = 7;
565+
pub const REG_EBX: ::c_int = 8;
566+
pub const REG_EDX: ::c_int = 9;
567+
pub const REG_ECX: ::c_int = 10;
568+
pub const REG_EAX: ::c_int = 11;
569+
pub const REG_TRAPNO: ::c_int = 12;
570+
pub const REG_ERR: ::c_int = 13;
571+
pub const REG_EIP: ::c_int = 14;
572+
pub const REG_CS: ::c_int = 15;
573+
pub const REG_EFL: ::c_int = 16;
574+
pub const REG_UESP: ::c_int = 17;
575+
pub const REG_SS: ::c_int = 18;
576+
417577
cfg_if! {
418578
if #[cfg(libc_align)] {
419579
mod align;

0 commit comments

Comments
 (0)