@@ -59,6 +59,25 @@ fn is_mutex_kind_normal<'tcx>(ecx: &MiriInterpCx<'tcx>, kind: i32) -> InterpResu
5959 Ok ( kind == ( mutex_normal_kind | PTHREAD_MUTEX_NORMAL_FLAG ) )
6060}
6161
62+ /// The mutex kind.
63+ #[ derive( Debug , Clone , Copy ) ]
64+ pub enum MutexKind {
65+ Normal ,
66+ Default ,
67+ Recursive ,
68+ ErrorCheck ,
69+ }
70+
71+ #[ derive( Debug ) ]
72+ /// Additional data that we attach with each mutex instance.
73+ pub struct AdditionalMutexData {
74+ /// The mutex kind, used by some mutex implementations like pthreads mutexes.
75+ pub kind : MutexKind ,
76+
77+ /// The address of the mutex.
78+ pub address : u64 ,
79+ }
80+
6281// pthread_mutex_t is between 24 and 48 bytes, depending on the platform.
6382// We ignore the platform layout and store our own fields:
6483// - id: u32
@@ -100,8 +119,8 @@ fn mutex_create<'tcx>(
100119 let mutex = ecx. deref_pointer ( mutex_ptr) ?;
101120 let address = mutex. ptr ( ) . addr ( ) . bytes ( ) ;
102121 let kind = translate_kind ( ecx, kind) ?;
103- let data = Some ( AdditionalMutexData { address, kind } ) ;
104- ecx. mutex_create ( & mutex, mutex_id_offset ( ecx) ?, data) ?;
122+ let data = Box :: new ( AdditionalMutexData { address, kind } ) ;
123+ ecx. mutex_create ( & mutex, mutex_id_offset ( ecx) ?, Some ( data) ) ?;
105124 Ok ( ( ) )
106125}
107126
@@ -121,11 +140,13 @@ fn mutex_get_id<'tcx>(
121140 // an ID yet. We have to determine the mutex kind from the static initializer.
122141 let kind = kind_from_static_initializer ( ecx, & mutex) ?;
123142
124- Ok ( Some ( AdditionalMutexData { kind, address } ) )
143+ Ok ( Some ( Box :: new ( AdditionalMutexData { kind, address } ) ) )
125144 } ) ?;
126145
127146 // Check that the mutex has not been moved since last use.
128- let data = ecx. mutex_get_data ( id) . expect ( "data should be always exist for pthreads" ) ;
147+ let data = ecx
148+ . mutex_get_data :: < AdditionalMutexData > ( id)
149+ . expect ( "data should always exist for pthreads" ) ;
129150 if data. address != address {
130151 throw_ub_format ! ( "pthread_mutex_t can't be moved after first use" )
131152 }
@@ -171,6 +192,13 @@ fn translate_kind<'tcx>(ecx: &MiriInterpCx<'tcx>, kind: i32) -> InterpResult<'tc
171192// We ignore the platform layout and store our own fields:
172193// - id: u32
173194
195+ #[ derive( Debug ) ]
196+ /// Additional data that may be used by shim implementations.
197+ pub struct AdditionalRwLockData {
198+ /// The address of the rwlock.
199+ pub address : u64 ,
200+ }
201+
174202fn rwlock_id_offset < ' tcx > ( ecx : & MiriInterpCx < ' tcx > ) -> InterpResult < ' tcx , u64 > {
175203 let offset = match & * ecx. tcx . sess . target . os {
176204 "linux" | "illumos" | "solaris" => 0 ,
@@ -205,11 +233,13 @@ fn rwlock_get_id<'tcx>(
205233 let address = rwlock. ptr ( ) . addr ( ) . bytes ( ) ;
206234
207235 let id = ecx. rwlock_get_or_create_id ( & rwlock, rwlock_id_offset ( ecx) ?, |_| {
208- Ok ( Some ( AdditionalRwLockData { address } ) )
236+ Ok ( Some ( Box :: new ( AdditionalRwLockData { address } ) ) )
209237 } ) ?;
210238
211239 // Check that the rwlock has not been moved since last use.
212- let data = ecx. rwlock_get_data ( id) . expect ( "data should be always exist for pthreads" ) ;
240+ let data = ecx
241+ . rwlock_get_data :: < AdditionalRwLockData > ( id)
242+ . expect ( "data should always exist for pthreads" ) ;
213243 if data. address != address {
214244 throw_ub_format ! ( "pthread_rwlock_t can't be moved after first use" )
215245 }
@@ -473,8 +503,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
473503 let this = self . eval_context_mut ( ) ;
474504
475505 let id = mutex_get_id ( this, mutex_op) ?;
476- let kind =
477- this. mutex_get_data ( id) . expect ( "data should always exist for pthread mutexes" ) . kind ;
506+ let kind = this
507+ . mutex_get_data :: < AdditionalMutexData > ( id)
508+ . expect ( "data should always exist for pthread mutexes" )
509+ . kind ;
478510
479511 let ret = if this. mutex_is_locked ( id) {
480512 let owner_thread = this. mutex_get_owner ( id) ;
@@ -492,10 +524,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
492524 this. mutex_lock ( id) ;
493525 0
494526 }
495- _ =>
496- throw_unsup_format ! (
497- "called pthread_mutex_lock on an unsupported type of mutex"
498- ) ,
499527 }
500528 }
501529 } else {
@@ -511,8 +539,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
511539 let this = self . eval_context_mut ( ) ;
512540
513541 let id = mutex_get_id ( this, mutex_op) ?;
514- let kind =
515- this. mutex_get_data ( id) . expect ( "data should always exist for pthread mutexes" ) . kind ;
542+ let kind = this
543+ . mutex_get_data :: < AdditionalMutexData > ( id)
544+ . expect ( "data should always exist for pthread mutexes" )
545+ . kind ;
516546
517547 Ok ( Scalar :: from_i32 ( if this. mutex_is_locked ( id) {
518548 let owner_thread = this. mutex_get_owner ( id) ;
@@ -526,10 +556,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
526556 this. mutex_lock ( id) ;
527557 0
528558 }
529- _ =>
530- throw_unsup_format ! (
531- "called pthread_mutex_trylock on an unsupported type of mutex"
532- ) ,
533559 }
534560 }
535561 } else {
@@ -543,8 +569,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
543569 let this = self . eval_context_mut ( ) ;
544570
545571 let id = mutex_get_id ( this, mutex_op) ?;
546- let kind =
547- this. mutex_get_data ( id) . expect ( "data should always exist for pthread mutexes" ) . kind ;
572+ let kind = this
573+ . mutex_get_data :: < AdditionalMutexData > ( id)
574+ . expect ( "data should always exist for pthread mutexes" )
575+ . kind ;
548576
549577 if let Some ( _old_locked_count) = this. mutex_unlock ( id) ? {
550578 // The mutex was locked by the current thread.
@@ -564,10 +592,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
564592 ) ,
565593 MutexKind :: ErrorCheck | MutexKind :: Recursive =>
566594 Ok ( Scalar :: from_i32 ( this. eval_libc_i32 ( "EPERM" ) ) ) ,
567- _ =>
568- throw_unsup_format ! (
569- "called pthread_mutex_unlock on an unsupported type of mutex"
570- ) ,
571595 }
572596 }
573597 }
0 commit comments