Skip to content

Commit

Permalink
Auto merge of #1461 - RalfJung:rwlock-win, r=oli-obk
Browse files Browse the repository at this point in the history
Implement rwlocks on Windows

Fixes #1059
  • Loading branch information
bors committed Jun 28, 2020
2 parents bde2eb4 + 3a5bcb9 commit 2dfa6c1
Show file tree
Hide file tree
Showing 45 changed files with 522 additions and 262 deletions.
31 changes: 31 additions & 0 deletions src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,37 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
}
}
}

fn read_scalar_at_offset(
&self,
op: OpTy<'tcx, Tag>,
offset: u64,
layout: TyAndLayout<'tcx>,
) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> {
let this = self.eval_context_ref();
let op_place = this.deref_operand(op)?;
let offset = Size::from_bytes(offset);
// Ensure that the following read at an offset is within bounds
assert!(op_place.layout.size >= offset + layout.size);
let value_place = op_place.offset(offset, MemPlaceMeta::None, layout, this)?;
this.read_scalar(value_place.into())
}

fn write_scalar_at_offset(
&mut self,
op: OpTy<'tcx, Tag>,
offset: u64,
value: impl Into<ScalarMaybeUninit<Tag>>,
layout: TyAndLayout<'tcx>,
) -> InterpResult<'tcx, ()> {
let this = self.eval_context_mut();
let op_place = this.deref_operand(op)?;
let offset = Size::from_bytes(offset);
// Ensure that the following read at an offset is within bounds
assert!(op_place.layout.size >= offset + layout.size);
let value_place = op_place.offset(offset, MemPlaceMeta::None, layout, this)?;
this.write_scalar(value, value_place.into())
}
}

/// Check that the number of args is what we expect.
Expand Down
43 changes: 10 additions & 33 deletions src/shims/dlsym.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,24 @@
use rustc_middle::mir;

use crate::*;
use helpers::check_arg_count;
use shims::posix::dlsym as posix;
use shims::windows::dlsym as windows;

#[derive(Debug, Copy, Clone)]
#[allow(non_camel_case_types)]
pub enum Dlsym {
GetEntropy,
Posix(posix::Dlsym),
Windows(windows::Dlsym),
}

impl 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: &[u8], target_os: &str) -> InterpResult<'static, Option<Dlsym>> {
use self::Dlsym::*;
let name = String::from_utf8_lossy(name);
let name = &*String::from_utf8_lossy(name);
Ok(match target_os {
"linux" => match &*name {
"__pthread_get_minstack" => None,
_ => throw_unsup_format!("unsupported Linux dlsym: {}", name),
}
"macos" => match &*name {
"getentropy" => Some(GetEntropy),
_ => throw_unsup_format!("unsupported macOS dlsym: {}", name),
}
"windows" => match &*name {
"SetThreadStackGuarantee" => None,
"AcquireSRWLockExclusive" => None,
"GetSystemTimePreciseAsFileTime" => None,
_ => throw_unsup_format!("unsupported Windows dlsym: {}", name),
}
"linux" | "macos" => posix::Dlsym::from_str(name, target_os)?.map(Dlsym::Posix),
"windows" => windows::Dlsym::from_str(name)?.map(Dlsym::Windows),
os => bug!("dlsym not implemented for target_os {}", os),
})
}
Expand All @@ -42,23 +32,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
args: &[OpTy<'tcx, Tag>],
ret: Option<(PlaceTy<'tcx, Tag>, mir::BasicBlock)>,
) -> InterpResult<'tcx> {
use self::Dlsym::*;

let this = self.eval_context_mut();
let (dest, ret) = ret.expect("we don't support any diverging dlsym");

match dlsym {
GetEntropy => {
let &[ptr, len] = check_arg_count(args)?;
let ptr = this.read_scalar(ptr)?.not_undef()?;
let len = this.read_scalar(len)?.to_machine_usize(this)?;
this.gen_random(ptr, len)?;
this.write_null(dest)?;
}
Dlsym::Posix(dlsym) => posix::EvalContextExt::call_dlsym(this, dlsym, args, ret),
Dlsym::Windows(dlsym) => windows::EvalContextExt::call_dlsym(this, dlsym, args, ret),
}

this.dump_place(*dest);
this.go_to_block(ret);
Ok(())
}
}
1 change: 0 additions & 1 deletion src/shims/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
// This matches calls to the foreign item `panic_impl`.
// The implementation is provided by the function with the `#[panic_handler]` attribute.
"panic_impl" => {
this.check_panic_supported()?;
let panic_impl_id = tcx.lang_items().panic_impl().unwrap();
let panic_impl_instance = ty::Instance::mono(tcx, panic_impl_id);
return Ok(Some(&*this.load_mir(panic_impl_instance.def, None)?));
Expand Down
8 changes: 0 additions & 8 deletions src/shims/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
return this.emulate_foreign_item(instance.def_id(), args, ret, unwind);
}

