Skip to content

Commit 130ff55

Browse files
committed
Use real addr instead of placeholder for signed type info vt ptrs
1 parent e0beb3f commit 130ff55

File tree

4 files changed

+38
-27
lines changed

4 files changed

+38
-27
lines changed

clang/lib/CodeGen/ItaniumCXXABI.cpp

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3975,18 +3975,9 @@ void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty) {
39753975

39763976
if (const auto &Schema =
39773977
CGM.getCodeGenOpts().PointerAuth.CXXTypeInfoVTablePointer) {
3978-
llvm::PointerType *PtrTy = llvm::PointerType::get(
3979-
CGM.getLLVMContext(),
3980-
CGM.getModule().getDataLayout().getProgramAddressSpace());
3981-
llvm::Constant *StorageAddress =
3982-
(Schema.isAddressDiscriminated()
3983-
? llvm::ConstantExpr::getIntToPtr(
3984-
llvm::ConstantInt::get(
3985-
CGM.IntPtrTy,
3986-
llvm::ConstantPtrAuth::
3987-
AddrDiscriminator_CXXTypeInfoVTablePointer),
3988-
PtrTy)
3989-
: nullptr);
3978+
// If address discrimination is enabled, we'll re-write that to actual
3979+
// storage address later in ItaniumRTTIBuilder::BuildTypeInfo.
3980+
llvm::Constant *StorageAddress = nullptr;
39903981
VTable = CGM.getConstantSignedPointer(VTable, Schema, StorageAddress,
39913982
GlobalDecl(), QualType(Ty, 0));
39923983
}
@@ -4107,6 +4098,7 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
41074098
llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass) {
41084099
// Add the vtable pointer.
41094100
BuildVTablePointer(cast<Type>(Ty));
4101+
size_t VTablePointerIdx = Fields.size() - 1;
41104102

41114103
// And the name.
41124104
llvm::GlobalVariable *TypeName = GetAddrOfTypeName(Ty, Linkage);
@@ -4222,7 +4214,6 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
42224214
}
42234215

42244216
llvm::Constant *Init = llvm::ConstantStruct::getAnon(Fields);
4225-
42264217
SmallString<256> Name;
42274218
llvm::raw_svector_ostream Out(Name);
42284219
CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty, Out);
@@ -4231,6 +4222,32 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
42314222
llvm::GlobalVariable *GV =
42324223
new llvm::GlobalVariable(M, Init->getType(),
42334224
/*isConstant=*/true, Linkage, Init, Name);
4225+
if (const auto &Schema =
4226+
CGM.getCodeGenOpts().PointerAuth.CXXTypeInfoVTablePointer) {
4227+
if (Schema.isAddressDiscriminated()) {
4228+
// If type info vtable pointer is signed with address discrimination
4229+
// enabled, we need to place actual storage address (which was unknown
4230+
// during construction in ItaniumRTTIBuilder::BuildVTablePointer) in the
4231+
// corresponding field.
4232+
ConstantInitBuilder Builder(CGM);
4233+
auto InitBuilder = Builder.beginStruct();
4234+
for (size_t I = 0; I < Fields.size(); ++I) {
4235+
if (I != VTablePointerIdx) {
4236+
InitBuilder.add(Fields[I]);
4237+
continue;
4238+
}
4239+
auto *SignedVTablePointer = cast<llvm::ConstantPtrAuth>(Fields[I]);
4240+
llvm::Constant *UnsignedVtablePointer =
4241+
SignedVTablePointer->getPointer();
4242+
llvm::Constant *StorageAddress =
4243+
InitBuilder.getAddrOfCurrentPosition(CGM.UnqualPtrTy);
4244+
InitBuilder.add(CGM.getConstantSignedPointer(
4245+
UnsignedVtablePointer, Schema, StorageAddress, GlobalDecl(),
4246+
QualType(cast<Type>(Ty), 0)));
4247+
}
4248+
InitBuilder.finishAndSetAsInitializer(GV);
4249+
}
4250+
}
42344251

42354252
// Export the typeinfo in the same circumstances as the vtable is exported.
42364253
auto GVDLLStorageClass = DLLStorageClass;

clang/test/CodeGenCXX/ptrauth-type-info-vtable.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ extern "C" int disc_std_type_info = __builtin_ptrauth_string_discriminator("_ZTV
6565

6666
// NODISC: @_ZTI10TestStruct = constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2), ptr @_ZTS10TestStruct }, align 8
6767

68-
// DISC: @_ZTI10TestStruct = constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2, i64 [[STDTYPEINFO_DISC]], ptr inttoptr (i64 1 to ptr)), ptr @_ZTS10TestStruct }, align 8
68+
// DISC: @_ZTI10TestStruct = constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2, i64 [[STDTYPEINFO_DISC]], ptr @_ZTI10TestStruct), ptr @_ZTS10TestStruct }, align 8
6969

7070
struct TestStruct {
7171
virtual ~TestStruct();

llvm/include/llvm/IR/Constants.h

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,18 +1067,12 @@ class ConstantPtrAuth final : public Constant {
10671067
return !getAddrDiscriminator()->isNullValue();
10681068
}
10691069

1070-
/// Constant values for the address discriminator which have special
1071-
/// significance to lowering in some contexts.
1072-
/// - For ctors/dtors, regular address discrimination can't
1073-
/// be applied for them since uses of llvm.global_{c|d}tors are disallowed
1074-
/// (see Verifier::visitGlobalVariable) and we can't emit getelementptr
1075-
/// expressions referencing these special arrays.
1076-
/// - For vtable pointers of std::type_info and classes derived from it,
1077-
/// we do not know the storage address when emitting ptrauth constant.
1078-
enum {
1079-
AddrDiscriminator_CtorsDtors = 1,
1080-
AddrDiscriminator_CXXTypeInfoVTablePointer = 1
1081-
};
1070+
/// A constant value for the address discriminator which has special
1071+
/// significance to ctors/dtors lowering. Regular address discrimination can't
1072+
/// be applied for them since uses of llvm.global_{c|d}tors are disallowed
1073+
/// (see Verifier::visitGlobalVariable) and we can't emit getelementptr
1074+
/// expressions referencing these special arrays.
1075+
enum { AddrDiscriminator_CtorsDtors = 1 };
10821076

10831077
/// Whether the address uses a special address discriminator.
10841078
/// These discriminators can't be used in real pointer-auth values; they

llvm/test/CodeGen/AArch64/ptrauth-type-info-vptr-discr.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
@_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr]
1515

1616
@_ZTS10Disc = constant [4 x i8] c"Disc", align 1
17-
@_ZTI10Disc = constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2, i64 45546, ptr inttoptr (i64 1 to ptr)), ptr @_ZTS10Disc }, align 8
17+
@_ZTI10Disc = constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2, i64 45546, ptr @_ZTI10Disc), ptr @_ZTS10Disc }, align 8
1818

1919
@_ZTS10NoDisc = constant [6 x i8] c"NoDisc", align 1
2020
@_ZTI10NoDisc = constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2, i64 45546), ptr @_ZTS10NoDisc }, align 8

0 commit comments

Comments
 (0)