Merge upstream/master into submodule/relibc
Sync the relibc fork with 50 upstream commits (socket layer rework, exec/signal/ptrace/path/timer updates, pthread cleanup, ld_so lifecycle work bringing mark_ready/run_fini into the tree, dynamically-linked init support, start.rs allocator-model rewrite, test harness updates). Satisfies the verify-fork-functions gate (2 previously-missing ld_so functions now present). Conflicts resolved (4 files; 46 auto-merged): - src/start.rs: took upstream's version wholesale. Upstream moved allocator/linker initialization into ld_so's new lifecycle (the mark_ready/run_fini work this merge brings in), superseding the RB alloc_init cluster; the old model's function was already merged out and its lone call would not compile. - redox-rt/src/sys.rs: kept the RB refresh flow with the non-fatal lseek fallback (upstream adopted the refresh as a fatal '?' — RB's conservative fallback protects spawn for uid-dropped / namespace-restricted exec where the kernel cannot refresh). - src/platform/redox/exec.rs: kept the RB root exec-permission bypass (ruid/euid != 0 gate, Linux-matching behavior). - Cargo.lock: syn 2.0.118 -> 2.0.119 (upstream). Verified: repo cook relibc --force-rebuild successful; verify-fork-functions.sh --no-fetch relibc passes; all 9 forks now pass the gate.
This commit is contained in:
@@ -76,7 +76,7 @@ macro_rules! pthread_assert_equal_size(
|
||||
|
||||
// Fail at compile-time if alignments differ.
|
||||
let a = [0_u8; core::mem::align_of::<$export>()];
|
||||
#[allow(clippy::useless_transmute)]
|
||||
#[expect(clippy::useless_transmute)]
|
||||
let b: [u8; core::mem::align_of::<Wrapped>()] = core::mem::transmute(a);
|
||||
};
|
||||
// TODO: Turn into a macro?
|
||||
@@ -88,6 +88,7 @@ macro_rules! pthread_assert_equal_size(
|
||||
let _: libc::$export = core::mem::transmute(export.__relibc_internal_size);
|
||||
|
||||
let a = [0_u8; core::mem::align_of::<$export>()];
|
||||
#[expect(clippy::useless_transmute)]
|
||||
let b: [u8; core::mem::align_of::<libc::$export>()] = core::mem::transmute(a);
|
||||
|
||||
};
|
||||
|
||||
@@ -68,13 +68,13 @@ impl<'a> From<&'a syscall::TimeSpec> for timespec {
|
||||
fn from(value: &'a syscall::TimeSpec) -> Self {
|
||||
Self {
|
||||
tv_sec: value.tv_sec as _,
|
||||
tv_nsec: value.tv_nsec as _,
|
||||
tv_nsec: value.tv_nsec.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "redox")]
|
||||
impl<'a> From<&'a timespec> for syscall::TimeSpec {
|
||||
impl From<×pec> for syscall::TimeSpec {
|
||||
fn from(tp: ×pec) -> Self {
|
||||
Self {
|
||||
tv_sec: tp.tv_sec as _,
|
||||
|
||||
+13
-15
@@ -11,10 +11,13 @@ use core::{
|
||||
sync::atomic::{AtomicUsize, Ordering},
|
||||
};
|
||||
|
||||
use alloc::sync::Arc;
|
||||
|
||||
use crate::{
|
||||
c_str::CStr,
|
||||
ld_so::{
|
||||
linker::{DlError, ObjectHandle, Resolve, ScopeKind},
|
||||
dso::DSO,
|
||||
linker::{DlError, Resolve, ScopeKind},
|
||||
tcb::Tcb,
|
||||
},
|
||||
platform::types::{c_char, c_int, c_void},
|
||||
@@ -123,11 +126,8 @@ pub unsafe extern "C" fn dlopen(cfilename: *const c_char, flags: c_int) -> *mut
|
||||
|
||||
let mut linker = unsafe { (*tcb.linker_ptr).lock() };
|
||||
|
||||
let cbs_c = linker.cbs.clone();
|
||||
let cbs = cbs_c.borrow();
|
||||
|
||||
match (cbs.load_library)(&mut linker, filename, resolve, scope, noload) {
|
||||
Ok(handle) => handle.as_ptr().cast_mut(),
|
||||
match linker.load_library(filename, resolve, scope, noload) {
|
||||
Ok(handle) => Arc::into_raw(handle).cast::<c_void>().cast_mut(),
|
||||
Err(error) => {
|
||||
set_last_error(error);
|
||||
ptr::null_mut()
|
||||
@@ -138,7 +138,7 @@ pub unsafe extern "C" fn dlopen(cfilename: *const c_char, flags: c_int) -> *mut
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/dlsym.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn dlsym(handle: *mut c_void, symbol: *const c_char) -> *mut c_void {
|
||||
let handle = ObjectHandle::from_ptr(handle);
|
||||
let handle = unsafe { handle.cast::<DSO>().as_ref() };
|
||||
|
||||
if symbol.is_null() {
|
||||
ERROR.store(ERROR_NOT_SUPPORTED.as_ptr() as usize, Ordering::SeqCst);
|
||||
@@ -161,9 +161,8 @@ pub unsafe extern "C" fn dlsym(handle: *mut c_void, symbol: *const c_char) -> *m
|
||||
}
|
||||
|
||||
let linker = unsafe { (*tcb.linker_ptr).lock() };
|
||||
let cbs_c = linker.cbs.clone();
|
||||
let cbs = cbs_c.borrow();
|
||||
match (cbs.get_sym)(&linker, handle, symbol_str) {
|
||||
|
||||
match linker.get_sym(handle, symbol_str) {
|
||||
Some(sym) => sym,
|
||||
_ => {
|
||||
ERROR.store(ERROR_NOT_SUPPORTED.as_ptr() as usize, Ordering::SeqCst);
|
||||
@@ -185,15 +184,14 @@ pub unsafe extern "C" fn dlclose(handle: *mut c_void) -> c_int {
|
||||
return -1;
|
||||
};
|
||||
|
||||
let Some(handle) = ObjectHandle::from_ptr(handle) else {
|
||||
if handle.is_null() {
|
||||
set_last_error(DlError::InvalidHandle);
|
||||
return -1;
|
||||
};
|
||||
}
|
||||
|
||||
let mut linker = unsafe { (*tcb.linker_ptr).lock() };
|
||||
let cbs_c = linker.cbs.clone();
|
||||
let cbs = cbs_c.borrow();
|
||||
(cbs.unload)(&mut linker, handle);
|
||||
let obj = unsafe { Arc::from_raw(handle.cast::<DSO>()) };
|
||||
linker.unload(obj);
|
||||
0
|
||||
}
|
||||
|
||||
|
||||
@@ -98,11 +98,16 @@ pub unsafe fn poll_epoll(fds: &mut [pollfd], timeout: c_int, sigmask: *const sig
|
||||
continue;
|
||||
}
|
||||
|
||||
#[expect(clippy::needless_update)]
|
||||
#[cfg(target_os = "redox")]
|
||||
let mut event = epoll_event {
|
||||
events: 0,
|
||||
data: epoll_data { u64: i as u64 },
|
||||
..Default::default()
|
||||
};
|
||||
#[cfg(target_os = "linux")]
|
||||
let mut event = epoll_event {
|
||||
events: 0,
|
||||
data: epoll_data { u64: i as u64 },
|
||||
..Default::default() // needed only on redox for _pad field
|
||||
};
|
||||
|
||||
for (p, ep) in event_map.iter() {
|
||||
|
||||
@@ -5,7 +5,7 @@ pub fn split(line: &mut [u8]) -> Option<passwd> {
|
||||
let mut parts = line.split_mut(|&c| c == b'\0');
|
||||
Some(passwd {
|
||||
pw_name: parts.next()?.as_mut_ptr().cast::<c_char>(),
|
||||
pw_passwd: c"x".as_ptr() as *const c_char as *mut c_char,
|
||||
pw_passwd: c"x".as_ptr().cast::<c_char>().cast_mut(),
|
||||
pw_uid: parsed(parts.next())?,
|
||||
pw_gid: parsed(parts.next())?,
|
||||
pw_gecos: parts.next()?.as_mut_ptr().cast::<c_char>(),
|
||||
|
||||
@@ -22,7 +22,9 @@ fn dup_read<T>(fd: c_int, name: &str, t: &mut T) -> syscall::Result<usize> {
|
||||
|
||||
let size = mem::size_of::<T>();
|
||||
|
||||
let bytes = dup.read(unsafe { slice::from_raw_parts_mut(t as *mut T as *mut u8, size) })?;
|
||||
let bytes = dup.read(unsafe {
|
||||
slice::from_raw_parts_mut(core::ptr::from_mut::<T>(t).cast::<u8>(), size)
|
||||
})?;
|
||||
|
||||
Ok(bytes / size)
|
||||
}
|
||||
@@ -33,7 +35,8 @@ fn dup_write<T>(fd: c_int, name: &str, t: &T) -> Result<usize> {
|
||||
|
||||
let size = mem::size_of::<T>();
|
||||
|
||||
let bytes = dup.write(unsafe { slice::from_raw_parts(t as *const T as *const u8, size) })?;
|
||||
let bytes = dup
|
||||
.write(unsafe { slice::from_raw_parts(core::ptr::from_ref::<T>(t).cast::<u8>(), size) })?;
|
||||
|
||||
Ok(bytes / size)
|
||||
}
|
||||
@@ -50,13 +53,13 @@ impl IoctlBuffer {
|
||||
unsafe fn read<T>(&self) -> Result<T> {
|
||||
let (ptr, size) = match *self {
|
||||
Self::Write(ptr, size) => (ptr, size),
|
||||
Self::ReadWrite(ptr, size) => (ptr as *const c_void, size),
|
||||
Self::ReadWrite(ptr, size) => (ptr.cast_const(), size),
|
||||
_ => {
|
||||
return Err(Errno(EINVAL));
|
||||
}
|
||||
};
|
||||
if size == mem::size_of::<T>() {
|
||||
let value = unsafe { ptr::read(ptr as *const T) };
|
||||
let value = unsafe { ptr::read(ptr.cast::<T>()) };
|
||||
Ok(value)
|
||||
} else {
|
||||
Err(Errno(EINVAL))
|
||||
@@ -64,14 +67,11 @@ impl IoctlBuffer {
|
||||
}
|
||||
|
||||
unsafe fn write<T>(&mut self, value: T) -> Result<()> {
|
||||
let (ptr, size) = match *self {
|
||||
Self::Read(ptr, size) | Self::ReadWrite(ptr, size) => (ptr, size),
|
||||
_ => {
|
||||
return Err(Errno(EINVAL));
|
||||
}
|
||||
let (Self::Read(ptr, size) | Self::ReadWrite(ptr, size)) = *self else {
|
||||
return Err(Errno(EINVAL));
|
||||
};
|
||||
if size == mem::size_of::<T>() {
|
||||
unsafe { ptr::write(ptr as *mut T, value) };
|
||||
unsafe { ptr::write(ptr.cast::<T>(), value) };
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Errno(EINVAL))
|
||||
@@ -83,7 +83,7 @@ pub unsafe fn ioctl_inner(fd: c_int, request: c_ulong, out: *mut c_void) -> Resu
|
||||
match request {
|
||||
FIONBIO => {
|
||||
let mut flags = Sys::fcntl(fd, fcntl::F_GETFL, 0)?;
|
||||
flags = if unsafe { *(out as *mut c_int) } == 0 {
|
||||
flags = if unsafe { *out.cast::<c_int>() } == 0 {
|
||||
flags & !fcntl::O_NONBLOCK
|
||||
} else {
|
||||
flags | fcntl::O_NONBLOCK
|
||||
@@ -91,7 +91,7 @@ pub unsafe fn ioctl_inner(fd: c_int, request: c_ulong, out: *mut c_void) -> Resu
|
||||
Sys::fcntl(fd, fcntl::F_SETFL, flags as c_ulonglong)?;
|
||||
}
|
||||
TCGETS => {
|
||||
let termios = unsafe { &mut *(out as *mut termios::termios) };
|
||||
let termios = unsafe { &mut *out.cast::<termios::termios>() };
|
||||
dup_read(fd, "termios", termios)?;
|
||||
}
|
||||
// TODO: give these different behaviors
|
||||
@@ -119,7 +119,7 @@ pub unsafe fn ioctl_inner(fd: c_int, request: c_ulong, out: *mut c_void) -> Resu
|
||||
todo_skip!(0, "ioctl TIOCSCTTY");
|
||||
}
|
||||
TIOCGPGRP => {
|
||||
let pgrp = unsafe { &mut *(out as *mut pid_t) };
|
||||
let pgrp = unsafe { &mut *out.cast::<pid_t>() };
|
||||
dup_read(fd, "pgrp", pgrp)?;
|
||||
}
|
||||
TIOCSPGRP => {
|
||||
@@ -127,7 +127,7 @@ pub unsafe fn ioctl_inner(fd: c_int, request: c_ulong, out: *mut c_void) -> Resu
|
||||
dup_write(fd, "pgrp", pgrp)?;
|
||||
}
|
||||
TIOCGWINSZ => {
|
||||
let winsize = unsafe { &mut *(out as *mut winsize) };
|
||||
let winsize = unsafe { &mut *out.cast::<winsize>() };
|
||||
dup_read(fd, "winsize", winsize)?;
|
||||
}
|
||||
TIOCSWINSZ => {
|
||||
@@ -135,7 +135,7 @@ pub unsafe fn ioctl_inner(fd: c_int, request: c_ulong, out: *mut c_void) -> Resu
|
||||
dup_write(fd, "winsize", winsize)?;
|
||||
}
|
||||
TIOCGPTLCK => {
|
||||
let lock = unsafe { &mut *(out as *mut c_int) };
|
||||
let lock = unsafe { &mut *out.cast::<c_int>() };
|
||||
dup_read(fd, "ptlock", lock)?;
|
||||
}
|
||||
TIOCSPTLCK => {
|
||||
@@ -143,7 +143,7 @@ pub unsafe fn ioctl_inner(fd: c_int, request: c_ulong, out: *mut c_void) -> Resu
|
||||
dup_write(fd, "ptlock", lock)?;
|
||||
}
|
||||
TIOCGPTN => {
|
||||
let name = unsafe { &mut *(out as *mut c_int) };
|
||||
let name = unsafe { &mut *out.cast::<c_int>() };
|
||||
dup_read(fd, "ptsname", name)?;
|
||||
}
|
||||
SIOCATMARK => {
|
||||
|
||||
@@ -72,7 +72,7 @@ pub(crate) struct timer_internal_t {
|
||||
#[cfg(target_os = "redox")]
|
||||
impl timer_internal_t {
|
||||
pub unsafe fn from_raw(timerid: timer_t) -> &'static mut Self {
|
||||
unsafe { &mut *(timerid as *mut Self) }
|
||||
unsafe { &mut *timerid.cast::<Self>() }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/// sysconf.h: <https://pubs.opengroup.org/onlinepubs/9799919799/functions/sysconf.html>.
|
||||
//! `sysconf.h` implementation.
|
||||
//!
|
||||
//! See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/sysconf.html>.
|
||||
|
||||
#[cfg(target_os = "redox")]
|
||||
#[path = "sysconf/redox.rs"]
|
||||
|
||||
@@ -40,7 +40,7 @@ pub(super) fn sysconf_impl(name: c_int) -> c_long {
|
||||
_SC_TIMEOUTS => 202405,
|
||||
_SC_TIMERS => 202405,
|
||||
_SC_SYMLOOP_MAX => -1,
|
||||
_SC_HOST_NAME_MAX => limits::HOST_NAME_MAX.try_into().unwrap_or(-1),
|
||||
_SC_HOST_NAME_MAX => limits::HOST_NAME_MAX,
|
||||
_SC_NPROCESSORS_CONF => get_cpu_count().unwrap_or(None).unwrap_or(1),
|
||||
_SC_NPROCESSORS_ONLN => get_cpu_count().unwrap_or(None).unwrap_or(1),
|
||||
_SC_PHYS_PAGES => get_mem_stat().map(|s| s.f_blocks as c_long).unwrap_or(-1),
|
||||
@@ -77,6 +77,6 @@ pub fn get_mem_stat() -> Result<sys_statvfs::statvfs, Errno> {
|
||||
let mut buf = sys_statvfs::statvfs::default();
|
||||
let res = Sys::fstatvfs(fd, Out::from_mut(&mut buf));
|
||||
if let Ok(()) = Sys::close(fd) {}; // TODO handle error
|
||||
let _ = res?;
|
||||
return Ok(buf);
|
||||
res?;
|
||||
Ok(buf)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user