1
+ pub mod dlsym;
2
+ pub mod env;
1
3
pub mod foreign_items;
2
4
pub mod intrinsics;
3
5
pub mod tls;
4
- pub mod dlsym;
5
- pub mod env;
6
6
pub mod io;
7
7
8
- use rustc:: { ty , mir } ;
8
+ use rustc:: { mir , ty } ;
9
9
10
10
use crate :: * ;
11
11
@@ -19,7 +19,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
19
19
ret : Option < mir:: BasicBlock > ,
20
20
) -> InterpResult < ' tcx , Option < & ' mir mir:: Body < ' tcx > > > {
21
21
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
+ ) ;
23
27
24
28
// First, run the common hooks also supported by CTFE.
25
29
if this. hook_fn ( instance, args, dest) ? {
@@ -28,27 +32,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
28
32
}
29
33
// There are some more lang items we want to hook that CTFE does not hook (yet).
30
34
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
-
50
35
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 ) ) ;
52
39
this. write_scalar ( Scalar :: from_uint ( n, dest. layout . size ) , dest) ?;
53
40
this. goto_block ( ret) ?;
54
41
return Ok ( None ) ;
@@ -66,4 +53,39 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
66
53
// Otherwise, load the MIR.
67
54
Ok ( Some ( this. load_mir ( instance. def , None ) ?) )
68
55
}
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
+ }
69
91
}
0 commit comments