@@ -3975,18 +3975,9 @@ void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty) {
3975
3975
3976
3976
if (const auto &Schema =
3977
3977
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 ;
3990
3981
VTable = CGM.getConstantSignedPointer (VTable, Schema, StorageAddress,
3991
3982
GlobalDecl (), QualType (Ty, 0 ));
3992
3983
}
@@ -4107,6 +4098,7 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
4107
4098
llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass) {
4108
4099
// Add the vtable pointer.
4109
4100
BuildVTablePointer (cast<Type>(Ty));
4101
+ size_t VTablePointerIdx = Fields.size () - 1 ;
4110
4102
4111
4103
// And the name.
4112
4104
llvm::GlobalVariable *TypeName = GetAddrOfTypeName (Ty, Linkage);
@@ -4222,7 +4214,6 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
4222
4214
}
4223
4215
4224
4216
llvm::Constant *Init = llvm::ConstantStruct::getAnon (Fields);
4225
-
4226
4217
SmallString<256 > Name;
4227
4218
llvm::raw_svector_ostream Out (Name);
4228
4219
CGM.getCXXABI ().getMangleContext ().mangleCXXRTTI (Ty, Out);
@@ -4231,6 +4222,32 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
4231
4222
llvm::GlobalVariable *GV =
4232
4223
new llvm::GlobalVariable (M, Init->getType (),
4233
4224
/* 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
+ }
4234
4251
4235
4252
// Export the typeinfo in the same circumstances as the vtable is exported.
4236
4253
auto GVDLLStorageClass = DLLStorageClass;
0 commit comments