Auto merge of #99420 - RalfJung:vtable, r=oli-obk
make vtable pointers entirely opaque This implements the scheme discussed in https://github.com/rust-lang/unsafe-code-guidelines/issues/338: vtable pointers should be considered entirely opaque and not even readable by Rust code, similar to function pointers. - We have a new kind of `GlobalAlloc` that symbolically refers to a vtable. - Miri uses that kind of allocation when generating a vtable. - The codegen backends, upon encountering such an allocation, call `vtable_allocation` to obtain an actually dataful allocation for this vtable. - We need new intrinsics to obtain the size and align from a vtable (for some `ptr::metadata` APIs), since direct accesses are UB now. I had to touch quite a bit of code that I am not very familiar with, so some of this might not make much sense... r? `@oli-obk`
This commit is contained in:
commit
aa01891700
69 changed files with 673 additions and 527 deletions
|
@ -257,6 +257,15 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
|||
self.get_fn_addr(fn_instance.polymorphize(self.tcx)),
|
||||
self.data_layout().instruction_address_space,
|
||||
),
|
||||
GlobalAlloc::VTable(ty, trait_ref) => {
|
||||
let alloc = self
|
||||
.tcx
|
||||
.global_alloc(self.tcx.vtable_allocation((ty, trait_ref)))
|
||||
.unwrap_memory();
|
||||
let init = const_alloc_to_llvm(self, alloc);
|
||||
let value = self.static_addr_of(init, alloc.inner().align, None);
|
||||
(value, AddressSpace::DATA)
|
||||
}
|
||||
GlobalAlloc::Static(def_id) => {
|
||||
assert!(self.tcx.is_static(def_id));
|
||||
assert!(!self.tcx.is_thread_local_static(def_id));
|
||||
|
|
|
@ -101,7 +101,9 @@ pub fn const_alloc_to_llvm<'ll>(cx: &CodegenCx<'ll, '_>, alloc: ConstAllocation<
|
|||
|
||||
let address_space = match cx.tcx.global_alloc(alloc_id) {
|
||||
GlobalAlloc::Function(..) => cx.data_layout().instruction_address_space,
|
||||
GlobalAlloc::Static(..) | GlobalAlloc::Memory(..) => AddressSpace::DATA,
|
||||
GlobalAlloc::Static(..) | GlobalAlloc::Memory(..) | GlobalAlloc::VTable(..) => {
|
||||
AddressSpace::DATA
|
||||
}
|
||||
};
|
||||
|
||||
llvals.push(cx.scalar_to_backend(
|
||||
|
|
|
@ -1420,7 +1420,7 @@ fn build_vtable_type_di_node<'ll, 'tcx>(
|
|||
cx,
|
||||
type_map::stub(
|
||||
cx,
|
||||
Stub::VtableTy { vtable_holder },
|
||||
Stub::VTableTy { vtable_holder },
|
||||
unique_type_id,
|
||||
&vtable_type_name,
|
||||
(size, pointer_align),
|
||||
|
|
|
@ -146,7 +146,7 @@ impl<'ll> DINodeCreationResult<'ll> {
|
|||
pub enum Stub<'ll> {
|
||||
Struct,
|
||||
Union,
|
||||
VtableTy { vtable_holder: &'ll DIType },
|
||||
VTableTy { vtable_holder: &'ll DIType },
|
||||
}
|
||||
|
||||
pub struct StubInfo<'ll, 'tcx> {
|
||||
|
@ -180,9 +180,9 @@ pub(super) fn stub<'ll, 'tcx>(
|
|||
let unique_type_id_str = unique_type_id.generate_unique_id_string(cx.tcx);
|
||||
|
||||
let metadata = match kind {
|
||||
Stub::Struct | Stub::VtableTy { .. } => {
|
||||
Stub::Struct | Stub::VTableTy { .. } => {
|
||||
let vtable_holder = match kind {
|
||||
Stub::VtableTy { vtable_holder } => Some(vtable_holder),
|
||||
Stub::VTableTy { vtable_holder } => Some(vtable_holder),
|
||||
_ => None,
|
||||
};
|
||||
unsafe {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue