Skip to content
/ rust Public
forked from rust-lang/rust

Commit 6513df9

Browse files
DarksonnRalfJung
andcommitted
Add comment
Co-authored-by: Ralf Jung <[email protected]>
1 parent 1cbdfab commit 6513df9

File tree

1 file changed

+19
-0
lines changed
  • library/core/src/fmt

1 file changed

+19
-0
lines changed

Diff for: library/core/src/fmt/rt.rs

+19
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,25 @@ macro_rules! argument_new {
7272
// a `fn(&T, ...)`, so the invariant is maintained.
7373
ty: ArgumentType::Placeholder {
7474
value: NonNull::<$t>::from_ref($x).cast(),
75+
// The Rust ABI considers all pointers to be equivalent, so transmuting a fn(&T) to
76+
// fn(NonNull<()>) and calling it with a NonNull<()> that points at a T is allowed.
77+
// However, the CFI sanitizer does not allow this, and triggers a crash when it
78+
// happens.
79+
//
80+
// To avoid this crash, we use a helper function when CFI is enabled. To avoid the
81+
// cost of this helper function (mainly code-size) when it is not needed, we
82+
// transmute the function pointer otherwise.
83+
//
84+
// This is similar to what the Rust compiler does internally with vtables when KCFI
85+
// is enabled, where it generates trampoline functions that only serve to adjust the
86+
// expected type of the argument. `ArgumentType::Placeholder` is a bit like a
87+
// manually constructed trait object, so it is not surprising that the same approach
88+
// has to be applied here as well.
89+
//
90+
// It is still considered problematic (from the Rust side) that CFI rejects entirely
91+
// legal Rust programs, so we do not consider anything done here a stable guarantee,
92+
// but meanwhile we carry this work-around to keep Rust compatible with CFI and
93+
// KCFI.
7594
#[cfg(not(any(sanitize = "cfi", sanitize = "kcfi")))]
7695
formatter: {
7796
let f: fn(&$t, &mut Formatter<'_>) -> Result = $f;

0 commit comments

Comments
 (0)