两个动态库的传递依赖中的符号冲突

时间:2019-06-19 18:16:29

标签: c linux linker elf dynamic-loading

我正在使用两个第三方动态库:liba.solibb.so。它们都调用另一个动态库中包含的名为common的函数,但是liba.so应该使用libsuba.so中的函数,而libb.so使用libsubb.so中的函数。

我无权访问这些动态库的源代码,因此无法更改一个库的函数名并重新编译它以解决冲突。

我知道macOS提供了一个似乎可以解决此问题的两级名称空间,但是我没有在ld手册页中找到类似的内容。

// exe.c
extern void func_a(void);
extern void func_b(void);

void main(void) {
    func_a();
    func_b();
}
// lib(a|b).c
extern void common(void);

void func_(a|b)(void) {
    common();
}
// libsub(a|b).c
#include <stdio.h>

void common(void) {
    printf("Common (A|B)\n");
}
all: exe

exe: exe.c liba.so libb.so
    gcc -L. -Wl,-rpath=. -o $@ $< -la -lb

liba.so: liba.c libsuba.so
    gcc -shared -fPIC -Wl,-rpath=. -L. -o $@ $< -lsuba

libb.so: libb.c libsubb.so
    gcc -shared -fPIC -Wl,-rpath=. -L. -o $@ $< -lsubb

libsub%.so: libsub%.c
    gcc -shared -fPIC -o $@ $<

有什么办法解决这个问题?

编辑:当前输出值为:

$ ./exe 
Common A
Common A

我希望输出为:

$ ./exe 
Common A
Common B

1 个答案:

答案 0 :(得分:1)

您应将问题报告给这些库的相应供应商。我认为它们缺少导出符号的命名空间(当然,如果libsubalibsubb都导出称为“ common”的符号)。

您是否考虑过使用objcopy --redefine-sym(请参阅this answer)?但是,objcopy似乎并未修改动态符号talbe,从而使此方法无用:(