Skip to content

Commit 8116b5e

Browse files
committed
Start abi chapter.
1 parent b2fd0f2 commit 8116b5e

File tree

1 file changed

+171
-44
lines changed

1 file changed

+171
-44
lines changed

src/abi.md

Lines changed: 171 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,126 @@
11
# Application Binary Interface (ABI)
22

3-
This section documents features that affect the ABI of the compiled output of
4-
a crate.
3+
r[abi]
54

6-
See *[extern functions]* for information on specifying the ABI for exporting
7-
functions. See *[external blocks]* for information on specifying the ABI for
8-
linking external libraries.
5+
## ABI Compatibility
6+
7+
r[abi.compatibility]
8+
9+
r[abi.compatibilty.type]
10+
Two types, `T` and `U`, can be *abi compatible*.
11+
12+
r[abi.compatibility.equivalence]
13+
Two types `T` and `U` are *abi compatible* if:
14+
* They are the same type,
15+
* `U` is *abi compatible* with `T`, or
16+
* There exists a type `V`, such that `T` is *abi compatible* with `V` an `V` is *abi compatuble* with `U`,
17+
18+
> [!NOTE]
19+
> These properties ensure that *abi compatibility* is an equivalence relation.
20+
21+
r[abi.compatibility.integer]
22+
Two integer types are *abi compatible* if they have the same size and the same signednes
23+
24+
> [!NOTE]
25+
> In particular, `usize` is *abi compatible* with `uN`, and `isize` is *abi compatible* with `iN` where `N` is the target_pointer_width.
26+
> Two integer types with different signedness, such as `u8` and `i8` are not *abi compatible*.
27+
28+
r[abi.compatibility.char]
29+
The type `char`is *abi compatible* with the type `u32`.
30+
31+
r[abi.compatibility.pointer]
32+
Two pointer types, `*mut T` and `*const U`, are *abi compatible* if the *metadata type*s of `T` and `U` are the same type.
33+
34+
> [!NOTE]
35+
> With transitivity, this applies regardless of the mutability of either pointer type
36+
37+
r[abi.compatibility.reference-box]
38+
The types `&T`, `&mut T`, [`Box<T>`][core::boxed::Box], and [`NonNull<T>`][core::ptr::NonNull], are *abi compatible* with `*const T`
39+
40+
> [!NOTE]
41+
> With transitivity,t hey are also *abi compatible** with each other, and with `*mut T`, as well as references/`Box` to different types that have the same *metadata type*.
42+
43+
44+
r[abi.compatibility.core]
45+
The types [`MaybeUninit<T>`][core::mem::MaybeUninit], [`UnsafeCell<T>`][core::cell::UnsafeCell], and [`NonZero<T>`][core::num::NonZero], are *abi compatible* with `T`.
46+
47+
r[abi.compatibility.transparent]
48+
A `struct` declared with the `transparent` representation is *abi compatible* with its field that does not have size 0 and alignment 1, if such a field exists
49+
50+
r[abi.compatibilty.zst]
51+
Two types, `T` and `U`, are *abi compatible* if both have size 0 and alignment 1.
52+
53+
r[abi.compatibility.option]
54+
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 [`Option<T>`], [`Result<T,S>`], and [`Result<S,T>`].
55+
56+
r[abi.compatibility.fn-ptr]
57+
An `fn`-ptr type `T` is compatible with an `fn`-ptr type `U` if `T` and `U` have *abi compatible* tags.
58+
59+
r[abi.compatibility.extern-tag]
60+
Two abi tags are *abi compatible* if:
61+
* They are the same string, or
62+
* One tag is `"X"`, and the other is `"X-unwind"`
63+
64+
r[abi.compatibility.signature]
65+
Two function signatures are compatible if:
66+
* The abi tags of both signatures are *abi compatible*,
67+
* They have the same number of parameters, excluding C-varargs,
68+
* Each parameter of both signatures, in order, are *abi compatible*, and
69+
* Either both signatures have C-varargs, or neither signature does.
70+
71+
r[abi.compatibility.simd-abi]
72+
A type has *simd abi requirements* if:
73+
* It is a type declared with the standard-library repr-attrbute `simd`,
74+
* It is a aggregate type, which has a type with *simd abi requirements* as a field.
75+
76+
r[abi.compatibility.simd-target-feature]
77+
A type with *simd abi requirements* may have one or more *salient target features* . In the case of an aggregate type, the set of *salient target features* is the union of the set of *salient target features* of each field with *simd abi requirements*.
78+
79+
> [!TARGET-SPECIFIC]
80+
> On x86 and x86-64, the *salient target features* of the `simd` types are:
81+
> * [`__m128`], [`__m128i`], [`__m128f`], and [`__m128d`]: `sse`
82+
> * [`__m256`], [`__m256i`], [`__m256f`], and [`__m256d`]: `avx`
83+
> * [`__m512`], [`__m512i`], [`__m512f`], and [`__m512d`]: `avx512f` and `avx512vl`
84+
85+
r[abi.compatibility.call]
86+
A call to a function `f` via a function item or function pointer with a given signature `S` is valid only if the signature of `f` is *compatible* with the signature `S`, and, if the type of any parameter, the return type, or the type of any argument passed via C-varargs has *simd abi requirements*, each *salient target feature* of that type is either set at both the definition site of the function, and at the call site, or is set at neither site. The behaviour a call that is not valid is undefined.
87+
88+
89+
[`__m128`]: https://doc.rust-lang.org/stable/core/arch/x86_64/struct.__m128.html
90+
[`__m128i`]: https://doc.rust-lang.org/stable/core/arch/x86_64/struct.__m128i.html
91+
[`__m128f`]: https://doc.rust-lang.org/stable/core/arch/x86_64/struct.__m128f.html
92+
[`__m128d`]: https://doc.rust-lang.org/stable/core/arch/x86_64/struct.__m128d.html
93+
[`__m256`]: https://doc.rust-lang.org/stable/core/arch/x86_64/struct.__m256.html
94+
[`__m256i`]: https://doc.rust-lang.org/stable/core/arch/x86_64/struct.__m256i.html
95+
[`__m256f`]: https://doc.rust-lang.org/stable/core/arch/x86_64/struct.__m256f.html
96+
[`__m256d`]: https://doc.rust-lang.org/stable/core/arch/x86_64/struct.__m256d.html
97+
[`__m512`]: https://doc.rust-lang.org/stable/core/arch/x86_64/struct.__m512.html
98+
[`__m512i`]: https://doc.rust-lang.org/stable/core/arch/x86_64/struct.__m512i.html
99+
[`__m512f`]: https://doc.rust-lang.org/stable/core/arch/x86_64/struct.__m512f.html
100+
[`__m512d`]: https://doc.rust-lang.org/stable/core/arch/x86_64/struct.__m512d.html
9101

