Repository: rust
Issue: Tracking Issue for stabilisation of `-Z branch-protection`
Labels: C-tracking-issue

<!--
NOTE: For library features, please use the "Library Tracking Issue" template instead.

Thank you for creating a tracking issue! 📜 Tracking issues are for tracking a
feature from implementation to stabilisation. Make sure to include the relevant
RFC for the feature if it has one. Otherwise provide a short summary of the
feature and link any relevant PRs or issues, and remove any sections that are
not relevant to the feature.

Remember to add team labels to the tracking issue.
For a language team feature, this would e.g., be `T-lang`.
Such a feature should also be labeled with e.g., `F-my_feature`.
This label is used to associate issues (e.g., bugs and design questions) to the feature.
-->

This is a tracking issue for standardising the `-Z branch-protection=...` codegen option, which enables control-flow integrity measures using Armv8.3 pointer authentication and/or Armv8.5 branch target identification on AArch64.

### About tracking issues

Tracking issues are used to record the overall progress of implementation.
They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions.
A tracking issue is however *not* meant for large scale discussion, questions, or bug reports about a feature.
Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.

### Steps
<!--
Include each step required to complete the feature. Typically this is a PR
implementing a feature, followed by a PR that stabilises the feature. However
for larger features an implementation could be broken up into multiple PRs.
-->

- [x] Implement the unstable option (`-Z branch-protection`).
- [ ] Stabilization PR for the stable option (`-C branch-protection`).

[stabilization-guide]: https://rustc-dev-guide.rust-lang.org/stabilization_guide.html#stabilization-pr
[doc-guide]: https://rustc-dev-guide.rust-lang.org/stabilization_guide.html#documentation-prs

### Unresolved Questions
<!--
Include any open questions that need to be answered before the feature can be
stabilised.
-->

- [ ] Should this first be merged with [`cf-protection`](https://github.com/rust-lang/rust/issues/93754)? ([Zulip](https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/.60-Zbranch-protection.60.20stability))

### Future Work

Stabilisation of `branch-protection` is a necessary step for making these technologies straightforward to use, but there are other obstacles beyond the codegen option itself:

#### `std`

Deploying these CFI technologies typically requires all code in a process to be compiled with similar mitigations. For example, today you probably also need to use the unstable [`build-std`](https://doc.rust-lang.org/cargo/reference/unstable.html#build-std) to rebuild the standard library accordingly, otherwise ROP-style gadgets may still be present in `std`. One way to improve this for users would be to offer a pre-built standard library with (for example) `branch-protection=pac-ret,bti`, in addition to the baseline. However, such a mechanism requires further work, and is out of scope of this tracking issue.

#### LTO and module flag combination

Module flags in LLVM 14 and 15 behave quite differently (e.g. during LTO). LLVM 14 uses `Error`, so all modules must match. [LLVM 15 uses `Min`](https://github.com/rust-lang/rust/pull/105932), so module flags are downgraded to the lowest value, without notification. As a result, it's quite easy to accidentally disable these flags process-wide with LTO builds, for example by linking a single module that lacks an `sign-return-address-*` flag that otherwise expect. `::Min` also interacts awkwardly with the `bkey` configuration, which isn't inherently ordered.

We should address this, but it's really an LLVM concern rather than a Rust one. Rust _could_ provide an additional option to use the `Warning` module flag instead of `Min`, since LLVM always allows the two to combine, but this is also out of scope of this tracking issue.

### Implementation history

* https://github.com/rust-lang/rust/pull/88354
* https://github.com/rust-lang/rust/pull/93516
* https://github.com/rust-lang/rust/pull/105421
* https://github.com/rust-lang/rust/pull/105932