Skip to content

How to generate one instruction only when asm! is used in naked functions? #96037

Closed
@luojia65

Description

@luojia65

There's a usage sceneario in Rust for embedded rom bootloader. Some chips use eGON.BT0 format on boot, it has one jump instruction on head and the following should be boot tables.

Bit index Content
0..4 an instruction j main
5..12 bootloader magic
12.. following boot configurations

It's ideal to write this instruction j main using Rust naked function as follows, in this way we do not require further tools to help with filling this instruction.

#[naked]
#[link_section = ".head.text"]
#[export_name = "head_jump"]
pub unsafe extern "C" fn head_jump() {
    asm!("j {}", sym main, options(noreturn))
}

The options(noreturn) is required in current naked function or it won't compile. I expect this function to generate one instruction j main only, however it generates an unimp which is unexpected:

Disassembly of section .head.text:

0000000000000000 <head_jump>:
       0: 6f 00 60 02   j       0x26 <_ZN18test_d1_flash_bare4main17h5fd8eeda800e7085E>
       4: 00 00         unimp

Disassembly of section .text:

...

I didn't expect this unimp instruction, for it will overlap bootloader magic, making this Rust image not bootable. What should I do?

I looked into RFC 2972, in section Naked Function Definition it shows:

  1. emit no additional instructions to the function body before the asm!() statement.

Should we expect that there would be additional instructions after what we have in asm! macro?

Note: I try to remove the option(noreturn), it shows following compile error:

   Compiling test-d1-flash-bare v0.1.0 (D:\RustSBI\test-d1-flash-bare)
error[E0787]: asm in naked functions must use `noreturn` option
  --> src\main.rs:17:5
   |
17 |     asm!("j {}", sym start)
   |     ^^^^^^^^^^^^^^^^^^^^^^^
   |
help: consider specifying that the asm block is responsible for returning from the function
   |
17 |     asm!("j {}", sym start, options(noreturn))
   |                           +++++++++++++++++++

For more information about this error, try `rustc --explain E0787`.
error: could not compile `test-d1-flash-bare` due to previous error

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-inline-assemblyArea: Inline assembly (`asm!(…)`)I-heavyIssue: Problems and improvements with respect to binary size of generated code.O-riscvTarget: RISC-V architectureT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions