|  | 
| 446 | 446 | // There are many unsafe functions taking pointers that don't dereference them. | 
| 447 | 447 | #![allow(clippy::not_unsafe_ptr_arg_deref)] | 
| 448 | 448 | 
 | 
|  | 449 | +use crate::arch::asm; | 
| 449 | 450 | use crate::cmp::Ordering; | 
| 450 | 451 | use crate::marker::FnPtr; | 
| 451 | 452 | use crate::mem::{self, MaybeUninit}; | 
| @@ -2441,3 +2442,33 @@ pub macro addr_of($place:expr) { | 
| 2441 | 2442 | pub macro addr_of_mut($place:expr) { | 
| 2442 | 2443 |     &raw mut $place | 
| 2443 | 2444 | } | 
|  | 2445 | + | 
|  | 2446 | +/// Simulate a realloc to a new address | 
|  | 2447 | +/// | 
|  | 2448 | +/// Intended for use with pointer tagging architecture features such as AArch64 TBI. | 
|  | 2449 | +/// This function creates a new pointer with the address `new_address` and a brand new provenance, | 
|  | 2450 | +/// simulating a realloc from the original address to the new address. | 
|  | 2451 | +/// Note that this is only a simulated realloc - nothing actually gets moved or reallocated. | 
|  | 2452 | +/// | 
|  | 2453 | +/// SAFETY: Users *must* ensure that `new_address` actually contains the same memory as the original. | 
|  | 2454 | +/// The primary use-case is working with various architecture pointer tagging schemes, where two | 
|  | 2455 | +/// different 64-bit addresses can point to the same chunk of memory due to some bits being ignored. | 
|  | 2456 | +/// When used incorrectly, this function can be used to violate the memory model in arbitrary ways. | 
|  | 2457 | +/// Furthermore, after using this function, users must ensure that the underlying memory is only ever | 
|  | 2458 | +/// accessed through the newly created pointer. Any accesses through the original pointer | 
|  | 2459 | +/// (or any pointers derived from it) would be Undefined Behaviour. | 
|  | 2460 | +#[inline(never)] | 
|  | 2461 | +#[unstable(feature = "ptr_simulate_realloc", issue = "none")] | 
|  | 2462 | +#[cfg_attr(not(bootstrap), rustc_simulate_allocator)] | 
|  | 2463 | +#[allow(fuzzy_provenance_casts)] | 
|  | 2464 | +pub unsafe fn simulate_realloc<T>(original: *mut T, new_address: usize) -> *mut T { | 
|  | 2465 | +    // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic. | 
|  | 2466 | +    let mut ptr = new_address as *mut T; | 
|  | 2467 | +    // SAFETY: This does not do anything | 
|  | 2468 | +    unsafe { | 
|  | 2469 | +        asm!("/* simulate realloc from {original} to {ptr} */", | 
|  | 2470 | +         original = in(reg) original, ptr = inout(reg) ptr); | 
|  | 2471 | +    } | 
|  | 2472 | +    // FIXME: call Miri hooks to update the address of the original allocation | 
|  | 2473 | +    ptr | 
|  | 2474 | +} | 
0 commit comments