有一个大的 数量的问题,关于如何执行库或动态加载一个可执行的SO。据我所知,所有答案都归结为:将可执行文件编译为与位置无关的代码,然后将其加载dlopen。直到最近glibc发生了更改(显式禁用了dlopenPIE),该方法仍然有效,并且在macOS上仍然有效。例如,此更改现在在ArchLinux的当前版本的glibc(2.30)中,并且尝试使用与dlopen位置无关的可执行文件会产生错误:“无法动态加载与位置无关的可执行文件”。
很难猜测是什么导致了如此巨大的改变,从而破坏了如此多的代码和有用的用例。(对Patchwork和Bugzilla的解释对我来说没有多大意义。)但是现在有一个问题:如果要创建同时也是动态库的可执行文件,该怎么办?反之亦然?
从其中一项评论链接了一个解决方案。为了后代在此复制:
#include <stdio.h>
#include <unistd.h>
const char service_interp[] __attribute__((section(".interp"))) = "/lib/ld-linux-x86-64.so.2";
extern "C" {
void lib_entry(void)
{
printf("Entry point of the service library\n");
_exit(0);
}
}
进行编译g++ -shared test-no-pie.cpp -o test-no-pie -Wl,-e,lib_entry会生成一个共享对象(动态库),该对象也可以在Linux上执行。
我有两个问题:
如果我想传递命令行参数怎么办?如何修改此解决方案以使其接受arc,argv? 还有其他选择吗?
很难猜测是什么促成这种根本性的变化
并非如此:它永远无法正常工作。
破坏太多代码
该代码已经以微妙的方式被破坏了。现在,您可以清楚地知道它将不起作用。
还有其他选择吗?
不做吗
dlopen可执行文件可以解决什么问题?
如果是真正的问题,请打开GLIBC bugzilla功能请求,解释该问题并请求支持的机制以实现所需的结果。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。