@@ -288,7 +288,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
288288
289289 // Under normal circumstances, we would use `deref_operand(statxbuf_op)` to produce a
290290 // proper `MemPlace` and then write the results of this function to it. However, the
291- // syscall API in Rust is untyped. This means that all the `statx` parameters are provided
291+ // ` syscall` function is untyped. This means that all the `statx` parameters are provided
292292 // as `isize`s instead of having the proper types. Thus, we have to recover the layout of
293293 // `statxbuf_op` by using the `libc::statx` struct type.
294294 let statxbuf_place = {
@@ -303,39 +303,23 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
303303 this. ref_to_mplace ( statxbuf_imm) ?
304304 } ;
305305
306- let pathname: PathBuf = this. read_os_str_from_c_str ( pathname_scalar) ?. into ( ) ;
307- // This argument should be a `c_int` but the syscall API just returns a pointer sized
308- // integer.
306+ let path: PathBuf = this. read_os_str_from_c_str ( pathname_scalar) ?. into ( ) ;
307+ // `flags` should be a `c_int` but the `syscall` function provides an `isize`.
309308 let flags: i32 = this. try_from_ptr_sized_operand ( flags_op) ?;
310309
311- let at_fdcwd = this. eval_libc_i32 ( "AT_FDCWD" ) ?;
312- // Now we need to resolve the path of the target file. This was done following the manual
313- // entry for `statx`
314-
315- // If `pathname` is absolute we can ignore `dirfd`.
316- let path = if pathname. is_absolute ( ) {
317- pathname
318- } else {
319- // This argument should be a `c_int` but the syscall API just returns a pointer sized
320- // integer.
321- let dirfd: i32 = this. try_from_ptr_sized_operand ( dirfd_op) ?;
322- // If `dirfd` is `AT_FDCWD`, `pathname` is relative to the current directory.
323- if dirfd == at_fdcwd {
324- match std:: env:: current_dir ( ) {
325- Ok ( cwd) => cwd. join ( pathname) ,
326- Err ( e) => {
327- this. set_last_error_from_io_error ( e) ?;
328- return Ok ( -1 ) ;
329- }
330- }
331- } else {
332- // This behavior is specified but cannot be tested from `libstd`. If you found this
333- // error please open an issue reporting it.
334- throw_unsup_format ! (
335- "Using statx with a fildes different from `AT_FDCWD` is not supported"
336- )
337- }
338- } ;
310+ // we only support interpreting `path` as an absolute directory or as a directory relative
311+ // to `dirfd` when the latter is `AT_FDCWD`. Other behavior is specified but it cannot be
312+ // tested from `libstd`. If you found this error, please open an issue reporting it.
313+
314+ // `dirfd` should be a `c_int` but the `syscall` function provides an `isize`.
315+ if !( path. is_absolute ( )
316+ || this. try_from_ptr_sized_operand :: < i32 > ( dirfd_op) ?
317+ == this. eval_libc_i32 ( "AT_FDCWD" ) ?)
318+ {
319+ throw_unsup_format ! (
320+ "Using statx with a file descriptor different from `AT_FDCWD` is not supported"
321+ )
322+ }
339323
340324 // the `_mask_op` paramter specifies the file information that the caller requested.
341325 // However `statx` is allowed to return information that was not requested or to not
@@ -366,8 +350,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
366350 // The `mode` field specifies the type of the file and the permissions over the file for
367351 // the owner, its group and other users. Given that we can only provide the file type
368352 // without using platform specific methods, we only set the bits corresponding to the file
369- // type. This argument should be an `__u16` but the syscall API just returns a pointer sized
370- // integer.
353+ // type. This should be an `__u16` but `libc` provides its values as `u32`.
371354 let mode = if file_type. is_file ( ) {
372355 this. eval_libc ( "S_IFREG" ) ?
373356 } else if file_type. is_dir ( ) {
@@ -377,7 +360,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
377360 } . to_u32 ( ) ?;
378361
379362 let mode: u16 = mode. try_into ( ) . map_err ( |e|
380- err_unsup_format ! ( "Failed to convert 32-bit operand to u16: {}" ,
363+ err_unsup_format ! ( "Failed to convert 32-bit value to u16: {}" ,
381364 e
382365 ) ) ?;
383366
0 commit comments