Introduce aarch64-unknown-linux-pauthtest target#155722
Introduce aarch64-unknown-linux-pauthtest target#155722jchlanda wants to merge 7 commits intorust-lang:mainfrom
Conversation
Co-authored-by: Daniil Kovalev <dkovalev@accesssoftek.com>
`const_ptr_auth` wraps aroudn `LLVMRustConstPtrAuth`, which provides a way to decorate a function pointer in `ConstPtrAuth`.
Allow PAC metadata to be passed to `get_fn_addr` and related API changes.
The set of supported attributes is: function * "aarch64-jump-table-hardening" * "ptrauth-auth-traps" * "ptrauth-calls" * "ptrauth-indirect-gotos" * "ptrauth-returns" module * "ptrauth-elf-got" * "ptrauth-sign-personality"
Also add flag for ELF-GOT signing.
Also: * update tests to force dynamic library when targetting pauthtest * various test fixes * introduce end-to-end tests for pauthtest (in run-make)
| } | ||
| } | ||
|
|
||
| if sess.target.env == Env::Pauthtest { |
There was a problem hiding this comment.
For a full context I'm going to bring comments from a draft PR into this one:
@asl
Note that pauthtest in clang is an interim thing. How we can enable pauth on, say, bare-metal platform? Or on some downstream platform?
@jchlanda
While there is already code gated by Env in codegen llvm, pauthtest is an outlier, such that all its functionality is behind the environment checks. Handling it earlier in the pipeline would make for a better design, one that decouples target/triple specifics from pauth logic. Maybe Session would be a good candidate to hold that info?
Clang does just that by solving platform/environment specifics on the driver level and later on basing the logic on language flags that are there regardless of the platform. Finally the flags are resolved to a concrete signing schema.
Note that
pauthtestin clang is an interim thing. How we can enable pauth on, say, bare-metal platform? Or on some downstream platform?
Specifically for this bit, I suggested on libc that env could be set to musl since that's what most libraries will care about, and then use the TargetOptions.cfg_abi field for pauthtest. Which means that you can cfg(target_abi = "pauthtest") regardless of whether it's musl or bare metal.
Either way, it could also be encapsulated in an .should_emit_pauth() -> bool function that can do the relevant checks in one place.
There was a problem hiding this comment.
For a full context I'm going to bring comments from a draft PR into this one:
@tgross35
Mentioned this elsewhere but the target should land as no-std first. The initial support should only be the bare minimum to get core building via --target, everything else can come as a followup.
(Fine to keep this PR around as a WIP of course)
There was a problem hiding this comment.
For a full context I'm going to bring comments from a draft PR into this one:
@tgross35
Probably worth a directory for pauth
There was a problem hiding this comment.
For a full context I'm going to bring comments from a draft PR into this one:
@tgross35
Could pauth-quicksort-*-driver be combined into one run-make test that builds/runs two different things in main? Since they can probably share some docs or reuse some code, and it saves the per-test overhead.
|
r? compiler |
|
cc: @davidtwco |
| arch: Arch::AArch64, | ||
|
|
||
| options: TargetOptions { | ||
| env: Env::Pauthtest, |
There was a problem hiding this comment.
I tend to think this should set target_abi = "pauth" instead of target_env = "pauth"? Or maybe an entirely new cfg(target_has_pointer_authentication)?
My motivation is that arm64e Apple targets have pointer authentication as well, but there target_env is used for things like Mac Catalyst too (target_env = "macabi").
|
|
||
| pub(crate) fn target() -> Target { | ||
| Target { | ||
| llvm_target: "aarch64-unknown-linux-pauthtest".into(), |
There was a problem hiding this comment.
I feel like the motivation for having "test" in the name is somewhat weak? If the intention is that the target is unstable, we have better ways of enforcing that (such as a check that you're on the nightly channel before using the target).
| TargetOptions, base, | ||
| }; | ||
|
|
||
| pub(crate) fn target() -> Target { |
There was a problem hiding this comment.
Could I get you to add some documentation for the target based on src/doc/rustc/src/platform-support/TEMPLATE.md?
| #[cfg_attr(target_env = "pauthtest", link(name = "rust_test_helpers", kind = "dylib"))] | ||
| #[cfg_attr(not(target_env = "pauthtest"), link(name = "rust_test_helpers", kind = "static"))] |
There was a problem hiding this comment.
Dynamic linking is required, with a dynamic linker acting as the ELF interpreter that can resolve pauth relocations and enforce pointer authentication constraints.
Maybe we could translate link(name = "xyz", kind = "static") to kind = "dynamic" on this target then in the meantime? It seems like the test suite is gonna break all the time otherwise when people assume that static linking works.
This target enables Pointer Authentication Code (PAC) support in Rust on AArch64
ELF-based Linux systems. It uses the
aarch64-unknown-linux-pauthtestLLVMtarget and a pointer-authentication-enabled sysroot with a custom musl as a
reference libc implementation. Dynamic linking is required, with a dynamic
linker acting as the ELF interpreter that can resolve pauth relocations and
enforce pointer authentication constraints.
Supported features include:
to LLVM's
-fptrauth-calls)after restoring for non-leaf functions (corresponds to
-fptrauth-returns)(corresponds to
-fptrauth-auth-traps)authentication scheme (corresponds to
-fptrauth-init-finiand-fptrauth-init-fini-address-discrimination)LLVM (corresponds to
-faarch64-jump-table-hardeningand-fptrauth-indirect-gotos)-Z ptrauth-elf-got, off by default)Existing compiler support, such as enabling branch authentication instructions
(i.e.:
-Z branch-protection) provide limited functionality, mainly signingreturn addresses (
pac-ret). The new target goes further by enabling ABI-levelpointer authentication support.
This target does not define a new ABI; it builds on the existing C/C++ language
ABI with pointer authentication support added. However, different authentication
features, encoded in the signing schema, are not ABI-compatible with one
another.
Useful links:
[WIP] Introduce aarch64-unknown-linux-pauthtest target #154759
https://rust-lang.github.io/rust-project-goals/2026/aarch64_pointer_authentication_pauthtest.html
https://clang.llvm.org/docs/PointerAuthentication.html
https://llvm.org/docs/PointerAuth.html
https://github.com/ARM-software/abi-aa/blob/main/pauthabielf64/pauthabielf64.rst
Tier 3 check list
I pledge to do my best maintaining it.
The name chosen for the target is
aarch64-unknown-linux-pauthtestwhichmirrors the LLVM target naming.
There should be no confusion, the name follows naming convention and is
descriptive.
Letters, numbers and dashes only.
The target requires system
clangandlldavailable as well as custom libc(musl based) and sysroot, provided through the build scripts.
There are no license implications.
Understood.
There are no new dependencies or requirements.
The target only relies on open source tools.
No such terms present.
Understood.
Understood.
aarch64-unknown-linux-pauthtest targethas std library support, moreover alllibrarytests pass for the target.Platform support document covers building instructions.
Understood.
Understood.
Understood.
Understood.
It is expected that the target should be able to compile binaries on any systems
that are capable of compiling
aarch64code.