Skip to content

Commit f06bc88

Browse files
committed
[PAC][Driver] Support pauthtest ABI for AArch64 Linux triples
When `pauthtest` is either passed as environment part of AArch64 Linux triple or passed via `-mabi=`, enable the following ptrauth flags: - `intrinsics`; - `calls`; - `returns`; - `auth-traps`; - `vtable-pointer-address-discrimination`; - `vtable-pointer-type-discrimination`; - `init-fini`. Some related stuff is still subject to change, and the ABI itself might be changed, so end users are not expected to use this and the ABI name has 'test' suffix. If `-mabi=pauthtest` option is used, it's normalized to effective triple. When the environment part of the effective triple is `pauthtest`, try to use `aarch64-linux-pauthtest` as multilib directory. The following is not supported: - combination of `pauthtest` ABI with any branch protection scheme except BTI; - explicit set of environment part of the triple to a value different from `pauthtest` in combination with `-mabi=pauthtest`; - usage on non-Linux OS.
1 parent a3dff30 commit f06bc88

File tree

19 files changed

+146
-52
lines changed

19 files changed

+146
-52
lines changed

clang/lib/Basic/Targets/AArch64.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,8 @@ AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple,
204204
StringRef AArch64TargetInfo::getABI() const { return ABI; }
205205

206206
bool AArch64TargetInfo::setABI(const std::string &Name) {
207-
if (Name != "aapcs" && Name != "aapcs-soft" && Name != "darwinpcs")
207+
if (Name != "aapcs" && Name != "aapcs-soft" && Name != "darwinpcs" &&
208+
Name != "pauthtest")
208209
return false;
209210

210211
ABI = Name;
@@ -218,6 +219,12 @@ bool AArch64TargetInfo::validateTarget(DiagnosticsEngine &Diags) const {
218219
Diags.Report(diag::err_target_unsupported_abi_with_fpu) << ABI;
219220
return false;
220221
}
222+
if (getTriple().getEnvironment() == llvm::Triple::PAuthTest &&
223+
getTriple().getOS() != llvm::Triple::Linux) {
224+
Diags.Report(diag::err_target_unsupported_abi_for_triple)
225+
<< getTriple().getEnvironmentName() << getTriple().getTriple();
226+
return false;
227+
}
221228
return true;
222229
}
223230

clang/lib/Basic/Targets/ARM.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,9 @@ ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
324324
case llvm::Triple::GNU:
325325
setABI("apcs-gnu");
326326
break;
327+
case llvm::Triple::PAuthTest:
328+
setABI("pauthtest");
329+
break;
327330
default:
328331
if (IsNetBSD)
329332
setABI("apcs-gnu");

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ createTargetCodeGenInfo(CodeGenModule &CGM) {
147147
return createWindowsAArch64TargetCodeGenInfo(CGM, AArch64ABIKind::Win64);
148148
else if (Target.getABI() == "aapcs-soft")
149149
Kind = AArch64ABIKind::AAPCSSoft;
150+
else if (Target.getABI() == "pauthtest")
151+
Kind = AArch64ABIKind::PAuthTest;
150152

151153
return createAArch64TargetCodeGenInfo(CGM, Kind);
152154
}

clang/lib/CodeGen/TargetInfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,7 @@ enum class AArch64ABIKind {
437437
DarwinPCS,
438438
Win64,
439439
AAPCSSoft,
440+
PAuthTest,
440441
};
441442

442443
std::unique_ptr<TargetCodeGenInfo>

