commit
ae964207bb
@ -1 +1 @@
|
||||
a4d9624242df6bfe6c0a298867dd2bd527263424
|
||||
b3ac52646f7591a811fa9bf55995b24fd17ece08
|
||||
|
@ -559,7 +559,7 @@ pub fn check_abi<'a>(abi: Abi, exp_abi: Abi) -> InterpResult<'a, ()> {
|
||||
if abi == exp_abi {
|
||||
Ok(())
|
||||
} else {
|
||||
throw_ub_format!("calling a function with ABI {:?} using caller ABI {:?}", exp_abi, abi)
|
||||
throw_ub_format!("calling a function with ABI {} using caller ABI {}", exp_abi.name(), abi.name())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -146,14 +146,14 @@ fn emulate_foreign_item(
|
||||
| "exit"
|
||||
| "ExitProcess"
|
||||
=> {
|
||||
check_abi(abi, if link_name == "exit" { Abi::C } else { Abi::System })?;
|
||||
check_abi(abi, if link_name == "exit" { Abi::C { unwind: false } } else { Abi::System { unwind: false } })?;
|
||||
let &[ref code] = check_arg_count(args)?;
|
||||
// it's really u32 for ExitProcess, but we have to put it into the `Exit` variant anyway
|
||||
let code = this.read_scalar(code)?.to_i32()?;
|
||||
throw_machine_stop!(TerminationInfo::Exit(code.into()));
|
||||
}
|
||||
"abort" => {
|
||||
check_abi(abi, Abi::C)?;
|
||||
check_abi(abi, Abi::C { unwind: false })?;
|
||||
throw_machine_stop!(TerminationInfo::Abort("the program aborted execution".to_owned()))
|
||||
}
|
||||
_ => throw_unsup_format!("can't call (diverging) foreign function: {}", link_name),
|
||||
@ -170,7 +170,7 @@ fn emulate_foreign_item(
|
||||
// Normally, this will be either `libpanic_unwind` or `libpanic_abort`, but it could
|
||||
// also be a custom user-provided implementation via `#![feature(panic_runtime)]`
|
||||
"__rust_start_panic" | "__rust_panic_cleanup" => {
|
||||
check_abi(abi, Abi::C)?;
|
||||
check_abi(abi, Abi::C { unwind: false })?;
|
||||
// This replicates some of the logic in `inject_panic_runtime`.
|
||||
// FIXME: is there a way to reuse that logic?
|
||||
let panic_runtime = match this.tcx.sess.panic_strategy() {
|
||||
@ -236,14 +236,14 @@ fn emulate_foreign_item_by_name(
|
||||
|
||||
// Standard C allocation
|
||||
"malloc" => {
|
||||
check_abi(abi, Abi::C)?;
|
||||
check_abi(abi, Abi::C { unwind: false })?;
|
||||
let &[ref size] = check_arg_count(args)?;
|
||||
let size = this.read_scalar(size)?.to_machine_usize(this)?;
|
||||
let res = this.malloc(size, /*zero_init:*/ false, MiriMemoryKind::C);
|
||||
this.write_scalar(res, dest)?;
|
||||
}
|
||||
"calloc" => {
|
||||
check_abi(abi, Abi::C)?;
|
||||
check_abi(abi, Abi::C { unwind: false })?;
|
||||
let &[ref items, ref len] = check_arg_count(args)?;
|
||||
let items = this.read_scalar(items)?.to_machine_usize(this)?;
|
||||
let len = this.read_scalar(len)?.to_machine_usize(this)?;
|
||||
@ -253,13 +253,13 @@ fn emulate_foreign_item_by_name(
|
||||
this.write_scalar(res, dest)?;
|
||||
}
|
||||
"free" => {
|
||||
check_abi(abi, Abi::C)?;
|
||||
check_abi(abi, Abi::C { unwind: false })?;
|
||||
let &[ref ptr] = check_arg_count(args)?;
|
||||
let ptr = this.read_scalar(ptr)?.check_init()?;
|
||||
this.free(ptr, MiriMemoryKind::C)?;
|
||||
}
|
||||
"realloc" => {
|
||||
check_abi(abi, Abi::C)?;
|
||||
check_abi(abi, Abi::C { unwind: false })?;
|
||||
let &[ref old_ptr, ref new_size] = check_arg_count(args)?;
|
||||
let old_ptr = this.read_scalar(old_ptr)?.check_init()?;
|
||||
let new_size = this.read_scalar(new_size)?.to_machine_usize(this)?;
|
||||
@ -334,7 +334,7 @@ fn emulate_foreign_item_by_name(
|
||||
|
||||
// C memory handling functions
|
||||
"memcmp" => {
|
||||
check_abi(abi, Abi::C)?;
|
||||
check_abi(abi, Abi::C { unwind: false })?;
|
||||
let &[ref left, ref right, ref n] = check_arg_count(args)?;
|
||||
let left = this.read_scalar(left)?.check_init()?;
|
||||
let right = this.read_scalar(right)?.check_init()?;
|
||||
@ -355,7 +355,7 @@ fn emulate_foreign_item_by_name(
|
||||
this.write_scalar(Scalar::from_i32(result), dest)?;
|
||||
}
|
||||
"memrchr" => {
|
||||
check_abi(abi, Abi::C)?;
|
||||
check_abi(abi, Abi::C { unwind: false })?;
|
||||
let &[ref ptr, ref val, ref num] = check_arg_count(args)?;
|
||||
let ptr = this.read_scalar(ptr)?.check_init()?;
|
||||
let val = this.read_scalar(val)?.to_i32()? as u8;
|
||||
@ -374,7 +374,7 @@ fn emulate_foreign_item_by_name(
|
||||
}
|
||||
}
|
||||
"memchr" => {
|
||||
check_abi(abi, Abi::C)?;
|
||||
check_abi(abi, Abi::C { unwind: false })?;
|
||||
let &[ref ptr, ref val, ref num] = check_arg_count(args)?;
|
||||
let ptr = this.read_scalar(ptr)?.check_init()?;
|
||||
let val = this.read_scalar(val)?.to_i32()? as u8;
|
||||
@ -392,7 +392,7 @@ fn emulate_foreign_item_by_name(
|
||||
}
|
||||
}
|
||||
"strlen" => {
|
||||
check_abi(abi, Abi::C)?;
|
||||
check_abi(abi, Abi::C { unwind: false })?;
|
||||
let &[ref ptr] = check_arg_count(args)?;
|
||||
let ptr = this.read_scalar(ptr)?.check_init()?;
|
||||
let n = this.memory.read_c_str(ptr)?.len();
|
||||
@ -408,7 +408,7 @@ fn emulate_foreign_item_by_name(
|
||||
| "asinf"
|
||||
| "atanf"
|
||||
=> {
|
||||
check_abi(abi, Abi::C)?;
|
||||
check_abi(abi, Abi::C { unwind: false })?;
|
||||
let &[ref f] = check_arg_count(args)?;
|
||||
// FIXME: Using host floats.
|
||||
let f = f32::from_bits(this.read_scalar(f)?.to_u32()?);
|
||||
@ -428,7 +428,7 @@ fn emulate_foreign_item_by_name(
|
||||
| "hypotf"
|
||||
| "atan2f"
|
||||
=> {
|
||||
check_abi(abi, Abi::C)?;
|
||||
check_abi(abi, Abi::C { unwind: false })?;
|
||||
let &[ref f1, ref f2] = check_arg_count(args)?;
|
||||
// underscore case for windows, here and below
|
||||
// (see https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/floating-point-primitives?view=vs-2019)
|
||||
@ -450,7 +450,7 @@ fn emulate_foreign_item_by_name(
|
||||
| "asin"
|
||||
| "atan"
|
||||
=> {
|
||||
check_abi(abi, Abi::C)?;
|
||||
check_abi(abi, Abi::C { unwind: false })?;
|
||||
let &[ref f] = check_arg_count(args)?;
|
||||
// FIXME: Using host floats.
|
||||
let f = f64::from_bits(this.read_scalar(f)?.to_u64()?);
|
||||
@ -470,7 +470,7 @@ fn emulate_foreign_item_by_name(
|
||||
| "hypot"
|
||||
| "atan2"
|
||||
=> {
|
||||
check_abi(abi, Abi::C)?;
|
||||
check_abi(abi, Abi::C { unwind: false })?;
|
||||
let &[ref f1, ref f2] = check_arg_count(args)?;
|
||||
// FIXME: Using host floats.
|
||||
let f1 = f64::from_bits(this.read_scalar(f1)?.to_u64()?);
|
||||
@ -486,7 +486,7 @@ fn emulate_foreign_item_by_name(
|
||||
| "ldexp"
|
||||
| "scalbn"
|
||||
=> {
|
||||
check_abi(abi, Abi::C)?;
|
||||
check_abi(abi, Abi::C { unwind: false })?;
|
||||
let &[ref x, ref exp] = check_arg_count(args)?;
|
||||
// For radix-2 (binary) systems, `ldexp` and `scalbn` are the same.
|
||||
let x = this.read_scalar(x)?.to_f64()?;
|
||||
@ -508,12 +508,12 @@ fn emulate_foreign_item_by_name(
|
||||
|
||||
// Architecture-specific shims
|
||||
"llvm.x86.sse2.pause" if this.tcx.sess.target.arch == "x86" || this.tcx.sess.target.arch == "x86_64" => {
|
||||
check_abi(abi, Abi::C)?;
|
||||
check_abi(abi, Abi::C { unwind: false })?;
|
||||
let &[] = check_arg_count(args)?;
|
||||
this.yield_active_thread();
|
||||
}
|
||||
"llvm.aarch64.hint" if this.tcx.sess.target.arch == "aarch64" => {
|
||||
check_abi(abi, Abi::C)?;
|
||||
check_abi(abi, Abi::C { unwind: false })?;
|
||||
let &[ref hint] = check_arg_count(args)?;
|
||||
let hint = this.read_scalar(hint)?.to_i32()?;
|
||||
match hint {
|
||||
|
@ -35,7 +35,7 @@ fn call_dlsym(
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
check_abi(abi, Abi::C)?;
|
||||
check_abi(abi, Abi::C { unwind: false })?;
|
||||
|
||||
match dlsym {
|
||||
Dlsym::Linux(dlsym) => linux::EvalContextExt::call_dlsym(this, dlsym, args, ret),
|
||||
|
@ -22,7 +22,7 @@ fn emulate_foreign_item_by_name(
|
||||
) -> InterpResult<'tcx, bool> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
check_abi(abi, Abi::C)?;
|
||||
check_abi(abi, Abi::C { unwind: false })?;
|
||||
|
||||
match link_name {
|
||||
// Environment related shims
|
||||
|
@ -32,7 +32,7 @@ fn call_dlsym(
|
||||
let (_dest, _ret) = ret.expect("we don't support any diverging dlsym");
|
||||
assert!(this.tcx.sess.target.os == "windows");
|
||||
|
||||
check_abi(abi, Abi::System)?;
|
||||
check_abi(abi, Abi::System { unwind: false })?;
|
||||
|
||||
match dlsym {}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ fn emulate_foreign_item_by_name(
|
||||
) -> InterpResult<'tcx, bool> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
check_abi(abi, Abi::System)?;
|
||||
check_abi(abi, Abi::System { unwind: false })?;
|
||||
|
||||
// Windows API stubs.
|
||||
// HANDLE = isize
|
||||
|
@ -3,13 +3,13 @@
|
||||
|
||||
//! Unwinding past the top frame of a stack is Undefined Behavior.
|
||||
|
||||
#![feature(rustc_private)]
|
||||
#![feature(rustc_private, c_unwind)]
|
||||
|
||||
extern crate libc;
|
||||
|
||||
use std::{mem, ptr};
|
||||
|
||||
extern "C" fn thread_start(_null: *mut libc::c_void) -> *mut libc::c_void {
|
||||
extern "C-unwind" fn thread_start(_null: *mut libc::c_void) -> *mut libc::c_void {
|
||||
panic!()
|
||||
}
|
||||
|
||||
@ -18,6 +18,9 @@ fn main() {
|
||||
let mut native: libc::pthread_t = mem::zeroed();
|
||||
let attr: libc::pthread_attr_t = mem::zeroed();
|
||||
// assert_eq!(libc::pthread_attr_init(&mut attr), 0); FIXME: this function is not yet implemented.
|
||||
// Cast to avoid inserting abort-on-unwind.
|
||||
let thread_start: extern "C-unwind" fn(*mut libc::c_void) -> *mut libc::c_void = thread_start;
|
||||
let thread_start: extern "C" fn(*mut libc::c_void) -> *mut libc::c_void = mem::transmute(thread_start);
|
||||
assert_eq!(libc::pthread_create(&mut native, &attr, thread_start, ptr::null_mut()), 0);
|
||||
assert_eq!(libc::pthread_join(native, ptr::null_mut()), 0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user