Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add documentation for the naked function attribute #1153

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/attributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ The following is an index of all built-in attributes.
- Code generation
- [`inline`] — Hint to inline code.
- [`cold`] — Hint that a function is unlikely to be called.
- [`naked`] - Prevent the compiler from emitting a function prologue.
- [`no_builtins`] — Disables use of certain built-in functions.
- [`target_feature`] — Configure platform-specific code generation.
- [`track_caller`] - Pass the parent call location to `std::panic::Location::caller()`.
Expand Down Expand Up @@ -302,6 +303,7 @@ The following is an index of all built-in attributes.
[`macro_export`]: macros-by-example.md#path-based-scope
[`macro_use`]: macros-by-example.md#the-macro_use-attribute
[`must_use`]: attributes/diagnostics.md#the-must_use-attribute
[`naked`]: attributes/codegen.md#the-naked-attribute
[`no_builtins`]: attributes/codegen.md#the-no_builtins-attribute
[`no_implicit_prelude`]: names/preludes.md#the-no_implicit_prelude-attribute
[`no_link`]: items/extern-crates.md#the-no_link-attribute
Expand Down
84 changes: 84 additions & 0 deletions src/attributes/codegen.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,80 @@ There are three ways to use the inline attribute:
The *`cold` [attribute]* suggests that the attributed function is unlikely to
be called.

## The `naked` attribute

The *`naked` [attribute]* may be applied to a function in order to prevent the compiler
from emitting a function prologue.

### Requirements

Any function marked with the `naked` attribute must meet the following requirements;
failure to do so will result in a compiler error.

* The [function body] must consist of exactly one [`asm!`] macro invocation,
which may be enclosed within an [unsafe block].
* This `asm!` invocation must not contain any [operands]
except for `const` and `sym` operands.
* This `asm!` invocation must specify the `noreturn` [option],
and must not specify any other options except for `att_syntax`.
* The function must not be marked with the [`inline`] attribute.

### Recommendations

Any function marked with the `naked` attribute should adhere to the following recommendations;
failure to do so will result in a compiler warning.

* The function should feature an [extern function qualifier] that is not `extern "Rust"`.
* All arguments and return types of the function should be [FFI-safe].

### Effects

Marking a function with the `naked` attribute has the following effects:

* The compiler will not generate a prologue for this function.
Within the function, all registers will remain precisely as they were set up
by its caller.
* The compiler will suppress the [`unused_variables`] lint for this function.

### Notes

* The [rules for inline assembly] ordinarily consider it undefined behavior to
refer to registers not specified as input operands, or to modify
registers not specified as output operands.
The reason for this is because ordinarily an `asm!` invocation cannot guarantee
the state of the registers surrounding the assembly block.
However, in naked functions the state of the registers is guaranteed
by adherence to the specified calling convention.
Therefore, it is not undefined behavior for the `asm!` invocation in a naked function
to refer to registers without specifying them as operands.
* A naked function that makes use of registers in a way that does not conform
to the specified calling convention imposes additional safety invariants on its caller,
and therefore must be marked as an [unsafe function].
* Implementations may assume that naked functions never unwind.
Unwinding through a naked function is undefined behavior.
* The semantics of naked functions require implementations to set up the call stack
according to the specified calling convention before executing a naked function,
even in contexts where setting up the call stack would ordinarily be unnecessary,
such as when the function is inlined.
An implementation can fulfill this requirement by guaranteeing that naked functions
are never inlined.
However, implementations are not currently required to guarantee that naked functions
are never inlined.
In the future it may become a requirement for implementations to guarantee that
naked functions are never inlined;
users must not rely on any observable behavior that may result from inlining.
* Although implementations are prohibited from generating code for a naked function that
contains any instructions that precede the naked function's `asm!` block,
under some circumstances, implementations may generate code that contains instructions
*after* a naked function's `asm!` block.
In the future it may become a requirement for implementations to guarantee
the absence of any instructions following a naked function's `asm!` block;
users must not rely on the presence of any trailing instructions.
If a user of the `naked` attribute relies on the absence of trailing instructions
for correctness, for the time being it is the user's responsibility to ensure that
the instructions truly are absent,
for example by passing any necessary code generation flags to the compiler.

## The `no_builtins` attribute

The *`no_builtins` [attribute]* may be applied at the crate level to disable
Expand Down Expand Up @@ -267,14 +341,24 @@ trait object whose methods are attributed.
[_MetaListNameValueStr_]: ../attributes.md#meta-item-attribute-syntax
[`-C target-cpu`]: ../../rustc/codegen-options/index.html#target-cpu
[`-C target-feature`]: ../../rustc/codegen-options/index.html#target-feature
[`asm!`]: ../inline-assembly.md
[`inline`]: #the-inline-attribute
[`is_x86_feature_detected`]: ../../std/macro.is_x86_feature_detected.html
[`target_feature` conditional compilation option]: ../conditional-compilation.md#target_feature
[`unused_variables`]: ../../rustc/lints/listing/warn-by-default.html#unused-variables
[attribute]: ../attributes.md
[attributes]: ../attributes.md
[extern function qualifier]: ../items/functions.md#extern-function-qualifier
[FFI-safe]: ../../rustc/lints/listing/warn-by-default.html#improper-ctypes-definitions
[function body]: ../items/functions.md#function-body
[functions]: ../items/functions.md
[operands]: ../inline-assembly.md#operand-type
[option]: ../inline-assembly.md#options
[rules for inline assembly]: ../inline-assembly.md#rules-for-inline-assembly
[target architecture]: ../conditional-compilation.md#target_arch
[trait]: ../items/traits.md
[undefined behavior]: ../behavior-considered-undefined.md
[unsafe block]: ../unsafe-blocks.md
[unsafe function]: ../unsafe-functions.md
[rust-abi]: ../items/external-blocks.md#abi
[`core::intrinsics::caller_location`]: ../../core/intrinsics/fn.caller_location.html
Expand Down