1
1
use std:: { collections:: hash_map:: Entry , io:: Write , iter, path:: Path } ;
2
2
3
3
use rustc_apfloat:: Float ;
4
- use rustc_ast:: expand:: allocator:: { alloc_error_handler_name, AllocatorKind } ;
4
+ use rustc_ast:: expand:: allocator:: alloc_error_handler_name;
5
5
use rustc_hir:: { def:: DefKind , def_id:: CrateNum } ;
6
6
use rustc_middle:: middle:: codegen_fn_attrs:: CodegenFnAttrFlags ;
7
7
use rustc_middle:: mir;
@@ -12,6 +12,7 @@ use rustc_target::{
12
12
spec:: abi:: Abi ,
13
13
} ;
14
14
15
+ use super :: alloc:: { check_alloc_request, EvalContextExt as _} ;
15
16
use super :: backtrace:: EvalContextExt as _;
16
17
use crate :: * ;
17
18
use helpers:: { ToHost , ToSoft } ;
@@ -232,138 +233,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
232
233
Some ( instance) => Ok ( Some ( ( this. load_mir ( instance. def , None ) ?, instance) ) ) ,
233
234
}
234
235
}
235
-
236
- fn malloc (
237
- & mut self ,
238
- size : u64 ,
239
- zero_init : bool ,
240
- kind : MiriMemoryKind ,
241
- ) -> InterpResult < ' tcx , Pointer < Option < Provenance > > > {
242
- let this = self . eval_context_mut ( ) ;
243
- if size == 0 {
244
- Ok ( Pointer :: null ( ) )
245
- } else {
246
- let align = this. min_align ( size, kind) ;
247
- let ptr = this. allocate_ptr ( Size :: from_bytes ( size) , align, kind. into ( ) ) ?;
248
- if zero_init {
249
- // We just allocated this, the access is definitely in-bounds and fits into our address space.
250
- this. write_bytes_ptr (
251
- ptr. into ( ) ,
252
- iter:: repeat ( 0u8 ) . take ( usize:: try_from ( size) . unwrap ( ) ) ,
253
- )
254
- . unwrap ( ) ;
255
- }
256
- Ok ( ptr. into ( ) )
257
- }
258
- }
259
-
260
- fn free (
261
- & mut self ,
262
- ptr : Pointer < Option < Provenance > > ,
263
- kind : MiriMemoryKind ,
264
- ) -> InterpResult < ' tcx > {
265
- let this = self . eval_context_mut ( ) ;
266
- if !this. ptr_is_null ( ptr) ? {
267
- this. deallocate_ptr ( ptr, None , kind. into ( ) ) ?;
268
- }
269
- Ok ( ( ) )
270
- }
271
-
272
- fn realloc (
273
- & mut self ,
274
- old_ptr : Pointer < Option < Provenance > > ,
275
- new_size : u64 ,
276
- kind : MiriMemoryKind ,
277
- ) -> InterpResult < ' tcx , Pointer < Option < Provenance > > > {
278
- let this = self . eval_context_mut ( ) ;
279
- let new_align = this. min_align ( new_size, kind) ;
280
- if this. ptr_is_null ( old_ptr) ? {
281
- if new_size == 0 {
282
- Ok ( Pointer :: null ( ) )
283
- } else {
284
- let new_ptr =
285
- this. allocate_ptr ( Size :: from_bytes ( new_size) , new_align, kind. into ( ) ) ?;
286
- Ok ( new_ptr. into ( ) )
287
- }
288
- } else {
289
- if new_size == 0 {
290
- this. deallocate_ptr ( old_ptr, None , kind. into ( ) ) ?;
291
- Ok ( Pointer :: null ( ) )
292
- } else {
293
- let new_ptr = this. reallocate_ptr (
294
- old_ptr,
295
- None ,
296
- Size :: from_bytes ( new_size) ,
297
- new_align,
298
- kind. into ( ) ,
299
- ) ?;
300
- Ok ( new_ptr. into ( ) )
301
- }
302
- }
303
- }
304
236
}
305
237
306
238
impl < ' mir , ' tcx : ' mir > EvalContextExtPriv < ' mir , ' tcx > for crate :: MiriInterpCx < ' mir , ' tcx > { }
307
239
trait EvalContextExtPriv < ' mir , ' tcx : ' mir > : crate :: MiriInterpCxExt < ' mir , ' tcx > {
308
- /// Returns the minimum alignment for the target architecture for allocations of the given size.
309
- fn min_align ( & self , size : u64 , kind : MiriMemoryKind ) -> Align {
310
- let this = self . eval_context_ref ( ) ;
311
- // List taken from `library/std/src/sys/pal/common/alloc.rs`.
312
- // This list should be kept in sync with the one from libstd.
313
- let min_align = match this. tcx . sess . target . arch . as_ref ( ) {
314
- "x86" | "arm" | "mips" | "mips32r6" | "powerpc" | "powerpc64" | "wasm32" => 8 ,
315
- "x86_64" | "aarch64" | "mips64" | "mips64r6" | "s390x" | "sparc64" | "loongarch64" =>
316
- 16 ,
317
- arch => bug ! ( "unsupported target architecture for malloc: `{}`" , arch) ,
318
- } ;
319
- // Windows always aligns, even small allocations.
320
- // Source: <https://support.microsoft.com/en-us/help/286470/how-to-use-pageheap-exe-in-windows-xp-windows-2000-and-windows-server>
321
- // But jemalloc does not, so for the C heap we only align if the allocation is sufficiently big.
322
- if kind == MiriMemoryKind :: WinHeap || size >= min_align {
323
- return Align :: from_bytes ( min_align) . unwrap ( ) ;
324
- }
325
- // We have `size < min_align`. Round `size` *down* to the next power of two and use that.
326
- fn prev_power_of_two ( x : u64 ) -> u64 {
327
- let next_pow2 = x. next_power_of_two ( ) ;
328
- if next_pow2 == x {
329
- // x *is* a power of two, just use that.
330
- x
331
- } else {
332
- // x is between two powers, so next = 2*prev.
333
- next_pow2 / 2
334
- }
335
- }
336
- Align :: from_bytes ( prev_power_of_two ( size) ) . unwrap ( )
337
- }
338
-
339
- /// Emulates calling the internal __rust_* allocator functions
340
- fn emulate_allocator (
341
- & mut self ,
342
- default : impl FnOnce ( & mut MiriInterpCx < ' mir , ' tcx > ) -> InterpResult < ' tcx > ,
343
- ) -> InterpResult < ' tcx , EmulateForeignItemResult > {
344
- let this = self . eval_context_mut ( ) ;
345
-
346
- let Some ( allocator_kind) = this. tcx . allocator_kind ( ( ) ) else {
347
- // in real code, this symbol does not exist without an allocator
348
- return Ok ( EmulateForeignItemResult :: NotSupported ) ;
349
- } ;
350
-
351
- match allocator_kind {
352
- AllocatorKind :: Global => {
353
- // When `#[global_allocator]` is used, `__rust_*` is defined by the macro expansion
354
- // of this attribute. As such we have to call an exported Rust function,
355
- // and not execute any Miri shim. Somewhat unintuitively doing so is done
356
- // by returning `NotSupported`, which triggers the `lookup_exported_symbol`
357
- // fallback case in `emulate_foreign_item`.
358
- return Ok ( EmulateForeignItemResult :: NotSupported ) ;
359
- }
360
- AllocatorKind :: Default => {
361
- default ( this) ?;
362
- Ok ( EmulateForeignItemResult :: NeedsJumping )
363
- }
364
- }
365
- }
366
-
367
240
fn emulate_foreign_item_inner (
368
241
& mut self ,
369
242
link_name : Symbol ,
@@ -610,7 +483,7 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
610
483
let size = this. read_target_usize ( size) ?;
611
484
let align = this. read_target_usize ( align) ?;
612
485
613
- Self :: check_alloc_request ( size, align) ?;
486
+ check_alloc_request ( size, align) ?;
614
487
615
488
let memory_kind = match link_name. as_str ( ) {
616
489
"__rust_alloc" => MiriMemoryKind :: Rust ,
@@ -644,7 +517,7 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
644
517
let size = this. read_target_usize ( size) ?;
645
518
let align = this. read_target_usize ( align) ?;
646
519
647
- Self :: check_alloc_request ( size, align) ?;
520
+ check_alloc_request ( size, align) ?;
648
521
649
522
let ptr = this. allocate_ptr (
650
523
Size :: from_bytes ( size) ,
@@ -708,7 +581,7 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
708
581
let new_size = this. read_target_usize ( new_size) ?;
709
582
// No need to check old_size; we anyway check that they match the allocation.
710
583
711
- Self :: check_alloc_request ( new_size, align) ?;
584
+ check_alloc_request ( new_size, align) ?;
712
585
713
586
let align = Align :: from_bytes ( align) . unwrap ( ) ;
714
587
let new_ptr = this. reallocate_ptr (
@@ -1100,16 +973,4 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
1100
973
// i.e., if we actually emulated the function with one of the shims.
1101
974
Ok ( EmulateForeignItemResult :: NeedsJumping )
1102
975
}
1103
-
1104
- /// Check some basic requirements for this allocation request:
1105
- /// non-zero size, power-of-two alignment.
1106
- fn check_alloc_request ( size : u64 , align : u64 ) -> InterpResult < ' tcx > {
1107
- if size == 0 {
1108
- throw_ub_format ! ( "creating allocation with size 0" ) ;
1109
- }
1110
- if !align. is_power_of_two ( ) {
1111
- throw_ub_format ! ( "creating allocation with non-power-of-two alignment {}" , align) ;
1112
- }
1113
- Ok ( ( ) )
1114
- }
1115
976
}
0 commit comments