Skip to content

Commit 073ca42

Browse files
committed
Add additional explanations to the abi compatibility section
1 parent 0d0635b commit 073ca42

File tree

1 file changed

+25
-15
lines changed

1 file changed

+25
-15
lines changed

src/abi.md

+25-15
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,18 @@ linking external libraries.
1313

1414
r[abi.compatibility]
1515

16-
r[abi.compatibility.type]
17-
Two types, `T` and `U`, can be *abi compatible*.
16+
r[abi.compatibility.intro]
17+
Function calls pass parameters and return values between the caller and the callee function. This requires the caller and callee to agree on an ABI for those parameters and return values. This is typically only guaranteed when the same type is used in both the call site and the definition site of the callee, but certain other types may be *abi compatible*. This can appear when transmuting a [function pointer] or using an [`extern` block] to call a function. When the parameters or return types differ between the call site and def site, assuming they are *abi compatible*, the parameters or return types are transmuted to the type at the def site or call site respectively.
1818

1919
> [!NOTE]
20-
> *abi compatible* types can be used in place of each other in signatures when calling via [function pointer] at runtime (via pointer, or [`extern` block]).
20+
> This can include calls to functions defined outside of rust, or built using a different Rust compiler version.
21+
> Additional guarantees will apply in this case for "FFI Safe" types, which match up with the platform C ABI in well-defined ways.
22+
> These are not fully documented here currently.
23+
24+
> [!WARNING]
25+
> Two types that are ABI Compatible may not allow the same set of values (e.g. [`*const T`] and [`core::ptr::NonNull<T>`]).
26+
> If an invalid value is passed as a parameter or returned from a function, the result is immediate undefined behaviour, even if the parameter or return value is never used.
27+
> For example, passing a null pointer to a function that accepts a `NonNull<i32>` parameter via `fn(*const i32)` function pointer caused undefined behaviour.
2128
2229
r[abi.compatibility.equivalence]
2330
Two types `T` and `U` are *abi compatible* if:
@@ -27,12 +34,16 @@ Two types `T` and `U` are *abi compatible* if:
2734

