Skip to content

Tracking Issue for RFC #2972: Constrained Naked Functions  #90957

Closed

Description

@nikomatsakis

This is a tracking issue for the RFC "Constrained Naked Functions" (rust-lang/rfcs#2972).
The feature gate for the issue is #![feature(naked_functions)].

About tracking issues

Tracking issues are used to record the overall progress of implementation.
They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions.
A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature.
Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.

Steps

Unresolved Questions

None.

Implementation history

Activity

  1. added
    B-RFC-approvedBlocker: Approved by a merged RFC but not yet implemented.
    C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFC
    T-langRelevant to the language team
    on Nov 16, 2021
  2. safinaskar commented on Jan 23, 2022

    @safinaskar
    Contributor

    "produce a clear warning if any of the above suggestions are not heeded" in RFC seems to contain typo

  3. self-assigned this
    on Jan 25, 2022
  4. bstrie commented on Jan 25, 2022

    @bstrie
    Contributor

    This is implemented, checking the box.

    Adding a new step: "Confirm that all errors and warnings are emitted properly".

  5. added
    A-nakedArea: `#[naked]`, prologue and epilogue-free, functions, https://git.io/vAzzS
    on Feb 2, 2022
  6. bstrie commented on Feb 2, 2022

    @bstrie
    Contributor

    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.
  7. added a commit that references this issue on Feb 2, 2022
    34386b3
  8. bjorn3 commented on Feb 2, 2022

    @bjorn3
    Member

    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.

    There is no observable difference between LLVM adding an epilogue and a following unnamed function starting with instructions identical to a regular epilogue.

  9. bstrie commented on Feb 2, 2022

    @bstrie
    Contributor

    @bjorn3 I believe it can cause problems in circumstances such as #32408 (comment) . If someone were to work around that issue by assuming the existence of extra instructions and manually accounting for it, then their code would be broken if Rust ever stopped generating those instructions. It is this sort of edge case that this defensive wording is designed to address.

  10. roblabla commented on Feb 2, 2022

    @roblabla
    Contributor

    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.

    There is no observable difference between LLVM adding an epilogue and a following unnamed function starting with instructions identical to a regular epilogue.

    I believe it's possible to observe a difference when naked is coupled with #[link_section]. You could apply that attributed to a naked function to put it in a well-known section that you expect to only contain your function.

  11. joshtriplett commented on Feb 2, 2022

    @joshtriplett
    Member

    👍 for stabilizing, though I'd like to make sure that there's consensus on #32408 (comment) .

  12. 169 remaining items

  13. added 2 commits that reference this issue on Mar 21, 2025
  14. added a commit that references this issue on Mar 21, 2025
  15. added a commit that references this issue on Apr 21, 2025
  16. added a commit that references this issue on Apr 21, 2025
  17. added a commit that references this issue on Apr 21, 2025
  18. tgross35 commented on Apr 22, 2025

    @tgross35
    Member

    With the stabilization at #134213, I believe this can be closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

A-nakedArea: `#[naked]`, prologue and epilogue-free, functions, https://git.io/vAzzSB-RFC-approvedBlocker: Approved by a merged RFC but not yet implemented.C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCF-naked_functions`#![feature(naked_functions)]`S-tracking-ready-to-stabilizeStatus: This is ready to stabilize; it may need a stabilization report and a PRT-langRelevant to the language teamdisposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.finished-final-comment-periodThe final comment period is finished for this PR / Issue.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions