Skip to content

[5.9] [AArch64][MachO] Support ptrauth ABI version. #7055

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions clang/include/clang/Basic/LangOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,10 @@ LANGOPT(PointerAuthReturns, 1, 0, "return pointer authentication")
LANGOPT(PointerAuthIndirectGotos, 1, 0, "indirect gotos pointer authentication")
LANGOPT(PointerAuthAuthTraps, 1, 0, "pointer authentication failure traps")
LANGOPT(SoftPointerAuth , 1, 0, "software emulation of pointer authentication")
VALUE_LANGOPT(PointerAuthABIVersion, 32, 0, "pointer authentication ABI version")
LANGOPT(PointerAuthKernelABIVersion, 1, 0, "controls whether the pointer auth abi version represents a kernel ABI")
LANGOPT(PointerAuthABIVersionEncoded, 1, 0, "controls whether the pointer auth abi version should be encoded in the IR")

LANGOPT(Unstable , 1, 0, "Enable unstable and experimental features")
LANGOPT(ExperimentalLibrary, 1, 0, "enable unstable and experimental library features")

Expand Down
14 changes: 14 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -3150,6 +3150,20 @@ let Group = f_Group in {
def fno_ptrauth_soft : Flag<["-"], "fno-ptrauth-soft">;
}

let Group = f_Group in {
def fptrauth_abi_version_EQ : Joined<["-"], "fptrauth-abi-version=">,
Flags<[CC1Option, CC1AsOption]>,
HelpText<"Pointer Authentication ABI version">;
def fno_ptrauth_abi_version : Flag<["-"], "fno-ptrauth-abi-version">,
HelpText<"Disable Pointer Authentication ABI versioning">;

def fptrauth_kernel_abi_version : Flag<["-"], "fptrauth-kernel-abi-version">,
Flags<[CC1Option, CC1AsOption]>,
HelpText<"Enable Pointer Authentication kernel ABI version">;
def fno_ptrauth_kernel_abi_version : Flag<["-"], "fno-ptrauth-kernel-abi-version">,
HelpText<"Disable Pointer Authentication kernel ABI versioning">;
}

def fenable_matrix : Flag<["-"], "fenable-matrix">, Group<f_Group>,
Flags<[CC1Option]>,
HelpText<"Enable matrix data type and related builtin functions">,
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Basic/Targets/OSTargets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
if (Opts.PointerAuthIntrinsics)
Builder.defineMacro("__PTRAUTH_INTRINSICS__");

if (Opts.PointerAuthABIVersionEncoded)
Builder.defineMacro("__ptrauth_abi_version__",
llvm::utostr(Opts.PointerAuthABIVersion));

