Skip to content

Commit bb55f52

Browse files
committed
follow-up on rust-lang#4052, making a miri evaluation context fn for strerror_r.
1 parent 6a4aa9a commit bb55f52

File tree

7 files changed

+62
-50
lines changed

7 files changed

+62
-50
lines changed

src/tools/miri/src/shims/unix/android/foreign_items.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ use rustc_abi::ExternAbi;
22
use rustc_span::Symbol;
33

44
use crate::shims::unix::android::thread::prctl;
5-
use crate::shims::unix::foreign_items::EvalContextExt as _;
65
use crate::shims::unix::linux::syscall::syscall;
76
use crate::*;
87

@@ -21,14 +20,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
2120
) -> InterpResult<'tcx, EmulateItemResult> {
2221
let this = self.eval_context_mut();
2322
match link_name.as_str() {
24-
// Querying system information
25-
"sysconf" => {
26-
let [val] =
27-
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
28-
let result = this.sysconf(val)?;
29-
this.write_scalar(result, dest)?;
30-
}
31-
3223
// Miscellaneous
3324
"__errno" => {
3425
let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;

src/tools/miri/src/shims/unix/foreign_items.rs

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,30 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
6868
throw_unsup_format!("unimplemented sysconf name: {}", name)
6969
}
7070

71+
fn strerror_r(
72+
&mut self,
73+
errnum: &OpTy<'tcx>,
74+
buf: &OpTy<'tcx>,
75+
buflen: &OpTy<'tcx>,
76+
) -> InterpResult<'tcx, Scalar> {
77+
let this = self.eval_context_mut();
78+
79+
let errnum = this.read_scalar(errnum)?;
80+
let buf = this.read_pointer(buf)?;
81+
let buflen = this.read_target_usize(buflen)?;
82+
let error = this.try_errnum_to_io_error(errnum)?;
83+
let formatted = match error {
84+
Some(err) => format!("{err}"),
85+
None => format!("<unknown errnum in strerror_r: {errnum}>"),
86+
};
87+
let (complete, _) = this.write_os_str_to_c_str(OsStr::new(&formatted), buf, buflen)?;
88+
if complete {
89+
interp_ok(Scalar::from_i32(0))
90+
} else {
91+
interp_ok(Scalar::from_i32(this.eval_libc_i32("ERANGE")))
92+
}
93+
}
94+
7195
fn emulate_foreign_item_inner(
7296
&mut self,
7397
link_name: Symbol,
@@ -113,6 +137,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
113137
this.write_scalar(result, dest)?;
114138
}
115139

140+
"sysconf" => {
141+
let [val] =
142+
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
143+
let result = this.sysconf(val)?;
144+
this.write_scalar(result, dest)?;
145+
}
146+
116147
// File descriptors
117148
"read" => {
118149
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> {
724755
// We do not support forking, so there is nothing to do here.
725756
this.write_null(dest)?;
726757
}
727-
"strerror_r" | "__xpg_strerror_r" => {
728-
let [errnum, buf, buflen] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
729-
let errnum = this.read_scalar(errnum)?;
730-
let buf = this.read_pointer(buf)?;
731-
let buflen = this.read_target_usize(buflen)?;
732-
733-
let error = this.try_errnum_to_io_error(errnum)?;
734-
let formatted = match error {
735-
Some(err) => format!("{err}"),
736-
None => format!("<unknown errnum in strerror_r: {errnum}>"),
737-
};
738-
let (complete, _) = this.write_os_str_to_c_str(OsStr::new(&formatted), buf, buflen)?;
739-
let ret = if complete { 0 } else { this.eval_libc_i32("ERANGE") };
740-
this.write_int(ret, dest)?;
741-
}
742758
"getentropy" => {
743759
// This function is non-standard but exists with the same signature and behavior on
744760
// Linux, macOS, FreeBSD and Solaris/Illumos.
@@ -766,6 +782,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
766782
this.write_null(dest)?;
767783
}
768784
}
785+
786+
"strerror_r" => {
787+
let [errnum, buf, buflen] =
788+
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
789+
let result = this.strerror_r(errnum, buf, buflen)?;
790+
this.write_scalar(result, dest)?;
791+
}
792+
769793
"getrandom" => {
770794
// This function is non-standard but exists with the same signature and behavior on
771795
// Linux, FreeBSD and Solaris/Illumos.

src/tools/miri/src/shims/unix/freebsd/foreign_items.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use rustc_abi::ExternAbi;
22
use rustc_span::Symbol;
33

4-
use crate::shims::unix::foreign_items::EvalContextExt as _;
54
use crate::shims::unix::*;
65
use crate::*;
76

@@ -76,14 +75,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
7675
this.write_scalar(result, dest)?;
7776
}
7877

