Skip to content

Commit 0c20bcd

Browse files
committed
[PAC] Fix address discrimination for type info vtable pointers
In llvm#99726, `-fptrauth-type-info-vtable-pointer-discrimination` was introduced, which is intended to enable type and address discrimination for type_info vtable pointers. However, some codegen logic for actually enabling address discrimination was missing. This patch addresses the issue. Fixes llvm#101716
1 parent 642259a commit 0c20bcd

File tree

4 files changed

+50
-10
lines changed

4 files changed

+50
-10
lines changed

clang/lib/CodeGen/ItaniumCXXABI.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3955,9 +3955,23 @@ void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty) {
39553955
VTable, Two);
39563956
}
39573957

3958-
if (auto &Schema = CGM.getCodeGenOpts().PointerAuth.CXXTypeInfoVTablePointer)
3959-
VTable = CGM.getConstantSignedPointer(VTable, Schema, nullptr, GlobalDecl(),
3960-
QualType(Ty, 0));
3958+
if (const auto &Schema =
3959+
CGM.getCodeGenOpts().PointerAuth.CXXTypeInfoVTablePointer) {
3960+
llvm::PointerType *PtrTy = llvm::PointerType::get(
3961+
CGM.getLLVMContext(),
3962+
CGM.getModule().getDataLayout().getProgramAddressSpace());
3963+
llvm::Constant *StorageAddress =
3964+
(Schema.isAddressDiscriminated()
3965+
? llvm::ConstantExpr::getIntToPtr(
3966+
llvm::ConstantInt::get(
3967+
CGM.IntPtrTy,
3968+
llvm::ConstantPtrAuth::
3969+
AddrDiscriminator_CXXTypeInfoVTablePointer),
3970+
PtrTy)
3971+
: nullptr);
3972+
VTable = CGM.getConstantSignedPointer(VTable, Schema, StorageAddress,
3973+
GlobalDecl(), QualType(Ty, 0));
3974+
}
39613975

39623976
Fields.push_back(VTable);
39633977
}

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 @_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 inttoptr (i64 1 to ptr)), ptr @_ZTS10TestStruct }, align 8
6969

7070
struct TestStruct {
7171
virtual ~TestStruct();

llvm/include/llvm/IR/Constants.h

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

1059-
/// A constant value for the address discriminator which has special
1060-
/// significance to ctors/dtors lowering. Regular address discrimination can't
1061-
/// be applied for them since uses of llvm.global_{c|d}tors are disallowed
1062-
/// (see Verifier::visitGlobalVariable) and we can't emit getelementptr
1063-
/// expressions referencing these special arrays.
1064-
enum { AddrDiscriminator_CtorsDtors = 1 };
1059+
/// Constant values for the address discriminator which have special
1060+
/// significance to lowering in some contexts.
1061+
/// - For ctors/dtors, regular address discrimination can't
1062+
/// be applied for them since uses of llvm.global_{c|d}tors are disallowed
1063+
/// (see Verifier::visitGlobalVariable) and we can't emit getelementptr
1064+
/// expressions referencing these special arrays.
1065+
/// - For vtable pointers of std::type_info and classes derived from it,
1066+
/// we do not know the storage address when emitting ptrauth constant.
1067+
enum {
1068+
AddrDiscriminator_CtorsDtors = 1,
1069+
AddrDiscriminator_CXXTypeInfoVTablePointer = 1
1070+
};
10651071

10661072
/// Whether the address uses a special address discriminator.
10671073
/// These discriminators can't be used in real pointer-auth values; they
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
; RUN: llc -mtriple aarch64-linux-gnu -mattr=+pauth -filetype=asm -o - %s | FileCheck --check-prefix=ELF %s
2+
; RUN: llc -mtriple aarch64-apple-darwin -mattr=+pauth -filetype=asm -o - %s | FileCheck --check-prefix=MACHO %s
3+
4+
; ELF-LABEL: _ZTI10Disc:
5+
; ELF-NEXT: .xword (_ZTVN10__cxxabiv117__class_type_infoE+16)@AUTH(da,45546,addr)
6+
; ELF-LABEL: _ZTI10NoDisc:
7+
; ELF-NEXT: .xword (_ZTVN10__cxxabiv117__class_type_infoE+16)@AUTH(da,45546)
8+
9+
; MACHO-LABEL: __ZTI10Disc:
10+
; MACHO-NEXT: .quad (__ZTVN10__cxxabiv117__class_type_infoE+16)@AUTH(da,45546,addr)
11+
; MACHO-LABEL: __ZTI10NoDisc:
12+
; MACHO-NEXT: .quad (__ZTVN10__cxxabiv117__class_type_infoE+16)@AUTH(da,45546)
13+
14+
@_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr]
15+
16+
@_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
18+
19+
@_ZTS10NoDisc = constant [6 x i8] c"NoDisc", align 1
20+
@_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)