Reputation: 1846
I am currently experimenting with GNU LD linker scripts.
I want to have multiple .text.* sections in the compiled & linked Linux x64 ELF binary. I compiled my sample code into an .o object file via
gcc -ffunction-sections -fdata-sections -c sample.c
and now every function is placed into a separate .text. section in the object file:
<...>
8 .text.main 0000003b 0000000000000000 0000000000000000 00000098 2**0
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
9 .text.printString 0000001f 0000000000000000 0000000000000000 000000d3 2**0
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
10 .text.addPrintNumbers 00000032 0000000000000000 0000000000000000 000000f2 2**0
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
11 .text.getAnotherNumber 0000000b 0000000000000000 0000000000000000 00000124 2**0
CONTENTS, ALLOC, LOAD, READONLY, CODE
<...>
Linking this with LD and a custom script, leads to all code being merged into one monolithic .text section in the ELF binary. I tried two variants for .text.* merging:
<...>
.text :
{
KEEP (*(.text .text.*))
KEEP (*(.text.unlikely .text.*_unlikely .text.unlikely.*))
KEEP (*(.text.exit .text.exit.*))
KEEP (*(.text.startup .text.startup.*))
KEEP (*(.text.hot .text.hot.*))
KEEP (*(.stub .gnu.linkonce.t.*))
/* .gnu.warning sections are handled specially by elf32.em. */
KEEP (*(.gnu.warning))
}
<...>
(I know this KEEP arguments is only for the LD garbage collector to keep this section in code, not to place it into a separate section.
When I tried this experimental construct:
<...>
.text.addPrintNumbers :
{
KEEP(*(.text.addPrintNumbers))
}
.text.printString :
{
KEEP(*(.text.printString))
}
.text :
{
KEEP (*(.text .text.*))
KEEP (*(.text.unlikely .text.*_unlikely .text.unlikely.*))
KEEP (*(.text.exit .text.exit.*))
KEEP (*(.text.startup .text.startup.*))
KEEP (*(.text.hot .text.hot.*))
KEEP (*(.stub .gnu.linkonce.t.*))
/* .gnu.warning sections are handled specially by elf32.em. */
KEEP (*(.gnu.warning))
}
<...>
I had some partial success (objdump -x ./sample | less):
<...>
11 .text.addPrintNumbers 00000032 0000000000400400 0000000000400400 00000400 2**0
CONTENTS, ALLOC, LOAD, READONLY, CODE
12 .text.printString 0000001f 0000000000400432 0000000000400432 00000432 2**0
CONTENTS, ALLOC, LOAD, READONLY, CODE
13 .text 00000112 0000000000400460 0000000000400460 00000460 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
<...>
And the two manual linked sections where placed in the ELF binary and were still executable.
Is it possible to have all .text.* sections in the compiled and linked binary automatically, without a manual edited LD script. I am looking for a flag which does automatically, what I managed with the manually edited LD script.
Upvotes: 2
Views: 5007
Reputation: 13
Try to turn optimization on. Somehow turning optimization on, e.g. -O2 flag, instructs the compiler and the linker not to merge .text.* sections
Upvotes: 0
Reputation: 98496
About avoiding a custom linker script, I don't think it is possible. If you want to fiddle with sections you need a linker script.
In my machine, the command ld --verbose
outputs:
.text :
{
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
*(.text.hot .text.hot.*)
*(.text .stub .text.* .gnu.linkonce.t.*)
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
}
If you want to change that, you must change the script. There is no workaround!
Upvotes: 3