我编写了几个程序,发现当在64位编译时,内存映射段(例如共享对象和共享内存保存)总是位于7f9aca84a000-7fff88400000左右但从未完全相同.
我想知道x86_64架构(ELF64)上的内存段是否有固定的起始地址,或者该段的最大和最小范围是多少?
这就是为什么我问这个问题.我们正在将系统从Tru64 UNIX迁移到Linux.该系统使用IPC Sys V共享内存的复杂固定内存映射,并使用链表在该段内从结构转到另一个.由于这段代码的大小和复杂性,以及我们手头有限的时间,我们正在尝试找到一种可靠的方法来修复共享内存的开始(有效地使用带有指定地址的shmat来附加段).
对于64位,虚拟地址空间是如此巨大(48位有效可能的地址),选择“安全”固定地址比32位更容易,风险更小.
最佳答案
x86-64内存映射布局在
原文链接:https://www.f2er.com/linux/440256.htmlarch/x86/mm/mmap.c
中定义.如您所见,有两种策略:自上而下和自下而上.
自上而下的分配是默认的.它从堆栈最大范围以下128MB开始(由堆栈rlimit定义),由随机偏移量调整,然后从内存中向下分配后续映射.
自下而上的分配是后备.它用于以下任何一种情况:
>堆栈限制是无限的;
>该过程具有ADDR_COMPAT_LAYOUT个性设置;要么
> vm.legacy_va_layout sysctl非零.
在自下而上分配下,映射区域被逐渐分配更高的地址,从TASK_SIZE / 3开始,由随机偏移量调整. x86-64上的TASK_SIZE为0x800000000000,因此自下而上的分配将从0x2AAAAAAAAAAA开始.
我会为你的固定映射建议一个合适的漏洞,在任一分配策略下都应该是2 * TASK_SIZE / 3 – 我会使用0x500000000000.