Code: Select all
build/a.o
[ 2] .rela.text RELA 0000000000000000 000009b0
0000000000000228 0000000000000018 I 5 1 8
build/b.o
[ 2] .rela.text RELA 0000000000000000 00000cb8
0000000000000060 0000000000000018 I 19 1 8
build/c.o
[ 2] .rela.text RELA 0000000000000000 00002f78
00000000000001f8 0000000000000018 I 18 1 8
Code: Select all
# readelf -S final.elf | grep rela
<no results>
Code: Select all
.text : { *(.text*) }
.data : { *(.data*) }
.module : { *(.module*) }
.rela : { *(.rela*) }
.bss : { *(.bss*) }
Code: Select all
-q, --emit-relocs Generate relocations in final output
-r, -i, --relocatable Generate relocatable output
Code: Select all
# readelf -S build/final.elf
There are 12 section headers, starting at offset 0x2c9c0:
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .text PROGBITS 0000000100000000 00010000
000000000000ed5c 0000000000000000 AX 0 0 2048
[ 2] .rela.text RELA 0000000000000000 00025800
0000000000006f60 0000000000000018 I 9 1 8
[ 3] .rodata PROGBITS 000000010000ed60 0001ed60
0000000000001c11 0000000000000000 A 0 0 8
[ 4] .rela.rodata RELA 0000000000000000 0002c760
00000000000001b0 0000000000000018 I 9 3 8
[ 5] .data PROGBITS 0000000100010978 00020978
00000000000000b0 0000000000000000 WA 0 0 8
[ 6] .module PROGBITS 0000000100010a28 00020a28
0000000000000028 0000000000000000 WA 0 0 8
[ 7] .rela.module RELA 0000000000000000 0002c910
0000000000000060 0000000000000018 I 9 6 8
...
So then I tried -r because the distinction is unclear on the difference from --emit-relocs. Now it looks like the linker actually honored my .rela section declaration - but it's empty?
Code: Select all
# readelf -S build/final.elf
There are 13 section headers, starting at offset 0x1d210:
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .text PROGBITS 0000000100000000 00000800
000000000000ed5c 0000000000000000 AX 0 0 2048
[ 2] .rela.text RELA 0000000000000000 00016048
0000000000006f60 0000000000000018 I 10 1 8
[ 3] .rodata PROGBITS 0000000000000000 0000f560
0000000000001c11 0000000000000000 A 0 0 8
[ 4] .rela.rodata RELA 0000000000000000 0001cfa8
00000000000001b0 0000000000000018 I 10 3 8
[ 5] .data PROGBITS 0000000000001c18 00011178
00000000000000b0 0000000000000000 WA 0 0 8
[ 6] .module PROGBITS 0000000000001cc8 00011228
0000000000000028 0000000000000000 WA 0 0 8
[ 7] .rela.module RELA 0000000000000000 0001d158
0000000000000060 0000000000000018 I 10 6 8
[ 8] .bss NOBITS 0000000000001d00 00011280
0000000000002190 0000000000000000 WA 0 0 64
readelf: Warning: [ 9]: Info field (0) should index a relocatable section.
[ 9] .rela RELA 0000000000001c11 00011280
0000000000000000 0000000000000018 W 10 0 1
...
And readelf is upset with the contents of the section, clearly. So something still is not quite right.
So, fundamentally the question is - how can I link some N object files together where each has their own arbitrary set of relocation sections (e.g. .rela.text, .rela.rodata, etc) and put them all into a single output section in the final binary?
As can be seen from my linker script above, the intent was to define a single .rela section that matches against all of these other .rela*` sections from the inputs .. but for some reason this is not working.
I have shown that the input files do have these .rela* sections, but the linker is refusing to merge them into a single final output section as I was (attempting) to describe in the linker script. And, in fact, the linker outright discarded all relocations without --emit-relocs or -r.
I feel confident that this is not altogether a strange ask, considering the default linker script used by my toolchain does this itself ..
Code: Select all
.rela.dyn :
{
*(.rela.init)
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
*(.rela.fini)
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
*(.rela.ctors)
*(.rela.dtors)
*(.rela.got)
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
*(.rela.ifunc)
}
.rela.plt :
{
*(.rela.plt)
PROVIDE_HIDDEN (__rela_iplt_start = .);
*(.rela.iplt)
PROVIDE_HIDDEN (__rela_iplt_end = .);
}