Skip to content

Commit 0e3c7fa

Browse files
committed
[WIP][PAC] Emit IR debug info metadata nodes for implicitly signed pointers
Emit debug metadata nodes with `DW_TAG_LLVM_ptrauth_type` tag containing signing scheme info for the following types of implicitly (without `__ptrauth` specifier) signed pointers: - virtual table pointers; - free function pointers; - member function pointers.
1 parent 62ce88f commit 0e3c7fa

File tree

3 files changed

+158
-3
lines changed

3 files changed

+158
-3
lines changed

clang/lib/CodeGen/CGDebugInfo.cpp

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1058,8 +1058,25 @@ llvm::DIType *CGDebugInfo::CreateType(const ObjCObjectPointerType *Ty,
10581058

10591059
llvm::DIType *CGDebugInfo::CreateType(const PointerType *Ty,
10601060
llvm::DIFile *Unit) {
1061-
return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
1062-
Ty->getPointeeType(), Unit);
1061+
llvm::DIType *DIPointerTy = CreatePointerLikeType(
1062+
llvm::dwarf::DW_TAG_pointer_type, Ty, Ty->getPointeeType(), Unit);
1063+
1064+
if (!Ty->getPointeeType()->isFunctionType())
1065+
return DIPointerTy;
1066+
1067+
CGPointerAuthInfo SignSchema =
1068+
CGM.getFunctionPointerAuthInfo(QualType(Ty, 0));
1069+
if (!SignSchema)
1070+
return DIPointerTy;
1071+
1072+
llvm::ConstantInt *Discr =
1073+
cast_or_null<llvm::ConstantInt>(SignSchema.getDiscriminator());
1074+
// See CodeGenModule::getMemberFunctionPointer in CGPointerAuth.cpp - we
1075+
// do not use address discrimination
1076+
return DBuilder.createPtrAuthQualifiedType(
1077+
DIPointerTy, SignSchema.getKey(), false,
1078+
Discr ? Discr->getValue().getZExtValue() : 0, SignSchema.isIsaPointer(),
1079+
SignSchema.authenticatesNullValues());
10631080
}
10641081

