1+ pub mod dlsym;
2+ pub mod env;
13pub mod foreign_items;
24pub mod intrinsics;
35pub mod tls;
46pub mod dlsym;
57pub mod env;
68pub mod io;
79
8- use rustc:: { ty , mir } ;
10+ use rustc:: { mir , ty } ;
911
1012use crate :: * ;
1113
@@ -19,7 +21,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1921 ret : Option < mir:: BasicBlock > ,
2022 ) -> InterpResult < ' tcx , Option < & ' mir mir:: Body < ' tcx > > > {
2123 let this = self . eval_context_mut ( ) ;
22- trace ! ( "eval_fn_call: {:#?}, {:?}" , instance, dest. map( |place| * place) ) ;
24+ trace ! (
25+ "eval_fn_call: {:#?}, {:?}" ,
26+ instance,
27+ dest. map( |place| * place)
28+ ) ;
2329
2430 // First, run the common hooks also supported by CTFE.
2531 if this. hook_fn ( instance, args, dest) ? {
@@ -28,27 +34,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
2834 }
2935 // There are some more lang items we want to hook that CTFE does not hook (yet).
3036 if this. tcx . lang_items ( ) . align_offset_fn ( ) == Some ( instance. def . def_id ( ) ) {
31-
32- let n = {
33- let ptr = this. force_ptr ( this. read_scalar ( args[ 0 ] ) ?. not_undef ( ) ?) ?;
34- let align = this. force_bits (
35- this. read_scalar ( args[ 1 ] ) ?. not_undef ( ) ?,
36- this. pointer_size ( )
37- ) ? as usize ;
38-
39- let stride = this. memory ( ) . get ( ptr. alloc_id ) ?. align . bytes ( ) as usize ;
40- // if the allocation alignment is at least the required alignment, we use the
41- // libcore implementation
42- if stride >= align {
43- ( ( stride + ptr. offset . bytes ( ) as usize ) as * const ( ) )
44- . align_offset ( align) as u128
45- } else {
46- u128:: max_value ( )
47- }
48- } ;
49-
5037 let dest = dest. unwrap ( ) ;
51- let n = this. truncate ( n, dest. layout ) ;
38+ let n = this
39+ . align_offset ( args[ 0 ] , args[ 1 ] ) ?
40+ . unwrap_or_else ( || this. truncate ( u128:: max_value ( ) , dest. layout ) ) ;
5241 this. write_scalar ( Scalar :: from_uint ( n, dest. layout . size ) , dest) ?;
5342 this. goto_block ( ret) ?;
5443 return Ok ( None ) ;
@@ -66,4 +55,39 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
6655 // Otherwise, load the MIR.
6756 Ok ( Some ( this. load_mir ( instance. def , None ) ?) )
6857 }
58+
59+ fn align_offset (
60+ & mut self ,
61+ ptr_op : OpTy < ' tcx , Tag > ,
62+ align_op : OpTy < ' tcx , Tag > ,
63+ ) -> InterpResult < ' tcx , Option < u128 > > {
64+ let this = self . eval_context_mut ( ) ;
65+
66+ let req_align = this. force_bits (
67+ this. read_scalar ( align_op) ?. not_undef ( ) ?,
68+ this. pointer_size ( ) ,
69+ ) ? as usize ;
70+
71+ // FIXME: This should actually panic in the interpreted program
72+ if !req_align. is_power_of_two ( ) {
73+ throw_unsup_format ! ( "Required alignment should always be a power of two" )
74+ }
75+
76+ let ptr_scalar = this. read_scalar ( ptr_op) ?. not_undef ( ) ?;
77+
78+ if let Ok ( ptr) = this. force_ptr ( ptr_scalar) {
79+ let cur_align = this. memory ( ) . get ( ptr. alloc_id ) ?. align . bytes ( ) as usize ;
80+ if cur_align >= req_align {
81+ // if the allocation alignment is at least the required alignment we use the
82+ // libcore implementation
83+ return Ok ( Some (
84+ ( this. force_bits ( ptr_scalar, this. pointer_size ( ) ) ? as * const i8 )
85+ . align_offset ( req_align) as u128 ,
86+ ) ) ;
87+ }
88+ }
89+ // If the allocation alignment is smaller than then required alignment or the pointer was
90+ // actually an integer, we return `None`
91+ Ok ( None )
92+ }
6993}
0 commit comments