2017-01-20 54 views
0

假設我有三個庫:libMissingSymbol.so,libMiddle.so和libSymbolHaver.so。 libMissingSymbol包含一個在libSymbolHaver中定義的符號,但只依賴於libMiddle。 libMiddle應該對libSymbolHaver有一個依賴關係,但它沒有。我沒有這些庫的源代碼或未鏈接的對象文件。我可以將libMiddle與libSymbolHaver鏈接起來,以便libMissingSymbol可以在加載時找到它需要的符號嗎?有沒有什麼方法可以僅使用這三個共享對象文件和任何必要的工具來解決此問題?我必須得到具有相同內容的庫(包括SONAME),禁止依賴項更改爲libMiddle,以便不會在我的項目中進一步細分。將依賴關係添加到現有的共享對象庫中

假設readelf輸出(修剪相關性)澄清:

$ readelf -s libMissingSymbol.so 
123: 00000000  0 OBJECT GLOBAL DEFAULT UND MangledSymbol 

$ readelf -d libMissingSymbol.so 
Dynamic section at offset 0x42434 contains 37 entries: 
    Tag  Type       Name/Value 
0x00000001 (NEEDED)      Shared library: [libMiddle.so] 
0x0000000e (SONAME)      Library soname: [libMissingSymbol.so] 

$ readelf -d libMiddle.so 
Dynamic section at offset 0x75b28 contains 29 entries: 
    Tag  Type       Name/Value 
0x0000000e (SONAME)      Library soname: [libMiddle.so] 

$ readelf -s libSymbolHaver.so 
    35: 00064d0c  4 OBJECT GLOBAL DEFAULT 22 MangledSymbol 

回答

1

是否有可能對我來說,libMiddle與libSymbolHaver鏈接,這樣libMissingSymbol可以找到它需要在加載時的符號?

號:所有UNIX接頭,除了AIX之一,考慮.so最終鏈接產品並沒有進一步的修改是可能的。

更新:

這個做不同的方式(例如反編譯libMiddle並以正確的依賴重建它)的可行性?

我不相信這是可行的兩種 - 這是真的很難修改完全鏈接ELF文件,並沒有違反內部一致性約束萬千。

我建議採用以下方法,這很可能只是工作(TM)。

  1. 放棄你的「只使用這三個庫」的限制。這似乎是人爲的和不必要的。

  2. 複製libMiddle.so - >libZiddle.so(如果出現問題,請務必在其他地方複印原始的libMiddle.so)。

  3. binary-patch SONAME in libZiddle.so以匹配新名稱。字符串"libMiddle.so"位於庫的.dynstr部分,並且(我相信)不以任何方式進行散列,因此更改其中的一個字母不會在新庫中引入任何自相矛盾的情況。

    一旦你做到了這一點,比較readelf -a libMiddle.soreadelf -a libZiddle.so,則SONAME應該是唯一差異。

  4. 刪除libMiddle.so

  5. 鏈接含有some_unused_function()具有上兩個libZiddle.solibSymbolHaver.so動態依賴性的新libMiddle.so

現在,目前鏈接對libMiddle.so和失敗,丟失的符號任何二進制(如libMissingSymbol.so)將找到新的(空)libMiddle.so,但由於新libMiddle.so既需要libZiddle.so(其中大多數符號是)libSymbolHaver.so,它應該只是工作。

+0

感謝您的回答。你有沒有關於以不同方式做這件事的可行性的洞察(例如反編譯libMiddle並用正確的依賴重建它)? –

+0

@ThomasDeSilva我已經更新了答案。 –

+0

Re:點#1,我有約束,因爲所有這一切的目的是模擬一個我無法控制的不同執行環境(我在一個更具體的論壇[這裏]有一個更詳細的帖子(https: //www.chiefdelphi.com/forums/showthread.php?t=153697)如果你在意細節)。然而,您的修改讓我再次檢查了我的情況,並發現了真正的問題:我的庫中存在版本偏差。我不必嘗試你的方法,但我接受你的答案;再次感謝您的幫助。 –