4

Tracking Issue for RFC #2972: Constrained Naked Functions · Issue #90957 · rust...

 2 years ago
source link: https://github.com/rust-lang/rust/issues/90957
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Copy link

Contributor

bstrie commented on Feb 2

edited

Request for Stabilization

A proposal that the naked_functions feature be stabilized for Rust 1.60, to be released 2022-04-07. A stabilization PR can be found at #93587.

Summary

Adds a new attribute, #[naked], which may be applied to functions. When applied to a function, the compiler will not emit a function prologue when generating code for this function. This attribute is analogous to __attribute__((naked)) in C. The use of this feature allows the programmer to have precise control over the assembly that is generated for a given function.

The body of a naked function must consist of a single asm! invocation. This asm! invocation is heavily restricted: the only legal operands are const and sym, and the only legal options are noreturn (which is mandatory) and att_syntax. In lieu of specifying operands, the asm! within a naked function relies on the specified extern calling convention in order to determine the validity of registers.

An example of a naked function:

const THREE: usize = 3;

#[naked]
/// Adds three to a number and returns the result.
pub extern "sysv64" fn add_n(number: usize) -> usize {
    // SAFETY: the validity of these registers is guaranteed according to the "sysv64" ABI
    unsafe {
        std::arch::asm!(
            "add rdi, {}",
            "mov rax, rdi",
            "ret",
            const THREE,
            options(noreturn)
        );
    }
}

Documentation

The Rust Reference: rust-lang/reference#1153

Tests

  • codegen/naked-functions.rs: tests for the absence of a function prologue.
  • codegen/naked-noinline.rs: tests for the presence of naked and noinline LLVM attributes.
  • ui/asm/naked-functions.rs: tests that naked functions cannot accept patterns as function parameters, that referencing their function parameters is prohibited, that their body must consist of a single asm! block, that they must specify the noreturn option, that they must not specify any other option except att_syntax, that they only support const and sym operands, that they warn when used with extern "Rust", and that they are incompatible with the inline attribute.
  • ui/asm/naked-functions-ffi.rs: tests that a warning occurs when the function signature contains types that are not FFI-safe.
  • ui/asm/naked-functions-unused.rs: tests that the unused_variables lint is suppressed within naked functions.
  • ui/asm/naked-invalid-attr.rs: tests that the naked attribute is only valid on function definitions.

History

This feature was originally proposed in RFC 1201, filed on 2015-07-10 and accepted on 2016-03-21. Support for this feature was added in #32410, landing on 2016-03-23. Development languished for several years as it was realized that the semantics given in RFC 1201 were insufficiently specific. To address this, a minimal subset of naked functions was specified by RFC 2972, filed on 2020-08-07 and accepted on 2021-11-16. Prior to the acceptance of RFC 2972, all of the stricter behavior specified by RFC 2972 was implemented as a series of warn-by-default lints that would trigger on existing uses of the naked attribute; these lints became hard errors in #93153 on 2022-01-22. As a result, today RFC 2972 has completely superseded RFC 1201 in describing the semantics of the naked attribute.

Unresolved Questions

  • In C, __attribute__((naked)) prevents the compiler from generating both a function prologue and a function epilogue. However in Rust it was discovered that under some circumstances LLVM will choose to emit instructions following the body of a naked function, which is seemingly non-trivial to prevent. Since most of the utility of naked functions comes from preventing the prologue rather than the epilogue, for the time being this feature has restricted itself to only guaranteeing the absence of the prologue. Instead, the reference will specify that users must not rely on the presence of code following the body of a naked function, and that a future version of Rust reserves the right to guarantee the absence of such code.
  • Prior to stabilization, concerns were raised that the current implementation might not be capable of guaranteeing that a naked function is never inlined in every circumstance. Obviously the correctness of naked functions relies on Rust setting up the callstack as if a function call were being performed, even in cases where the function is ultimately inlined. However, there may be observable differences in behavior based on whether or not a naked function is inlined, e.g. due to exported symbols or named labels. Thus the reference will specify that implementations are not currently required to prevent the inlining of naked functions, but that a future version of Rust reserves the right to guarantee that naked functions are not inlined, and that users must not rely on any observable differences that may arise due to the inlining of a naked function.

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK