Skip to content

Commit d0314ca

Browse files
Rollup merge of #155722 - jchlanda:jakub/pac, r=davidtwco
Introduce aarch64-unknown-linux-pauthtest target This target enables Pointer Authentication Code (PAC) support in Rust on AArch64 ELF-based Linux systems. It uses the `aarch64-unknown-linux-pauthtest` LLVM target 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: * authentication of signed function pointers for extern "C" calls (corresponds to LLVM's `-fptrauth-calls`) * signing of return addresses before spilling to the stack and authentication after restoring for non-leaf functions (corresponds to `-fptrauth-returns`) * trapping on authentication failure when the FPAC feature is not present (corresponds to `-fptrauth-auth-traps`) * signing of init/fini array entries using the LLVM-defined pointer authentication scheme (corresponds to `-fptrauth-init-fini` and `-fptrauth-init-fini-address-discrimination`) * non-ABI-affecting indirect control-flow hardening features as implemented in LLVM (corresponds to `-faarch64-jump-table-hardening` and `-fptrauth-indirect-gotos`) * signed ELF GOT entries (gated behind `-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 signing return addresses (`pac-ret`). The new target goes further by enabling ABI-level pointer 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: * Earlier PR: rust-lang/rust#154759 * Part of: rust-lang/rust#148640 * Project goal: https://rust-lang.github.io/rust-project-goals/2026/aarch64_pointer_authentication_pauthtest.html * Clang pointer authentication documentation: https://clang.llvm.org/docs/PointerAuthentication.html * LLVM pointer authentication documentation: https://llvm.org/docs/PointerAuth.html * PAuth ABI Extension to ELF for the AArch64 architecture: https://github.com/ARM-software/abi-aa/blob/main/pauthabielf64/pauthabielf64.rst ### Tier 3 check list > - A tier 3 target must have a designated developer or developers (the "target > maintainers") on record to be CCed when issues arise regarding the target. > (The mechanism to track and CC such developers may evolve over time.) I pledge to do my best maintaining it. > - Targets must use naming consistent with any existing targets; for instance, a > target for the same CPU or OS as an existing Rust target should use the same > name for that CPU or OS. Targets should normally use the same names and > naming conventions as used elsewhere in the broader ecosystem beyond Rust > (such as in other toolchains), unless they have a very good reason to > diverge. Changing the name of a target can be highly disruptive, especially > once the target reaches a higher tier, so getting the name right is important > even for a tier 3 target. The name chosen for the target is `aarch64-unknown-linux-pauthtest` which mirrors the [LLVM target naming](https://github.com/llvm/llvm-project/blob/main/llvm/unittests/TargetParser/TripleTest.cpp#L1407). > - Target names should not introduce undue confusion or ambiguity unless > absolutely necessary to maintain ecosystem compatibility. For example, if > the name of the target makes people extremely likely to form incorrect > beliefs about what it targets, the name should be changed or augmented to > disambiguate it. There should be no confusion, the name follows naming convention and is descriptive. > - If possible, use only letters, numbers, dashes and underscores for the name. > Periods (`.`) are known to cause issues in Cargo. Letters, numbers and dashes only. > - Tier 3 targets may have unusual requirements to build or use, but must not > create legal issues or impose onerous legal terms for the Rust project or for > Rust developers or users. The target requires system `clang` and `lld` available as well as custom libc ([musl](https://github.com/access-softek/musl) based) and sysroot, provided [through the build scripts](https://github.com/access-softek/pauth-toolchain-build-scripts/tree/master). > - The target must not introduce license incompatibilities. There are no license implications. > - Anything added to the Rust repository must be under the standard Rust > license (`MIT OR Apache-2.0`). Understood. > - The target must not cause the Rust tools or libraries built for any other > host (even when supporting cross-compilation to the target) to depend > on any new dependency less permissive than the Rust licensing policy. This > applies whether the dependency is a Rust crate that would require adding > new license exceptions (as specified by the `tidy` tool in the > rust-lang/rust repository), or whether the dependency is a native library > or binary. In other words, the introduction of the target must not cause a > user installing or running a version of Rust or the Rust tools to be > subject to any new license requirements. There are no new dependencies or requirements. > - Compiling, linking, and emitting functional binaries, libraries, or other > code for the target (whether hosted on the target itself or cross-compiling > from another target) must not depend on proprietary (non-FOSS) libraries. > Host tools built for the target itself may depend on the ordinary runtime > libraries supplied by the platform and commonly used by other applications > built for the target, but those libraries must not be required for code > generation for the target; cross-compilation to the target must not require > such libraries at all. For instance, `rustc` built for the target may > depend on a common proprietary C runtime library or console output library, > but must not depend on a proprietary code generation library or code > optimization library. Rust's license permits such combinations, but the > Rust project has no interest in maintaining such combinations within the > scope of Rust itself, even at tier 3. The target only relies on open source tools. > - "onerous" here is an intentionally subjective term. At a minimum, "onerous" > legal/licensing terms include but are *not* limited to: non-disclosure > requirements, non-compete requirements, contributor license agreements > (CLAs) or equivalent, "non-commercial"/"research-only"/etc terms, > requirements conditional on the employer or employment of any particular > Rust developers, revocable terms, any requirements that create liability > for the Rust project or its developers or users, or any requirements that > adversely affect the livelihood or prospects of the Rust project or its > developers or users. No such terms present. > - Neither this policy nor any decisions made regarding targets shall create any > binding agreement or estoppel by any party. If any member of an approving > Rust team serves as one of the maintainers of a target, or has any legal or > employment requirement (explicit or implicit) that might affect their > decisions regarding a target, they must recuse themselves from any approval > decisions regarding the target's tier status, though they may otherwise > participate in discussions. Understood. > - This requirement does not prevent part or all of this policy from being > cited in an explicit contract or work agreement (e.g. to implement or > maintain support for a target). This requirement exists to ensure that a > developer or team responsible for reviewing and approving a target does not > face any legal threats or obligations that would prevent them from freely > exercising their judgment in such approval, even if such judgment involves > subjective matters or goes beyond the letter of these requirements. Understood. > - Tier 3 targets should attempt to implement as much of the standard libraries > as possible and appropriate (`core` for most targets, `alloc` for targets > that can support dynamic memory allocation, `std` for targets with an > operating system or equivalent layer of system-provided functionality), but > may leave some code unimplemented (either unavailable or stubbed out as > appropriate), whether because the target makes it impossible to implement or > challenging to implement. The authors of pull requests are not obligated to > avoid calling any portions of the standard library on the basis of a tier 3 > target not implementing those portions. `aarch64-unknown-linux-pauthtest target` has std library support, moreover all `library` tests pass for the target. > - The target must provide documentation for the Rust community explaining how > to build for the target, using cross-compilation if possible. If the target > supports running binaries, or running tests (even if they do not pass), the > documentation must explain how to run such binaries or tests for the target, > using emulation if possible or dedicated hardware if necessary. Platform support document covers building instructions. > - Tier 3 targets must not impose burden on the authors of pull requests, or > other developers in the community, to maintain the target. In particular, > do not post comments (automated or manual) on a PR that derail or suggest a > block on the PR based on a tier 3 target. Do not send automated messages or > notifications (via any medium, including via `@`) to a PR author or others > involved with a PR regarding a tier 3 target, unless they have opted into > such messages. Understood. > - Backlinks such as those generated by the issue/PR tracker when linking to > an issue or PR are not considered a violation of this policy, within > reason. However, such messages (even on a separate repository) must not > generate notifications to anyone involved with a PR who has not requested > such notifications. Understood. > - Patches adding or updating tier 3 targets must not break any existing tier 2 > or tier 1 target, and must not knowingly break another tier 3 target without > approval of either the compiler team or the maintainers of the other tier 3 > target. Understood. > - In particular, this may come up when working on closely related targets, > such as variations of the same architecture with different features. Avoid > introducing unconditional uses of features that another variation of the > target may not have; use conditional compilation or runtime detection, as > appropriate, to let each target run code supported by that target. Understood. > - Tier 3 targets must be able to produce assembly using at least one of > rustc's supported backends from any host target. (Having support in a fork > of the backend is not sufficient, it must be upstream.) It is expected that the target should be able to compile binaries on any systems that are capable of compiling `aarch64` code.
2 parents 87e532e + 59b042d commit d0314ca

2 files changed

Lines changed: 14 additions & 5 deletions

File tree

src/common.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ use gccjit::{LValue, RValue, ToRValue, Type};
22
use rustc_abi::Primitive::Pointer;
33
use rustc_abi::{self as abi, HasDataLayout};
44
use rustc_codegen_ssa::traits::{
5-
BaseTypeCodegenMethods, ConstCodegenMethods, MiscCodegenMethods, StaticCodegenMethods,
5+
BaseTypeCodegenMethods, ConstCodegenMethods, MiscCodegenMethods, PacMetadata,
6+
StaticCodegenMethods,
67
};
78
use rustc_middle::mir::Mutability;
89
use rustc_middle::mir::interpret::{GlobalAlloc, PointerArithmetic, Scalar};
@@ -241,7 +242,13 @@ impl<'gcc, 'tcx> ConstCodegenMethods for CodegenCx<'gcc, 'tcx> {
241242
None
242243
}
243244

244-
fn scalar_to_backend(&self, cv: Scalar, layout: abi::Scalar, ty: Type<'gcc>) -> RValue<'gcc> {
245+
fn scalar_to_backend_with_pac(
246+
&self,
247+
cv: Scalar,
248+
layout: abi::Scalar,
249+
ty: Type<'gcc>,
250+
_pac: Option<PacMetadata>,
251+
) -> RValue<'gcc> {
245252
let bitsize = if layout.is_bool() { 1 } else { layout.size(self).bits() };
246253
match cv {
247254
Scalar::Int(int) => {
@@ -290,7 +297,7 @@ impl<'gcc, 'tcx> ConstCodegenMethods for CodegenCx<'gcc, 'tcx> {
290297
}
291298
value
292299
}
293-
GlobalAlloc::Function { instance, .. } => self.get_fn_addr(instance),
300+
GlobalAlloc::Function { instance, .. } => self.get_fn_addr(instance, None),
294301
GlobalAlloc::VTable(ty, dyn_ty) => {
295302
let alloc = self
296303
.tcx

src/context.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ use gccjit::{Block, CType, Context, Function, FunctionType, LValue, Location, RV
55
use rustc_abi::{Align, HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx};
66
use rustc_codegen_ssa::base::wants_msvc_seh;
77
use rustc_codegen_ssa::errors as ssa_errors;
8-
use rustc_codegen_ssa::traits::{BackendTypes, BaseTypeCodegenMethods, MiscCodegenMethods};
8+
use rustc_codegen_ssa::traits::{
9+
BackendTypes, BaseTypeCodegenMethods, MiscCodegenMethods, PacMetadata,
10+
};
911
use rustc_data_structures::base_n::{ALPHANUMERIC_ONLY, ToBaseN};
1012
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1113
use rustc_middle::mir::interpret::Allocation;
@@ -398,7 +400,7 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
398400
get_fn(self, instance)
399401
}
400402

401-
fn get_fn_addr(&self, instance: Instance<'tcx>) -> RValue<'gcc> {
403+
fn get_fn_addr(&self, instance: Instance<'tcx>, _pac: Option<PacMetadata>) -> RValue<'gcc> {
402404
let func_name = self.tcx.symbol_name(instance).name;
403405

404406
let func = if let Some(variable) = self.get_declared_value(func_name) {

0 commit comments

Comments
 (0)