Linux 中 ld 到没有版本信息的库

Sea*_*ard 5 linker ld

编译 C/C++ 程序时,有没有一种方法可以链接到 Linux 中的库导出,而无需 ld 嵌入版本信息?

我正在构建一个链接到 Firefox 中的 libxul.so 的共享对象(它是 Firefox 二进制扩展)。我想构建我的共享对象并链接到 libxul.so,以便在运行时加载程序不关心 libxul.so 是什么版本。

现在,我的输出 .so 文件具有以下依赖项:

readelf -V myext.so
  0x0080: Version: 1  File: libxul.so  Cnt: 1
  0x0090:   Name: xul24.0  Flags: none  Version: 9
Run Code Online (Sandbox Code Playgroud)

(请注意,这取决于版本“xul24.0”)

导出的函数在 Firefox 版本之间不会发生变化。所以,我想删除这个版本指令。

当尝试加载到 Firefox 26 时,LD_DEBUG=file 会出现以下错误:

/usr/lib/firefox/libxul.so: error: version lookup error:
version `xul24.0' not found (required by /.../myext.so) (fatal)
Run Code Online (Sandbox Code Playgroud)

对于 Firefox 26 版本的 libxul.so,版本为'xul26'.

那么,如何防止 ld 将版本信息嵌入到我的库中呢?

Sea*_*ard 2

我能够根据需要构建库,而无需版本信息。

\n\n

我最终做的是使用适当的导出符号创建一个虚拟库——没有版本(或soname)信息——并在编译和链接我的库时链接到该虚拟库。在运行时,加载器加载真实库(libxul.so),不会因版本控制问题而失败,因为我的库不包含真实库的版本信息。为了弄清楚我需要哪些导出的符号,我首先链接到真实的 libxul.so,然后用于readelf --dyn-syms确定实际需要哪些符号。

\n\n

其中 ARCH 为 32 或 64(对于 32 位或 64 位编译):\ngcc -o $ARCH/libxul.so -fPIC -shared -DM$ARCH -m$ARCH xulstubs.c

\n\n

xulstubs.c:

\n\n
/*\n 2: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND NS_Realloc@xul26 (2)\n 3: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND NS_UTF16ToCString@xul26 (2)\n 7: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND NS_CStringCloneData@xul26 (2)\n13: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND NS_GetMemoryManager@xul26 (2)\n...\n */\nvoid NS_Realloc() {}\nvoid NS_UTF16ToCString() {}\nvoid NS_CStringCloneData() {}\nvoid NS_GetMemoryManager() {}\n/* ... etc. ... */\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在,从我的库导入的符号没有版本附加:

\n\n
23: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND NS_Realloc\n29: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND NS_UTF16ToCString\n33: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND NS_CStringCloneData\n37: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND NS_GetMemoryManager\n
Run Code Online (Sandbox Code Playgroud)\n\n

它按预期运行。

\n\n

我仍然想要一个更 \xe2\x80\x9celegant\xe2\x80\x9d 解决方案,一个不需要创建虚拟库的解决方案。但是,如果这是使用标准工具链的唯一解决方法,我可以接受。

\n