Skip to content
/ rust Public
forked from rust-lang/rust

Commit

Permalink
Rollup merge of rust-lang#131654 - betrusted-io:xous-various-fixes, r…
Browse files Browse the repository at this point in the history
…=thomcc

Various fixes for Xous

This patchset includes several fixes for Xous that have crept in over the last few months:

* The `adjust_process()` syscall was incorrect
* Warnings have started appearing in `alloc` -- adopt the same approach as wasm, until wasm figures out a workaround
* Dead code warnings have appeared in the networking code. Add `allow(dead_code)` as these structs are used as IPC values
* Add support for `args` and `env`, which have been useful for running tests
* Update `unwinding` to `0.2.3` which fixes the recent regression due to changes in `asm!()` code
  • Loading branch information
jhpratt authored Oct 18, 2024
2 parents 43808df + 99de67a commit 516e71e
Show file tree
Hide file tree
Showing 11 changed files with 518 additions and 40 deletions.
12 changes: 6 additions & 6 deletions library/Cargo.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
version = 4

[[package]]
name = "addr2line"
Expand Down Expand Up @@ -124,9 +124,9 @@ dependencies = [

[[package]]
name = "gimli"
version = "0.30.0"
version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2e1d97fbe9722ba9bbd0c97051c2956e726562b61f86a25a4360398a40edfc9"
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
dependencies = [
"compiler_builtins",
"rustc-std-workspace-alloc",
Expand Down Expand Up @@ -406,12 +406,12 @@ dependencies = [

[[package]]
name = "unwinding"
version = "0.2.2"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc55842d0db6329a669d55a623c674b02d677b16bfb2d24857d4089d41eba882"
checksum = "637d511437df708cee34bdec7ba2f1548d256b7acf3ff20e0a1c559f9bf3a987"
dependencies = [
"compiler_builtins",
"gimli 0.30.0",
"gimli 0.31.1",
"rustc-std-workspace-core",
]

Expand Down
2 changes: 1 addition & 1 deletion library/std/src/os/xous/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,7 @@ pub(crate) fn thread_id() -> Result<ThreadId, Error> {
/// An error is generated if the `knob` is not a valid limit, or if the call
/// would not succeed.
pub(crate) fn adjust_limit(knob: Limits, current: usize, new: usize) -> Result<usize, Error> {
let mut a0 = Syscall::JoinThread as usize;
let mut a0 = Syscall::AdjustProcessLimit as usize;
let mut a1 = knob as usize;
let a2 = current;
let a3 = new;
Expand Down
3 changes: 3 additions & 0 deletions library/std/src/sys/alloc/xous.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]

use crate::alloc::{GlobalAlloc, Layout, System};

#[cfg(not(test))]
Expand Down
53 changes: 53 additions & 0 deletions library/std/src/sys/pal/xous/args.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use crate::ffi::OsString;
use crate::sys::pal::xous::os::get_application_parameters;
use crate::sys::pal::xous::os::params::ArgumentList;
use crate::{fmt, vec};

pub struct Args {
parsed_args_list: vec::IntoIter<OsString>,
}

pub fn args() -> Args {
let Some(params) = get_application_parameters() else {
return Args { parsed_args_list: vec![].into_iter() };
};

for param in params {
if let Ok(args) = ArgumentList::try_from(&param) {
let mut parsed_args = vec![];
for arg in args {
parsed_args.push(arg.into());
}
return Args { parsed_args_list: parsed_args.into_iter() };
}
}
Args { parsed_args_list: vec![].into_iter() }
}

impl fmt::Debug for Args {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.parsed_args_list.as_slice().fmt(f)
}
}

impl Iterator for Args {
type Item = OsString;
fn next(&mut self) -> Option<OsString> {
self.parsed_args_list.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.parsed_args_list.size_hint()
}
}

impl DoubleEndedIterator for Args {
fn next_back(&mut self) -> Option<OsString> {
self.parsed_args_list.next_back()
}
}

impl ExactSizeIterator for Args {
fn len(&self) -> usize {
self.parsed_args_list.len()
}
}
1 change: 0 additions & 1 deletion library/std/src/sys/pal/xous/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#![forbid(unsafe_op_in_unsafe_fn)]

#[path = "../unsupported/args.rs"]
pub mod args;
#[path = "../unsupported/env.rs"]
pub mod env;
Expand Down
1 change: 1 addition & 0 deletions library/std/src/sys/pal/xous/net/dns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::os::xous::ffi::lend_mut;
use crate::os::xous::services::{DnsLendMut, dns_server};

pub struct DnsError {
#[allow(dead_code)]
pub code: u8,
}

Expand Down
2 changes: 2 additions & 0 deletions library/std/src/sys/pal/xous/net/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ pub mod netc {

#[derive(Copy, Clone)]
pub struct sockaddr_in {
#[allow(dead_code)]
pub sin_family: sa_family_t,
pub sin_port: u16,
pub sin_addr: in_addr,
Expand All @@ -72,6 +73,7 @@ pub mod netc {

#[derive(Copy, Clone)]
pub struct sockaddr_in6 {
#[allow(dead_code)]
pub sin6_family: sa_family_t,
pub sin6_port: u16,
pub sin6_addr: in6_addr,
Expand Down
136 changes: 105 additions & 31 deletions library/std/src/sys/pal/xous/os.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,35 @@
use super::unsupported;
use crate::collections::HashMap;
use crate::error::Error as StdError;
use crate::ffi::{OsStr, OsString};
use crate::marker::PhantomData;
use crate::os::xous::ffi::Error as XousError;
use crate::path::{self, PathBuf};
use crate::{fmt, io};
use crate::sync::atomic::{AtomicPtr, AtomicUsize, Ordering};
use crate::sync::{Mutex, Once};
use crate::{fmt, io, vec};

pub(crate) mod params;

static PARAMS_ADDRESS: AtomicPtr<u8> = AtomicPtr::new(core::ptr::null_mut());

#[cfg(not(test))]
#[cfg(feature = "panic_unwind")]
mod eh_unwinding {
pub(crate) struct EhFrameFinder(usize /* eh_frame */);
pub(crate) static mut EH_FRAME_SETTINGS: EhFrameFinder = EhFrameFinder(0);
impl EhFrameFinder {
pub(crate) unsafe fn init(&mut self, eh_frame: usize) {
unsafe {
EH_FRAME_SETTINGS.0 = eh_frame;
}
}
}
pub(crate) struct EhFrameFinder;
pub(crate) static mut EH_FRAME_ADDRESS: usize = 0;
pub(crate) static EH_FRAME_SETTINGS: EhFrameFinder = EhFrameFinder;

unsafe impl unwind::EhFrameFinder for EhFrameFinder {
fn find(&self, _pc: usize) -> Option<unwind::FrameInfo> {
Some(unwind::FrameInfo {
text_base: None,
kind: unwind::FrameInfoKind::EhFrame(self.0),
})
if unsafe { EH_FRAME_ADDRESS == 0 } {
None
} else {
Some(unwind::FrameInfo {
text_base: None,
kind: unwind::FrameInfoKind::EhFrame(unsafe { EH_FRAME_ADDRESS }),
})
}
}
}
}
Expand All @@ -41,12 +47,21 @@ mod c_compat {
}

#[no_mangle]
pub extern "C" fn _start(eh_frame: usize) {
pub extern "C" fn _start(eh_frame: usize, params_address: usize) {
#[cfg(feature = "panic_unwind")]
unsafe {
super::eh_unwinding::EH_FRAME_SETTINGS.init(eh_frame);
{
unsafe { super::eh_unwinding::EH_FRAME_ADDRESS = eh_frame };
unwind::set_custom_eh_frame_finder(&super::eh_unwinding::EH_FRAME_SETTINGS).ok();
}

if params_address != 0 {
let params_address = crate::ptr::with_exposed_provenance_mut::<u8>(params_address);
if unsafe {
super::params::ApplicationParameters::new_from_ptr(params_address).is_some()
} {
super::PARAMS_ADDRESS.store(params_address, core::sync::atomic::Ordering::Relaxed);
}
}
exit(unsafe { main() });
}

Expand Down Expand Up @@ -116,44 +131,103 @@ pub fn current_exe() -> io::Result<PathBuf> {
unsupported()
}

pub struct Env(!);
pub(crate) fn get_application_parameters() -> Option<params::ApplicationParameters> {
let params_address = PARAMS_ADDRESS.load(Ordering::Relaxed);
unsafe { params::ApplicationParameters::new_from_ptr(params_address) }
}

// ---------- Environment handling ---------- //
static ENV: AtomicUsize = AtomicUsize::new(0);
static ENV_INIT: Once = Once::new();
type EnvStore = Mutex<HashMap<OsString, OsString>>;

fn get_env_store() -> &'static EnvStore {
ENV_INIT.call_once(|| {
let env_store = EnvStore::default();
if let Some(params) = get_application_parameters() {
for param in params {
if let Ok(envs) = params::EnvironmentBlock::try_from(&param) {
let mut env_store = env_store.lock().unwrap();
for env in envs {
env_store.insert(env.key.into(), env.value.into());
}
break;
}
}
}
ENV.store(Box::into_raw(Box::new(env_store)) as _, Ordering::Relaxed)
});
unsafe { &*core::ptr::with_exposed_provenance::<EnvStore>(ENV.load(Ordering::Relaxed)) }
}

pub struct Env {
iter: vec::IntoIter<(OsString, OsString)>,
}

// FIXME(https://github.com/rust-lang/rust/issues/114583): Remove this when <OsStr as Debug>::fmt matches <str as Debug>::fmt.
pub struct EnvStrDebug<'a> {
slice: &'a [(OsString, OsString)],
}

impl fmt::Debug for EnvStrDebug<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let Self { slice } = self;
f.debug_list()
.entries(slice.iter().map(|(a, b)| (a.to_str().unwrap(), b.to_str().unwrap())))
.finish()
}
}

impl Env {
// FIXME(https://github.com/rust-lang/rust/issues/114583): Remove this when <OsStr as Debug>::fmt matches <str as Debug>::fmt.
pub fn str_debug(&self) -> impl fmt::Debug + '_ {
let Self(inner) = self;
match *inner {}
let Self { iter } = self;
EnvStrDebug { slice: iter.as_slice() }
}
}

impl fmt::Debug for Env {
fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
let Self(inner) = self;
match *inner {}
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let Self { iter } = self;
f.debug_list().entries(iter.as_slice()).finish()
}
}

impl !Send for Env {}
impl !Sync for Env {}

impl Iterator for Env {
type Item = (OsString, OsString);
fn next(&mut self) -> Option<(OsString, OsString)> {
self.0
self.iter.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}

pub fn env() -> Env {
panic!("not supported on this platform")
let clone_to_vec = |map: &HashMap<OsString, OsString>| -> Vec<_> {
map.iter().map(|(k, v)| (k.clone(), v.clone())).collect()
};

let iter = clone_to_vec(&*get_env_store().lock().unwrap()).into_iter();
Env { iter }
}

pub fn getenv(_: &OsStr) -> Option<OsString> {
None
pub fn getenv(k: &OsStr) -> Option<OsString> {
get_env_store().lock().unwrap().get(k).cloned()
}

pub unsafe fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> {
Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot set env vars on this platform"))
pub unsafe fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
let (k, v) = (k.to_owned(), v.to_owned());
get_env_store().lock().unwrap().insert(k, v);
Ok(())
}

pub unsafe fn unsetenv(_: &OsStr) -> io::Result<()> {
Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot unset env vars on this platform"))
pub unsafe fn unsetenv(k: &OsStr) -> io::Result<()> {
get_env_store().lock().unwrap().remove(k);
Ok(())
}

pub fn temp_dir() -> PathBuf {
Expand Down
Loading

0 comments on commit 516e71e

Please sign in to comment.