]> git.lizzy.rs Git - rust.git/commitdiff
introduce platform-specific module hierarchy for dlsym (similar to foreign_items)
authorRalf Jung <post@ralfj.de>
Sat, 27 Jun 2020 11:50:52 +0000 (13:50 +0200)
committerRalf Jung <post@ralfj.de>
Sat, 27 Jun 2020 12:36:05 +0000 (14:36 +0200)
src/shims/dlsym.rs
src/shims/posix/dlsym.rs [new file with mode: 0644]
src/shims/posix/linux/dlsym.rs [new file with mode: 0644]
src/shims/posix/linux/mod.rs
src/shims/posix/macos/dlsym.rs [new file with mode: 0644]
src/shims/posix/macos/mod.rs
src/shims/posix/mod.rs
src/shims/windows/dlsym.rs [new file with mode: 0644]
src/shims/windows/mod.rs
src/shims/windows/sync.rs [new file with mode: 0644]
tests/run-pass/concurrency/sync_singlethread.rs

index 87c7f447ac03cff3580f09b951110cb2a86625d4..9b15cb9ac9a31a96bc1b550101dc91d948102a39 100644 (file)
@@ -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),
         })
     }
@@ -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 (file)
index 0000000..52d9844
--- /dev/null
@@ -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),
+        }
+    }
+}
diff --git a/src/shims/posix/linux/dlsym.rs b/src/shims/posix/linux/dlsym.rs
new file mode 100644 (file)
index 0000000..9be300e
--- /dev/null
@@ -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 {}
+    }
+}
index 09c6507b24f84df2ca99460082fe4581ad4bf758..cadd6a8ea384e0c142dcbb268fd9c8cfff39229c 100644 (file)
@@ -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 (file)
index 0000000..8256c10
--- /dev/null
@@ -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(())
+    }
+}
index 09c6507b24f84df2ca99460082fe4581ad4bf758..cadd6a8ea384e0c142dcbb268fd9c8cfff39229c 100644 (file)
@@ -1 +1,2 @@
 pub mod foreign_items;
+pub mod dlsym;
index 2f505cfb9c0b54c0f4b26f52e5aa3a927333ccb4..9916c65be0fb852c9c068da148317a632e7126bd 100644 (file)
@@ -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 (file)
index 0000000..34ed6ca
--- /dev/null
@@ -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<Dlsym>> {
+        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(())
+    }
+}
index 09c6507b24f84df2ca99460082fe4581ad4bf758..04f9ace8e799b92ec4cce160ca007eb8f4c36c81 100644 (file)
@@ -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 (file)
index 0000000..e69de29
index 8b8594d4df69dc32a124f609e31c83dc5ba926bb..749db855e296f13f10ebf8c1b7b7dbbe86ab0cb6 100644 (file)
@@ -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);