Merge pull request #4054 from devnexen/strerror_r_chg
follow-up on #4052, making a miri evaluation context fn for strerror_r.
This commit is contained in:
commit
a221d506bc
7 changed files with 62 additions and 50 deletions
|
|
@ -2,7 +2,6 @@ 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::*;
|
||||
|
||||
|
|
@ -21,14 +20,6 @@ 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)?;
|
||||
|
|
|
|||
|
|
@ -68,6 +68,30 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
throw_unsup_format!("unimplemented sysconf name: {}", name)
|
||||
}
|
||||
|
||||
fn strerror_r(
|
||||
&mut self,
|
||||
errnum: &OpTy<'tcx>,
|
||||
buf: &OpTy<'tcx>,
|
||||
buflen: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let errnum = this.read_scalar(errnum)?;
|
||||
let buf = this.read_pointer(buf)?;
|
||||
let buflen = this.read_target_usize(buflen)?;
|
||||
let error = this.try_errnum_to_io_error(errnum)?;
|
||||
let formatted = match error {
|
||||
Some(err) => format!("{err}"),
|
||||
None => format!("<unknown errnum in strerror_r: {errnum}>"),
|
||||
};
|
||||
let (complete, _) = this.write_os_str_to_c_str(OsStr::new(&formatted), buf, buflen)?;
|
||||
if complete {
|
||||
interp_ok(Scalar::from_i32(0))
|
||||
} else {
|
||||
interp_ok(Scalar::from_i32(this.eval_libc_i32("ERANGE")))
|
||||
}
|
||||
}
|
||||
|
||||
fn emulate_foreign_item_inner(
|
||||
&mut self,
|
||||
link_name: Symbol,
|
||||
|
|
@ -113,6 +137,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.write_scalar(result, 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)?;
|
||||
}
|
||||
|
||||
// File descriptors
|
||||
"read" => {
|
||||
let [fd, buf, count] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
|
||||
|
|
@ -724,21 +755,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// We do not support forking, so there is nothing to do here.
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
"strerror_r" | "__xpg_strerror_r" => {
|
||||
let [errnum, buf, buflen] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
|
||||
let errnum = this.read_scalar(errnum)?;
|
||||
let buf = this.read_pointer(buf)?;
|
||||
let buflen = this.read_target_usize(buflen)?;
|
||||
|
||||
let error = this.try_errnum_to_io_error(errnum)?;
|
||||
let formatted = match error {
|
||||
Some(err) => format!("{err}"),
|
||||
None => format!("<unknown errnum in strerror_r: {errnum}>"),
|
||||
};
|
||||
let (complete, _) = this.write_os_str_to_c_str(OsStr::new(&formatted), buf, buflen)?;
|
||||
let ret = if complete { 0 } else { this.eval_libc_i32("ERANGE") };
|
||||
this.write_int(ret, dest)?;
|
||||
}
|
||||
"getentropy" => {
|
||||
// This function is non-standard but exists with the same signature and behavior on
|
||||
// Linux, macOS, FreeBSD and Solaris/Illumos.
|
||||
|
|
@ -766,6 +782,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.write_null(dest)?;
|
||||
}
|
||||
}
|
||||
|
||||
"strerror_r" => {
|
||||
let [errnum, buf, buflen] =
|
||||
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
|
||||
let result = this.strerror_r(errnum, buf, buflen)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
|
||||
"getrandom" => {
|
||||
// This function is non-standard but exists with the same signature and behavior on
|
||||
// Linux, FreeBSD and Solaris/Illumos.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
use rustc_abi::ExternAbi;
|
||||
use rustc_span::Symbol;
|
||||
|
||||
use crate::shims::unix::foreign_items::EvalContextExt as _;
|
||||
use crate::shims::unix::*;
|
||||
use crate::*;
|
||||
|
||||
|
|
@ -76,14 +75,6 @@ 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)?;
|
||||
|
|
|
|||
|
|
@ -125,14 +125,6 @@ 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)?;
|
||||
|
|
@ -152,6 +144,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
let ptr = this.mremap(old_address, old_size, new_size, flags)?;
|
||||
this.write_scalar(ptr, dest)?;
|
||||
}
|
||||
"__xpg_strerror_r" => {
|
||||
let [errnum, buf, buflen] =
|
||||
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
|
||||
let result = this.strerror_r(errnum, buf, buflen)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
"__errno_location" => {
|
||||
let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
|
||||
let errno_place = this.last_error_place()?;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ 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::*;
|
||||
|
||||
|
|
@ -168,13 +167,6 @@ 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] =
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.write_null(dest)?;
|
||||
}
|
||||
|
||||
"sysconf" | "__sysconf_xpg7" => {
|
||||
"__sysconf_xpg7" => {
|
||||
let [val] =
|
||||
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
|
||||
let result = this.sysconf(val)?;
|
||||
|
|
|
|||
16
src/tools/miri/tests/pass-dep/libc/libc-strerror_r.rs
Normal file
16
src/tools/miri/tests/pass-dep/libc/libc-strerror_r.rs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
//@ignore-target: windows # Supported only on unixes
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
let mut buf = vec![0u8; 32];
|
||||
assert_eq!(libc::strerror_r(libc::EPERM, buf.as_mut_ptr().cast(), buf.len()), 0);
|
||||
let mut buf2 = vec![0u8; 64];
|
||||
assert_eq!(libc::strerror_r(-1i32, buf2.as_mut_ptr().cast(), buf2.len()), 0);
|
||||
// This buffer is deliberately too small so this triggers ERANGE.
|
||||
let mut buf3 = vec![0u8; 2];
|
||||
assert_eq!(
|
||||
libc::strerror_r(libc::E2BIG, buf3.as_mut_ptr().cast(), buf3.len()),
|
||||
libc::ERANGE
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue