]> git.lizzy.rs Git - rust.git/blob - src/shims/windows/dlsym.rs
implement Windows SRWLock shims
[rust.git] / src / shims / windows / dlsym.rs
1 use rustc_middle::mir;
2
3 use crate::*;
4 use helpers::check_arg_count;
5 use shims::windows::sync::EvalContextExt as _;
6
7 #[derive(Debug, Copy, Clone)]
8 pub enum Dlsym {
9     AcquireSRWLockExclusive,
10     ReleaseSRWLockExclusive,
11     TryAcquireSRWLockExclusive,
12     AcquireSRWLockShared,
13     ReleaseSRWLockShared,
14     TryAcquireSRWLockShared,
15 }
16
17 impl Dlsym {
18     // Returns an error for unsupported symbols, and None if this symbol
19     // should become a NULL pointer (pretend it does not exist).
20     pub fn from_str(name: &str) -> InterpResult<'static, Option<Dlsym>> {
21         Ok(match name {
22             "AcquireSRWLockExclusive" => Some(Dlsym::AcquireSRWLockExclusive),
23             "ReleaseSRWLockExclusive" => Some(Dlsym::ReleaseSRWLockExclusive),
24             "TryAcquireSRWLockExclusive" => Some(Dlsym::TryAcquireSRWLockExclusive),
25             "AcquireSRWLockShared" => Some(Dlsym::AcquireSRWLockShared),
26             "ReleaseSRWLockShared" => Some(Dlsym::ReleaseSRWLockShared),
27             "TryAcquireSRWLockShared" => Some(Dlsym::TryAcquireSRWLockShared),
28             "SetThreadStackGuarantee" => None,
29             "GetSystemTimePreciseAsFileTime" => None,
30             _ => throw_unsup_format!("unsupported Windows dlsym: {}", name),
31         })
32     }
33 }
34
35 impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
36 pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
37     fn call_dlsym(
38         &mut self,
39         dlsym: Dlsym,
40         args: &[OpTy<'tcx, Tag>],
41         ret: Option<(PlaceTy<'tcx, Tag>, mir::BasicBlock)>,
42     ) -> InterpResult<'tcx> {
43         let this = self.eval_context_mut();
44         let (dest, ret) = ret.expect("we don't support any diverging dlsym");
45         assert!(this.tcx.sess.target.target.target_os == "windows");
46
47         match dlsym {
48             Dlsym::AcquireSRWLockExclusive => {
49                 let &[ptr] = check_arg_count(args)?;
50                 this.AcquireSRWLockExclusive(ptr)?;
51             }
52             Dlsym::ReleaseSRWLockExclusive => {
53                 let &[ptr] = check_arg_count(args)?;
54                 this.ReleaseSRWLockExclusive(ptr)?;
55             }
56             Dlsym::TryAcquireSRWLockExclusive => {
57                 let &[ptr] = check_arg_count(args)?;
58                 let ret = this.TryAcquireSRWLockExclusive(ptr)?;
59                 this.write_scalar(Scalar::from_u8(ret), dest)?;
60             }
61             Dlsym::AcquireSRWLockShared => {
62                 let &[ptr] = check_arg_count(args)?;
63                 this.AcquireSRWLockShared(ptr)?;
64             }
65             Dlsym::ReleaseSRWLockShared => {
66                 let &[ptr] = check_arg_count(args)?;
67                 this.ReleaseSRWLockShared(ptr)?;
68             }
69             Dlsym::TryAcquireSRWLockShared => {
70                 let &[ptr] = check_arg_count(args)?;
71                 let ret = this.TryAcquireSRWLockShared(ptr)?;
72                 this.write_scalar(Scalar::from_u8(ret), dest)?;
73             }
74         }
75
76         this.dump_place(*dest);
77         this.go_to_block(ret);
78         Ok(())
79     }
80 }