@@ -65,7 +65,8 @@ fn mutexattr_set_kind<'mir, 'tcx: 'mir>(
65
65
// (need to avoid this because it is set by static initializer macros)
66
66
// bytes 4-7: mutex id as u32 or 0 if id is not assigned yet.
67
67
// 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.)
69
70
70
71
fn mutex_get_id < ' mir , ' tcx : ' mir > (
71
72
ecx : & mut MiriInterpCx < ' mir , ' tcx > ,
@@ -123,11 +124,13 @@ fn mutex_set_kind<'mir, 'tcx: 'mir>(
123
124
// (need to avoid this because it is set by static initializer macros)
124
125
// bytes 4-7: rwlock id as u32 or 0 if id is not assigned yet.
125
126
127
+ const RWLOCK_ID_OFFSET : u64 = 4 ;
128
+
126
129
fn rwlock_get_id < ' mir , ' tcx : ' mir > (
127
130
ecx : & mut MiriInterpCx < ' mir , ' tcx > ,
128
131
rwlock_op : & OpTy < ' tcx , Provenance > ,
129
132
) -> 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 )
131
134
}
132
135
133
136
// pthread_condattr_t
@@ -136,13 +139,15 @@ fn rwlock_get_id<'mir, 'tcx: 'mir>(
136
139
// store an i32 in the first four bytes equal to the corresponding libc clock id constant
137
140
// (e.g. CLOCK_REALTIME).
138
141
142
+ const CONDATTR_CLOCK_OFFSET : u64 = 0 ;
143
+
139
144
fn condattr_get_clock_id < ' mir , ' tcx : ' mir > (
140
145
ecx : & MiriInterpCx < ' mir , ' tcx > ,
141
146
attr_op : & OpTy < ' tcx , Provenance > ,
142
147
) -> InterpResult < ' tcx , i32 > {
143
148
ecx. deref_pointer_and_read (
144
149
attr_op,
145
- 0 ,
150
+ CONDATTR_CLOCK_OFFSET ,
146
151
ecx. libc_ty_layout ( "pthread_condattr_t" ) ,
147
152
ecx. machine . layouts . i32 ,
148
153
) ?
@@ -156,7 +161,7 @@ fn condattr_set_clock_id<'mir, 'tcx: 'mir>(
156
161
) -> InterpResult < ' tcx , ( ) > {
157
162
ecx. deref_pointer_and_write (
158
163
attr_op,
159
- 0 ,
164
+ CONDATTR_CLOCK_OFFSET ,
160
165
Scalar :: from_i32 ( clock_id) ,
161
166
ecx. libc_ty_layout ( "pthread_condattr_t" ) ,
162
167
ecx. machine . layouts . i32 ,
@@ -172,11 +177,14 @@ fn condattr_set_clock_id<'mir, 'tcx: 'mir>(
172
177
// bytes 4-7: the conditional variable id as u32 or 0 if id is not assigned yet.
173
178
// bytes 8-11: the clock id constant as i32
174
179
180
+ const CONDVAR_ID_OFFSET : u64 = 4 ;
181
+ const CONDVAR_CLOCK_OFFSET : u64 = 8 ;
182
+
175
183
fn cond_get_id < ' mir , ' tcx : ' mir > (
176
184
ecx : & mut MiriInterpCx < ' mir , ' tcx > ,
177
185
cond_op : & OpTy < ' tcx , Provenance > ,
178
186
) -> 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 )
180
188
}
181
189
182
190
fn cond_reset_id < ' mir , ' tcx : ' mir > (
@@ -185,7 +193,7 @@ fn cond_reset_id<'mir, 'tcx: 'mir>(
185
193
) -> InterpResult < ' tcx , ( ) > {
186
194
ecx. deref_pointer_and_write (
187
195
cond_op,
188
- 4 ,
196
+ CONDVAR_ID_OFFSET ,
189
197
Scalar :: from_i32 ( 0 ) ,
190
198
ecx. libc_ty_layout ( "pthread_cond_t" ) ,
191
199
ecx. machine . layouts . u32 ,
@@ -198,7 +206,7 @@ fn cond_get_clock_id<'mir, 'tcx: 'mir>(
198
206
) -> InterpResult < ' tcx , i32 > {
199
207
ecx. deref_pointer_and_read (
200
208
cond_op,
201
- 8 ,
209
+ CONDVAR_CLOCK_OFFSET ,
202
210
ecx. libc_ty_layout ( "pthread_cond_t" ) ,
203
211
ecx. machine . layouts . i32 ,
204
212
) ?
@@ -212,7 +220,7 @@ fn cond_set_clock_id<'mir, 'tcx: 'mir>(
212
220
) -> InterpResult < ' tcx , ( ) > {
213
221
ecx. deref_pointer_and_write (
214
222
cond_op,
215
- 8 ,
223
+ CONDVAR_CLOCK_OFFSET ,
216
224
Scalar :: from_i32 ( clock_id) ,
217
225
ecx. libc_ty_layout ( "pthread_cond_t" ) ,
218
226
ecx. machine . layouts . i32 ,
@@ -719,6 +727,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
719
727
) -> InterpResult < ' tcx , Scalar < Provenance > > {
720
728
let this = self . eval_context_mut ( ) ;
721
729
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
+
722
738
let clock_id = this. read_scalar ( clock_id_op) ?. to_i32 ( ) ?;
723
739
if clock_id == this. eval_libc_i32 ( "CLOCK_REALTIME" )
724
740
|| clock_id == this. eval_libc_i32 ( "CLOCK_MONOTONIC" )
@@ -739,6 +755,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
739
755
) -> InterpResult < ' tcx , Scalar < Provenance > > {
740
756
let this = self . eval_context_mut ( ) ;
741
757
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
+
742
766
let clock_id = condattr_get_clock_id ( this, attr_op) ?;
743
767
this. write_scalar ( Scalar :: from_i32 ( clock_id) , & this. deref_pointer ( clk_id_op) ?) ?;
744
768
0 commit comments