1+ pub mod dlsym;
2+ pub mod env;
13pub mod foreign_items;
24pub mod intrinsics;
35pub mod tls;
4- pub mod dlsym;
5- pub mod env;
66pub mod io;
77
8- use rustc:: { ty , mir } ;
8+ use rustc:: { mir , ty } ;
99
1010use crate :: * ;
1111
@@ -19,7 +19,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1919 ret : Option < mir:: BasicBlock > ,
2020 ) -> InterpResult < ' tcx , Option < & ' mir mir:: Body < ' tcx > > > {
2121 let this = self . eval_context_mut ( ) ;
22- trace ! ( "eval_fn_call: {:#?}, {:?}" , instance, dest. map( |place| * place) ) ;
22+ trace ! (
23+ "eval_fn_call: {:#?}, {:?}" ,
24+ instance,
25+ dest. map( |place| * place)
26+ ) ;
2327
2428 // First, run the common hooks also supported by CTFE.
2529 if this. hook_fn ( instance, args, dest) ? {
@@ -28,27 +32,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
2832 }
2933 // There are some more lang items we want to hook that CTFE does not hook (yet).
3034 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-
5035 let dest = dest. unwrap ( ) ;
51- let n = this. truncate ( n, dest. layout ) ;
36+ let n = this
37+ . align_offset ( args[ 0 ] , args[ 1 ] ) ?
38+ . unwrap_or_else ( || this. truncate ( u128:: max_value ( ) , dest. layout ) ) ;
5239 this. write_scalar ( Scalar :: from_uint ( n, dest. layout . size ) , dest) ?;
5340 this. goto_block ( ret) ?;
5441 return Ok ( None ) ;
@@ -66,4 +53,39 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
6653 // Otherwise, load the MIR.
6754 Ok ( Some ( this. load_mir ( instance. def , None ) ?) )
6855 }
56+
57+ fn align_offset (
58+ & mut self ,
59+ ptr_op : OpTy < ' tcx , Tag > ,
60+ align_op : OpTy < ' tcx , Tag > ,
61+ ) -> InterpResult < ' tcx , Option < u128 > > {
62+ let this = self . eval_context_mut ( ) ;
63+
64+ let req_align = this. force_bits (
65+ this. read_scalar ( align_op) ?. not_undef ( ) ?,
66+ this. pointer_size ( ) ,
67+ ) ? as usize ;
68+
69+ // FIXME: This should actually panic in the interpreted program
70+ if !req_align. is_power_of_two ( ) {
71+ throw_unsup_format ! ( "Required alignment should always be a power of two" )
72+ }
73+
74+ let ptr_scalar = this. read_scalar ( ptr_op) ?. not_undef ( ) ?;
75+
76+ if let Ok ( ptr) = this. force_ptr ( ptr_scalar) {
77+ let cur_align = this. memory ( ) . get ( ptr. alloc_id ) ?. align . bytes ( ) as usize ;
78+ if cur_align >= req_align {
79+ // if the allocation alignment is at least the required alignment we use the
80+ // libcore implementation
81+ return Ok ( Some (
82+ ( this. force_bits ( ptr_scalar, this. pointer_size ( ) ) ? as * const i8 )
83+ . align_offset ( req_align) as u128 ,
84+ ) ) ;
85+ }
86+ }
87+ // If the allocation alignment is smaller than then required alignment or the pointer was
88+ // actually an integer, we return `None`
89+ Ok ( None )
90+ }
6991}
0 commit comments