Shared libraries 是否可以将库参照添加到现有共享对象?

Shared libraries 是否可以将库参照添加到现有共享对象?,shared-libraries,unix,elf,dynamic-linking,Shared Libraries,Unix,Elf,Dynamic Linking,我有一个系统“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 =>

我有一个系统“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作为输入,并编写一个新的。那么使用额外的库呢

# 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
第一次尝试stackoverflow时,对我放轻松:)

不容易

大多数<代码> UNIX < /C>系统(<代码> AIX是一个显著的例外)考虑<代码> *.So < /Cord>一个“最终”链接产品,它不适合作为任何其他链接的输入。

要向
fsimage.so
的动态部分添加新的DT_-NEEDED标记,您需要重写其
.dynamic
部分。从
.dynamic
中删除一个条目相对容易——您只需“滑动”其他条目,然后将最后一个条目替换为
DT_NULL

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

有现成的工具可以做到这一点,例如,但我的成功与否参差不齐。

谢谢你的“雇佣俄罗斯人”,你给了我深入搜索所需的信息。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.9版自2016年2月29日发布,您可以:

  • 更改可执行文件的动态加载程序(“ELF解释器”)
  • 更改可执行文件和库的RPATH
  • 收缩可执行文件和库的RPATH
  • 删除动态库上声明的依赖项(需要DT_ 参赛作品)
  • 在动态库上添加声明的依赖项(需要DT_)
  • 将动态库上声明的依赖项替换为另一个依赖项(需要DT_)
  • 更改动态库的名称
在您的情况下:


我怀疑是这样的。我知道Solaris将在ELF中留下512字节的空间,因此您可以轻松地添加新的部分,如文本等,但不能(直接/轻松地)扩展DT_所需的部分。仍然是有趣的学习。现在,我可以重新编译我的python并添加我想要的库,但是输入了一个单独的32位对64位的混乱。叹气:)我用运行elfedit,所以我想作为第一个参数进行编辑,第二个参数使用新名称,但什么也没发生。显示帮助。不过我是在Linux上。最新的稳定版本[v0.8][1]只有
——删除所需的库
,而没有添加,可能是因为lundman在接受的版本中所述的原因。然而,[development version in github][2]也有--add library选项,因此这可能是一种方法[1]:[2]:
$ patchelf --add-needed /usr/lib/libgen.so /usr/lib/python2.4/vendor-packages/fsimage.so