rust-embedded / cortex-m-rt

Minimal startup / runtime for Cortex-M microcontrollers

Home Page:https://rust-embedded.github.io/cortex-m-rt/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How to "INSERT AFTER .text"?

Dirbaio opened this issue · comments

I'm trying to link Rust code with C code from the Nordic Semiconductor nRF5 SDK.

The issue is it uses clever linker tricks to "collect things" from several C files and have the linker put them in a contiguous array, so it can iterate over all of them.

Their linker script does multiple instances of this:

SECTIONS
{
  .sdh_soc_observers :
  {
    PROVIDE(__start_sdh_soc_observers = .);
    KEEP(*(SORT(.sdh_soc_observers*)))
    PROVIDE(__stop_sdh_soc_observers = .);
  } > FLASH
} INSERT AFTER .text

I tried adding that to memory.x, but linking fails with these errors:

  = note: rust-lld: error: section .sdh_ble_observers file range overlaps with .rodata
          >>> .sdh_ble_observers range is [0x13E20, 0x13EB7]
          >>> .rodata range is [0x13E20, 0x16D6F]
          
          rust-lld: error: section .rodata file range overlaps with .sdh_soc_observers
          >>> .rodata range is [0x13E20, 0x16D6F]
          >>> .sdh_soc_observers range is [0x13EB8, 0x13ECF]
          
          rust-lld: error: section .sdh_ble_observers virtual address range overlaps with .rodata
          >>> .sdh_ble_observers range is [0x39E20, 0x39EB7]
          >>> .rodata range is [0x39E20, 0x3CD6F]
          
          rust-lld: error: section .rodata virtual address range overlaps with .sdh_soc_observers
          >>> .rodata range is [0x39E20, 0x3CD6F]
          >>> .sdh_soc_observers range is [0x39EB8, 0x39ECF]
          
          rust-lld: error: section .sdh_ble_observers load address range overlaps with .rodata
          >>> .sdh_ble_observers range is [0x39E20, 0x39EB7]
          >>> .rodata range is [0x39E20, 0x3CD6F]
          
          rust-lld: error: section .rodata load address range overlaps with .sdh_soc_observers
          >>> .rodata range is [0x39E20, 0x3CD6F]
          >>> .sdh_soc_observers range is [0x39EB8, 0x39ECF]

If I change link.x.in like this it works:

  /* ### .text */
  .text _stext :
  {
    *(.text .text.*);
    *(.HardFaultTrampoline);
    *(.HardFault.*);
  } > FLASH

  . = ALIGN(4); /* THIS IS MOVED OUT OF .text */
  __etext = .;

  /* ### .rodata */
  .rodata __etext : ALIGN(4)
  {

It seems the issue is that __etext doesn't get "moved" by the INSERT AFTER if it's inside the .text section, but it does if it's outside. I'm not sure if that's the best fix though, because __extext is then "lying" (it's at the end of .text + other stuff).

Is there a supported way to add extra data to flash? (from memory.x, without having to edit linkr.x)? Or would you accept these changes in a PR?