入口点地址和__executable_start有什么区别

What is the difference between Entry point address and __executable_start

我正在学习链接器如何在 Linux 上工作。有人告诉我,链接器会为可执行文件生成一些符号,例如 __executable_start,这是程序启动的地址。

此外,我知道 ELF 文件中有一个 "Entry point address"。

所以不知道它们有什么区别

我在下面写了一个简单的代码:

#include <stdio.h>

extern char __executable_start[];

int main()
{
    printf("Executable Start %X\n", __executable_start);

    return 0;
}

我用 GCC 编译它并得到一个名为 a.out.

的可执行文件

当我执行它时,它给了我 Executable Start 4CEDA000

然后我执行命令readelf -h a.out,关于入口点的输出是Entry point address: 0x540

嗯,显然,0x5404CEDA000 是完全不同的。

符号__executable_start不是入口点,而是.text节的开始。符号_start_确实是入口点。

在您的例子中,符号 _start 在运行时位于 4CEDA540 处。这是因为出于安全原因 (PIE) 可以在某个随机位置加载二进制文件,所以入口点仅相对于二进制文件中(由 ASLR 在运行时随机定位).text 部分的偏移量存储.这就是为什么 readelf 只显示 540