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