Я экспериментирую с исполняемыми файлами ELF и gnu toolchain на Linux x86_64:
Я связал и лишил (вручную) тест Hello World test.s:
.global _start
.text
_start:
mov $1, %rax
...
в исполняемый файл ELF64 размером 267 байтов...
0000000: 7f45 4c46 0201 0100 0000 0000 0000 0000 .ELF............
0000010: 0200 3e00 0100 0000 d400 4000 0000 0000 ..>[email protected]
0000020: 4000 0000 0000 0000 0000 0000 0000 0000 @...............
0000030: 0000 0000 4000 3800 0100 4000 0000 0000 [email protected]@.....
0000040: 0100 0000 0500 0000 0000 0000 0000 0000 ................
0000050: 0000 4000 0000 0000 0000 4000 0000 0000 [email protected]@.....
0000060: 0b01 0000 0000 0000 0b01 0000 0000 0000 ................
0000070: 0000 2000 0000 0000 0000 0000 0000 0000 .. .............
0000080: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000090: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000b0: 0400 0000 1400 0000 0300 0000 474e 5500 ............GNU.
00000c0: c3b0 cbbd 0abf a73c 26ef e960 fc64 4026 .......<&..`[email protected]&
00000d0: e242 8bc7 48c7 c001 0000 0048 c7c7 0100 .B..H......H....
00000e0: 0000 48c7 c6fe 0040 0048 c7c2 0d00 0000 [email protected]
00000f0: 0f05 48c7 c03c 0000 0048 31ff 0f05 4865 ..H..<...H1...He
0000100: 6c6c 6f2c 2057 6f72 6c64 0a llo, World.
Он имеет один заголовок программы (LOAD) и без разделов:
There are 1 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x000000000000010b 0x000000000000010b R E 200000
Кажется, что загружает весь файл (смещение файла 0 через 0x10b - заголовок эльфа и все) по адресу 0x400000.
Точка входа:
Entry point address: 0x4000d4
Что соответствует смещению 0xd4 в файле, и, как мы видим, этот адрес является началом машинного кода (mov $1, %rax1
)
Мой вопрос: почему (каким образом) gnu-компоновщик выбрал адрес 0x400000
для сопоставления файла?