我有一个由GCC编译成特殊部分的C struct
,并通过链接描述文件放在输出二进制文件的开头。它包含文件元数据,包括开头的魔术值。
这是一个简单的例子,只使用一个字符串作为结构。
const char __magic_value[9] __attribute__((section(".the_header"))) = "MAGICVAL";
GCC将此值放入其自己的部分,我们可以看到readelf -S
:
There are 10 section headers, starting at offset 0x190:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00000000 000034 000000 00 AX 0 0 2
[ 2] .data PROGBITS 00000000 000034 000000 00 WA 0 0 1
[ 3] .bss NOBITS 00000000 000034 000000 00 WA 0 0 1
[ 4] .the_header PROGBITS 00000000 000034 000009 00 A 0 0 1
[ 5] .comment PROGBITS 00000000 00003d 00001e 01 MS 0 0 1
[ 6] .ARM.attributes ARM_ATTRIBUTES 00000000 00005b 000033 00 0 0 1
[ 7] .shstrtab STRTAB 00000000 00008e 000051 00 0 0 1
[ 8] .symtab SYMTAB 00000000 0000e0 000090 10 9 8 4
[ 9] .strtab STRTAB 00000000 000170 00001e 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
(注意第4节。)
现在,如果我为GCC调用指定-flto
,则不再发出此部分!
There are 19 section headers, starting at offset 0x730:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00000000 000034 000000 00 AX 0 0 2
[ 2] .data PROGBITS 00000000 000034 000000 00 WA 0 0 1
[ 3] .bss NOBITS 00000000 000034 000000 00 WA 0 0 1
[ 4] .gnu.lto_.profile PROGBITS 00000000 000034 00000f 00 E 0 0 1
[ 5] .gnu.lto_.icf.93e PROGBITS 00000000 000043 000017 00 E 0 0 1
[ 6] .gnu.lto_.jmpfunc PROGBITS 00000000 00005a 00000f 00 E 0 0 1
[ 7] .gnu.lto_.inline. PROGBITS 00000000 000069 00000f 00 E 0 0 1
[ 8] .gnu.lto_.purecon PROGBITS 00000000 000078 00000f 00 E 0 0 1
[ 9] .gnu.lto_.symbol_ PROGBITS 00000000 000087 000022 00 E 0 0 1
[10] .gnu.lto_.refs.93 PROGBITS 00000000 0000a9 00000f 00 E 0 0 1
[11] .gnu.lto_.decls.9 PROGBITS 00000000 0000b8 000239 00 E 0 0 1
[12] .gnu.lto_.symtab. PROGBITS 00000000 0002f1 00001d 00 E 0 0 1
[13] .gnu.lto_.opts PROGBITS 00000000 00030e 0000e8 00 E 0 0 1
[14] .comment PROGBITS 00000000 0003f6 00001e 01 MS 0 0 1
[15] .ARM.attributes ARM_ATTRIBUTES 00000000 000414 000033 00 0 0 1
[16] .shstrtab STRTAB 00000000 000447 00018c 00 0 0 1
[17] .symtab SYMTAB 00000000 0005d4 000130 10 18 17 4
[18] .strtab STRTAB 00000000 000704 00002c 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
我的链接描述文件找不到.the_header
部分,导致二进制文件损坏。
我已尝试为标头变量指定__attribute__((used))
,但没有效果。
这是链接描述文件的相关部分:
ENTRY(main)
MEMORY
{
APP (rwx) : ORIGIN = 0, LENGTH = 65536
}
SECTIONS
{
.header :
{
KEEP(*(.the_header))
} > APP
...
}
在使用链接时优化和上面的链接描述文件片段时,如何告诉GCC将.the_header
发送到最终二进制文件中?