1
- use std:: sync:: atomic:: { AtomicU64 , Ordering } ;
2
-
3
1
use rustc_middle:: ty:: { TyKind , TypeAndMut } ;
4
- use rustc_target:: abi:: { FieldsShape , LayoutOf , Size } ;
2
+ use rustc_target:: abi:: { LayoutOf , Size } ;
5
3
6
4
use crate :: stacked_borrows:: Tag ;
7
5
use crate :: * ;
@@ -102,7 +100,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
102
100
mutex_set_locked_count ( this, mutex_op, Scalar :: from_u32 ( 1 ) ) ?;
103
101
Ok ( 0 )
104
102
} else {
105
- throw_unsup_format ! ( " Deadlock due to locking a PTHREAD_MUTEX_NORMAL mutex twice" ) ;
103
+ throw_machine_stop ! ( TerminationInfo :: Deadlock ) ;
106
104
}
107
105
} else if kind == this. eval_libc ( "PTHREAD_MUTEX_ERRORCHECK" ) ? {
108
106
if locked_count == 0 {
@@ -404,58 +402,6 @@ fn mutexattr_set_kind<'mir, 'tcx: 'mir>(
404
402
// bytes 12-15 or 16-19 (depending on platform): mutex kind, as an i32
405
403
// (the kind has to be at its offset for compatibility with static initializer macros)
406
404
407
- static LIBC_MUTEX_KIND_OFFSET_CACHE : AtomicU64 = AtomicU64 :: new ( 0 ) ;
408
-
409
- fn libc_mutex_kind_offset < ' mir , ' tcx : ' mir > (
410
- ecx : & mut MiriEvalContext < ' mir , ' tcx > ,
411
- ) -> InterpResult < ' tcx , u64 > {
412
- // Check if this offset has already been found and memoized
413
- let cached_value = LIBC_MUTEX_KIND_OFFSET_CACHE . load ( Ordering :: Relaxed ) ;
414
- if cached_value != 0 {
415
- return Ok ( cached_value) ;
416
- }
417
-
418
- // This function infers the offset of the `kind` field of libc's pthread_mutex_t
419
- // C struct by examining the array inside libc::PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP.
420
- // At time of writing, it is always all zero bytes except for a one byte at one of
421
- // four positions, depending on the target OS's C struct layout and the endianness of the
422
- // target architecture. This offset will then be used in getters and setters below, so that
423
- // mutexes created from static initializers can be emulated with the correct behavior.
424
- let initializer_path = [ "libc" , "PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP" ] ;
425
- let initializer_instance = ecx. resolve_path ( & initializer_path) ;
426
- let initializer_cid = GlobalId { instance : initializer_instance, promoted : None } ;
427
- let initializer_const_val = ecx. const_eval_raw ( initializer_cid) ?;
428
- let array_mplacety = ecx. mplace_field ( initializer_const_val, 0 ) ?;
429
- let array_length = match array_mplacety. layout . fields {
430
- FieldsShape :: Array { count, .. } => count,
431
- _ => bug ! ( "Couldn't get array length from type {:?}" , array_mplacety. layout. ty) ,
432
- } ;
433
-
434
- let kind_offset = if array_length < 20 {
435
- bug ! ( "libc::PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP array was shorter than expected" ) ;
436
- } else if ecx. read_scalar ( ecx. mplace_field ( array_mplacety, 16 ) ?. into ( ) ) ?. to_u8 ( ) ? != 0 {
437
- // for little-endian architectures
438
- 16
439
- } else if ecx. read_scalar ( ecx. mplace_field ( array_mplacety, 19 ) ?. into ( ) ) ?. to_u8 ( ) ? != 0 {
440
- // for big-endian architectures
441
- // (note that the i32 spans bytes 16 through 19, so the offset of the kind field is 16)
442
- 16
443
- } else if ecx. read_scalar ( ecx. mplace_field ( array_mplacety, 12 ) ?. into ( ) ) ?. to_u8 ( ) ? != 0 {
444
- // for little-endian architectures
445
- 12
446
- } else if ecx. read_scalar ( ecx. mplace_field ( array_mplacety, 15 ) ?. into ( ) ) ?. to_u8 ( ) ? != 0 {
447
- // for big-endian architectures
448
- // (note that the i32 spans bytes 12 through 15, so the offset of the kind field is 12)
449
- 12
450
- } else {
451
- bug ! ( "Couldn't determine offset of `kind` in pthread_mutex_t" ) ;
452
- } ;
453
-
454
- // Save offset to memoization cache for future calls
455
- LIBC_MUTEX_KIND_OFFSET_CACHE . store ( kind_offset, Ordering :: Relaxed ) ;
456
- Ok ( kind_offset)
457
- }
458
-
459
405
fn mutex_get_locked_count < ' mir , ' tcx : ' mir > (
460
406
ecx : & MiriEvalContext < ' mir , ' tcx > ,
461
407
mutex_op : OpTy < ' tcx , Tag > ,
@@ -491,12 +437,9 @@ fn mutex_get_kind<'mir, 'tcx: 'mir>(
491
437
assert_ptr_target_min_size ( ecx, mutex_op, 20 ) ?;
492
438
let mutex_place = ecx. deref_operand ( mutex_op) ?;
493
439
let i32_layout = ecx. layout_of ( ecx. tcx . types . i32 ) ?;
494
- let kind_place = mutex_place. offset (
495
- Size :: from_bytes ( libc_mutex_kind_offset ( ecx) ?) ,
496
- MemPlaceMeta :: None ,
497
- i32_layout,
498
- ecx,
499
- ) ?;
440
+ let kind_offset = if ecx. pointer_size ( ) . bytes ( ) == 8 { 16 } else { 12 } ;
441
+ let kind_place =
442
+ mutex_place. offset ( Size :: from_bytes ( kind_offset) , MemPlaceMeta :: None , i32_layout, ecx) ?;
500
443
ecx. read_scalar ( kind_place. into ( ) )
501
444
}
502
445
@@ -509,12 +452,9 @@ fn mutex_set_kind<'mir, 'tcx: 'mir>(
509
452
assert_ptr_target_min_size ( ecx, mutex_op, 20 ) ?;
510
453
let mutex_place = ecx. deref_operand ( mutex_op) ?;
511
454
let i32_layout = ecx. layout_of ( ecx. tcx . types . i32 ) ?;
512
- let kind_place = mutex_place. offset (
513
- Size :: from_bytes ( libc_mutex_kind_offset ( ecx) ?) ,
514
- MemPlaceMeta :: None ,
515
- i32_layout,
516
- ecx,
517
- ) ?;
455
+ let kind_offset = if ecx. pointer_size ( ) . bytes ( ) == 8 { 16 } else { 12 } ;
456
+ let kind_place =
457
+ mutex_place. offset ( Size :: from_bytes ( kind_offset) , MemPlaceMeta :: None , i32_layout, ecx) ?;
518
458
ecx. write_scalar ( kind. into ( ) , kind_place. into ( ) )
519
459
}
520
460
0 commit comments