10651082
/// \return whether a C++ mangling exists for the type defined by TD.
@@ -2432,6 +2449,14 @@ void CGDebugInfo::CollectVTableInfo(const CXXRecordDecl *RD, llvm::DIFile *Unit,
24322449
if (!VPtrTy)
24332450
VPtrTy = getOrCreateVTablePtrType(Unit);
24342451

2452+
if (std::optional<PointerAuthQualifier> VTAuth =
2453+
CGM.getVTablePointerAuthentication(RD)) {
2454+
VPtrTy = DBuilder.createPtrAuthQualifiedType(
2455+
VPtrTy, VTAuth->getKey(), VTAuth->isAddressDiscriminated(),
2456+
VTAuth->getExtraDiscriminator(), VTAuth->isIsaPointer(),
2457+
VTAuth->authenticatesNullValues());
2458+
}
2459+
24352460
unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
24362461
llvm::DIType *VPtrMember =
24372462
DBuilder.createMemberType(Unit, getVTableName(RD), Unit, 0, Size, 0, 0,
@@ -3311,11 +3336,26 @@ llvm::DIType *CGDebugInfo::CreateType(const MemberPointerType *Ty,
33113336

33123337
const FunctionProtoType *FPT =
33133338
Ty->getPointeeType()->castAs<FunctionProtoType>();
3314-
return DBuilder.createMemberPointerType(
3339+
3340+
llvm::DIType *DIPointerTy = DBuilder.createMemberPointerType(
33153341
getOrCreateInstanceMethodType(
33163342
CXXMethodDecl::getThisType(FPT, Ty->getMostRecentCXXRecordDecl()),
33173343
FPT, U),
33183344
ClassType, Size, /*Align=*/0, Flags);
3345+
3346+
CGPointerAuthInfo SignSchema =
3347+
CGM.getMemberFunctionPointerAuthInfo(QualType(Ty, 0));
3348+
if (!SignSchema)
3349+
return DIPointerTy;
3350+
3351+
llvm::ConstantInt *Discr =
3352+
cast_or_null<llvm::ConstantInt>(SignSchema.getDiscriminator());
3353+
// See CodeGenModule::getFunctionPointer in CGPointerAuth.cpp - we do not
3354+
// use address discrimination
3355+
return DBuilder.createPtrAuthQualifiedType(
3356+
DIPointerTy, SignSchema.getKey(), false,
3357+
Discr ? Discr->getValue().getZExtValue() : 0, SignSchema.isIsaPointer(),
3358+
SignSchema.authenticatesNullValues());
33193359
}
33203360

33213361
llvm::DIType *CGDebugInfo::CreateType(const AtomicType *Ty, llvm::DIFile *U) {
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// RUN: split-file %s %t && cd %t
2+
3+
//--- vtptr.cpp
4+
5+
// RUN: %clang -g -target aarch64-elf -mbranch-protection=pauthabi \
6+
// RUN: -S -emit-llvm vtptr.cpp -o - | FileCheck vtptr.cpp
7+
8+
// CHECK: !DIDerivedType(tag: DW_TAG_member
9+
// CHECK-SAME: name: "_vptr$A"
10+
// CHECK-SAME: baseType: [[BASE1:![0-9]+]]
11+
12+
// CHECK: [[BASE1]] = !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type
13+
// CHECK-SAME: baseType: [[BASE2:![0-9]+]]
14+
// CHECK-SAME: ptrAuthKey: 2
15+
// CHECK-SAME: ptrAuthIsAddressDiscriminated: true
16+
// CHECK-SAME: ptrAuthExtraDiscriminator: 62866
17+
// CHECK-SAME: ptrAuthIsaPointer: false
18+
// CHECK-SAME: ptrAuthAuthenticatesNullValues: false
19+
20+
// CHECK: [[BASE2]] = !DIDerivedType(tag: DW_TAG_pointer_type
21+
// CHECK-SAME: baseType: [[BASE3:![0-9]+]]
22+
23+
// CHECK: [[BASE3]] = !DIDerivedType(tag: DW_TAG_pointer_type
24+
// CHECK-SAME: name: "__vtbl_ptr_type"
25+
// CHECK-SAME: baseType: [[BASE4:![0-9]+]]
26+
27+
// CHECK: [[BASE4]] = !DISubroutineType
28+
29+
struct A {
30+
virtual void foo() {};
31+
};
32+
33+
void bar(A& a) {
34+
a.foo();
35+
}
36+
37+
void test() {
38+
A a;
39+
bar(a);
40+
}
41+
42+
//--- fptr.c
43+
44+
// RUN: %clang -g -target aarch64-elf -mbranch-protection=pauthabi \
45+
// RUN: -S -emit-llvm fptr.c -o - | FileCheck fptr.c
46+
47+
// CHECK: !DIGlobalVariable(name: "y"
48+
// CHECK-SAME: type: [[TYPE:![0-9]+]]
49+
50+
/* IA key and zero extra discriminator are not emitted in IR metadata nodes
51+
* but are still present in Dwarf output generated. */
52+
53+
// CHECK: [[TYPE]] = !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type
54+
// CHECK-SAME: baseType: [[BASE1:![0-9]+]]
55+
// CHECK-SAME: ptrAuthIsAddressDiscriminated: false
56+
// CHECK-SAME: ptrAuthIsaPointer: false
57+
// CHECK-SAME: ptrAuthAuthenticatesNullValues: false
58+
59+
// CHECK: [[BASE1]] = !DIDerivedType(tag: DW_TAG_pointer_type
60+
// CHECK-SAME: baseType: [[BASE2:![0-9]+]]
61+
62+
// CHECK: [[BASE2]] = !DIDerivedType(tag: DW_TAG_typedef
63+
// CHECK-SAME: name: "fptr"
64+
65+
typedef void fptr();
66+
67+
fptr x;
68+
69+
fptr *y = &x;
70+
71+
//--- member-fptr.cpp
72+
73+
// RUN: %clang -g -target aarch64-elf -mbranch-protection=pauthabi \
74+
// RUN: -S -emit-llvm member-fptr.cpp -o - | FileCheck member-fptr.cpp
75+
76+
// CHECK: !DIGlobalVariable(name: "x"
77+
// CHECK-SAME: type: [[TYPEDEF:![0-9]+]]
78+
79+
// CHECK: [[TYPEDEF]] = !DIDerivedType(tag: DW_TAG_typedef
80+
// CHECK-SAME: name: "fptr",
81+
// CHECK-SAME: baseType: [[TYPE:![0-9]+]]
82+
83+
/* IA key is not emitted in IR metadata nodes but is still present
84+
* in Dwarf output generated. */
85+
86+
// CHECK: [[TYPE]] = !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type
87+
// CHECK-SAME: baseType: [[BASE1:![0-9]+]]
88+
// CHECK-SAME: ptrAuthIsAddressDiscriminated: false
89+
// CHECK-SAME: ptrAuthExtraDiscriminator: 15253
90+
// CHECK-SAME: ptrAuthIsaPointer: false
91+
// CHECK-SAME: ptrAuthAuthenticatesNullValues: false
92+
93+
// CHECK: [[BASE1]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type
94+
// CHECK-SAME: baseType: [[BASE2:![0-9]+]]
95+
96+
// CHECK: [[BASE2]] = !DISubroutineType
97+
98+
struct A {
99+
void foo() {};
100+
};
101+
102+
typedef void (A::*fptr)();
103+
104+
fptr x = &A::foo;

clang/test/CodeGen/ptrauth-debuginfo.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,17 @@ void f() {
3939
// CHECK-SAME: ptrAuthIsaPointer: false,
4040
// CHECK-SAME: ptrAuthAuthenticatesNullValues: false)
4141

42+
/* Block descriptor signed function type. The same is used for further block
43+
* descriptors, so checking only once. */
44+
45+
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "__FuncPtr",
46+
// CHECK-SAME: baseType: [[BASE1:![0-9]+]],
47+
48+
// CHECK: [[BASE1]] = !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type,
49+
// CHECK-SAME: ptrAuthIsAddressDiscriminated: false,
50+
// CHECK-SAME: ptrAuthIsaPointer: false,
51+
// CHECK-SAME: ptrAuthAuthenticatesNullValues: false)
52+
4253
void f2() {
4354
__block struct A *__ptrauth(1, 1, 1237, "isa-pointer") ptr = createA();
4455
^{

0 commit comments

Comments
 (0)