|
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