implement macOS functions for argc, argv

This commit is contained in:
Ralf Jung 2018-12-18 19:26:57 +01:00
parent b3f7991367
commit e8c53e81f8
2 changed files with 29 additions and 9 deletions

View File

@ -513,10 +513,6 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a+'mir>: crate::MiriEvalContextExt<'a,
this.write_null(dest)?;
}
"_tlv_atexit" => {
// FIXME: Register the dtor
},
// Determining stack base address
"pthread_attr_init" | "pthread_attr_destroy" | "pthread_attr_get_np" |
"pthread_getattr_np" | "pthread_self" | "pthread_get_stacksize_np" => {
@ -554,7 +550,18 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a+'mir>: crate::MiriEvalContextExt<'a,
this.write_null(dest)?;
}
// Windows API subs
// macOS API stubs
"_tlv_atexit" => {
// FIXME: Register the dtor
},
"_NSGetArgc" => {
this.write_scalar(Scalar::Ptr(this.machine.argc.unwrap()), dest)?;
},
"_NSGetArgv" => {
this.write_scalar(Scalar::Ptr(this.machine.argv.unwrap()), dest)?;
},
// Windows API stubs
"AddVectoredExceptionHandler" => {
// any non zero value works for the stdlib. This is just used for stackoverflows anyway
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,
// this is c::ERROR_CALL_NOT_IMPLEMENTED
this.write_scalar(Scalar::from_int(120, dest.layout.size), dest)?;
},
// Windows TLS
"TlsAlloc" => {
// This just creates a key; Windows does not natively support TLS dtors.

View File

@ -121,7 +121,11 @@ pub fn create_ecx<'a, 'mir: 'a, 'tcx: 'mir>(
// Second argument (argc): 1
let dest = ecx.eval_place(&mir::Place::Local(args.next().unwrap()))?;
ecx.write_scalar(Scalar::from_int(1, dest.layout.size), dest)?;
let argc = Scalar::from_int(1, dest.layout.size);
ecx.write_scalar(argc, dest)?;
let argc_place = ecx.allocate(dest.layout, MiriMemoryKind::Env.into())?;
ecx.write_scalar(argc, argc_place.into())?;
ecx.machine.argc = Some(argc_place.ptr.to_ptr()?);
// FIXME: extract main source file path
// Third argument (argv): &[b"foo"]
@ -132,7 +136,11 @@ pub fn create_ecx<'a, 'mir: 'a, 'tcx: 'mir>(
let foo_place = ecx.allocate(foo_layout, MiriMemoryKind::Env.into())?;
ecx.write_scalar(Scalar::Ptr(foo), foo_place.into())?;
ecx.memory_mut().mark_immutable(foo_place.to_ptr()?.alloc_id)?;
ecx.write_scalar(foo_place.ptr, dest)?;
let argv = foo_place.ptr;
ecx.write_scalar(argv, dest)?;
let argv_place = ecx.allocate(dest.layout, MiriMemoryKind::Env.into())?;
ecx.write_scalar(argv, argv_place.into())?;
ecx.machine.argc = Some(argv_place.ptr.to_ptr()?);
assert!(args.next().is_none(), "start lang item has more arguments than expected");
@ -253,6 +261,11 @@ pub struct Evaluator<'tcx> {
/// Miri does not expose env vars from the host to the emulated program
pub(crate) env_vars: HashMap<Vec<u8>, Pointer<Borrow>>,
/// Program arguments (`Option` because we can only initialize them after creating the ecx).
/// These are *pointers* to argc/argv because macOS.
pub(crate) argc: Option<Pointer<Borrow>>,
pub(crate) argv: Option<Pointer<Borrow>>,
/// TLS state
pub(crate) tls: TlsData<'tcx>,
@ -267,6 +280,8 @@ impl<'tcx> Evaluator<'tcx> {
fn new(validate: bool) -> Self {
Evaluator {
env_vars: HashMap::default(),
argc: None,
argv: None,
tls: TlsData::default(),
validate,
stacked_borrows: stacked_borrows::State::default(),