有没有办法将Linux共享库加载到特定的内存位置?

时间:2014-09-18 18:29:17

标签: c linux elf dlopen

我有一个Linux应用程序,它在运行时加载非常小的(一些小函数)共享库。对于各种重要原因,我需要将共享库加载到某个虚拟内存范围。但是,dlopen()并没有提供任何方法(我可以看到)告诉它,或提示它,在哪里放置它。

有没有办法告诉dlopen()它应该把它加载的库放在哪里?

是否有dlopen()的替代品可以提供该功能?

3 个答案:

答案 0 :(得分:2)

您需要指定您尝试解决的实际问题。

  

对于各种重要原因™

我只能解释这个陈述,因为这是对你的要求,你不能对此做任何事情(即争议) 所以关于你的问题:
已指定加载地址,因此您无法通过此库更改它。实际上你需要阅读PIC 我认为做你想做的事的唯一方法是“破解”库并修改文本段 看看specify-preferred-load-address

说实话,你应该在这里解释一下你试图解决的问题是什么,这样你就可以得到答案,以各种方式帮助你。即这样你就可以有另一个选择作为解决方案

答案 1 :(得分:2)

我认为如果您愿意修改库,预链接程序实际上可能会演示如何执行此操作。目标是修改库,使其具有首选地址。预链接的目的是为了提高性能,但我怀疑它可以修改为适合您的用例。 请注意,永远不会保证在一般情况下会发生这种情况,但在受控制的情况下,您可以保证它会发生。 当然,检查预链接将使您了解所涉及的精灵的部分,并做出更明智的决定是否可能。 http://en.wikipedia.org/wiki/Prelink# 或者在Debian中查看http://packages.qa.debian.org/prelink来源。

答案 2 :(得分:0)

您不能这样做,dlopen(以及任何mmap ,而不是 MAP_FIXED)在最近的Linux系统上受ASLR约束。

因此,即使您在某个固定地址成功执行dlopen,您的方法也会失败,除非您在系统范围内禁用ASLR

特别是同一个程序执行相同dlopen - s的两个“相同”运行(即将dlopen - ed共享库)转换为可能不同的地址。

此外,在Linux上,您可以dlopen大量(至少数十万)共享对象。以我的manydl.c为例

正如我评论的那样,您的问题看起来像XY problem。你应该解释你想要的原因。什么是真正的动机和总体目标?

您可以通过处理ELF共享对象文件来重新实现修改后的dlopen,并自行重新定位。您还需要专门编译和链接您的共享对象。

如果函数简单而且很小(并且如果您接受相对于使用dlopen编译的小型共享库的gcc -fPIC -O2 -shared -Wall性能略有下降),您可以考虑使用一些{{3}像JIT compilationlibjitGNU lightingasmjit,...这样的库可以在某个固定地址生成机器代码(或者只是生成一个调用或跳转到真实的共享库函数)

顺便说一句,您可以使用并适应您的奇怪需求LLVM(它包含一个dlopen函数,您可以根据自己的需要进行操作)