// Darwin defines __weak, __strong, and __unsafe_unretained even in C mode.
if (!Opts.ObjC) {
// __weak is always defined, for use in blocks and with objc pointers.
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -863,6 +863,11 @@ void CodeGenModule::Release() {
if (LangOpts.HLSL)
getHLSLRuntime().finishCodeGen();

if (LangOpts.PointerAuthABIVersionEncoded)
TheModule.setPtrAuthABIVersion(
{static_cast<int>(LangOpts.PointerAuthABIVersion),
static_cast<bool>(LangOpts.PointerAuthKernelABIVersion)});

if (uint32_t PLevel = Context.getLangOpts().PICLevel) {
assert(PLevel < 3 && "Invalid PIC Level");
getModule().setPICLevel(static_cast<llvm::PICLevel::Level>(PLevel));
Expand Down
41 changes: 41 additions & 0 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8106,6 +8106,46 @@ void ClangAs::AddRISCVTargetArgs(const ArgList &Args,
CmdArgs.push_back(ABIName.data());
}

void ClangAs::AddAArch64TargetArgs(const ArgList &Args,
ArgStringList &CmdArgs) const {
const llvm::Triple &Triple = getToolChain().getTriple();

// In the assembler, arm64e support mostly consists of setting an ABI version.
// It also enables various preprocessor macros, but that's done before -cc1as.
if (Triple.isArm64e()) {
// The ptrauth ABI version is 0 by default, but can be overridden.
static const constexpr unsigned DefaultPtrauthABIVersion = 0;

unsigned PtrAuthABIVersion = DefaultPtrauthABIVersion;
const Arg *A = Args.getLastArg(options::OPT_fptrauth_abi_version_EQ,
options::OPT_fno_ptrauth_abi_version);
bool HasVersionArg =
A && A->getOption().matches(options::OPT_fptrauth_abi_version_EQ);
if (HasVersionArg) {
unsigned PtrAuthABIVersionArg;
if (StringRef(A->getValue()).getAsInteger(10, PtrAuthABIVersionArg))
getToolChain().getDriver().Diag(diag::err_drv_invalid_value)
<< A->getAsString(Args) << A->getValue();
else
PtrAuthABIVersion = PtrAuthABIVersionArg;
}

// Pass the ABI version to -cc1, regardless of its value, if the user asked
// for it or if the user didn't explicitly disable it.
if (HasVersionArg || !Args.hasArg(options::OPT_fno_ptrauth_abi_version)) {
CmdArgs.push_back(Args.MakeArgString("-fptrauth-abi-version=" +
llvm::utostr(PtrAuthABIVersion)));

// -f(no-)ptrauth-kernel-abi-version can override -mkernel and
// -fapple-kext
if (Args.hasArg(options::OPT_fptrauth_kernel_abi_version,
options::OPT_mkernel, options::OPT_fapple_kext) &&
!Args.hasArg(options::OPT_fno_ptrauth_kernel_abi_version))
CmdArgs.push_back("-fptrauth-kernel-abi-version");
}
}
}

void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output, const InputInfoList &Inputs,
const ArgList &Args,
Expand Down Expand Up @@ -8296,6 +8336,7 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-mllvm");
CmdArgs.push_back("-aarch64-mark-bti-property");
}
AddAArch64TargetArgs(Args, CmdArgs);
break;

case llvm::Triple::riscv32:
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/Driver/ToolChains/Clang.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ class LLVM_LIBRARY_VISIBILITY ClangAs : public Tool {
llvm::opt::ArgStringList &CmdArgs) const;
void AddRISCVTargetArgs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const;
void AddAArch64TargetArgs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const;
bool hasGoodDiagnostics() const override { return true; }
bool hasIntegratedAssembler() const override { return false; }
bool hasIntegratedCPP() const override { return false; }
Expand Down
32 changes: 32 additions & 0 deletions clang/lib/Driver/ToolChains/Darwin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1244,6 +1244,38 @@ void DarwinClang::addClangTargetOptions(
// On arm64e, enable pointer authentication (for the return address and
// indirect calls), as well as usage of the intrinsics.
if (getArchName() == "arm64e") {
// The ptrauth ABI version is 0 by default, but can be overridden.
static const constexpr unsigned DefaultPtrauthABIVersion = 0;

unsigned PtrAuthABIVersion = DefaultPtrauthABIVersion;
const Arg *A = DriverArgs.getLastArg(options::OPT_fptrauth_abi_version_EQ,
options::OPT_fno_ptrauth_abi_version);
bool HasVersionArg =
A && A->getOption().matches(options::OPT_fptrauth_abi_version_EQ);
if (HasVersionArg) {
unsigned PtrAuthABIVersionArg;
if (StringRef(A->getValue()).getAsInteger(10, PtrAuthABIVersionArg))
getDriver().Diag(diag::err_drv_invalid_value)
<< A->getAsString(DriverArgs) << A->getValue();
else
PtrAuthABIVersion = PtrAuthABIVersionArg;
}

// Pass the ABI version to -cc1, regardless of its value, if the user asked
// for it or if the user didn't explicitly disable it.
if (HasVersionArg ||
!DriverArgs.hasArg(options::OPT_fno_ptrauth_abi_version)) {
CC1Args.push_back(DriverArgs.MakeArgString(
"-fptrauth-abi-version=" + llvm::utostr(PtrAuthABIVersion)));

// -f(no-)ptrauth-kernel-abi-version can override -mkernel and
// -fapple-kext
if (DriverArgs.hasArg(options::OPT_fptrauth_kernel_abi_version,
options::OPT_mkernel, options::OPT_fapple_kext) &&
!DriverArgs.hasArg(options::OPT_fno_ptrauth_kernel_abi_version))
CC1Args.push_back("-fptrauth-kernel-abi-version");
}

if (!DriverArgs.hasArg(options::OPT_fptrauth_returns,
options::OPT_fno_ptrauth_returns))
CC1Args.push_back("-fptrauth-returns");
Expand Down
19 changes: 17 additions & 2 deletions clang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3655,15 +3655,30 @@ static void GeneratePointerAuthArgs(LangOptions &Opts,
GenerateArg(Args, OPT_fptrauth_auth_traps, SA);
if (Opts.SoftPointerAuth)
GenerateArg(Args, OPT_fptrauth_soft, SA);

if (Opts.PointerAuthABIVersionEncoded) {
GenerateArg(Args, OPT_fptrauth_abi_version_EQ,
Twine(Opts.PointerAuthABIVersion), SA);
if (Opts.PointerAuthKernelABIVersion)
GenerateArg(Args, OPT_fptrauth_kernel_abi_version, SA);
}
}

static void ParsePointerAuthArgs(LangOptions &Opts, ArgList &Args) {
static void ParsePointerAuthArgs(LangOptions &Opts, ArgList &Args,
DiagnosticsEngine &Diags) {
Opts.PointerAuthIntrinsics = Args.hasArg(OPT_fptrauth_intrinsics);
Opts.PointerAuthCalls = Args.hasArg(OPT_fptrauth_calls);
Opts.PointerAuthReturns = Args.hasArg(OPT_fptrauth_returns);
Opts.PointerAuthIndirectGotos = Args.hasArg(OPT_fptrauth_indirect_gotos);
Opts.PointerAuthAuthTraps = Args.hasArg(OPT_fptrauth_auth_traps);
Opts.SoftPointerAuth = Args.hasArg(OPT_fptrauth_soft);

Opts.PointerAuthABIVersionEncoded =
Args.hasArg(OPT_fptrauth_abi_version_EQ) ||
Args.hasArg(OPT_fptrauth_kernel_abi_version);
Opts.PointerAuthABIVersion =
getLastArgIntValue(Args, OPT_fptrauth_abi_version_EQ, 0, Diags);
Opts.PointerAuthKernelABIVersion = Args.hasArg(OPT_fptrauth_kernel_abi_version);
}

/// Check if input file kind and language standard are compatible.
Expand Down Expand Up @@ -4958,7 +4973,7 @@ bool CompilerInvocation::CreateFromArgsImpl(
ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), Args, Diags,
Res.getFileSystemOpts().WorkingDir);
ParseAPINotesArgs(Res.getAPINotesOpts(), Args, Diags);
ParsePointerAuthArgs(LangOpts, Args);
ParsePointerAuthArgs(LangOpts, Args, Diags);

ParseLangArgs(LangOpts, Args, DashX, T, Res.getPreprocessorOpts().Includes,
Diags);
Expand Down
18 changes: 18 additions & 0 deletions clang/test/CodeGen/ptrauth-abi-version.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// RUN: %clang_cc1 %s -triple arm64e-apple-ios -disable-llvm-passes -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-NONE
// 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
// 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
// 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
// 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
// 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

int f(void) {
return 0;
}
// CHECK-NONE-NOT: ptrauth.abi-version
// CHECK-WITH: !llvm.module.flags = !{{{.*}} ![[ABI_VERSION_REF:[0-9]+]]}
// CHECK-WITH: ![[ABI_VERSION_REF]] = !{i32 6, !"ptrauth.abi-version", ![[ABI_VERSION_VAR:[0-9]+]]}
// CHECK-WITH: ![[ABI_VERSION_VAR]] = !{![[ABI_VERSION_VAL:[0-9]+]]}
// CHECK-ZERO: ![[ABI_VERSION_VAL]] = !{i32 0, i1 false}
// CHECK-ZEROK: ![[ABI_VERSION_VAL]] = !{i32 0, i1 true}
// CHECK-FIVE: ![[ABI_VERSION_VAL]] = !{i32 5, i1 false}
// CHECK-FIVEK: ![[ABI_VERSION_VAL]] = !{i32 5, i1 true}
16 changes: 16 additions & 0 deletions clang/test/Driver/arch-arm64e-abi-versioning-defaults.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Check the ABI version support defaults.

// RUN: %clang -arch arm64e -c %s -### 2>&1 | FileCheck %s --check-prefix ABIVERSION-DEFAULT --check-prefix NOKERNELABIVERSION
// RUN: %clang -mkernel -arch arm64e -c %s -### 2>&1 | FileCheck %s --check-prefix ABIVERSION-DEFAULT --check-prefix KERNELABIVERSION
// RUN: %clang -fapple-kext -arch arm64e -c %s -### 2>&1 | FileCheck %s --check-prefix ABIVERSION-DEFAULT --check-prefix KERNELABIVERSION
//
// RUN: %clang -fno-ptrauth-kernel-abi-version -mkernel -arch arm64e -c %s -### 2>&1 | FileCheck %s --check-prefix ABIVERSION-DEFAULT --check-prefix NOKERNELABIVERSION
// RUN: %clang -mkernel -fno-ptrauth-kernel-abi-version -arch arm64e -c %s -### 2>&1 | FileCheck %s --check-prefix ABIVERSION-DEFAULT --check-prefix NOKERNELABIVERSION
// RUN: %clang -fno-ptrauth-kernel-abi-version -fapple-kext -arch arm64e -c %s -### 2>&1 | FileCheck %s --check-prefix ABIVERSION-DEFAULT --check-prefix NOKERNELABIVERSION
// RUN: %clang -fapple-kext -fno-ptrauth-kernel-abi-version -arch arm64e -c %s -### 2>&1 | FileCheck %s --check-prefix ABIVERSION-DEFAULT --check-prefix NOKERNELABIVERSION
// 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
// 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
//
// ABIVERSION-DEFAULT: "-fptrauth-abi-version=0"
// KERNELABIVERSION: "-fptrauth-kernel-abi-version"
// NOKERNELABIVERSION-NOT: fptrauth-kernel-abi-version
16 changes: 16 additions & 0 deletions clang/test/Driver/arch-arm64e-abi-versioning.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Check the ABI version support.

// RUN: %clang -fptrauth-abi-version=5 -arch arm64e -c %s -### 2>&1 | FileCheck %s --check-prefix ABIVERSION --check-prefix NOKERNELABIVERSION

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ahmedbougacha This test and the defaults version above are failing on Linux:

warning: argument unused during compilation: '-fptrauth-abi-version=5' [-Wunused-command-line-argument]
warning: argument unused during compilation: '-arch arm64e' [-Wunused-command-line-argument]

The -arch flag seems to be Darwin specific: https://github.com/apple/llvm-project/blob/next/clang/docs/CommandGuide/clang.rst, and at a glance the new ptrauth ABI related flags are also only used on Darwin.

Can we gate these tests behind a REQUIRES: system-darwin or otherwise fix them?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep! Removed -arch in favor of -target in:
#7071
#7072

// RUN: %clang -fptrauth-abi-version=5 -mkernel -arch arm64e -c %s -### 2>&1 | FileCheck %s --check-prefix ABIVERSION --check-prefix KERNELABIVERSION
// RUN: %clang -fptrauth-abi-version=5 -fapple-kext -arch arm64e -c %s -### 2>&1 | FileCheck %s --check-prefix ABIVERSION --check-prefix KERNELABIVERSION
// RUN: %clang -fptrauth-abi-version=5 -fptrauth-kernel-abi-version -arch arm64e -c %s -### 2>&1 | FileCheck %s --check-prefix ABIVERSION --check-prefix KERNELABIVERSION

// RUN: %clang -fno-ptrauth-abi-version -arch arm64e -c %s -### 2>&1 | FileCheck %s --check-prefix NOABIVERSION --check-prefix NOKERNELABIVERSION
// RUN: %clang -fptrauth-abi-version=5 -fno-ptrauth-abi-version -arch arm64e -c %s -### 2>&1 | FileCheck %s --check-prefix NOABIVERSION --check-prefix NOKERNELABIVERSION
// RUN: %clang -fno-ptrauth-abi-version -fptrauth-abi-version=5 -arch arm64e -c %s -### 2>&1 | FileCheck %s --check-prefix ABIVERSION --check-prefix NOKERNELABIVERSION

// ABIVERSION: "-fptrauth-abi-version=5"
// ABIVERSION-DEFAULT: "-fptrauth-abi-version=0"
// NOABIVERSION-NOT: fptrauth-abi-version
// KERNELABIVERSION: "-fptrauth-kernel-abi-version"
// NOKERNELABIVERSION-NOT: fptrauth-kernel-abi-version
8 changes: 8 additions & 0 deletions clang/test/Preprocessor/ptrauth_abi_version.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// RUN: %clang_cc1 -E -dM -ffreestanding -triple=arm64e-apple-ios < /dev/null | FileCheck %s --check-prefix=NONE
// RUN: %clang_cc1 -E -dM -ffreestanding -triple=arm64e-apple-ios -fptrauth-abi-version=0 < /dev/null | FileCheck %s --check-prefix=ZERO
// RUN: %clang_cc1 -E -dM -ffreestanding -triple=arm64e-apple-ios -fptrauth-kernel-abi-version < /dev/null | FileCheck %s --check-prefix=ZERO
// RUN: %clang_cc1 -E -dM -ffreestanding -triple=arm64e-apple-ios -fptrauth-abi-version=5 < /dev/null | FileCheck %s --check-prefix=FIVE

// ZERO: #define __ptrauth_abi_version__ 0
// FIVE: #define __ptrauth_abi_version__ 5
// NONE-NOT: __ptrauth_abi_version__
20 changes: 20 additions & 0 deletions clang/tools/driver/cc1as_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,13 @@ struct AssemblerInvocation {
/// for which the code is being compiled.
llvm::Optional<llvm::Triple> DarwinTargetVariantTriple;

/// The ptrauth ABI version targeted by the backend.
unsigned PointerAuthABIVersion;
/// Whether the ptrauth ABI version represents a kernel ABI.
unsigned PointerAuthKernelABIVersion : 1;
/// Whether the assembler should encode the ptrauth ABI version.
unsigned PointerAuthABIVersionEncoded : 1;

/// The name of a file to use with \c .secure_log_unique directives.
std::string AsSecureLogFile;
/// @}
Expand Down Expand Up @@ -318,6 +325,14 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
Args.hasArg(OPT_mincremental_linker_compatible);
Opts.SymbolDefs = Args.getAllArgValues(OPT_defsym);

Opts.PointerAuthABIVersionEncoded =
Args.hasArg(OPT_fptrauth_abi_version_EQ) ||
Args.hasArg(OPT_fptrauth_kernel_abi_version);
Opts.PointerAuthABIVersion =
getLastArgIntValue(Args, OPT_fptrauth_abi_version_EQ, 0, Diags);
Opts.PointerAuthKernelABIVersion =
Args.hasArg(OPT_fptrauth_kernel_abi_version);

// EmbedBitcode Option. If -fembed-bitcode is enabled, set the flag.
// EmbedBitcode behaves the same for all embed options for assembly files.
if (auto *A = Args.getLastArg(OPT_fembed_bitcode_EQ)) {
Expand Down Expand Up @@ -537,6 +552,11 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
// Assembly to object compilation should leverage assembly info.
Str->setUseAssemblerInfoForParsing(true);

// Emit the ptrauth ABI version, if any.
if (Opts.PointerAuthABIVersionEncoded)
Str->EmitPtrAuthABIVersion(Opts.PointerAuthABIVersion,
Opts.PointerAuthKernelABIVersion);

bool Failed = false;

std::unique_ptr<MCAsmParser> Parser(
Expand Down
5 changes: 5 additions & 0 deletions llvm/docs/LangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7516,6 +7516,11 @@ stored at::
!llvm.embedded.objects = !{!0}
!0 = !{ptr @object, !".section"}

Pointer Authentication ABI Version Module Flags Metadata
--------------------------------------------------------

FIXME: write about abi version, maybe?

Automatic Linker Flags Named Metadata
=====================================

Expand Down
33 changes: 33 additions & 0 deletions llvm/include/llvm/BinaryFormat/MachO.h
Original file line number Diff line number Diff line change
Expand Up @@ -1641,8 +1641,39 @@ enum CPUSubTypeARM64 {
CPU_SUBTYPE_ARM64_ALL = 0,
CPU_SUBTYPE_ARM64_V8 = 1,
CPU_SUBTYPE_ARM64E = 2,

// 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
};

inline int CPU_SUBTYPE_ARM64E_PTRAUTH_VERSION(unsigned ST) {
return (ST & CPU_SUBTYPE_ARM64E_PTRAUTH_MASK) >> 24;
}

inline unsigned
CPU_SUBTYPE_ARM64E_WITH_PTRAUTH_VERSION(unsigned PtrAuthABIVersion,
bool PtrAuthKernelABIVersion) {
assert((PtrAuthABIVersion <= 0x3F) &&
"ptrauth abi version must fit in 6 bits");
return CPU_SUBTYPE_ARM64E | CPU_SUBTYPE_ARM64E_VERSIONED_PTRAUTH_ABI_MASK |
(PtrAuthKernelABIVersion ? CPU_SUBTYPE_ARM64E_KERNEL_PTRAUTH_ABI_MASK
: 0) |
(PtrAuthABIVersion << 24);
}

inline unsigned CPU_SUBTYPE_ARM64E_IS_VERSIONED_PTRAUTH_ABI(unsigned ST) {
return ST & CPU_SUBTYPE_ARM64E_VERSIONED_PTRAUTH_ABI_MASK;
}

inline unsigned CPU_SUBTYPE_ARM64E_IS_KERNEL_PTRAUTH_ABI(unsigned ST) {
return ST & CPU_SUBTYPE_ARM64E_KERNEL_PTRAUTH_ABI_MASK;
}

enum CPUSubTypeARM64_32 { CPU_SUBTYPE_ARM64_32_V8 = 1 };

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

Expected<uint32_t> getCPUType(const Triple &T);
Expected<uint32_t> getCPUSubType(const Triple &T);
Expected<uint32_t> getCPUSubType(const Triple &T, unsigned PtrAuthABIVersion,
bool PtrAuthKernelABIVersion);

struct x86_thread_state32_t {
uint32_t eax;
Expand Down
Loading