【发布时间】:2010-04-11 09:57:41
【问题描述】:
我现有的 Linux 共享对象文件(共享库)已被剥离。我想制作一个包含一些附加功能的新版本的库。我曾希望类似以下的方法会起作用,但没有:
ld -o newlib.so newfuncs.o --whole-archive existinglib.so
我没有现有库的源代码。我可以得到它,但要获得一个具有必要依赖项的完整构建环境,对于一个看似简单的问题来说,需要付出很多努力。
【问题讨论】:
我现有的 Linux 共享对象文件(共享库)已被剥离。我想制作一个包含一些附加功能的新版本的库。我曾希望类似以下的方法会起作用,但没有:
ld -o newlib.so newfuncs.o --whole-archive existinglib.so
我没有现有库的源代码。我可以得到它,但要获得一个具有必要依赖项的完整构建环境,对于一个看似简单的问题来说,需要付出很多努力。
【问题讨论】:
您可能希望通过使用预加载来加载您的对象,从一个稍微不同的角度来尝试。
设置 LD_PRELOAD 指向你的新对象
export LD_PRELOAD=/my/newfuncs/dir/newfuncs.o
并通过您的 LD_LIBRARY_PATH 以相同的方式指定现有库。
这将指示运行时链接器在查找位于您的 LD_LIBRARY_PATH 中的对象之前在您的对象中搜索所需的符号。
顺便说一句,如果您没有指定一个或多个 LD_PRELOAD 对象,您可以将调用放入您的对象中,然后调用将被调用的函数。这就是为什么有时将其称为插入。
这就是内存分配分析工具的工作量。它们插入 malloc() 和 free() 的版本,记录对 alloc() 和 free() 的调用,然后调用实际的系统 alloc 和 free 函数来执行内存管理。
互联网上有很多关于使用 LD_PRELOAD 的教程。最原始的和最好的之一仍然是“Building library interposers for fun and profit”。虽然是 9 年前为 Solaris 编写的,但它仍然是一个极好的资源。
HTH,祝你好运。
【讨论】:
完全未经测试的想法:
# mv existinglib.so existinglib-real.so
# ld -o exlistinglib.so -shared newfuncs.o -lexistinglib-real
当加载预期加载existinglib.so 的程序时,动态链接器将找到您的版本,并加载它所依赖的existinglib-real.so。它并没有完全达到您问题的既定目标,但看起来好像它对加载库的程序有作用。
【讨论】:
共享库不是档案,它们实际上更像是可执行文件。因此,您不能像 .a 静态库那样将额外的内容塞入其中。
【讨论】:
简答:正是你所要求的无法完成。
更长的答案:根据为什么您要这样做,以及 existinglib.so 的确切链接方式,您可能会接近所需的行为。除了已经提到的LD_PRELOAD 和重命名existinglib.so,您还可以使用链接描述文件(cat /lib/libc.so 了解我的意思)。
【讨论】: