Skip to content

Commit b0e56db

Browse files
authoredFeb 13, 2025··
Merge pull request #3716 from Darksonn/target-modifiers
[RFC] Target Modifiers
2 parents 1c590ce + 37b1d9d commit b0e56db

File tree

1 file changed

+523
-0
lines changed

1 file changed

+523
-0
lines changed
 

‎text/3716-target-modifiers.md

+523
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,523 @@
1+
- Feature Name: `target_modifiers`
2+
- Start Date: 2024-10-24
3+
- RFC PR: [rust-lang/rfcs#3716](https://github.com/rust-lang/rfcs/pull/3716)
4+
- Rust Issue: None
5+
6+
# Summary
7+
[summary]: #summary
8+
9+
* We introduce the concept of "target modifier". A target modifier is a flag
10+
where it may be unsound if you link together two compilation units that
11+
disagree on the flag.
12+
* We fail the build if rustc can see two Rust compilation units that do not
13+
agree on the exact set of target modifier flags.
14+
* There are already several existing flags that could fall into this category.
15+
There are also hypothetical new flags that do.
16+
* The error can be silenced using the `-Cunsafe-allow-abi-mismatch` escape
17+
hatch.
18+
* Not having a stable way to build stdlib crates does not block stabilization
19+
of target modifiers.
20+
* As a future extension we may be able to relax the rules to allow some
21+
specific kinds of mismatches.
22+
* This RFC does not stabilize any target modifiers. That should happen in
23+
follow-up MCPs/FCPs/RFCs/etc.
24+
25+
# Motivation
26+
[motivation]: #motivation
27+
28+
As Rust expands into low-level domains, there will be a need for precise
29+
control over how code is compiled. This often manifests as a new compiler flag.
30+
Some of these flags trigger undefined behavior if used incorrectly, which is in
31+
tension with Rust's safety goals. This RFC proposes a new mechanism to allow
32+
use of such flags while also preventing undefined behavior.
33+
34+
The primary goal of this RFC is to unblock *stabilization* of target modifier
35+
flags. Adding them as unstable (and unsound) flags is already happening today
36+
without this RFC.
37+
38+
## The Linux Kernel
39+
40+
The Linux Kernel has run into a handful of cases where it is necessary to tweak
41+
the ABI used in the kernel. Often, this is done conditionally depending on a
42+
configuration option. A few examples:
43+
44+
* When using `CONFIG_SHADOW_CALLSTACK` the x18 register must be reserved in the
45+
ABI with `-Zfixed-x18`.
46+
* The `-Ctarget-feature=-neon` flag is used to prevent use of floating points
47+
on arm.
48+
* On 32-bit x86, `-Zreg-struct-return` and `-Zregparm=3` are used.
49+
* When using `CONFIG_CFI_CLANG` the kCFI sanitizer is enabled with
50+
`-Zsanitizer=kcfi`. Unlike most other sanitizers, this sanitizer is used in
51+
production.
52+
* In several different cases, `-Zpatchable-function-entry` is used to add nops
53+
before or after the function entrypoint. When mixed with `-Zsanitizer=kcfi`
54+
this causes special considerations as kcfi works by placing a tag before the
55+
function entrypoint.
56+
* To support `MITIGATION_RETPOLINE` and `MITIGATION_SLS`, `target.json` is used
57+
on x86.
58+
59+
We expect there to be more examples in the future.
60+
61+
## Sanitizers
62+
63+
There is [an ongoing effort to stabilize some of the sanitizers][issue123615].
64+
However, this effort explicitly aims to stabilize sanitizers that can be used
65+
without rebuilding the stdlib. With this RFC, that is no longer a blocker as
66+
the remaining sanitizers can be classified as a target modifier and then
67+
stabilized.
68+
69+
[issue123615]: https://github.com/rust-lang/rust/issues/123615
70+
71+
## Embedded Targets
72+
73+
Currently, embedded platforms such as `thumb*` or `rv*` use separate targets
74+
for configuration with significant ABI changes. For `thumb*` targets, this is
75+
currently limited to Hard- vs Soft-Float which can cause issues when linked.
76+
However for RISC-V targets, the F (32-bit hardware float), D (64-bit hardware
77+
float), and Q (128-bit hardware float) extensions all can [potentially change
78+
the ABI][riscv-float], which would increase the number of required targets. The
79+
[E extension][riscv-e] may also change the ABI by limiting the number of
80+
registers used by the I (integer operations) extension.
81+
82+
[riscv-float]: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc#named-abis
83+
[riscv-e]: https://github.com/riscv/riscv-isa-manual/blob/main/src/rv32e.adoc
84+
85+
## Existing -C flags that are unsound
86+
87+
It has recently been discovered that several existing `-C` flags modify the
88+
ABI, making them unsound. Examples:
89+
90+
* [`-Csoft-float`](https://github.com/rust-lang/rust/issues/129893)
91+
* [`-Ctarget-feature=-neon`](https://github.com/rust-lang/rust/issues/131058)
92+
* [`-Clinker-plugin-lto`](https://github.com/rust-lang/rust/issues/127979)
93+
* [`-Cllvm-args`](https://github.com/rust-lang/rust/issues/131800#issuecomment-2418595757)
94+
* Possibly `-Ccode-model` and `-Crelocation-model`
95+
96+
This problem is a new discovery and it's still not clear how to solve it.
97+
Target modifiers will not solve all of the flags; [some flags are just
98+
unfixable and need to be removed][issue130968]. But I expect that target
99+
modifiers will be the solution for some of these flags.
100+
101+
[issue130968]: https://github.com/rust-lang/rust/issues/130968
102+
103+
# Guide-level explanation
104+
[guide-level-explanation]: #guide-level-explanation
105+
106+
The Rust compiler has many flags that affect how source code is turned into
107+
machine code. Some flags can be turned on and off for each CU (compilation
108+
unit) in your project separately, and other flags must be applied to the entire
109+
application as a whole. The typical reason for flags to be in the latter
110+
category is that change some aspect of the ABI. For example,
111+
`-Zreg-struct-return` changes how to return a struct from a function call, and
112+
both the caller and callee must agree on how to do that even if they are in
113+
different CUs.
114+
115+
The Rust compiler will detect if you incorrectly use a flag that must be
116+
applied to the application as a whole. For example, if you compile the standard
117+
library with `-Zreg-struct-return`, but don't pass the flag when compiling a
118+
dependency, then you will get the following error:
119+
```
120+
error: mixing -Zreg-struct-return will cause an ABI mismatch
121+
122+
help: This error occurs because the -Zreg-struct-return flag modifies the ABI,
123+
and different crates in your project were compiled with inconsistent
124+
settings.
125+
help: To resolve this, ensure that -Zreg-struct-return is set to the same value
126+
for all crates during compilation.
127+
help: To ignore this error, recompile with the following flag:
128+
-Cunsafe-allow-abi-mismatch=reg-struct-return
129+
```
130+
As an escape hatch, you can use `-Cunsafe-allow-abi-mismatch=reg-struct-return`
131+
to disable the error. Using this flag is unsafe as incorrect use of the ABI is
132+
undefined behavior. However, there may be some cases where the check is too
133+
strict, and you can use the flag to proceed in those cases.
134+
135+
The requirement that all CUs agree includes stdlib crates (core, alloc, std),
136+
so using these flags usually requires that you compile your own standard
137+
library with `-Zbuild-std` or by directly invoking `rustc`. That said, some
138+
flags (e.g., `-Cpanic`) have mechanisms to avoid this requirement.
139+
140+
# Reference-level explanation
141+
[reference-level-explanation]: #reference-level-explanation
142+
143+
A compiler flag can be classified as a _target modifier_. When a flag is a
144+
target modifier, it can be undefined behavior to link together two CUs that
145+
disagree on the flag.
146+
147+
To avoid unsoundness from mixing target modifiers, rustc will store the set of
148+
target modifiers in use in the crate metadata of each crate. Whenever rustc is
149+
invoked, it will inspect the crate metadata of all crates that are visible to
150+
it (usually the current crate and its direct dependencies) and emit an error if
151+
any of them have mismatched target modifiers in use.
152+
153+
The `-Cunsafe-allow-abi-mismatch=flagname` flag can be used when compiling a
154+
crate to indicate that it should not be included in the list of crates when
155+
checking that all crates agree on `flagname`.
156+
157+
Note that `-Cunsafe-allow-abi-mismatch=flagname` should be passed to rustc when
158+
compiling the crate that uses an incompatible value for `flagname`, which may
159+
not be the same rustc invocation as the one where the mismatch is detected. For
160+
example, if you build four CUs A,B,C,D where D depends on A,B,C and C is the
161+
only one with a different value for `flagname`, then the mismatch is detected
162+
by rustc when compiling D, but `-Cunsafe-allow-abi-mismatch` should be used
163+
when compiling C.
164+
165+
## Stabilization
166+
167+
It is possible to stabilize target modifiers even if they cannot be utilized
168+
without an unstable feature such as `-Zbuild-std`.
169+
170+
# Drawbacks
171+
[drawbacks]: #drawbacks
172+
173+
## Teaching
174+
[teaching]: #teaching
175+
176+
We should be careful to not introduce too many concepts that end-users have to
177+
learn.
178+
179+
It is intentional that the guide-level section of this RFC does not use the
180+
word "target modifier". The "target modifier" name is not intended to be used
181+
outside of the compiler internals and very technical documentation. Compiler
182+
errors should not say "error: trying to mix target modifiers" or something like
183+
that; rather the error should just say that mixing `-Cfoo` may cause ABI
184+
issues.
185+
186+
For similar reasons, the flag for silencing the error is called
187+
`-Cunsafe-allow-abi-mismatch` with the word "ABI" to avoid having to teach the
188+
user about mismatched flags or target modifiers.
189+
190+
# Rationale and alternatives
191+
[rationale-and-alternatives]: #rationale-and-alternatives
192+
193+
## Why not just add flags like normal?
194+
195+
Preventing undefined behaviour is an important goal of the Rust project. If we
196+
add flags that change the abi, then that is in direct opposition to that goal,
197+
as mixing them would lead to UB.
198+
199+
## Why not just add new targets?
200+
201+
The flag that started this entire discussion is `-Zfixed-x18`. This flag
202+
changes the ABI by changing the x18 register from a caller-saved temporary
203+
register to a reserved register. At the time, people suggested adding a new
204+
target (e.g., `aarch64-unknown-none-fixed18`), instead of adding a dedicated
205+
`-Zfixed-x18` flag.
206+
207+
The primary benefit of adding a new target is that it's a workaround for
208+
`-Zbuild-std` being unstable. Each new target will get a prebuilt stdlib, which
209+
sidesteps the need for building your own stdlib.
210+
211+
This RFC does not propose this solution because:
212+
213+
1. The primary benefit is not being blocked on stabilization of `-Zbuild-std`.
214+
However, I don't think we really are blocked on stabilization of
215+
`-Zbuild-std` in the first place. See [the stabilization of target modifier
216+
flags section][stabilization] below.
217+
2. Target modifiers help with other problems such as unblocking the
218+
stabilization of sanitizers as well as existing `-C` flags that are unsound
219+
due to ABI issues. Adding new targets would leave these issues unsolved.
220+
3. Adding new targets risks an exponential number of targets. In the kernel on
221+
x86 we would need 8 different targets to support the different possible
222+
kernel configurations. It's not hard to imagine that number growing to 16 or
223+
32 targets in the near future, especially once you consider that other
224+
embedded projects may have their own set of target modifier flags.
225+
4. Adding new prebuilt stdlibs does not actually help the projects that need
226+
these flags. Even if a prebuilt stdlib is provided for every combination of
227+
ABI-affecting flags that the kernel may need, the kernel has other reasons
228+
that require building a custom `core`.
229+
230+
## Why not use `target.json`
231+
232+
Because the `target.json` feature is perma-unstable, and this RFC primarily
233+
concerns itself with unblocking the _stabilization_ of these flags. Adding
234+
target modifiers as unstable flags is already happening today. (However, if
235+
this RFC gets accepted, it becomes a soundness bug to add such unstable flags
236+
without wiring them up with the target modifier machinery.)
237+
238+
One possible alternative would be to stabilize a subset of `target.json`.
239+
However, I don't think there's much benefit to this. It just means that you now
240+
have to learn two different ways of passing flags to the compiler. See [the
241+
Teaching section][teaching] above.
242+
243+
It would also be inconvenient to use in external build systems. Right now, the
244+
kernel passes the `-Zfixed-x18` flag like this:
245+
```make
246+
ifeq ($(CONFIG_SHADOW_CALL_STACK), y)
247+
KBUILD_CFLAGS += -ffixed-x18
248+
KBUILD_RUSTFLAGS += -Zfixed-x18
249+
endif
250+
```
251+
If `-Zfixed-x18` had to be specified in a `target.json` file, it would need to
252+
happen in an entirely different part of the kernel build system. It is better
253+
to specify the rustc flag together with the clang/gcc flag.
254+
255+
## Stabilization of target modifiers
256+
[stabilization]: #stabilization-of-target-modifiers
257+
258+
Using a target modifier without rebuilding the Rust stdlib is often not
259+
possible. This means that some target modifiers can only be used in tandem with
260+
`-Zbuild-std`, which is currently unstable.
261+
262+
However, there's no reason we _have_ to block the stabilization of target
263+
modifiers on the stabilization of `-Zbuild-std`. If a target modifier `-Cfoo`
264+
is stabilized, then you can break users of `-Cfoo` with the reason "we changed
265+
the way you pass flags to `core`", but you can't break users with the reason
266+
"we renamed `-Cfoo` to `-Cbar`; this is okay because you're also using
267+
`-Zbuild-std` even though the rename is unrelated to `-Zbuild-std`".
268+
269+
## Not all mismatches are unsound
270+
[not-all-unsound]: #not-all-mismatches-are-unsound
271+
272+
This RFC says that mismatching target modifiers in any way results in a build
273+
error. However, there are a lot of cases where the real rules are more
274+
complicated than that. For example, with the following three CUs:
275+
276+
* CU A compiled with `-Zfixed-x18 -Zsanitizer=shadow-call-stack`.
277+
* CU B compiled with `-Zfixed-x18`.
278+
* CU C compiled with neither flag.
279+
280+
It is unsound to link together CUs A and C, but linking A with B or B with C is
281+
sound.
282+
283+
However, real-world scenarios where mismatching a target modifier is necessary
284+
are quite uncommon. The only case I'm aware of is the runtime for a sanitizer.
285+
For example, when ASAN (address sanitizer) detects a bug, it calls into a
286+
special ASAN-failure-handler function. The function for handling ASAN-failures
287+
should not be sanitized.
288+
289+
Making the compiler accept specific mismatches that are sound is out of scope
290+
for this RFC. Such decisions will be made on a flag-by-flag basis in follow-up
291+
decisions (most likely an MCP). Until then, end-users can use
292+
`-Cunsafe-allow-abi-mismatch` to proceed in such cases.
293+
294+
## Cases that are not caught
295+
[not-caught]: #cases-that-are-not-caught
296+
297+
This RFC proposes to store information in the crate metadata to detect ABI
298+
mismatches. However, this means that there are two cases that could result in
299+
mismatches being missed:
300+
301+
* When rustc is not doing the final link, different incompatible leaf modules
302+
might not get detected. For instance, using the CUs A,B,C from [the previous
303+
section][not-all-unsound], then if stdlib is CU B and there are two leaf CUs
304+
A and C, then the incompatibility between A and C would not get detected
305+
unless rustc performs the final link.
306+
* With dynamic linking, you may have two shared objects compiled completely
307+
separately with incompatible ABIs.
308+
309+
Note that the first situation can never happen with the base proposal: if we
310+
require exact matches, then all CUs must agree because all CUs depend on
311+
`core`. The missed detection requires that we don't consider AB or BC
312+
incompatible. This could be an argument in favor of not allowing any mismatches
313+
with the shadow call stack sanitizer (which you never want to mix in practice
314+
anyway).
315+
316+
The dynamic linking case is considered acceptable. Detecting it is out of scope
317+
of this RFC.
318+
319+
## Name mangling
320+
321+
It has been proposed that the modified target could be encoded in the name
322+
mangling scheme to help catch the two cases from [the previous
323+
section][not-caught]. However, this raises a bunch of open questions:
324+
325+
1. It probably does not help catch the first case. Dynamic function calls
326+
between the leaf modules wouldn't get caught, so that would require that one
327+
of the leaf modules references a symbol defined by the other leaf module.
328+
However, I find it hard to imagine this happening in the real world unless
329+
the symbol is marked `#[no_mangle]`.
330+
2. Similarly, if two dynamic objects are compiled completely separately, they
331+
probably do not reference each other through anything other than symbols
332+
marked `#[no_mangle]`. While it could potentially identify a mismatch where
333+
component A depends on component B, and component B is recompiled with a
334+
different ABI while using the old version of A, this scenario is not
335+
well-supported to start with because of Rust's unstable ABI.
336+
3. Some ABI-affecting flags only change the C ABI, but those symbols are
337+
usually using `#[no_mangle]`.
338+
4. Do we really want to make our symbol names even longer?
339+
340+
For the above reasons, name mangling is not proposed as a mechanism for
341+
detection for now. However, it could be a potential future addition.
342+
343+
## Policy around flags that might not be ABI affecting
344+
345+
Some flags have an unclear status where it is unclear whether it affects the
346+
ABI. For example, `-Zpatchable-function-entry` (which adds nop instructions
347+
before/after the function entrypoint) generally isn't considered to affect the
348+
ABI, but if combined with `-Zsanitizer=kcfi` then it does affect it since kcfi
349+
works by placing a hash of the function signature before the function
350+
entrypoint. Since `-Zsanitizer=kcfi` already needs to be a target modifier
351+
_anyway_, you could argue that `-Zpatchable-function-entry` doesn't need to be
352+
one.
353+
354+
However, for these cases where we are uncertain, we take a conservative
355+
approach and mark them as a target modifier. It is not breaking to relax the
356+
rules in future releases.
357+
358+
As for flags such as `-Cllvm-args` that can do basically anything, it may make
359+
more sense to just rename it to `-Cunsafe-llvm-args` rather than use the target
360+
modifier functionality.
361+
362+
## Problems with mixing non-target-modifiers
363+
364+
I discussed this proposal with people from other communities (mainly kernel and
365+
C folks), and they shared several other cases where mixing flags are a problem.
366+
They pointed out that there are some flags where mixing them is really bad and
367+
should be detected, but which are not ABI issues or unsound per se. The most
368+
common example of this is exploit mitigations, where mixing the flags will
369+
silently lead to a vulnerable binary. On the other hand, ABI mismatches usually
370+
fail in a loud way, so they were not as concerned about those.
371+
372+
The sections below describe several such cases. They are intended to provide
373+
additional context for the reader to better understand the problem space. We
374+
will likely want to use the same infrastructure for detecting some of the
375+
mismatches mentioned below, but the precise list is out of scope of this RFC.
376+
377+
Since the cases below are not unsound, the flag for overriding them should not
378+
include the word "unsafe".
379+
380+
### Exploit mitigations
381+
382+
There are some mitigations that are used to mitigate CPU speculation
383+
vulnerabilities (e.g., SPECTRE) or used to make exploitation of vulnerabilities
384+
harder (e.g., control flow protection), which work by either telling the
385+
compiler to generate code that include instructions to prevent CPU speculation
386+
in some specific locations, or telling the compiler to generate code that
387+
checks that destinations of indirect branches are one of their valid
388+
destinations in the control flow graph. These mitigations usually don't change
389+
the ABI, as they just change how code is generated within functions.
390+
391+
The problem is that the attacks you are trying to mitigate involve either
392+
forcing CPU speculation in some specific locations or changing the control flow
393+
to an arbitrary attacker-controlled address. If you have an unprotected
394+
specific location or unprotected indirect branch anywhere in your program, an
395+
attacker may still be able to use it either forcing CPU speculation in these
396+
unprotected specific locations, or by changing addresses in memory used by
397+
these unprotected indirect branches. This means that if you only apply the
398+
mitigation to some CUs, then the CUs that lack the mitigation will be
399+
completely unprotected, and the mitigation might be bypassable.
400+
401+
### Sanitizers
402+
403+
This case is rather similar to exploit mitigations.
404+
405+
Some sanitizers can be mixed and matched between CUs without breaking the ABI.
406+
For example, on the Android aarch64 target, the shadow call stack sanitizer
407+
does not change the ABI, and can be freely mixed between CUs. However, the
408+
sanitizer does not catch violations in CUs that don't enable the sanitizer.
409+
410+
For sanitizers used in production (such as shadow call stack or kcfi) this is
411+
particularly problematic, as a vulnerability in sanitized code may allow you to
412+
jump into unsanitized code.
413+
414+
### .note.gnu.property
415+
416+
In the case of BTI (`-Zbranch-protection=bti`), the mitigation relies on the
417+
kernel's ELF loader setting a special bit in the page table. However, setting
418+
this bit is only valid if BTI is enabled everywhere. The compiler will use a
419+
section called `.note.gnu.property` to tell the linker whether BTI is enabled,
420+
and the linker only propagates `.note.gnu.property` if all CUs agree on it.
421+
This means that if one CU is missing BTI, the linker will disable it for the
422+
entire executable, and the kernel's ELF loader will not set the bit in the page
423+
tables when loading the machine code, rendering BTI ineffective.
424+
425+
### Performance
426+
427+
Another reason is performance. One some targets, the precompiled stdlib always
428+
comes with panic landing pads, even if you're using `-Cpanic=abort`. It's also
429+
usually compiled with a very minimal set of target features for greater
430+
compatibility. These discrepancies can have an unacceptable impact on
431+
performance.
432+
433+
### Code patching
434+
435+
You might use `-Zbranch-protection=pac-ret` or `-Zpatchable-function-entry` to
436+
insert special instructions at the beginning/end of all functions so you can
437+
use runtime code-patching to replace them later. It is only because of the
438+
runtime code-patching logic that these flags need to be used everywhere.
439+
440+
### Debugging information
441+
442+
Mixing CUs with different options for `-Cforce-unwind-tables`,
443+
`-Zdwarf-version`, or `-Zdebuginfo-compression` may result in a binary that you
444+
consider to be invalid as you may be unable to read the debugging information.
445+
But it would not be an ABI issue.
446+
447+
# Prior art
448+
[prior-art]: #prior-art
449+
450+
## The panic strategy
451+
452+
The Rust compiler already *has* infrastructure to detect flag mismatches: the
453+
flags `-Cpanic` and `-Zpanic-in-drop`. The prebuilt stdlib comes with different
454+
pieces depending on which strategy is used, although panic landing flags are
455+
not entirely removed when using `-Cpanic=abort`, as only part of the prebuilt
456+
stdlib is switched out.
457+
458+
## Global target modifiers
459+
460+
A suggestion that has come up several times
461+
([1](https://github.com/rust-lang/rust/issues/116972),
462+
[2](https://github.com/rust-lang/rust/issues/116973),
463+
[3](https://github.com/rust-lang/rust/issues/121970#issuecomment-1978605782))
464+
is to have a variation of `-Ctarget-feature=` that must be applied globally,
465+
which could be called `-Cglobal-target-features=`. This is very similar to this
466+
RFC, though it is broader as the "target modifier" concept can apply to any
467+
compiler flag and not just to a single `-Cglobal-target-features=` flag.
468+
469+
## Stabilization of things that require nightly features
470+
471+
This RFC proposes that we shouldn't block stabilization of target modifiers on
472+
a stable way to build libcore. There is precedent in the rust project for
473+
unblocking stabilizations in this manner: When `#![no_std]` was stabilized,
474+
[the RFC][rfc1184] said the following:
475+
476+
> As mentioned above, there are three separate lang items which are required by
477+
> the libcore library to link correctly. These items are:
478+
>
479+
> * `panic_fmt`
480+
> * `stack_exhausted`
481+
> * `eh_personality`
482+
>
483+
> This RFC does not attempt to stabilize these lang items for a number of
484+
> reasons:
485+
>
486+
> * The exact set of these lang items is somewhat nebulous and may change over
487+
> time.
488+
> * The signatures of each of these lang items can either be platform-specific
489+
> or it’s just “too weird” to stabilize.
490+
> * These items are pretty obscure and it’s not very widely known what they do
491+
> or how they should be implemented.
492+
>
493+
> Stabilization of these lang items (in any form) will be considered in a
494+
> future RFC.
495+
496+
This means that no-std can't actually be used without providing these symbols
497+
in some other way. Doing so is unstable.
498+
499+
[rfc1184]: https://rust-lang.github.io/rfcs/1184-stabilize-no_std.html
500+
501+
## .note.gnu.property
502+
503+
The `.note.gnu.property` section discussed previously is an example of C code
504+
detecting mismatches of a flag at link time.
505+
506+
# Unresolved questions
507+
[unresolved-questions]: #unresolved-questions
508+
509+
This RFC does not stabilize any target modifiers. Such decisions should be made
510+
as a follow-up to this RFC on a flag-by-flag basis using the usual process for
511+
stabilizing a compiler flag.
512+
513+
The `-Cunsafe-allow-abi-mismatch` flag will be stabilized when the first target
514+
modifier is stabilized.
515+
516+
# Future possibilities
517+
[future-possibilities]: #future-possibilities
518+
519+
A possible future extension could be to detect inconsistencies between the ABI
520+
of C code and Rust code. This would be an interesting extension, but it is not
521+
critical for target modifiers as calling into C is inherently unsafe to start
522+
with. Similarly, another possible future extension could be to catch ABI
523+
mismatches when using dynamic linking.

0 commit comments

Comments
 (0)
Please sign in to comment.