@@ -79,7 +79,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
79
79
80
80
// pthread_mutex_t is between 24 and 48 bytes, depending on the platform
81
81
// memory layout:
82
- // bytes 0-3: count of how many times this mutex has been locked, as a u32
82
+ // bytes 0-3: reserved for signature on macOS
83
+ // bytes 4-7: count of how many times this mutex has been locked, as a u32
83
84
// bytes 12-15: mutex kind, as an i32
84
85
// (the kind should be at this offset for compatibility with the static
85
86
// initializer macro)
@@ -112,7 +113,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
112
113
} ;
113
114
114
115
let u32_layout = this. layout_of ( this. tcx . types . u32 ) ?;
115
- let locked_count_place = mutex_place. offset ( Size :: ZERO , MemPlaceMeta :: None , u32_layout, this) ?;
116
+ let locked_count_place = mutex_place. offset ( Size :: from_bytes ( 4 ) , MemPlaceMeta :: None , u32_layout, this) ?;
116
117
this. write_scalar ( Scalar :: from_u32 ( 0 ) , locked_count_place. into ( ) ) ?;
117
118
118
119
let mutex_kind_place = mutex_place. offset ( Size :: from_bytes ( 12 ) , MemPlaceMeta :: None , i32_layout, & * this. tcx ) ?;
@@ -137,7 +138,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
137
138
let kind = this. read_scalar ( kind_place. into ( ) ) ?. not_undef ( ) ?;
138
139
139
140
let u32_layout = this. layout_of ( this. tcx . types . u32 ) ?;
140
- let locked_count_place = mutex_place. offset ( Size :: ZERO , MemPlaceMeta :: None , u32_layout, this) ?;
141
+ let locked_count_place = mutex_place. offset ( Size :: from_bytes ( 4 ) , MemPlaceMeta :: None , u32_layout, this) ?;
141
142
let locked_count = this. read_scalar ( locked_count_place. into ( ) ) ?. to_u32 ( ) ?;
142
143
143
144
if kind == this. eval_libc ( "PTHREAD_MUTEX_NORMAL" ) ? {
@@ -178,7 +179,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
178
179
let kind = this. read_scalar ( kind_place. into ( ) ) ?. not_undef ( ) ?;
179
180
180
181
let u32_layout = this. layout_of ( this. tcx . types . u32 ) ?;
181
- let locked_count_place = mutex_place. offset ( Size :: ZERO , MemPlaceMeta :: None , u32_layout, this) ?;
182
+ let locked_count_place = mutex_place. offset ( Size :: from_bytes ( 4 ) , MemPlaceMeta :: None , u32_layout, this) ?;
182
183
let locked_count = this. read_scalar ( locked_count_place. into ( ) ) ?. to_u32 ( ) ?;
183
184
184
185
if kind == this. eval_libc ( "PTHREAD_MUTEX_NORMAL" ) ? ||
@@ -213,7 +214,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
213
214
let kind = this. read_scalar ( kind_place. into ( ) ) ?. not_undef ( ) ?;
214
215
215
216
let u32_layout = this. layout_of ( this. tcx . types . u32 ) ?;
216
- let locked_count_place = mutex_place. offset ( Size :: ZERO , MemPlaceMeta :: None , u32_layout, this) ?;
217
+ let locked_count_place = mutex_place. offset ( Size :: from_bytes ( 4 ) , MemPlaceMeta :: None , u32_layout, this) ?;
217
218
let locked_count = this. read_scalar ( locked_count_place. into ( ) ) ?. to_u32 ( ) ?;
218
219
219
220
if kind == this. eval_libc ( "PTHREAD_MUTEX_NORMAL" ) ? {
@@ -254,7 +255,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
254
255
let mutex_place = this. deref_operand ( mutex_op) ?;
255
256
256
257
let u32_layout = this. layout_of ( this. tcx . types . u32 ) ?;
257
- let locked_count_place = mutex_place. offset ( Size :: ZERO , MemPlaceMeta :: None , u32_layout, this) ?;
258
+ let locked_count_place = mutex_place. offset ( Size :: from_bytes ( 4 ) , MemPlaceMeta :: None , u32_layout, this) ?;
258
259
if this. read_scalar ( locked_count_place. into ( ) ) ?. to_u32 ( ) ? != 0 {
259
260
return this. eval_libc_i32 ( "EBUSY" ) ;
260
261
}
@@ -269,13 +270,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
269
270
270
271
// pthread_rwlock_t is between 32 and 56 bytes, depending on the platform
271
272
// memory layout:
272
- // bytes 0-3: reader count, as a u32
273
- // bytes 4-7: writer count, as a u32
273
+ // bytes 0-3: reserved for signature on macOS
274
+ // bytes 4-7: reader count, as a u32
275
+ // bytes 8-11: writer count, as a u32
274
276
275
277
fn pthread_rwlock_rdlock ( & mut self , rwlock_op : OpTy < ' tcx , Tag > ) -> InterpResult < ' tcx , i32 > {
276
278
let this = self . eval_context_mut ( ) ;
277
279
278
- check_ptr_target_min_size ( this, rwlock_op, 8 ) ?;
280
+ check_ptr_target_min_size ( this, rwlock_op, 12 ) ?;
279
281
280
282
let rwlock = this. read_scalar ( rwlock_op) ?. not_undef ( ) ?;
281
283
if this. is_null ( rwlock) ? {
@@ -284,8 +286,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
284
286
let rwlock_place = this. deref_operand ( rwlock_op) ?;
285
287
286
288
let u32_layout = this. layout_of ( this. tcx . types . u32 ) ?;
287
- let readers_place = rwlock_place. offset ( Size :: ZERO , MemPlaceMeta :: None , u32_layout, this) ?;
288
- let writers_place = rwlock_place. offset ( Size :: from_bytes ( 4 ) , MemPlaceMeta :: None , u32_layout, this) ?;
289
+ let readers_place = rwlock_place. offset ( Size :: from_bytes ( 4 ) , MemPlaceMeta :: None , u32_layout, this) ?;
290
+ let writers_place = rwlock_place. offset ( Size :: from_bytes ( 8 ) , MemPlaceMeta :: None , u32_layout, this) ?;
289
291
let readers = this. read_scalar ( readers_place. into ( ) ) ?. to_u32 ( ) ?;
290
292
let writers = this. read_scalar ( writers_place. into ( ) ) ?. to_u32 ( ) ?;
291
293
if writers != 0 {
@@ -299,7 +301,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
299
301
fn pthread_rwlock_tryrdlock ( & mut self , rwlock_op : OpTy < ' tcx , Tag > ) -> InterpResult < ' tcx , i32 > {
300
302
let this = self . eval_context_mut ( ) ;
301
303
302
- check_ptr_target_min_size ( this, rwlock_op, 8 ) ?;
304
+ check_ptr_target_min_size ( this, rwlock_op, 12 ) ?;
303
305
304
306
let rwlock = this. read_scalar ( rwlock_op) ?. not_undef ( ) ?;
305
307
if this. is_null ( rwlock) ? {
@@ -308,8 +310,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
308
310
let rwlock_place = this. deref_operand ( rwlock_op) ?;
309
311
310
312
let u32_layout = this. layout_of ( this. tcx . types . u32 ) ?;
311
- let readers_place = rwlock_place. offset ( Size :: ZERO , MemPlaceMeta :: None , u32_layout, this) ?;
312
- let writers_place = rwlock_place. offset ( Size :: from_bytes ( 4 ) , MemPlaceMeta :: None , u32_layout, this) ?;
313
+ let readers_place = rwlock_place. offset ( Size :: from_bytes ( 4 ) , MemPlaceMeta :: None , u32_layout, this) ?;
314
+ let writers_place = rwlock_place. offset ( Size :: from_bytes ( 8 ) , MemPlaceMeta :: None , u32_layout, this) ?;
313
315
let readers = this. read_scalar ( readers_place. into ( ) ) ?. to_u32 ( ) ?;
314
316
let writers = this. read_scalar ( writers_place. into ( ) ) ?. to_u32 ( ) ?;
315
317
if writers != 0 {
@@ -323,7 +325,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
323
325
fn pthread_rwlock_wrlock ( & mut self , rwlock_op : OpTy < ' tcx , Tag > ) -> InterpResult < ' tcx , i32 > {
324
326
let this = self . eval_context_mut ( ) ;
325
327
326
- check_ptr_target_min_size ( this, rwlock_op, 8 ) ?;
328
+ check_ptr_target_min_size ( this, rwlock_op, 12 ) ?;
327
329
328
330
let rwlock = this. read_scalar ( rwlock_op) ?. not_undef ( ) ?;
329
331
if this. is_null ( rwlock) ? {
@@ -332,8 +334,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
332
334
let rwlock_place = this. deref_operand ( rwlock_op) ?;
333
335
334
336
let u32_layout = this. layout_of ( this. tcx . types . u32 ) ?;
335
- let readers_place = rwlock_place. offset ( Size :: ZERO , MemPlaceMeta :: None , u32_layout, this) ?;
336
- let writers_place = rwlock_place. offset ( Size :: from_bytes ( 4 ) , MemPlaceMeta :: None , u32_layout, this) ?;
337
+ let readers_place = rwlock_place. offset ( Size :: from_bytes ( 4 ) , MemPlaceMeta :: None , u32_layout, this) ?;
338
+ let writers_place = rwlock_place. offset ( Size :: from_bytes ( 8 ) , MemPlaceMeta :: None , u32_layout, this) ?;
337
339
let readers = this. read_scalar ( readers_place. into ( ) ) ?. to_u32 ( ) ?;
338
340
let writers = this. read_scalar ( writers_place. into ( ) ) ?. to_u32 ( ) ?;
339
341
if readers != 0 {
@@ -349,7 +351,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
349
351
fn pthread_rwlock_trywrlock ( & mut self , rwlock_op : OpTy < ' tcx , Tag > ) -> InterpResult < ' tcx , i32 > {
350
352
let this = self . eval_context_mut ( ) ;
351
353
352
- check_ptr_target_min_size ( this, rwlock_op, 8 ) ?;
354
+ check_ptr_target_min_size ( this, rwlock_op, 12 ) ?;
353
355
354
356
let rwlock = this. read_scalar ( rwlock_op) ?. not_undef ( ) ?;
355
357
if this. is_null ( rwlock) ? {
@@ -358,8 +360,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
358
360
let rwlock_place = this. deref_operand ( rwlock_op) ?;
359
361
360
362
let u32_layout = this. layout_of ( this. tcx . types . u32 ) ?;
361
- let readers_place = rwlock_place. offset ( Size :: ZERO , MemPlaceMeta :: None , u32_layout, this) ?;
362
- let writers_place = rwlock_place. offset ( Size :: from_bytes ( 4 ) , MemPlaceMeta :: None , u32_layout, this) ?;
363
+ let readers_place = rwlock_place. offset ( Size :: from_bytes ( 4 ) , MemPlaceMeta :: None , u32_layout, this) ?;
364
+ let writers_place = rwlock_place. offset ( Size :: from_bytes ( 8 ) , MemPlaceMeta :: None , u32_layout, this) ?;
363
365
let readers = this. read_scalar ( readers_place. into ( ) ) ?. to_u32 ( ) ?;
364
366
let writers = this. read_scalar ( writers_place. into ( ) ) ?. to_u32 ( ) ?;
365
367
if readers != 0 || writers != 0 {
@@ -373,7 +375,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
373
375
fn pthread_rwlock_unlock ( & mut self , rwlock_op : OpTy < ' tcx , Tag > ) -> InterpResult < ' tcx , i32 > {
374
376
let this = self . eval_context_mut ( ) ;
375
377
376
- check_ptr_target_min_size ( this, rwlock_op, 8 ) ?;
378
+ check_ptr_target_min_size ( this, rwlock_op, 12 ) ?;
377
379
378
380
let rwlock = this. read_scalar ( rwlock_op) ?. not_undef ( ) ?;
379
381
if this. is_null ( rwlock) ? {
@@ -382,8 +384,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
382
384
let rwlock_place = this. deref_operand ( rwlock_op) ?;
383
385
384
386
let u32_layout = this. layout_of ( this. tcx . types . u32 ) ?;
385
- let readers_place = rwlock_place. offset ( Size :: ZERO , MemPlaceMeta :: None , u32_layout, this) ?;
386
- let writers_place = rwlock_place. offset ( Size :: from_bytes ( 4 ) , MemPlaceMeta :: None , u32_layout, this) ?;
387
+ let readers_place = rwlock_place. offset ( Size :: from_bytes ( 4 ) , MemPlaceMeta :: None , u32_layout, this) ?;
388
+ let writers_place = rwlock_place. offset ( Size :: from_bytes ( 8 ) , MemPlaceMeta :: None , u32_layout, this) ?;
387
389
let readers = this. read_scalar ( readers_place. into ( ) ) ?. to_u32 ( ) ?;
388
390
let writers = this. read_scalar ( writers_place. into ( ) ) ?. to_u32 ( ) ?;
389
391
if readers != 0 {
@@ -400,7 +402,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
400
402
fn pthread_rwlock_destroy ( & mut self , rwlock_op : OpTy < ' tcx , Tag > ) -> InterpResult < ' tcx , i32 > {
401
403
let this = self . eval_context_mut ( ) ;
402
404
403
- check_ptr_target_min_size ( this, rwlock_op, 8 ) ?;
405
+ check_ptr_target_min_size ( this, rwlock_op, 12 ) ?;
404
406
405
407
let rwlock = this. read_scalar ( rwlock_op) ?. not_undef ( ) ?;
406
408
if this. is_null ( rwlock) ? {
@@ -409,11 +411,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
409
411
let rwlock_place = this. deref_operand ( rwlock_op) ?;
410
412
411
413
let u32_layout = this. layout_of ( this. tcx . types . u32 ) ?;
412
- let readers_place = rwlock_place. offset ( Size :: ZERO , MemPlaceMeta :: None , u32_layout, this) ?;
414
+ let readers_place = rwlock_place. offset ( Size :: from_bytes ( 4 ) , MemPlaceMeta :: None , u32_layout, this) ?;
413
415
if this. read_scalar ( readers_place. into ( ) ) ?. to_u32 ( ) ? != 0 {
414
416
return this. eval_libc_i32 ( "EBUSY" ) ;
415
417
}
416
- let writers_place = rwlock_place. offset ( Size :: from_bytes ( 4 ) , MemPlaceMeta :: None , u32_layout, this) ?;
418
+ let writers_place = rwlock_place. offset ( Size :: from_bytes ( 8 ) , MemPlaceMeta :: None , u32_layout, this) ?;
417
419
if this. read_scalar ( writers_place. into ( ) ) ?. to_u32 ( ) ? != 0 {
418
420
return this. eval_libc_i32 ( "EBUSY" ) ;
419
421
}
0 commit comments