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,140 +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
- // Here we must behave like `malloc`.
282
- if new_size == 0 {
283
- Ok ( Pointer :: null ( ) )
284
- } else {
285
- let new_ptr =
286
- this. allocate_ptr ( Size :: from_bytes ( new_size) , new_align, kind. into ( ) ) ?;
287
- Ok ( new_ptr. into ( ) )
288
- }
289
- } else {
290
- if new_size == 0 {
291
- // C, in their infinite wisdom, made this UB.
292
- // <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2464.pdf>
293
- throw_ub_format ! ( "`realloc` with a size of zero" ) ;
294
- } else {
295
- let new_ptr = this. reallocate_ptr (
296
- old_ptr,
297
- None ,
298
- Size :: from_bytes ( new_size) ,
299
- new_align,
300
- kind. into ( ) ,
301
- ) ?;
302
- Ok ( new_ptr. into ( ) )
303
- }
304
- }
305
- }
306
236
}
307
237
308
238
impl < ' mir , ' tcx : ' mir > EvalContextExtPriv < ' mir , ' tcx > for crate :: MiriInterpCx < ' mir , ' tcx > { }
309
239
trait EvalContextExtPriv < ' mir , ' tcx : ' mir > : crate :: MiriInterpCxExt < ' mir , ' tcx > {
310
- /// Returns the minimum alignment for the target architecture for allocations of the given size.
311
- fn min_align ( & self , size : u64 , kind : MiriMemoryKind ) -> Align {
312
- let this = self . eval_context_ref ( ) ;
313
- // List taken from `library/std/src/sys/pal/common/alloc.rs`.
314
- // This list should be kept in sync with the one from libstd.
315
- let min_align = match this. tcx . sess . target . arch . as_ref ( ) {
316
- "x86" | "arm" | "mips" | "mips32r6" | "powerpc" | "powerpc64" | "wasm32" => 8 ,
317
- "x86_64" | "aarch64" | "mips64" | "mips64r6" | "s390x" | "sparc64" | "loongarch64" =>
318
- 16 ,
319
- arch => bug ! ( "unsupported target architecture for malloc: `{}`" , arch) ,
320
- } ;
321
- // Windows always aligns, even small allocations.
322
- // Source: <https://support.microsoft.com/en-us/help/286470/how-to-use-pageheap-exe-in-windows-xp-windows-2000-and-windows-server>
323
- // But jemalloc does not, so for the C heap we only align if the allocation is sufficiently big.
324
- if kind == MiriMemoryKind :: WinHeap || size >= min_align {
325
- return Align :: from_bytes ( min_align) . unwrap ( ) ;
326
- }
327
- // We have `size < min_align`. Round `size` *down* to the next power of two and use that.
328
- fn prev_power_of_two ( x : u64 ) -> u64 {
329
- let next_pow2 = x. next_power_of_two ( ) ;
330
- if next_pow2 == x {
331
- // x *is* a power of two, just use that.
332
- x
333
- } else {
334
- // x is between two powers, so next = 2*prev.
335
- next_pow2 / 2
336
- }
337
- }
338
- Align :: from_bytes ( prev_power_of_two ( size) ) . unwrap ( )
339
- }
340
-
341
- /// Emulates calling the internal __rust_* allocator functions
342
- fn emulate_allocator (
343
- & mut self ,
344
- default : impl FnOnce ( & mut MiriInterpCx < ' mir , ' tcx > ) -> InterpResult < ' tcx > ,
345
- ) -> InterpResult < ' tcx , EmulateForeignItemResult > {
346
- let this = self . eval_context_mut ( ) ;
347
-
348
- let Some ( allocator_kind) = this. tcx . allocator_kind ( ( ) ) else {
349
- // in real code, this symbol does not exist without an allocator
350
- return Ok ( EmulateForeignItemResult :: NotSupported ) ;
351
- } ;
352
-
353
- match allocator_kind {
354
- AllocatorKind :: Global => {
355
- // When `#[global_allocator]` is used, `__rust_*` is defined by the macro expansion
356
- // of this attribute. As such we have to call an exported Rust function,
357
- // and not execute any Miri shim. Somewhat unintuitively doing so is done
358
- // by returning `NotSupported`, which triggers the `lookup_exported_symbol`
359
- // fallback case in `emulate_foreign_item`.
360
- return Ok ( EmulateForeignItemResult :: NotSupported ) ;
361
- }
362
- AllocatorKind :: Default => {
363
- default ( this) ?;
364
- Ok ( EmulateForeignItemResult :: NeedsJumping )
365
- }
366
- }
367
- }
368
-
369
240
fn emulate_foreign_item_inner (
370
241
& mut self ,
371
242
link_name : Symbol ,
@@ -612,7 +483,7 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
612
483
let size = this. read_target_usize ( size) ?;
613
484
let align = this. read_target_usize ( align) ?;
614
485
615
- Self :: check_alloc_request ( size, align) ?;
486
+ check_alloc_request ( size, align) ?;
616
487
617
488
let memory_kind = match link_name. as_str ( ) {
618
489
"__rust_alloc" => MiriMemoryKind :: Rust ,
@@ -646,7 +517,7 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
646
517
let size = this. read_target_usize ( size) ?;
647
518
let align = this. read_target_usize ( align) ?;
648
519
649
- Self :: check_alloc_request ( size, align) ?;
520
+ check_alloc_request ( size, align) ?;
650
521
651
522
let ptr = this. allocate_ptr (
652
523
Size :: from_bytes ( size) ,
@@ -710,7 +581,7 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
710
581
let new_size = this. read_target_usize ( new_size) ?;
711
582
// No need to check old_size; we anyway check that they match the allocation.
712
583
713
- Self :: check_alloc_request ( new_size, align) ?;
584
+ check_alloc_request ( new_size, align) ?;
714
585
715
586
let align = Align :: from_bytes ( align) . unwrap ( ) ;
716
587
let new_ptr = this. reallocate_ptr (
@@ -1102,16 +973,4 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
1102
973
// i.e., if we actually emulated the function with one of the shims.
1103
974
Ok ( EmulateForeignItemResult :: NeedsJumping )
1104
975
}
1105
-
1106
- /// Check some basic requirements for this allocation request:
1107
- /// non-zero size, power-of-two alignment.
1108
- fn check_alloc_request ( size : u64 , align : u64 ) -> InterpResult < ' tcx > {
1109
- if size == 0 {
1110
- throw_ub_format ! ( "creating allocation with size 0" ) ;
1111
- }
1112
- if !align. is_power_of_two ( ) {
1113
- throw_ub_format ! ( "creating allocation with non-power-of-two alignment {}" , align) ;
1114
- }
1115
- Ok ( ( ) )
1116
- }
1117
976
}
0 commit comments