Skip to content

Commit 919af72

Browse files
[PAC][clang] Define ptrauth driver flags and preprocessor features
Define the following clang driver flags: - `-fptrauth-intrinsics`: `PointerAuth.intrinsics()` in `LangOptions`, `ptrauth_intrinsics` preprocessor feature; - `-fptrauth-calls`: `PointerAuth.calls()` in `LangOptions`, `ptrauth_calls` and and `ptrauth_member_function_pointer_type_discrimination` preprocessor features; - `-fptrauth-returns`: `PointerAuth.returns()` in `LangOptions`, `ptrauth_returns` preprocessor feature; - `-fptrauth-auth-traps`: `PointerAuth.authTraps()` in `LangOptions`; - `-fptrauth-vtable-pointer-address-discrimination`: `PointerAuth.vtptrAddressDiscrimination()` in `LangOptions`, `ptrauth_vtable_pointer_address_discrimination` preprocessor feature; - `-fptrauth-vtable-pointer-type-discrimination`: `PointerAuth.vtptrTypeDiscrimination()` in `LangOptions`, `ptrauth_vtable_pointer_type_discrimination` preprocessor feature; - `-fptrauth-init-fini`: `PointerAuth.initFini()` in `LangOptions`, `ptrauth_init_fini` preprocessor feature. The patch only defines the flags and having corresponding `LangOptions` set does not affect codegen yet. Co-authored-by: Ahmed Bougacha <[email protected]>
1 parent 4a6bc9f commit 919af72

File tree

7 files changed

+214
-2
lines changed

7 files changed

+214
-2
lines changed

clang/include/clang/Basic/Features.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,12 @@ FEATURE(thread_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Thread))
102102
FEATURE(dataflow_sanitizer, LangOpts.Sanitize.has(SanitizerKind::DataFlow))
103103
FEATURE(scudo, LangOpts.Sanitize.hasOneOf(SanitizerKind::Scudo))
104104
FEATURE(ptrauth_intrinsics, LangOpts.PointerAuthIntrinsics)
105+
FEATURE(ptrauth_calls, LangOpts.PointerAuthCalls)
106+
FEATURE(ptrauth_returns, LangOpts.PointerAuthReturns)
107+
FEATURE(ptrauth_vtable_pointer_address_discrimination, LangOpts.PointerAuthVTPtrAddressDiscrimination)
108+
FEATURE(ptrauth_vtable_pointer_type_discrimination, LangOpts.PointerAuthVTPtrTypeDiscrimination)
109+
FEATURE(ptrauth_member_function_pointer_type_discrimination, LangOpts.PointerAuthCalls)
110+
FEATURE(ptrauth_init_fini, LangOpts.PointerAuthInitFini)
105111
FEATURE(swiftasynccc,
106112
PP.getTargetInfo().checkCallingConvention(CC_SwiftAsync) ==
107113
clang::TargetInfo::CCCR_OK)

clang/include/clang/Basic/LangOptions.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,12 @@ LANGOPT(RelaxedTemplateTemplateArgs, 1, 0, "C++17 relaxed matching of template t
162162
LANGOPT(ExperimentalLibrary, 1, 0, "enable unstable and experimental library features")
163163

164164
LANGOPT(PointerAuthIntrinsics, 1, 0, "pointer authentication intrinsics")
165+
LANGOPT(PointerAuthCalls , 1, 0, "function pointer authentication")
166+
LANGOPT(PointerAuthReturns, 1, 0, "return pointer authentication")
167+
LANGOPT(PointerAuthAuthTraps, 1, 0, "pointer authentication failure traps")
168+
LANGOPT(PointerAuthVTPtrAddressDiscrimination, 1, 0, "incorporate address discrimination in authenticated vtable pointers")
169+
LANGOPT(PointerAuthVTPtrTypeDiscrimination, 1, 0, "incorporate type discrimination in authenticated vtable pointers")
170+
LANGOPT(PointerAuthInitFini, 1, 0, "sign function pointers in init/fini arrays")
165171

166172
LANGOPT(DoubleSquareBracketAttributes, 1, 0, "'[[]]' attributes extension for all language standard modes")
167173

clang/include/clang/Driver/Options.td

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4110,8 +4110,26 @@ let Group = f_Group in {
41104110
let Visibility = [ClangOption,CC1Option] in {
41114111
def fptrauth_intrinsics : Flag<["-"], "fptrauth-intrinsics">,
41124112
HelpText<"Enable pointer authentication intrinsics">;
4113+
def fptrauth_calls : Flag<["-"], "fptrauth-calls">,
4114+
HelpText<"Enable signing and authentication of all indirect calls">;
4115+
def fptrauth_returns : Flag<["-"], "fptrauth-returns">,
4116+
HelpText<"Enable signing and authentication of return addresses">;
4117+
def fptrauth_auth_traps : Flag<["-"], "fptrauth-auth-traps">,
4118+
HelpText<"Enable traps on authentication failures">;
4119+
def fptrauth_vtable_pointer_address_discrimination : Flag<["-"], "fptrauth-vtable-pointer-address-discrimination">,
4120+
HelpText<"Enable address discrimination of vtable pointers">;
4121+
def fptrauth_vtable_pointer_type_discrimination : Flag<["-"], "fptrauth-vtable-pointer-type-discrimination">,
4122+
HelpText<"Enable type discrimination of vtable pointers">;
4123+
def fptrauth_init_fini : Flag<["-"], "fptrauth-init-fini">,
4124+
HelpText<"Enable signing of function pointers in init/fini arrays">;
41134125
}
41144126
def fno_ptrauth_intrinsics : Flag<["-"], "fno-ptrauth-intrinsics">;
4127+
def fno_ptrauth_calls : Flag<["-"], "fno-ptrauth-calls">;
4128+
def fno_ptrauth_returns : Flag<["-"], "fno-ptrauth-returns">;
4129+
def fno_ptrauth_auth_traps : Flag<["-"], "fno-ptrauth-auth-traps">;
4130+
def fno_ptrauth_vtable_pointer_address_discrimination : Flag<["-"], "fno-ptrauth-vtable-pointer-address-discrimination">;
4131+
def fno_ptrauth_vtable_pointer_type_discrimination : Flag<["-"], "fno-ptrauth-vtable-pointer-type-discrimination">;
4132+
def fno_ptrauth_init_fini : Flag<["-"], "fno-ptrauth-init-fini">;
41154133
}
41164134

41174135
def fenable_matrix : Flag<["-"], "fenable-matrix">, Group<f_Group>,

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7203,6 +7203,33 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
72037203
options::OPT_fno_ptrauth_intrinsics, false))
72047204
CmdArgs.push_back("-fptrauth-intrinsics");
72057205

