I need to put data to a separate object section in a static library. I would expect it gets linked into the main binary that uses the library, however it disappears after linking. See a reproducer below:
lib.c
static int keep_somewhere __attribute__((used, section("mySection"))) = 0xdeadbeef;
main.c
#include <stdio.h>
static int keep_in_main __attribute__((used, section("fromMain"))) = 0xdeadbeef;
int main(void) {
printf("test done\n");
return 0;
}
Makefile
report: main main-simple
size -A -d lib.a
size -A -d main
size -A -d main-simple
main: lib.a main.c
gcc -L. -l:lib.a main.c -o main
main-simple: lib.o main.c
gcc lib.o main.c -o main-simple
lib.o: lib.c
gcc -c lib.c
lib.a: lib.o
ar rcs lib.a lib.o
clean:
rm lib.a lib.o main
.PHONY: clean report
Run make
and observe the report.
Size of lib.a shows mySection just fine:
$ size -A -d lib.a
lib.o (ex lib.a):
section size addr
...
mySection 4 0
...
Total
So does the main-simple
binary created without the archive step:
size -A -d main-simple
main-simple :
section size addr
...
mySection 4 4210724
fromMain 4 4210728
...
Total 8387
However the main
binary does not. Notice the fromMain
section does appear:
$ size -A -d main
main :
section size addr
.interp 28 4195096
.note.gnu.property 64 4195128
.note.gnu.build-id 36 4195192
.note.ABI-tag 32 4195228
.gnu.hash 28 4195264
.dynsym 96 4195296
.dynstr 72 4195392
.gnu.version 8 4195464
.gnu.version_r 48 4195472
.rela.dyn 48 4195520
.rela.plt 24 4195568
.init 27 4198400
.plt 32 4198432
.text 251 4198464
.fini 13 4198716
.rodata 26 4202496
.eh_frame_hdr 44 4202524
.eh_frame 140 4202568
.init_array 8 4210192
.fini_array 8 4210200
.dynamic 464 4210208
.got 16 4210672
.got.plt 32 4210688
.data 4 4210720
fromMain 4 4210724
.bss 8 4210728
.comment 46 0
.gnu.build.attributes 6780 4218928
Total 8387
Just for reference, this was tested using gcc (GCC) 11.2.1 20210728 (Red Hat 11.2.1-1)
Edit 24th of Nov 2021:
For the sake of the used/unused symbol argument, I updated main.c to show that this works when the same pattern is used in the main compile unit.
I also added a simpler case where lib.o is linked directly and not as a library.