Skip to content

Commit

Permalink
Merge pull request #1539 from carbotaniuman/add-unsafe-attr-docs
Browse files Browse the repository at this point in the history
Add some basic docs for unsafe attrs
  • Loading branch information
ehuss authored Aug 19, 2024
2 parents ecf7600 + 73c11ac commit 135bdee
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 6 deletions.
21 changes: 18 additions & 3 deletions src/abi.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,27 @@ item's name.
Additionally, the item will be publicly exported from the produced library or
object file, similar to the [`used` attribute](#the-used-attribute).

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

```rust
#[unsafe(no_mangle)]
extern "C" fn foo() {}
```

## The `link_section` attribute

The *`link_section` attribute* specifies the section of the object file that a
[function] or [static]'s content will be placed into. It uses the
[_MetaNameValueStr_] syntax to specify the section name.

This attribute is unsafe as it allows users to place data and code into sections
of memory not expecting them, such as mutable data into read-only areas.

<!-- no_run: don't link. The format of the section name is platform-specific. -->
```rust,no_run
#[no_mangle]
#[link_section = ".example_section"]
#[unsafe(no_mangle)]
#[unsafe(link_section = ".example_section")]
pub static VAR1: u32 = 1;
```

Expand All @@ -85,8 +96,12 @@ The *`export_name` attribute* specifies the name of the symbol that will be
exported on a [function] or [static]. It uses the [_MetaNameValueStr_] syntax
to specify the symbol name.

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

```rust
#[export_name = "exported_symbol_name"]
#[unsafe(export_name = "exported_symbol_name")]
pub fn name_in_rust() { }
```

Expand Down
14 changes: 13 additions & 1 deletion src/attributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
> &nbsp;&nbsp; `#` `[` _Attr_ `]`
>
> _Attr_ :\
> &nbsp;&nbsp; [_SimplePath_] _AttrInput_<sup>?</sup>
> &nbsp;&nbsp; &nbsp;&nbsp; [_SimplePath_] _AttrInput_<sup>?</sup>\
> &nbsp;&nbsp; | `unsafe` `(` [_SimplePath_] _AttrInput_<sup>?</sup> `)`
>
> _AttrInput_ :\
> &nbsp;&nbsp; &nbsp;&nbsp; [_DelimTokenTree_]\
Expand All @@ -29,6 +30,17 @@ Attributes other than macro attributes also allow the input to be an equals
sign (`=`) followed by an expression. See the [meta item
syntax](#meta-item-attribute-syntax) below for more details.

An attribute may be unsafe to apply. To avoid undefined behavior when using
these attributes, certain obligations that cannot be checked by the compiler
must be met. To assert these have been, the attribute is wrapped in
`unsafe(..)`, e.g. `#[unsafe(no_mangle)]`.

The following attributes are unsafe:

* [`export_name`]
* [`link_section`]
* [`no_mangle`]

Attributes can be classified into the following kinds:

* [Built-in attributes]
Expand Down
10 changes: 8 additions & 2 deletions src/unsafe-keyword.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# The `unsafe` keyword

The `unsafe` keyword can occur in several different contexts:
unsafe functions (`unsafe fn`), unsafe blocks (`unsafe {}`), unsafe traits (`unsafe trait`), unsafe trait implementations (`unsafe impl`), and unsafe external blocks (`unsafe extern`).
unsafe functions (`unsafe fn`), unsafe blocks (`unsafe {}`), unsafe traits (`unsafe trait`), unsafe trait implementations (`unsafe impl`), unsafe external blocks (`unsafe extern`), and unsafe attributes (`#[unsafe(attr)]`).
It plays several different roles, depending on where it is used and whether the `unsafe_op_in_unsafe_fn` lint is enabled:
- it is used to mark code that *defines* extra safety conditions (`unsafe fn`, `unsafe trait`)
- it is used to mark code that needs to *satisfy* extra safety conditions (`unsafe {}`, `unsafe impl`, `unsafe fn` without [`unsafe_op_in_unsafe_fn`], `unsafe extern`)
- it is used to mark code that needs to *satisfy* extra safety conditions (`unsafe {}`, `unsafe impl`, `unsafe fn` without [`unsafe_op_in_unsafe_fn`], `unsafe extern`, `#[unsafe(attr)]`)

The following discusses each of these cases.
See the [keyword documentation][keyword] for some illustrative examples.
Expand Down Expand Up @@ -62,3 +62,9 @@ Unsafe trait implementations are the logical dual to unsafe traits: where unsafe
The programmer who declares an [external block] must assure that the signatures of the items contained within are correct. Failing to do so may lead to undefined behavior. That this obligation has been met is indicated by writing `unsafe extern`.

[external block]: items/external-blocks.md

## Unsafe attributes (`#[unsafe(attr)]`)

An [unsafe attribute] is one that has extra safety conditions that must be upheld when using the attribute. The compiler cannot check whether these conditions have been upheld. To assert that they have been, these attributes must be wrapped in `unsafe(..)`, e.g. `#[unsafe(no_mangle)]`.

[unsafe attribute]: attributes.md
2 changes: 2 additions & 0 deletions src/unsafety.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ Rust:
- Calling an unsafe function (including an intrinsic or foreign function).
- Implementing an [unsafe trait].
- Declaring an [`extern`] block.
- Applying an [unsafe attribute] to an item.

[`extern`]: items/external-blocks.md
[`union`]: items/unions.md
[mutable]: items/static-items.md#mutable-statics
[external]: items/external-blocks.md
[raw pointer]: types/pointer.md
[unsafe trait]: items/traits.md#unsafe-traits
[unsafe attribute]: attributes.md

0 comments on commit 135bdee

Please sign in to comment.