2012-07-04 36 views
39

我有c++filt命令來去掉符號,什麼是做相反的工具和破壞符號名稱?什麼是Linux實用程序來修改C++符號名稱?

如果我想要調用dlsym()上一個錯位的C++函數名稱,這將會很有用。我寧願不要在代碼中硬編碼名稱,因爲隨着時間的推移,由於新的編譯器版本或新的編譯器品牌被使用,或者由於編譯多個平臺,目前它可能會改變。

是否有一種編程方式來獲取代表C++函數在運行時的字符串,以便代碼獨立於編譯器?一種可能的方法是在編譯時調用一個實用程序,爲正在使用的編譯器執行名稱修改,並將適當的錯位C++符號名稱插入到要使用的dlsym()的字符串中。

Here is the closest to a solution I've found on this site這是通過使用一個固定的C樣式名稱間接到你想dlsym()庫中定義的C++符號來完成,但如果你沒有過什麼庫提供的控制,這是不是一種選擇。

+13

每個人都使用C++編譯器來壓縮名稱。 –

+2

呃,編譯器呢? –

+1

-1,編譯器是你需要的唯一東西......這是相當明顯的答案。 – Griwes

回答

3

您可以得到你想要的東西通過看。所以符號表 你正在看:其他人已經回答了這個問題 Returning a shared library symbol table

但是,如果有太多的符號...可能無法正常工作。
所以這裏有一個瘋狂的想法。買者自負!

一個潛在的解決方案是:

  1. 創建存根文件恰好與一個名字:你想要的名稱:無效myfunction的(){}

  2. 編譯文件( - fpic和-shared所以這是對特定文件的動態庫)

  3. 呼叫的dlopen/dlsym進行

  4. 迭代救援人員到場呃符號(應該只有一個想要加上其他常規垃圾,你可以過濾)。通過符號迭代是笨拙,但你可以做到這一點:你想使用dlopen

  5. Returning a shared library symbol table

  6. dlclose()來釋放它(失去存根你的符號)

  7. 打開文件

基本上,你想從你的代碼中調用編譯器,它會創建一個 你可以看看。所以在,得到的唯一值出來,然後卸載該的.so ,所以你可以在你想要的加載。

這很瘋狂。

3

名稱修改是特定於實現的。

有沒有標準的名稱修改,所以你最好的選擇是找到一個編譯器來爲你做。

Name mangling

有一個表在這裏,可以幫助你,如果你想這樣做手工

5

這就是g ++如何命名的。你可以在你的程序中實現這些修改規則。

另一個(瘋狂的)解決方案是列出要使用的庫中的所有符號(如果您瞭解格式,則不會那麼困難),將它們全部取消並在列表中搜索函數的名稱。這種方法的優點是demangling更容易,因爲有一個函數調用來執行它:abi::__cxa_demangle,來自cxxabi.h頭文件。

+0

斷開的鏈接!我發現這個參考:http://refspecs.linuxbase.org/cxxabi-1.83.html#mangling – fonini

0

比首先發布的更簡單的方法。 寫一個小C++程序,如:

#include <stdlib.h> 

extern int doit(const char *toto, bool is); 

int main(int argc, char *argv[]) 
{ 
    exit(doit (argv[0], true)); 
} 

# g++ -S test.cpp 

建立它,而且從彙編源中提取符號名

# cat test.s | grep call | grep doit | awk '{print $2}' 

你得到:

[email protected]:/tmp/TestC++$ cat test.s | grep call | grep doit | awk '{print $2}' 
_Z4doitPKcb 
[email protected]:/tmp/TestC++$ 

doit損壞的符號是_Z4doitPKcb 使用您計劃使用的編譯器,因爲每個編譯器都有自己的名稱修改規則(正如之前所說的,從一個編譯器到另一個編譯器可能會更改這些規則)。

玩得開心!

+0

因爲compliers可能會有所不同,所以問題是在運行時要求一種方式來動態計算它。 – WilliamKF