pub use crate::mono_hash_map::MonoHashMap;
pub use crate::stacked_borrows::{EvalContextExt as StackedBorEvalContextExt, Tag, Permission, Stack, Stacks, Item};
pub use crate::machine::{
- PAGE_SIZE, STACK_ADDR, NUM_CPUS,
+ PAGE_SIZE, STACK_ADDR, STACK_SIZE, NUM_CPUS,
MemoryExtra, AllocExtra, MiriMemoryKind, Evaluator, MiriEvalContext, MiriEvalContextExt,
};
pub use crate::eval::{eval_main, create_ecx, MiriConfig};
}
impl Dlsym {
- pub fn from_str(name: &str) -> Option<Dlsym> {
+ // Returns an error for unsupported symbols, and None if this symbol
+ // should become a NULL pointer (pretend it does not exist).
+ pub fn from_str(name: &str) -> InterpResult<'static, Option<Dlsym>> {
use self::Dlsym::*;
- Some(match name {
- "getentropy" => GetEntropy,
- _ => return None,
+ Ok(match name {
+ "getentropy" => Some(GetEntropy),
+ "__pthread_get_minstack" => None,
+ _ =>
+ return err!(Unimplemented(format!(
+ "Unsupported dlsym: {}", name
+ ))),
})
}
}
let dest = dest.expect("we don't support any diverging dlsym");
let ret = ret.expect("dest is `Some` but ret is `None`");
-
+
match dlsym {
GetEntropy => {
let ptr = this.read_scalar(args[0])?.not_undef()?;
let symbol_name = this.memory().get(symbol.alloc_id)?.read_c_str(tcx, symbol)?;
let err = format!("bad c unicode symbol: {:?}", symbol_name);
let symbol_name = ::std::str::from_utf8(symbol_name).unwrap_or(&err);
- if let Some(dlsym) = Dlsym::from_str(symbol_name) {
+ if let Some(dlsym) = Dlsym::from_str(symbol_name)? {
let ptr = this.memory_mut().create_fn_alloc(FnVal::Other(dlsym));
this.write_scalar(Scalar::from(ptr), dest)?;
} else {
- return err!(Unimplemented(format!(
- "Unsupported dlsym: {}", symbol_name
- )));
+ this.write_null(dest)?;
}
}
this.write_null(dest)?;
}
- // Determine stack base address.
- "pthread_attr_init" | "pthread_attr_destroy" | "pthread_attr_get_np" |
- "pthread_getattr_np" | "pthread_self" | "pthread_get_stacksize_np" => {
+ // Stack size/address stuff.
+ "pthread_attr_init" | "pthread_attr_destroy" | "pthread_self" |
+ "pthread_attr_setstacksize" => {
this.write_null(dest)?;
}
"pthread_attr_getstack" => {
- // Second argument is where we are supposed to write the stack size.
- let ptr = this.deref_operand(args[1])?;
- // Just any address.
- let stack_addr = Scalar::from_uint(STACK_ADDR, args[1].layout.size);
- this.write_scalar(stack_addr, ptr.into())?;
+ let addr_place = this.deref_operand(args[1])?;
+ let size_place = this.deref_operand(args[2])?;
+
+ this.write_scalar(
+ Scalar::from_uint(STACK_ADDR, addr_place.layout.size),
+ addr_place.into(),
+ )?;
+ this.write_scalar(
+ Scalar::from_uint(STACK_SIZE, size_place.layout.size),
+ size_place.into(),
+ )?;
+
// Return success (`0`).
this.write_null(dest)?;
}
- "pthread_get_stackaddr_np" => {
- // Just any address.
- let stack_addr = Scalar::from_uint(STACK_ADDR, dest.layout.size);
- this.write_scalar(stack_addr, dest)?;
+
+ // We don't support threading.
+ "pthread_create" => {
+ return err!(Unimplemented(format!("Miri does not support threading")));
}
// Stub out calls for condvar, mutex and rwlock, to just return `0`.
}
// macOS API stubs.
+ "pthread_attr_get_np" | "pthread_getattr_np" => {
+ this.write_null(dest)?;
+ }
+ "pthread_get_stackaddr_np" => {
+ let stack_addr = Scalar::from_uint(STACK_ADDR, dest.layout.size);
+ this.write_scalar(stack_addr, dest)?;
+ }
+ "pthread_get_stacksize_np" => {
+ let stack_size = Scalar::from_uint(STACK_SIZE, dest.layout.size);
+ this.write_scalar(stack_size, dest)?;
+ }
"_tlv_atexit" => {
// FIXME: register the destructor.
},