Skip to content

Commit 49328b6

Browse files
committed
[AArch64][MachO] Support ptrauth ABI version.
This introduces additional meaning to some of the high bits in the mach-o header "flags" byte of the cpusubtype field. Quoting: // arm64 reserves bits in the high byte for subtype-specific flags. // On arm64e, the 6 low bits represent the ptrauth ABI version. CPU_SUBTYPE_ARM64E_PTRAUTH_MASK = 0x3f000000, // On arm64e, the top bit tells whether the Mach-O is versioned. CPU_SUBTYPE_ARM64E_VERSIONED_PTRAUTH_ABI_MASK = 0x80000000, // On arm64e, the 2nd high bit tells whether the Mach-O is using kernel ABI. CPU_SUBTYPE_ARM64E_KERNEL_PTRAUTH_ABI_MASK = 0x40000000 rdar://110506296
1 parent 78f2e02 commit 49328b6

File tree

56 files changed

+865
-20
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+865
-20
lines changed

clang/include/clang/Basic/LangOptions.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,10 @@ LANGOPT(PointerAuthReturns, 1, 0, "return pointer authentication")
164164
LANGOPT(PointerAuthIndirectGotos, 1, 0, "indirect gotos pointer authentication")
165165
LANGOPT(PointerAuthAuthTraps, 1, 0, "pointer authentication failure traps")
166166
LANGOPT(SoftPointerAuth , 1, 0, "software emulation of pointer authentication")
167+
VALUE_LANGOPT(PointerAuthABIVersion, 32, 0, "pointer authentication ABI version")
168+
LANGOPT(PointerAuthKernelABIVersion, 1, 0, "controls whether the pointer auth abi version represents a kernel ABI")
169+
LANGOPT(PointerAuthABIVersionEncoded, 1, 0, "controls whether the pointer auth abi version should be encoded in the IR")
170+
167171
LANGOPT(Unstable , 1, 0, "Enable unstable and experimental features")
168172
LANGOPT(ExperimentalLibrary, 1, 0, "enable unstable and experimental library features")
169173

clang/include/clang/Driver/Options.td

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3356,6 +3356,20 @@ let Group = f_Group in {
33563356
def fno_ptrauth_soft : Flag<["-"], "fno-ptrauth-soft">;
33573357
}
33583358

3359+
let Group = f_Group in {
3360+
def fptrauth_abi_version_EQ : Joined<["-"], "fptrauth-abi-version=">,
3361+
Flags<[CC1Option, CC1AsOption]>,
3362+
HelpText<"Pointer Authentication ABI version">;
3363+
def fno_ptrauth_abi_version : Flag<["-"], "fno-ptrauth-abi-version">,
3364+
HelpText<"Disable Pointer Authentication ABI versioning">;
3365+
3366+
def fptrauth_kernel_abi_version : Flag<["-"], "fptrauth-kernel-abi-version">,
3367+
Flags<[CC1Option, CC1AsOption]>,
3368+
HelpText<"Enable Pointer Authentication kernel ABI version">;
3369+
def fno_ptrauth_kernel_abi_version : Flag<["-"], "fno-ptrauth-kernel-abi-version">,
3370+
HelpText<"Disable Pointer Authentication kernel ABI versioning">;
3371+
}
3372+
33593373
def fenable_matrix : Flag<["-"], "fenable-matrix">, Group<f_Group>,
33603374
Flags<[CC1Option]>,
33613375
HelpText<"Enable matrix data type and related builtin functions">,

clang/lib/Basic/Targets/OSTargets.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
3434
if (Opts.PointerAuthIntrinsics)
3535
Builder.defineMacro("__PTRAUTH_INTRINSICS__");
3636

37+
if (Opts.PointerAuthABIVersionEncoded)
38+
Builder.defineMacro("__ptrauth_abi_version__",
39+
llvm::utostr(Opts.PointerAuthABIVersion));
40+
3741
// Darwin defines __weak, __strong, and __unsafe_unretained even in C mode.
3842
if (!Opts.ObjC) {
3943
// __weak is always defined, for use in blocks and with objc pointers.

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,6 +1121,11 @@ void CodeGenModule::Release() {
11211121
if (LangOpts.HLSL)
11221122
getHLSLRuntime().finishCodeGen();
11231123

1124+
if (LangOpts.PointerAuthABIVersionEncoded)
1125+
TheModule.setPtrAuthABIVersion(
1126+
{static_cast<int>(LangOpts.PointerAuthABIVersion),
1127+
static_cast<bool>(LangOpts.PointerAuthKernelABIVersion)});
1128+
11241129
if (uint32_t PLevel = Context.getLangOpts().PICLevel) {
11251130
assert(PLevel < 3 && "Invalid PIC Level");
11261131
getModule().setPICLevel(static_cast<llvm::PICLevel::Level>(PLevel));

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8183,6 +8183,46 @@ void ClangAs::AddRISCVTargetArgs(const ArgList &Args,
81838183
}
81848184
}
81858185

8186+
void ClangAs::AddAArch64TargetArgs(const ArgList &Args,
8187+
ArgStringList &CmdArgs) const {
8188+
const llvm::Triple &Triple = getToolChain().getTriple();
8189+
8190+
// In the assembler, arm64e support mostly consists of setting an ABI version.
8191+
// It also enables various preprocessor macros, but that's done before -cc1as.
8192+
if (Triple.isArm64e()) {
8193+
// The ptrauth ABI version is 0 by default, but can be overridden.
8194+
static const constexpr unsigned DefaultPtrauthABIVersion = 0;
8195+
8196+
unsigned PtrAuthABIVersion = DefaultPtrauthABIVersion;
8197+
const Arg *A = Args.getLastArg(options::OPT_fptrauth_abi_version_EQ,
8198+
options::OPT_fno_ptrauth_abi_version);
8199+
bool HasVersionArg =
8200+
A && A->getOption().matches(options::OPT_fptrauth_abi_version_EQ);
8201+
if (HasVersionArg) {
8202+
unsigned PtrAuthABIVersionArg;
8203+
if (StringRef(A->getValue()).getAsInteger(10, PtrAuthABIVersionArg))
8204+
getToolChain().getDriver().Diag(diag::err_drv_invalid_value)
8205+
<< A->getAsString(Args) << A->getValue();
8206+
else
8207+
PtrAuthABIVersion = PtrAuthABIVersionArg;
8208+
}
8209+
8210+
// Pass the ABI version to -cc1, regardless of its value, if the user asked
8211+
// for it or if the user didn't explicitly disable it.
8212+
if (HasVersionArg || !Args.hasArg(options::OPT_fno_ptrauth_abi_version)) {
8213+
CmdArgs.push_back(Args.MakeArgString("-fptrauth-abi-version=" +
8214+
llvm::utostr(PtrAuthABIVersion)));
8215+
8216+
// -f(no-)ptrauth-kernel-abi-version can override -mkernel and
8217+
// -fapple-kext
8218+
if (Args.hasArg(options::OPT_fptrauth_kernel_abi_version,
8219+
options::OPT_mkernel, options::OPT_fapple_kext) &&
8220+
!Args.hasArg(options::OPT_fno_ptrauth_kernel_abi_version))
8221+
CmdArgs.push_back("-fptrauth-kernel-abi-version");
8222+
}
8223+
}
8224+
}
8225+
81868226
void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
81878227
const InputInfo &Output, const InputInfoList &Inputs,
81888228
const ArgList &Args,
@@ -8364,6 +8404,7 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
83648404
CmdArgs.push_back("-mllvm");
83658405
CmdArgs.push_back("-aarch64-mark-bti-property");
83668406
}
8407+
AddAArch64TargetArgs(Args, CmdArgs);
83678408
break;
83688409

83698410
case llvm::Triple::loongarch32:

clang/lib/Driver/ToolChains/Clang.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ class LLVM_LIBRARY_VISIBILITY ClangAs : public Tool {
139139
llvm::opt::ArgStringList &CmdArgs) const;
140140
void AddRISCVTargetArgs(const llvm::opt::ArgList &Args,
141141
llvm::opt::ArgStringList &CmdArgs) const;
142+
void AddAArch64TargetArgs(const llvm::opt::ArgList &Args,
143+
llvm::opt::ArgStringList &CmdArgs) const;
142144
bool hasGoodDiagnostics() const override { return true; }
143145
bool hasIntegratedAssembler() const override { return false; }
144146
bool hasIntegratedCPP() const override { return false; }

clang/lib/Driver/ToolChains/Darwin.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1269,6 +1269,38 @@ void DarwinClang::addClangTargetOptions(
12691269
// On arm64e, enable pointer authentication (for the return address and
12701270
// indirect calls), as well as usage of the intrinsics.
12711271
if (getArchName() == "arm64e") {
1272+
// The ptrauth ABI version is 0 by default, but can be overridden.
1273+
static const constexpr unsigned DefaultPtrauthABIVersion = 0;
1274+
1275+
unsigned PtrAuthABIVersion = DefaultPtrauthABIVersion;
1276+
const Arg *A = DriverArgs.getLastArg(options::OPT_fptrauth_abi_version_EQ,
1277+
options::OPT_fno_ptrauth_abi_version);
1278+
bool HasVersionArg =
1279+
A && A->getOption().matches(options::OPT_fptrauth_abi_version_EQ);
1280+
if (HasVersionArg) {
1281+
unsigned PtrAuthABIVersionArg;
1282+
if (StringRef(A->getValue()).getAsInteger(10, PtrAuthABIVersionArg))
1283+
getDriver().Diag(diag::err_drv_invalid_value)
1284+
<< A->getAsString(DriverArgs) << A->getValue();
1285+
else
1286+
PtrAuthABIVersion = PtrAuthABIVersionArg;
1287+
}
1288+
1289+
// Pass the ABI version to -cc1, regardless of its value, if the user asked
1290+
// for it or if the user didn't explicitly disable it.
1291+
if (HasVersionArg ||
1292+
!DriverArgs.hasArg(options::OPT_fno_ptrauth_abi_version)) {
1293+
CC1Args.push_back(DriverArgs.MakeArgString(
1294+
"-fptrauth-abi-version=" + llvm::utostr(PtrAuthABIVersion)));
1295+
1296+
// -f(no-)ptrauth-kernel-abi-version can override -mkernel and
1297+
// -fapple-kext
1298+
if (DriverArgs.hasArg(options::OPT_fptrauth_kernel_abi_version,
1299+
options::OPT_mkernel, options::OPT_fapple_kext) &&
1300+
!DriverArgs.hasArg(options::OPT_fno_ptrauth_kernel_abi_version))
1301+
CC1Args.push_back("-fptrauth-kernel-abi-version");
1302+
}
1303+
12721304
if (!DriverArgs.hasArg(options::OPT_fptrauth_returns,
12731305
options::OPT_fno_ptrauth_returns))
12741306
CC1Args.push_back("-fptrauth-returns");

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3581,15 +3581,30 @@ static void GeneratePointerAuthArgs(LangOptions &Opts,
35813581
GenerateArg(Args, OPT_fptrauth_auth_traps, SA);
35823582
if (Opts.SoftPointerAuth)
35833583
GenerateArg(Args, OPT_fptrauth_soft, SA);
3584+
3585+
if (Opts.PointerAuthABIVersionEncoded) {
3586+
GenerateArg(Args, OPT_fptrauth_abi_version_EQ,
3587+
Twine(Opts.PointerAuthABIVersion), SA);
3588+
if (Opts.PointerAuthKernelABIVersion)
3589+
GenerateArg(Args, OPT_fptrauth_kernel_abi_version, SA);
3590+
}
35843591
}
35853592

3586-
static void ParsePointerAuthArgs(LangOptions &Opts, ArgList &Args) {
3593+
static void ParsePointerAuthArgs(LangOptions &Opts, ArgList &Args,
3594+
DiagnosticsEngine &Diags) {
35873595
Opts.PointerAuthIntrinsics = Args.hasArg(OPT_fptrauth_intrinsics);
35883596
Opts.PointerAuthCalls = Args.hasArg(OPT_fptrauth_calls);
35893597
Opts.PointerAuthReturns = Args.hasArg(OPT_fptrauth_returns);
35903598
Opts.PointerAuthIndirectGotos = Args.hasArg(OPT_fptrauth_indirect_gotos);
35913599
Opts.PointerAuthAuthTraps = Args.hasArg(OPT_fptrauth_auth_traps);
35923600
Opts.SoftPointerAuth = Args.hasArg(OPT_fptrauth_soft);
3601+
3602+
Opts.PointerAuthABIVersionEncoded =
3603+
Args.hasArg(OPT_fptrauth_abi_version_EQ) ||
3604+
Args.hasArg(OPT_fptrauth_kernel_abi_version);
3605+
Opts.PointerAuthABIVersion =
3606+
getLastArgIntValue(Args, OPT_fptrauth_abi_version_EQ, 0, Diags);
3607+
Opts.PointerAuthKernelABIVersion = Args.hasArg(OPT_fptrauth_kernel_abi_version);
35933608
}
35943609

35953610
/// Check if input file kind and language standard are compatible.
@@ -4835,7 +4850,7 @@ bool CompilerInvocation::CreateFromArgsImpl(
48354850
ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), Args, Diags,
48364851
Res.getFileSystemOpts().WorkingDir);
48374852
ParseAPINotesArgs(Res.getAPINotesOpts(), Args, Diags);
4838-
ParsePointerAuthArgs(LangOpts, Args);
4853+
ParsePointerAuthArgs(LangOpts, Args, Diags);
48394854

48404855
ParseLangArgs(LangOpts, Args, DashX, T, Res.getPreprocessorOpts().Includes,
48414856
Diags);
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: %clang_cc1 %s -triple arm64e-apple-ios -disable-llvm-passes -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-NONE
2+
// RUN: %clang_cc1 %s -fptrauth-kernel-abi-version -triple arm64e-apple-ios -disable-llvm-passes -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-WITH --check-prefix=CHECK-ZEROK
3+
// RUN: %clang_cc1 %s -fptrauth-abi-version=0 -triple arm64e-apple-ios -disable-llvm-passes -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-WITH --check-prefix=CHECK-ZERO
4+
// RUN: %clang_cc1 %s -fptrauth-abi-version=0 -fptrauth-kernel-abi-version -triple arm64e-apple-ios -disable-llvm-passes -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-WITH --check-prefix=CHECK-ZEROK
5+
// RUN: %clang_cc1 %s -fptrauth-abi-version=5 -triple arm64e-apple-ios -disable-llvm-passes -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-WITH --check-prefix=CHECK-FIVE
6+
// RUN: %clang_cc1 %s -fptrauth-abi-version=5 -fptrauth-kernel-abi-version -triple arm64e-apple-ios -disable-llvm-passes -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-WITH --check-prefix=CHECK-FIVEK
7+
8+
int f(void) {
9+
return 0;
10+
}
11+
// CHECK-NONE-NOT: ptrauth.abi-version
12+
// CHECK-WITH: !llvm.module.flags = !{{{.*}} ![[ABI_VERSION_REF:[0-9]+]]}
13+
// CHECK-WITH: ![[ABI_VERSION_REF]] = !{i32 6, !"ptrauth.abi-version", ![[ABI_VERSION_VAR:[0-9]+]]}
14+
// CHECK-WITH: ![[ABI_VERSION_VAR]] = !{![[ABI_VERSION_VAL:[0-9]+]]}
15+
// CHECK-ZERO: ![[ABI_VERSION_VAL]] = !{i32 0, i1 false}
16+
// CHECK-ZEROK: ![[ABI_VERSION_VAL]] = !{i32 0, i1 true}
17+
// CHECK-FIVE: ![[ABI_VERSION_VAL]] = !{i32 5, i1 false}
18+
// CHECK-FIVEK: ![[ABI_VERSION_VAL]] = !{i32 5, i1 true}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Check the ABI version support defaults.
2+
3+
// RUN: %clang -arch arm64e -c %s -### 2>&1 | FileCheck %s --check-prefix ABIVERSION-DEFAULT --check-prefix NOKERNELABIVERSION
4+
// RUN: %clang -mkernel -arch arm64e -c %s -### 2>&1 | FileCheck %s --check-prefix ABIVERSION-DEFAULT --check-prefix KERNELABIVERSION
5+
// RUN: %clang -fapple-kext -arch arm64e -c %s -### 2>&1 | FileCheck %s --check-prefix ABIVERSION-DEFAULT --check-prefix KERNELABIVERSION
6+
//
7+
// RUN: %clang -fno-ptrauth-kernel-abi-version -mkernel -arch arm64e -c %s -### 2>&1 | FileCheck %s --check-prefix ABIVERSION-DEFAULT --check-prefix NOKERNELABIVERSION
8+
// RUN: %clang -mkernel -fno-ptrauth-kernel-abi-version -arch arm64e -c %s -### 2>&1 | FileCheck %s --check-prefix ABIVERSION-DEFAULT --check-prefix NOKERNELABIVERSION
9+
// RUN: %clang -fno-ptrauth-kernel-abi-version -fapple-kext -arch arm64e -c %s -### 2>&1 | FileCheck %s --check-prefix ABIVERSION-DEFAULT --check-prefix NOKERNELABIVERSION
10+
// RUN: %clang -fapple-kext -fno-ptrauth-kernel-abi-version -arch arm64e -c %s -### 2>&1 | FileCheck %s --check-prefix ABIVERSION-DEFAULT --check-prefix NOKERNELABIVERSION
11+
// RUN: %clang -fno-ptrauth-kernel-abi-version -fptrauth-kernel-abi-version -arch arm64e -c %s -### 2>&1 | FileCheck %s --check-prefix ABIVERSION-DEFAULT --check-prefix NOKERNELABIVERSION
12+
// RUN: %clang -fptrauth-kernel-abi-version -fno-ptrauth-kernel-abi-version -arch arm64e -c %s -### 2>&1 | FileCheck %s --check-prefix ABIVERSION-DEFAULT --check-prefix NOKERNELABIVERSION
13+
//
14+
// ABIVERSION-DEFAULT: "-fptrauth-abi-version=0"
15+
// KERNELABIVERSION: "-fptrauth-kernel-abi-version"
16+
// NOKERNELABIVERSION-NOT: fptrauth-kernel-abi-version
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Check the ABI version support.
2+
3+
// RUN: %clang -fptrauth-abi-version=5 -arch arm64e -c %s -### 2>&1 | FileCheck %s --check-prefix ABIVERSION --check-prefix NOKERNELABIVERSION
4+
// RUN: %clang -fptrauth-abi-version=5 -mkernel -arch arm64e -c %s -### 2>&1 | FileCheck %s --check-prefix ABIVERSION --check-prefix KERNELABIVERSION
5+
// RUN: %clang -fptrauth-abi-version=5 -fapple-kext -arch arm64e -c %s -### 2>&1 | FileCheck %s --check-prefix ABIVERSION --check-prefix KERNELABIVERSION
6+
// RUN: %clang -fptrauth-abi-version=5 -fptrauth-kernel-abi-version -arch arm64e -c %s -### 2>&1 | FileCheck %s --check-prefix ABIVERSION --check-prefix KERNELABIVERSION
7+
8+
// RUN: %clang -fno-ptrauth-abi-version -arch arm64e -c %s -### 2>&1 | FileCheck %s --check-prefix NOABIVERSION --check-prefix NOKERNELABIVERSION
9+
// RUN: %clang -fptrauth-abi-version=5 -fno-ptrauth-abi-version -arch arm64e -c %s -### 2>&1 | FileCheck %s --check-prefix NOABIVERSION --check-prefix NOKERNELABIVERSION
10+
// RUN: %clang -fno-ptrauth-abi-version -fptrauth-abi-version=5 -arch arm64e -c %s -### 2>&1 | FileCheck %s --check-prefix ABIVERSION --check-prefix NOKERNELABIVERSION
11+
12+
// ABIVERSION: "-fptrauth-abi-version=5"
13+
// ABIVERSION-DEFAULT: "-fptrauth-abi-version=0"
14+
// NOABIVERSION-NOT: fptrauth-abi-version
15+
// KERNELABIVERSION: "-fptrauth-kernel-abi-version"
16+
// NOKERNELABIVERSION-NOT: fptrauth-kernel-abi-version
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// RUN: %clang_cc1 -E -dM -ffreestanding -triple=arm64e-apple-ios < /dev/null | FileCheck %s --check-prefix=NONE
2+
// RUN: %clang_cc1 -E -dM -ffreestanding -triple=arm64e-apple-ios -fptrauth-abi-version=0 < /dev/null | FileCheck %s --check-prefix=ZERO
3+
// RUN: %clang_cc1 -E -dM -ffreestanding -triple=arm64e-apple-ios -fptrauth-kernel-abi-version < /dev/null | FileCheck %s --check-prefix=ZERO
4+
// RUN: %clang_cc1 -E -dM -ffreestanding -triple=arm64e-apple-ios -fptrauth-abi-version=5 < /dev/null | FileCheck %s --check-prefix=FIVE
5+
6+
// ZERO: #define __ptrauth_abi_version__ 0
7+
// FIVE: #define __ptrauth_abi_version__ 5
8+
// NONE-NOT: __ptrauth_abi_version__

clang/tools/driver/cc1as_main.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,13 @@ struct AssemblerInvocation {
162162
/// compilation
163163
llvm::VersionTuple DarwinTargetVariantSDKVersion;
164164

165+
/// The ptrauth ABI version targeted by the backend.
166+
unsigned PointerAuthABIVersion;
167+
/// Whether the ptrauth ABI version represents a kernel ABI.
168+
unsigned PointerAuthKernelABIVersion : 1;
169+
/// Whether the assembler should encode the ptrauth ABI version.
170+
unsigned PointerAuthABIVersionEncoded : 1;
171+
165172
/// The name of a file to use with \c .secure_log_unique directives.
166173
std::string AsSecureLogFile;
167174
/// @}
@@ -336,6 +343,14 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
336343
Args.hasArg(OPT_mincremental_linker_compatible);
337344
Opts.SymbolDefs = Args.getAllArgValues(OPT_defsym);
338345

346+
Opts.PointerAuthABIVersionEncoded =
347+
Args.hasArg(OPT_fptrauth_abi_version_EQ) ||
348+
Args.hasArg(OPT_fptrauth_kernel_abi_version);
349+
Opts.PointerAuthABIVersion =
350+
getLastArgIntValue(Args, OPT_fptrauth_abi_version_EQ, 0, Diags);
351+
Opts.PointerAuthKernelABIVersion =
352+
Args.hasArg(OPT_fptrauth_kernel_abi_version);
353+
339354
// EmbedBitcode Option. If -fembed-bitcode is enabled, set the flag.
340355
// EmbedBitcode behaves the same for all embed options for assembly files.
341356
if (auto *A = Args.getLastArg(OPT_fembed_bitcode_EQ)) {
@@ -561,6 +576,11 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
561576
// Assembly to object compilation should leverage assembly info.
562577
Str->setUseAssemblerInfoForParsing(true);
563578

579+
// Emit the ptrauth ABI version, if any.
580+
if (Opts.PointerAuthABIVersionEncoded)
581+
Str->EmitPtrAuthABIVersion(Opts.PointerAuthABIVersion,
582+
Opts.PointerAuthKernelABIVersion);
583+
564584
bool Failed = false;
565585

566586
std::unique_ptr<MCAsmParser> Parser(

llvm/docs/LangRef.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7821,6 +7821,11 @@ stored at::
78217821
!llvm.embedded.objects = !{!0}
78227822
!0 = !{ptr @object, !".section"}
78237823

7824+
Pointer Authentication ABI Version Module Flags Metadata
7825+
--------------------------------------------------------
7826+
7827+
FIXME: write about abi version, maybe?
7828+
78247829
Automatic Linker Flags Named Metadata
78257830
=====================================
78267831

llvm/include/llvm/BinaryFormat/MachO.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1641,8 +1641,39 @@ enum CPUSubTypeARM64 {
16411641
CPU_SUBTYPE_ARM64_ALL = 0,
16421642
CPU_SUBTYPE_ARM64_V8 = 1,
16431643
CPU_SUBTYPE_ARM64E = 2,
1644+
1645+
// arm64 reserves bits in the high byte for subtype-specific flags.
1646+
// On arm64e, the 6 low bits represent the ptrauth ABI version.
1647+
CPU_SUBTYPE_ARM64E_PTRAUTH_MASK = 0x3f000000,
1648+
// On arm64e, the top bit tells whether the Mach-O is versioned.
1649+
CPU_SUBTYPE_ARM64E_VERSIONED_PTRAUTH_ABI_MASK = 0x80000000,
1650+
// On arm64e, the 2nd high bit tells whether the Mach-O is using kernel ABI.
1651+
CPU_SUBTYPE_ARM64E_KERNEL_PTRAUTH_ABI_MASK = 0x40000000
16441652
};
16451653

1654+
inline int CPU_SUBTYPE_ARM64E_PTRAUTH_VERSION(unsigned ST) {
1655+
return (ST & CPU_SUBTYPE_ARM64E_PTRAUTH_MASK) >> 24;
1656+
}
1657+
1658+
inline unsigned
1659+
CPU_SUBTYPE_ARM64E_WITH_PTRAUTH_VERSION(unsigned PtrAuthABIVersion,
1660+
bool PtrAuthKernelABIVersion) {
1661+
assert((PtrAuthABIVersion <= 0x3F) &&
1662+
"ptrauth abi version must fit in 6 bits");
1663+
return CPU_SUBTYPE_ARM64E | CPU_SUBTYPE_ARM64E_VERSIONED_PTRAUTH_ABI_MASK |
1664+
(PtrAuthKernelABIVersion ? CPU_SUBTYPE_ARM64E_KERNEL_PTRAUTH_ABI_MASK
1665+
: 0) |
1666+
(PtrAuthABIVersion << 24);
1667+
}
1668+
1669+
inline unsigned CPU_SUBTYPE_ARM64E_IS_VERSIONED_PTRAUTH_ABI(unsigned ST) {
1670+
return ST & CPU_SUBTYPE_ARM64E_VERSIONED_PTRAUTH_ABI_MASK;
1671+
}
1672+
1673+
inline unsigned CPU_SUBTYPE_ARM64E_IS_KERNEL_PTRAUTH_ABI(unsigned ST) {
1674+
return ST & CPU_SUBTYPE_ARM64E_KERNEL_PTRAUTH_ABI_MASK;
1675+
}
1676+
16461677
enum CPUSubTypeARM64_32 { CPU_SUBTYPE_ARM64_32_V8 = 1 };
16471678

16481679
enum CPUSubTypeSPARC { CPU_SUBTYPE_SPARC_ALL = 0 };
@@ -1668,6 +1699,8 @@ enum CPUSubTypePowerPC {
16681699

16691700
Expected<uint32_t> getCPUType(const Triple &T);
16701701
Expected<uint32_t> getCPUSubType(const Triple &T);
1702+
Expected<uint32_t> getCPUSubType(const Triple &T, unsigned PtrAuthABIVersion,
1703+
bool PtrAuthKernelABIVersion);
16711704

16721705
struct x86_thread_state32_t {
16731706
uint32_t eax;

0 commit comments

Comments
 (0)