【发布时间】:2015-02-18 04:18:07
【问题描述】:
我一直在研究 mmap 函数的不同标志,即 MAP_FIXED、MAP_SHARED、MAP_PRIVATE。有人可以向我解释 MAP_FIXED 的目的吗?无法保证首先会使用地址空间。
【问题讨论】:
我一直在研究 mmap 函数的不同标志,即 MAP_FIXED、MAP_SHARED、MAP_PRIVATE。有人可以向我解释 MAP_FIXED 的目的吗?无法保证首先会使用地址空间。
【问题讨论】:
MAP_FIXED 是dup2 用于内存映射,它在dup2 用于文件描述符的完全相同的情况下很有用:当您想要执行原子重新分配的 replace 操作时一个资源标识符(在MAP_FIXED 的情况下是内存范围,或者在dup2 的情况下是fd)来引用一个新资源,而不会发生竞争,如果您首先释放旧资源,它可能会被重新分配给其他东西然后尝试为新资源重新获得它。
以加载共享库为例(通过动态加载器)。它至少包含三种类型的映射:程序代码的read+exec-only映射和来自可执行文件的只读数据,初始化数据的读写映射(也来自可执行文件,但通常使用不同的映射)相对偏移)和读写零初始化匿名内存(对于.bss)。将它们创建为单独的映射是行不通的,因为它们必须相对于彼此位于固定的相对地址。因此,您首先在没有MAP_FIXED 的情况下对所需的总长度进行虚拟映射(此映射的类型无关紧要),只是为了在内核分配的位置保留足够范围的连续地址,然后使用MAP_FIXED根据需要使用您需要创建的三个或更多映射来映射此范围的顶部。
此外,请注意,将MAP_FIXED 与硬编码地址或随机地址一起使用总是一个错误。使用MAP_FIXED 的唯一正确方法是替换现有映射,该映射的地址是由先前成功调用mmap 而不使用MAP_FIXED 分配的,或者以您认为替换整个页面安全的其他方式。这方面也完全类似于dup2;当调用者在目标 fd 上还没有打开文件并打算替换它时,使用 dup2 总是一个错误。
【讨论】:
如果您正在加载的文件包含指针,您需要将其加载到固定位置以确保指针正确。在某些情况下,这可能只是一种优化。
非位置无关的可执行文件必须加载到固定地址。
共享内存可能包含指针。
使用预绑定的可执行文件将尝试在预先确定的内存位置加载动态库以作为优化,但如果使用不同的位置(或库已更改),则会回退到正常加载技术。
所以MAP_FIXED 不是典型用法。
【讨论】: