From a1530dd10f2bd84e29eeb9c7bec1535859d22a7a Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Fri, 29 Sep 2023 10:04:04 +0200 Subject: [PATCH 1/2] Implement libredox ABI --- Cargo.lock | 13 +++- Cargo.toml | 2 +- src/platform/redox/libredox.rs | 93 ++++++++++++++++++++++++ src/platform/redox/mod.rs | 15 +--- src/platform/redox/redox-exec/Cargo.toml | 2 +- 5 files changed, 108 insertions(+), 17 deletions(-) create mode 100644 src/platform/redox/libredox.rs diff --git a/Cargo.lock b/Cargo.lock index 92eb0d3704..b81c0586dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -377,7 +377,7 @@ version = "0.1.0" dependencies = [ "goblin", "plain", - "redox_syscall 0.3.5", + "redox_syscall 0.4.1", ] [[package]] @@ -394,6 +394,15 @@ dependencies = [ "bitflags", ] +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags", +] + [[package]] name = "relibc" version = "0.2.5" @@ -413,7 +422,7 @@ dependencies = [ "ralloc", "rand", "redox-exec", - "redox_syscall 0.3.5", + "redox_syscall 0.4.1", "sc", "spin 0.9.8", "unicode-width", diff --git a/Cargo.toml b/Cargo.toml index 61f84fbbf1..f7ae07026d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,7 +44,7 @@ optional = true sc = "0.2.3" [target.'cfg(target_os = "redox")'.dependencies] -redox_syscall = "0.3" +redox_syscall = "0.4" spin = "0.9.0" redox-exec = { path = "src/platform/redox/redox-exec" } diff --git a/src/platform/redox/libredox.rs b/src/platform/redox/libredox.rs new file mode 100644 index 0000000000..d834d282af --- /dev/null +++ b/src/platform/redox/libredox.rs @@ -0,0 +1,93 @@ +use core::{slice, str}; + +use libc::{c_int, mode_t}; +use syscall::{Error, Result, EMFILE, WaitFlags}; + +pub type RawResult = usize; + +pub fn open(path: &str, oflag: c_int, mode: mode_t) -> Result { + let usize_fd = super::path::open( + path, + ((oflag as usize) & 0xFFFF_0000) | ((mode as usize) & 0xFFFF), + )?; + + c_int::try_from(usize_fd).map_err(|_| { + let _ = syscall::close(usize_fd); + Error::new(EMFILE) + }).map(|f| f as usize) +} + +#[no_mangle] +pub unsafe extern "C" fn redox_open_v1(path_base: *const u8, path_len: usize, flags: i32, mode: u16) -> RawResult { + Error::mux(open(str::from_utf8_unchecked(slice::from_raw_parts(path_base, path_len)), flags, mode as mode_t)) +} + +#[no_mangle] +pub unsafe extern "C" fn redox_dup_v1(fd: usize, buf: *const u8, len: usize) -> RawResult { + Error::mux(syscall::dup(fd, core::slice::from_raw_parts(buf, len))) +} +#[no_mangle] +pub unsafe extern "C" fn redox_dup2_v1(old_fd: usize, new_fd: usize, buf: *const u8, len: usize) -> RawResult { + Error::mux(syscall::dup2(old_fd, new_fd, core::slice::from_raw_parts(buf, len))) +} +#[no_mangle] +pub unsafe extern "C" fn redox_read_v1(fd: usize, dst_base: *mut u8, dst_len: usize) -> RawResult { + Error::mux(syscall::read(fd, slice::from_raw_parts_mut(dst_base, dst_len))) +} +#[no_mangle] +pub unsafe extern "C" fn redox_write_v1(fd: usize, src_base: *const u8, src_len: usize) -> RawResult { + Error::mux(syscall::write(fd, slice::from_raw_parts(src_base, src_len))) +} +#[no_mangle] +pub unsafe extern "C" fn redox_fsync_v1(fd: usize) -> RawResult { + Error::mux(syscall::fsync(fd)) +} +#[no_mangle] +pub unsafe extern "C" fn redox_fdatasync_v1(fd: usize) -> RawResult { + // TODO + Error::mux(syscall::fsync(fd)) +} +#[no_mangle] +pub unsafe extern "C" fn redox_fchmod_v1(fd: usize, new_mode: u16) -> RawResult { + Error::mux(syscall::fchmod(fd, new_mode)) +} +#[no_mangle] +pub unsafe extern "C" fn redox_fchown_v1(fd: usize, new_uid: u32, new_gid: u32) -> RawResult { + Error::mux(syscall::fchown(fd, new_uid, new_gid)) +} +#[no_mangle] +pub unsafe extern "C" fn redox_fpath_v1(fd: usize, dst_base: *mut u8, dst_len: usize) -> RawResult { + Error::mux(syscall::fpath(fd, core::slice::from_raw_parts_mut(dst_base, dst_len))) +} +#[no_mangle] +pub unsafe extern "C" fn redox_close_v1(fd: usize) -> RawResult { + Error::mux(syscall::close(fd)) +} + +#[no_mangle] +pub unsafe extern "C" fn redox_get_euid_v1() -> RawResult { + Error::mux(syscall::geteuid()) +} +#[no_mangle] +pub unsafe extern "C" fn redox_get_ruid_v1() -> RawResult { + Error::mux(syscall::getuid()) +} +#[no_mangle] +pub unsafe extern "C" fn redox_get_egid_v1() -> RawResult { + Error::mux(syscall::getegid()) +} +#[no_mangle] +pub unsafe extern "C" fn redox_get_rgid_v1() -> RawResult { + Error::mux(syscall::getgid()) +} +#[no_mangle] +pub unsafe extern "C" fn redox_setrens_v1(rns: usize, ens: usize) -> RawResult { + Error::mux(syscall::setrens(rns, ens)) +} +#[no_mangle] +pub unsafe extern "C" fn redox_waitpid_v1(pid: usize, status: *mut i32, options: i32) -> RawResult { + let mut sts = 0_usize; + let res = Error::mux(syscall::waitpid(pid, &mut sts, WaitFlags::from_bits_truncate(options as usize))); + status.write(sts as i32); + res +} diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs index f07b3124da..c09bb4586b 100644 --- a/src/platform/redox/mod.rs +++ b/src/platform/redox/mod.rs @@ -43,6 +43,7 @@ mod clone; mod epoll; mod exec; mod extra; +mod libredox; pub(crate) mod path; mod ptrace; mod signal; @@ -765,19 +766,7 @@ impl Pal for Sys { fn open(path: &CStr, oflag: c_int, mode: mode_t) -> c_int { let path = path_from_c_str!(path); - match path::open( - path, - ((oflag as usize) & 0xFFFF_0000) | ((mode as usize) & 0xFFFF), - ) { - Ok(fd) => match c_int::try_from(fd) { - Ok(c_fd) => c_fd, - Err(_) => { - let _ = syscall::close(fd); - e(Err(Error::new(EMFILE))) as c_int - } - }, - Err(error) => e(Err(error)) as c_int, - } + e(libredox::open(path, oflag, mode)) as c_int } fn pipe2(fds: &mut [c_int], flags: c_int) -> c_int { diff --git a/src/platform/redox/redox-exec/Cargo.toml b/src/platform/redox/redox-exec/Cargo.toml index bb1744cab5..1a47f79812 100644 --- a/src/platform/redox/redox-exec/Cargo.toml +++ b/src/platform/redox/redox-exec/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -redox_syscall = "0.3" +redox_syscall = "0.4" # TODO: Update goblin = { version = "0.0.21", default-features = false, features = ["elf32", "elf64", "endian_fd"] } plain = "0.2" From 920bafb130bb0ab43a8ea07bce9b5386b47ade08 Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Sun, 8 Oct 2023 12:21:54 +0200 Subject: [PATCH 2/2] Impl libredox getpid, kill, sigprocmask, sigaction. --- src/platform/redox/libredox.rs | 28 +++++++++-- src/platform/redox/signal.rs | 85 ++++++++++++++++++---------------- 2 files changed, 71 insertions(+), 42 deletions(-) diff --git a/src/platform/redox/libredox.rs b/src/platform/redox/libredox.rs index d834d282af..07d0fe5446 100644 --- a/src/platform/redox/libredox.rs +++ b/src/platform/redox/libredox.rs @@ -3,6 +3,8 @@ use core::{slice, str}; use libc::{c_int, mode_t}; use syscall::{Error, Result, EMFILE, WaitFlags}; +use crate::header::signal::sigaction; + pub type RawResult = usize; pub fn open(path: &str, oflag: c_int, mode: mode_t) -> Result { @@ -18,8 +20,8 @@ pub fn open(path: &str, oflag: c_int, mode: mode_t) -> Result { } #[no_mangle] -pub unsafe extern "C" fn redox_open_v1(path_base: *const u8, path_len: usize, flags: i32, mode: u16) -> RawResult { - Error::mux(open(str::from_utf8_unchecked(slice::from_raw_parts(path_base, path_len)), flags, mode as mode_t)) +pub unsafe extern "C" fn redox_open_v1(path_base: *const u8, path_len: usize, flags: u32, mode: u16) -> RawResult { + Error::mux(open(str::from_utf8_unchecked(slice::from_raw_parts(path_base, path_len)), flags as c_int, mode as mode_t)) } #[no_mangle] @@ -64,6 +66,11 @@ pub unsafe extern "C" fn redox_close_v1(fd: usize) -> RawResult { Error::mux(syscall::close(fd)) } +#[no_mangle] +pub unsafe extern "C" fn redox_get_pid_v1() -> RawResult { + Error::mux(syscall::getpid()) +} + #[no_mangle] pub unsafe extern "C" fn redox_get_euid_v1() -> RawResult { Error::mux(syscall::geteuid()) @@ -85,9 +92,24 @@ pub unsafe extern "C" fn redox_setrens_v1(rns: usize, ens: usize) -> RawResult { Error::mux(syscall::setrens(rns, ens)) } #[no_mangle] -pub unsafe extern "C" fn redox_waitpid_v1(pid: usize, status: *mut i32, options: i32) -> RawResult { +pub unsafe extern "C" fn redox_waitpid_v1(pid: usize, status: *mut i32, options: u32) -> RawResult { let mut sts = 0_usize; let res = Error::mux(syscall::waitpid(pid, &mut sts, WaitFlags::from_bits_truncate(options as usize))); status.write(sts as i32); res } + +#[no_mangle] +pub unsafe extern "C" fn redox_kill_v1(pid: usize, signal: u32) -> RawResult { + Error::mux(syscall::kill(pid, signal as usize)) +} + +#[no_mangle] +pub unsafe extern "C" fn redox_sigaction_v1(signal: u32, new: *const sigaction, old: *mut sigaction) -> RawResult { + Error::mux(super::signal::sigaction_impl(signal as i32, new.as_ref(), old.as_mut()).map(|()| 0)) +} + +#[no_mangle] +pub unsafe extern "C" fn redox_sigprocmask_v1(how: u32, new: *const u64, old: *mut u64) -> RawResult { + Error::mux(super::signal::sigprocmask_impl(how as i32, new, old).map(|()| 0)) +} diff --git a/src/platform/redox/signal.rs b/src/platform/redox/signal.rs index ef039c6fdb..0b36869b73 100644 --- a/src/platform/redox/signal.rs +++ b/src/platform/redox/signal.rs @@ -1,5 +1,5 @@ use core::mem; -use syscall; +use syscall::{self, Result}; use super::{ super::{types::*, Pal, PalSignal}, @@ -107,29 +107,7 @@ impl PalSignal for Sys { } fn sigaction(sig: c_int, act: Option<&sigaction>, oact: Option<&mut sigaction>) -> c_int { - let new_opt = act.map(|act| { - let m = act.sa_mask; - let sa_handler = unsafe { mem::transmute(act.sa_handler) }; - syscall::SigAction { - sa_handler, - sa_mask: [m as u64, 0], - sa_flags: syscall::SigActionFlags::from_bits(act.sa_flags as usize) - .expect("sigaction: invalid bit pattern"), - } - }); - let mut old_opt = oact.as_ref().map(|_| syscall::SigAction::default()); - let ret = e(syscall::sigaction( - sig as usize, - new_opt.as_ref(), - old_opt.as_mut(), - )) as c_int; - if let (Some(old), Some(oact)) = (old_opt, oact) { - oact.sa_handler = unsafe { mem::transmute(old.sa_handler) }; - let m = old.sa_mask; - oact.sa_mask = m[0] as sigset_t; - oact.sa_flags = old.sa_flags.bits() as c_ulong; - } - ret + e(sigaction_impl(sig, act, oact).map(|()| 0)) as c_int } fn sigaltstack(ss: *const stack_t, old_ss: *mut stack_t) -> c_int { @@ -144,21 +122,7 @@ impl PalSignal for Sys { } fn sigprocmask(how: c_int, set: *const sigset_t, oset: *mut sigset_t) -> c_int { - let new_opt = if set.is_null() { - None - } else { - Some([unsafe { *set as u64 }, 0]) - }; - let mut old_opt = if oset.is_null() { None } else { Some([0, 0]) }; - let ret = e(syscall::sigprocmask( - how as usize, - new_opt.as_ref(), - old_opt.as_mut(), - )) as c_int; - if let Some(old) = old_opt { - unsafe { *oset = old[0] as sigset_t }; - } - ret + e(sigprocmask_impl(how, set, oset).map(|()| 0)) as c_int } fn sigsuspend(set: *const sigset_t) -> c_int { @@ -175,3 +139,46 @@ impl PalSignal for Sys { -1 } } + +pub(crate) fn sigaction_impl(sig: i32, act: Option<&sigaction>, oact: Option<&mut sigaction>) -> Result<()> { + let new_opt = act.map(|act| { + let m = act.sa_mask; + let sa_handler = unsafe { mem::transmute(act.sa_handler) }; + syscall::SigAction { + sa_handler, + sa_mask: [m as u64, 0], + sa_flags: syscall::SigActionFlags::from_bits(act.sa_flags as usize) + .expect("sigaction: invalid bit pattern"), + } + }); + let mut old_opt = oact.as_ref().map(|_| syscall::SigAction::default()); + syscall::sigaction( + sig as usize, + new_opt.as_ref(), + old_opt.as_mut(), + )?; + if let (Some(old), Some(oact)) = (old_opt, oact) { + oact.sa_handler = unsafe { mem::transmute(old.sa_handler) }; + let m = old.sa_mask; + oact.sa_mask = m[0] as sigset_t; + oact.sa_flags = old.sa_flags.bits() as c_ulong; + } + Ok(()) +} +pub(crate) fn sigprocmask_impl(how: i32, set: *const sigset_t, oset: *mut sigset_t) -> Result<()> { + let new_opt = if set.is_null() { + None + } else { + Some([unsafe { *set as u64 }, 0]) + }; + let mut old_opt = if oset.is_null() { None } else { Some([0, 0]) }; + syscall::sigprocmask( + how as usize, + new_opt.as_ref(), + old_opt.as_mut(), + )?; + if let Some(old) = old_opt { + unsafe { *oset = old[0] as sigset_t }; + } + Ok(()) +}