Rtic duplicate symbol in example

Hello,

Contexte

I am trying to compile for a minimal RISC-V target the [task example](h ttps://github.com/rtic-rs/rtic/blob/master/examples/hifive1/examples/task.rs). This is the lined that I changed. I named the file rtic_task in src/bin of a rust project.

- use hifive1::hal::e310x;
+ use panic_halt as _;
- #[cfg_attr(feature = "riscv-mecall-backend", rtic::app(device = e310x))]
- #[cfg_attr(feature = "riscv-clint-backend", rtic::app(device = e310x, backend = H0))]
+ use my-chip_pac_from_svd2rust;
+ #[rtic::app(device = my-chip_pac_from_svd2rust)]

The my-chip_pac_from_svd2rust is generated using [update.sh script ](h ttps://github.com/riscv-rust/e310x/blob/master/e310x/update.sh) with same [e310x.svd](h ttps://github.com/riscv-rust/e310x/blob/master/e310x/e310x.svd) and [settings.yaml](h ttps://github.com/riscv-rust/e310x/blob/master/e310x/settings.yaml).

I get the following error running cargo build --bin rtic_task with this Cargo.toml

[dependencies]
my-chip-hal = { path = "../my-chip-hal" }
riscv-rt = { version = "0.14.0", features = ["single-hart"] }
embassy-sync = "0.6.2"
riscv = { version = "0.13.0", features = ["critical-section-single-hart"] }
panic-halt = "1.0.0"
embassy-time = "0.4.0"
embassy-executor = { version = "0.7.0", features = [
  "executor-thread",
  "arch-riscv32",
] }

# Examples
my-chip-semihosting = { path = "../my-chip-semihosting/" }
heapless = "0.8.0"
embedded-alloc = "0.6.0"
hashbrown = "0.15"
rand = { version = "0.9.1", default-features = false, features = ["small_rng"] }

# RTIC
rtic = { version = "2.2.0", features = [
  "riscv-mecall-backend",
  "test-critical-section",
] }
my-chip-pac = { path = "../my-chip-pac/" }
my-chip-pac-from-svd2rust = { path = "../my-chip-pac-from-svd2rust/", default-features = false }
error: linking with `rust-lld` failed: exit status: 1
  |
  = note:  "rust-lld" "-flavor" "gnu" "/tmp/rustck1aLee/symbols.o" "<52 object files omitted>" "--as-needed" "-Bstatic" "/my-chip-hal/tes
t-my-chip/target/riscv32im-unknown-none-elf/debug/deps/{libmy-chip_semihosting-2ffbf42f5a1c0b2b.rlib,libembassy_sync-87b9119bfe00654a.rlib,libfutures_sink-7c98d367e6868ba0.rlib,libembedded_io_asy
nc-6332518b4e0af9e1.rlib,libembedded_io-5a7a05882103caa1.rlib,libfutures_util-d70cd5914d6416bd.rlib,libpin_project_lite-1859dfb40d3b8df4.rlib,libfutures_task-9ce427ef940865dd.rlib,libpin_util
s-ff398133d360329c.rlib,libfutures_core-4dc0f3f50c08b2b2.rlib,librtic-c6ff90d7d03e9bce.rlib,libriscv_slic-037ca3eb600b6a02.rlib,libheapless-9be483b3723099fb.rlib,libhash32-a1720725e97bdabe.rl
ib,libbyteorder-276e6e17804c2b5e.rlib,libriscv-2b6b4891b309942b.rlib,libportable_atomic-d4113a794ead99e7.rlib,libbare_metal-0e51519dd53d7ec1.rlib,librtic_core-006ab86be720f86c.rlib,libmy-chip_p
ac_from_svd2rust-3f2d93f5074198d7.rlib,libvcell-6766a3ae69eeb921.rlib,libmy-chip_pac-99a5ea606d2af385.rlib,libriscv_rt-4d802197c67b9db8.rlib,libriscv-ce7d11ce67ab26e3.rlib,libcritical_section-4
e5b9e256e06c46b.rlib,libriscv_pac-2b64b5252652eb28.rlib,libembedded_hal-ada048c45269068b.rlib,libpanic_halt-e71b09e24a3f2b28.rlib}.rlib" "<sysroot>/lib/rustlib/riscv32im-unknown-none-elf/lib/
{librustc_std_workspace_core-*,libcore-*,libcompiler_builtins-*}.rlib" "-L" "/tmp/rustck1aLee/raw-dylibs" "-Bdynamic" "-z" "noexecstack" "-L" "my-chip-hal/test-my-chip" "-L" "/my-chip-hal/test-my-chip/target/riscv32im-unknown-none-elf/debug/build/riscv-rt-43ba08c2bfeca675/out"
 "-o" "/my-chip-hal/test-my-chip/target/riscv32im-unknown-none-elf/debug/deps/rtic_task-b1dc03ec8a5af0be" "--gc-sections" "-Tmemory.x" "-Tl
ink.x"
  = note: some arguments are omitted. use `--verbose` to show all linker arguments
  = note: rust-lld: error: duplicate symbol: _dispatch_core_interrupt
          >>> defined at interrupt.rs:2 (src/interrupt.rs:2)
          >>>            my-chip_pac_from_svd2rust-3f2d93f5074198d7.c6zc17v4kqt7gdf7wpco3txyf.rcgu.o:(_dispatch_core_interrupt) in archive 
my-chip-hal/test-my-chip/target/riscv32im-unknown-none-elf/debug/deps/libmy-chip_pac_from_svd2rust-3f2d93f5074198d7.rlib
          >>> defined at interrupts.rs:21 (src/interrupts.rs:21)
          >>>            riscv_rt-4d802197c67b9db8.riscv_rt.35be41d95d78462b-cgu.0.rcgu.o:(.text._dispatch_core_interrupt+0x0) in archive my-chip-hal/test-my-chip/target/riscv32im-unknown-none-elf/debug/deps/libriscv_rt-4d802197c67b9db8.rlib

          rust-lld: error: duplicate symbol: __CORE_INTERRUPTS
          >>> defined at interrupt.rs:2 (src/interrupt.rs:2)
          >>>            my-chip_pac_from_svd2rust-3f2d93f5074198d7.c6zc17v4kqt7gdf7wpco3txyf.rcgu.o:(__CORE_INTERRUPTS) in archive /stxp
5-hal/test-my-chip/target/riscv32im-unknown-none-elf/debug/deps/libmy-chip_pac_from_svd2rust-3f2d93f5074198d7.rlib
          >>> defined at interrupts.rs:21 (src/interrupts.rs:21)
          >>>            riscv_rt-4d802197c67b9db8.riscv_rt.35be41d95d78462b-cgu.0.rcgu.o:(.rodata.__CORE_INTERRUPTS+0x0) in archive /s
txp5-hal/test-my-chip/target/riscv32im-unknown-none-elf/debug/deps/libriscv_rt-4d802197c67b9db8.rlib```

What I did

Remove th intterupt module

To prevent duplicate symbol from the intterupt module and riscv_rt.

If I remove the intterupt module from which the error is refering to (defined at interrupt.rs:2) by ommiting the settings.yaml in my svd2rust command I get the following error :

error[E0433]: failed to resolve: could not find `interrupt` in `my-chip_pac_from_svd2rust`
 --> src/bin/rtic_task.rs:9:1
  |
9 | #[rtic::app(device = my-chip_pac_from_svd2rust)]
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ could not find `interrupt` in `my-chip_pac_from_svd2rust`
  |
  = help: consider importing one of these enums:
          crate::app::slic::riscv::interrupt::Exception
          crate::app::slic::riscv::interrupt::supervisor::Exception
          riscv::interrupt::Exception
          riscv::interrupt::supervisor::Exception
  = note: this error originates in the macro `rtic::export::codegen` (in Nightly builds, run with -Z macro-backtrace for more info)

rt feature

In the Cargo.toml of chip_pac_from_svd2rust

[dependencies]
critical-section = { version = "1.2.0", optional = true }
riscv = "0.13.0"
riscv-peripheral = "0.2.1"
riscv-rt = { version = "0.14.0", optional = true }
vcell = "0.1.3"


[features]
rt = ["riscv-rt"]
v-trap = ["rt", "riscv-rt/v-trap"] 

The feature rt is not default but to make sure I set default-features = false to chip_pac_from_svd2rust in my Cargo.toml at the top.

Question

Why do I have duplicate symbol, with my configuration and not with the hifive example of the rtic repository ? Altough I generated the pac with the same script.

Thank you advance for your answer

I didn't read the hifive code, but the documentation for riscv_rt::interrupts has this paragraph:

Note

If your target has custom core interrupt sources, the target PAC might provide equivalent code to adapt for the target needs (and is responsible for any alignment constraint). In this case, you may need to opt out this module. To do so, activate the no-interrupts feature of the riscv-rt crate.

1 Like

Thank you for your answer,

Setting riscv-rt = { version = "0.14.0", features = ["single-hart", "no-interrupts"] } leads to undefined symbol :

error: linking with `rust-lld` failed: exit status: 1
  |
  = note:  "rust-lld" "-flavor" "gnu" "/tmp/rustcjGVO7V/symbols.o" "<53 object files omitted>" "--as-needed" "-Bstatic" "my-chip-hal/test-my-chip/target/riscv32im-unknown-none-elf/debug/deps/{libmy-chip_semihosting-2ffbf42f5a1c0b2b.rlib,libembassy_sync-87b9119bfe00654a.rlib,libfutures_sink-7c98d367e6868ba0.rlib,libembedded_io_async-6332518b4e0af9e1.rlib,libembedded_io-5a7a05882103caa1.rlib,libfutures_util-d70cd5914d6416bd.rlib,libpin_project_lite-1859dfb40d3b8df4.rlib,libfutures_task-9ce427ef940865dd.rlib,libpin_utils-ff398133d360329c.rlib,libfutures_core-4dc0f3f50c08b2b2.rlib,librtic-c6ff90d7d03e9bce.rlib,libriscv_slic-037ca3eb600b6a02.rlib,libheapless-9be483b3723099fb.rlib,libhash32-a1720725e97bdabe.rlib,libbyteorder-276e6e17804c2b5e.rlib,libriscv-2b6b4891b309942b.rlib,libportable_atomic-d4113a794ead99e7.rlib,libbare_metal-0e51519dd53d7ec1.rlib,librtic_core-006ab86be720f86c.rlib,libmy-chip_pac_from_svd2rust-3f2d93f5074198d7.rlib,libvcell-6766a3ae69eeb921.rlib,libriscv_peripheral-291ce5b390a4509e.rlib,libmy-chip_pac-99a5ea606d2af385.rlib,libriscv_rt-6c6d04fcad39994c.rlib,libriscv-ce7d11ce67ab26e3.rlib,libcritical_section-4e5b9e256e06c46b.rlib,libriscv_pac-2b64b5252652eb28.rlib,libembedded_hal-ada048c45269068b.rlib,libpanic_halt-e71b09e24a3f2b28.rlib}.rlib" "<sysroot>/lib/rustlib/riscv32im-unknown-none-elf/lib/{librustc_std_workspace_core-*,libcore-*,libcompiler_builtins-*}.rlib" "-L" "/tmp/rustcjGVO7V/raw-dylibs" "-Bdynamic" "-z" "noexecstack" "-L" "my-chip-hal/test-my-chip" "-L" "my-chip-hal/test-my-chip/target/riscv32im-unknown-none-elf/debug/build/riscv-rt-fbfb95228d5f27d3/out" "-o" "my-chip-hal/test-my-chip/target/riscv32im-unknown-none-elf/debug/deps/rtic_task-574484c9f072815f" "--gc-sections" "-Tmemory.x" "-Tlink.x"
  = note: some arguments are omitted. use `--verbose` to show all linker arguments
  = note: rust-lld: error: undefined symbol: _ebss
          >>> referenced by executor.rs:75 (/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rtic-2.2.0/src/export/executor.rs:75)
          >>>               my-chip-hal/test-my-chip/target/riscv32im-unknown-none-elf/debug/deps/rtic_task-574484c9f072815f.cgkbgwtcq9awxm5pgakbbuua8.rcgu.o:(main)
          >>> referenced by executor.rs:75 (/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rtic-2.2.0/src/export/executor.rs:75)
          >>>               my-chip-hal/test-my-chip/target/riscv32im-unknown-none-elf/debug/deps/rtic_task-574484c9f072815f.cgkbgwtcq9awxm5pgakbbuua8.rcgu.o:(main)
          >>> referenced by executor.rs:75 (/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rtic-2.2.0/src/export/executor.rs:75)
          >>>               my-chip-hal/test-my-chip/target/riscv32im-unknown-none-elf/debug/deps/rtic_task-574484c9f072815f.cgkbgwtcq9awxm5pgakbbuua8.rcgu.o:(main)
          >>> referenced 3 more times
          >>> did you mean: __ebss
          >>> defined in: my-chip-hal/test-my-chip/target/riscv32im-unknown-none-elf/debug/build/riscv-rt-fbfb95228d5f27d3/out/link.x:168

I added _ebss = __ebss; to my linker script and it seems to compile, I will look further into making it work with spike

riscv-rt renamed _ebss to __ebss in version 0.14, to better align with cortex-m-rt, and apparently, rtic is not updated to be compatible with the newer version.

until rtic was updated, I suggest you downgrade your riscv-rt dependency to 0.13 to avoid potential other compatibility issues.

1 Like

Thank you,

Downgrading riscv-rt to 0.13.0 and adding the no-interrupts feature solved the issue.
Still wonder why it works without this feature within the hifive rtic example. But that's work for me!

the example project depends on the e310x pac, which has the no-interrupts feature enabled.

you can use the cargo tree command to see the full dependency tree (or rather, dependency graph), for example:

$ # show the unified package versions and features
$ cargo tree --format "{p} {f}"

$ # show inverse dependency to check which
$ # features are enabled by which dependent
$ cargo tree -i riscv-rt -e features
1 Like