@@ -65,7 +65,8 @@ fn mutexattr_set_kind<'mir, 'tcx: 'mir>(
6565// (need to avoid this because it is set by static initializer macros)
6666// bytes 4-7: mutex id as u32 or 0 if id is not assigned yet.
6767// bytes 12-15 or 16-19 (depending on platform): mutex kind, as an i32
68- // (the kind has to be at its offset for compatibility with static initializer macros)
68+ // (the kind has to be at this particular offset for compatibility with Linux's static initializer
69+ // macros, e.g. PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP.)
6970
7071fn mutex_get_id < ' mir , ' tcx : ' mir > (
7172 ecx : & mut MiriInterpCx < ' mir , ' tcx > ,
@@ -123,11 +124,13 @@ fn mutex_set_kind<'mir, 'tcx: 'mir>(
123124// (need to avoid this because it is set by static initializer macros)
124125// bytes 4-7: rwlock id as u32 or 0 if id is not assigned yet.
125126
127+ const RWLOCK_ID_OFFSET : u64 = 4 ;
128+
126129fn rwlock_get_id < ' mir , ' tcx : ' mir > (
127130 ecx : & mut MiriInterpCx < ' mir , ' tcx > ,
128131 rwlock_op : & OpTy < ' tcx , Provenance > ,
129132) -> InterpResult < ' tcx , RwLockId > {
130- ecx. rwlock_get_or_create_id ( rwlock_op, ecx. libc_ty_layout ( "pthread_rwlock_t" ) , 4 )
133+ ecx. rwlock_get_or_create_id ( rwlock_op, ecx. libc_ty_layout ( "pthread_rwlock_t" ) , RWLOCK_ID_OFFSET )
131134}
132135
133136// pthread_condattr_t
@@ -136,13 +139,15 @@ fn rwlock_get_id<'mir, 'tcx: 'mir>(
136139// store an i32 in the first four bytes equal to the corresponding libc clock id constant
137140// (e.g. CLOCK_REALTIME).
138141
142+ const CONDATTR_CLOCK_OFFSET : u64 = 0 ;
143+
139144fn condattr_get_clock_id < ' mir , ' tcx : ' mir > (
140145 ecx : & MiriInterpCx < ' mir , ' tcx > ,
141146 attr_op : & OpTy < ' tcx , Provenance > ,
142147) -> InterpResult < ' tcx , i32 > {
143148 ecx. deref_pointer_and_read (
144149 attr_op,
145- 0 ,
150+ CONDATTR_CLOCK_OFFSET ,
146151 ecx. libc_ty_layout ( "pthread_condattr_t" ) ,
147152 ecx. machine . layouts . i32 ,
148153 ) ?
@@ -156,7 +161,7 @@ fn condattr_set_clock_id<'mir, 'tcx: 'mir>(
156161) -> InterpResult < ' tcx , ( ) > {
157162 ecx. deref_pointer_and_write (
158163 attr_op,
159- 0 ,
164+ CONDATTR_CLOCK_OFFSET ,
160165 Scalar :: from_i32 ( clock_id) ,
161166 ecx. libc_ty_layout ( "pthread_condattr_t" ) ,
162167 ecx. machine . layouts . i32 ,
@@ -172,11 +177,14 @@ fn condattr_set_clock_id<'mir, 'tcx: 'mir>(
172177// bytes 4-7: the conditional variable id as u32 or 0 if id is not assigned yet.
173178// bytes 8-11: the clock id constant as i32
174179
180+ const CONDVAR_ID_OFFSET : u64 = 4 ;
181+ const CONDVAR_CLOCK_OFFSET : u64 = 8 ;
182+
175183fn cond_get_id < ' mir , ' tcx : ' mir > (
176184 ecx : & mut MiriInterpCx < ' mir , ' tcx > ,
177185 cond_op : & OpTy < ' tcx , Provenance > ,
178186) -> InterpResult < ' tcx , CondvarId > {
179- ecx. condvar_get_or_create_id ( cond_op, ecx. libc_ty_layout ( "pthread_cond_t" ) , 4 )
187+ ecx. condvar_get_or_create_id ( cond_op, ecx. libc_ty_layout ( "pthread_cond_t" ) , CONDVAR_ID_OFFSET )
180188}
181189
182190fn cond_reset_id < ' mir , ' tcx : ' mir > (
@@ -185,7 +193,7 @@ fn cond_reset_id<'mir, 'tcx: 'mir>(
185193) -> InterpResult < ' tcx , ( ) > {
186194 ecx. deref_pointer_and_write (
187195 cond_op,
188- 4 ,
196+ CONDVAR_ID_OFFSET ,
189197 Scalar :: from_i32 ( 0 ) ,
190198 ecx. libc_ty_layout ( "pthread_cond_t" ) ,
191199 ecx. machine . layouts . u32 ,
@@ -198,7 +206,7 @@ fn cond_get_clock_id<'mir, 'tcx: 'mir>(
198206) -> InterpResult < ' tcx , i32 > {
199207 ecx. deref_pointer_and_read (
200208 cond_op,
201- 8 ,
209+ CONDVAR_CLOCK_OFFSET ,
202210 ecx. libc_ty_layout ( "pthread_cond_t" ) ,
203211 ecx. machine . layouts . i32 ,
204212 ) ?
@@ -212,7 +220,7 @@ fn cond_set_clock_id<'mir, 'tcx: 'mir>(
212220) -> InterpResult < ' tcx , ( ) > {
213221 ecx. deref_pointer_and_write (
214222 cond_op,
215- 8 ,
223+ CONDVAR_CLOCK_OFFSET ,
216224 Scalar :: from_i32 ( clock_id) ,
217225 ecx. libc_ty_layout ( "pthread_cond_t" ) ,
218226 ecx. machine . layouts . i32 ,
@@ -719,6 +727,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
719727 ) -> InterpResult < ' tcx , Scalar < Provenance > > {
720728 let this = self . eval_context_mut ( ) ;
721729
730+ // Does not exist on macOS!
731+ if !matches ! ( & * this. tcx. sess. target. os, "linux" ) {
732+ throw_unsup_format ! (
733+ "`pthread_condattr_init` is not supported on {}" ,
734+ this. tcx. sess. target. os
735+ ) ;
736+ }
737+
722738 let clock_id = this. read_scalar ( clock_id_op) ?. to_i32 ( ) ?;
723739 if clock_id == this. eval_libc_i32 ( "CLOCK_REALTIME" )
724740 || clock_id == this. eval_libc_i32 ( "CLOCK_MONOTONIC" )
@@ -739,6 +755,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
739755 ) -> InterpResult < ' tcx , Scalar < Provenance > > {
740756 let this = self . eval_context_mut ( ) ;
741757
758+ // Does not exist on macOS!
759+ if !matches ! ( & * this. tcx. sess. target. os, "linux" ) {
760+ throw_unsup_format ! (
761+ "`pthread_condattr_init` is not supported on {}" ,
762+ this. tcx. sess. target. os
763+ ) ;
764+ }
765+
742766 let clock_id = condattr_get_clock_id ( this, attr_op) ?;
743767 this. write_scalar ( Scalar :: from_i32 ( clock_id) , & this. deref_pointer ( clk_id_op) ?) ?;
744768
0 commit comments