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