【问题标题】:Memory mapping of binary to VAS二进制到 VAS 的内存映射
【发布时间】:2010-06-29 11:16:39
【问题描述】:

当创建一个新进程时,地址空间是使用 fork() 创建的,即为新进程创建与父进程完全相同的新页表条目。 在 fork() 之后调用 exec()。 exec() 系统调用期间会发生什么?

我在《操作系统概念》一书中读到,当执行一个新程序时,该进程会被赋予一个新的空 VAS。这是否意味着在 fork() 期间创建的页表条目将被删除/修改?空的VAS是什么意思?

二进制到VAS的内存映射是如何进行的? loader如何知道VAS的哪些地址应该映射到对应的二进制文件?

我真的很困惑。

【问题讨论】:

  • 这完全依赖于操作系统,与 C 无关。
  • @Paul 是的,但几乎所有现代操作系统都做类似的事情

标签: memory-management


【解决方案1】:

当您调用 exec 时,内核将加载二进制文件并设置一组全新的页表(替换旧的)。

加载器从二进制文件本身获取加载二进制文件的地址(基本上它使用read() 来获取不是代码的标题和内容,然后mmap() 实际加载二进制文件中的代码/数据内容)

所以它会查看二进制文件并确定应该如何加载它,mmap() 会传递一个地址来为需要位于不同位置的二进制文件的每个部分(即代码和数据部分可能是对mmap() 的两个不同调用,.bss 部分也将从 /dev/zero 映射)

请注意,根据操作系统和正在加载的二进制文件,其中一些内容可能由内核直接处理或由用户空间加载器处理(在 UNIXish 系统上,ld 是加载器,它处理共享对象加载)

【讨论】:

  • 加载器确实通过读取 ELF 格式二进制文件的标头从二进制文件本身获取将二进制文件映射到 VAS 的信息。现在,假设有两个进程同时使用二进制文件 abc.exe,那么如果根据二进制文件映射 VAS,则意味着两个进程的虚拟地址空间将相似。是这样吗??
  • 有时...也有可以在任何地址加载的位置无关代码(共享库总是这样)。加载器工作的另一部分是处理“重定位”,即更改某些值,使它们与加载二进制文件的实际地址相匹配。然而,可执行文件通常不是 PIC,因此它们总是加载到相同的虚拟地址。 (但如果由于某种原因加载的动态链接器在不同的位置说 libc(例如地址随机化),地址空间可能仍然不同)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-18
  • 1970-01-01
  • 2014-06-30
  • 2014-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多