Skip to content

Commit

Permalink
Merge pull request #4052 from devnexen/gh4050
Browse files Browse the repository at this point in the history
sysconf interception fix for solarish systems.
  • Loading branch information
RalfJung authored Nov 23, 2024
2 parents 44e8a2a + da8a3df commit 2382a20
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 30 deletions.
2 changes: 1 addition & 1 deletion ci/ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions src/shims/unix/android/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;

Expand All @@ -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)?;
Expand Down
58 changes: 29 additions & 29 deletions src/shims/unix/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)?;
Expand Down
9 changes: 9 additions & 0 deletions src/shims/unix/freebsd/foreign_items.rs
Original file line number Diff line number Diff line change
@@ -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::*;

Expand Down Expand Up @@ -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)?;
Expand Down
9 changes: 9 additions & 0 deletions src/shims/unix/linux/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;

Expand Down Expand Up @@ -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)?;
Expand Down
8 changes: 8 additions & 0 deletions src/shims/unix/macos/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;

Expand Down Expand Up @@ -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] =
Expand Down
8 changes: 8 additions & 0 deletions src/shims/unix/solarish/foreign_items.rs
Original file line number Diff line number Diff line change
@@ -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::*;

Expand Down Expand Up @@ -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)
Expand Down
17 changes: 17 additions & 0 deletions tests/pass-dep/libc/libc-sysconf.rs
Original file line number Diff line number Diff line change
@@ -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();
}

0 comments on commit 2382a20

Please sign in to comment.