我可以向现有的共享对象添加库拒绝?

问题描述:

我有一个系统“fsimage.so”,需要mkdirp,它恰好位于libgen.so中。但是fsimage.so不知道这一点。例如:我可以向现有的共享对象添加库拒绝?

# ldd /usr/lib/python2.4/vendor-packages/fsimage.so 
    libfsimage.so.1.0 =>  /usr/lib/libfsimage.so.1.0 
    libxml2.so.2 => /lib/libxml2.so.2 
    libgcc_s.so.1 =>   /usr/sfw/lib/libgcc_s.so.1 
    libpthread.so.1 =>  /lib/libpthread.so.1 
    libz.so.1 =>  /lib/libz.so.1 
    libm.so.2 =>  /lib/libm.so.2 
    libsocket.so.1 =>  /lib/libsocket.so.1 
    libnsl.so.1 => /lib/libnsl.so.1 
    libc.so.1 =>  /lib/libc.so.1 
    libmp.so.2 => /lib/libmp.so.2 
    libmd.so.1 => /lib/libmd.so.1 

# ./test 
Traceback (most recent call last): 
    File "./test", line 26, in ? 
    import fsimage 
ImportError: ld.so.1: isapython2.4: fatal: relocation error: file /usr/lib/python2.4/vendor-packages/fsimage.so: symbol mkdirp: referenced symbol not found 

# LD_PRELOAD=/usr/lib/libgen.so ./test 
Usage: ./test 

当然,如果我有来源等,我可以简单地再次将其链接,并添加“-lgen”,这将增加libgen.so作为一个依赖。

但作为hackery的练习,比方说我没有任何资源,只是想补充说fsimage.so还需要加载libgen.so。使用elfedit/objcopy等,这是不可能的?我不认为我可以使用“ld”来将.so用作输入,并用额外的库编写一个新的.so文件?

# elfdump /usr/lib/python2.4/vendor-packages/fsimage.so|grep NEEDED 
    [0] NEEDED   0x5187    libfsimage.so.1.0 
    [1] NEEDED   0x5152    libxml2.so.2 
    [2] NEEDED   0x5171    libgcc_s.so.1 

计算器在第一次尝试,去容易对我:)

谢谢“就业俄罗斯”,你给了我更深入的搜索所需的信息。 Solaris已经附带“elfedit”,所以如果其他人想知道,这些是说明

# elfedit libfsimage.so.1.0.0 libfsimage.so.1.0.0-new 
> dyn:value DT_NEEDED 
index tag    value 
    [0] NEEDED   0x4f81    libpthread.so.1 
    [1] NEEDED   0x4fac    libxml2.so.2 
    [2] NEEDED   0x4fc2    libgcc_s.so.1 
> dyn:value -add -s DT_NEEDED libscf.so 
index tag    value 
    [35] NEEDED   0x500d    libscf.so 
> dyn:value DT_NEEDED 
index tag    value 
    [0] NEEDED   0x4f81    libpthread.so.1 
    [1] NEEDED   0x4fac    libxml2.so.2 
    [2] NEEDED   0x4fc2    libgcc_s.so.1 
    [35] NEEDED   0x500d    libscf.so 
> :write 
> :quit 

# ldd libfsimage.so.1.0.0-new 
    libpthread.so.1 =>  /lib/libpthread.so.1 
    libxml2.so.2 => /lib/libxml2.so.2 
    libgcc_s.so.1 =>   /usr/sfw/lib/libgcc_s.so.1 
    libscf.so =>  /lib/libscf.so 
    libz.so.1 =>  /lib/libz.so.1 
    libm.so.2 =>  /lib/libm.so.2 
    libsocket.so.1 =>  /lib/libsocket.so.1 
    libnsl.so.1 => /lib/libnsl.so.1 
    libc.so.1 =>  /lib/libc.so.1 
    libuutil.so.1 =>   /lib/libuutil.so.1 
    libgen.so.1 => /lib/libgen.so.1 
    libnvpair.so.1 =>  /lib/libnvpair.so.1 
    libsmbios.so.1 =>  /usr/lib/libsmbios.so.1 
    libmp.so.2 => /lib/libmp.so.2 
    libmd.so.1 => /lib/libmd.so.1 
+0

我运行elfedit所以我想编辑为第一个参数和第二个新名称,什么也没有发生。显示帮助。尽管我在Linux上。 – kaneda 2014-10-13 19:04:09

不容易。

大多数UNIX系统(AIX是一个值得注意的例外)考虑*.so“最终”链接产品,它不适合作为任何进一步链接的输入。

要将一个新的DT_NEEDED标记添加到fsimage.so的动态部分,您需要重写它的.dynamic部分。从.dynamic中删除条目相对比较简单 - 您只需“滑动”其他条目,然后用DT_NULL替换最后一个条目即可。

另一方面,添加一个新条目需要您将一个全新的.dynamic节添加到文件中,然后更新fsimage.so内的所有指针(偏移量)以指向新节。这需要对ELF格式有“深刻的”理解。

现在有一些工具可以做到这一点,例如, rpath但我已经与它混合成功。

+0

我怀疑这样的。我知道Solaris会在ELF中留下512个字节的空间,因此您可以轻松地添加新的部分,如文本等。但不能(直接/轻松地)扩展DT_NEEDED部分。仍然有趣的学习。现在,我可以重新编译我的Python并添加我想要的库,但进入了一个单独的32位和64位。叹息:) – lundman 2010-11-20 23:33:51

您可以使用PatchELF。版本0。9是出于自2016年2月29日,让你:

  • 变化动态加载程序的可执行文件(“ELF解释”)
  • 更改可执行文件的RPATH和库
  • 收缩了的RPATH可执行文件和库
  • 动态库
  • 删除声明的依赖性(DT_NEEDED 项)
  • 添加上一个动态库声明的依赖性(DT_NEEDED)
  • 用另一块(DT_NEEDED)
  • 动态库

在你的情况变化SONAME一个动态库声明的依赖性:

$ patchelf --add-needed /usr/lib/libgen.so /usr/lib/python2.4/vendor-packages/fsimage.so 
+1

最近的稳定版本[v0.8] [1]只有'--remove-needed LIBRARY'并且没有添加,可能是因为lundman在接受的版本中陈述的原因。然而[github的开发版本] [2]也有--add-library选项,所以这可能是要走的路[1]:https://github.com/NixOS/patchelf/blob/0.8 /src/patchelf.cc [2]:https://github.com/NixOS/patchelf/blob/master/src/patchelf.cc – Davide 2015-10-22 21:46:09