Skip to content

[PAC] ABI-compatibility rules for discriminator calculation (4.5/8) - #163103

Open
jchlanda wants to merge 8 commits into
rust-lang:mainfrom
jchlanda:jakub/pac_ty_disc_PR_4_and_a_half
Open

jchlanda wants to merge 8 commits into
rust-lang:mainfrom
jchlanda:jakub/pac_ty_disc_PR_4_and_a_half

Conversation

@jchlanda

@jchlanda jchlanda commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

View all comments

This patch extends the discriminator calculation logic to honour Rust's ABI compatibility rules. If two types are ABI compatible they must end up with the same discriminator.

The patch also includes a UI-based test (inspired by layout dump test) that enforces the rule.


This is part 2 of a sequence of 8 PRs that together implement support for function pointer type discrimination:

  1. Encoder and hash
  2. FnAbi, llvm.ptrauth.resign and Session API change
  3. FPTR_TYPE_DISCR in ABI Version
  4. Static allocs
  1. Transmutes
  2. Propagate discriminator logic through remaining get_fn_ptr calls sites
  3. Minicore updates to support fn ptr type discriminator tests
  4. Fn ptr type discrimination tests

Useful links:

@rustbot

rustbot commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator

Some changes occurred in compiler/rustc_passes/src/check_attr.rs

cc @jdonszelmann, @JonathanBrouwer

rustc_codegen_gcc is developed in its own repository. If possible, consider making this change to rust-lang/rustc_codegen_gcc instead.

cc @antoyo, @GuillaumeGomez

Some changes occurred in compiler/rustc_attr_parsing

cc @jdonszelmann, @JonathanBrouwer

Some changes occurred in compiler/rustc_attr_ir

cc @jdonszelmann, @JonathanBrouwer

@rustbot rustbot added the A-attributes Area: Attributes (`#[…]`, `#![…]`) label Sep 21, 2026
@rustbot rustbot added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Sep 21, 2026
@rustbot

rustbot commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator

r? @folkertdev

rustbot has assigned @folkertdev.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler
  • compiler expanded to 77 candidates
  • Random selection from 18 candidates

@rust-log-analyzer

This comment has been minimized.

@folkertdev

Copy link
Copy Markdown
Contributor

r? davidtwco (who I believe is the dedicated reviewer for PAC)

@rustbot rustbot assigned davidtwco and unassigned folkertdev Sep 21, 2026
@jchlanda jchlanda changed the title [PAC] ABI-compatibility rules for discriminator calculation [PAC] ABI-compatibility rules for discriminator calculation (4.5) Sep 21, 2026
@jchlanda jchlanda changed the title [PAC] ABI-compatibility rules for discriminator calculation (4.5) [PAC] ABI-compatibility rules for discriminator calculation (4.5/8) Sep 21, 2026
@jchlanda
jchlanda force-pushed the jakub/pac_ty_disc_PR_4_and_a_half branch from e049e45 to 1eb204a Compare September 21, 2026 11:39
This patch introduces the following:

* Extends `FnAbi` (`callconv`) with a `ptrauth_type_discriminator`
  field. This field is only used when emitting pointer authentication
  call bundles. It is stored in `FnAbi` because the call site is not
  guaranteed to have access to an `Instance`, so the discriminator
  cannot always be computed on demand.
* Adds support for `llvm.ptrauth.resign`. This intrinsic will be used
  when support for semantic transmute is added.
* Performs a minor API redesign as groundwork for allowing call sites to
  modify schemas in place.
Also remove error messages/tests that used to guarded it.
The codegen now walks the layout of static initializer types to find extern "C"
function pointer fields, computes their type discriminators, and applies those
discriminators when emitting authenticated function pointer relocations.

Also make sure that type discrimination is never applied to init/fini
entries.
This covers standalone function pointer constants, promoted temporaries,
immutable and mutable statics, arrays of function pointers, and mixed
structs containing function pointers. Consult
pauth-fn-ptr-type-discrimination-static-allocs.rs test for example uses.

Revolves around threading PAC information through:
* static_addr_of (StaticCodegenMethods)
* from_const and from_const_alloc (both on rustc_codegen_ssa::mir::operand / OperandRef)
Also a fix for non function (closure, coroutines, etc) in
discriminator_input.
Fix in v-table assert.
Meaning if two types are ABI compatible they must have the same encoding
and hash value.

Provide a ui test which groups the function pointers by the ABI
compatibility rules and enforces the rule.
@jchlanda
jchlanda force-pushed the jakub/pac_ty_disc_PR_4_and_a_half branch from 1eb204a to bb798a1 Compare September 21, 2026 12:12
@rustbot

rustbot commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

// also ABI-compatible with each other for different T if they have the same
// metadata type (<T as Pointee>::Metadata)."
#[rustc_dump_ptrauth_discriminator(ptrauth_encoding, ptrauth_hash)]
extern "C" fn g1_a(_: *const i32) {} // expect: "FvPE": 10942 (0x2abe)

@bjorn3 bjorn3 Sep 21, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any reason not to do this?

Suggested change
extern "C" fn g1_a(_: *const i32) {} // expect: "FvPE": 10942 (0x2abe)
extern "C" fn g1_a(_: *const i32) {} //~ ERROR ptrauth discriminator encoding: "FvPE"

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I followed how rustc_dump_layout is handled, for example: https://github.com/rust-lang/rust/blob/main/tests/ui/attributes/doc_examples/rustc_dump_layout_align.rs#L1Press

//@ dont-require-annotations: ERROR seems like a nice trick to reduce the noise.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case you are already saying what you expect in the test itself, but not letting compiletest check that the expectation matches. If you are worried about the "ptrauth discriminator encoding" noise, maybe it would be possible to normalize that away?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if I understand your point. My idea was to be able to check what the discriminator is right at the point of calculating it, not when it's attached to a call instruction or function pointer address. That's why I decided to use attribute. The down side of it is that we effectively are saying "as long as the stderr match all is good", rather than doing more sophisticated check (like FileCheck capture plus match for example).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

//~ ERROR ptrauth discriminator encoding: "FvPE" will match the error message that was emitted to stderr similar to filecheck. Just without regex support. So my question is why you used // expect: "FvPE": 10942 (0x2abe) (which is not checked by compiletest) instead of //~ ERROR ptrauth discriminator encoding: "FvPE" (which is checked)?

@jchlanda jchlanda Sep 21, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, so for each use of #[rustc_dump_ptrauth_discriminator(ptrauth_encoding, ptrauth_hash)] you get:

error: ptrauth discriminator encoding: "FvPE"
  --> $DIR/discriminator-abi-compat-encoder-and-hash.rs:47:1
   |
LL | extern "C" fn g1_a(_: *const i32) {} // expect: "FvPE": 10942 (0x2abe)
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: ptrauth discriminator hash: 10942 (0x2abe)
  --> $DIR/discriminator-abi-compat-encoder-and-hash.rs:47:1
   |
LL | extern "C" fn g1_a(_: *const i32) {} // expect: "FvPE": 10942 (0x2abe)
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Which is a mixture of:

  • compiler generated message error: ptrauth discriminator encoding: "FvPE" / error: ptrauth discriminator hash: 10942 (0x2abe)
  • my comment // expect: "FvPE": 10942 (0x2abe)

I though it was quite neat, as it gives you an immediate feedback, should this ever fail it will be clear what two values were expected.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I missed that you produce two errors. That makes the //~ ERROR way less ergonomic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-attributes Area: Attributes (`#[…]`, `#![…]`) A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants