Open Dragorn421 opened 4 months ago
I just realized that there is no need for section names to be unique for __attribute__((section))
or in general, neither inside one file or across TUs.
So this could also just be only keeping sections keep.{text,data,rodata}
and putting symbols in those, no need to have a .symbolthing
suffix. Would that be better?
Modern versions of binutils/GCC (GCC 11+, and matching binutils) have __attribute__((retain))
. This should do the trick?
@Dragorn421 does __attribute__((retain))
work for you?
It unfortunately does not work
my gcc / ld(binutils) versions:
$ $N64_GCCPREFIX/bin/mips64-elf-gcc --version
mips64-elf-gcc (GCC) 13.2.0
$ $N64_GCCPREFIX/bin/mips64-elf-ld --version
GNU ld (GNU Binutils) 2.41
on compilation:
src/main.c:8:1: error: 'retain' attribute ignored [-Werror=attributes]
8 | __attribute__((retain)) char str_main_abcdef[] = "str_main_abcdef contents";
| ^~~~~~~~~~~~~
the docs for the attribute (which I didn't know about btw, thanks for sharing) https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-retain-variable-attribute
-fdata-sections
inhibits this attribute from working. But compiling without that flag yields the same error.
This allows manually preventing specific sections (that is, specific symbols, since
-ffunction-sections -fdata-sections
means one section per symbol) from being garbage collected by the linker ld in the case they are not referenced.For example:
The
-fdata-sections
flag passed to gcc makes thestring
symbol be put into its own.rodata.string
section. Then on linking since that symbol is unreferenced the section is dropped.This PR changes the linker script n64.ld such that sections named like
keep.{text,data,rodata}.*
are always linked in regardless of garbage collection. This allows using the gcc section attribute to put a symbol in a so-named section that would be kept:The section suffix ("string" here) doesn't matter but I'd recommend using the symbol name like
-fdata-sections
does for simplicity, consistency andavoiding name collisions(EDIT: section names don't collide. that's the point of the linker after all... should we just not have suffixes at all?).I also made this possible with text and data. Not that it matters where a symbol ends up, afaik having put this string in
keep.text.string
and having it ending up in the rom elf's .text section would work just fine. (likewise with putting text in .data/.rodata) Still it seems preferable to put things where they're expected.I did not add this for .bss because that looks like a footgun, for example picture doing
__attribute__((section("keep.bss.mydata"))) int mydata;
, and later adding an initializer tomydata
but not changing the section fromkeep.bss
tokeep.data
: then the C source makes it look like the variable has that initial value, but it will be linked in the NOLOAD bss section which is 0-initialized regardless. Note that (afaik) linking a "bss" uninitialized data symbol into a LOAD section such as .data (__attribute__((section("keep.data.mydata"))) int mydata;
) will just work, the linker will store 0s in the data section for those bytes.Other alternatives:
LDFLAGS += --require-defined=string
in the Makefile but it would be better/easier to control this from the .c where the symbol is