Skip to content

Commit 1394471

Browse files
[PAC][clang] Define ptrauth driver flags and preprocessor features
Define the following clang driver flags: - `-fptrauth-intrinsics`: `PointerAuthIntrinsics` in `LangOptions`, `ptrauth_intrinsics` preprocessor feature; - `-fptrauth-calls`: `PointerAuthCalls` in `LangOptions`, `ptrauth_calls` and `ptrauth_member_function_pointer_type_discrimination` preprocessor features; - `-fptrauth-returns`: `PointerAuthReturns` in `LangOptions`, `ptrauth_returns` preprocessor feature; - `-fptrauth-auth-traps`: `PointerAuthAuthTraps` in `LangOptions`; - `-fptrauth-vtable-pointer-address-discrimination`: `PointerAuthVTPtrAddressDiscrimination` in `LangOptions`, `ptrauth_vtable_pointer_address_discrimination` preprocessor feature; - `-fptrauth-vtable-pointer-type-discrimination`: `PointerAuthVTPtrTypeDiscrimination` in `LangOptions`, `ptrauth_vtable_pointer_type_discrimination` preprocessor feature; - `-fptrauth-init-fini`: `PointerAuthInitFini` 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 4a21e3a commit 1394471

File tree

7 files changed

+250
-0
lines changed

7 files changed

+250
-0
lines changed

clang/include/clang/Basic/Features.def

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,13 @@ FEATURE(memory_sanitizer,
101101
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))
104+
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)
104111
FEATURE(swiftasynccc,
105112
PP.getTargetInfo().checkCallingConvention(CC_SwiftAsync) ==
106113
clang::TargetInfo::CCCR_OK)

