[PAC] Encoder and hash (1/8) - #159071
Conversation
bca55be to
8cf67b9
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
8cf67b9 to
7ee3f2c
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
7ee3f2c to
fdd1189
Compare
This comment has been minimized.
This comment has been minimized.
d798449 to
4c1b0ac
Compare
Done in: 5e05159 |
03337eb to
8b0e0ca
Compare
|
Some changes occurred in src/doc/rustc/src/platform-support cc @Noratrieb |
|
r? @wesleywiser rustbot has assigned @wesleywiser. Use Why was this reviewer chosen?The reviewer was selected based on:
|
|
r? compiler |
This patch implements Rust's equivalent of Clang's function pointer type discriminator computation used in pointer authentication. Compatibility with Clang is a primary goal. The discriminator produced for a given external "C" function type must match the value computed by Clang so that function pointers can be exchanged safely between Rust and C code while preserving pointer authentication semantics. The implementation mirrors Clang's behavior in `ASTContext::encodeTypeForFunctionPointerAuth`, ensuring that identical C-compatible function types produce identical discriminators. See: <https://clang.llvm.org/doxygen/ASTContext_8cpp.html#abb1375e068e807917527842d05cadea3>.
8b0e0ca to
67fd305
Compare
|
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. |
|
r? @davidtwco |
| @@ -0,0 +1,493 @@ | |||
| /*! | |||
There was a problem hiding this comment.
Use //! so that this is a documentation comment
| @@ -0,0 +1,142 @@ | |||
| // LLVM SipHash-2-4 | |||
There was a problem hiding this comment.
Why can't we just call LLVM's definitions of these over FFI from rustc_codegen_llvm? That let us avoid the need for this to remain identical to LLVM's definition
There was a problem hiding this comment.
LLVM's implementation is currently a header-only C++ template and does not expose a callable C ABI function. Using it through FFI would require introducing a new wrapper API with a specific interface shape.
Given the comments in code, the header only was a deliberate design decision:
// This is a header-only implementation of SipHash. It lacks library
// dependencies so it can be used from LLVM and compiler-rt.
I chose a direct Rust translation because the algorithm is small and stable, and it keeps the discriminator implementation self-contained. The implementation is easy to validate by using the same test vectors as LLVM's implementation.
| /// This is not a full semantic translation of Rust types. It is a lossy mapping | ||
| /// that intentionally matches Clang's function pointer authentication encoding | ||
| /// rules where Rust has a direct language-level equivalent. |
There was a problem hiding this comment.
These lines are duplicated
| let ty = canonicalize_c_type(tcx, ty); | ||
| match ty.kind() { | ||
| // C void / Rust () | ||
| ty::Tuple(list) if list.is_empty() => ClangDiscTy::Void, |
There was a problem hiding this comment.
_ if ty.is_unit() is clearer
|
|
||
| loop { | ||
| match ty.kind() { | ||
| ty::Adt(def, args) if tcx.is_diagnostic_item(sym::Option, def.did()) => { |
There was a problem hiding this comment.
You should use the LangItem::Option, rather than the diagnostic item, given this isn't for a diagnostic.
There was a problem hiding this comment.
Done, had to add #[lang = "Option"] to minicore's Option.
|
|
||
| // Clang disc type. | ||
| #[derive(Debug)] | ||
| enum ClangDiscTy<'tcx> { |
There was a problem hiding this comment.
I'm not sure what we're gaining from having this intermediate representation - the mapping seems straightforward enough that you could just go direct from a Ty to a encoding
There was a problem hiding this comment.
The main benefit of this separation is to decouple Rust type handling from the encoding logic.
Clang's discriminator computation is based on its own normalized type categories, not on the full C type set. Rust needs to produce identical encodings for equivalent ABI types, so the implementation first normalizes Rust types into the corresponding Clang discriminator categories.
This separation allows the encoding logic to remain aligned with Clang's implementation, while the Rust-specific part is responsible only for the type translation: determining which Rust types map to which Clang discriminator categories. Without it Rust type matching and encoding would be intertwined, making it harder to keep the encoding logic identical between the two compilers.
For example, if Clang extends the encoding in the future (such as adding support for 128-bit types, which is in progress now), we can port the encoding changes directly and only need to extend the Rust type matcher to map the new Rust types into the corresponding Clang categories.
| All tests from `assembly-llvm`, `codegen-llvm`, `codegen-units`, `coverage`, | ||
| `crashes`, `incremental`, `library`, `mir-opt`, `run-make`, `ui` and | ||
| `ui-fulldeps` subsets are expected to pass. | ||
| `crashes`, `incremental`, `library`, `mir-opt`, `run-make`, `rust_middle` `ui` |
There was a problem hiding this comment.
| `crashes`, `incremental`, `library`, `mir-opt`, `run-make`, `rust_middle` `ui` | |
| `crashes`, `incremental`, `library`, `mir-opt`, `run-make`, `rust_middle`, `ui` |
|
Reminder, once the PR becomes ready for a review, use |
67fd305 to
43ed719
Compare
|
@rustbot ready |
|
|
||
| use super::*; | ||
|
|
||
| // These tests mirror the SipHash tests from LLVM's Support/SipHashTest.cpp. |
There was a problem hiding this comment.
Are there licensing implications of this?
There was a problem hiding this comment.
I don't believe this introduces a licensing issue. LLVM appears to be using the reference vectors verbatim from the SipHash test vectors, which originate from: https://github.com/veorq/SipHash/blob/master/vectors.h
The tests here are just a trivial loop over those values to verify the implementation against the known reference outputs.
That said, I am not a lawyer and cannot provide any formal legal guarantee.
View all comments
This patch implements Rust's equivalent of Clang's function pointer type discriminator computation used for pointer authentication. Compatibility with Clang is a primary design goal. For a given extern "C" function type, the discriminator produced by Rust must match the value computed by Clang so that function pointers can be exchanged safely between Rust and C code while preserving pointer authentication semantics.
The implementation mirrors Clang's behavior in ASTContext::encodeTypeForFunctionPointerAuth, ensuring that identical C-compatible function types produce identical discriminators. See: https://clang.llvm.org/doxygen/ASTContext_8cpp.html#abb1375e068e807917527842d05cadea3.
This is part 1 of a sequence of 8 PRs that together implement support for function pointer type discrimination:
Useful links:
pauthtestintroduction: Introduce aarch64-unknown-linux-pauthtest target #155722