2010-07-29 67 views
6

我有一個Linux共享庫,foo.so,它是從使用dlopen("foo.so", RTLD_NOW | RTLD_LOCAL)可執行加載。從foo.so開始,我想將另一個庫bar.so放到另一個庫中,它引用了foo.so中定義的符號,但鏈接程序未能找到它們。我無法將RTLD_LOCAL更改爲RTLD_GLOBAL,因爲我沒有執行加載的可執行文件的源代碼。我認爲-Wl,--export-dynamic當鏈接foo.so可能會幫助,但它不會覆蓋本地標誌爲dlopen。 GCC的新屬性可見性功能看起來並不像它提供的答案。dlopen的具有兩個共享庫,導出符號

有沒有一種方法可以指示鏈接器將bar.so中未定義符號的引用解析爲foo.so中的那些定義,而不使用鏈接欄與-lfoo或相似性將符號移動到第3個庫中並將這兩個foo並阻止它呢?這發生在我的唯一的事情是從內部foo.so本身,然後使用dlopen bar.so與RTLD_GLOBAL到dlopen的foo.so,但在我看來是一個有點亂。謝謝。

回答

4

鏈接foo.sobar.so

當可執行文件dlopen() s foo.so,bar.so也將被加載。

或者,可執行文件的二進制補丁將RTLD_GLOBAL添加到針對dlopen()調用的標誌中。該代碼將看起來像它

movl $2, 4(%esp)  # $2 == RTLD_NOW; RTLD_LOCAL is 0 
    movl $0xNNNNN, (%esp) # $0xNNNNN == &"foo.so" 
    call dlopen 

補丁來代替movl $0x102, 4(%esp)RTLD_GLOBAL == 0x100),就萬事大吉了。

編輯:
如果你知道bar.so的名字,那麼你可以鏈接foo.so反對「存根」 bar.so。沒有關係,你沒有「真正的」bar.so;重要的是foo.so對它有依賴性。在運行時,這種依賴會導致bar.so每當foo.so加載到被加載。

+0

感謝您的答覆。我無法將foo.so與bar.so鏈接,因爲bar.so將是用戶提供的插件。我也無法修補的可執行文件,因爲這通常會是超級用戶擁有的客戶的系統上,我不知道修補它會下去太清楚他們,它確實複雜安裝過程頗有幾分。它也會打破執行官開放的其他圖書館,其中一些依賴於RTLD_LOCAL。我想我必須跟着dlopen foo.so從本身入手,這似乎很有效。乾杯 – 2010-07-31 12:10:41

相關問題