gpt4 book ai didi

c - 如何让共享库中的符号覆盖现有符号?

转载 作者:太空宇宙 更新时间:2023-11-04 07:53:15 25 4
gpt4 key购买 nike

我想使用 dlopen 加载一个共享库,并使其中的符号可用,而不必使用 dlsym 单独获取指向它们的函数指针。 man page表示 RTLD_DEEPBIND 标志将在全局范围之前在库中查找符号,但显然这并不意味着它会覆盖现有符号,因为这不起作用。考虑这个例子:

主.c:

#define _GNU_SOURCE
#include <stdio.h>
#include <dlfcn.h>

int is_loaded(){return 0;}

int main(){
void *h = dlopen("./libimplementation.so", RTLD_NOW | RTLD_DEEPBIND);
if(!h){
printf("Could not load implementation: %s\n", dlerror());
return 1;
}
puts(is_loaded() ? "Implementation loaded" : "Implementation not loaded");
dlclose(h);
}

实现.c:

int is_loaded(){return 1;}

生成文件:

all: main libimplementation.so

main: main.c
gcc -Wall -std=c99 -o $@ $^ -ldl

lib%.so: %.c
gcc -Wall -std=c99 -o $@ $^ -shared

clean:
-rm main *.so

当我使用 make./main 构建和运行时,我期望 libimplementation.so 中的 test() 函数 以覆盖 main 中的 test() 函数,但事实并非如此。我知道我也可以将 main() 中的所有代码移动到另一个共享库 run 中,然后让 main() dlopen libimplementation.soRTLD_GLOBAL 然后让 librun.so 引用来自 libimplementation.so 的符号> 没有定义它们所以加载它们:

修改后的main.c:

#define _GNU_SOURCE
#include <stdio.h>
#include <dlfcn.h>

int main(){
void *impl_h = dlopen("./libimplementation.so", RTLD_LAZY | RTLD_GLOBAL);
if(!impl_h){
printf("Could not load implementation: %s\n", dlerror());
return 1;
}
void *run_h = dlopen("./librun.so", RTLD_LAZY);
if(!run_h){
printf("Could not load run: %s\n", dlerror());
dlclose(impl_h);
return 1;
}
void (*run)(void);
*(void**)&run = dlsym(run_h, "run");
if(!*(void**)&run){
printf("Could not find entry point in run: %s\n", dlerror());
dlclose(impl_h);
dlclose(run_h);
return 1;
}
run();
dlclose(impl_h);
dlclose(run_h);
}

运行.c:

#include <stdio.h>

int is_loaded(void);

void run(void){
puts(is_loaded() ? "Implementation loaded" : "Implementation not loaded");
}

并且 Makefile 获取 librun.so 添加为 all 的先决条件。

有没有办法在不使用 dlsym 或将实际代码放入另一个共享库(如 librun.so)的情况下一次性从共享库中获取符号?

最佳答案

根本上没有办法做你要求的事情。想象一下主程序有这样的东西:

static char *myptr = array_in_lib1;

稍后,在您dlopen 时,myptr 有一些其他值。程序是否只是将变量更改为指向不同的对象?或者它是否已递增以指向数组中稍后的某个元素 - 在这种情况下,您是否希望它调整以解释 array_in_lib1 的重新定义以及来自新打开的库的新定义?或者它只是一个转换为 char * 的随机整数?如果不了解程序员的意图 完整的过程历史记录它是如何到达当前状态的,就不可能决定如何处理它。

上面是我构建的一个特别令人震惊的示例,但是符号在运行时更改定义的想法在各种方面从根本上都是不一致的。即使是 RTLD_DEEPBIND,在它已经做的事情中,也可以说是不一致和错误的。无论您想做什么,都应该找到另一种方法。

关于c - 如何让共享库中的符号覆盖现有符号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52461328/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com