79-
// Querying system information
80-
"sysconf" => {
81-
let [val] =
82-
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
83-
let result = this.sysconf(val)?;
84-
this.write_scalar(result, dest)?;
85-
}
86-
8778
// Miscellaneous
8879
"__error" => {
8980
let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;

src/tools/miri/src/shims/unix/linux/foreign_items.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -125,14 +125,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
125125
this.write_scalar(result, dest)?;
126126
}
127127

128-
// Querying system information
129-
"sysconf" => {
130-
let [val] =
131-
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
132-
let result = this.sysconf(val)?;
133-
this.write_scalar(result, dest)?;
134-
}
135-
136128
// Dynamically invoked syscalls
137129
"syscall" => {
138130
syscall(this, link_name, abi, args, dest)?;
@@ -152,6 +144,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
152144
let ptr = this.mremap(old_address, old_size, new_size, flags)?;
153145
this.write_scalar(ptr, dest)?;
154146
}
147+
"__xpg_strerror_r" => {
148+
let [errnum, buf, buflen] =
149+
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
150+
let result = this.strerror_r(errnum, buf, buflen)?;
151+
this.write_scalar(result, dest)?;
152+
}
155153
"__errno_location" => {
156154
let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
157155
let errno_place = this.last_error_place()?;

src/tools/miri/src/shims/unix/macos/foreign_items.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ use rustc_abi::ExternAbi;
22
use rustc_span::Symbol;
33

44
use super::sync::EvalContextExt as _;
5-
use crate::shims::unix::foreign_items::EvalContextExt as _;
65
use crate::shims::unix::*;
76
use crate::*;
87

@@ -168,13 +167,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
168167
this.write_scalar(stack_size, dest)?;
169168
}
170169

171-
"sysconf" => {
172-
let [val] =
173-
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
174-
let result = this.sysconf(val)?;
175-
this.write_scalar(result, dest)?;
176-
}
177-
178170
// Threading
179171
"pthread_setname_np" => {
180172
let [name] =

src/tools/miri/src/shims/unix/solarish/foreign_items.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
113113
this.write_null(dest)?;
114114
}
115115

116-
"sysconf" | "__sysconf_xpg7" => {
116+
"__sysconf_xpg7" => {
117117
let [val] =
118118
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
119119
let result = this.sysconf(val)?;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//@ignore-target: windows # Supported only on unixes
2+
3+
fn main() {
4+
unsafe {
5+
let mut buf = vec![0u8; 32];
6+
assert_eq!(libc::strerror_r(libc::EPERM, buf.as_mut_ptr().cast(), buf.len()), 0);
7+
let mut buf2 = vec![0u8; 64];
8+
assert_eq!(libc::strerror_r(-1i32, buf2.as_mut_ptr().cast(), buf2.len()), 0);
9+
// This buffer is deliberately too small so this triggers ERANGE.
10+
let mut buf3 = vec![0u8; 2];
11+
assert_eq!(
12+
libc::strerror_r(libc::E2BIG, buf3.as_mut_ptr().cast(), buf3.len()),
13+
libc::ERANGE
14+
);
15+
}
16+
}

0 commit comments

Comments
 (0)