Saya tidak tahu perintah skrip linker yang dapat melakukan ini, tetapi Anda dapat melakukannya setelah tautan menggunakan objcopy memerintah. --add-section opsi dapat digunakan untuk menambahkan bagian yang berisi data arbitrer ke file ELF. Jika header ELF tidak berisi bidang yang Anda inginkan, buat saja bagian baru dan tambahkan di sana.
Tautan ini (biner elf mungil) adalah jawaban seseorang untuk pertanyaan lain, tetapi tautan ini membahas seluk-beluk header ELF secara mendetail.
Anda dapat membuat file objek dengan bidang informatif seperti nomor versi dan menautkan file tersebut sehingga disertakan dalam biner ELF yang dihasilkan.
Identitas
Misalnya, sebagai bagian dari proses pembuatan, Anda dapat membuat - katakanlah - info.c
yang berisi satu atau lebih #ident
arahan:
#ident "Build: 1.2.3 (Halloween)"
#ident "Environment: example.org"
Kompilasi:
$ gcc -c info.c
Periksa apakah informasi tersebut disertakan:
$ 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)
Sebagai alternatif, Anda dapat menggunakan objdump -s --section .comment info.o
. Perhatikan bahwa GCC juga menulis komentarnya sendiri, secara default.
Periksa informasi setelah menautkan executable 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
Bagian Komentar
Menggunakan #ident
dalam unit terjemahan C pada dasarnya sama dengan membuat .comment
bagian dalam file assembler. Contoh:
$ 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
Menggunakan nama bagian yang tidak umum juga dapat digunakan (mis. .section .blahblah
). Tapi .comment
digunakan dan dipahami oleh alat lain. GNU juga memahami .ident
direktif, dan inilah yang GCC terjemahkan #ident
ke.
Dengan Simbol
Untuk data yang juga ingin Anda akses dari executable ELF itu sendiri, Anda perlu membuat simbol.
Salinan objek
Katakanlah Anda ingin memasukkan beberapa byte ajaib yang disimpan dalam file data:
$ cat magic.bin
2342
Ubah menjadi file objek dengan GNU objcopy:
$ objcopy -I binary -O elf64-x86-64 -B i386 \
--rename-section .data=.rodata,alloc,load,readonly,data,contents \
magic.bin magic.o
Periksa simbol:
$ nm magic.o
0000000000000005 R _binary_magic_bin_end
0000000000000005 A _binary_magic_bin_size
0000000000000000 R _binary_magic_bin_start
Contoh penggunaan:
#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;
}
Tautkan semuanya menjadi satu:
$ gcc -g -o main_magic main_magic.c magic.o
GNU ld
GNU ld juga dapat mengubah file data menjadi file objek menggunakan skema penamaan yang kompatibel dengan objcopy:
$ ld -r -b binary magic.bin -o magic-ld.o
Tidak seperti objcopy, ini menempatkan simbol ke dalam .data
bukan .rodata
bagian, meskipun (lih. objdump -h magic.o
).
incbin
Jika objcopy GNU tidak tersedia, seseorang dapat menggunakan GNU sebagai .incbin
direktif untuk membuat file objek (rakit dengan 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
Alternatif yang lebih portabel yang tidak memerlukan objcopy GNU atau GNU adalah membuat file C perantara dan mengompilasi serta menautkannya. Misalnya dengan 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;