i86-32位系统: 有没有办法在进程内存映射中保留特定范围的虚拟地址空间,以阻止ld.so(动态链接器)将任何共享对象加载到该范围内?
我想使用至少2个1G虚拟内存来映射两个1G大页面,但是,ld.so在中间加载共享库,所以我无法映射1G大页面。
编译器无法完成这项工作。链接器脚本也不行。 ld.so由加载器加载到可执行文件中,然后ld.so加载其他共享库。然而,ld.so本身甚至在映射空间的中间。
ld.so和libc.so的入口点位于更高的地址,无法为我们的应用程序更改。 入口点地址:0x46c38810
谢谢, 江涛
答案 0 :(得分:1)
ld.so由加载器加载到可执行文件中,
否:ld.so
是加载程序,它由内核加载到进程中。
你有几个选择:
dlopen
其他共享库,尽管这不是一个受到良好支持或经过良好测试的事情。ld.so
,并使您的应用程序使用ld.so
(使用-Wl,--dynamic-linker=...
标记)。ld.so
之前运行)。答案 1 :(得分:0)
共享库中的入口点地址由预链接编辑。 prelink是为了避免共享库的加载地址冲突,以优化和加速运行时加载器。默认情况下,它在我们的系统中。
prelink是一个修改ELF共享库和ELF动态链接二进制文件的程序,并为每个lib分配一个唯一的虚拟地址空间槽。以这种方式,动态链接器在启动时执行重定位所需的时间显着减少。由于重定位次数减少,运行时内存消耗也会减少。
/ usr / sbin / prelink -avmR 预链接在/etc/prelink.conf中指定的目录中找到的所有二进制文件及其所有依赖库,为库分配唯一的虚拟地址空间插槽
通过禁用预链接,入口点不在lib的中间。所以我们可以获得另一个1G内存。