From a3c6633907e8243e1c93e348f8622eb0c4be8b92 Mon Sep 17 00:00:00 2001 From: Nathaniel McCallum Date: Thu, 6 Aug 2020 16:36:02 -0400 Subject: [PATCH 01/13] First attempt at a naked functions RFC --- text/0000-constrained-naked.md | 142 +++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 text/0000-constrained-naked.md diff --git a/text/0000-constrained-naked.md b/text/0000-constrained-naked.md new file mode 100644 index 00000000000..6582b1c4788 --- /dev/null +++ b/text/0000-constrained-naked.md @@ -0,0 +1,142 @@ +- Feature Name: `constrained_naked` +- Start Date: 2020-08-06 +- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000) +- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) + +# Summary +This document attempts to increase the utility of [naked functions](https://github.com/rust-lang/rfcs/blob/master/text/1201-naked-fns.md) by constraining their use and increasing their defined invariants. This document also defines a new calling convention: `extern "custom"`. + +# Motivation + +Naked functions have long been a feature of compilers. These functions are typically defined as normal functions in every regard, except that the compiler does not emit the function prologue and epilogue. Rust's early attempt to support this feature ([RFC 1201](https://github.com/rust-lang/rfcs/blob/master/text/1201-naked-fns.md)) mostly copied the existing compiler behaviors. + +However, naked functions are often avoided in practice because their behavior is not well defined. The root cause of this problem is that naked functions are defined by negation: they are functions which lack a prologue and epilogue. Unfortunately, functions that lack a prologue and epilogue present a number of complicated problems that the compiler needs to solve and developers need to work around. And there is a long history of compilers and developers getting this wrong. + +This document seeks to define naked functions in a much more constrained, positivistic way. In doing so, naked functions can become more useful. + +# Naked function definition + +A naked function is a type of FFI function with a defined calling convention and a body which contains only assembly code which can rely upon the defined calling convention. + +A naked function is identified by the `#[naked]` attribute and: +1. must specify a calling convention besides `extern "Rust"`. +1. must define only FFI-safe arguments and return types. +1. must not specify the `#[inline]` or `#[inline(always)]` attribute. +1. must have a body which contains only a single `asm!()` statement which: + 1. may be wrapped in an `unsafe` block. + 1. must not contain any operands except `const` or `sym`. + 1. must contain the `noreturn` option. + 1. must not contain any other options except `att_syntax`. + 1. must ensure that the requirements of the calling convention are followed. + +In exchange for the above constraints, the compiler commits to: +1. produce a clear error if any of the above rules are violated. +1. never inline the function (implicit `#[inline(never)]`). +1. emit no instructions to the function body that are not contained in the `asm!()` statement. + +As a (weaker) correlary to the last compiler commitment, since the compiler generates no additional instructions, the initial state of all registers in the `asm!()` statement conform to the specified calling convention. + +# Custom Calling Convention + +In order to expand the usefulness of naked functions, this document also define a new calling convention, `extern "custom"`, that can be used only with naked functions. Functions with `extern "custom"` are not callable from Rust and must be marked as`unsafe`. The function definition must contain no arguments or return type. For example: + +```rust +#[naked] +unsafe extern "custom" fn callback() { + asm!("mov rbx, rsi") +} +``` + +An `extern "custom"` function can be passed as a function pointer argument or passed to an `asm!()` block via `sym`. + +# Explanation + +Since a naked function has no prologue, any naive attempt to use the stack can produce invalid code. This certainly includes local variables. But this can also include attempts to reference function arguments which may be placed on the stack. This is why a naked function may only contain a single `asm!()` statement. + +Further, since many platforms store the return address on the stack, it is the responsibility of the `asm!()` statement to return in the appropriate way. This is why the `options(noreturn)` option is required. + +Any attempt to use function arguments, even as operands, may cause stack access or modification. Likewise, any register operands may cause the compiler to attempt to preserve registers on the stack. Since the function has no prologue, this is problematic. To avoid this problem, we simply refuse to allow the use of any function arguments in Rust. + +If this were the end of the story, naked functions would not be very useful. In order to re-enable access to the function arguments, the compiler ensures that the initial state of the registers in the `asm!()` statement conform to the function's calling convention. This allows hand-crafted assembly access to the function arguments through the calling convention. Since the `extern "Rust"` calling convention is undefined, its use is disallowed and an alternative, well-defined calling convention must be specified. Likewise, since the `asm!()` statement can access the function arguments through the calling convention, the arguments themselves must be FFI safe to ensure that they can be reliably accessed from assembly. + +Because naked functions depend upon the calling convention so heavily, inlining of these functions would make code generation extremely difficult. Therefore, we disallow inlining. + +Since the `const` and `sym` operands modify neither the stack nor the registers, their use is permitted. + +Because the compiler guarantees that no instructions not in the `asm!()` block of a naked function will be emitted to the function body, an `extern "custom"` function can implement whatever custom calling convention it wants. This is useful in a variety of scenarios where the calling convention is custom, such as in interrupt handlers or callbacks from assembly code. + +## Examples + +This function adds three to a number and returns the result: + +```rust +const THREE: usize = 3; + +#[naked] +pub extern "sysv64" fn add_n(number: usize) -> usize { + unsafe { + asm!( + "add rdi, {}" + "mov rax, rdi" + "ret", + const THREE, + options(noreturn) + ); + } +} +``` + +The calling convention is defined as `extern "sysv64"`, therefore we know that the input is in the `rdi` register and the return value is in the `rax` register. The `asm!()` statement contains `options(noreturn)` and therefore we handle the return directly through the `ret` instruction. We can provide a `const` operand since it modifies neither registers nor stack. Since we have strong guarantees about the state of the registers, we can mark this function as safe and wrap the `asm!()` statement in an `unsafe` block. + +# Drawbacks + +Implementing this will break compatiliby of existing uses of the nightly `#[naked]` attribute. All of these uses likely depend on undefined behavior. If this was a problem, we could simply use a different attribute. + +This definition may be overly strict. There is certainly some code that would work without this. The counter argument is that this code relies on undefined behavior and is probably not worth preserving. It might also be possible to reasonably ease the constraints over time. + +This proposal requires the use of assembly where it is theoretically possible to use Rust in a naked function. However, practically the use of Rust in naked functions is nearly impossible and relies on extensively undefined behavior. + +Adopting this definition changes the invariants of `asm!()`. Currently, all registers not supplied as operands to `asm!()` contain undefined values. This proposal changes this to define that the initial register state is unmodified from the function call. This is an even stronger commitment than merely guaranteeing calling convention conformance, which some may dislike. However, the change to permit defined initial register state applies **only** to the use of `asm!()` as the body of a naked function. + +Refusing to allow argument operands means that architectures that have multiple calling conventions (i.e. x86_64 SystemV vs Windows) cannot share function bodies. This could be remedied with a future improvement. + +# Alternatives + +## Do nothing + +We could do nothing and let naked functions work as they currently do. However, this is likely to be a source of a long stream of difficult compiler bugs and therefore there is no clear path to stabilization. Further, because of the lack of clear constraints, naked functions today are hard to use correctly. And when the developer fails to get every detail right, the result can be hard to debug. + +## Remove naked functions + +Another possibility is to simply remove support for naked functions altogether. This does solve the undefined behavior problem. But it forces the developer to pursue other options. Most notably `global_asm!()` or using an external assembler. + +It would be possible to use `global_asm!()` to define functions with existing constraints. However, there is not currently a clear path to stabilization for `global_asm!()` since it is a thin wrapper around LLVM functionality. Further, `global_asm!()` does not provide features like namespacing and documentation. Nor can you use `global_asm!()` to provide `const` or `sym` operands, which are very useful. + +Alternatively, developers could use an external assembler and link in the result. This approach is similar to `global_asm!()` but offloads the problem to external tooling such as the `cc` crate. It has the same drawbacks as `global_asm!()` and also puts additional requirements on compilers of the software. + +# Prior art + +All languages represented here follow the weaker definition of naked functions: + +| | supported | +|-------------------|-----------| +| | | +| C/C\+\+ \(GCC\) | x | +| C/C\+\+ \(Clang\) | x | +| C/C\+\+ \(MSVC\) | x | +| C/C\+\+ \(ICC\) | | +| D | x | +| Go | | +| Nim | x | +| Rust | x | +| Zig | x | + +# Unresolved questions + +Due to the definition of naked functions, the arguments will always be flagged as unused. Should we consider adding `#[used]` implicitly to all arguments? + +# Future possibilities + +It would be possible to define new calling conventions that can be used with naked functions. + +It may also be possible to loosen the definition of a naked function in a future RFC. For example, it might be possible to allow the use of some additional, possibly new, operands to the `asm!()` block. From a58060662c7ade09c91344dc8bb61fb8c78a26b3 Mon Sep 17 00:00:00 2001 From: Nathaniel McCallum Date: Fri, 21 Aug 2020 08:36:05 -0400 Subject: [PATCH 02/13] An assortment of minor fixes All of these fixes should be considered either gramatical or implement uncontroversial minor suggestions from review. In particular, this commit turns the first two requirements into warnings instead of errors. --- text/0000-constrained-naked.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/text/0000-constrained-naked.md b/text/0000-constrained-naked.md index 6582b1c4788..8105469ddf1 100644 --- a/text/0000-constrained-naked.md +++ b/text/0000-constrained-naked.md @@ -16,11 +16,11 @@ This document seeks to define naked functions in a much more constrained, positi # Naked function definition -A naked function is a type of FFI function with a defined calling convention and a body which contains only assembly code which can rely upon the defined calling convention. +A naked function has a defined calling convention and a body which contains only assembly code which can rely upon the defined calling convention. A naked function is identified by the `#[naked]` attribute and: -1. must specify a calling convention besides `extern "Rust"`. -1. must define only FFI-safe arguments and return types. +1. should specify a calling convention besides `extern "Rust"`. +1. should define only FFI-safe arguments and return types. 1. must not specify the `#[inline]` or `#[inline(always)]` attribute. 1. must have a body which contains only a single `asm!()` statement which: 1. may be wrapped in an `unsafe` block. @@ -30,11 +30,12 @@ A naked function is identified by the `#[naked]` attribute and: 1. must ensure that the requirements of the calling convention are followed. In exchange for the above constraints, the compiler commits to: -1. produce a clear error if any of the above rules are violated. +1. produce a clear error if any of the above requirements are violated. +1. produce a clear warning if any of the above suggestions are not heeded. 1. never inline the function (implicit `#[inline(never)]`). -1. emit no instructions to the function body that are not contained in the `asm!()` statement. +1. emit no additional instructions to the function body before the `asm!()` statement. -As a (weaker) correlary to the last compiler commitment, since the compiler generates no additional instructions, the initial state of all registers in the `asm!()` statement conform to the specified calling convention. +As a (weaker) correlary to the last compiler commitment, the initial state of all registers in the `asm!()` statement conform to the specified calling convention. # Custom Calling Convention @@ -90,7 +91,7 @@ The calling convention is defined as `extern "sysv64"`, therefore we know that t # Drawbacks -Implementing this will break compatiliby of existing uses of the nightly `#[naked]` attribute. All of these uses likely depend on undefined behavior. If this was a problem, we could simply use a different attribute. +Implementing this will break compatiliby of existing uses of the nightly `#[naked]` attribute. All of these uses likely depend on undefined behavior. If this is a problem, we could simply use a different attribute. This definition may be overly strict. There is certainly some code that would work without this. The counter argument is that this code relies on undefined behavior and is probably not worth preserving. It might also be possible to reasonably ease the constraints over time. From 9122563965da557e7a1bfe2c74a87c1be5d04bce Mon Sep 17 00:00:00 2001 From: Nathaniel McCallum Date: Fri, 21 Aug 2020 08:50:53 -0400 Subject: [PATCH 03/13] Remove the `extern "custom"` calling convention This feature likely needs more design and constrained naked functions are useful without it. I have also added a brief discussion of this feature to the future possibilities section. If people feel strongly that we should keep the custom calling convention, we can revert this commit. --- text/0000-constrained-naked.md | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/text/0000-constrained-naked.md b/text/0000-constrained-naked.md index 8105469ddf1..1f94ae959e3 100644 --- a/text/0000-constrained-naked.md +++ b/text/0000-constrained-naked.md @@ -4,7 +4,7 @@ - Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) # Summary -This document attempts to increase the utility of [naked functions](https://github.com/rust-lang/rfcs/blob/master/text/1201-naked-fns.md) by constraining their use and increasing their defined invariants. This document also defines a new calling convention: `extern "custom"`. +This document attempts to increase the utility of [naked functions](https://github.com/rust-lang/rfcs/blob/master/text/1201-naked-fns.md) by constraining their use and increasing their defined invariants. # Motivation @@ -37,19 +37,6 @@ In exchange for the above constraints, the compiler commits to: As a (weaker) correlary to the last compiler commitment, the initial state of all registers in the `asm!()` statement conform to the specified calling convention. -# Custom Calling Convention - -In order to expand the usefulness of naked functions, this document also define a new calling convention, `extern "custom"`, that can be used only with naked functions. Functions with `extern "custom"` are not callable from Rust and must be marked as`unsafe`. The function definition must contain no arguments or return type. For example: - -```rust -#[naked] -unsafe extern "custom" fn callback() { - asm!("mov rbx, rsi") -} -``` - -An `extern "custom"` function can be passed as a function pointer argument or passed to an `asm!()` block via `sym`. - # Explanation Since a naked function has no prologue, any naive attempt to use the stack can produce invalid code. This certainly includes local variables. But this can also include attempts to reference function arguments which may be placed on the stack. This is why a naked function may only contain a single `asm!()` statement. @@ -64,8 +51,6 @@ Because naked functions depend upon the calling convention so heavily, inlining Since the `const` and `sym` operands modify neither the stack nor the registers, their use is permitted. -Because the compiler guarantees that no instructions not in the `asm!()` block of a naked function will be emitted to the function body, an `extern "custom"` function can implement whatever custom calling convention it wants. This is useful in a variety of scenarios where the calling convention is custom, such as in interrupt handlers or callbacks from assembly code. - ## Examples This function adds three to a number and returns the result: @@ -140,4 +125,6 @@ Due to the definition of naked functions, the arguments will always be flagged a It would be possible to define new calling conventions that can be used with naked functions. +A previous version of this document defined an `extern "custom"` calling convention. It was observed in conversation that calling conventions are really a *type* and that it could be useful to have calling conventions as part of the type system. In the interest of moving forward with constrained naked functions, it is best to limit the scope of this RFC and defer this (very good) conversation to a future RFC. + It may also be possible to loosen the definition of a naked function in a future RFC. For example, it might be possible to allow the use of some additional, possibly new, operands to the `asm!()` block. From 92b909aa6a4de7d094d867547f98c29fb010df7c Mon Sep 17 00:00:00 2001 From: Nathaniel McCallum Date: Mon, 24 Aug 2020 09:44:21 -0400 Subject: [PATCH 04/13] Commit the compiler to disable the unused arguments lint This solves a paper cut with naked functions that the compiler would mark all arguments as unused, forcing the developer to either disable the lint or prefix all arguments with '_'. --- text/0000-constrained-naked.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/text/0000-constrained-naked.md b/text/0000-constrained-naked.md index 1f94ae959e3..e81ebc7bff6 100644 --- a/text/0000-constrained-naked.md +++ b/text/0000-constrained-naked.md @@ -32,6 +32,7 @@ A naked function is identified by the `#[naked]` attribute and: In exchange for the above constraints, the compiler commits to: 1. produce a clear error if any of the above requirements are violated. 1. produce a clear warning if any of the above suggestions are not heeded. +1. disable the unused argument lint for the function. 1. never inline the function (implicit `#[inline(never)]`). 1. emit no additional instructions to the function body before the `asm!()` statement. @@ -119,7 +120,7 @@ All languages represented here follow the weaker definition of naked functions: # Unresolved questions -Due to the definition of naked functions, the arguments will always be flagged as unused. Should we consider adding `#[used]` implicitly to all arguments? +All outstanding questions have been resolved. # Future possibilities From 7ecd56102e9e77ee17437983d09e2a97ec828c06 Mon Sep 17 00:00:00 2001 From: Nathaniel McCallum Date: Sun, 1 Aug 2021 10:38:39 -0400 Subject: [PATCH 05/13] Rename constrained naked file to match rfc number --- text/{0000-constrained-naked.md => 2972-constrained-naked.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename text/{0000-constrained-naked.md => 2972-constrained-naked.md} (100%) diff --git a/text/0000-constrained-naked.md b/text/2972-constrained-naked.md similarity index 100% rename from text/0000-constrained-naked.md rename to text/2972-constrained-naked.md From 08adbc06eb39b170f5b6caf191975281d84fb105 Mon Sep 17 00:00:00 2001 From: Nathaniel McCallum Date: Wed, 4 Aug 2021 10:13:31 -0400 Subject: [PATCH 06/13] Reject all inline attributes on naked functions This matches the behavior of the merged PR implementing this criteria. https://github.com/rust-lang/rust/pull/87652 --- text/2972-constrained-naked.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/2972-constrained-naked.md b/text/2972-constrained-naked.md index e81ebc7bff6..cd5e7221564 100644 --- a/text/2972-constrained-naked.md +++ b/text/2972-constrained-naked.md @@ -21,7 +21,7 @@ A naked function has a defined calling convention and a body which contains only A naked function is identified by the `#[naked]` attribute and: 1. should specify a calling convention besides `extern "Rust"`. 1. should define only FFI-safe arguments and return types. -1. must not specify the `#[inline]` or `#[inline(always)]` attribute. +1. must not specify the `#[inline]` or `#[inline(*)]` attribute. 1. must have a body which contains only a single `asm!()` statement which: 1. may be wrapped in an `unsafe` block. 1. must not contain any operands except `const` or `sym`. From 3537016c8e3e3d461cf79ef74628a8bf7b122667 Mon Sep 17 00:00:00 2001 From: Nathaniel McCallum Date: Wed, 4 Aug 2021 10:14:09 -0400 Subject: [PATCH 07/13] Clarify the unused lint clause in naked functions This simply points out which warning is actually being disabled. --- text/2972-constrained-naked.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/2972-constrained-naked.md b/text/2972-constrained-naked.md index cd5e7221564..5dd28b3c348 100644 --- a/text/2972-constrained-naked.md +++ b/text/2972-constrained-naked.md @@ -32,7 +32,7 @@ A naked function is identified by the `#[naked]` attribute and: In exchange for the above constraints, the compiler commits to: 1. produce a clear error if any of the above requirements are violated. 1. produce a clear warning if any of the above suggestions are not heeded. -1. disable the unused argument lint for the function. +1. disable the unused argument lint for the function (implicit `#[allow(unused_variables)]`). 1. never inline the function (implicit `#[inline(never)]`). 1. emit no additional instructions to the function body before the `asm!()` statement. From 7a02895997fe1ccd334a05854160102499b05beb Mon Sep 17 00:00:00 2001 From: Nathaniel McCallum Date: Wed, 4 Aug 2021 10:17:15 -0400 Subject: [PATCH 08/13] Fix an inconsistency in naked functions ABI spec We had previously update the requirements in the first section, but forgot to match the explanatory paragraph to match. --- text/2972-constrained-naked.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/2972-constrained-naked.md b/text/2972-constrained-naked.md index 5dd28b3c348..7ac15b50142 100644 --- a/text/2972-constrained-naked.md +++ b/text/2972-constrained-naked.md @@ -46,7 +46,7 @@ Further, since many platforms store the return address on the stack, it is the r Any attempt to use function arguments, even as operands, may cause stack access or modification. Likewise, any register operands may cause the compiler to attempt to preserve registers on the stack. Since the function has no prologue, this is problematic. To avoid this problem, we simply refuse to allow the use of any function arguments in Rust. -If this were the end of the story, naked functions would not be very useful. In order to re-enable access to the function arguments, the compiler ensures that the initial state of the registers in the `asm!()` statement conform to the function's calling convention. This allows hand-crafted assembly access to the function arguments through the calling convention. Since the `extern "Rust"` calling convention is undefined, its use is disallowed and an alternative, well-defined calling convention must be specified. Likewise, since the `asm!()` statement can access the function arguments through the calling convention, the arguments themselves must be FFI safe to ensure that they can be reliably accessed from assembly. +If this were the end of the story, naked functions would not be very useful. In order to re-enable access to the function arguments, the compiler ensures that the initial state of the registers in the `asm!()` statement conform to the function's calling convention. This allows hand-crafted assembly access to the function arguments through the calling convention. Since the `extern "Rust"` calling convention is undefined, its use is discouraged and an alternative, well-defined calling convention should be specified. Likewise, since the `asm!()` statement can access the function arguments through the calling convention, the arguments themselves should be FFI safe to ensure that they can be reliably accessed from assembly. Because naked functions depend upon the calling convention so heavily, inlining of these functions would make code generation extremely difficult. Therefore, we disallow inlining. From c1e2bbd2326e0ec8ff1a279cba75d187d4f61d89 Mon Sep 17 00:00:00 2001 From: Nathaniel McCallum Date: Wed, 4 Aug 2021 10:18:42 -0400 Subject: [PATCH 09/13] Clarify naked function calling convention reqs Although we don't have `extern "custom"` anymore, `unsafe` can pragmatically fill this roll. Marking a function as `unsafe` implies that the function cannot be safely called unless additional criteria are met (as documented in the safety section, per standard convention). This wording clarifies the RFC to point to this well-established convention. --- text/2972-constrained-naked.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/text/2972-constrained-naked.md b/text/2972-constrained-naked.md index 7ac15b50142..2152539abe0 100644 --- a/text/2972-constrained-naked.md +++ b/text/2972-constrained-naked.md @@ -27,7 +27,7 @@ A naked function is identified by the `#[naked]` attribute and: 1. must not contain any operands except `const` or `sym`. 1. must contain the `noreturn` option. 1. must not contain any other options except `att_syntax`. - 1. must ensure that the requirements of the calling convention are followed. + 1. must ensure that the calling convention is followed or the function is `unsafe`. In exchange for the above constraints, the compiler commits to: 1. produce a clear error if any of the above requirements are violated. @@ -126,6 +126,6 @@ All outstanding questions have been resolved. It would be possible to define new calling conventions that can be used with naked functions. -A previous version of this document defined an `extern "custom"` calling convention. It was observed in conversation that calling conventions are really a *type* and that it could be useful to have calling conventions as part of the type system. In the interest of moving forward with constrained naked functions, it is best to limit the scope of this RFC and defer this (very good) conversation to a future RFC. +A previous version of this document defined an `extern "custom"` calling convention. It was observed in conversation that calling conventions are really a *type* and that it could be useful to have calling conventions as part of the type system. In the interest of moving forward with constrained naked functions, it is best to limit the scope of this RFC and defer this (very good) conversation to a future RFC. As a simple workaround, naked functions which do not conform to their specified calling convention should be marked as unsafe and the caller requirements should be documented in the safety section of the documentation per standard convention. It may also be possible to loosen the definition of a naked function in a future RFC. For example, it might be possible to allow the use of some additional, possibly new, operands to the `asm!()` block. From 3e7940ec09d1dfa1b7880e08e9f0a10106e818ef Mon Sep 17 00:00:00 2001 From: Nathaniel McCallum Date: Wed, 4 Aug 2021 16:37:56 -0400 Subject: [PATCH 10/13] Fix a typo in the Constrained Naked RFC --- text/2972-constrained-naked.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/2972-constrained-naked.md b/text/2972-constrained-naked.md index 2152539abe0..f5906486b72 100644 --- a/text/2972-constrained-naked.md +++ b/text/2972-constrained-naked.md @@ -77,7 +77,7 @@ The calling convention is defined as `extern "sysv64"`, therefore we know that t # Drawbacks -Implementing this will break compatiliby of existing uses of the nightly `#[naked]` attribute. All of these uses likely depend on undefined behavior. If this is a problem, we could simply use a different attribute. +Implementing this will break compatibility of existing uses of the nightly `#[naked]` attribute. All of these uses likely depend on undefined behavior. If this is a problem, we could simply use a different attribute. This definition may be overly strict. There is certainly some code that would work without this. The counter argument is that this code relies on undefined behavior and is probably not worth preserving. It might also be possible to reasonably ease the constraints over time. From d4a418b5735d4ec69601d6addf59ad350feac6fd Mon Sep 17 00:00:00 2001 From: Nathaniel McCallum Date: Thu, 5 Aug 2021 09:36:11 -0400 Subject: [PATCH 11/13] Fill in RFC number in Constrained Naked --- text/2972-constrained-naked.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/2972-constrained-naked.md b/text/2972-constrained-naked.md index f5906486b72..7f8b31ae55d 100644 --- a/text/2972-constrained-naked.md +++ b/text/2972-constrained-naked.md @@ -1,6 +1,6 @@ - Feature Name: `constrained_naked` - Start Date: 2020-08-06 -- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000) +- RFC PR: [rust-lang/rfcs#2972](https://github.com/rust-lang/rfcs/pull/2972) - Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) # Summary From 4137ed686ec317d1d30ced312eb7fa68e97e7408 Mon Sep 17 00:00:00 2001 From: Nathaniel McCallum Date: Wed, 10 Nov 2021 12:06:28 -0500 Subject: [PATCH 12/13] Fix a typo Co-authored-by: Andrea Canciani --- text/2972-constrained-naked.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/2972-constrained-naked.md b/text/2972-constrained-naked.md index 7f8b31ae55d..00f062337cd 100644 --- a/text/2972-constrained-naked.md +++ b/text/2972-constrained-naked.md @@ -36,7 +36,7 @@ In exchange for the above constraints, the compiler commits to: 1. never inline the function (implicit `#[inline(never)]`). 1. emit no additional instructions to the function body before the `asm!()` statement. -As a (weaker) correlary to the last compiler commitment, the initial state of all registers in the `asm!()` statement conform to the specified calling convention. +As a (weaker) corollary to the last compiler commitment, the initial state of all registers in the `asm!()` statement conform to the specified calling convention. # Explanation From 8e40788bf2106aa2407897b4afdcf531649b8f6c Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 16 Nov 2021 14:33:19 -0500 Subject: [PATCH 13/13] link to tracking issue --- text/2972-constrained-naked.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/2972-constrained-naked.md b/text/2972-constrained-naked.md index 00f062337cd..56a1b424e26 100644 --- a/text/2972-constrained-naked.md +++ b/text/2972-constrained-naked.md @@ -1,7 +1,7 @@ - Feature Name: `constrained_naked` - Start Date: 2020-08-06 - RFC PR: [rust-lang/rfcs#2972](https://github.com/rust-lang/rfcs/pull/2972) -- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) +- Rust Issue: [rust-lang/rust#90957](https://github.com/rust-lang/rust/issues/90957) # Summary This document attempts to increase the utility of [naked functions](https://github.com/rust-lang/rfcs/blob/master/text/1201-naked-fns.md) by constraining their use and increasing their defined invariants.