7206+
if (Args.hasFlag(options::OPT_fptrauth_calls, options::OPT_fno_ptrauth_calls,
7207+
false))
7208+
CmdArgs.push_back("-fptrauth-calls");
7209+
7210+
if (Args.hasFlag(options::OPT_fptrauth_returns,
7211+
options::OPT_fno_ptrauth_returns, false))
7212+
CmdArgs.push_back("-fptrauth-returns");
7213+
7214+
if (Args.hasFlag(options::OPT_fptrauth_auth_traps,
7215+
options::OPT_fno_ptrauth_auth_traps, false))
7216+
CmdArgs.push_back("-fptrauth-auth-traps");
7217+
7218+
if (Args.hasFlag(
7219+
options::OPT_fptrauth_vtable_pointer_address_discrimination,
7220+
options::OPT_fno_ptrauth_vtable_pointer_address_discrimination,
7221+
false))
7222+
CmdArgs.push_back("-fptrauth-vtable-pointer-address-discrimination");
7223+
7224+
if (Args.hasFlag(options::OPT_fptrauth_vtable_pointer_type_discrimination,
7225+
options::OPT_fno_ptrauth_vtable_pointer_type_discrimination,
7226+
false))
7227+
CmdArgs.push_back("-fptrauth-vtable-pointer-type-discrimination");
7228+
7229+
if (Args.hasFlag(options::OPT_fptrauth_init_fini,
7230+
options::OPT_fno_ptrauth_init_fini, false))
7231+
CmdArgs.push_back("-fptrauth-init-fini");
7232+
72067233
// -fsigned-bitfields is default, and clang doesn't yet support
72077234
// -funsigned-bitfields.
72087235
if (!Args.hasFlag(options::OPT_fsigned_bitfields,

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3297,11 +3297,31 @@ static void GeneratePointerAuthArgs(const LangOptions &Opts,
32973297
ArgumentConsumer Consumer) {
32983298
if (Opts.PointerAuthIntrinsics)
32993299
GenerateArg(Consumer, OPT_fptrauth_intrinsics);
3300+
if (Opts.PointerAuthCalls)
3301+
GenerateArg(Consumer, OPT_fptrauth_calls);
3302+
if (Opts.PointerAuthReturns)
3303+
GenerateArg(Consumer, OPT_fptrauth_returns);
3304+
if (Opts.PointerAuthAuthTraps)
3305+
GenerateArg(Consumer, OPT_fptrauth_auth_traps);
3306+
if (Opts.PointerAuthVTPtrAddressDiscrimination)
3307+
GenerateArg(Consumer, OPT_fptrauth_vtable_pointer_address_discrimination);
3308+
if (Opts.PointerAuthVTPtrTypeDiscrimination)
3309+
GenerateArg(Consumer, OPT_fptrauth_vtable_pointer_type_discrimination);
3310+
if (Opts.PointerAuthInitFini)
3311+
GenerateArg(Consumer, OPT_fptrauth_init_fini);
33003312
}
33013313

33023314
static void ParsePointerAuthArgs(LangOptions &Opts, ArgList &Args,
33033315
DiagnosticsEngine &Diags) {
33043316
Opts.PointerAuthIntrinsics = Args.hasArg(OPT_fptrauth_intrinsics);
3317+
Opts.PointerAuthCalls = Args.hasArg(OPT_fptrauth_calls);
3318+
Opts.PointerAuthReturns = Args.hasArg(OPT_fptrauth_returns);
3319+
Opts.PointerAuthAuthTraps = Args.hasArg(OPT_fptrauth_auth_traps);
3320+
Opts.PointerAuthVTPtrAddressDiscrimination =
3321+
Args.hasArg(OPT_fptrauth_vtable_pointer_address_discrimination);
3322+
Opts.PointerAuthVTPtrTypeDiscrimination =
3323+
Args.hasArg(OPT_fptrauth_vtable_pointer_type_discrimination);
3324+
Opts.PointerAuthInitFini = Args.hasArg(OPT_fptrauth_init_fini);
33053325
}
33063326

33073327
/// Check if input file kind and language standard are compatible.

clang/test/Driver/ptrauth.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Check that we can manually enable specific ptrauth features.
2+
3+
// RUN: %clang -target aarch64 -c %s -### 2>&1 | FileCheck %s --check-prefix NONE
4+
// NONE: "-cc1"
5+
// NONE-NOT: "-fptrauth-intrinsics"
6+
// NONE-NOT: "-fptrauth-calls"
7+
// NONE-NOT: "-fptrauth-returns"
8+
// NONE-NOT: "-fptrauth-auth-traps"
9+
// NONE-NOT: "-fptrauth-vtable-pointer-address-discrimination"
10+
// NONE-NOT: "-fptrauth-vtable-pointer-type-discrimination"
11+
// NONE-NOT: "-fptrauth-init-fini"
12+
13+
// RUN: %clang -target aarch64 -fptrauth-intrinsics -c %s -### 2>&1 | FileCheck %s --check-prefix INTRIN
14+
// INTRIN: "-cc1"{{.*}} {{.*}} "-fptrauth-intrinsics"
15+
16+
// RUN: %clang -target aarch64 -fptrauth-calls -c %s -### 2>&1 | FileCheck %s --check-prefix CALL
17+
// CALL: "-cc1"{{.*}} {{.*}} "-fptrauth-calls"
18+
19+
// RUN: %clang -target aarch64 -fptrauth-returns -c %s -### 2>&1 | FileCheck %s --check-prefix RETURN
20+
// RETURN: "-cc1"{{.*}} {{.*}} "-fptrauth-returns"
21+
22+
// RUN: %clang -target aarch64 -fptrauth-auth-traps -c %s -### 2>&1 | FileCheck %s --check-prefix TRAPS
23+
// TRAPS: "-cc1"{{.*}} {{.*}} "-fptrauth-auth-traps"
24+
25+
// RUN: %clang -target aarch64 -fptrauth-vtable-pointer-address-discrimination -c %s -### 2>&1 | FileCheck %s --check-prefix VPTR_ADDR_DISCR
26+
// VPTR_ADDR_DISCR: "-cc1"{{.*}} {{.*}} "-fptrauth-vtable-pointer-address-discrimination"
27+
28+
// RUN: %clang -target aarch64 -fptrauth-vtable-pointer-type-discrimination -c %s -### 2>&1 | FileCheck %s --check-prefix VPTR_TYPE_DISCR
29+
// VPTR_TYPE_DISCR: "-cc1"{{.*}} {{.*}} "-fptrauth-vtable-pointer-type-discrimination"
30+
31+
// RUN: %clang -target aarch64 -fptrauth-init-fini -c %s -### 2>&1 | FileCheck %s --check-prefix INITFINI
32+
// INITFINI: "-cc1"{{.*}} {{.*}} "-fptrauth-init-fini"
Lines changed: 105 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,59 @@
1-
// RUN: %clang_cc1 %s -E -triple=arm64-- | FileCheck %s --check-prefixes=NOINTRIN
2-
// RUN: %clang_cc1 %s -E -triple=arm64-- -fptrauth-intrinsics | FileCheck %s --check-prefixes=INTRIN
1+
// RUN: %clang_cc1 -E %s -triple=aarch64 \
2+
// RUN: -fptrauth-intrinsics \
3+
// RUN: -fptrauth-calls \
4+
// RUN: -fptrauth-returns \
5+
// RUN: -fptrauth-vtable-pointer-address-discrimination \
6+
// RUN: -fptrauth-vtable-pointer-type-discrimination \
7+
// RUN: -fptrauth-init-fini | \
8+
// RUN: FileCheck %s --check-prefixes=INTRIN,CALLS,RETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,INITFINI
9+
10+
// RUN: %clang_cc1 -E %s -triple=aarch64 \
11+
// RUN: -fptrauth-calls \
12+
// RUN: -fptrauth-returns \
13+
// RUN: -fptrauth-vtable-pointer-address-discrimination \
14+
// RUN: -fptrauth-vtable-pointer-type-discrimination \
15+
// RUN: -fptrauth-init-fini | \
16+
// RUN: FileCheck %s --check-prefixes=NOINTRIN,CALLS,RETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,INITFINI
17+
18+
// RUN: %clang_cc1 -E %s -triple=aarch64 \
19+
// RUN: -fptrauth-intrinsics \
20+
// RUN: -fptrauth-returns \
21+
// RUN: -fptrauth-vtable-pointer-address-discrimination \
22+
// RUN: -fptrauth-vtable-pointer-type-discrimination \
23+
// RUN: -fptrauth-init-fini | \
24+
// RUN: FileCheck %s --check-prefixes=INTRIN,NOCALLS,RETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,INITFINI
25+
26+
// RUN: %clang_cc1 -E %s -triple=aarch64 \
27+
// RUN: -fptrauth-intrinsics \
28+
// RUN: -fptrauth-calls \
29+
// RUN: -fptrauth-vtable-pointer-address-discrimination \
30+
// RUN: -fptrauth-vtable-pointer-type-discrimination \
31+
// RUN: -fptrauth-init-fini | \
32+
// RUN: FileCheck %s --check-prefixes=INTRIN,CALLS,NORETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,INITFINI
33+
34+
// RUN: %clang_cc1 -E %s -triple=aarch64 \
35+
// RUN: -fptrauth-intrinsics \
36+
// RUN: -fptrauth-calls \
37+
// RUN: -fptrauth-returns \
38+
// RUN: -fptrauth-vtable-pointer-type-discrimination \
39+
// RUN: -fptrauth-init-fini | \
40+
// RUN: FileCheck %s --check-prefixes=INTRIN,CALLS,RETS,NOVPTR_ADDR_DISCR,VPTR_TYPE_DISCR,INITFINI
41+
42+
// RUN: %clang_cc1 -E %s -triple=aarch64 \
43+
// RUN: -fptrauth-intrinsics \
44+
// RUN: -fptrauth-calls \
45+
// RUN: -fptrauth-returns \
46+
// RUN: -fptrauth-vtable-pointer-address-discrimination \
47+
// RUN: -fptrauth-init-fini | \
48+
// RUN: FileCheck %s --check-prefixes=INTRIN,CALLS,RETS,VPTR_ADDR_DISCR,NOVPTR_TYPE_DISCR,INITFINI
49+
50+
// RUN: %clang_cc1 -E %s -triple=aarch64 \
51+
// RUN: -fptrauth-intrinsics \
52+
// RUN: -fptrauth-calls \
53+
// RUN: -fptrauth-returns \
54+
// RUN: -fptrauth-vtable-pointer-address-discrimination \
55+
// RUN: -fptrauth-vtable-pointer-type-discrimination | \
56+
// RUN: FileCheck %s --check-prefixes=INTRIN,CALLS,RETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,NOINITFINI
357

458
#if __has_feature(ptrauth_intrinsics)
559
// INTRIN: has_ptrauth_intrinsics
@@ -8,3 +62,52 @@ void has_ptrauth_intrinsics() {}
862
// NOINTRIN: no_ptrauth_intrinsics
963
void no_ptrauth_intrinsics() {}
1064
#endif
65+
66+
#if __has_feature(ptrauth_calls)
67+
// CALLS: has_ptrauth_calls
68+
void has_ptrauth_calls() {}
69+
#else
70+
// NOCALLS: no_ptrauth_calls
71+
void no_ptrauth_calls() {}
72+
#endif
73+
74+
// This is always enabled when ptrauth_calls is enabled
75+
#if __has_feature(ptrauth_member_function_pointer_type_discrimination)
76+
// CALLS: has_ptrauth_member_function_pointer_type_discrimination
77+
void has_ptrauth_member_function_pointer_type_discrimination() {}
78+
#else
79+
// NOCALLS: no_ptrauth_member_function_pointer_type_discrimination
80+
void no_ptrauth_member_function_pointer_type_discrimination() {}
81+
#endif
82+
83+
#if __has_feature(ptrauth_returns)
84+
// RETS: has_ptrauth_returns
85+
void has_ptrauth_returns() {}
86+
#else
87+
// NORETS: no_ptrauth_returns
88+
void no_ptrauth_returns() {}
89+
#endif
90+
91+
#if __has_feature(ptrauth_vtable_pointer_address_discrimination)
92+
// VPTR_ADDR_DISCR: has_ptrauth_vtable_pointer_address_discrimination
93+
void has_ptrauth_vtable_pointer_address_discrimination() {}
94+
#else
95+
// NOVPTR_ADDR_DISCR: no_ptrauth_vtable_pointer_address_discrimination
96+
void no_ptrauth_vtable_pointer_address_discrimination() {}
97+
#endif
98+
99+
#if __has_feature(ptrauth_vtable_pointer_type_discrimination)
100+
// VPTR_TYPE_DISCR: has_ptrauth_vtable_pointer_type_discrimination
101+
void has_ptrauth_vtable_pointer_type_discrimination() {}
102+
#else
103+
// NOVPTR_TYPE_DISCR: no_ptrauth_vtable_pointer_type_discrimination
104+
void no_ptrauth_vtable_pointer_type_discrimination() {}
105+
#endif
106+
107+
#if __has_feature(ptrauth_init_fini)
108+
// INITFINI: has_ptrauth_init_fini
109+
void has_ptrauth_init_fini() {}
110+
#else
111+
// NOINITFINI: no_ptrauth_init_fini
112+
void no_ptrauth_init_fini() {}
113+
#endif

0 commit comments

Comments
 (0)