什么时候使用 mmap MAP_FIXED?

When would one use mmap MAP_FIXED?

我一直在查看 mmap 函数的不同标志,即 MAP_FIXED、MAP_SHARED、MAP_PRIVATE。有人可以向我解释 MAP_FIXED 的目的吗?不能保证地址 space 会首先被使用。

如果您正在加载的文件包含指针,您需要将其加载到固定位置以确保指针正确。在某些情况下,这可能只是一种优化。

  • 非位置无关的可执行文件必须加载到固定地址。

  • 共享内存可能包含指针。

  • 使用预绑定的可执行文件将尝试在预定的内存位置加载动态库作为优化,但如果使用不同的位置(或如果库已更改),将回退到正常加载技术.

所以 MAP_FIXED 不是典型用法。

MAP_FIXED 是内存映射的 dup2,它在 dup2 对文件描述符有用的情况下非常有用:当你想执行 replace 操作以原子方式重新分配资源标识符(在 MAP_FIXED 的情况下为内存范围,在 dup2 的情况下为 fd)以引用新资源而不会出现竞争如果您首先释放旧资源然后尝试为新资源重新获得它,它可能会被重新分配给其他东西。

以加载共享库(通过动态加载程序)为例。它至少包含三种类型的映射:程序代码和可执行文件中的只读数据的只读+执行映射,初始化数据的读写映射(也来自可执行文件,但通常具有不同的相对偏移量)和读写零初始化匿名内存(.bss)。将它们创建为单独的映射是行不通的,因为它们必须相对于彼此处于固定的 相对地址 。因此,您首先在没有 MAP_FIXED 的情况下对所需的总长度进行虚拟映射(此映射的类型无关紧要)只是为了在内核分配的位置保留足够范围的连续地址,然后您使用 MAP_FIXED 根据需要使用您需要创建的三个或更多映射映射到此范围部分的顶部。

此外,请注意将 MAP_FIXED 与硬编码地址或随机地址一起使用 始终是一个错误 。使用 MAP_FIXED 的唯一正确方法是替换现有映射,其地址是通过先前成功调用 mmap 而没有 MAP_FIXED 分配的,或者以其他您认为安全的方式替换整页。这方面也完全类似于dup2;当调用者在目标 fd 上还没有打开文件并打算替换它时,使用 dup2 总是一个错误。