Merge pull request #4052 from devnexen/gh4050
sysconf interception fix for solarish systems.
This commit is contained in:
commit
6a4aa9a36d
8 changed files with 90 additions and 30 deletions
|
|
@ -153,7 +153,7 @@ case $HOST_TARGET in
|
|||
TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal $BASIC $UNIX time hashmap random threadname pthread fs libc-pipe
|
||||
TEST_TARGET=i686-unknown-freebsd run_tests_minimal $BASIC $UNIX time hashmap random threadname pthread fs libc-pipe
|
||||
TEST_TARGET=x86_64-unknown-illumos run_tests_minimal $BASIC $UNIX time hashmap random thread sync available-parallelism tls libc-pipe
|
||||
# TEST_TARGET=x86_64-pc-solaris run_tests_minimal $BASIC $UNIX time hashmap random thread sync available-parallelism tls libc-pipe
|
||||
TEST_TARGET=x86_64-pc-solaris run_tests_minimal $BASIC $UNIX time hashmap random thread sync available-parallelism tls libc-pipe
|
||||
TEST_TARGET=aarch64-linux-android run_tests_minimal $BASIC $UNIX time hashmap random sync threadname pthread
|
||||
TEST_TARGET=wasm32-wasip2 run_tests_minimal $BASIC wasm
|
||||
TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std empty_main wasm # this target doesn't really have std
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use rustc_abi::ExternAbi;
|
|||
use rustc_span::Symbol;
|
||||
|
||||
use crate::shims::unix::android::thread::prctl;
|
||||
use crate::shims::unix::foreign_items::EvalContextExt as _;
|
||||
use crate::shims::unix::linux::syscall::syscall;
|
||||
use crate::*;
|
||||
|
||||
|
|
@ -20,6 +21,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
) -> InterpResult<'tcx, EmulateItemResult> {
|
||||
let this = self.eval_context_mut();
|
||||
match link_name.as_str() {
|
||||
// Querying system information
|
||||
"sysconf" => {
|
||||
let [val] =
|
||||
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
|
||||
let result = this.sysconf(val)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
|
||||
// Miscellaneous
|
||||
"__errno" => {
|
||||
let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
|
||||
|
|
|
|||
|
|
@ -39,6 +39,35 @@ pub fn is_dyn_sym(name: &str, target_os: &str) -> bool {
|
|||
|
||||
impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
|
||||
pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
// Querying system information
|
||||
fn sysconf(&mut self, val: &OpTy<'tcx>) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let name = this.read_scalar(val)?.to_i32()?;
|
||||
// FIXME: Which of these are POSIX, and which are GNU/Linux?
|
||||
// At least the names seem to all also exist on macOS.
|
||||
let sysconfs: &[(&str, fn(&MiriInterpCx<'_>) -> Scalar)] = &[
|
||||
("_SC_PAGESIZE", |this| Scalar::from_int(this.machine.page_size, this.pointer_size())),
|
||||
("_SC_PAGE_SIZE", |this| Scalar::from_int(this.machine.page_size, this.pointer_size())),
|
||||
("_SC_NPROCESSORS_CONF", |this| {
|
||||
Scalar::from_int(this.machine.num_cpus, this.pointer_size())
|
||||
}),
|
||||
("_SC_NPROCESSORS_ONLN", |this| {
|
||||
Scalar::from_int(this.machine.num_cpus, this.pointer_size())
|
||||
}),
|
||||
// 512 seems to be a reasonable default. The value is not critical, in
|
||||
// the sense that getpwuid_r takes and checks the buffer length.
|
||||
("_SC_GETPW_R_SIZE_MAX", |this| Scalar::from_int(512, this.pointer_size())),
|
||||
];
|
||||
for &(sysconf_name, value) in sysconfs {
|
||||
let sysconf_name = this.eval_libc_i32(sysconf_name);
|
||||
if sysconf_name == name {
|
||||
return interp_ok(value(this));
|
||||
}
|
||||
}
|
||||
throw_unsup_format!("unimplemented sysconf name: {}", name)
|
||||
}
|
||||
|
||||
fn emulate_foreign_item_inner(
|
||||
&mut self,
|
||||
link_name: Symbol,
|
||||
|
|
@ -393,35 +422,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
// Querying system information
|
||||
"sysconf" => {
|
||||
let [name] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
|
||||
let name = this.read_scalar(name)?.to_i32()?;
|
||||
// FIXME: Which of these are POSIX, and which are GNU/Linux?
|
||||
// At least the names seem to all also exist on macOS.
|
||||
let sysconfs: &[(&str, fn(&MiriInterpCx<'_>) -> Scalar)] = &[
|
||||
("_SC_PAGESIZE", |this| Scalar::from_int(this.machine.page_size, this.pointer_size())),
|
||||
("_SC_NPROCESSORS_CONF", |this| Scalar::from_int(this.machine.num_cpus, this.pointer_size())),
|
||||
("_SC_NPROCESSORS_ONLN", |this| Scalar::from_int(this.machine.num_cpus, this.pointer_size())),
|
||||
// 512 seems to be a reasonable default. The value is not critical, in
|
||||
// the sense that getpwuid_r takes and checks the buffer length.
|
||||
("_SC_GETPW_R_SIZE_MAX", |this| Scalar::from_int(512, this.pointer_size()))
|
||||
];
|
||||
let mut result = None;
|
||||
for &(sysconf_name, value) in sysconfs {
|
||||
let sysconf_name = this.eval_libc_i32(sysconf_name);
|
||||
if sysconf_name == name {
|
||||
result = Some(value(this));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if let Some(result) = result {
|
||||
this.write_scalar(result, dest)?;
|
||||
} else {
|
||||
throw_unsup_format!("unimplemented sysconf name: {}", name)
|
||||
}
|
||||
}
|
||||
|
||||
// Thread-local storage
|
||||
"pthread_key_create" => {
|
||||
let [key, dtor] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use rustc_abi::ExternAbi;
|
||||
use rustc_span::Symbol;
|
||||
|
||||
use crate::shims::unix::foreign_items::EvalContextExt as _;
|
||||
use crate::shims::unix::*;
|
||||
use crate::*;
|
||||
|
||||
|
|
@ -75,6 +76,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
|
||||
// Querying system information
|
||||
"sysconf" => {
|
||||
let [val] =
|
||||
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
|
||||
let result = this.sysconf(val)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
|
||||
// Miscellaneous
|
||||
"__error" => {
|
||||
let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use self::shims::unix::linux::eventfd::EvalContextExt as _;
|
|||
use self::shims::unix::linux::mem::EvalContextExt as _;
|
||||
use self::shims::unix::linux::syscall::syscall;
|
||||
use crate::machine::{SIGRTMAX, SIGRTMIN};
|
||||
use crate::shims::unix::foreign_items::EvalContextExt as _;
|
||||
use crate::shims::unix::*;
|
||||
use crate::*;
|
||||
|
||||
|
|
@ -124,6 +125,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
|
||||
// Querying system information
|
||||
"sysconf" => {
|
||||
let [val] =
|
||||
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
|
||||
let result = this.sysconf(val)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
|
||||
// Dynamically invoked syscalls
|
||||
"syscall" => {
|
||||
syscall(this, link_name, abi, args, dest)?;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use rustc_abi::ExternAbi;
|
|||
use rustc_span::Symbol;
|
||||
|
||||
use super::sync::EvalContextExt as _;
|
||||
use crate::shims::unix::foreign_items::EvalContextExt as _;
|
||||
use crate::shims::unix::*;
|
||||
use crate::*;
|
||||
|
||||
|
|
@ -167,6 +168,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.write_scalar(stack_size, dest)?;
|
||||
}
|
||||
|
||||
"sysconf" => {
|
||||
let [val] =
|
||||
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
|
||||
let result = this.sysconf(val)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
|
||||
// Threading
|
||||
"pthread_setname_np" => {
|
||||
let [name] =
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use rustc_abi::ExternAbi;
|
||||
use rustc_span::Symbol;
|
||||
|
||||
use crate::shims::unix::foreign_items::EvalContextExt as _;
|
||||
use crate::shims::unix::*;
|
||||
use crate::*;
|
||||
|
||||
|
|
@ -112,6 +113,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.write_null(dest)?;
|
||||
}
|
||||
|
||||
"sysconf" | "__sysconf_xpg7" => {
|
||||
let [val] =
|
||||
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
|
||||
let result = this.sysconf(val)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
|
||||
_ => return interp_ok(EmulateItemResult::NotSupported),
|
||||
}
|
||||
interp_ok(EmulateItemResult::NeedsReturn)
|
||||
|
|
|
|||
17
src/tools/miri/tests/pass-dep/libc/libc-sysconf.rs
Normal file
17
src/tools/miri/tests/pass-dep/libc/libc-sysconf.rs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
//@ignore-target: windows # Supported only on unixes
|
||||
|
||||
fn test_sysconfbasic() {
|
||||
unsafe {
|
||||
let ncpus = libc::sysconf(libc::_SC_NPROCESSORS_CONF);
|
||||
assert!(ncpus >= 1);
|
||||
let psz = libc::sysconf(libc::_SC_PAGESIZE);
|
||||
assert!(psz % 4096 == 0);
|
||||
// note that in reality it can return -1 (no hard limit) on some platforms.
|
||||
let gwmax = libc::sysconf(libc::_SC_GETPW_R_SIZE_MAX);
|
||||
assert!(gwmax >= 512);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
test_sysconfbasic();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue