std: xous: add support for args and env · qinheping/verify-rust-std@3919c4f (original) (raw)

1

1

`use super::unsupported;

`

``

2

`+

use crate::collections::HashMap;

`

2

3

`use crate::error::Error as StdError;

`

3

4

`use crate::ffi::{OsStr, OsString};

`

4

5

`use crate:📑:PhantomData;

`

5

6

`use crate::os::xous::ffi::Error as XousError;

`

6

7

`use crate::path::{self, PathBuf};

`

7

``

`-

use crate::{fmt, io};

`

``

8

`+

use crate::sync::atomic::{AtomicPtr, AtomicUsize, Ordering};

`

``

9

`+

use crate::sync::{Mutex, Once};

`

``

10

`+

use crate::{fmt, io, vec};

`

``

11

+

``

12

`+

pub(crate) mod params;

`

``

13

+

``

14

`+

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

`

8

15

``

9

16

`#[cfg(not(test))]

`

10

17

`#[cfg(feature = "panic_unwind")]

`

11

18

`mod eh_unwinding {

`

12

``

`-

pub(crate) struct EhFrameFinder(usize /* eh_frame */);

`

13

``

`-

pub(crate) static mut EH_FRAME_SETTINGS: EhFrameFinder = EhFrameFinder(0);

`

14

``

`-

impl EhFrameFinder {

`

15

``

`-

pub(crate) unsafe fn init(&mut self, eh_frame: usize) {

`

16

``

`-

unsafe {

`

17

``

`-

EH_FRAME_SETTINGS.0 = eh_frame;

`

18

``

`-

}

`

19

``

`-

}

`

20

``

`-

}

`

``

19

`+

pub(crate) struct EhFrameFinder;

`

``

20

`+

pub(crate) static mut EH_FRAME_ADDRESS: usize = 0;

`

``

21

`+

pub(crate) static EH_FRAME_SETTINGS: EhFrameFinder = EhFrameFinder;

`

``

22

+

21

23

`unsafe impl unwind::EhFrameFinder for EhFrameFinder {

`

22

24

`fn find(&self, _pc: usize) -> Optionunwind::FrameInfo {

`

23

``

`-

Some(unwind::FrameInfo {

`

24

``

`-

text_base: None,

`

25

``

`-

kind: unwind::FrameInfoKind::EhFrame(self.0),

`

26

``

`-

})

`

``

25

`+

if unsafe { EH_FRAME_ADDRESS == 0 } {

`

``

26

`+

None

`

``

27

`+

} else {

`

``

28

`+

Some(unwind::FrameInfo {

`

``

29

`+

text_base: None,

`

``

30

`+

kind: unwind::FrameInfoKind::EhFrame(unsafe { EH_FRAME_ADDRESS }),

`

``

31

`+

})

`

``

32

`+

}

`

27

33

`}

`

28

34

`}

`

29

35

`}

`

`@@ -41,12 +47,21 @@ mod c_compat {

`

41

47

`}

`

42

48

``

43

49

`#[no_mangle]

`

44

``

`-

pub extern "C" fn _start(eh_frame: usize) {

`

``

50

`+

pub extern "C" fn _start(eh_frame: usize, params_address: usize) {

`

45

51

`#[cfg(feature = "panic_unwind")]

`

46

``

`-

unsafe {

`

47

``

`-

super::eh_unwinding::EH_FRAME_SETTINGS.init(eh_frame);

`

``

52

`+

{

`

``

53

`+

unsafe { super::eh_unwinding::EH_FRAME_ADDRESS = eh_frame };

`

48

54

` unwind::set_custom_eh_frame_finder(&super::eh_unwinding::EH_FRAME_SETTINGS).ok();

`

49

55

`}

`

``

56

+

``

57

`+

if params_address != 0 {

`

``

58

`+

let params_address = crate::ptr::with_exposed_provenance_mut::(params_address);

`

``

59

`+

if unsafe {

`

``

60

`+

super::params::ApplicationParameters::new_from_ptr(params_address).is_some()

`

``

61

`+

} {

`

``

62

`+

super::PARAMS_ADDRESS.store(params_address, core::sync::atomic::Ordering::Relaxed);

`

``

63

`+

}

`

``

64

`+

}

`

50

65

`exit(unsafe { main() });

`

51

66

`}

`

52

67

``

`@@ -116,44 +131,103 @@ pub fn current_exe() -> io::Result {

`

116

131

`unsupported()

`

117

132

`}

`

118

133

``

119

``

`-

pub struct Env(!);

`

``

134

`+

pub(crate) fn get_application_parameters() -> Optionparams::ApplicationParameters {

`

``

135

`+

let params_address = PARAMS_ADDRESS.load(Ordering::Relaxed);

`

``

136

`+

unsafe { params::ApplicationParameters::new_from_ptr(params_address) }

`

``

137

`+

}

`

``

138

+

``

139

`+

// ---------- Environment handling ---------- //

`

``

140

`+

static ENV: AtomicUsize = AtomicUsize::new(0);

`

``

141

`+

static ENV_INIT: Once = Once::new();

`

``

142

`+

type EnvStore = Mutex<HashMap<OsString, OsString>>;

`

