@@ -261,14 +261,58 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
261
261
this. try_unwrap_io_result ( result)
262
262
}
263
263
264
- fn stat ( & mut self ,
265
- _path_op : OpTy < ' tcx , Tag > ,
264
+ fn stat (
265
+ & mut self ,
266
+ path_op : OpTy < ' tcx , Tag > ,
266
267
buf_op : OpTy < ' tcx , Tag > ,
267
268
) -> InterpResult < ' tcx , i32 > {
268
269
let this = self . eval_context_mut ( ) ;
269
270
271
+ let path_scalar = this. read_scalar ( path_op) ?. not_undef ( ) ?;
272
+ let path = this. read_os_str_from_c_str ( path_scalar) ?;
273
+
270
274
let buf = this. deref_operand ( buf_op) ?;
271
275
276
+ let metadata = match std:: fs:: metadata ( path) {
277
+ Ok ( metadata) => metadata,
278
+ Err ( e) => {
279
+ this. set_last_error_from_io_error ( e) ?;
280
+ return Ok ( -1 ) ;
281
+ }
282
+ } ;
283
+
284
+ let file_type = metadata. file_type ( ) ;
285
+
286
+ let mode_name = if file_type. is_file ( ) {
287
+ "S_IFREG"
288
+ } else if file_type. is_dir ( ) {
289
+ "S_IFDIR"
290
+ } else {
291
+ "S_IFLNK"
292
+ } ;
293
+
294
+ let mode = this. eval_libc ( mode_name) ?. to_u32 ( ) ?;
295
+
296
+ let size = metadata. len ( ) ;
297
+
298
+ let ( access_sec, access_nsec) = extract_sec_and_nsec (
299
+ metadata. accessed ( ) ,
300
+ & mut 0 ,
301
+ 0 ,
302
+ ) ?;
303
+
304
+ let ( created_sec, created_nsec) = extract_sec_and_nsec (
305
+ metadata. created ( ) ,
306
+ & mut 0 ,
307
+ 0 ,
308
+ ) ?;
309
+
310
+ let ( modified_sec, modified_nsec) = extract_sec_and_nsec (
311
+ metadata. modified ( ) ,
312
+ & mut 0 ,
313
+ 0 ,
314
+ ) ?;
315
+
272
316
let dev_t_layout = this. libc_ty_layout ( "dev_t" ) ?;
273
317
let mode_t_layout = this. libc_ty_layout ( "mode_t" ) ?;
274
318
let nlink_t_layout = this. libc_ty_layout ( "nlink_t" ) ?;
@@ -284,21 +328,21 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
284
328
285
329
let imms = [
286
330
immty_from_uint_checked ( 0u128 , dev_t_layout) ?, // st_dev
287
- immty_from_uint_checked ( 0u128 , mode_t_layout) ?, // st_mode
331
+ immty_from_uint_checked ( mode , mode_t_layout) ?, // st_mode
288
332
immty_from_uint_checked ( 0u128 , nlink_t_layout) ?, // st_nlink
289
333
immty_from_uint_checked ( 0u128 , ino_t_layout) ?, // st_ino
290
334
immty_from_uint_checked ( 0u128 , uid_t_layout) ?, // st_uid
291
335
immty_from_uint_checked ( 0u128 , gid_t_layout) ?, // st_gid
292
336
immty_from_uint_checked ( 0u128 , dev_t_layout) ?, // st_rdev
293
- immty_from_uint_checked ( 0u128 , time_t_layout) ?, // st_atime
294
- immty_from_uint_checked ( 0u128 , long_layout) ?, // st_atime_nsec
295
- immty_from_uint_checked ( 0u128 , time_t_layout) ?, // st_mtime
296
- immty_from_uint_checked ( 0u128 , long_layout) ?, // st_mtime_nsec
337
+ immty_from_uint_checked ( access_sec , time_t_layout) ?, // st_atime
338
+ immty_from_uint_checked ( access_nsec , long_layout) ?, // st_atime_nsec
339
+ immty_from_uint_checked ( modified_sec , time_t_layout) ?, // st_mtime
340
+ immty_from_uint_checked ( modified_nsec , long_layout) ?, // st_mtime_nsec
297
341
immty_from_uint_checked ( 0u128 , time_t_layout) ?, // st_ctime
298
342
immty_from_uint_checked ( 0u128 , long_layout) ?, // st_ctime_nsec
299
- immty_from_uint_checked ( 0u128 , time_t_layout) ?, // st_birthtime
300
- immty_from_uint_checked ( 0u128 , long_layout) ?, // st_birthtime_nsec
301
- immty_from_uint_checked ( 0u128 , off_t_layout) ?, // st_size
343
+ immty_from_uint_checked ( created_sec , time_t_layout) ?, // st_birthtime
344
+ immty_from_uint_checked ( created_nsec , long_layout) ?, // st_birthtime_nsec
345
+ immty_from_uint_checked ( size , off_t_layout) ?, // st_size
302
346
immty_from_uint_checked ( 0u128 , blkcnt_t_layout) ?, // st_blocks
303
347
immty_from_uint_checked ( 0u128 , blksize_t_layout) ?, // st_blksize
304
348
immty_from_uint_checked ( 0u128 , uint32_t_layout) ?, // st_flags
0 commit comments