fix(android/aarch64): use libc::ucontext_t from Android NDK#5189
fix(android/aarch64): use libc::ucontext_t from Android NDK#5189StackOverflowExcept1on wants to merge 1 commit into
libc::ucontext_t from Android NDK#5189Conversation
|
Some changes occurred in an Android module cc @maurer |
43ad692 to
f674b08
Compare
| pub uc_sigmask__c_anonymous_union: __c_anonymous_uc_sigmask, | ||
| /* The kernel adds extra padding after uc_sigmask to match | ||
| * glibc sigset_t on ARM64. */ | ||
| __padding: Padding<[c_char; 128 - size_of::<crate::sigset_t>()]>, |
There was a problem hiding this comment.
Why is this subtracting sigset_t (32 bit?), but the comment refers to ARM64?
This calculation seems weird for either 32-bit or 64-bit, and might need further comments:
- the union is the size of sigset64_t (assuming it's bigger) but we subtract sigset_t (the 32-bit size) from the padding
There was a problem hiding this comment.
| if #[cfg(feature = "extra_traits")] { | ||
| impl PartialEq for __c_anonymous_uc_sigmask { | ||
| fn eq(&self, other: &__c_anonymous_uc_sigmask) -> bool { | ||
| unsafe { self.uc_sigmask == other.uc_sigmask } |
There was a problem hiding this comment.
Is this sound and correct if the 64-bit sigmask was initialised in the union?
- if the 64-bit sigmask is larger and has no padding, then the equality check misses some bytes
- if the 32-bit sigmask is larger (unlikely), then we're comparing uninitialised bytes
- if there's padding, then does it need to be ignored?
| impl Eq for __c_anonymous_uc_sigmask {} | ||
| impl hash::Hash for __c_anonymous_uc_sigmask { | ||
| fn hash<H: hash::Hasher>(&self, state: &mut H) { | ||
| unsafe { self.uc_sigmask.hash(state) } |
There was a problem hiding this comment.
Same here, not sure we can do this with unions, without some guarantee they are the same size.
There was a problem hiding this comment.
This code was simply borrowed from the ARM module:
libc/src/unix/linux_like/android/b32/arm.rs
Lines 59 to 73 in a8e2958
There was a problem hiding this comment.
x86_64 has same layout:
libc/src/unix/linux_like/android/b64/x86_64/mod.rs
Lines 170 to 184 in a8e2958
|
@teor2345 I created test repository demonstrating that the offsets are correct (Android NDK C++). It also has passed CI. #include <ucontext.h>
static_assert(offsetof(ucontext_t, uc_flags) == 0);
static_assert(offsetof(ucontext_t, uc_link) == 8);
static_assert(offsetof(ucontext_t, uc_stack) == 16);
static_assert(offsetof(ucontext_t, uc_sigmask) == 40);
static_assert(offsetof(ucontext_t, uc_mcontext) == 176);
static_assert(sizeof(ucontext_t) == 4560);I also cloned my branch with the patch in
fn main() {
const _: () = {
assert!(std::mem::offset_of!(libc::ucontext_t, uc_flags) == 0);
assert!(std::mem::offset_of!(libc::ucontext_t, uc_link) == 8);
assert!(std::mem::offset_of!(libc::ucontext_t, uc_stack) == 16);
assert!(std::mem::offset_of!(libc::ucontext_t, uc_sigmask__c_anonymous_union) == 40);
assert!(std::mem::offset_of!(libc::ucontext_t, uc_mcontext) == 176);
assert!(std::mem::size_of::<libc::ucontext_t>() == 4560);
};
} |
There was a problem hiding this comment.
We can do the padding change in 0.2 for sure, but I'm not sure about the sigmask portion. It's technically more accurate to source but is there any difference?
libc/src/unix/linux_like/android/b64/mod.rs
Lines 11 to 13 in e59daae
libc/src/unix/linux_like/android/b64/mod.rs
Lines 138 to 140 in e59daae
sigset_t and sigset64_t) appear to have the same definition.
I'm fine with or without it, but will defer to @maurer

Resolves #5159
https://android.googlesource.com/platform/bionic/+/refs/tags/ndk-r29/libc/include/sys/ucontext.h#102
It would be good to backport this to
libc-0.2r? @tgross35