Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core/ptr: Add simulate_realloc() #130886

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions compiler/rustc_codegen_llvm/src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,10 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
let allocated_pointer = AttributeKind::AllocatedPointer.create_attr(cx.llcx);
attributes::apply_to_llfn(llfn, AttributePlace::Argument(0), &[allocated_pointer]);
}
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::SIMULATE_ALLOCATOR) {
let no_alias = AttributeKind::NoAlias.create_attr(cx.llcx);
attributes::apply_to_llfn(llfn, AttributePlace::ReturnValue, &[no_alias]);
}
if let Some(align) = codegen_fn_attrs.alignment {
llvm::set_alignment(llfn, align);
}
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_codegen_ssa/src/codegen_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
sym::rustc_nounwind => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND,
sym::rustc_reallocator => codegen_fn_attrs.flags |= CodegenFnAttrFlags::REALLOCATOR,
sym::rustc_deallocator => codegen_fn_attrs.flags |= CodegenFnAttrFlags::DEALLOCATOR,
sym::rustc_simulate_allocator => {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::SIMULATE_ALLOCATOR
}
sym::rustc_allocator_zeroed => {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR_ZEROED
}
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -691,6 +691,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
rustc_allocator_zeroed, Normal, template!(Word), WarnFollowing,
EncodeCrossCrate::No, IMPL_DETAIL
),
rustc_attr!(
rustc_simulate_allocator, Normal, template!(Word), WarnFollowing,
EncodeCrossCrate::No, IMPL_DETAIL
),
gated!(
default_lib_allocator, Normal, template!(Word), WarnFollowing,
EncodeCrossCrate::No, allocator_internals, experimental!(default_lib_allocator),
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ bitflags::bitflags! {
const ALLOCATOR_ZEROED = 1 << 18;
/// `#[no_builtins]`: indicates that disable implicit builtin knowledge of functions for the function.
const NO_BUILTINS = 1 << 19;
/// `#[rustc_simulate_allocator]`: a hint to LLVM that the function simulates an allocation
const SIMULATE_ALLOCATOR = 1 << 20;
}
}
rustc_data_structures::external_bitflags_debug! { CodegenFnAttrFlags }
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1735,6 +1735,7 @@ symbols! {
rustc_runtime,
rustc_safe_intrinsic,
rustc_serialize,
rustc_simulate_allocator,
rustc_skip_during_method_dispatch,
rustc_specialization_trait,
rustc_std_internal_symbol,
Expand Down
31 changes: 31 additions & 0 deletions library/core/src/ptr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,7 @@
// There are many unsafe functions taking pointers that don't dereference them.
#![allow(clippy::not_unsafe_ptr_arg_deref)]

use crate::arch::asm;
use crate::cmp::Ordering;
use crate::marker::FnPtr;
use crate::mem::{self, MaybeUninit};
Expand Down Expand Up @@ -2441,3 +2442,33 @@ pub macro addr_of($place:expr) {
pub macro addr_of_mut($place:expr) {
&raw mut $place
}

/// Simulate a realloc to a new address
///
/// Intended for use with pointer tagging architecture features such as AArch64 TBI.
/// This function creates a new pointer with the address `new_address` and a brand new provenance,
/// simulating a realloc from the original address to the new address.
/// Note that this is only a simulated realloc - nothing actually gets moved or reallocated.
///
/// SAFETY: Users *must* ensure that `new_address` actually contains the same memory as the original.
/// The primary use-case is working with various architecture pointer tagging schemes, where two
/// different 64-bit addresses can point to the same chunk of memory due to some bits being ignored.
/// When used incorrectly, this function can be used to violate the memory model in arbitrary ways.
/// Furthermore, after using this function, users must ensure that the underlying memory is only ever
/// accessed through the newly created pointer. Any accesses through the original pointer
/// (or any pointers derived from it) would be Undefined Behaviour.
#[inline(never)]
#[unstable(feature = "ptr_simulate_realloc", issue = "none")]
#[cfg_attr(not(bootstrap), rustc_simulate_allocator)]
#[allow(fuzzy_provenance_casts)]
pub unsafe fn simulate_realloc<T>(original: *mut T, new_address: usize) -> *mut T {
// FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
let mut ptr = new_address as *mut T;
// SAFETY: This does not do anything
unsafe {
asm!("/* simulate realloc from {original} to {ptr} */",
original = in(reg) original, ptr = inout(reg) ptr);
}
// FIXME: call Miri hooks to update the address of the original allocation
ptr
}
Loading