我正在使用二进制文件,当我将其加载到我的调试器中,或者甚至运行readelf时,我注意到入口点是0x530,而不是通常的0x80 ******' d学会了ELF的装载。
这是为什么?还有什么事吗?二进制是链接的而不是剥离的。
答案 0 :(得分:2)
而不是通常的
0x80******
已经学会了ELF的加载。
你错了。
虽然0x804800
是32位x86 Linux二进制文件链接的常用地址,但该地址绝不是通用或特殊的。
64位x86_64
和aarch64
二进制文件的默认地址为0x40000
,powerpc64le
二进制文件的默认地址为0x10000000
。
没有理由不能在任何其他(页面对齐的)地址链接二进制文件(只要它不是0
,并且在地址空间的高端允许足够的堆栈。< / p>
为什么会这样?
二进制文件可能与自定义链接描述文件链接。没错。
答案 1 :(得分:1)
如雇员所述,入境地址不固定。
只是为了验证,我已尝试过x86_64:
gcc -Wl,-Ttext-segment=0x800000 hello_world.c
将入口点设置为0x800000
(+ ELF标头大小,在内存中加载0x800000
)而不是默认0x400000
。
然后两个:
readelf -h a.out
和gdb -ex 'b _start'
告诉我条目符合预期0x800440
(标题为0x440
字节)。
这是因为该值是一个输入,它告诉Linux内核在分配新进程时在哪里设置PC。
默认0x400000
来自使用的默认链接描述文件。您还可以修改https://stackoverflow.com/a/31380105/895245中提到的链接描述文件,在那里更改0x400000,并将新脚本与-T script
一起使用
如果我把它放在0x200000(2Mb)以下的任何地方或其他低地址,程序就会被杀死。我认为这是因为ld总是以2Mb的倍数加载部分,这是支持的最大页面大小(在大页面中),所以任何较低的部分都从0
开始,这很糟糕:Why is the ELF execution entry point virtual address of the form 0x80xxxxx and not zero 0x0?