@@ -119,24 +119,14 @@ impl<'mir, 'tcx> GlobalStateInner {
119
119
Ok ( ( ) )
120
120
}
121
121
122
- pub fn ptr_from_addr_transmute (
123
- _ecx : & MiriInterpCx < ' mir , ' tcx > ,
124
- addr : u64 ,
125
- ) -> Pointer < Option < Provenance > > {
126
- trace ! ( "Transmuting {:#x} to a pointer" , addr) ;
127
-
128
- // We consider transmuted pointers to be "invalid" (`None` provenance).
129
- Pointer :: new ( None , Size :: from_bytes ( addr) )
130
- }
131
-
132
122
pub fn ptr_from_addr_cast (
133
123
ecx : & MiriInterpCx < ' mir , ' tcx > ,
134
124
addr : u64 ,
135
125
) -> InterpResult < ' tcx , Pointer < Option < Provenance > > > {
136
126
trace ! ( "Casting {:#x} to a pointer" , addr) ;
137
127
128
+ // Potentially emit a warning.
138
129
let global_state = ecx. machine . intptrcast . borrow ( ) ;
139
-
140
130
match global_state. provenance_mode {
141
131
ProvenanceMode :: Default => {
142
132
// The first time this happens at a particular location, print a warning.
@@ -158,7 +148,12 @@ impl<'mir, 'tcx> GlobalStateInner {
158
148
ProvenanceMode :: Permissive => { }
159
149
}
160
150
161
- // This is how wildcard pointers are born.
151
+ // We do *not* look up the `AllocId` here! This is a `ptr as usize` cast, and it is
152
+ // completely legal to do a cast and then `wrapping_offset` to another allocation and only
153
+ // *then* do a memory access. So the allocation that the pointer happens to point to on a
154
+ // cast is fairly irrelevant. Instead we generate this as a "wildcard" pointer, such that
155
+ // *every time the pointer is used*, we do an `AllocId` lookup to find the (exposed)
156
+ // allocation it might be referencing.
162
157
Ok ( Pointer :: new ( Some ( Provenance :: Wildcard ) , Size :: from_bytes ( addr) ) )
163
158
}
164
159
@@ -219,22 +214,27 @@ impl<'mir, 'tcx> GlobalStateInner {
219
214
} )
220
215
}
221
216
222
- /// Convert a relative (tcx) pointer to an absolute address .
223
- pub fn rel_ptr_to_addr (
217
+ /// Convert a relative (tcx) pointer to a Miri pointer .
218
+ pub fn ptr_from_rel_ptr (
224
219
ecx : & MiriInterpCx < ' mir , ' tcx > ,
225
220
ptr : Pointer < AllocId > ,
226
- ) -> InterpResult < ' tcx , u64 > {
221
+ tag : BorTag ,
222
+ ) -> InterpResult < ' tcx , Pointer < Provenance > > {
227
223
let ( alloc_id, offset) = ptr. into_parts ( ) ; // offset is relative (AllocId provenance)
228
224
let base_addr = GlobalStateInner :: alloc_base_addr ( ecx, alloc_id) ?;
229
225
230
226
// Add offset with the right kind of pointer-overflowing arithmetic.
231
227
let dl = ecx. data_layout ( ) ;
232
- Ok ( dl. overflowing_offset ( base_addr, offset. bytes ( ) ) . 0 )
228
+ let absolute_addr = dl. overflowing_offset ( base_addr, offset. bytes ( ) ) . 0 ;
229
+ Ok ( Pointer :: new (
230
+ Provenance :: Concrete { alloc_id, tag } ,
231
+ Size :: from_bytes ( absolute_addr) ,
232
+ ) )
233
233
}
234
234
235
235
/// When a pointer is used for a memory access, this computes where in which allocation the
236
236
/// access is going.
237
- pub fn abs_ptr_to_rel (
237
+ pub fn ptr_get_alloc (
238
238
ecx : & MiriInterpCx < ' mir , ' tcx > ,
239
239
ptr : Pointer < Provenance > ,
240
240
) -> Option < ( AllocId , Size ) > {
@@ -252,12 +252,11 @@ impl<'mir, 'tcx> GlobalStateInner {
252
252
let base_addr = GlobalStateInner :: alloc_base_addr ( ecx, alloc_id) . unwrap ( ) ;
253
253
254
254
// Wrapping "addr - base_addr"
255
- let dl = ecx. data_layout ( ) ;
256
255
#[ allow( clippy:: cast_possible_wrap) ] // we want to wrap here
257
256
let neg_base_addr = ( base_addr as i64 ) . wrapping_neg ( ) ;
258
257
Some ( (
259
258
alloc_id,
260
- Size :: from_bytes ( dl . overflowing_signed_offset ( addr. bytes ( ) , neg_base_addr) . 0 ) ,
259
+ Size :: from_bytes ( ecx . overflowing_signed_offset ( addr. bytes ( ) , neg_base_addr) . 0 ) ,
261
260
) )
262
261
}
263
262
0 commit comments