为什么我的可执行文件中的入口点地址是0x8048330(0x330是.text部分的偏移量)

时间:2012-09-19 03:05:32

标签: c linux assembly x86 elf

我写了一个小程序来添加到整数并使用“readelf -a executable_name”它在elf标题中显示了入口点地址:

Entry point address: 0x8048330

即使在加载程序将内存加载到内存之前,我的可执行文件如何预先知道此地址? elf_format.pdf表示该成员提供系统首先转移控制的虚拟地址,从而启动该过程。任何人都可以解释这句话的含义是什么,这里虚拟地址的含义是什么?

另请注意,可执行文件的值为0x8048330,作为入口点地址。只是为了交叉检查,我编译了另一个程序,为此,入口点地址保持相同的值0x8048330(两种情况下.text部分的偏移量为0x330)。

3 个答案:

答案 0 :(得分:13)

输入地址由链接编辑器在创建时设置 可执行文件。加载程序将程序文件映射到指定的地址 在将控制转移到入口地址之前,通过ELF标头。

要使用具体示例,请考虑以下事项:

% file a.out
a.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, \
    for GNU/Linux 2.6.15, not stripped
% readelf -e a.out
... snip ...
Elf file type is EXEC (Executable file)
Entry point 0x8048170
There are 6 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000000 0x08048000 0x08048000 0x7cca6 0x7cca6 R E 0x1000
  LOAD           0x07cf98 0x080c5f98 0x080c5f98 0x00788 0x022fc RW  0x1000
... snip ...

第一个程序头指定文件的内容 文件偏移量0应映射到虚拟地址0x08048000。该 该段的文件和内存大小为0x7cca6字节。这个 segment将以可读和可执行的方式映射,但不可写 (它包含程序的代码)。

ELF头中指定的入口点地址是0x8048170,其中 落在包含程序代码的区域内。

John Levine的书“Linkers and Loaders”是一个很好的资源,可以就链接编辑和加载器相关事宜进行咨询。

答案 1 :(得分:11)

第一个问题:

您看到的入口点0x8048330是虚拟内存地址(相反,是物理内存)。 这意味着您的主管不必知道要映射的物理地址。 (用装载机加载后) 它甚至无法访问物理内存。 对于程序的过程,您的.text部分始终从0x8048330开始,您的系统(操作系统和硬件)将在运行时将其(虚拟地址)映射到物理内存。

映射和管理物理内存是很多事情,您可以在Google上查看更多信息。

第二个问题

我不确定哪一部分让你感到困惑,所以我会试着全部覆盖它们:

  • 多个程序可以有相同的入口点吗?

是的,可能有另一个具有相同入口点0x8048330的程序。因为此地址是虚拟的,所以当您尝试同时运行程序时,程序将在运行时映射到不同的物理内存。

  • 条目总是0x8048330吗?

嗯,Linux主管从0x8048000开始,但.text部分的偏移与其他部分的长度有关。所以不,它可以是0x8048034或其他任何东西。

  • 为什么它总是从0x8048000开始?

我认为这是历史的事情,Linux的设计者选择这个是出于某种未知甚至随机的原因。您可以参考this thread查看该领域的内容。

答案 2 :(得分:4)

关于虚拟地址问题:

普通用户态应用程序使用虚拟地址,这意味着它们不能直接访问内存空间。操作系统(借助某些微处理器的特殊功能)将此虚拟地址映射到物理地址

这样,操作系统可以防止应用程序读/写到其他应用程序内存或操作系统保留的内存中。此外,这允许以透明的方式为应用程序分页内存(使用硬盘作为内存)。