2010-11-19 33 views
11

我有一個系統「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 

計算器在第一次嘗試,去容易對我:)

回答

10

謝謝「就業俄羅斯」,你給了我更深入的搜索所需的信息。 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

7

不容易。

大多數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

1

您可以使用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

相關問題