clang/lib/Driver/ToolChain.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,11 +1031,12 @@ std::string ToolChain::ComputeLLVMTriple(const ArgList &Args,
10311031
}
10321032
case llvm::Triple::aarch64: {
10331033
llvm::Triple Triple = getTriple();
1034+
tools::aarch64::setPAuthABIInTriple(getDriver(), Args, Triple);
10341035
if (!Triple.isOSBinFormatMachO())
1035-
return getTripleString();
1036+
return Triple.getTriple();
10361037

10371038
if (Triple.isArm64e())
1038-
return getTripleString();
1039+
return Triple.getTriple();
10391040

10401041
// FIXME: older versions of ld64 expect the "arm64" component in the actual
10411042
// triple string and query it to determine whether an LTO file can be

clang/lib/Driver/ToolChains/Arch/AArch64.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,3 +449,24 @@ void aarch64::getAArch64TargetFeatures(const Driver &D,
449449
if (Args.getLastArg(options::OPT_mno_bti_at_return_twice))
450450
Features.push_back("+no-bti-at-return-twice");
451451
}
452+
453+
void aarch64::setPAuthABIInTriple(const Driver &D, const ArgList &Args,
454+
llvm::Triple &Triple) {
455+
Arg *ABIArg = Args.getLastArg(options::OPT_mabi_EQ);
456+
bool HasPAuthABI =
457+
ABIArg ? (StringRef(ABIArg->getValue()) == "pauthtest") : false;
458+
459+
switch (Triple.getEnvironment()) {
460+
case llvm::Triple::UnknownEnvironment:
461+
if (HasPAuthABI)
462+
Triple.setEnvironment(llvm::Triple::PAuthTest);
463+
break;
464+
case llvm::Triple::PAuthTest:
465+
break;
466+
default:
467+
if (HasPAuthABI)
468+
D.Diag(diag::err_drv_unsupported_opt_for_target)
469+
<< ABIArg->getAsString(Args) << Triple.getTriple();
470+
break;
471+
}
472+
}

clang/lib/Driver/ToolChains/Arch/AArch64.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ void getAArch64TargetFeatures(const Driver &D, const llvm::Triple &Triple,
2828
std::string getAArch64TargetCPU(const llvm::opt::ArgList &Args,
2929
const llvm::Triple &Triple, llvm::opt::Arg *&A);
3030

31+
void setPAuthABIInTriple(const Driver &D, const llvm::opt::ArgList &Args,
32+
llvm::Triple &triple);
33+
3134
} // end namespace aarch64
3235
} // end namespace target
3336
} // end namespace driver

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1487,8 +1487,7 @@ void AddUnalignedAccessWarning(ArgStringList &CmdArgs) {
14871487
// Each combination of options here forms a signing schema, and in most cases
14881488
// each signing schema is its own incompatible ABI. The default values of the
14891489
// options represent the default signing schema.
1490-
static void handlePAuthABIOption(const ArgList &DriverArgs,
1491-
ArgStringList &CC1Args) {
1490+
static void handlePAuthABI(const ArgList &DriverArgs, ArgStringList &CC1Args) {
14921491
if (!DriverArgs.hasArg(options::OPT_fptrauth_intrinsics,
14931492
options::OPT_fno_ptrauth_intrinsics))
14941493
CC1Args.push_back("-fptrauth-intrinsics");
@@ -1573,30 +1572,37 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args,
15731572
if (!isAArch64 && PBP.Key == "b_key")
15741573
D.Diag(diag::warn_unsupported_branch_protection)
15751574
<< "b-key" << A->getAsString(Args);
1576-
if (!isAArch64 && PBP.HasPauthABI)
1577-
D.Diag(diag::warn_unsupported_branch_protection)
1578-
<< "pauthabi" << A->getAsString(Args);
15791575
Scope = PBP.Scope;
15801576
Key = PBP.Key;
15811577
BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR;
15821578
IndirectBranches = PBP.BranchTargetEnforcement;
15831579
GuardedControlStack = PBP.GuardedControlStack;
1584-
if (isAArch64 && PBP.HasPauthABI)
1585-
handlePAuthABIOption(Args, CmdArgs);
15861580
}
15871581

15881582
CmdArgs.push_back(
15891583
Args.MakeArgString(Twine("-msign-return-address=") + Scope));
1590-
if (Scope != "none")
1584+
if (Scope != "none") {
1585+
if (Triple.getEnvironment() == llvm::Triple::PAuthTest)
1586+
D.Diag(diag::err_drv_unsupported_opt_for_target)
1587+
<< A->getAsString(Args) << Triple.getTriple();
15911588
CmdArgs.push_back(
15921589
Args.MakeArgString(Twine("-msign-return-address-key=") + Key));
1593-
if (BranchProtectionPAuthLR)
1590+
}
1591+
if (BranchProtectionPAuthLR) {
1592+
if (Triple.getEnvironment() == llvm::Triple::PAuthTest)
1593+
D.Diag(diag::err_drv_unsupported_opt_for_target)
1594+
<< A->getAsString(Args) << Triple.getTriple();
15941595
CmdArgs.push_back(
15951596
Args.MakeArgString(Twine("-mbranch-protection-pauth-lr")));
1597+
}
15961598
if (IndirectBranches)
15971599
CmdArgs.push_back("-mbranch-target-enforce");
1598-
if (GuardedControlStack)
1600+
if (GuardedControlStack) {
1601+
if (Triple.getEnvironment() == llvm::Triple::PAuthTest)
1602+
D.Diag(diag::err_drv_unsupported_opt_for_target)
1603+
<< A->getAsString(Args) << Triple.getTriple();
15991604
CmdArgs.push_back("-mguarded-control-stack");
1605+
}
16001606
}
16011607

16021608
void Clang::AddARMTargetArgs(const llvm::Triple &Triple, const ArgList &Args,
@@ -1740,6 +1746,8 @@ void RenderAArch64ABI(const llvm::Triple &Triple, const ArgList &Args,
17401746
ABIName = A->getValue();
17411747
else if (Triple.isOSDarwin())
17421748
ABIName = "darwinpcs";
1749+
else if (Triple.getEnvironment() == llvm::Triple::PAuthTest)
1750+
ABIName = "pauthtest";
17431751
else
17441752
ABIName = "aapcs";
17451753

@@ -1776,6 +1784,9 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args,
17761784
// Enable/disable return address signing and indirect branch targets.
17771785
CollectARMPACBTIOptions(getToolChain(), Args, CmdArgs, true /*isAArch64*/);
17781786

1787+
if (Triple.getEnvironment() == llvm::Triple::PAuthTest)
1788+
handlePAuthABI(Args, CmdArgs);
1789+
17791790
// Handle -msve_vector_bits=<bits>
17801791
if (Arg *A = Args.getLastArg(options::OPT_msve_vector_bits_EQ)) {
17811792
StringRef Val = A->getValue();

clang/lib/Driver/ToolChains/Linux.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ std::string Linux::getMultiarchTriple(const Driver &D,
8686
case llvm::Triple::aarch64:
8787
if (IsAndroid)
8888
return "aarch64-linux-android";
89+
if (hasEffectiveTriple() &&
90+
getEffectiveTriple().getEnvironment() == llvm::Triple::PAuthTest)
91+
return "aarch64-linux-pauthtest";
8992
return "aarch64-linux-gnu";
9093
case llvm::Triple::aarch64_be:
9194
return "aarch64_be-linux-gnu";

clang/test/Driver/Inputs/multilib_aarch64_linux_tree/usr/include/aarch64-linux-gnu/.keep

Whitespace-only changes.

0 commit comments

Comments
 (0)