-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
[PAC][Driver] Support pauthtest
ABI for AArch64 Linux triples
#97237
Conversation
Enable the following ptrauth flags when `pauthabi` is passed as branch protection: - `intrinsics`; - `calls`; - `returns`; - `auth-traps`; - `vtable-pointer-address-discrimination`; - `vtable-pointer-type-discrimination`; - `init-fini`. Co-authored-by: Anatoly Trosinenko <atrosinenko@accesssoftek.com>
@llvm/pr-subscribers-clang-driver @llvm/pr-subscribers-clang Author: Daniil Kovalev (kovdan01) ChangesEnable the following ptrauth flags when
Co-authored-by: Anatoly Trosinenko <atrosinenko@accesssoftek.com> Full diff: https://github.com/llvm/llvm-project/pull/97237.diff 4 Files Affected:
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 1b7cc82ea816e..4ed1ece22b7aa 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -1484,6 +1484,39 @@ void AddUnalignedAccessWarning(ArgStringList &CmdArgs) {
}
}
+static void handlePAuthABIOption(const ArgList &DriverArgs,
+ ArgStringList &CC1Args, const Driver &D) {
+ if (!DriverArgs.hasArg(options::OPT_fptrauth_intrinsics,
+ options::OPT_fno_ptrauth_intrinsics))
+ CC1Args.push_back("-fptrauth-intrinsics");
+
+ if (!DriverArgs.hasArg(options::OPT_fptrauth_calls,
+ options::OPT_fno_ptrauth_calls))
+ CC1Args.push_back("-fptrauth-calls");
+
+ if (!DriverArgs.hasArg(options::OPT_fptrauth_returns,
+ options::OPT_fno_ptrauth_returns))
+ CC1Args.push_back("-fptrauth-returns");
+
+ if (!DriverArgs.hasArg(options::OPT_fptrauth_auth_traps,
+ options::OPT_fno_ptrauth_auth_traps))
+ CC1Args.push_back("-fptrauth-auth-traps");
+
+ if (!DriverArgs.hasArg(
+ options::OPT_fptrauth_vtable_pointer_address_discrimination,
+ options::OPT_fno_ptrauth_vtable_pointer_address_discrimination))
+ CC1Args.push_back("-fptrauth-vtable-pointer-address-discrimination");
+
+ if (!DriverArgs.hasArg(
+ options::OPT_fptrauth_vtable_pointer_type_discrimination,
+ options::OPT_fno_ptrauth_vtable_pointer_type_discrimination))
+ CC1Args.push_back("-fptrauth-vtable-pointer-type-discrimination");
+
+ if (!DriverArgs.hasArg(options::OPT_fptrauth_init_fini,
+ options::OPT_fno_ptrauth_init_fini))
+ CC1Args.push_back("-fptrauth-init-fini");
+}
+
static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs, bool isAArch64) {
const Arg *A = isAArch64
@@ -1537,11 +1570,16 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args,
if (!isAArch64 && PBP.Key == "b_key")
D.Diag(diag::warn_unsupported_branch_protection)
<< "b-key" << A->getAsString(Args);
+ if (!isAArch64 && PBP.HasPauthABI)
+ D.Diag(diag::warn_unsupported_branch_protection)
+ << "pauthabi" << A->getAsString(Args);
Scope = PBP.Scope;
Key = PBP.Key;
BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR;
IndirectBranches = PBP.BranchTargetEnforcement;
GuardedControlStack = PBP.GuardedControlStack;
+ if (isAArch64 && PBP.HasPauthABI)
+ handlePAuthABIOption(Args, CmdArgs, D);
}
CmdArgs.push_back(
diff --git a/clang/test/Driver/aarch64-ptrauth.c b/clang/test/Driver/aarch64-ptrauth.c
index fa0125f4b22a9..dc63545a47a86 100644
--- a/clang/test/Driver/aarch64-ptrauth.c
+++ b/clang/test/Driver/aarch64-ptrauth.c
@@ -13,13 +13,33 @@
// RUN: %s 2>&1 | FileCheck %s --check-prefix=ALL
// ALL: "-cc1"{{.*}} "-fptrauth-intrinsics" "-fptrauth-calls" "-fptrauth-returns" "-fptrauth-auth-traps" "-fptrauth-vtable-pointer-address-discrimination" "-fptrauth-vtable-pointer-type-discrimination" "-fptrauth-init-fini"
+// RUN: %clang -### -c --target=aarch64 -mbranch-protection=pauthabi %s 2>&1 | \
+// RUN: FileCheck %s --check-prefix=PAUTHABI1
+// PAUTHABI1: "-cc1"{{.*}} "-fptrauth-intrinsics" "-fptrauth-calls" "-fptrauth-returns" "-fptrauth-auth-traps" "-fptrauth-vtable-pointer-address-discrimination" "-fptrauth-vtable-pointer-type-discrimination" "-fptrauth-init-fini"
+
+// RUN: %clang -### -c --target=aarch64 -mbranch-protection=pauthabi -fno-ptrauth-intrinsics \
+// RUN: -fno-ptrauth-calls -fno-ptrauth-returns -fno-ptrauth-auth-traps \
+// RUN: -fno-ptrauth-vtable-pointer-address-discrimination -fno-ptrauth-vtable-pointer-type-discrimination \
+// RUN: -fno-ptrauth-init-fini %s 2>&1 | FileCheck %s --check-prefix=PAUTHABI2
+// PAUTHABI2-NOT: "-fptrauth-intrinsics"
+// PAUTHABI2-NOT: "-fptrauth-calls"
+// PAUTHABI2-NOT: "-fptrauth-returns"
+// PAUTHABI2-NOT: "-fptrauth-auth-traps"
+// PAUTHABI2-NOT: "-fptrauth-vtable-pointer-address-discrimination"
+// PAUTHABI2-NOT: "-fptrauth-vtable-pointer-type-discrimination"
+// PAUTHABI2-NOT: "-fptrauth-init-fini"
+
// RUN: not %clang -### -c --target=x86_64 -fptrauth-intrinsics -fptrauth-calls -fptrauth-returns -fptrauth-auth-traps \
// RUN: -fptrauth-vtable-pointer-address-discrimination -fptrauth-vtable-pointer-type-discrimination \
-// RUN: -fptrauth-init-fini %s 2>&1 | FileCheck %s --check-prefix=ERR
-// ERR: error: unsupported option '-fptrauth-intrinsics' for target '{{.*}}'
-// ERR-NEXT: error: unsupported option '-fptrauth-calls' for target '{{.*}}'
-// ERR-NEXT: error: unsupported option '-fptrauth-returns' for target '{{.*}}'
-// ERR-NEXT: error: unsupported option '-fptrauth-auth-traps' for target '{{.*}}'
-// ERR-NEXT: error: unsupported option '-fptrauth-vtable-pointer-address-discrimination' for target '{{.*}}'
-// ERR-NEXT: error: unsupported option '-fptrauth-vtable-pointer-type-discrimination' for target '{{.*}}'
-// ERR-NEXT: error: unsupported option '-fptrauth-init-fini' for target '{{.*}}'
+// RUN: -fptrauth-init-fini %s 2>&1 | FileCheck %s --check-prefix=ERR1
+// ERR1: error: unsupported option '-fptrauth-intrinsics' for target '{{.*}}'
+// ERR1-NEXT: error: unsupported option '-fptrauth-calls' for target '{{.*}}'
+// ERR1-NEXT: error: unsupported option '-fptrauth-returns' for target '{{.*}}'
+// ERR1-NEXT: error: unsupported option '-fptrauth-auth-traps' for target '{{.*}}'
+// ERR1-NEXT: error: unsupported option '-fptrauth-vtable-pointer-address-discrimination' for target '{{.*}}'
+// ERR1-NEXT: error: unsupported option '-fptrauth-vtable-pointer-type-discrimination' for target '{{.*}}'
+// ERR1-NEXT: error: unsupported option '-fptrauth-init-fini' for target '{{.*}}'
+
+// RUN: not %clang -### -c --target=x86_64 -mbranch-protection=pauthabi %s 2>&1 | \
+// RUN: FileCheck %s --check-prefix=ERR2
+// ERR2: error: unsupported option '-mbranch-protection=' for target 'x86_64'
diff --git a/llvm/include/llvm/TargetParser/ARMTargetParserCommon.h b/llvm/include/llvm/TargetParser/ARMTargetParserCommon.h
index f6115718e9f5f..ca634ed969d84 100644
--- a/llvm/include/llvm/TargetParser/ARMTargetParserCommon.h
+++ b/llvm/include/llvm/TargetParser/ARMTargetParserCommon.h
@@ -43,6 +43,7 @@ struct ParsedBranchProtection {
bool BranchTargetEnforcement;
bool BranchProtectionPAuthLR;
bool GuardedControlStack;
+ bool HasPauthABI;
};
bool parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP,
diff --git a/llvm/lib/TargetParser/ARMTargetParserCommon.cpp b/llvm/lib/TargetParser/ARMTargetParserCommon.cpp
index d6ce6581bb1a9..0b1e6d3356f68 100644
--- a/llvm/lib/TargetParser/ARMTargetParserCommon.cpp
+++ b/llvm/lib/TargetParser/ARMTargetParserCommon.cpp
@@ -140,7 +140,7 @@ ARM::EndianKind ARM::parseArchEndian(StringRef Arch) {
// an erroneous part of the spec.
bool ARM::parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP,
StringRef &Err, bool EnablePAuthLR) {
- PBP = {"none", "a_key", false, false, false};
+ PBP = {"none", "a_key", false, false, false, false};
if (Spec == "none")
return true; // defaults are ok
@@ -160,6 +160,10 @@ bool ARM::parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP,
PBP.BranchTargetEnforcement = true;
continue;
}
+ if (Opt == "pauthabi") {
+ PBP.HasPauthABI = true;
+ continue;
+ }
if (Opt == "pac-ret") {
PBP.Scope = "non-leaf";
for (; I + 1 != E; ++I) {
|
@@ -1484,6 +1484,39 @@ void AddUnalignedAccessWarning(ArgStringList &CmdArgs) { | |||
} | |||
} | |||
|
|||
static void handlePAuthABIOption(const ArgList &DriverArgs, | |||
ArgStringList &CC1Args, const Driver &D) { | |||
if (!DriverArgs.hasArg(options::OPT_fptrauth_intrinsics, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See addOptInFlag.
But the implementation seems quite different from the title/description.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See addOptInFlag.
Do you mean that we need to replace
if (!DriverArgs.hasArg(options::OPT_fptrauth_xxx,
options::OPT_fno_ptrauth_xxx))
CC1Args.push_back("-fptrauth-xxx");
with
DriverArgs.addOptInFlag(CC1Args, options::OPT_fptrauth_xxx,
options::OPT_fno_ptrauth_xxx);
...?
If so, this does not look correct - addOptInFlag
would add the flag present (if any) in DriverArgs
to CC1Args
, but we want to append a list of ptrauth flags to cc1 args unconditionally if pauthabi
is passed as branch protection.
Do I miss smth? I suppose I might have misunderstood you point.
But the implementation seems quite different from the title/description.
Hmm, it actually looks consistent to me, the implementation seems matching the description from my point of view - we want to add a bunch of arguments with -mbranch-protection=pauthabi
used as a shortcut, we do that. Could you please describe what is inconsistent between description and implementation in a bit more detail?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I understand it we are implicitly defining the default signing schema for ELF platforms with -mbranch-protection=pauthabi
.
Is there any thought on how we want to manage signing schemas going forward? For example I can imagine looking an environment from the triple to select a signing schema for a particular platform. I could also see a potential for a separate command line option to choose from documented named signing schemas.
I don't think these need to implemented now, would be good to make sure that there are enough comments stating the ABI implications of making changes.
@@ -1484,6 +1484,39 @@ void AddUnalignedAccessWarning(ArgStringList &CmdArgs) { | |||
} | |||
} | |||
|
|||
static void handlePAuthABIOption(const ArgList &DriverArgs, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it will be worth a comment above and possibly inline explaining the ABI implications of the options.
For example:
Each combination of options here forms a signing schema, and in most cases each signing schema is its own incompatible ABI. The default values of the options represent the default signing schema.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added the comment, thanks! See fcd090c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering if it is worth resurrecting https://discourse.llvm.org/t/aarch64-pauthabi-options-for-command-line-options-to-use-the-pauthabi-and-set-signing-schema/73479 to see if we can get some more visibility on this. It has also been almost a year since that was posted.
Some colleagues expressed some concern that as this was introducing a new ABI, while the existing -mbranch-protection options are ABI neutral [*], then perhaps a better option would be to use the -mabi
option. For example -mabi=pauthabi
.
There are some advantages and disadvantages to doing that. It is explicit that there is a different ABI being used, however it is logically an extension of the CFI features in -mbranch-protection
and some of the branch-protection modifiers such as +ret
could be useful.
Will be worth having some thoughts on how you would want to interact with existing mbranch-protection options. If pauthabi would supersede all the pointer authentication parts then it may be better to have a -mabi
option?
[*] Stack unwinding needs to be aware of signed return addresses, but these can be optional.
Scope = PBP.Scope; | ||
Key = PBP.Key; | ||
BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR; | ||
IndirectBranches = PBP.BranchTargetEnforcement; | ||
GuardedControlStack = PBP.GuardedControlStack; | ||
if (isAArch64 && PBP.HasPauthABI) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need any additional error checking for the existing branch protection options that affect pointer authentication?
For example we have
pac-ret // return address signing with A key
pac-ret+leaf // extend return address signing to leaf functions
standard = pac-ret+bti+pc // enable pac-ret, bti and pc (if available on hardware).
pc // Enable pc as modifier in return address signing.
b-key // Use b-key for signing return address.
When pauthabi is used, are the other PAC related options ignored? I can see +leaf
being potentially useful, as well as +pc
. I think b-key is going to clash with the signing schema.
The other options look to be subsets of pauthabi (unless additional command line options unless -fno-ptrauth-returns
is used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest not to support pauthabi
in combination with other branch protection options as for now. Here are the reasons why.
-
pac-ret
: this and-fptrauth-returns
(which is enabled by-mbranch-protection=pauthabi
) are intended to do similar stuff, but the implementation differs.For
-mbranch-protection=pac-ret
:sign-return-address
llvm module flag is set (and optionallysign-return-address-all
with+leaf
);PAUTH_PROLOGUE
andPAUTH_EPILOGUE
pseudo-instructions are emitted inAArch64FrameLowering::emitPrologue
andAArch64FrameLowering::emitEpilogue
; these pseudos are later expanded byAArch64PointerAuth
pass;- both A and B keys can be used (depending on
+b-key
and corresponding function attributesign-return-address-key
or module flagsign-return-address-with-bkey
); - using
pc
register as additional modifier is supported with+pc
(corresponding module flag isbranch-protection-pauth-lr
).
For
-fptrauth-returns
(I'll talk about downstream Apple implementation since many parts are not upstreamed yet, see, for example, swiftlang@13f9944):ptrauth-returns
attribute is set on functions we want this to be enabled;- actual codegen logic is implemented in
AArch64FrameLowering::emitPrologue
andAArch64FrameLowering::emitEpilogue
- we emit actual instructions likepacibsp
directly there; - B key is always used;
- using
pc
register as additional modifier is not supported.
If we try to enable both by
-mbranch-protection=pauthabi+pac-ret
, it'll result in incorrect code with duplicating sign/auth instructions. For example, for this:int a() { return b() + c(); }
We get this:
a: paciasp pacibsp stp x29, x30, [sp, #-32]! // 16-byte Folded Spill str x19, [sp, #16] // 8-byte Folded Spill mov x29, sp bl b mov w19, w0 bl c add w0, w0, w19 ldr x19, [sp, #16] // 8-byte Folded Reload ldp x29, x30, [sp], #32 // 16-byte Folded Reload autiasp retab
A corresponding issue was already previously opened (mistakenly in mainline llvm repo while it was and actually still is an issue specific for Apple downstream). Links:
- the issue in mainline repo Incorrect code generation with
-arch arm64e -mbranch-protection=standard
or=pac-ret
#60239; - thread on Apple forum regarding the issue https://forums.developer.apple.com/forums/thread/724568;
- the issue on Apple feedback portal (I was unable to open that actually but the link should be correct) https://feedbackassistant.apple.com/feedback/1196543.
I'll probably re-open the issue in mainline repo when codegen support for
ptrauth-returns
is upstreamed. Alternatively, the Apple's downstream implementation for return address signing might be dropped sincepac-ret
seems to be more complete, and we can use-fptrauth-returns
for setting the same return address signing options aspac-ret+b-key
. Tagging @ahmedbougacha. -
+leaf
and+pc
: these are only allowed withpac-ret
, and while it's not clear how we'll resolve collisions betweenpac-ret
andptrauth-returns
(which is part ofpauthabi
), it's probably better to just disallowpauthabi+leaf
andpauthabi+pc
. -
+b-key
:ptrauth-returns
(which is part ofpauthabi
) already uses B key by default (but the codegen support is still present only in Apple downstream, see swiftlang@13f9944) -
gcs
: as far as I understand, guarded control stack is smth like what is usually called shadow stack. I'm not sure how it's supposed to work with return address signing - probably, these shouldn't be used together, so, sincepauthabi
implies return address signing, disallowpauthabi+gcs
. -
bti
: depending on operand value (c
,j
orjc
), thebti
instruction inserted at beginning of valid call/jump targets checks thatPSTATE.BTYPE
matches the value set byblr
and/orbr
instructions (see https://developer.arm.com/documentation/100076/0100/A64-Instruction-Set-Reference/A64-General-Instructions/BTI). As far as I understand, instructions likeblraa
do not set this state (at least, I was unable to find info regarding this), so furtherbti
instruction will fail. @smithp35 Could you please clarify ifblraa
and other authenticating branch instruction setPSTATE.BTYPE
whichbti
instructions treat as correct? -
standard
- a combination ofbti
,gcs
,pac-ret
w/o+leaf
and, optionally,+pc
- so, shouldn't be supported withpauthabi
since its parts are not supported.
Regarding disallowing separate flags like -fptrauth-returns
with other branch protection schemes - I don't think we need to do that since the -fptrauth-*
flags are not intended to be used directly - instead, we propose this "umbrella" option -mbranch-protection=pauthabi
, which enabled a "good enough" set of flags at once.
Please let me know your thought about that. I'll update the PR with corresponding checks as soon as we come to some consensus on the question.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI - I'm going to change the sign-return-address
and variants to be a function flag. (#82819)
bti
- All BRA*
and BLRA*
instructions set the PSTATE.BTYPE
. I prefer to check the pseudo codefor this things (see BTypeNext)
IMHO pauthabi+bti
makes sense as they are complementary while other option are overlapping. We can introduce this combination later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@DanielKristofKiss Thanks! Yes, I now see that authenticating branch instructions also set the PSTATE.BTYPE
. So, I agree that we can allow pauthabi+bti. The codegen when pauthabi+bti
is passed as branch protection looks OK on downstream:
- for functions which do not sign LR (w/o
pacibsp
in the beginning, e.g. leaf functions), a properbti
instruction is emitted in the beginning of the function; - for function which sign LR (with
pacibsp
in the beginning), no additionalbti
instruction is emitted sincepacibsp
also hasbti
built-in, seeSetBTypeCompatible
in https://developer.arm.com/documentation/ddi0602/2022-06/Base-Instructions/PACIB--PACIB1716--PACIBSP--PACIBZ--PACIZB--Pointer-Authentication-Code-for-Instruction-address--using-key-B-
In mainline, codegen with -fptrauth-returns
is not implemented yet, so I can't provide tests verifying generated assembly correctness right now. I'll add them as soon as codegen support for this flag is merged.
I've implemented a check which only allows bti
with pauthabi
and does not allow pac-ret[+leaf,+pc,+b-key]
and gcs
. See 3067c93
Tagging @smithp35
I think we discussed this a bit and the conclusion was that it would be up to the platform to chose the appropriate signing scheme (and do ABI versioning if desired / necessary). However, currently there is no way to ask platform for this and it looks like a chicken-and-egg problem. So we may want to come with some "default" values that are more or less "good enough". These in the future might be fully overridden by a platform or we may chose alternative approach. For now it is just a way to combine different |
clang/test/Driver/aarch64-ptrauth.c
Outdated
// RUN: -fno-ptrauth-calls -fno-ptrauth-returns -fno-ptrauth-auth-traps \ | ||
// RUN: -fno-ptrauth-vtable-pointer-address-discrimination -fno-ptrauth-vtable-pointer-type-discrimination \ | ||
// RUN: -fno-ptrauth-init-fini %s 2>&1 | FileCheck %s --check-prefix=PAUTHABI2 | ||
// PAUTHABI2-NOT: "-fptrauth-intrinsics" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One -NOT: "-fptrauth
should catch all undesired "-fptrauth-*"
options
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed, thanks, see 1d81b91
Apologies, it looks like I'm not going to get this out this morning, still working on it. |
Apologies for the length of the post, it could probably do with more revisions and research but I thought it better to send what I have and refine later after comments. Most of this is a summation of a discussion had in the PAuthABI call, followed by my attempts at analysing the options we discussed. My apologies if I've misrepresented or missed out anything in the call. Please feel free to correct me where I'm wrong or have missed something out. I'll be at a conference this week so I may be slow to respond. Known use cases and background.We have three known use cases for PAuthABI, with two in active development:
On each of the platforms, there is expected to be more than onesigning schema, for example kernel vs user-space. With the possible exception of return address signing, each signing schema is its own ABI. While low-level options may exist to control the signing schema, we do not expect end users to use them as they risk breaking the platform ABI. This infers that we need an option to choose between high-level signing schemas, that map to some combination of the low-level options. This mapping will need to be per-platform as Linux may choose differently to BSD. The signing schema will also need to be used as the multilib key so that a compatible set of libraries can be linked for the signing schema. On ELF the (platform, signing-schema) choice can be recorded in the ELF properties. Users of the low-level command line options cannot be easily recorded in the ELF properties. There are various platform specific choices that could be made if the low-level options are used. For example:
I think that this has to be under control of the platform. My intuition is that we trust the user, perhaps with a warning, and On a bare-metal embedded system each toolchain can make up their own signing schema, however no toolchain is likely to provide pre-compiled libraries for every possible choice so we expect there to be a sensible default signing schema. Thoughts on
|
Thanks @smithp35 for a detailed description!
I suppose we should use this this option since it's harder for end users to use that incorrectly - it looks like that many real-world code and corresponding build environments rely on triple and do not encounter other options (for example, as you said, hard/soft float are encoded in triple or normalized to triple if passed separately). I'll implement initial support for that and update current PR.
We actually have a similar issue already opened, see #97332, so yes, it's a known feature request.
I like this idea. Of course, we can mark functionality as "alpha" or "experimental", but just using a different option value makes this more explicit and end users will not have a chance to mix "alpha" stuff with "released" stuff when we have one.
In general, I agree with that point, but for the first "adoption" phase (while we have |
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.
0ac4724
to
f06bc88
Compare
-mbranch-protection=pauthabi
optionpauthtest
ABI for AArch64 Linux triples
@smithp35 I've implemented Please let me know your thoughts on the implementation. Anyone else interested is also welcome to leave feedback. Tagging @MaskRay |
clang/lib/Basic/Targets/ARM.cpp
Outdated
@@ -324,6 +324,9 @@ ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple, | |||
case llvm::Triple::GNU: | |||
setABI("apcs-gnu"); | |||
break; | |||
case llvm::Triple::PAuthTest: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really need to touch 32-bit ARM?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, we do not need that, thanks for bringing attention to this.
Deleted here and in ARM::computeDefaultTargetABI
, see eae6f7c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apologies for the delay in responding, been a bit backed up. I like the idea of pauthtest as it does give some leeway to change the signing schema.
I expect that with some work this could be made to work with bare-metal targets too, but I think it is best to stick with what has been tested so far.
Not had a chance to go through the tests in detail yet. Will aim to do that before the end of the week.
if (IndirectBranches) | ||
CmdArgs.push_back("-mbranch-target-enforce"); | ||
if (GuardedControlStack) | ||
if (GuardedControlStack) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think GuardedControlStack should be compatible with PAuthABI but there won't be hardware available for some time so we could retrospectively support it later after testing it.
Perhaps worth a comment that GCS is untested with PAuthABI, but could be enabled after testing with a suitable system.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a comment, thanks! See 4f3da9e
@@ -0,0 +1,4 @@ | |||
// RUN: %clang --target=aarch64-linux-pauthtest --sysroot=%S/Inputs/multilib_aarch64_linux_tree -### -c %s 2>&1 | FileCheck %s |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks this is not used: "clang/test/Driver/Inputs/multilib_aarch64_linux_tree/usr/include/aarch64-linux-gnu/.keep"
BTW we could just add to the test:
rm -rf %t.dir && mkdir -p %t.dir/multilib_aarch64_linux_tree/usr/include/aarch64-linux-gnu/ && mkdir -p %t.dir/multilib_aarch64_linux_tree/usr/include/aarch64-linux-pauthtest/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks this is not used: "clang/test/Driver/Inputs/multilib_aarch64_linux_tree/usr/include/aarch64-linux-gnu/.keep"
It's not directly used in this test, but I've added that in order to have a choice between two directories (one with default triple, one with pauthtest) and check that the pauthtest directory is chosen. Is this considered unneeded?
BTW we could just add to the test
Yes, that's possible, thanks for suggestion! But I've followed convention with already present multilib_arm_linux_tree (see clang/test/Driver/arm-multilibs.c test). I'm not sure what's better - stick with old existing conventions or not clutter source tree with empty directories which can be created on demand during test. So, I'll leave this "as is" currently and change this if there are more requests.
If you actually have a strong preference for not keeping empty multilib folders in source tree and just creating directories during test - please let me know.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After discussion in the PAuthABI call. We agreed that it would be best to have an exemplar of how a signing schema for a platform should be encoded rather than always using the individual options.
Anton mentioned that we can document that pauthtest is not a stable signing schema to be used in production, and if there ended up being a stable upstream linux signing schema -mabi=pauth (probably) then pauthtest could be removed.
Summary: 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. --------- Co-authored-by: Anatoly Trosinenko <atrosinenko@accesssoftek.com> Test Plan: Reviewers: Subscribers: Tasks: Tags: Differential Revision: https://phabricator.intern.facebook.com/D60251253
When
pauthtest
is either passed as environment part of AArch64 Linux tripleor 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
, tryto use
aarch64-linux-pauthtest
as multilib directory.The following is not supported:
pauthtest
ABI with any branch protection scheme except BTI;from
pauthtest
in combination with-mabi=pauthtest
;