@@ -9,6 +9,12 @@ use rustc_middle::mir::interpret::AllocBytes;
99use crate :: alloc:: discrete_alloc:: MachineAlloc ;
1010use crate :: helpers:: ToU64 as _;
1111
12+ #[ derive( Clone , Copy , Debug ) ]
13+ pub enum MiriByteMdata {
14+ Global ,
15+ Isolated ,
16+ }
17+
1218/// Allocation bytes that explicitly handle the layout of the data they're storing.
1319/// This is necessary to interface with native code that accesses the program store in Miri.
1420#[ derive( Debug ) ]
@@ -21,15 +27,15 @@ pub struct MiriAllocBytes {
2127 /// * Otherwise, `self.ptr` points to memory allocated with `self.layout`.
2228 ptr : * mut u8 ,
2329 /// Whether this instance of `MiriAllocBytes` had its allocation created by calling `alloc::alloc()`
24- /// (true ) or the discrete allocator (false )
25- alloc_is_global : bool ,
30+ /// (`Global` ) or the discrete allocator (`Isolated` )
31+ dsc : MiriByteMdata ,
2632}
2733
2834impl Clone for MiriAllocBytes {
2935 fn clone ( & self ) -> Self {
3036 let bytes: Cow < ' _ , [ u8 ] > = Cow :: Borrowed ( self ) ;
3137 let align = Align :: from_bytes ( self . layout . align ( ) . to_u64 ( ) ) . unwrap ( ) ;
32- MiriAllocBytes :: from_bytes ( bytes, align)
38+ MiriAllocBytes :: from_bytes ( bytes, align, self . dsc )
3339 }
3440}
3541
@@ -45,16 +51,15 @@ impl Drop for MiriAllocBytes {
4551
4652 // SAFETY: Invariant, `self.ptr` points to memory allocated with `self.layout`.
4753 unsafe {
48- #[ cfg( target_os = "linux" ) ]
49- {
50- if self . alloc_is_global {
51- alloc:: dealloc ( self . ptr , alloc_layout) ;
52- } else {
53- MachineAlloc :: dealloc ( self . ptr , alloc_layout) ;
54- }
54+ match self . dsc {
55+ MiriByteMdata :: Global => alloc:: dealloc ( self . ptr , alloc_layout) ,
56+ MiriByteMdata :: Isolated => {
57+ #[ cfg( target_os = "linux" ) ]
58+ { MachineAlloc :: dealloc ( self . ptr , alloc_layout) }
59+ #[ cfg( not( target_os = "linux" ) ) ]
60+ { unreachable ! ( ) }
61+ } ,
5562 }
56- #[ cfg( not( target_os = "linux" ) ) ]
57- alloc:: dealloc ( self . ptr , alloc_layout) ;
5863 }
5964 }
6065}
@@ -84,41 +89,45 @@ impl MiriAllocBytes {
8489 fn alloc_with (
8590 size : u64 ,
8691 align : u64 ,
87- alloc_fn : impl FnOnce ( Layout ) -> ( * mut u8 , bool ) ,
92+ dsc : MiriByteMdata ,
93+ alloc_fn : impl FnOnce ( Layout ) -> * mut u8 ,
8894 ) -> Result < MiriAllocBytes , ( ) > {
8995 let size = usize:: try_from ( size) . map_err ( |_| ( ) ) ?;
9096 let align = usize:: try_from ( align) . map_err ( |_| ( ) ) ?;
9197 let layout = Layout :: from_size_align ( size, align) . map_err ( |_| ( ) ) ?;
9298 // When size is 0 we allocate 1 byte anyway, to ensure each allocation has a unique address.
9399 let alloc_layout =
94100 if size == 0 { Layout :: from_size_align ( 1 , align) . unwrap ( ) } else { layout } ;
95- let ( ptr, alloc_is_global ) = alloc_fn ( alloc_layout) ;
101+ let ptr = alloc_fn ( alloc_layout) ;
96102 if ptr. is_null ( ) {
97103 Err ( ( ) )
98104 } else {
99105 // SAFETY: All `MiriAllocBytes` invariants are fulfilled.
100- Ok ( Self { ptr, layout, alloc_is_global } )
106+ Ok ( Self { ptr, layout, dsc } )
101107 }
102108 }
103109}
104110
105111impl AllocBytes for MiriAllocBytes {
106- fn from_bytes < ' a > ( slice : impl Into < Cow < ' a , [ u8 ] > > , align : Align ) -> Self {
112+ type ByteMetadata = MiriByteMdata ;
113+
114+ fn from_bytes < ' a > ( slice : impl Into < Cow < ' a , [ u8 ] > > , align : Align , dsc : MiriByteMdata ) -> Self {
107115 let slice = slice. into ( ) ;
108116 let size = slice. len ( ) ;
109117 let align = align. bytes ( ) ;
110118 // SAFETY: `alloc_fn` will only be used with `size != 0`.
111119 let alloc_fn = |layout| unsafe {
112- #[ cfg( target_os = "linux" ) ]
113- {
114- MachineAlloc :: alloc ( layout)
115- }
116- #[ cfg( not( target_os = "linux" ) ) ]
117- {
118- ( alloc:: alloc ( layout) , true )
120+ match dsc {
121+ MiriByteMdata :: Global => alloc:: alloc ( layout) ,
122+ MiriByteMdata :: Isolated => {
123+ #[ cfg( target_os = "linux" ) ]
124+ { MachineAlloc :: alloc ( layout) }
125+ #[ cfg( not( target_os = "linux" ) ) ]
126+ { unreachable ! ( ) }
127+ } ,
119128 }
120129 } ;
121- let alloc_bytes = MiriAllocBytes :: alloc_with ( size. to_u64 ( ) , align, alloc_fn)
130+ let alloc_bytes = MiriAllocBytes :: alloc_with ( size. to_u64 ( ) , align, dsc , alloc_fn)
122131 . unwrap_or_else ( |( ) | {
123132 panic ! ( "Miri ran out of memory: cannot create allocation of {size} bytes" )
124133 } ) ;
@@ -128,21 +137,22 @@ impl AllocBytes for MiriAllocBytes {
128137 alloc_bytes
129138 }
130139
131- fn zeroed ( size : Size , align : Align ) -> Option < Self > {
140+ fn zeroed ( size : Size , align : Align , dsc : MiriByteMdata ) -> Option < Self > {
132141 let size = size. bytes ( ) ;
133142 let align = align. bytes ( ) ;
134143 // SAFETY: `alloc_fn` will only be used with `size != 0`.
135144 let alloc_fn = |layout| unsafe {
136- #[ cfg( target_os = "linux" ) ]
137- {
138- MachineAlloc :: alloc_zeroed ( layout)
139- }
140- #[ cfg( not( target_os = "linux" ) ) ]
141- {
142- ( alloc:: alloc_zeroed ( layout) , true )
145+ match dsc {
146+ MiriByteMdata :: Global => alloc:: alloc_zeroed ( layout) ,
147+ MiriByteMdata :: Isolated => {
148+ #[ cfg( target_os = "linux" ) ]
149+ { MachineAlloc :: alloc_zeroed ( layout) }
150+ #[ cfg( not( target_os = "linux" ) ) ]
151+ { unreachable ! ( ) }
152+ } ,
143153 }
144154 } ;
145- MiriAllocBytes :: alloc_with ( size, align, alloc_fn) . ok ( )
155+ MiriAllocBytes :: alloc_with ( size, align, dsc , alloc_fn) . ok ( )
146156 }
147157
148158 fn as_mut_ptr ( & mut self ) -> * mut u8 {
@@ -152,4 +162,8 @@ impl AllocBytes for MiriAllocBytes {
152162 fn as_ptr ( & self ) -> * const u8 {
153163 self . ptr
154164 }
165+
166+ fn get_mdata ( & self ) -> MiriByteMdata {
167+ self . dsc
168+ }
155169}
0 commit comments