我有一个Linux应用程序,它在运行时加载非常小的(一些小函数)共享库。对于各种重要原因,我需要将共享库加载到某个虚拟内存范围。但是,dlopen()
并没有提供任何方法(我可以看到)告诉它,或提示它,在哪里放置它。
有没有办法告诉dlopen()
它应该把它加载的库放在哪里?
是否有dlopen()
的替代品可以提供该功能?
答案 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 compilation,libjit,GNU lighting,asmjit,...这样的库可以在某个固定地址生成机器代码(或者只是生成一个调用或跳转到真实的共享库函数)
dlopen
函数,您可以根据自己的需要进行操作)