I'm experimenting with ELF executables and the gnu toolchain on Linux x86_64:
我在Linux x86_64上试验ELF可执行文件和gnu工具链:
I've linked and stripped (by hand) a "Hello World" test.s:
我已经链接并剥离(手工)“Hello World”测试。:
.global _start
.text
_start:
mov $1, %rax
...
into a 267 byte ELF64 executable...
到一个267字节的ELF64可执行文件...
0000000: 7f45 4c46 0201 0100 0000 0000 0000 0000 .ELF............
0000010: 0200 3e00 0100 0000 d400 4000 0000 0000 ..>.......@.....
0000020: 4000 0000 0000 0000 0000 0000 0000 0000 @...............
0000030: 0000 0000 4000 3800 0100 4000 0000 0000 ....@.8...@.....
0000040: 0100 0000 0500 0000 0000 0000 0000 0000 ................
0000050: 0000 4000 0000 0000 0000 4000 0000 0000 ..@.......@.....
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 .......<&..`.d@&
00000d0: e242 8bc7 48c7 c001 0000 0048 c7c7 0100 .B..H......H....
00000e0: 0000 48c7 c6fe 0040 0048 c7c2 0d00 0000 ..H....@.H......
00000f0: 0f05 48c7 c03c 0000 0048 31ff 0f05 4865 ..H..<...H1...He
0000100: 6c6c 6f2c 2057 6f72 6c64 0a llo, World.
It has one program header (LOAD) and no sections:
它有一个程序头(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
This seems to load the entire file (file offset 0 thru 0x10b - elf header and all) at address 0x400000.
这似乎加载了整个文件(文件偏移0到0x10b - elf标题和所有)在地址0x400000。
The entry point is:
切入点是:
Entry point address: 0x4000d4
Which corresponds to 0xd4 offset in the file, and as we can see that address is the start of the machine code (mov $1, %rax1
)
这对应于文件中的0xd4偏移量,因为我们可以看到地址是机器代码的开头(mov $ 1,%rax1)
My question is why (how) did the gnu linker choose address 0x400000
to map the file to?
我的问题是为什么(如何)gnu链接器选择地址0x400000来映射文件?
1 个解决方案
#1
10
The start address is usually set by a linker script.
起始地址通常由链接描述文件设置。
For example, on GNU/Linux, looking at /usr/lib/ldscripts/elf_x86_64.x
we see:
例如,在GNU / Linux上,查看/usr/lib/ldscripts/elf_x86_64.x,我们看到:
...
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); \
. = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;
The value 0x400000
is the default value for the SEGMENT_START()
function on this platform.
值0x400000是此平台上SEGMENT_START()函数的默认值。
You can find out more about linker scripts by browsing the linker manual:
您可以通过浏览链接器手册找到有关链接器脚本的更多信息:
% info ld Scripts
#1
10
The start address is usually set by a linker script.
起始地址通常由链接描述文件设置。
For example, on GNU/Linux, looking at /usr/lib/ldscripts/elf_x86_64.x
we see:
例如,在GNU / Linux上,查看/usr/lib/ldscripts/elf_x86_64.x,我们看到:
...
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); \
. = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;
The value 0x400000
is the default value for the SEGMENT_START()
function on this platform.
值0x400000是此平台上SEGMENT_START()函数的默认值。
You can find out more about linker scripts by browsing the linker manual:
您可以通过浏览链接器手册找到有关链接器脚本的更多信息:
% info ld Scripts