为什么对象(ELF)文件中没有堆栈段?

时间:2018-02-23 18:12:28

标签: c operating-system elf

我是操作系统的初学者。这个问题是我的教授给出的,让我很困惑。我希望我能得到一些提示和帮助。

在我的记忆中,ELF文件可以相互链接。这是ELF文件不能有堆栈段的原因吗?

非常感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

这是因为堆栈不是需要以文件格式保存的东西,它与运行时执行完全相关。就像你不需要在文件中有一个“堆段”一样。

另一方面,堆栈属于执行线程,数据或函数,并且它没有固定大小。考虑一个递归函数:

int foo() {
    printf("Stack Overflow!\n");
    return foo();
}

每个递归在堆栈中都有自己的帧,没有堆栈属于foo()本身,只是为了执行它。

当然你可以在你的文件中保留一个堆栈段,就像一个很大的静态内存块一样,让%rsp指针(x64)指向它。但OS已经为你做了,所以没有必要。

答案 1 :(得分:2)

大多数GNU / Linux ELF程序都有堆栈段,因为在所有但非常新的架构中,程序头中的堆栈段用于将堆栈标记为不可执行(这是一种安全加固形式)。 p>

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000400040 0x0000000000400040
                 0x00000000000001f8 0x00000000000001f8  R E    0x8
  INTERP         0x0000000000000238 0x0000000000400238 0x0000000000400238
                 0x000000000000001c 0x000000000000001c  R      0x1
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
  LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
                 0x00000000000ffd0c 0x00000000000ffd0c  R E    0x200000
  LOAD           0x0000000000100548 0x0000000000700548 0x0000000000700548
                 0x000000000000b6fc 0x0000000000015440  RW     0x200000
…
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     0x10
  GNU_RELRO      0x0000000000100548 0x0000000000700548 0x0000000000700548
                 0x0000000000002ab8 0x0000000000002ab8  R      0x1

在某些GNU / Linux体系结构(FDPIC)上,内核甚至使用堆栈段的大小来设置主线程的堆栈大小。

(有不同类型的程序段。并非所有程序段都从文件映像加载位。)