// Better error message for panics on Windows.
let def_id = instance.def_id();
if Some(def_id) == this.tcx.lang_items().begin_panic_fn() ||
Some(def_id) == this.tcx.lang_items().panic_impl()
{
this.check_panic_supported()?;
}

// Otherwise, load the MIR.
Ok(Some(&*this.load_mir(instance.def, None)?))
}
Expand Down
8 changes: 0 additions & 8 deletions src/shims/panic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,6 @@ pub struct CatchUnwindData<'tcx> {

impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
/// Check if panicking is supported on this target, and give a good error otherwise.
fn check_panic_supported(&self) -> InterpResult<'tcx> {
match self.eval_context_ref().tcx.sess.target.target.target_os.as_str() {
"linux" | "macos" => Ok(()),
_ => throw_unsup_format!("panicking is not supported on this target"),
}
}

/// Handles the special `miri_start_panic` intrinsic, which is called
/// by libpanic_unwind to delegate the actual unwinding process to Miri.
fn handle_miri_start_panic(
Expand Down
39 changes: 39 additions & 0 deletions src/shims/posix/dlsym.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use rustc_middle::mir;

use crate::*;
use shims::posix::linux::dlsym as linux;
use shims::posix::macos::dlsym as macos;

#[derive(Debug, Copy, Clone)]
pub enum Dlsym {
Linux(linux::Dlsym),
MacOs(macos::Dlsym),
}

impl 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, target_os: &str) -> InterpResult<'static, Option<Dlsym>> {
Ok(match target_os {
"linux" => linux::Dlsym::from_str(name)?.map(Dlsym::Linux),
"macos" => macos::Dlsym::from_str(name)?.map(Dlsym::MacOs),
_ => unreachable!(),
})
}
}

impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
fn call_dlsym(
&mut self,
dlsym: Dlsym,
args: &[OpTy<'tcx, Tag>],
ret: Option<(PlaceTy<'tcx, Tag>, mir::BasicBlock)>,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
match dlsym {
Dlsym::Linux(dlsym) => linux::EvalContextExt::call_dlsym(this, dlsym, args, ret),
Dlsym::MacOs(dlsym) => macos::EvalContextExt::call_dlsym(this, dlsym, args, ret),
}
}
}
34 changes: 34 additions & 0 deletions src/shims/posix/linux/dlsym.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use rustc_middle::mir;

use crate::*;

#[derive(Debug, Copy, Clone)]
pub enum Dlsym {
}

impl 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>> {
Ok(match &*name {
"__pthread_get_minstack" => None,
_ => throw_unsup_format!("unsupported Linux dlsym: {}", name),
})
}
}

impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
fn call_dlsym(
&mut self,
dlsym: Dlsym,
_args: &[OpTy<'tcx, Tag>],
ret: Option<(PlaceTy<'tcx, Tag>, mir::BasicBlock)>,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
let (_dest, _ret) = ret.expect("we don't support any diverging dlsym");
assert!(this.tcx.sess.target.target.target_os == "linux");

match dlsym {}
}
}
1 change: 1 addition & 0 deletions src/shims/posix/linux/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod foreign_items;
pub mod dlsym;
49 changes: 49 additions & 0 deletions src/shims/posix/macos/dlsym.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use rustc_middle::mir;

use crate::*;
use helpers::check_arg_count;

#[derive(Debug, Copy, Clone)]
#[allow(non_camel_case_types)]
pub enum Dlsym {
getentropy,
}

impl 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>> {
Ok(match name {
"getentropy" => Some(Dlsym::getentropy),
_ => throw_unsup_format!("unsupported macOS dlsym: {}", name),
})
}
}

impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
fn call_dlsym(
&mut self,
dlsym: Dlsym,
args: &[OpTy<'tcx, Tag>],
ret: Option<(PlaceTy<'tcx, Tag>, mir::BasicBlock)>,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
let (dest, ret) = ret.expect("we don't support any diverging dlsym");
assert!(this.tcx.sess.target.target.target_os == "macos");

match dlsym {
Dlsym::getentropy => {
let &[ptr, len] = check_arg_count(args)?;
let ptr = this.read_scalar(ptr)?.not_undef()?;
let len = this.read_scalar(len)?.to_machine_usize(this)?;
this.gen_random(ptr, len)?;
this.write_null(dest)?;
}
}

this.dump_place(*dest);
this.go_to_block(ret);
Ok(())
}
}
1 change: 1 addition & 0 deletions src/shims/posix/macos/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod foreign_items;
pub mod dlsym;
1 change: 1 addition & 0 deletions src/shims/posix/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod foreign_items;
pub mod dlsym;

mod fs;
mod sync;
Expand Down
Loading

0 comments on commit 2dfa6c1

Please sign in to comment.