struct
GCC によって特別なセクションにコンパイルされ、リンカー スクリプトを介して出力バイナリの先頭に配置されるCがあります。先頭にマジック値を含むファイル メタデータが含まれます。
構造体として文字列のみを使用した簡単な例を次に示します。
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
...
}
.the_header
リンク時の最適化と上記のリンカー スクリプト スニペットを使用する場合、GCC に最終的なバイナリを出力するように指示するにはどうすればよいですか?