【问题标题】:how to reserve a particular range of virtual memory from a linux process如何从 linux 进程中保留特定范围的虚拟内存
【发布时间】:2016-04-29 16:57:35
【问题描述】:

i86-32 位系统: 有没有办法在进程内存映射中保留特定范围的虚拟地址空间,以阻止 ld.so(动态链接器)将任何共享对象加载到该范围内?

我想用至少2个1G的虚拟内存来映射两个1G的huge page,但是ld.so加载了中间的共享库,所以无法映射1G的huge page。

编译器无法完成这项工作。链接器脚本也不能。 ld.so 由加载器加载到可执行文件中,然后 ld.so 加载其他共享库。但是,ld.so 本身甚至位于映射空间的中间。

ld.so 和 libc.so 的入口点位于更高的地址,对于我们的应用程序无法更改。 入口地址:0x46c38810

谢谢, 江涛

【问题讨论】:

    标签: linux linker mmap


    【解决方案1】:

    ld.so被加载器加载到可执行文件中,

    否:ld.so加载器,由内核加载到进程中。

    你确实有几个选择:

    • 最简单的解决方案是完全静态链接二进制文件。请注意,在 Linux 上,这样的二进制文件仍然可以 dlopen 其他共享库,尽管这不是一个得到很好支持或经过很好测试的事情。
    • 更难的解决方案是构建您自己的补丁ld.so,并让您的应用程序使用该ld.so(使用-Wl,--dynamic-linker=... 标志)。
    • 如果您不想这样做,rtldi 可能会有所帮助(它将在之前 ld.so 运行)。

    【讨论】:

    • ld.so 由 execv 加载到可执行文件中。错字。感谢您的信息。
    【解决方案2】:

    共享库中的入口点地址由预链接编辑。 prelink 是为了避免共享库的加载地址冲突,优化和加速运行时加载器。默认情况下,它在我们的系统中处于开启状态。

    prelink 是一个程序,它修改 ELF 共享库和 ELF 动态链接的二进制文件,并为每个库分配一个唯一的虚拟地址空间槽。这样,动态链接器在启动时执行重定位所需的时间显着减少。由于更少的重定位,运行时内存消耗也减少了。

    /usr/sbin/prelink -avmR 预链接在 /etc/prelink.conf 中指定的目录中找到的所有二进制文件及其所有依赖库,为库分配唯一的虚拟地址空间槽

    通过禁用预链接,入口点不在库的中间。这样我们就可以映射另一个 1G 内存。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-23
      • 2018-09-21
      • 2014-02-06
      • 1970-01-01
      • 2011-08-21
      • 2015-08-16
      • 2013-12-13
      • 2016-11-23
      相关资源
      最近更新 更多