ELF文件格式如何定义堆栈?

6
我正在学习ELF文件格式,因此编译了一个小程序,并从生成的可执行文件中转储了节头和它们的内容。
ELF头包含入口点地址,指向.text节的开头。
我还发现了包含静态数据的.data节和包含只读数据的.rodata节...我预计也会有一个用于堆栈的节,但我找不到那个节。
我还期望在某个时刻ESP被设置为某个节的顶部,但我在反汇编中找不到类似的东西。
那么ESP是如何获得其初始值的呢?
1个回答

12
下图描述了x86平台上典型C ELF可执行文件的内存映射。

Memory map of an C ELF executable on x86

  • 该过程在基地址处加载.text.data部分。

  • 主堆栈位于下方并向下增长。

  • 每个线程和函数调用都将有其自己的堆栈/堆栈帧
    这位于主堆栈下方。

  • 每个堆栈都由一个守卫页隔开,以检测堆栈溢出。

因此,在ELF文件中不需要专门的stack部分。


然而在ELF手册中,我们可以找到一些控制内存中栈属性的东西。主要是可执行权限来控制栈。
  1. PT_GNU_STACK
    GNU扩展,用于通过设置p_flags成员中的标志来控制栈的状态。

  2. .note.GNU-stack
    此节用于声明Linux对象文件的栈属性。该节的类型为SHT_PROGBITS。唯一使用的属性是SHF_EXECINSTR。这表示GNU链接器需要一个可执行栈的对象文件。


所以基地址==入口点地址?所以堆栈从0x08040000地址向下增长?看起来在那个图像上它在一个更高的地址。 - Calmarius
дёҚпәЊе…ӨеЏӘз‚№жЊ‡еђ‘.textе†…зљ„жџђдёҒдҢҚзҢ®пәЊдёҺе †ж €ж— е…ігЂ‚ - TheCodeArtist
1
总之,当我为我的宠物语言编写链接器(生成ELF文件)时,我不需要担心堆栈,因为加载器将为我分配并初始化ESP,是吗? - Calmarius
1
是的。加载器会处理这个问题。请查看文章,它描述了Linux ELF加载器将可执行文件加载到内存中的步骤。 - TheCodeArtist
请澄清一下,当您说“每个线程和函数调用将拥有自己的堆栈”时,是否意味着函数会创建它们自己的堆栈帧?对于线程来说,拥有单独的堆栈是有意义的,但是对于函数来说,这似乎与我之前的知识不符。 - J-Cake
1
每个函数调用,而不是每个函数。另外,称其为一个“栈帧”可能更有意义(已更新回答)。 - TheCodeArtist

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接