-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Tracking issue for naked fns (RFC #1201) #32408
Comments
This issue was partially addressed by #29189 |
#32410 is an up to date implementation |
It might be a little late to point it out, but the RFC does not say anything about the interaction between naked functions and unwinding/panics. |
Note that global-asm has also been added, which overlaps somewhat with naked fns. |
So how exactly do experimental features get stabilized? This is an incredibly useful feature for building an OS, and I would love to see it move forward :) |
@mark-i-m well, if we retrofit this into the "experimental RFC" process that we are experimenting with (so much experimenting!), then the next step would be to take the lessons we've learned from having the feature around and write-up a new RFC that lays out the:
and then we would proceed as normal. In the case of naked functions, I think if anything my doubts have grown more grave, not less. In particular, I still don't think we can say much with confidence about how Rust code embedded in naked functions is expected to be compiled. Right now it's all pretty darn unspecified, iirc. I'd be interested to see some kind of data points for whether all naked fns in the wild use purely inline assembly, or whether they embed Rust code, and if so, what Rust code they embed (maybe we can define some kind of sensible subset)? |
@nikomatsakis Here is some code I wrote last weekend for an OS kernel: https://gist.github.com/mark-i-m/361cbcc39769f965b1c419091b9cbf4f It is mostly assembly, but it does have Rust mixed in. Specifically, it has function calls not just to other naked or inlined functions, but also to normal Rust functions, such as here.
Personally, my expectation is that it should compile just like it normally would -- just the prologue/epilogue are left out. For example, extern "C" fn foo(bar: usize) -> usize {
bar << 1
} generates _ZN10playground3foo17h002f6b2acb4d5b2dE:
.Lfunc_begin2:
.loc 1 2 0
.cfi_startproc
pushq %rbp
.Ltmp12:
.cfi_def_cfa_offset 16
.Ltmp13:
.cfi_offset %rbp, -16
movq %rsp, %rbp
.Ltmp14:
.cfi_def_cfa_register %rbp
movq %rdi, -16(%rbp)
.Ltmp15:
.loc 1 2 0 prologue_end
movq -16(%rbp), %rdi
movq %rdi, -8(%rbp)
.Ltmp16:
.loc 1 3 0
movq -8(%rbp), %rdi
shlq $1, %rdi
movq %rdi, -24(%rbp)
.loc 1 4 0
movq -24(%rbp), %rax
popq %rbp
retq I imagine the _ZN10playground3foo17h002f6b2acb4d5b2dE:
.Ltmp15:
.loc 1 2 0 prologue_end
movq -16(%rbp), %rdi
movq %rdi, -8(%rbp)
.Ltmp16:
.loc 1 3 0
movq -8(%rbp), %rdi
shlq $1, %rdi
|
Oh, and
|
I guess since embedded is a focus in 2018, this will be revived soon. One thing to note is that this feature is pretty useless to stabilize before inline asm 😛 |
It would be nice to see some movement on naked functions; I'm using them for e.g. interrupt handlers and the like in kernel-level code. Naked functions are one of the only ways to inject e.g. Rust constants into things like interrupt and syscall handlers. Yes, one can do that via inline assembly in "normal" functions, but there the preamble and epilogue can trash things you'd like to preserve on your stack (if you even have one! Consider the behavior of the Module level assembler doesn't really work here since you can't inject the value of a We're getting concerned about the dependency on unstable features and ties to the nightly compiler to get access to those unstable features, and what production people might have to say about that (which could potentially scuttle our entire Rust effort). Put another way, it sure would be nice to be able to build a kernel using only stable Rust. |
I think the general consensus is that we are happy to have naked functions, but there is no point in stabilizing them before inline asm since they are useless without it. |
Lol, that sounds like a challenge to find something you can do with naked functions without assembly 😆 #[naked]
fn hehehe() -> ! {
loop {} // No inline asm here!
} More seriously, I think naked functions can actually be useful apart from inline-asm. I was thinking about what specifically
In light of this, the following examples seem like they would be valid: #[no_mangle]
fn unsafe extern "x86-interrupts" do_pic_irq(irq_stack: IrqStackFrame) {
sched.timer(&irq_stack);
} #[no_mangle]
fn unsafe extern "x86-interrupts" do_page_fault(exception_stack: ExceptionStackFrame) {
CURRENT_PROCESS.mm.handle(&exception_stack);
} |
Naked functions are mostly equivalent to global asm. Notable exceptions:
Nothing else that I am aware of. When it comes to constants, I see no reason why global asm shouldn't support this as well. Executing Rust code is the really powerful part. But it's very tricky due to the Rust ABI not being specified (#600). Let's say rust-abi suddenly declares that on x86 |
I think it makes sense to just enforce that all naked fns have to be extern C. |
I'm not even sure if this is sufficient. What about arguments? Obviously declaring function parameters is out of the question - you would have to do it in your asm prologue instead. But this opens up the interesting problem that you can no longer have a volatile inline asm block as the first thing in the function: you need to at least declare (and potentially initialize?) the variables that are going to hold your parameters first. Is this guaranteed to be safe? Given that Rust does not have a I get the feeling that naked functions are a minefield of UB and footguns that should be avoided. Perhaps custom ABIs / calling conventions could be a better way to solve the same problems? |
I didn’t followed this point. The arguments are not on the callee’s stack frame; they are on the caller’s stack frame. As long as the caller obeys the calling convention, what’s the problem?
I think that would lead to a proliferation of custom calling conventions. Moreover fully specifying a calling convention sounds like a pain. |
@ds84182 That seems useful, but it seems like it would be fully backwards-compatible to stabilize naked_functions as-is and only later extend it to allow multiple |
@bstrie Correct. The CNF RFC explicitly states: "This definition may be overly strict. There is certainly some code that would work without this. ... It might also be possible to reasonably ease the constraints over time." From my perspective, I'd like to get something overly restrictive available for use in stable. Over time we can relax those restrictions or add features. But I don't want to let the perfect be the enemy of the good. |
One thing to consider: is any of the requirements on CNF not relaxable? For example, is there any future compatibility hazard in the |
@mark-i-m I think we'd have to consider that on a feature-by-feature basis. In your particular example, I don't think it is ever the intent to allow anything except |
This stabilizes the feature described in RFC 2972, which supersedes the earlier RFC 1201. Closes rust-lang#32408 Closes rust-lang#90957
I have submitted a stabilization proposal for the |
@rfcbot reviewed I am in favor of NOT doing "extended naked functions" and just doing the constrained version. |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
The final comment period, with a disposition to close, as per the review above, is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. |
I am not on the lang team, but since the FCP has ended I hope it is not presumptuous of me to close this in acknowledgement of the lang team's decision to supersede RFC 1201 with RFC 2972. Allow me to once again strongly encourage anyone interested in naked functions to please review the tentative stabilization report for RFC 2972's minimal subset of naked functions ( #90957 (comment) ); that stabilization is not yet in FCP, but it may become so relatively soon, so now is the time to bring up any concerns you may have. |
Update tracking issue of naked_functions The original tracking issue rust-lang#32408 was superseded by the new one rust-lang#90957 (constrainted naked functions) and therefore is closed.
Update tracking issue of naked_functions The original tracking issue rust-lang#32408 was superseded by the new one rust-lang#90957 (constrainted naked functions) and therefore is closed.
Update tracking issue of naked_functions The original tracking issue rust-lang#32408 was superseded by the new one rust-lang#90957 (constrainted naked functions) and therefore is closed.
Update tracking issue of naked_functions The original tracking issue rust-lang#32408 was superseded by the new one rust-lang#90957 (constrainted naked functions) and therefore is closed.
Rollup merge of rust-lang#119474 - nbdd0121:naked, r=Nilstrieb Update tracking issue of naked_functions The original tracking issue rust-lang#32408 was superseded by the new one rust-lang#90957 (constrainted naked functions) and therefore is closed.
This is the tracking issue for rust-lang/rfcs#1201.
Note that this is intended as a (particularly) experimental feature.
Feedback on its design is required, as well as comparisons with global asm.
The text was updated successfully, but these errors were encountered: