Skip to content

Commit

Permalink
fix wording regarding UB due to unwinding linkage
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed Nov 29, 2024
1 parent db97d54 commit 117ca17
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 30 deletions.
62 changes: 33 additions & 29 deletions src/linkage.md
Original file line number Diff line number Diff line change
Expand Up @@ -272,35 +272,39 @@ binary link:

Passing `rlib`s directly into your foreign linker is currently unsupported.

### Prohibited linkage and foreign unwinding

r[link.foreign-code.prohibited]

Undfined behavior may be caused by foreign code unwinding into a Rust crate
with these characteristics:

* The foreign unwind enters Rust via a function or function pointer declared
with an ABI that permits unwinding, that is, `"Rust"` (the default ABI) or
any `-unwind` ABI
* The Rust crate containing the `-unwind` ABI declaration was compiled with
`panic=unwind`
* The final binary is linked with [the `panic=abort` runtime][panic-runtime]

> **Note**: To protect against this undefined behavior, `rustc` does not permit
> linking the `panic=abort` runtime against any crate that was compiled with
> `panic=unwind` if that crate also contains a call to a foreign function or
> function pointer declared with an `-unwind` ABI. Note that this prohibition
> applies even when linking a static or dynamic library that only includes Rust
> code, since the resulting library may be subsequently linked against another
> library that may unwind. However, use of the `Rust` (default) ABI does not
> cause a link-error, since that ABI is not expected to be used as an
> entrypoint into a static or shared library.
> **Note**: the restriction can only be violated when mixing code with different
> `-C panic` flags. This is not possible in normal use of cargo, so most users
> need not be concerned about this.
r[link.foreign-code.prohibited.lint.ffi_unwind_calls]
> [!NOTE]
> Rust code compiled or linked with a different instance of the Rust runtime counts as a
> "foreign code" for the purpose of this section.
### Prohibited linkage and unwinding

r[link.unwinding]
If you are *not* using `rustc` to link Rust files, you must take care to ensure that unwinding is
handled consistently across the entire binary. This includes using `dlopen` or similar facilities
where linking is done by the system runtime without `rustc` being involved.

r[link.unwinding.potential]
A Rust binary or `staticlib` is called *potentially unwinding* if any of the following conditions
is met:
- The binary or `staticlib` is linked with [the `panic=unwind` runtime][panic-runtime].
- The binary or `staticlib` contains a crate built with `-Cpanic=unwind` that makes a call
to a function using a `-unwind` ABI.
- The binary or `staticlib` makes a `"Rust"` ABI call to code running in a separately built
`staticlib` (i.e., a separate instance of the Rust runtime), and that other `staticlib` is
potentially unwinding.

> [!NOTE]
> This definition captures whether a `"Rust"` ABI call inside a Rust binary or `staticlib` can ever
> unwind.
r[link.unwinding.prohibited]
If a Rust binary or `staticlib` is potentially unwinding, then all its crates must be built with `-Cpanic=unwind`.

> [!NOTE]
> This restriction can only be violated when mixing code with different `-C panic` flags
> while also using a non-`rustc` linker. Most users to not have to be concerned about this.
r[link.unwinding.prohibited.lint.ffi_unwind_calls]
To guarantee that a library will be sound (and linkable with `rustc`)
regardless of the panic mode used at link-time, the [`ffi_unwind_calls` lint]
may be used. The lint flags any calls to `-unwind` foreign functions or
Expand Down
2 changes: 1 addition & 1 deletion src/panic.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ which will occur:
* The function returns a `Result::Err` containing an opaque type.

> [!NOTE]
> Rust code compiled or linked with a different runtime counts as a
> Rust code compiled or linked with a different instance of the Rust runtime counts as a
> "foreign exception" for the purpose of this guarantee. Thus, a library that
> uses `panic!` and is linked against one version of the Rust standard library,
> invoked from an application that uses a different version of the standard
Expand Down

0 comments on commit 117ca17

Please sign in to comment.