clang/include/clang/Basic/LangOptions.def

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,14 @@ LANGOPT(DllExportInlines , 1, 1, "dllexported classes dllexport inline methods"
161161
LANGOPT(RelaxedTemplateTemplateArgs, 1, 0, "C++17 relaxed matching of template template arguments")
162162
LANGOPT(ExperimentalLibrary, 1, 0, "enable unstable and experimental library features")
163163

164+
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")
171+
164172
LANGOPT(DoubleSquareBracketAttributes, 1, 0, "'[[]]' attributes extension for all language standard modes")
165173

166174
COMPATIBLE_LANGOPT(RecoveryAST, 1, 1, "Preserve expressions in AST when encountering errors")

clang/include/clang/Driver/Options.td

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4085,6 +4085,32 @@ defm strict_return : BoolFOption<"strict-return",
40854085
" of a non-void function as unreachable">,
40864086
PosFlag<SetTrue>>;
40874087

4088+
let Group = f_Group in {
4089+
let Visibility = [ClangOption,CC1Option] in {
4090+
def fptrauth_intrinsics : Flag<["-"], "fptrauth-intrinsics">,
4091+
HelpText<"Enable pointer-authentication intrinsics">;
4092+
def fptrauth_calls : Flag<["-"], "fptrauth-calls">,
4093+
HelpText<"Enable signing and authentication of all indirect calls">;
4094+
def fptrauth_returns : Flag<["-"], "fptrauth-returns">,
4095+
HelpText<"Enable signing and authentication of return addresses">;
4096+
def fptrauth_auth_traps : Flag<["-"], "fptrauth-auth-traps">,
4097+
HelpText<"Enable traps on authentication failures">;
4098+
def fptrauth_vtable_pointer_address_discrimination : Flag<["-"], "fptrauth-vtable-pointer-address-discrimination">,
4099+
HelpText<"Enable address discrimination of vtable pointers">;
4100+
def fptrauth_vtable_pointer_type_discrimination : Flag<["-"], "fptrauth-vtable-pointer-type-discrimination">,
4101+
HelpText<"Enable type discrimination of vtable pointers">;
4102+
def fptrauth_init_fini : Flag<["-"], "fptrauth-init-fini">,
4103+
HelpText<"Enable signing of function pointers in init/fini arrays">;
4104+
}
4105+
def fno_ptrauth_intrinsics : Flag<["-"], "fno-ptrauth-intrinsics">;
4106+
def fno_ptrauth_calls : Flag<["-"], "fno-ptrauth-calls">;
4107+
def fno_ptrauth_returns : Flag<["-"], "fno-ptrauth-returns">;
4108+
def fno_ptrauth_auth_traps : Flag<["-"], "fno-ptrauth-auth-traps">;
4109+
def fno_ptrauth_vtable_pointer_address_discrimination : Flag<["-"], "fno-ptrauth-vtable-pointer-address-discrimination">;
4110+
def fno_ptrauth_vtable_pointer_type_discrimination : Flag<["-"], "fno-ptrauth-vtable-pointer-type-discrimination">;
4111+
def fno_ptrauth_init_fini : Flag<["-"], "fno-ptrauth-init-fini">;
4112+
}
4113+
40884114
def fenable_matrix : Flag<["-"], "fenable-matrix">, Group<f_Group>,
40894115
Visibility<[ClangOption, CC1Option]>,
40904116
HelpText<"Enable matrix data type and related builtin functions">,

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7182,6 +7182,37 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
71827182
// -fno-common is the default, set -fcommon only when that flag is set.
71837183
Args.addOptInFlag(CmdArgs, options::OPT_fcommon, options::OPT_fno_common);
71847184

7185+
if (Args.hasFlag(options::OPT_fptrauth_intrinsics,
7186+
options::OPT_fno_ptrauth_intrinsics, false))
7187+
CmdArgs.push_back("-fptrauth-intrinsics");
7188+
7189+
if (Args.hasFlag(options::OPT_fptrauth_calls, options::OPT_fno_ptrauth_calls,
7190+
false))
7191+
CmdArgs.push_back("-fptrauth-calls");
7192+
7193+
if (Args.hasFlag(options::OPT_fptrauth_returns,
7194+
options::OPT_fno_ptrauth_returns, false))
7195+
CmdArgs.push_back("-fptrauth-returns");
7196+
7197+
if (Args.hasFlag(options::OPT_fptrauth_auth_traps,
7198+
options::OPT_fno_ptrauth_auth_traps, false))
7199+
CmdArgs.push_back("-fptrauth-auth-traps");
7200+
7201+
if (Args.hasFlag(
7202+
options::OPT_fptrauth_vtable_pointer_address_discrimination,
7203+
options::OPT_fno_ptrauth_vtable_pointer_address_discrimination,
7204+
false))
7205+
CmdArgs.push_back("-fptrauth-vtable-pointer-address-discrimination");
7206+
7207+
if (Args.hasFlag(options::OPT_fptrauth_vtable_pointer_type_discrimination,
7208+
options::OPT_fno_ptrauth_vtable_pointer_type_discrimination,
7209+
false))
7210+
CmdArgs.push_back("-fptrauth-vtable-pointer-type-discrimination");
7211+
7212+
if (Args.hasFlag(options::OPT_fptrauth_init_fini,
7213+
options::OPT_fno_ptrauth_init_fini, false))
7214+
CmdArgs.push_back("-fptrauth-init-fini");
7215+
71857216
// -fsigned-bitfields is default, and clang doesn't yet support
71867217
// -funsigned-bitfields.
71877218
if (!Args.hasFlag(options::OPT_fsigned_bitfields,

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3293,6 +3293,37 @@ static void ParseAPINotesArgs(APINotesOptions &Opts, ArgList &Args,
32933293
Opts.ModuleSearchPaths.push_back(A->getValue());
32943294
}
32953295

3296+
static void GeneratePointerAuthArgs(const LangOptions &Opts,
3297+
ArgumentConsumer Consumer) {
3298+
if (Opts.PointerAuthIntrinsics)
3299+
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);
3312+
}
3313+
3314+
static void ParsePointerAuthArgs(LangOptions &Opts, ArgList &Args,
3315+
DiagnosticsEngine &Diags) {
3316+
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);
3325+
}
3326+
32963327
/// Check if input file kind and language standard are compatible.
32973328
static bool IsInputCompatibleWithStandard(InputKind IK,
32983329
const LangStandard &S) {
@@ -4610,6 +4641,7 @@ bool CompilerInvocation::CreateFromArgsImpl(
46104641
llvm::Triple T(Res.getTargetOpts().Triple);
46114642
ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), Args, Diags,
46124643
Res.getFileSystemOpts().WorkingDir);
4644+
ParsePointerAuthArgs(LangOpts, Args, Diags);
46134645
ParseAPINotesArgs(Res.getAPINotesOpts(), Args, Diags);
46144646

46154647
ParseLangArgs(LangOpts, Args, DashX, T, Res.getPreprocessorOpts().Includes,
@@ -4841,6 +4873,7 @@ void CompilerInvocationBase::generateCC1CommandLine(
48414873
GenerateFrontendArgs(getFrontendOpts(), Consumer, getLangOpts().IsHeaderFile);
48424874
GenerateTargetArgs(getTargetOpts(), Consumer);
48434875
GenerateHeaderSearchArgs(getHeaderSearchOpts(), Consumer);
4876+
GeneratePointerAuthArgs(getLangOpts(), Consumer);
48444877
GenerateAPINotesArgs(getAPINotesOpts(), Consumer);
48454878
GenerateLangArgs(getLangOpts(), Consumer, T, getFrontendOpts().DashX);
48464879
GenerateCodeGenArgs(getCodeGenOpts(), Consumer, T,

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"

clang/test/Preprocessor/ptrauth.c

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
// RUN: %clang -E %s --target=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 -E %s --target=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 -E %s --target=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 -E %s --target=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 -E %s --target=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 -E %s --target=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 -E %s --target=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
57+
58+
#if __has_feature(ptrauth_intrinsics)
59+
// INTRIN: has_ptrauth_intrinsics
60+
void has_ptrauth_intrinsics() {}
61+
#else
62+
// NOINTRIN: no_ptrauth_intrinsics
63+
void no_ptrauth_intrinsics() {}
64+
#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)