From dca00ab85ec970432ebaf1cf59b0e795db2d65cd Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 27 Jun 2020 13:50:52 +0200 Subject: [PATCH] introduce platform-specific module hierarchy for dlsym (similar to foreign_items) --- src/shims/dlsym.rs | 43 ++++----------- src/shims/posix/dlsym.rs | 39 +++++++++++++ src/shims/posix/linux/dlsym.rs | 34 ++++++++++++ src/shims/posix/linux/mod.rs | 1 + src/shims/posix/macos/dlsym.rs | 49 +++++++++++++++++ src/shims/posix/macos/mod.rs | 1 + src/shims/posix/mod.rs | 1 + src/shims/windows/dlsym.rs | 55 +++++++++++++++++++ src/shims/windows/mod.rs | 3 + src/shims/windows/sync.rs | 0 .../run-pass/concurrency/sync_singlethread.rs | 6 +- 11 files changed, 194 insertions(+), 38 deletions(-) create mode 100644 src/shims/posix/dlsym.rs create mode 100644 src/shims/posix/linux/dlsym.rs create mode 100644 src/shims/posix/macos/dlsym.rs create mode 100644 src/shims/windows/dlsym.rs create mode 100644 src/shims/windows/sync.rs diff --git a/src/shims/dlsym.rs b/src/shims/dlsym.rs index 87c7f447ac0..9b15cb9ac9a 100644 --- a/src/shims/dlsym.rs +++ b/src/shims/dlsym.rs @@ -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> { - 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), }) } @@ -42,23 +32,10 @@ fn call_dlsym( 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(()) } } diff --git a/src/shims/posix/dlsym.rs b/src/shims/posix/dlsym.rs new file mode 100644 index 00000000000..52d9844bed5 --- /dev/null +++ b/src/shims/posix/dlsym.rs @@ -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> { + 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), + } + } +} diff --git a/src/shims/posix/linux/dlsym.rs b/src/shims/posix/linux/dlsym.rs new file mode 100644 index 00000000000..9be300edf49 --- /dev/null +++ b/src/shims/posix/linux/dlsym.rs @@ -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> { + 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 {} + } +} diff --git a/src/shims/posix/linux/mod.rs b/src/shims/posix/linux/mod.rs index 09c6507b24f..cadd6a8ea38 100644 --- a/src/shims/posix/linux/mod.rs +++ b/src/shims/posix/linux/mod.rs @@ -1 +1,2 @@ pub mod foreign_items; +pub mod dlsym; diff --git a/src/shims/posix/macos/dlsym.rs b/src/shims/posix/macos/dlsym.rs new file mode 100644 index 00000000000..8256c10b0d3 --- /dev/null +++ b/src/shims/posix/macos/dlsym.rs @@ -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> { + 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(()) + } +} diff --git a/src/shims/posix/macos/mod.rs b/src/shims/posix/macos/mod.rs index 09c6507b24f..cadd6a8ea38 100644 --- a/src/shims/posix/macos/mod.rs +++ b/src/shims/posix/macos/mod.rs @@ -1 +1,2 @@ pub mod foreign_items; +pub mod dlsym; diff --git a/src/shims/posix/mod.rs b/src/shims/posix/mod.rs index 2f505cfb9c0..9916c65be0f 100644 --- a/src/shims/posix/mod.rs +++ b/src/shims/posix/mod.rs @@ -1,4 +1,5 @@ pub mod foreign_items; +pub mod dlsym; mod fs; mod sync; diff --git a/src/shims/windows/dlsym.rs b/src/shims/windows/dlsym.rs new file mode 100644 index 00000000000..34ed6ca150e --- /dev/null +++ b/src/shims/windows/dlsym.rs @@ -0,0 +1,55 @@ +use rustc_middle::mir; + +use crate::*; +use helpers::check_arg_count; + +#[derive(Debug, Copy, Clone)] +pub enum Dlsym { + AcquireSRWLockExclusive, + AcquireSRWLockShared, +} + +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> { + Ok(match name { + "AcquireSRWLockExclusive" => Some(Dlsym::AcquireSRWLockExclusive), + "AcquireSRWLockShared" => Some(Dlsym::AcquireSRWLockShared), + "SetThreadStackGuarantee" => None, + "GetSystemTimePreciseAsFileTime" => None, + _ => throw_unsup_format!("unsupported Windows 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 == "windows"); + + match dlsym { + Dlsym::AcquireSRWLockExclusive => { + let &[ptr] = check_arg_count(args)?; + let lock = this.deref_operand(ptr)?; // points to ptr-sized data + throw_unsup_format!("AcquireSRWLockExclusive is not actually implemented"); + } + Dlsym::AcquireSRWLockShared => { + let &[ptr] = check_arg_count(args)?; + let lock = this.deref_operand(ptr)?; // points to ptr-sized data + throw_unsup_format!("AcquireSRWLockExclusive is not actually implemented"); + } + } + + this.dump_place(*dest); + this.go_to_block(ret); + Ok(()) + } +} diff --git a/src/shims/windows/mod.rs b/src/shims/windows/mod.rs index 09c6507b24f..04f9ace8e79 100644 --- a/src/shims/windows/mod.rs +++ b/src/shims/windows/mod.rs @@ -1 +1,4 @@ pub mod foreign_items; +pub mod dlsym; + +mod sync; diff --git a/src/shims/windows/sync.rs b/src/shims/windows/sync.rs new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/run-pass/concurrency/sync_singlethread.rs b/tests/run-pass/concurrency/sync_singlethread.rs index 8b8594d4df6..749db855e29 100644 --- a/tests/run-pass/concurrency/sync_singlethread.rs +++ b/tests/run-pass/concurrency/sync_singlethread.rs @@ -6,10 +6,7 @@ fn main() { test_mutex_stdlib(); - #[cfg(not(target_os = "windows"))] // TODO: implement RwLock on Windows - { - test_rwlock_stdlib(); - } + test_rwlock_stdlib(); test_spin_loop_hint(); test_thread_yield_now(); } @@ -24,7 +21,6 @@ fn test_mutex_stdlib() { drop(m); } -#[cfg(not(target_os = "windows"))] fn test_rwlock_stdlib() { use std::sync::RwLock; let rw = RwLock::new(0); -- 2.44.0