【问题标题】:Symbol conflict in transitive dependencies of two dynamic libraries两个动态库的传递依赖中的符号冲突
【发布时间】:2019-06-19 18:16:29
【问题描述】:

我正在使用两个第三方动态库: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

【问题讨论】:

  • LD_PRELOAD=libsubb.so。另请参阅 What is the LD_PRELOAD trick?ld.so(8) 手册页。
  • 它强制common 函数来自libsubb.so。我希望func_a 使用来自libsuba.sofunc_bcommon 函数,来自libsubb.so 的函数。

标签: c linux linker elf dynamic-loading


【解决方案1】:

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

您是否考虑过使用objcopy --redefine-sym(参见this answer)?但是,objcopy 似乎没有修改动态符号表,使这种方法无用:(

【讨论】:

  • objcopy 确实似乎只更新了.symtab 而不是.dynsym。我报告了这个问题,与此同时,我将尝试使用 dlsym()RTLD_LOCAL 加载两个库之一,希望查找范围不同(它们根据 dsohowto.pdf)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-26
  • 2021-09-03
  • 2017-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多