diff --git a/src/attributes.md b/src/attributes.md index 857cd7d72..b649a9eb4 100644 --- a/src/attributes.md +++ b/src/attributes.md @@ -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()`. @@ -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 diff --git a/src/attributes/codegen.md b/src/attributes/codegen.md index 37713c0c9..e1d15047f 100644 --- a/src/attributes/codegen.md +++ b/src/attributes/codegen.md @@ -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 @@ -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