https://github.com/chbessonova created https://github.com/llvm/llvm-project/pull/205808
Add support for address and type discrimination for vtable pointers stored in VTTs under the `-fptrauth-vtt-vtable-pointer-discrimination` option. This option is not enabled by default on any target and works in combination with `-fptrauth-vtable-pointer-address-discrimination` and/or `-fptrauth-vtable-pointer-type-discrimination`. For address discrimination, the address of the corresponding VTT entry is used as the discriminator. The type discriminator is computed similarly to the one used for vtable pointers stored in objects, but is based on the vtable type rather than its base type. >From 584cd1a8cfd5a5efbb0ba668dee5b88787e27d61 Mon Sep 17 00:00:00 2001 From: Kristina Bessonova <[email protected]> Date: Fri, 19 Jun 2026 18:08:22 +0200 Subject: [PATCH] [PAC][clang] Implement address/type discrimination for VTT vtable pointers Add support for address and type discrimination for vtable pointers stored in VTTs under the `-fptrauth-vtt-vtable-pointer-discrimination` option. This option is not enabled by default on any target and works in combination with `-fptrauth-vtable-pointer-address-discrimination` and/or `-fptrauth-vtable-pointer-type-discrimination`. For address discrimination, the address of the corresponding VTT entry is used as the discriminator. The type discriminator is computed similarly to the one used for vtable pointers stored in objects, but is based on the vtable type rather than its base type. --- clang/include/clang/Basic/Features.def | 1 + clang/include/clang/Basic/LangOptions.def | 1 + clang/include/clang/Options/Options.td | 2 + clang/lib/CodeGen/CGPointerAuth.cpp | 36 +++++-- clang/lib/CodeGen/CGVTT.cpp | 37 +++++-- clang/lib/CodeGen/CodeGenFunction.h | 3 + clang/lib/CodeGen/ItaniumCXXABI.cpp | 19 +++- clang/lib/Driver/ToolChains/Clang.cpp | 3 + clang/lib/Frontend/CompilerInvocation.cpp | 15 ++- .../test/CodeGenCXX/ptrauth-vtable-in-vtt.cpp | 99 +++++++++++++++++++ clang/test/Driver/aarch64-ptrauth.c | 10 +- 11 files changed, 197 insertions(+), 29 deletions(-) create mode 100644 clang/test/CodeGenCXX/ptrauth-vtable-in-vtt.cpp diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def index 2f7741ff74f9b..d848b92afe93d 100644 --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -156,6 +156,7 @@ FEATURE(ptrauth_calls, LangOpts.PointerAuthCalls) FEATURE(ptrauth_returns, LangOpts.PointerAuthReturns) FEATURE(ptrauth_vtable_pointer_address_discrimination, LangOpts.PointerAuthVTPtrAddressDiscrimination) FEATURE(ptrauth_vtable_pointer_type_discrimination, LangOpts.PointerAuthVTPtrTypeDiscrimination) +FEATURE(ptrauth_vtt_vtable_pointer_discrimination, LangOpts.PointerAuthVTTVTPtrDiscrimination) FEATURE(ptrauth_type_info_vtable_pointer_discrimination, LangOpts.PointerAuthTypeInfoVTPtrDiscrimination) FEATURE(ptrauth_member_function_pointer_type_discrimination, LangOpts.PointerAuthCalls) FEATURE(ptrauth_signed_block_descriptors, LangOpts.PointerAuthBlockDescriptorPointers) diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index d68784b7efbcd..2c153e0c125f9 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -125,6 +125,7 @@ LANGOPT(PointerAuthIndirectGotos, 1, 0, NotCompatible, "indirect gotos pointer a LANGOPT(PointerAuthAuthTraps, 1, 0, NotCompatible, "pointer authentication failure traps") LANGOPT(PointerAuthVTPtrAddressDiscrimination, 1, 0, NotCompatible, "incorporate address discrimination in authenticated vtable pointers") LANGOPT(PointerAuthVTPtrTypeDiscrimination, 1, 0, NotCompatible, "incorporate type discrimination in authenticated vtable pointers") +LANGOPT(PointerAuthVTTVTPtrDiscrimination, 1, 0, NotCompatible, "incorporate discrimination in authenticated vtable pointers in VTTs") LANGOPT(PointerAuthTypeInfoVTPtrDiscrimination, 1, 0, NotCompatible, "incorporate type and address discrimination in authenticated vtable pointers for std::type_info") LANGOPT(PointerAuthFunctionTypeDiscrimination, 1, 0, Benign, "Use type discrimination when signing function pointers") diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index 3c2091013d152..403faf460e8a0 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -4972,6 +4972,8 @@ defm ptrauth_vtable_pointer_address_discrimination : OptInCC1FFlag<"ptrauth-vtable-pointer-address-discrimination", "Enable address discrimination of vtable pointers">; defm ptrauth_vtable_pointer_type_discrimination : OptInCC1FFlag<"ptrauth-vtable-pointer-type-discrimination", "Enable type discrimination of vtable pointers">; +defm ptrauth_vtt_vtable_pointer_discrimination : + OptInCC1FFlag<"ptrauth-vtt-vtable-pointer-discrimination", "Apply the same vtable pointer discrimination scheme to VTT entries as to object vtable pointers">; defm ptrauth_type_info_vtable_pointer_discrimination : OptInCC1FFlag<"ptrauth-type-info-vtable-pointer-discrimination", "Enable type and address discrimination of vtable pointer of std::type_info">; defm ptrauth_function_pointer_type_discrimination : OptInCC1FFlag<"ptrauth-function-pointer-type-discrimination", diff --git a/clang/lib/CodeGen/CGPointerAuth.cpp b/clang/lib/CodeGen/CGPointerAuth.cpp index 28d3289dfe04f..5a8ed28485a77 100644 --- a/clang/lib/CodeGen/CGPointerAuth.cpp +++ b/clang/lib/CodeGen/CGPointerAuth.cpp @@ -14,6 +14,7 @@ #include "CGCXXABI.h" #include "CodeGenFunction.h" #include "CodeGenModule.h" +#include "clang/Basic/PointerAuthOptions.h" #include "clang/CodeGen/CodeGenABITypes.h" #include "clang/CodeGen/ConstantInitBuilder.h" #include "llvm/Analysis/ValueTracking.h" @@ -121,20 +122,37 @@ CGPointerAuthInfo CodeGenFunction::EmitPointerAuthInfo( if (!Schema) return CGPointerAuthInfo(); - llvm::Value *Discriminator = - CGM.getPointerAuthOtherDiscriminator(Schema, SchemaDecl, SchemaType); + llvm::ConstantInt *Discriminator = + Schema.getOtherDiscrimination() == PointerAuthSchema::Discrimination::None + ? nullptr + : CGM.getPointerAuthOtherDiscriminator(Schema, SchemaDecl, + SchemaType); + + return EmitPointerAuthInfo(Schema, StorageAddress, Discriminator); +} + +CGPointerAuthInfo +CodeGenFunction::EmitPointerAuthInfo(const PointerAuthSchema &Schema, + llvm::Value *StorageAddress, + llvm::ConstantInt *ExtraDiscriminator) { + if (!Schema) + return CGPointerAuthInfo(); + PointerAuthSchema::Discrimination ExtraDiscKind = Schema.getOtherDiscrimination(); + assert( + (ExtraDiscKind == PointerAuthSchema::Discrimination::None || + ExtraDiscriminator) && + "extra discrimination is requested but no discriminator gets provided"); + + llvm::Value *Discriminator = ExtraDiscriminator; if (Schema.isAddressDiscriminated()) { assert(StorageAddress && "address not provided for address-discriminated schema"); - - if (Discriminator) - Discriminator = - EmitPointerAuthBlendDiscriminator(StorageAddress, Discriminator); - else - Discriminator = Builder.CreatePtrToInt(StorageAddress, IntPtrTy); + Discriminator = + ExtraDiscKind != PointerAuthSchema::Discrimination::None + ? EmitPointerAuthBlendDiscriminator(StorageAddress, Discriminator) + : Builder.CreatePtrToInt(StorageAddress, IntPtrTy); } - return CGPointerAuthInfo(Schema.getKey(), Schema.getAuthenticationMode(), Schema.isIsaPointer(), Schema.authenticatesNullValues(), Discriminator); diff --git a/clang/lib/CodeGen/CGVTT.cpp b/clang/lib/CodeGen/CGVTT.cpp index 989a07d09d50e..81033079d0eda 100644 --- a/clang/lib/CodeGen/CGVTT.cpp +++ b/clang/lib/CodeGen/CGVTT.cpp @@ -13,7 +13,9 @@ #include "CodeGenModule.h" #include "CGCXXABI.h" #include "clang/AST/RecordLayout.h" +#include "clang/AST/TypeBase.h" #include "clang/AST/VTTBuilder.h" +#include "clang/Basic/PointerAuthOptions.h" using namespace clang; using namespace CodeGen; @@ -55,18 +57,17 @@ CodeGenVTables::EmitVTTDefinition(llvm::GlobalVariable *VTT, } SmallVector<llvm::Constant *, 8> VTTComponents; - for (const VTTComponent *i = Builder.getVTTComponents().begin(), - *e = Builder.getVTTComponents().end(); i != e; ++i) { - const VTTVTable &VTTVT = Builder.getVTTVTables()[i->VTableIndex]; - llvm::GlobalVariable *VTable = VTables[i->VTableIndex]; + for (const auto &[Idx, C] : llvm::enumerate(Builder.getVTTComponents())) { + const VTTVTable &VTTVT = Builder.getVTTVTables()[C.VTableIndex]; + llvm::GlobalVariable *VTable = VTables[C.VTableIndex]; VTableLayout::AddressPointLocation AddressPoint; if (VTTVT.getBase() == RD) { // Just get the address point for the regular vtable. AddressPoint = getItaniumVTableContext().getVTableLayout(RD).getAddressPoint( - i->VTableBase); + C.VTableBase); } else { - AddressPoint = VTableAddressPoints[i->VTableIndex].lookup(i->VTableBase); + AddressPoint = VTableAddressPoints[C.VTableIndex].lookup(C.VTableBase); assert(AddressPoint.AddressPointIndex != 0 && "Did not find ctor vtable address point!"); } @@ -92,10 +93,26 @@ CodeGenVTables::EmitVTTDefinition(llvm::GlobalVariable *VTT, VTable->getValueType(), VTable, Idxs, /*InBounds=*/true, InRange); if (const auto &Schema = - CGM.getCodeGenOpts().PointerAuth.CXXVTTVTablePointers) - Init = CGM.getConstantSignedPointer(Init, Schema, nullptr, GlobalDecl(), - QualType()); - + CGM.getCodeGenOpts().PointerAuth.CXXVTTVTablePointers) { + llvm::Constant *AddressDesc = + Schema.isAddressDiscriminated() + ? llvm::ConstantExpr::getGetElementPtr( + VTT->getType(), VTT, + llvm::ConstantInt::get(CGM.Int32Ty, Idx)) + : nullptr; + if (Schema.getOtherDiscrimination() == + PointerAuthSchema::Discrimination::Type) { + auto *TypeDesc = llvm::ConstantInt::get( + CGM.IntPtrTy, + CGM.getContext().getPointerAuthVTablePointerDiscriminator( + VTTVT.getBase())); + Init = CGM.getConstantSignedPointer(Init, Schema.getKey(), AddressDesc, + TypeDesc); + } else { + Init = CGM.getConstantSignedPointer(Init, Schema, AddressDesc, + GlobalDecl(), QualType()); + } + } VTTComponents.push_back(Init); } diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 6d0718c243812..c590551c2b9ac 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -4659,6 +4659,9 @@ class CodeGenFunction : public CodeGenTypeCache { /// Create the discriminator from the storage address and the entity hash. llvm::Value *EmitPointerAuthBlendDiscriminator(llvm::Value *StorageAddress, llvm::Value *Discriminator); + CGPointerAuthInfo EmitPointerAuthInfo(const PointerAuthSchema &Schema, + llvm::Value *StorageAddress, + llvm::ConstantInt *Discriminator); CGPointerAuthInfo EmitPointerAuthInfo(const PointerAuthSchema &Schema, llvm::Value *StorageAddress, GlobalDecl SchemaDecl, diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index b4b3284f752ae..da3f29d8820cb 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -29,6 +29,7 @@ #include "clang/AST/Mangle.h" #include "clang/AST/StmtCXX.h" #include "clang/AST/Type.h" +#include "clang/Basic/PointerAuthOptions.h" #include "clang/CodeGen/ConstantInitBuilder.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/GlobalValue.h" @@ -2221,13 +2222,21 @@ llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT( CGF.Builder.CreateAlignedLoad(CGF.GlobalsVoidPtrTy, VTT, CGF.getPointerAlign()); - if (auto &Schema = CGF.CGM.getCodeGenOpts().PointerAuth.CXXVTTVTablePointers) { - CGPointerAuthInfo PointerAuth = CGF.EmitPointerAuthInfo(Schema, VTT, - GlobalDecl(), - QualType()); + if (auto &Schema = CGM.getCodeGenOpts().PointerAuth.CXXVTTVTablePointers) { + CGPointerAuthInfo PointerAuth; + if (Schema.getOtherDiscrimination() == + PointerAuthSchema::Discrimination::Type) { + auto *TypeDesc = llvm::ConstantInt::get( + CGM.IntPtrTy, + CGM.getContext().getPointerAuthVTablePointerDiscriminator( + VTableClass)); + PointerAuth = CGF.EmitPointerAuthInfo(Schema, VTT, TypeDesc); + } else { + PointerAuth = + CGF.EmitPointerAuthInfo(Schema, VTT, GlobalDecl(), QualType()); + } AP = CGF.EmitPointerAuthAuth(PointerAuth, AP); } - return AP; } diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 418d540895681..518f10c92a373 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1728,6 +1728,9 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args, Args.addOptInFlag( CmdArgs, options::OPT_fptrauth_vtable_pointer_type_discrimination, options::OPT_fno_ptrauth_vtable_pointer_type_discrimination); + Args.addOptInFlag( + CmdArgs, options::OPT_fptrauth_vtt_vtable_pointer_discrimination, + options::OPT_fno_ptrauth_vtt_vtable_pointer_discrimination); Args.addOptInFlag( CmdArgs, options::OPT_fptrauth_type_info_vtable_pointer_discrimination, options::OPT_fno_ptrauth_type_info_vtable_pointer_discrimination); diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index dfde7b756dbff..8b6548f35b491 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1480,8 +1480,15 @@ void CompilerInvocation::setDefaultPointerAuthOptions( Opts.CXXTypeInfoVTablePointer = PointerAuthSchema(Key::ASDA, false, Discrimination::None); - Opts.CXXVTTVTablePointers = - PointerAuthSchema(Key::ASDA, false, Discrimination::None); + if (LangOpts.PointerAuthVTTVTPtrDiscrimination) + Opts.CXXVTTVTablePointers = PointerAuthSchema( + Key::ASDA, LangOpts.PointerAuthVTPtrAddressDiscrimination, + LangOpts.PointerAuthVTPtrTypeDiscrimination ? Discrimination::Type + : Discrimination::None); + else + Opts.CXXVTTVTablePointers = + PointerAuthSchema(Key::ASDA, false, Discrimination::None); + Opts.CXXVirtualFunctionPointers = Opts.CXXVirtualVariadicFunctionPointers = PointerAuthSchema(Key::ASIA, true, Discrimination::Decl); Opts.CXXMemberFunctionPointers = @@ -3592,6 +3599,8 @@ static void GeneratePointerAuthArgs(const LangOptions &Opts, GenerateArg(Consumer, OPT_fptrauth_vtable_pointer_address_discrimination); if (Opts.PointerAuthVTPtrTypeDiscrimination) GenerateArg(Consumer, OPT_fptrauth_vtable_pointer_type_discrimination); + if (Opts.PointerAuthVTTVTPtrDiscrimination) + GenerateArg(Consumer, OPT_fptrauth_vtt_vtable_pointer_discrimination); if (Opts.PointerAuthTypeInfoVTPtrDiscrimination) GenerateArg(Consumer, OPT_fptrauth_type_info_vtable_pointer_discrimination); if (Opts.PointerAuthFunctionTypeDiscrimination) @@ -3625,6 +3634,8 @@ static void ParsePointerAuthArgs(LangOptions &Opts, ArgList &Args, Args.hasArg(OPT_fptrauth_vtable_pointer_address_discrimination); Opts.PointerAuthVTPtrTypeDiscrimination = Args.hasArg(OPT_fptrauth_vtable_pointer_type_discrimination); + Opts.PointerAuthVTTVTPtrDiscrimination = + Args.hasArg(OPT_fptrauth_vtt_vtable_pointer_discrimination); Opts.PointerAuthTypeInfoVTPtrDiscrimination = Args.hasArg(OPT_fptrauth_type_info_vtable_pointer_discrimination); Opts.PointerAuthFunctionTypeDiscrimination = diff --git a/clang/test/CodeGenCXX/ptrauth-vtable-in-vtt.cpp b/clang/test/CodeGenCXX/ptrauth-vtable-in-vtt.cpp new file mode 100644 index 0000000000000..1a81946dd3241 --- /dev/null +++ b/clang/test/CodeGenCXX/ptrauth-vtable-in-vtt.cpp @@ -0,0 +1,99 @@ +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 %s -x c++ -std=c++11 -triple aarch64-linux-pauthtest -fptrauth-calls -disable-llvm-passes \ +// RUN: -emit-llvm -O0 -o - | FileCheck --check-prefixes=CHECK,DEFAULT %s +// RUN: %clang_cc1 %s -x c++ -std=c++11 -triple aarch64-linux-pauthtest -fptrauth-calls -fptrauth-vtt-vtable-pointer-discrimination \ +// RUN: -disable-llvm-passes -emit-llvm -O0 -o - | FileCheck --check-prefixes=CHECK,DEFAULT %s +// RUN: %clang_cc1 %s -x c++ -std=c++11 -triple aarch64-linux-pauthtest -fptrauth-calls -fptrauth-vtt-vtable-pointer-discrimination \ +// RUN: -fptrauth-vtable-pointer-address-discrimination -disable-llvm-passes -emit-llvm -O0 -o - | FileCheck --check-prefixes=CHECK,ADDRESS %s +// RUN: %clang_cc1 %s -x c++ -std=c++11 -triple aarch64-linux-pauthtest -fptrauth-calls -fptrauth-vtt-vtable-pointer-discrimination \ +// RUN: -fptrauth-vtable-pointer-type-discrimination -disable-llvm-passes -emit-llvm -O0 -o - | FileCheck --check-prefixes=CHECK,TYPE %s +// RUN: %clang_cc1 %s -x c++ -std=c++11 -triple aarch64-linux-pauthtest -fptrauth-calls -fptrauth-vtt-vtable-pointer-discrimination \ +// RUN: -fptrauth-vtable-pointer-address-discrimination -fptrauth-vtable-pointer-type-discrimination \ +// RUN: -disable-llvm-passes -emit-llvm -O0 -o - | FileCheck --check-prefixes=CHECK,ADDRESSTYPE %s + +// CHECK: @_ZTT1D = linkonce_odr unnamed_addr constant [4 x ptr] [ +// DEFAULT-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV1D, i32 0, i32 0, i32 4), i32 2), +// DEFAULT-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTC1D0_1A, i32 0, i32 0, i32 4), i32 2), +// DEFAULT-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTC1D0_1A, i32 0, i32 0, i32 4), i32 2), +// DEFAULT-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV1D, i32 0, i32 0, i32 4), i32 2)] + +// ADDRESS-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV1D, i32 0, i32 0, i32 4), i32 2, i64 0, ptr @_ZTT1D), +// ADDRESS-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTC1D0_1A, i32 0, i32 0, i32 4), i32 2, i64 0, ptr getelementptr (ptr, ptr @_ZTT1D, i32 1)), +// ADDRESS-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTC1D0_1A, i32 0, i32 0, i32 4), i32 2, i64 0, ptr getelementptr (ptr, ptr @_ZTT1D, i32 2)), +// ADDRESS-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV1D, i32 0, i32 0, i32 4), i32 2, i64 0, ptr getelementptr (ptr, ptr @_ZTT1D, i32 3))] + +// TYPE-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV1D, i32 0, i32 0, i32 4), i32 2, i64 46475), +// TYPE-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTC1D0_1A, i32 0, i32 0, i32 4), i32 2, i64 62866), +// TYPE-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTC1D0_1A, i32 0, i32 0, i32 4), i32 2, i64 62866), +// TYPE-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV1D, i32 0, i32 0, i32 4), i32 2, i64 46475)] + +// ADDRESSTYPE-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV1D, i32 0, i32 0, i32 4), i32 2, i64 46475, ptr @_ZTT1D), +// ADDRESSTYPE-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTC1D0_1A, i32 0, i32 0, i32 4), i32 2, i64 62866, ptr getelementptr (ptr, ptr @_ZTT1D, i32 1)), +// ADDRESSTYPE-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTC1D0_1A, i32 0, i32 0, i32 4), i32 2, i64 62866, ptr getelementptr (ptr, ptr @_ZTT1D, i32 2)), +// ADDRESSTYPE-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV1D, i32 0, i32 0, i32 4), i32 2, i64 46475, ptr getelementptr (ptr, ptr @_ZTT1D, i32 3))] + +// CHECK: @_ZTT1A = linkonce_odr unnamed_addr constant [2 x ptr] [ +// DEFAULT-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 4), i32 2), +// DEFAULT-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 4), i32 2)] + +// ADDRESS-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 4), i32 2, i64 0, ptr @_ZTT1A), +// ADDRESS-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 4), i32 2, i64 0, ptr getelementptr (ptr, ptr @_ZTT1A, i32 1))] + +// TYPE-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 4), i32 2, i64 62866), +// TYPE-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 4), i32 2, i64 62866)] + +// ADDRESSTYPE-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 4), i32 2, i64 62866, ptr @_ZTT1A), +// ADDRESSTYPE-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 4), i32 2, i64 62866, ptr getelementptr (ptr, ptr @_ZTT1A, i32 1))] + +// CHECK-LABEL: @_ZN1AC2Ev +// CHECK: %vtt.addr = alloca ptr, align 8 +// CHECK: store ptr %vtt, ptr %vtt.addr, align 8 +// CHECK: [[VTT:%.*]] = load ptr, ptr %vtt.addr, align 8 +// CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTT]], align 8 +// ADDRESS: [[VTABLE_ADDR:%.*]] = ptrtoint ptr [[VTT]] to i64 +// ADDRESSTYPE: [[VTABLE_ADDR:%.*]] = ptrtoint ptr [[VTT]] to i64 +// ADDRESSTYPE: [[DISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTABLE_ADDR]], i64 62866) +// CHECK: [[VTABLEi64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 +// DEFAULT: call i64 @llvm.ptrauth.auth(i64 [[VTABLEi64]], i32 2, i64 0) +// ADDRESS: call i64 @llvm.ptrauth.auth(i64 [[VTABLEi64]], i32 2, i64 [[VTABLE_ADDR]]) +// TYPE: call i64 @llvm.ptrauth.auth(i64 [[VTABLEi64]], i32 2, i64 62866) +// ADDRESSTYPE: call i64 @llvm.ptrauth.auth(i64 [[VTABLEi64]], i32 2, i64 [[DISC]]) + +// CHECK: [[VTTOFFSET:%.*]] = getelementptr inbounds ptr, ptr [[VTT]], i64 1 +// CHECK: [[VTABLE2:%.*]] = load ptr, ptr [[VTTOFFSET]], align 8 +// ADDRESS: [[VTABLE2_ADDR:%.*]] = ptrtoint ptr [[VTTOFFSET]] to i64 +// ADDRESSTYPE: [[VTABLE2_ADDR:%.*]] = ptrtoint ptr [[VTTOFFSET]] to i64 +// ADDRESSTYPE: [[DISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTABLE2_ADDR]], i64 62866) +// CHECK: [[VTABLE2i64:%.*]] = ptrtoint ptr [[VTABLE2]] to i64 +// DEFAULT: call i64 @llvm.ptrauth.auth(i64 [[VTABLE2i64]], i32 2, i64 0) +// ADDRESS: call i64 @llvm.ptrauth.auth(i64 [[VTABLE2i64]], i32 2, i64 [[VTABLE2_ADDR]]) +// TYPE: call i64 @llvm.ptrauth.auth(i64 [[VTABLE2i64]], i32 2, i64 62866) +// ADDRESSTYPE: call i64 @llvm.ptrauth.auth(i64 [[VTABLE2i64]], i32 2, i64 [[DISC]]) + +// CHECK-LABEL: @_ZN1DC2Ev +// CHECK: %vtt.addr = alloca ptr, align 8 +// CHECK: store ptr %vtt, ptr %vtt.addr, align 8 +// CHECK: [[VTT:%.*]] = load ptr, ptr %vtt.addr, align 8 +// CHECK: [[VTTOFFSET:%.*]] = getelementptr inbounds ptr, ptr [[VTT]], i64 1 +// CHECK: call void @_ZN1AC2Ev(ptr noundef nonnull align 8 dereferenceable(8) %this1, ptr noundef [[VTTOFFSET]]) +// CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTT]], align 8 +// ADDRESS: [[VTABLE_ADDR:%.*]] = ptrtoint ptr [[VTT]] to i64 +// CHECK: [[VTABLEi64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 +// DEFAULT: call i64 @llvm.ptrauth.auth(i64 [[VTABLEi64]], i32 2, i64 0) +// ADDRESS: call i64 @llvm.ptrauth.auth(i64 [[VTABLEi64]], i32 2, i64 [[VTABLE_ADDR]]) +// TYPE: call i64 @llvm.ptrauth.auth(i64 [[VTABLEi64]], i32 2, i64 46475) + +struct V { + virtual void f(); +}; + +struct A : virtual V { + A(); +}; + +struct D : A { + D(); +}; + +A::A() {} +D::D() {} diff --git a/clang/test/Driver/aarch64-ptrauth.c b/clang/test/Driver/aarch64-ptrauth.c index a67e98fdda714..1a2050b941f4f 100644 --- a/clang/test/Driver/aarch64-ptrauth.c +++ b/clang/test/Driver/aarch64-ptrauth.c @@ -12,6 +12,7 @@ // RUN: -fno-ptrauth-auth-traps -fptrauth-auth-traps \ // RUN: -fno-ptrauth-vtable-pointer-address-discrimination -fptrauth-vtable-pointer-address-discrimination \ // RUN: -fno-ptrauth-vtable-pointer-type-discrimination -fptrauth-vtable-pointer-type-discrimination \ +// RUN: -fno-ptrauth-vtt-vtable-pointer-discrimination -fptrauth-vtt-vtable-pointer-discrimination \ // RUN: -fno-ptrauth-type-info-vtable-pointer-discrimination -fptrauth-type-info-vtable-pointer-discrimination \ // RUN: -fno-ptrauth-indirect-gotos -fptrauth-indirect-gotos \ // RUN: -fno-ptrauth-init-fini -fptrauth-init-fini \ @@ -26,6 +27,7 @@ // RUN: -fno-ptrauth-auth-traps -fptrauth-auth-traps \ // RUN: -fno-ptrauth-vtable-pointer-address-discrimination -fptrauth-vtable-pointer-address-discrimination \ // RUN: -fno-ptrauth-vtable-pointer-type-discrimination -fptrauth-vtable-pointer-type-discrimination \ +// RUN: -fno-ptrauth-vtt-vtable-pointer-discrimination -fptrauth-vtt-vtable-pointer-discrimination \ // RUN: -fno-ptrauth-type-info-vtable-pointer-discrimination -fptrauth-type-info-vtable-pointer-discrimination \ // RUN: -fno-ptrauth-indirect-gotos -fptrauth-indirect-gotos \ // RUN: -fno-ptrauth-init-fini -fptrauth-init-fini \ @@ -33,7 +35,7 @@ // RUN: -fno-ptrauth-elf-got -fptrauth-elf-got \ // RUN: -fno-aarch64-jump-table-hardening -faarch64-jump-table-hardening \ // RUN: %s 2>&1 | FileCheck %s --check-prefix=ALL-LINUX-PAUTHABI -// ALL-LINUX-PAUTHABI: "-cc1"{{.*}} "-fptrauth-intrinsics" "-fptrauth-calls" "-fptrauth-returns" "-fptrauth-auth-traps" "-fptrauth-vtable-pointer-address-discrimination" "-fptrauth-vtable-pointer-type-discrimination" "-fptrauth-type-info-vtable-pointer-discrimination" "-fptrauth-indirect-gotos" "-fptrauth-init-fini" "-fptrauth-init-fini-address-discrimination" "-fptrauth-elf-got"{{.*}} "-faarch64-jump-table-hardening" +// ALL-LINUX-PAUTHABI: "-cc1"{{.*}} "-fptrauth-intrinsics" "-fptrauth-calls" "-fptrauth-returns" "-fptrauth-auth-traps" "-fptrauth-vtable-pointer-address-discrimination" "-fptrauth-vtable-pointer-type-discrimination" "-fptrauth-vtt-vtable-pointer-discrimination" "-fptrauth-type-info-vtable-pointer-discrimination" "-fptrauth-indirect-gotos" "-fptrauth-init-fini" "-fptrauth-init-fini-address-discrimination" "-fptrauth-elf-got"{{.*}} "-faarch64-jump-table-hardening" // RUN: %clang -### -c --target=aarch64-linux \ // RUN: -fno-aarch64-jump-table-hardening -faarch64-jump-table-hardening \ @@ -93,14 +95,16 @@ //// Non-pauthtest ABI. // RUN: not %clang -### -c --target=aarch64-linux -fptrauth-intrinsics -fptrauth-calls -fptrauth-returns -fptrauth-auth-traps \ // RUN: -fptrauth-vtable-pointer-address-discrimination -fptrauth-vtable-pointer-type-discrimination \ -// RUN: -fptrauth-type-info-vtable-pointer-discrimination -fptrauth-indirect-gotos -fptrauth-init-fini \ -// RUN: -fptrauth-init-fini-address-discrimination -fptrauth-elf-got %s 2>&1 | FileCheck %s --check-prefix=ERR1 +// RUN: -fptrauth-vtt-vtable-pointer-discrimination -fptrauth-type-info-vtable-pointer-discrimination \ +// RUN: -fptrauth-indirect-gotos -fptrauth-init-fini -fptrauth-init-fini-address-discrimination \ +// RUN: -fptrauth-elf-got %s 2>&1 | FileCheck %s --check-prefix=ERR1 // ERR1: error: unsupported option '-fptrauth-intrinsics' for target '{{.*}}' // ERR1-NEXT: error: unsupported option '-fptrauth-calls' for target '{{.*}}' // ERR1-NEXT: error: unsupported option '-fptrauth-returns' for target '{{.*}}' // ERR1-NEXT: error: unsupported option '-fptrauth-auth-traps' for target '{{.*}}' // ERR1-NEXT: error: unsupported option '-fptrauth-vtable-pointer-address-discrimination' for target '{{.*}}' // ERR1-NEXT: error: unsupported option '-fptrauth-vtable-pointer-type-discrimination' for target '{{.*}}' +// ERR1-NEXT: error: unsupported option '-fptrauth-vtt-vtable-pointer-discrimination' for target '{{.*}}' // ERR1-NEXT: error: unsupported option '-fptrauth-type-info-vtable-pointer-discrimination' for target '{{.*}}' // ERR1-NEXT: error: unsupported option '-fptrauth-indirect-gotos' for target '{{.*}}' // ERR1-NEXT: error: unsupported option '-fptrauth-init-fini' for target '{{.*}}' _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
