Skip to content
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

Unhelpful error message on risc-v using the asm! macro with register extractions #54315

Closed
liamnaddell opened this issue Sep 18, 2018 · 10 comments
Labels
A-inline-assembly Area: Inline assembly (`asm!(…)`) O-riscv Target: RISC-V architecture requires-nightly This issue requires a nightly compiler in some way.

Comments

@liamnaddell
Copy link

(this is my first issue, sorry)

This is sort of a bug and sort of a feature request/cry for help. All of the following stuff is new to me, so this is probably user error.

The code I tried is attached below
diosix.tar.gz

If you take the src/kernel/main.rs function, and replace the a2 with r, the rust compiler no longer segfaults!

I expected some kind of helpful error about how you can't use the a2 register, but got the following beauty:

./build.sh --triple riscv32imac-unknown-none-elf --platform sifive_e
[+] Building for riscv32 SiFive-E series
   Compiling diosix v2.0.0 (/home/liam/repos/diosix)
warning: function is never used: `serial_write`
  --> src/kernel/main.rs:39:1
   |
39 | fn serial_write(s: &str) {
   | ^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: #[warn(dead_code)] on by default
error: Could not compile `diosix`.
To learn more, run the command again with --verbose.
make: *** [Makefile:2: all] Error 101

when the --verbose flag is added, you get

./build.sh --triple riscv32imac-unknown-none-elf --platform sifive_e
[+] Building for riscv32 SiFive-E series
       Fresh version_check v0.1.4
       Fresh libc v0.2.43
       Fresh ucd-util v0.1.1
       Fresh utf8-ranges v1.0.1
       Fresh bare-metal v0.2.3
       Fresh memchr v2.0.2
       Fresh regex-syntax v0.6.2
       Fresh riscv v0.3.0
       Fresh aho-corasick v0.6.8
       Fresh lazy_static v1.1.0
       Fresh thread_local v0.3.6
       Fresh regex v1.0.5
   Compiling diosix v2.0.0 (/home/liam/repos/diosix)
     Running `rustc --crate-name kernel src/kernel/main.rs --color always --crate-type bin --emit=dep-info,link -C opt-level=3 -C panic=abort --cfg 'feature="sifive_e"' -C metadata=332af80c5eb5cf4e -C extra-filename=-332af80c5eb5cf4e --out-dir /home/liam/repos/diosix/target/riscv32imac-unknown-none-elf/release/deps --target riscv32imac-unknown-none-elf -C ar=riscv32-elf-ar -C linker=riscv32-elf-ld -L dependency=/home/liam/repos/diosix/target/riscv32imac-unknown-none-elf/release/deps -L dependency=/home/liam/repos/diosix/target/release/deps --extern riscv=/home/liam/repos/diosix/target/riscv32imac-unknown-none-elf/release/deps/libriscv-9f27c1cf8cae7478.rlib -C link-arg=-Tsrc/platform/riscv32/sifive_e/link.ld -L native=/home/liam/repos/diosix/target/riscv32imac-unknown-none-elf/release/build/diosix-8a0e4656ce8eac69/out -l static=entry`
warning: function is never used: `serial_write`
  --> src/kernel/main.rs:39:1
   |
39 | fn serial_write(s: &str) {
   | ^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: #[warn(dead_code)] on by default
error: Could not compile `diosix`.
Caused by:
  process didn't exit successfully: `rustc --crate-name kernel src/kernel/main.rs --color always --crate-type bin --emit=dep-info,link -C opt-level=3 -C panic=abort --cfg 'feature="sifive_e"' -C metadata=332af80c5eb5cf4e -C extra-filename=-332af80c5eb5cf4e --out-dir /home/liam/repos/diosix/target/riscv32imac-unknown-none-elf/release/deps --target riscv32imac-unknown-none-elf -C ar=riscv32-elf-ar -C linker=riscv32-elf-ld -L dependency=/home/liam/repos/diosix/target/riscv32imac-unknown-none-elf/release/deps -L dependency=/home/liam/repos/diosix/target/release/deps --extern riscv=/home/liam/repos/diosix/target/riscv32imac-unknown-none-elf/release/deps/libriscv-9f27c1cf8cae7478.rlib -C link-arg=-Tsrc/platform/riscv32/sifive_e/link.ld -L native=/home/liam/repos/diosix/target/riscv32imac-unknown-none-elf/release/build/diosix-8a0e4656ce8eac69/out -l static=entry` (signal: 11, SIGSEGV: invalid memory reference)
make: *** [Makefile:2: all] Error 101

It is totally unclear to me what registers are allowed to be used where(this is because I have no idea what I am doing).

btw im on nightly: rustc 1.30.0-nightly (2ab3eba30 2018-09-14)
btw here is the code this is all based off of: "https://github.com/diodesign/diosix"
I really love rust-lang and I would love to hear back :)

@liamnaddell
Copy link
Author

wtf

@liamnaddell
Copy link
Author

I think this is b/c there is no type checking on the asm! macro's outputs

@nagisa nagisa added the A-inline-assembly Area: Inline assembly (`asm!(…)`) label Sep 18, 2018
@liamnaddell
Copy link
Author

This code also works when using the x(n) versions of registers instead of t0, a0 and other stuff like that

@levex
Copy link
Contributor

levex commented Oct 12, 2018

@liamnaddell hi, could you please upload the relevant source code to https://play.rust-lang.org/ ?

I don't really trust random archives on the internet :)

@liamnaddell
Copy link
Author

I really can't I'm sorry.

It uses separate asm files, and a build.sh and build.rs script for building. It also ships with multiple linker scripts

@liamnaddell
Copy link
Author

It's a bare-metal risc-v elf binary, not an app u run on your system, you need qemu

@levex
Copy link
Contributor

levex commented Nov 3, 2018

It failed to build for the sifive_e platform (a board which I happen to have):

[+] Building for riscv32 SiFive-E series
       Fresh version_check v0.1.4
       Fresh libc v0.2.43
       Fresh ucd-util v0.1.1
       Fresh utf8-ranges v1.0.1
       Fresh bare-metal v0.2.3
       Fresh memchr v2.0.2
       Fresh regex-syntax v0.6.2
       Fresh riscv v0.3.0
       Fresh aho-corasick v0.6.8
       Fresh lazy_static v1.1.0
       Fresh thread_local v0.3.6
       Fresh regex v1.0.5
   Compiling diosix v2.0.0 (/data/rust/rust-lang-rust/issues/misc/diosix)
     Running `/data/rust/rust-lang-rust/issues/misc/diosix/target/release/build/diosix-631a70b0814a0e1c/build-script-build`
error: failed to run custom build command for `diosix v2.0.0 (/data/rust/rust-lang-rust/issues/misc/diosix)`
process didn't exit successfully: `/data/rust/rust-lang-rust/issues/misc/diosix/target/release/build/diosix-631a70b0814a0e1c/build-script-build` (exit code: 101)
--- stdout
cargo:rerun-if-changed=src/platform/riscv32/sifive_e/link.ld
cargo:rerun-if-changed=src/platform/riscv32/sifive_e/asm/entry.s

--- stderr
thread 'main' panicked at 'Failed to assemble src/platform/riscv32/sifive_e/asm/entry.s: Os { code: 2, kind: NotFound, message: "No such file or directory" }', libcore/result.rs:1009:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.

But I reproduced your issue with the spike platform:

[+] Building for riscv32 Spike emulator
       Fresh version_check v0.1.4
       Fresh libc v0.2.43
       Fresh ucd-util v0.1.1
       Fresh utf8-ranges v1.0.1
       Fresh bare-metal v0.2.3
       Fresh memchr v2.0.2
       Fresh regex-syntax v0.6.2
       Fresh riscv v0.3.0
       Fresh aho-corasick v0.6.8
       Fresh lazy_static v1.1.0
       Fresh thread_local v0.3.6
       Fresh regex v1.0.5
   Compiling diosix v2.0.0 (/data/rust/rust-lang-rust/issues/misc/diosix)
     Running `rustc --crate-name kernel src/kernel/main.rs --color never --crate-type bin --emit=dep-info,link -C opt-level=3 -C panic=abort --cfg 'feature="spike"' -C metadata=dd9000a3a945a083 -C extra-filename=-dd9000a3a945a083 --out-dir /data/rust/rust-lang-rust/issues/misc/diosix/target/riscv32imac-unknown-none-elf/release/deps --target riscv32imac-unknown-none-elf -C ar=riscv32-elf-ar -C linker=riscv32-elf-ld -L dependency=/data/rust/rust-lang-rust/issues/misc/diosix/target/riscv32imac-unknown-none-elf/release/deps -L dependency=/data/rust/rust-lang-rust/issues/misc/diosix/target/release/deps --extern riscv=/data/rust/rust-lang-rust/issues/misc/diosix/target/riscv32imac-unknown-none-elf/release/deps/libriscv-88d9c8be593b66e4.rlib -C link-arg=-Tsrc/platform/riscv32/spike/link.ld`
warning: function is never used: `serial_write`
  --> src/kernel/main.rs:39:1
   |
39 | fn serial_write(s: &str) {
   | ^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: #[warn(dead_code)] on by default

error[E0668]: malformed inline assembly
  --> src/kernel/main.rs:27:9
   |
27 |         asm!("li $0,-1" :"=a2"(r) ::: "volatile");
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0668`.
error: Could not compile `diosix`.

Caused by:
  process didn't exit successfully: `rustc --crate-name kernel src/kernel/main.rs --color never --crate-type bin --emit=dep-info,link -C opt-level=3 -C panic=abort --cfg 'feature="spike"' -C metadata=dd9000a3a945a083 -C extra-filename=-dd9000a3a945a083 --out-dir /data/rust/rust-lang-rust/issues/misc/diosix/target/riscv32imac-unknown-none-elf/release/deps --target riscv32imac-unknown-none-elf -C ar=riscv32-elf-ar -C linker=riscv32-elf-ld -L dependency=/data/rust/rust-lang-rust/issues/misc/diosix/target/riscv32imac-unknown-none-elf/release/deps -L dependency=/data/rust/rust-lang-rust/issues/misc/diosix/target/release/deps --extern riscv=/data/rust/rust-lang-rust/issues/misc/diosix/target/riscv32imac-unknown-none-elf/release/deps/libriscv-88d9c8be593b66e4.rlib -C link-arg=-Tsrc/platform/riscv32/spike/link.ld` (exit code: 1)

Seems fixed. :-)

@nagisa nagisa added the O-riscv Target: RISC-V architecture label Jan 27, 2019
@lenary
Copy link
Contributor

lenary commented Aug 7, 2019

Using a reduced version of the same issue, here, the issue with the inline assembly has not gone away, but the error messages are much better. Sadly, you can't provide --target to play.rust-lang.org, even if you do only want to generate llvm IR, so it's hard to show.

For reference, the way to fix the inline assembly is to write the input constraint with braces (and, at the moment, due to a bug, using the architectural register name x12) ={x12}, as documented in the LLVM IR reference. Rust's asm! macro is a thin shim on top of this, and this has subtly different features to the inline assembly that GCC supports.

@liamnaddell
Copy link
Author

Thanks for your response :)

@Centril Centril added the requires-nightly This issue requires a nightly compiler in some way. label Oct 25, 2019
@Amanieu
Copy link
Member

Amanieu commented May 22, 2020

This issue does not apply to the new asm! (RFC 2850).

The legacy llvm_asm! is deprecated and is no longer maintained.

@Amanieu Amanieu closed this as completed May 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-inline-assembly Area: Inline assembly (`asm!(…)`) O-riscv Target: RISC-V architecture requires-nightly This issue requires a nightly compiler in some way.
Projects
None yet
Development

No branches or pull requests

6 participants