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