introduce platform-specific module hierarchy for dlsym (similar to foreign_items)
This commit is contained in:
parent
bde2eb4a44
commit
dca00ab85e
@ -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 @@ 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(())
|
||||
}
|
||||
}
|
||||
|
39
src/shims/posix/dlsym.rs
Normal file
39
src/shims/posix/dlsym.rs
Normal file
@ -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
src/shims/posix/linux/dlsym.rs
Normal file
34
src/shims/posix/linux/dlsym.rs
Normal file
@ -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 +1,2 @@
|
||||
pub mod foreign_items;
|
||||
pub mod dlsym;
|
||||
|
49
src/shims/posix/macos/dlsym.rs
Normal file
49
src/shims/posix/macos/dlsym.rs
Normal file
@ -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 +1,2 @@
|
||||
pub mod foreign_items;
|
||||
pub mod dlsym;
|
||||
|
@ -1,4 +1,5 @@
|
||||
pub mod foreign_items;
|
||||
pub mod dlsym;
|
||||
|
||||
mod fs;
|
||||
mod sync;
|
||||
|
55
src/shims/windows/dlsym.rs
Normal file
55
src/shims/windows/dlsym.rs
Normal file
@ -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(())
|
||||
}
|
||||
}
|
@ -1 +1,4 @@
|
||||
pub mod foreign_items;
|
||||
pub mod dlsym;
|
||||
|
||||
mod sync;
|
||||
|
0
src/shims/windows/sync.rs
Normal file
0
src/shims/windows/sync.rs
Normal file
@ -6,10 +6,7 @@ use std::hint;
|
||||
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user