@@ -8,6 +8,7 @@ use rustc_target::spec::abi::Abi;
88use crate :: * ;
99use shims:: foreign_items:: EmulateByNameResult ;
1010use shims:: windows:: sync:: EvalContextExt as _;
11+ use smallvec:: SmallVec ;
1112
1213impl < ' mir , ' tcx : ' mir > EvalContextExt < ' mir , ' tcx > for crate :: MiriEvalContext < ' mir , ' tcx > { }
1314pub trait EvalContextExt < ' mir , ' tcx : ' mir > : crate :: MiriEvalContextExt < ' mir , ' tcx > {
@@ -119,10 +120,56 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
119120 system_info. ptr ,
120121 iter:: repeat ( 0u8 ) . take ( system_info. layout . size . bytes ( ) as usize ) ,
121122 ) ?;
123+ // Set selected fields.
124+ let word_layout = this. machine . layouts . u16 ;
125+ let dword_layout = this. machine . layouts . u32 ;
126+ let usize_layout = this. machine . layouts . usize ;
127+
128+ // Using `mplace_field` is error-prone, see: https://github.com/rust-lang/miri/issues/2136.
129+ // Pointer fields have different sizes on different targets.
130+ // To avoid all these issue we calculate the offsets ourselves.
131+ let field_sizes = [
132+ word_layout. size , // 0, wProcessorArchitecture : WORD
133+ word_layout. size , // 1, wReserved : WORD
134+ dword_layout. size , // 2, dwPageSize : DWORD
135+ usize_layout. size , // 3, lpMinimumApplicationAddress : LPVOID
136+ usize_layout. size , // 4, lpMaximumApplicationAddress : LPVOID
137+ usize_layout. size , // 5, dwActiveProcessorMask : DWORD_PTR
138+ dword_layout. size , // 6, dwNumberOfProcessors : DWORD
139+ dword_layout. size , // 7, dwProcessorType : DWORD
140+ dword_layout. size , // 8, dwAllocationGranularity : DWORD
141+ word_layout. size , // 9, wProcessorLevel : WORD
142+ word_layout. size , // 10, wProcessorRevision : WORD
143+ ] ;
144+ let field_offsets: SmallVec < [ Size ; 11 ] > = field_sizes
145+ . iter ( )
146+ . copied ( )
147+ . scan ( Size :: ZERO , |a, x| {
148+ let res = Some ( * a) ;
149+ * a += x;
150+ res
151+ } )
152+ . collect ( ) ;
153+
154+ // Set page size.
155+ let page_size = system_info. offset (
156+ field_offsets[ 2 ] ,
157+ MemPlaceMeta :: None ,
158+ dword_layout,
159+ & this. tcx ,
160+ ) ?;
161+ this. write_scalar (
162+ Scalar :: from_int ( PAGE_SIZE , dword_layout. size ) ,
163+ & page_size. into ( ) ,
164+ ) ?;
122165 // Set number of processors.
123- let dword_size = Size :: from_bytes ( 4 ) ;
124- let num_cpus = this. mplace_field ( & system_info, 6 ) ?;
125- this. write_scalar ( Scalar :: from_int ( NUM_CPUS , dword_size) , & num_cpus. into ( ) ) ?;
166+ let num_cpus = system_info. offset (
167+ field_offsets[ 6 ] ,
168+ MemPlaceMeta :: None ,
169+ dword_layout,
170+ & this. tcx ,
171+ ) ?;
172+ this. write_scalar ( Scalar :: from_int ( NUM_CPUS , dword_layout. size ) , & num_cpus. into ( ) ) ?;
126173 }
127174
128175 // Thread-local storage
0 commit comments