我编译了一个hello world C程序,这是file
信息:
hello: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 3.2.0, BuildID[sha1]=3c4fc3bc82d53281357312935790846333a3c7bc, with debug_info, not stripped
[当我检查段头信息时,我看到LOAD段的VirtAddr指向地址0x0000000000000000,该地址定义为NULL。入口地址为0x540,表示它位于两者的第一个LOAD段中。 E(执行)标志和.text部分也映射到第一个LOAD段。
[当我使用gdb并在main处设置一个断点时,我看到地址被更改,这意味着地址已经偏移了一定的偏移量。为什么会这样呢?我尝试多次加载程序,但是偏移量保持不变,这意味着没有地址随机化发生。我看到SO上的other questions正在获得与我相反的加载地址。为什么?当我用-m32
编译时,也会发生同样的事情。在过去几年中,从链接问题中获得了不同的输出后,Linux上的w.r.t有什么变化吗?
由于ELF与位置无关,因此您看到0
为LOAD
。
现代版本的GCC默认情况下会生成Position Independent Executables(除非另行配置)。如果可执行文件是PIE,则ELF标头中的基本虚拟地址设置为0
。在GDB下运行程序时,它会暂时禁用地址随机化并将程序加载到默认地址0x0000555555554000
。
如果要编译非PIE可执行文件,则可以使用-no-pie -fno-pie
编译标志。