10102
## The `used` attribute
11103

12-
The *`used` attribute* can only be applied to [`static` items]. This [attribute] forces the
13-
compiler to keep the variable in the output object file (.o, .rlib, etc. excluding final binaries)
14-
even if the variable is not used, or referenced, by any other item in the crate.
15-
However, the linker is still free to remove such an item.
16104

17-
Below is an example that shows under what conditions the compiler keeps a `static` item in the
18-
output object file.
105+
r[abi.used]
106+
107+
```abnf
108+
MetaItemUsed := "used"
109+
```
110+
111+
r[abi.used.syntax]
112+
The *`used` attribute* may be specified as a built-in attribute, using the [_MetaWord_] syntax.
113+
114+
r[abi.used.restriction]
115+
The `used` attribute shall only be applied to a `static` item. It shall not be applied to a `static` item declared within an [`extern` block].
116+
117+
r[abi.used.application]
118+
A `static` item with the `used` attribute is an *exported item*.
119+
120+
> [!NOTE]
121+
> *exported items* will generally appear in the output when linking a library crate, and will generally be available when linking a binary crate as a global symbol.
122+
> The `used` attribute does not give the `static` item a *linkage name*, and thus does not disable name mangling. It may be used to place data into a given section that is referenced by the linker via the input section, without regard to the name of the symbol.
123+
> Due to toolchain limitations, it is not guaranteed that a `#[used]` static will appear in the final output when linking a binary, or when linking an rlib/staticlib crate into a `dylib` or `cdylib`.
19124
20125
``` rust
21126
// foo.rs
@@ -57,31 +162,54 @@ $ nm -C foo.o
57162
0000000000000000 T foo::quux
58163
```
59164

60-
## The `no_mangle` attribute
165+
## Symbol naming
61166

62-
The *`no_mangle` attribute* may be used on any [item] to disable standard
63-
symbol name mangling. The symbol for the item will be the identifier of the
64-
item's name.
167+
r[abi.symbol-name]
65168

66-
Additionally, the item will be publicly exported from the produced library or
67-
object file, similar to the [`used` attribute](#the-used-attribute).
169+
```abnf
170+
MetaItemNoMangle := "no_mangle"
171+
MetaItemExportName := "export_name" "=" ([STRING_LITERAL] | [RAW_STRING_LITERAL])
172+
```
173+
174+
r[abi.symbol-name.names]
175+
The *`no_mangle` attribute* and the *`export_name` attribute* shall only be applied to a `static` or `fn` item. The *`export_name` attribute* shall not be applied to an item declared within an [`extern` block].
176+
177+
> [!NOTE]
178+
> They may be applied to an associated `fn` of an `impl` block.
179+
180+
r[abi.symbol-name.exported]
181+
An item with either the *`no_mangle` attrbute* or the *`export_name` attribute* is an *exported item*.
182+
183+
r[abi.symbol-name.no_mangle]
184+
The *`no_mangle` attribute* may be specified as a built-in attribute, using the [_MetaWord_] syntax. The *export name* of an item with the *`no_mangle` attribute* is the declaration name of the item.
185+
186+
r[abi.symbol-name.export_name]
187+
The *`export_name` attribute* may be specified as a built-in attribute, using the [_MetaNameValueStr_] syntax. The *export name* of an item with the *`no_mangle` attribute* is the content of `STRING_LITERAL`.
68188

69-
This attribute is unsafe as an unmangled symbol may collide with another symbol
70-
with the same name (or with a well-known symbol), leading to undefined behavior.
71189

72-
```rust
73-
#[unsafe(no_mangle)]
74-
extern "C" fn foo() {}
75-
```
76190

77191
## The `link_section` attribute
78192

79-
The *`link_section` attribute* specifies the section of the object file that a
80-
[function] or [static]'s content will be placed into. It uses the
81-
[_MetaNameValueStr_] syntax to specify the section name.
193+
r[abi.link_section]
194+
195+
```abnf
196+
MetaItemLinkSection := "link_section" "=" ([STRING_LITERAL] | [RAW_STRING_LITERAL])
197+
```
198+
199+
r[abi.link_section.syntax]
200+
The *`link_section` attribute* may be specified as a built-in attribute, using the [_MetaNameValueStr_] syntax.
201+
202+
r[abi.link_section.restriction]
203+
The *`link_section` attribute* shall be aplied to a `static` or `fn` item.
82204

83-
This attribute is unsafe as it allows users to place data and code into sections
84-
of memory not expecting them, such as mutable data into read-only areas.
205+
r[abi.link_section.def]
206+
An item with the *`link_section` attribute* is placed in the specified section when linking. The section specified shall not violate the constraints on section names on the target, and shall not be invalid for the item type, no diagnostic is required.
207+
208+
> [!NOTE]
209+
> A section name may be invalid if it violates the requirements for the item type, for example, an `fn` item must be placed in an executable section, and a mutable static item (`static mut` or one containing an `UnsafeCell`) must be placed in a writable section.
210+
> The required format and any restrictions on section names are target-specific.
211+
>
212+
> The result of using an invalid section name may be that the section is placed into the section but cannot be used as applicable, or that the section is given additional attributes that may be incompatible when linking.
85213
86214
<!-- no_run: don't link. The format of the section name is platform-specific. -->
87215
```rust,no_run
@@ -90,26 +218,25 @@ of memory not expecting them, such as mutable data into read-only areas.
90218
pub static VAR1: u32 = 1;
91219
```
92220

93-
## The `export_name` attribute
94-
95-
The *`export_name` attribute* specifies the name of the symbol that will be
96-
exported on a [function] or [static]. It uses the [_MetaNameValueStr_] syntax
97-
to specify the symbol name.
98-
99-
This attribute is unsafe as a symbol with a custom name may collide with another
100-
symbol with the same name (or with a well-known symbol), leading to undefined
101-
behavior.
102-
103-
```rust
104-
#[unsafe(export_name = "exported_symbol_name")]
105-
pub fn name_in_rust() { }
106-
```
107-
221+
> [!TARGET-SPECIFIC]
222+
> On ELF Platforms, the standard section names, and their attributes are:
223+
> * `.text`: Readable and Executable,
224+
> * `.rodata`: Readable,
225+
> * `.data`: Readable and Writable,
226+
> * `.bss`: Readable and Writable - Uninitialized data,
227+
> * `.tdata`: Readable and Writable - Thread-local,
228+
> * `.tbss`: Readable and Writable - Uninitialized and Thread-local.
229+
>
230+
> This is not an exhaustive list, and generally extended versions of these section names such as `.text.foo`, are also defined with the same properties as the base section.
231+
>
232+
>
233+
234+
[_MetaWord_]: attributes.md#meta-item-attribute-syntax
108235
[_MetaNameValueStr_]: attributes.md#meta-item-attribute-syntax
109236
[`static` items]: items/static-items.md
110237
[attribute]: attributes.md
111238
[extern functions]: items/functions.md#extern-function-qualifier
112-
[external blocks]: items/external-blocks.md
239+
[`extern` block]: items/external-blocks.md
113240
[function]: items/functions.md
114241
[item]: items.md
115242
[static]: items/static-items.md

0 commit comments

Comments
 (0)