I'd like to write a linker script looking something like this:
SECTIONS {
. = 0x0;
.startup . : { startup.o(.text) }
.text : { *(.text) }
.data : { *(.data) }
.bss : { *(.bss COMMON) }
. = 0x4000;
other.text : { other.o(.text) }
other.data : { other.o(.data) }
other.bss : { other.o(.bss) }
}
My intention here is to have, in this order:
- a section with the
.text
from startup.o
.text
, .data
and .bss
containing those sections from all other input files besides other.o
- the
.text
, .data
and .bss
sections from other.o
Of course there is a problem with the script I've given: other.o
is included in the *
wildcards used previously, so it doesn't get put in the output section other
.
Besides manually listing all the input object files bar other.o
in place of the *
s, is there a way I can achieve what I want here?
You can use section attributes to solve this. Suppose you add the following attribute when declaring functions in that file (or any other file):
void foo() __attribute__ ((section(".specialmem")));
And a similar section definition in your linker script:
.specialmem:
{
*(.specialmem)
}
You can do the same thing with data/bss (global variables) as well.
Assuming you want some files/functions to end up in a specific memory location, it is a good practice to define these memory blocks in your linker file as well and then place them there like:
.specialmem:
{
*(.specialmem)
} >specialMemBlock
You may want to try EXCLUDE_FILE
Something like this:
*(EXCLUDE_FILE (other.o) .text .text. )
Partial solution: *
wildcards are fully-fledged file wildcards. If you're lucky enough that other.o
is in a different directory from the other input files, this will work:
SECTIONS {
. = 0x0;
.startup . : { foo/startup.o(.text) }
.text : { foo/*(.text) }
.data : { foo/*(.data) }
.bss : { foo/*(.bss COMMON) }
. = 0x4000;
other.text : { bar/other.o(.text) }
other.data : { bar/other.o(.data) }
other.bss : { bar/other.o(.bss) }
}