Fixes for 32-bit Android.

This commit is contained in:
Dan Gohman
2021-11-22 13:43:03 -08:00
parent 7308a25d23
commit c4e61d12fc
7 changed files with 99 additions and 45 deletions
+13 -4
View File
@@ -304,11 +304,14 @@ pub(crate) fn chmodat(dirfd: BorrowedFd<'_>, path: &ZStr, mode: Mode) -> io::Res
pub(crate) fn chmodat(dirfd: BorrowedFd<'_>, path: &ZStr, mode: Mode) -> io::Result<()> {
// Note that Linux's `fchmodat` does not have a flags argument.
unsafe {
// Pass `mode` as a `c_uint` even if `mode_t` is narrower, since
// `libc_openat` is declared as a variadic function and narrrower
// arguments are promoted.
syscall_ret(c::syscall(
c::SYS_fchmodat,
borrowed_fd(dirfd),
c_str(path),
mode.bits(),
c::c_uint::from(mode.bits()),
))
}
}
@@ -503,7 +506,13 @@ pub(crate) fn fchmod(fd: BorrowedFd<'_>, mode: Mode) -> io::Result<()> {
// implementations, such as musl, add extra logic to `fchmod` to emulate
// support for `O_PATH`, which uses `/proc` outside our control and
// interferes with our own use of `O_PATH`.
unsafe { syscall_ret(c::syscall(c::SYS_fchmod, borrowed_fd(fd), mode.bits())) }
unsafe {
syscall_ret(c::syscall(
c::SYS_fchmod,
borrowed_fd(fd),
c::c_uint::from(mode.bits()),
))
}
}
#[cfg(not(target_os = "wasi"))]
@@ -617,11 +626,11 @@ pub(crate) fn ftruncate(fd: BorrowedFd<'_>, length: u64) -> io::Result<()> {
// Use `ftruncate64` when available, in Android 12 and later.
#[cfg(all(target_os = "android", target_pointer_width = "32"))]
{
weak!(fn ftruncate64(c_int, i64) -> c_int);
weak!(fn ftruncate64(c::c_int, i64) -> c::c_int);
unsafe {
match ftruncate64.get() {
Some(f) => return ret(f(fd, size as i64)),
Some(f) => return ret(f(borrowed_fd(fd), length as i64)),
None => {}
}
}
+29 -32
View File
@@ -58,23 +58,22 @@ pub(crate) fn write(fd: BorrowedFd<'_>, buf: &[u8]) -> io::Result<usize> {
pub(crate) fn pread(fd: BorrowedFd<'_>, buf: &mut [u8], offset: u64) -> io::Result<usize> {
let len = min(buf.len(), READ_LIMIT);
// Silently cast; we'll get `EINVAL` if the value is negative.
let offset = offset as i64;
#[cfg(not(all(target_os = "android", target_pointer_width = "32")))]
let nread = {
// Silently cast; we'll get `EINVAL` if the value is negative.
let offset = offset as i64;
unsafe {
ret_ssize_t(libc_pread(
borrowed_fd(fd),
buf.as_mut_ptr().cast(),
len,
offset,
))?
}
let nread = unsafe {
ret_ssize_t(libc_pread(
borrowed_fd(fd),
buf.as_mut_ptr().cast(),
len,
offset,
))?
};
#[cfg(all(target_os = "android", target_pointer_width = "32"))]
let nread = {
weak!(fn pread64(c_int, *mut c_void, size_t, i64) -> ssize_t);
let nread = unsafe {
weak!(fn pread64(c::c_int, *mut c::c_void, c::size_t, i64) -> c::ssize_t);
pread64
.get()
.map(|f| ret_ssize_t(f(borrowed_fd(fd), buf.as_mut_ptr().cast(), len, offset)))
@@ -89,38 +88,36 @@ pub(crate) fn pread(fd: BorrowedFd<'_>, buf: &mut [u8], offset: u64) -> io::Resu
} else {
return Err(io::Error::FBIG);
}
})
})?
};
Ok(nread as usize)
}
#[cfg(not(all(target_os = "android", target_pointer_width = "32")))]
pub(crate) fn pwrite(fd: BorrowedFd<'_>, buf: &[u8], offset: u64) -> io::Result<usize> {
let len = min(buf.len(), READ_LIMIT);
// Silently cast; we'll get `EINVAL` if the value is negative.
let offset = offset as i64;
#[cfg(not(all(target_os = "android", target_pointer_width = "32")))]
let nwritten = {
// Silently cast; we'll get `EINVAL` if the value is negative.
let offset = offset as i64;
unsafe {
ret_ssize_t(libc_pwrite(
borrowed_fd(fd),
buf.as_ptr().cast(),
len,
offset,
))?
}
let nwritten = unsafe {
ret_ssize_t(libc_pwrite(
borrowed_fd(fd),
buf.as_ptr().cast(),
len,
offset,
))?
};
#[cfg(all(target_os = "android", target_pointer_width = "32"))]
{
weak!(fn pwrite64(c_int, *const c_void, size_t, i64) -> ssize_t);
let nwritten = unsafe {
weak!(fn pwrite64(c::c_int, *const c::c_void, c::size_t, i64) -> c::ssize_t);
pwrite64
.get()
.map(|f| ret_ssize_t(f(borrowed_fd(fd), buf.as_mut_ptr.cast(), len, offset)))
.map(|f| ret_ssize_t(f(borrowed_fd(fd), buf.as_ptr().cast(), len, offset)))
.unwrap_or_else(|| {
if let Ok(o) = offset.try_into() {
if let Ok(offset) = offset.try_into() {
ret_ssize_t(libc_pwrite(
borrowed_fd(fd),
buf.as_ptr().cast(),
@@ -130,8 +127,8 @@ pub(crate) fn pwrite(fd: BorrowedFd<'_>, buf: &[u8], offset: u64) -> io::Result<
} else {
return Err(io::Error::FBIG);
}
})
}
})?
};
Ok(nwritten as usize)
}
+1 -1
View File
@@ -128,7 +128,7 @@ pub(crate) fn sendto_unix(
send_recv_len(buf.len()),
flags.bits(),
as_ptr(&encode_sockaddr_unix(addr)).cast::<c::sockaddr>(),
size_of::<SocketAddrUnix>() as u32,
size_of::<SocketAddrUnix>() as _,
))?
};
Ok(nwritten as usize)
+12 -3
View File
@@ -1,5 +1,8 @@
use super::super::c;
#[cfg(any(target_os = "android", target_os = "linux"))]
#[cfg(any(
all(target_os = "android", target_pointer_width = "64"),
target_os = "linux"
))]
use crate::ffi::ZStr;
#[inline]
@@ -7,7 +10,10 @@ pub(crate) fn page_size() -> usize {
unsafe { c::sysconf(c::_SC_PAGESIZE) as usize }
}
#[cfg(any(target_os = "android", target_os = "linux"))]
#[cfg(any(
all(target_os = "android", target_pointer_width = "64"),
target_os = "linux"
))]
#[inline]
pub(crate) fn linux_hwcap() -> (usize, usize) {
unsafe {
@@ -17,7 +23,10 @@ pub(crate) fn linux_hwcap() -> (usize, usize) {
}
}
#[cfg(any(target_os = "android", target_os = "linux"))]
#[cfg(any(
all(target_os = "android", target_pointer_width = "64"),
target_os = "linux"
))]
#[inline]
pub(crate) fn linux_execfn() -> &'static ZStr {
unsafe { ZStr::from_ptr(c::getauxval(c::AT_EXECFN) as *const _) }
+4 -1
View File
@@ -6,7 +6,10 @@ use super::c;
#[cfg(not(windows))]
pub(crate) mod syscalls;
pub(crate) use auxv::page_size;
#[cfg(any(target_os = "android", target_os = "linux"))]
#[cfg(any(
all(target_os = "android", target_pointer_width = "64"),
target_os = "linux"
))]
pub(crate) use auxv::{linux_execfn, linux_hwcap};
#[cfg(not(target_os = "wasi"))]
pub(crate) use c::{
+30 -3
View File
@@ -2,7 +2,16 @@
//! pointers.
#![cfg_attr(target_vendor = "mustang", allow(unsafe_code))]
#[cfg(any(linux_raw, all(libc, any(target_os = "android", target_os = "linux"))))]
#[cfg(any(
linux_raw,
all(
libc,
any(
all(target_os = "android", target_pointer_width = "64"),
target_os = "linux"
)
)
))]
use crate::ffi::ZStr;
use crate::imp;
@@ -23,7 +32,16 @@ pub fn page_size() -> usize {
/// - [Linux]
///
/// [Linux]: https://man7.org/linux/man-pages/man3/getauxval.3.html
#[cfg(any(linux_raw, all(libc, any(target_os = "android", target_os = "linux"))))]
#[cfg(any(
linux_raw,
all(
libc,
any(
all(target_os = "android", target_pointer_width = "64"),
target_os = "linux"
)
)
))]
#[inline]
pub fn linux_hwcap() -> (usize, usize) {
imp::process::linux_hwcap()
@@ -38,7 +56,16 @@ pub fn linux_hwcap() -> (usize, usize) {
/// - [Linux]
///
/// [Linux]: https://man7.org/linux/man-pages/man3/getauxval.3.html
#[cfg(any(linux_raw, all(libc, any(target_os = "android", target_os = "linux"))))]
#[cfg(any(
linux_raw,
all(
libc,
any(
all(target_os = "android", target_pointer_width = "64"),
target_os = "linux"
)
)
))]
#[inline]
pub fn linux_execfn() -> &'static ZStr {
imp::process::linux_execfn()
+10 -1
View File
@@ -29,7 +29,16 @@ mod wait;
#[cfg(target_vendor = "mustang")]
pub use auxv::init;
pub use auxv::page_size;
#[cfg(any(linux_raw, all(libc, any(target_os = "android", target_os = "linux"))))]
#[cfg(any(
linux_raw,
all(
libc,
any(
all(target_os = "android", target_pointer_width = "64"),
target_os = "linux"
)
)
))]
pub use auxv::{linux_execfn, linux_hwcap};
#[cfg(not(target_os = "wasi"))]
pub use chdir::chdir;