2835
> [!NOTE]
2936
> These properties are respectively called "reflexivity", "symmetry", and "transitivity". They ensure that *abi compatibility* is an equivalence relation.
37+
> ABI compatibility is a pairwise relation between two types. With Transivity and Symmetry, however, it can be well-defined to refer to several types being ABI compatible
3038
3139
r[abi.compatibility.integer]
32-
Two [integer types] are *abi compatible* if they have the same size and the same signedness.
40+
Two [integer types] are *abi compatible* if they have the same width and the same signedness.
41+
42+
> [!NOTE]
43+
> The width of an integer type is the number of bits, e.g. `u8` has a width of 8, and `i128` has a width of 128.
3344
3445
> [!NOTE]
35-
> In particular, `usize` is *abi compatible* with `uN`, and `isize` is *abi compatible* with `iN` where `N` is the target_pointer_width.
46+
> In particular, [`usize`] is *abi compatible* with `uN`, and `isize` is *abi compatible* with `iN` where `N` is the target_pointer_width.
3647
> Two integer types with different signedness, such as `u8` and `i8` are not *abi compatible*.
3748
3849
```rust
@@ -124,7 +135,6 @@ Two types, `T` and `U`, are *abi compatible* if both have size 0 and alignment 1
124135
r[abi.compatibility.option]
125136
If `T` is a type listed in [layout.enum.option](https://doc.rust-lang.org/stable/core/option/index.html#representation), then given `S` is a type with size 0 and alignment 1, `T` is *abi compatible* with the types [`core::option::Option<T>`], [`core::result::Result<T,S>`], and [`core::result::Result<S,T>`].
126137

127-
128138
r[abi.compatibility.fn-ptr]
129139
An [function pointer] type `T` is *abi compatible* with an [function pointer] type `U` if `T` and `U` have *abi compatible* tags.
130140

@@ -147,22 +157,24 @@ Two function signatures are compatible if:
147157
> A signature is compatible with itself.
148158
149159
r[abi.compatibility.simd-abi]
150-
A type has *simd abi requirements* if:
160+
Certain types have *simd abi requirements*, which can impose additional constraints on calls with a parameter or return value of that type. A type has *simd abi requirements* if:
151161
* It is a type declared with the standard-library repr-attribute `simd`, or
152162
* It is a aggregate type[^aggregate], which has a type with *simd abi requirements* as a field.
153163

154164
> [!NOTE]
155165
> Types with *simd abi requirements* may be passed using special registers that aren't always available to code.
156166
157167
> [!NOTE]
158-
> Notably References and pointers to types with *simd abi requirements* do not have *simd abi requirements*.
168+
> Notably References and pointers to types with *simd abi requirements* do not have *simd abi requirements*.
169+
> Only direct parameters and return values are affected by *simd abi requirements*.
159170
160171
> [!NOTE]
161-
> The `repr(simd)` attribute cannot be used by Rust code, only by the standard library.
172+
> The `repr(simd)` attribute cannot be used by Rust code, only by the standard library. The name used here is for *exposition only*.
162173
163174
r[abi.compatibility.simd-target-feature]
164175
A type with *simd abi requirements* may have one or more [*salient target features*][target_feature] . In the case of an aggregate type, the set of [*salient target features*][target_feature] is the union of the set of [*salient target features*][target_feature] of each field with *simd abi requirements*.
165176

177+
r[abi.compatibility.simd-target-feature-x86]
166178
> [!TARGET-SPECIFIC]
167179
> On x86 and x86-64, the [*salient target features*][target_feature] of the `simd` types are:
168180
> * [`__m128`], [`__m128i`], [`__m128f`], and [`__m128d`] (128-bit vector types): `sse`
@@ -176,8 +188,6 @@ A call to a function `f` via a function item or function pointer with a given si
176188

177189
The behavior of a call that is not valid is undefined.
178190

179-
> [!NOTE]
180-
> When parameter or return types do not exactly match, they are converted as though by calling [`core::mem::transmute`]. The representation and validity requirements of the type in the definition or return site still apply. For example, passing `0` to a function pointer `fn(u32)` that points to a function declared as `fn foo(x: NonZeroU32)` is undefined behavior.
181191

182192
> [!NOTE]
183193
> The ABI tag `extern "Rust"` is the default when the `extern` keyword is not used (either to declare the function within an [`extern` block], or as a [function qualifier][extern functions]). Thus it is safe to call most functions that use simd types.
@@ -270,8 +280,7 @@ $ nm -C foo.o
270280

271281
r[abi.symbol-name]
272282

273-
274-
The `no_mangle` and `export_name` attributes allow you to control which symbols are exported from rust code under provided symbol names.
283+
The `no_mangle` and `export_name` attributes allow you to control which symbols are exported from rust code under provided symbol names.
275284

276285
> **<sup>Attribute Syntax</sup>**\
277286
> _MetaItemNoMangle_ :\
@@ -304,7 +313,6 @@ extern "C" {
304313
> [!NOTE]
305314
> They may be applied to an associated `fn` of an `impl` block.
306315
307-
308316
r[abi.symbol-name.exported]
309317
An item with either the *`no_mangle` attribute* or the *`export_name` attribute* is an *exported item*.
310318

@@ -361,7 +369,7 @@ extern "C" fn foo() {}
361369

362370
r[abi.link_section]
363371

364-
The `link_section` attribute allows a program to control the section that certain items are placed into.
372+
The `link_section` attribute allows a program to control the section that certain items are placed into.
365373

366374
> **<sup>Attribute Syntax</sup>**\
367375
> _MetaItemLinkSection_ :\
@@ -395,11 +403,13 @@ pub static VAR1: u32 = 1;
395403
[integer types]: types/numeric.md#integer-types
396404
[`char`]: types/textual.md
397405
[pointer types]: types/pointer.md#raw-pointers-const-and-mut
406+
[`*const T`]: types/pointer.md#raw-pointers-const-and-mut
398407
[`&T`]: types/pointer.md#shared-references-
399408
[`&mut T`]: types/pointer.md#mutable-references-mut
400409
[`struct`]: types/struct.md
401410
[`enum`]: types/enum.md
402411
[`union`]: types/union.md
412+
[`usize`]: types/numeric.md#machine-dependent-integer-types
403413
[array]: types/array.md
404414
[item]: items.md
405415
[static]: items/static-items.md

0 commit comments

Comments
 (0)