oxidecomputer / hubris

A lightweight, memory-protected, message-passing kernel for deeply embedded systems.
Mozilla Public License 2.0
3.04k stars 180 forks source link

Setting release profile optimization level to 1 instead of "z" causes linker script to produce ambiguous error message with example app #1914

Closed kairoswater-jason closed 4 weeks ago

kairoswater-jason commented 4 weeks ago

Reproducible example: In /hubris/Cargo.toml set [profile.release] opt-level = 1 Increase /hubris/app/demo-stm32g0-nucleo/app-g070-mini.toml flash and stack sizes as needed Run cargo xtask dist app/demo-stm32g0-nucleo/app-g070-mini.toml

building crate demo-stm32g0-nucleo
   Compiling cortex-m-rt v0.6.15
   Compiling r0 v0.2.2
   Compiling kerncore v0.1.0 (/home/jason/Desktop/hubris_build_issue_test/hubris/sys/kerncore)
   Compiling demo-stm32g0-nucleo v0.1.0 (/home/jason/Desktop/hubris_build_issue_test/hubris/app/demo-stm32g0-nucleo)
   Compiling armv8-m-mpu v0.1.0 (/home/jason/Desktop/hubris_build_issue_test/hubris/lib/armv8-m-mpu)
   Compiling kern v0.1.0 (/home/jason/Desktop/hubris_build_issue_test/hubris/sys/kern)
   Compiling stm32g0 v0.15.1
error: linking with `rust-lld` failed: exit status: 1
  |
  = note: LC_ALL="C" PATH="/home/jason/.rustup/toolchains/nightly-2024-09-17-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/bin:/home/jason/.rustup/toolchains/nightly-2024-09-17-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/bin:/home/jason/.rustup/toolchains/nightly-2024-09-17-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/bin:/home/jason/.pyenv/shims:/home/jason/.pyenv/bin:/home/jason/.cargo/bin:/home/jason/.nvm/versions/node/v16.14.0/bin:/usr/local/arm_linux_4.8/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/opt/cmake/bin/" VSLANG="1033" "rust-lld" "-flavor" "gnu" "/tmp/rustcZO5yeq/symbols.o" "/home/jason/Desktop/hubris_build_issue_test/hubris/target/thumbv6m-none-eabi/release/deps/demo_stm32g0_nucleo-29d3a96be47810e8.demo_stm32g0_nucleo.9846eb9c8a0b0c12-cgu.0.rcgu.o" "--as-needed" "-Bstatic" "/tmp/rustcZO5yeq/libcortex_m_rt-3102eeec9bd1181d.rlib" "/tmp/rustcZO5yeq/libcortex_m-00330d557bc2ae61.rlib" "/home/jason/.rustup/toolchains/nightly-2024-09-17-x86_64-unknown-linux-gnu/lib/rustlib/thumbv6m-none-eabi/lib/libcompiler_builtins-6a4abc43e8e3a95c.rlib" "-Bdynamic" "--eh-frame-hdr" "-z" "noexecstack" "-L" "target" "-L" "/home/jason/Desktop/hubris_build_issue_test/hubris/target/thumbv6m-none-eabi/release/build/cortex-m-70325280d2379024/out" "-L" "/home/jason/Desktop/hubris_build_issue_test/hubris/target/thumbv6m-none-eabi/release/build/cortex-m-rt-bd5ec0d8ba48d352/out" "-L" "/home/jason/Desktop/hubris_build_issue_test/hubris/target/thumbv6m-none-eabi/release/build/stm32g0-de7ed7210dceb27a/out" "-o" "/home/jason/Desktop/hubris_build_issue_test/hubris/target/thumbv6m-none-eabi/release/deps/demo_stm32g0_nucleo-29d3a96be47810e8" "--gc-sections" "-Tlink.x" "-z" "common-page-size=0x20" "-z" "max-page-size=0x20"
  = note: rust-lld: error: 
          ERROR(cortex-m-rt): The .text section must be placed inside the FLASH memory.
          Set _stext to an address smaller than 'ORIGIN(FLASH) + LENGTH(FLASH)'

          rust-lld: error: 
          ERROR(cortex-m-rt): The .text section must be placed inside the FLASH memory.
          Set _stext to an address smaller than 'ORIGIN(FLASH) + LENGTH(FLASH)'

          rust-lld: error: section .fill at 0x8006D00 of size 0xFFFFFFFFFFFFD980 exceeds available address space
          rust-lld: error: section .text file range overlaps with .stack_sizes
          >>> .text range is [0x26C, 0x61B7]
          >>> .stack_sizes range is [0x4808, 0x4986]

          rust-lld: error: section .debug_loc file range overlaps with .rodata
          >>> .debug_loc range is [0x4987, 0x1922C]
          >>> .rodata range is [0x61B8, 0x6E47]

error: could not compile `demo-stm32g0-nucleo` (bin "demo-stm32g0-nucleo") due to 1 previous error

it appears the .fill section of target/link.X does not play well with optimzation level 1 but works fine with optimization level "z" ?

(context: this issue was discovered when trying to debug a system, and the optimizations were making following the program execution path in gdb difficult, this prompted changing the optimization level)

Is modifying the optimization setting for release in the toplevel Cargo.toml the proper way to change the optimization level? (my goal is to ship with less aggressive size optimization in release)

Side-note: this same .fill section build issue occurs on larger chips with significantly more flash memory.

kairoswater-jason commented 4 weeks ago

After some digging, it looks like whatever estimates size of the flash section of target/memory.x possibly might assume optimization level "z" not optimization level 1 (estimated size used to set length of FLASH section is shorter than the size of .text)

kairoswater-jason commented 4 weeks ago

it looks like it was user error (or rather absence of familiarity/knowledge)

[kernel]
requires = {flash = XXX ....

was the culprit (XXX was too small)

The generated linker error did not immediately clue me in that it was this particular setting. I assumed that kernel sizing issues would produce warnings similar to what is emitted for tasks.