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
7
- use rustc:: { ty , mir } ;
7
+ use rustc:: { mir , ty } ;
8
8
9
9
use crate :: * ;
10
10
@@ -18,7 +18,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
18
18
ret : Option < mir:: BasicBlock > ,
19
19
) -> InterpResult < ' tcx , Option < & ' mir mir:: Body < ' tcx > > > {
20
20
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
+ ) ;
22
26
23
27
// First, run the common hooks also supported by CTFE.
24
28
if this. hook_fn ( instance, args, dest) ? {
@@ -27,27 +31,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
27
31
}
28
32
// There are some more lang items we want to hook that CTFE does not hook (yet).
29
33
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
-
49
34
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 ) ) ;
51
38
this. write_scalar ( Scalar :: from_uint ( n, dest. layout . size ) , dest) ?;
52
39
this. goto_block ( ret) ?;
53
40
return Ok ( None ) ;
@@ -65,4 +52,39 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
65
52
// Otherwise, load the MIR.
66
53
Ok ( Some ( this. load_mir ( instance. def , None ) ?) )
67
54
}
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
+ }
68
90
}
0 commit comments