Gnu
GNU 連結器在 ELF 文件中的部分之間產生無用的間距
我的意圖是將文本部分放在記憶體中的特定位置(0x00100000)。
SECTIONS { . = 0x00100000; .text : { *(.text*) } }
儘管連結器確實這樣做了(注意 0x01000000
Addr
欄位):$ readelf -S file.elf There are 12 section headers, starting at offset 0x104edc: 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 00100000 100000 000e66 00 AX 0 0 4 [ 2] .eh_frame PROGBITS 00100e68 100e68 000628 00 A 0 0 4 ...
它還
.text
在 ELF 文件中的部分之前放置約 1MB 的零(注意該.text
部分的偏移量為 1MB)。以另一種方式顯示:$ hexdump -C file.elf 00000000 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 |.ELF............| 00000010 02 00 03 00 01 00 00 00 0c 00 10 00 34 00 00 00 |............4...| 00000020 dc 4e 10 00 00 00 00 00 34 00 20 00 02 00 28 00 |.N......4. ...(.| 00000030 0c 00 0b 00 01 00 00 00 00 00 00 00 00 00 00 00 |................| 00000040 00 00 00 00 90 14 10 00 96 04 4f 00 07 00 00 00 |..........O.....| 00000050 00 00 20 00 51 e5 74 64 00 00 00 00 00 00 00 00 |.. .Q.td........| 00000060 00 00 00 00 00 00 00 00 00 00 00 00 07 00 00 00 |................| 00000070 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00100000 02 b0 ad 1b 03 00 00 00 fb 4f 52 e4 8b 25 90 04 |.........OR..%..| 00100010 4f 00 50 53 e8 88 00 00 00 fa f4 eb fc 55 89 e5 |O.PS.........U..| 00100020 83 ec 10 c7 45 f8 00 80 0b 00 c7 45 fc 00 00 00 |....E......E....| 00100030 00 eb 24 8b 45 fc 8d 14 00 8b 45 f8 01 d0 8b 4d |..$.E.....E....M|
如何防止這種情況?我是否不正確地使用位置計數器(“點”表示法)語法?
事實證明,告訴連結器模擬 elf_i386 產生了我正在尋找的輸出,儘管我不明白為什麼。即,呼叫連結器:
$ ld -melf_i386 [...]
使用和不使用生成的文件
-melf_i386
似乎大多相似:with.elf: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, not stripped, with debug_info without.elf: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, not stripped, with debug_info
除了它們的大小有很大不同:
$ ls -l *.elf -rwxr-xr-x 1 user user 10948 May 24 11:56 with.elf -rwxr-xr-x 1 user user 1055428 May 24 11:56 without.elf
據我所知,輸出文件在其他方面完全相同:
$ readelf -S with.elf There are 12 section headers, starting at offset 0x28e4: 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 00100000 001000 000205 00 AX 0 0 4 [ 2] .eh_frame PROGBITS 00100208 001208 0000b8 00 A 0 0 4 [ 3] .bss NOBITS 001002c0 0012c0 3ef000 00 WA 0 0 4 [ 4] .debug_info PROGBITS 00000000 0012c0 0007bf 00 0 0 1 [ 5] .debug_abbrev PROGBITS 00000000 001a7f 0002c9 00 0 0 1 [ 6] .debug_aranges PROGBITS 00000000 001d48 000060 00 0 0 1 [ 7] .debug_line PROGBITS 00000000 001da8 00023c 00 0 0 1 [ 8] .debug_str PROGBITS 00000000 001fe4 0004bd 01 MS 0 0 1 [ 9] .symtab SYMTAB 00000000 0024a4 000280 10 10 22 4 [10] .strtab STRTAB 00000000 002724 00014e 00 0 0 1 [11] .shstrtab STRTAB 00000000 002872 000070 00 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings), I (info), L (link order), O (extra OS processing required), G (group), T (TLS), C (compressed), x (unknown), o (OS specific), E (exclude), p (processor specific)
請注意“偏移”欄位略有不同
$ readelf -S without.elf There are 12 section headers, starting at offset 0x1018e4: 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 00100000 100000 000205 00 AX 0 0 4 [ 2] .eh_frame PROGBITS 00100208 100208 0000b8 00 A 0 0 4 [ 3] .bss NOBITS 001002c0 1002c0 3ef000 00 WA 0 0 4 [ 4] .debug_info PROGBITS 00000000 1002c0 0007bf 00 0 0 1 [ 5] .debug_abbrev PROGBITS 00000000 100a7f 0002c9 00 0 0 1 [ 6] .debug_aranges PROGBITS 00000000 100d48 000060 00 0 0 1 [ 7] .debug_line PROGBITS 00000000 100da8 00023c 00 0 0 1 [ 8] .debug_str PROGBITS 00000000 100fe4 0004bd 01 MS 0 0 1 [ 9] .symtab SYMTAB 00000000 1014a4 000280 10 10 22 4 [10] .strtab STRTAB 00000000 101724 00014e 00 0 0 1 [11] .shstrtab STRTAB 00000000 101872 000070 00 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings), I (info), L (link order), O (extra OS processing required), G (group), T (TLS), C (compressed), x (unknown), o (OS specific), E (exclude), p (processor specific)