Define `link_section` separate from the function definition

Hello, there is link_section attribute that allows setting a link section for a function. In my use case, embedded, I use it to put some important code into high speed ram so that it runs faster. But I can't go into other crates I depend and put it there.

Maybe allow to separate the definition of the function from some attributes? Example syntax (with crate-level attributes on bin crate):

#![unsafe(link_section(other_crate::foo::bar, ".my_section"))]

I don't know how it should combine with visibility, ideally I would be able to put any function in the section. Maybe allowing modules would solve this - set link section for every function in the module and its submodules.


One may argue that library may somehow put the code in some sections and I in my linker script would put them where needed, but it would be extremely inconvenient for libraries and they would most likely reject it.

By the time this separate link section attribute is known, it is already too late. other_crate::foo::bar is likely already compiled and assigned a section in the object file. Only a linker script can help you at that point.

If you are fine to depend on implementation details, something you could do is to put .my_section { *(.text.*other_crate*foo*bar*) } or something like that in your linker script. This should work for as long as -ffunction-sections is enabled, which it should be by default on most targets. It should work with both the legacy and v0 symbol mangling.

Unfortunately, this solution doesn't work :sweat_smile:

Linker script can only go forward, so if sections were already collected before, they cannot be kept like this. It would've worked if RAM was before FLASH, but not the other way around.

And for FLASH they are collected like (.text), so there isn't a way to make an exception

I don't know what linker you're using, but what's stopping you from putting RAM before FLASH? GNU linker scripts don't require you to collect input sections into output sections in ascending order of load address (as far as I can tell from the manual, anyway).

  1. I can't put RAM before FLASH because they are defined by MCU manufacturer.

cannot move location counter backwards (from 0000000020000882 to 000000001ffe0000) collect2: error: ld returned 1 exit status

Maybe instead of crate attribute it may be a rustc flag?

You should be able to patch the linker script to use a custom one? And report an issue with the vendor so they can get this resolved for everyone.

What do you mean? The linker script is fine, the address space of the MCU has RAM after FLASH