``

143

+

``

144

`+

fn get_env_store() -> &'static EnvStore {

`

``

145

`+

ENV_INIT.call_once(|| {

`

``

146

`+

let env_store = EnvStore::default();

`

``

147

`+

if let Some(params) = get_application_parameters() {

`

``

148

`+

for param in params {

`

``

149

`+

if let Ok(envs) = params::EnvironmentBlock::try_from(&param) {

`

``

150

`+

let mut env_store = env_store.lock().unwrap();

`

``

151

`+

for env in envs {

`

``

152

`+

env_store.insert(env.key.into(), env.value.into());

`

``

153

`+

}

`

``

154

`+

break;

`

``

155

`+

}

`

``

156

`+

}

`

``

157

`+

}

`

``

158

`+

ENV.store(Box::into_raw(Box::new(env_store)) as _, Ordering::Relaxed)

`

``

159

`+

});

`

``

160

`+

unsafe { &*core::ptr::with_exposed_provenance::(ENV.load(Ordering::Relaxed)) }

`

``

161

`+

}

`

``

162

+

``

163

`+

pub struct Env {

`

``

164

`+

iter: vec::IntoIter<(OsString, OsString)>,

`

``

165

`+

}

`

``

166

+

``

167

`+

// FIXME(https://github.com/rust-lang/rust/issues/114583): Remove this when ::fmt matches ::fmt.

`

``

168

`+

pub struct EnvStrDebug<'a> {

`

``

169

`+

slice: &'a [(OsString, OsString)],

`

``

170

`+

}

`

``

171

+

``

172

`+

impl fmt::Debug for EnvStrDebug<'_> {

`

``

173

`+

fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {

`

``

174

`+

let Self { slice } = self;

`

``

175

`+

f.debug_list()

`

``

176

`+

.entries(slice.iter().map(|(a, b)| (a.to_str().unwrap(), b.to_str().unwrap())))

`

``

177

`+

.finish()

`

``

178

`+

}

`

``

179

`+

}

`

120

180

``

121

181

`impl Env {

`

122

182

`// FIXME(https://github.com/rust-lang/rust/issues/114583): Remove this when ::fmt matches ::fmt.

`

123

183

`pub fn str_debug(&self) -> impl fmt::Debug + '_ {

`

124

``

`-

let Self(inner) = self;

`

125

``

`-

match *inner {}

`

``

184

`+

let Self { iter } = self;

`

``

185

`+

EnvStrDebug { slice: iter.as_slice() }

`

126

186

`}

`

127

187

`}

`

128

188

``

129

189

`impl fmt::Debug for Env {

`

130

``

`-

fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {

`

131

``

`-

let Self(inner) = self;

`

132

``

`-

match *inner {}

`

``

190

`+

fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {

`

``

191

`+

let Self { iter } = self;

`

``

192

`+

f.debug_list().entries(iter.as_slice()).finish()

`

133

193

`}

`

134

194

`}

`

135

195

``

``

196

`+

impl !Send for Env {}

`

``

197

`+

impl !Sync for Env {}

`

``

198

+

136

199

`impl Iterator for Env {

`

137

200

`type Item = (OsString, OsString);

`

138

201

`fn next(&mut self) -> Option<(OsString, OsString)> {

`

139

``

`-

self.0

`

``

202

`+

self.iter.next()

`

``

203

`+

}

`

``

204

`+

fn size_hint(&self) -> (usize, Option) {

`

``

205

`+

self.iter.size_hint()

`

140

206

`}

`

141

207

`}

`

142

208

``

143

209

`pub fn env() -> Env {

`

144

``

`-

panic!("not supported on this platform")

`

``

210

`+

let clone_to_vec = |map: &HashMap<OsString, OsString>| -> Vec<_> {

`

``

211

`+

map.iter().map(|(k, v)| (k.clone(), v.clone())).collect()

`

``

212

`+

};

`

``

213

+

``

214

`+

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

`

``

215

`+

Env { iter }

`

145

216

`}

`

146

217

``

147

``

`-

pub fn getenv(_: &OsStr) -> Option {

`

148

``

`-

None

`

``

218

`+

pub fn getenv(k: &OsStr) -> Option {

`

``

219

`+

get_env_store().lock().unwrap().get(k).cloned()

`

149

220

`}

`

150

221

``

151

``

`-

pub unsafe fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> {

`

152

``

`-

Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot set env vars on this platform"))

`

``

222

`+

pub unsafe fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {

`

``

223

`+

let (k, v) = (k.to_owned(), v.to_owned());

`

``

224

`+

get_env_store().lock().unwrap().insert(k, v);

`

``

225

`+

Ok(())

`

153

226

`}

`

154

227

``

155

``

`-

pub unsafe fn unsetenv(_: &OsStr) -> io::Result<()> {

`

156

``

`-

Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot unset env vars on this platform"))

`

``

228

`+

pub unsafe fn unsetenv(k: &OsStr) -> io::Result<()> {

`

``

229

`+

get_env_store().lock().unwrap().remove(k);

`

``

230

`+

Ok(())

`

157

231

`}

`

158

232

``

159

233

`pub fn temp_dir() -> PathBuf {

`