Skip to content

Commit e8c53e8

Browse files
committed
implement macOS functions for argc, argv
1 parent b3f7991 commit e8c53e8

File tree

2 files changed

+29
-9
lines changed

2 files changed

+29
-9
lines changed

src/fn_call.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -513,10 +513,6 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a+'mir>: crate::MiriEvalContextExt<'a,
513513
this.write_null(dest)?;
514514
}
515515

516-
"_tlv_atexit" => {
517-
// FIXME: Register the dtor
518-
},
519-
520516
// Determining stack base address
521517
"pthread_attr_init" | "pthread_attr_destroy" | "pthread_attr_get_np" |
522518
"pthread_getattr_np" | "pthread_self" | "pthread_get_stacksize_np" => {
@@ -554,7 +550,18 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a+'mir>: crate::MiriEvalContextExt<'a,
554550
this.write_null(dest)?;
555551
}
556552

557-
// Windows API subs
553+
// macOS API stubs
554+
"_tlv_atexit" => {
555+
// FIXME: Register the dtor
556+
},
557+
"_NSGetArgc" => {
558+
this.write_scalar(Scalar::Ptr(this.machine.argc.unwrap()), dest)?;
559+
},
560+
"_NSGetArgv" => {
561+
this.write_scalar(Scalar::Ptr(this.machine.argv.unwrap()), dest)?;
562+
},
563+
564+
// Windows API stubs
558565
"AddVectoredExceptionHandler" => {
559566
// any non zero value works for the stdlib. This is just used for stackoverflows anyway
560567
this.write_scalar(Scalar::from_int(1, dest.layout.size), dest)?;
@@ -576,8 +583,6 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a+'mir>: crate::MiriEvalContextExt<'a,
576583
// this is c::ERROR_CALL_NOT_IMPLEMENTED
577584
this.write_scalar(Scalar::from_int(120, dest.layout.size), dest)?;
578585
},
579-
580-
// Windows TLS
581586
"TlsAlloc" => {
582587
// This just creates a key; Windows does not natively support TLS dtors.
583588

src/lib.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,11 @@ pub fn create_ecx<'a, 'mir: 'a, 'tcx: 'mir>(
121121

122122
// Second argument (argc): 1
123123
let dest = ecx.eval_place(&mir::Place::Local(args.next().unwrap()))?;
124-
ecx.write_scalar(Scalar::from_int(1, dest.layout.size), dest)?;
124+
let argc = Scalar::from_int(1, dest.layout.size);
125+
ecx.write_scalar(argc, dest)?;
126+
let argc_place = ecx.allocate(dest.layout, MiriMemoryKind::Env.into())?;
127+
ecx.write_scalar(argc, argc_place.into())?;
128+
ecx.machine.argc = Some(argc_place.ptr.to_ptr()?);
125129

126130
// FIXME: extract main source file path
127131
// Third argument (argv): &[b"foo"]
@@ -132,7 +136,11 @@ pub fn create_ecx<'a, 'mir: 'a, 'tcx: 'mir>(
132136
let foo_place = ecx.allocate(foo_layout, MiriMemoryKind::Env.into())?;
133137
ecx.write_scalar(Scalar::Ptr(foo), foo_place.into())?;
134138
ecx.memory_mut().mark_immutable(foo_place.to_ptr()?.alloc_id)?;
135-
ecx.write_scalar(foo_place.ptr, dest)?;
139+
let argv = foo_place.ptr;
140+
ecx.write_scalar(argv, dest)?;
141+
let argv_place = ecx.allocate(dest.layout, MiriMemoryKind::Env.into())?;
142+
ecx.write_scalar(argv, argv_place.into())?;
143+
ecx.machine.argc = Some(argv_place.ptr.to_ptr()?);
136144

137145
assert!(args.next().is_none(), "start lang item has more arguments than expected");
138146

@@ -253,6 +261,11 @@ pub struct Evaluator<'tcx> {
253261
/// Miri does not expose env vars from the host to the emulated program
254262
pub(crate) env_vars: HashMap<Vec<u8>, Pointer<Borrow>>,
255263

264+
/// Program arguments (`Option` because we can only initialize them after creating the ecx).
265+
/// These are *pointers* to argc/argv because macOS.
266+
pub(crate) argc: Option<Pointer<Borrow>>,
267+
pub(crate) argv: Option<Pointer<Borrow>>,
268+
256269
/// TLS state
257270
pub(crate) tls: TlsData<'tcx>,
258271

@@ -267,6 +280,8 @@ impl<'tcx> Evaluator<'tcx> {
267280
fn new(validate: bool) -> Self {
268281
Evaluator {
269282
env_vars: HashMap::default(),
283+
argc: None,
284+
argv: None,
270285
tls: TlsData::default(),
271286
validate,
272287
stacked_borrows: stacked_borrows::State::default(),

0 commit comments

Comments
 (0)