2009-11-26 51 views
3

任何人都可以請建議一些方法,我們可以限制我們的符號導出到全局符號表嗎?將符號限制爲可執行的本地範圍

在此先感謝


嗨,

感謝回答...

其實我有一個靜態鏈接到第三方庫可執行說「ver1.a」並且還使用第三方「.so」文件,該文件再次與相同的庫鏈接,但不同的版本稱爲「ver2.a」。問題是執行這兩個版本是不同的。一開始,當加載可執行文件時,來自「ver1.a」的符號將被導出到全局符號表。現在無論何時加載「.so」,它都會嘗試引用ver2.a中的符號,它最終會引用先前加載的「ver1.a」中的符號,從而導致我們的二進制文件崩潰。

我們想到了一種解決方案,我們不會將可執行符號導出爲全局符號表,因此當「.so」被加載並嘗試使用來自ver2.a的符號時,它不會在全局符號表中找到它,並且它將使用自己的符號,即從ver2.a的符號

我無法找到任何方式,我可以限制符號導出到全局符號表。我試着用--version-script和retain-symbol-file,但它沒有用。對於-fvisibility = hidden選項,它提供了一個錯誤,「-f選項只能與-shared一起使用」。所以我想,這也像「 - 版本腳本」只適用於共享庫而不是可執行的二進制文件。

代碼在C++,OS-Linux,gcc version-3.2中。可能無法重新編譯任何第三方庫和「.so」。因此,重新編譯與bsymbolic標誌「,所以」文件的選項被排除在外。

任何幫助,將不勝感激。

+1

您至少可以告訴我們該應用程序以哪種語言編寫? –

回答

2

拉第三方庫使用dlopen。

您可能能夠避免由創建你自己的共享庫,隱藏所有的第三方符號,只暴露你自己的API,但如果所有其他都失敗了,dlopen會給你完全的控制權

0

最簡單的解決方案是重命名符號(通過改變源代碼)在您的可執行文件中,以便它們不會與共享庫發生衝突

下一個最簡單的事情就是用'objcopy -L problem_symbol'本地化「問題」符號。

最後,如果你不與第三方庫直接鏈接(dlopen的,但它不是,因爲bmargulies建議),您沒有任何其他的共享庫的使用定義的「問題」的符號,你不要鏈接-rdynamic或者它的一個等價物,那麼這個符號不應該被導出到可執行文件的動態符號表中,因此你不應該有衝突。

注意:'nm a.out'仍然,顯示符號爲全局定義,但這對動態鏈接無關緊要。您想查看動態符號表a.out'nm -D a.out'

1

我有什麼聽起來像,類似的問題/問題:Segfault on C++ Plugin Library with Duplicate Symbols

如果你可以重建第三方庫,你可以嘗試添加鏈接器標誌-Bsymbolic(旗GCC/G ++是-Wl,-Bsymbolic) 。這可能會解決您的問題。這一切都取決於你的代碼和東西的組織,因爲有警告使用它:
http://www.technovelty.org/code/c/bsymbolic.html
http://software.intel.com/en-us/articles/performance-tools-for-software-developers-bsymbolic-can-cause-dangerous-side-effects/

如果不能重建它,根據第一警告鏈接:

實際上,在構建共享 庫時,-Bsymbolic 標誌唯一執行的操作是在名爲 DT_SYMBOLIC的二進制文件的動態 部分中添加一個標誌。

所以也許有辦法將DT_SYMBOLIC標誌添加到動態節後鏈接?