@@ -51,6 +51,18 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
5151 Ok ( Some ( this. load_mir ( instance. def ) ?) )
5252 }
5353
54+ /// Returns the minimum alignment for the target architecture.
55+ fn min_align ( & self ) -> Align {
56+ let this = self . eval_context_ref ( ) ;
57+ // List taken from `libstd/sys_common/alloc.rs`.
58+ let min_align = match this. tcx . tcx . sess . target . target . arch . as_str ( ) {
59+ "x86" | "arm" | "mips" | "powerpc" | "powerpc64" | "asmjs" | "wasm32" => 8 ,
60+ "x86_64" | "aarch64" | "mips64" | "s390x" | "sparc64" => 16 ,
61+ arch => bug ! ( "Unsupported target architecture: {}" , arch) ,
62+ } ;
63+ Align :: from_bytes ( min_align) . unwrap ( )
64+ }
65+
5466 fn malloc (
5567 & mut self ,
5668 size : u64 ,
@@ -61,7 +73,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
6173 if size == 0 {
6274 Scalar :: from_int ( 0 , this. pointer_size ( ) )
6375 } else {
64- let align = this. tcx . data_layout . pointer_align . abi ;
76+ let align = this. min_align ( ) ;
6577 let ptr = this. memory_mut ( ) . allocate ( Size :: from_bytes ( size) , align, MiriMemoryKind :: C . into ( ) ) ;
6678 if zero_init {
6779 // We just allocated this, the access cannot fail
@@ -94,7 +106,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
94106 new_size : u64 ,
95107 ) -> InterpResult < ' tcx , Scalar < Tag > > {
96108 let this = self . eval_context_mut ( ) ;
97- let align = this. tcx . data_layout . pointer_align . abi ;
109+ let align = this. min_align ( ) ;
98110 if old_ptr. is_null_ptr ( this) {
99111 if new_size == 0 {
100112 Ok ( Scalar :: from_int ( 0 , this. pointer_size ( ) ) )
@@ -191,12 +203,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
191203 if !align. is_power_of_two ( ) {
192204 return err ! ( HeapAllocNonPowerOfTwoAlignment ( align) ) ;
193205 }
206+ /*
207+ FIXME: This check is disabled because rustc violates it.
208+ See <https://github.com/rust-lang/rust/issues/62251>.
194209 if align < this.pointer_size().bytes() {
195210 return err!(MachineError(format!(
196211 "posix_memalign: alignment must be at least the size of a pointer, but is {}",
197212 align,
198213 )));
199214 }
215+ */
200216 if size == 0 {
201217 this. write_null ( ret. into ( ) ) ?;
202218 } else {
@@ -622,11 +638,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
622638 let name = this. read_scalar ( args[ 0 ] ) ?. to_i32 ( ) ?;
623639
624640 trace ! ( "sysconf() called with name {}" , name) ;
625- // Cache the sysconf integers via Miri's global cache.
641+ // TODO: Cache the sysconf integers via Miri's global cache.
626642 let paths = & [
627- ( & [ "libc" , "_SC_PAGESIZE" ] , Scalar :: from_int ( 4096 , dest. layout . size ) ) ,
643+ ( & [ "libc" , "_SC_PAGESIZE" ] , Scalar :: from_int ( PAGE_SIZE , dest. layout . size ) ) ,
628644 ( & [ "libc" , "_SC_GETPW_R_SIZE_MAX" ] , Scalar :: from_int ( -1 , dest. layout . size ) ) ,
629- ( & [ "libc" , "_SC_NPROCESSORS_ONLN" ] , Scalar :: from_int ( 1 , dest. layout . size ) ) ,
645+ ( & [ "libc" , "_SC_NPROCESSORS_ONLN" ] , Scalar :: from_int ( NUM_CPUS , dest. layout . size ) ) ,
630646 ] ;
631647 let mut result = None ;
632648 for & ( path, path_value) in paths {
@@ -648,6 +664,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
648664 }
649665 }
650666
667+ "sched_getaffinity" => {
668+ // Return an error; `num_cpus` then falls back to `sysconf`.
669+ this. write_scalar ( Scalar :: from_int ( -1 , dest. layout . size ) , dest) ?;
670+ }
671+
651672 "isatty" => {
652673 this. write_null ( dest) ?;
653674 }
@@ -722,14 +743,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
722743 // Second argument is where we are supposed to write the stack size.
723744 let ptr = this. deref_operand ( args[ 1 ] ) ?;
724745 // Just any address.
725- let stack_addr = Scalar :: from_int ( 0x80000 , args[ 1 ] . layout . size ) ;
746+ let stack_addr = Scalar :: from_uint ( STACK_ADDR , args[ 1 ] . layout . size ) ;
726747 this. write_scalar ( stack_addr, ptr. into ( ) ) ?;
727748 // Return success (`0`).
728749 this. write_null ( dest) ?;
729750 }
730751 "pthread_get_stackaddr_np" => {
731752 // Just any address.
732- let stack_addr = Scalar :: from_int ( 0x80000 , dest. layout . size ) ;
753+ let stack_addr = Scalar :: from_uint ( STACK_ADDR , dest. layout . size ) ;
733754 this. write_scalar ( stack_addr, dest) ?;
734755 }
735756
@@ -838,14 +859,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
838859 // Initialize with `0`.
839860 this. memory_mut ( ) . get_mut ( system_info_ptr. alloc_id ) ?
840861 . write_repeat ( tcx, system_info_ptr, 0 , system_info. layout . size ) ?;
841- // Set number of processors to `1` .
862+ // Set number of processors.
842863 let dword_size = Size :: from_bytes ( 4 ) ;
843864 let offset = 2 * dword_size + 3 * tcx. pointer_size ( ) ;
844865 this. memory_mut ( ) . get_mut ( system_info_ptr. alloc_id ) ?
845866 . write_scalar (
846867 tcx,
847868 system_info_ptr. offset ( offset, tcx) ?,
848- Scalar :: from_int ( 1 , dword_size) . into ( ) ,
869+ Scalar :: from_int ( NUM_CPUS , dword_size) . into ( ) ,
849870 dword_size,
850871 ) ?;
851872 }
0 commit comments