これを実行できるリンカ スクリプト コマンドは知りませんが、objcopy を使用してリンク後に実行できます。 指図。 --add-section オプションを使用して、任意のデータを含むセクションを ELF ファイルに追加できます。 ELF ヘッダーに必要なフィールドが含まれていない場合は、新しいセクションを作成してそこに追加してください。
このリンク (十代のエルフ バイナリ) は別の質問に対する誰かの回答ですが、ELF ヘッダーの複雑さについて詳しく説明しています。
バージョン番号などの情報フィールドを含むオブジェクト ファイルを作成し、そのファイルをリンクして、結果の ELF バイナリに含まれるようにすることができます。
アイデンティティ
たとえば、ビルド プロセスの一部として、たとえば info.c
を生成できます。 1 つ以上の #ident
を含む ディレクティブ:
#ident "Build: 1.2.3 (Halloween)"
#ident "Environment: example.org"
コンパイルします:
$ gcc -c info.c
情報が含まれているかどうかを確認してください:
$ readelf -p .comment info.o
String dump of section '.comment':
[ 1] Build: 1.2.3 (Halloween)
[ 1a] Environment: example.org
[ 33] GCC: (GNU) 7.2.1 20170915 (Red Hat 7.2.1-2)
または、 objdump -s --section .comment info.o
を使用できます .デフォルトでは、GCC も独自のコメントを書き込むことに注意してください。
ELF 実行可能ファイルをリンクした後、情報を確認してください:
$ gcc -o main main.o info.o
$ readelf -p .comment main
String dump of section '.comment':
[ 0] GCC: (GNU) 7.2.1 20170915 (Red Hat 7.2.1-2)
[ 2c] Build: 1.2.3 (Halloween)
[ 45] Environment: example.org
コメント セクション
#ident
の使用 C 翻訳単位で .comment
を作成するのと基本的に同じです アセンブラ ファイルのセクション。例:
$ cat info.s
.section .comment
.string "Build: 1.2.3 (Halloween)"
.string "Environment: example.org"
$ gcc -c info.s
$ readelf -p .comment info.o
String dump of section '.comment':
[ 0] Build: 1.2.3 (Halloween)
[ 19] Environment: example.org
珍しいセクション名を使用することもできます (例:.section .blahblah
)。しかし .comment
他のツールによって使用され、理解されます。 GNU は .ident
も理解します ディレクティブであり、これは GCC が #ident
を変換するものです
記号付き
ELF 実行可能ファイル自体からもアクセスしたいデータについては、シンボルを作成する必要があります。
オブジェクトコピー
データ ファイルに格納されているマジック バイトを含めたいとします。
$ cat magic.bin
2342
GNU objcopy でオブジェクト ファイルに変換:
$ objcopy -I binary -O elf64-x86-64 -B i386 \
--rename-section .data=.rodata,alloc,load,readonly,data,contents \
magic.bin magic.o
記号を確認してください:
$ nm magic.o
0000000000000005 R _binary_magic_bin_end
0000000000000005 A _binary_magic_bin_size
0000000000000000 R _binary_magic_bin_start
使用例:
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
extern const char _binary_magic_bin_start[];
extern const char _binary_magic_bin_end[];
extern const unsigned char _binary_magic_bin_size;
static const size_t magic_bin_size = (uintptr_t) &_binary_magic_bin_size;
int main()
{
char s[23];
memcpy(s, _binary_magic_bin_start,
_binary_magic_bin_end - _binary_magic_bin_start);
s[magic_bin_size] = 0;
puts(s);
return 0;
}
すべてをリンク:
$ gcc -g -o main_magic main_magic.c magic.o
GNU ld
GNU ld は、objcopy と互換性のある命名スキームを使用して、データ ファイルをオブジェクト ファイルに変換することもできます。
$ ld -r -b binary magic.bin -o magic-ld.o
objcopy とは異なり、シンボルを .data
に配置します。 .rodata
の代わりに ただし、セクション (cf. objdump -h magic.o
).
インクビン
GNU objcopy が利用できない場合は、GNU を .incbin
として使用できます オブジェクトファイルを作成するディレクティブ (gcc -c incbin.s
でアセンブル) ):
.section .rodata
.global _binary_magic_bin_start
.type _binary_magic_bin_start, @object
_binary_magic_bin_start:
.incbin "magic.bin"
.size _binary_magic_bin_start, . - _binary_magic_bin_start
.global _binary_magic_bin_size
.type _binary_magic_bin_size, @object
.set _binary_magic_bin_size, . - _binary_magic_bin_start
.global _binary_magic_bin_end
.type _binary_magic_bin_end, @object
.set _binary_magic_bin_end, _binary_magic_bin_start + _binary_magic_bin_size
; an alternate way to include the size
.global _binary_magic_bin_len
.type _binary_magic_bin_len, @object
.size _binary_magic_bin_len, 8
_binary_magic_bin_len:
.quad _binary_magic_bin_size
xxd
中間Cファイルを作成し、それをコンパイルしてリンクするために、GNU objcopyもGNUも必要としない、より移植性の高い代替手段。たとえば、xxd:
$ xxd -i magic.bin | sed 's/\(unsigned\)/const \1/' > magic.c
$ gcc -c magic.c
$ nm magic.o
0000000000000000 R magic_bin
0000000000000008 R magic_bin_len
$ cat magic.c
const unsigned char magic_bin[] = {
0x32, 0x33, 0x34, 0x32, 0x0a
};
const unsigned int magic_bin_len = 5;