2012-07-21 64 views
9

我正在使用C++中的裸機cortex-M3來獲得樂趣和利潤。如何調試鏈接過程 - GCC/ld - STL C++

最近我決定嘗試使用STL庫,因爲我需要一些容器。 我認爲通過簡單地提供我的分配器,它不會向 最終二進制文件添加太多的代碼,因爲您只能得到您使用的內容。 我實際上甚至沒有期望STL (給出我的分配器)的任何鏈接過程,因爲我認爲它是全部模板代碼。

我正在用-fno-exception進行編譯。

不幸的是,我的二進制文件中增加了約600KB或更多。我用nm查找包含在最終二進制文件中的什麼符號 ,這對我來說似乎是個玩笑。名單很長 我不會試着去過去。雖然有一些微弱的符號。

我也看了在鏈接器生成的.map文件,我甚至發現scanf函數符號

.text   0x000158bc  0x30 /CodeSourcery/Sourcery_CodeBench_Lite_for_ARM_GNU_Linux/bin/../arm-none-linux-gnueabi/libc/usr/lib/libc.a(sscanf.o)¶ 
      0x000158bc    __sscanf¶ 
      0x000158bc    sscanf¶ 
      0x000158bc    _IO_sscanf¶ 


$ arm-none-linux-gnueabi-nm binary | grep scanf 
000158bc T _IO_sscanf 
0003e5f4 T _IO_vfscanf 
0003e5f4 T _IO_vfscanf_internal 
000164a8 T _IO_vsscanf 
00046814 T ___vfscanf 
000158bc T __sscanf 
00046814 T __vfscanf 
000164a8 W __vsscanf 
000158bc T sscanf 
00046814 W vfscanf 
000164a8 W vsscanf 

如何調試呢?首先,我想了解GCC正在使用什麼來鏈接(我通過GCC鏈接)。我知道如果在文本段中找到符號,則使用整個段,但仍然太多。

任何有關如何解決這個問題的建議真的很感謝。

感謝, S.

回答

3

使用GCC的-v-Wl,-v選項將顯示正在使用的鏈接器命令(和鏈接器的版本信息)。

您使用的是哪個版本的GCC?我對GCC 4.6進行了一些更改(請參閱PR 44647PR 43863)以減少代碼大小以幫助嵌入式系統。還有一個出色的增強請求(PR 43852)允許禁止包含您看到的IO符號 - 其中一些來自詳細終止處理程序,當進程以活動異常終止時,它會輸出消息。如果你不使用執行選項,那麼一些代碼對你來說就沒用了。

+0

我使用Code Sourcery的gcc版本4.6.3。 -Wl,-v選項非常有用。除了我傳遞給鏈接的標誌,它也包含以下 -lstdC++ -lm --start組-lgcc -lgcc_eh -lc --end組 現在我明白爲什麼,以及如何刪除它們。特別是我認爲gcc_eh代表異常處理。任何建議或閱讀關於此? – emitrax 2012-07-22 08:29:08

+0

如果你用'gcc',而不是'G ++鏈接'那麼它不會通過-lstdc''++的鏈接,而且還可能消除對'-lgcc -lgcc_eh'需要(我不記得的副手,我倒是要檢查),但如果不從這些庫使用任何代碼,那麼它不應該增加可執行文件的大小無論如何 - 冗長終止處理程序中的libstdC++可能是不需要的代碼 – 2012-07-22 11:31:30

+0

什麼拉如果我用gcc它贏得找不到_List_node_base :: _ M_hook符號。通過-lstdC++包含其他所有內容。 爲了縮小這個問題,我試着直接連接ld,然後逐個添加這些標誌。它缺少的libstdC++ __aeabi_unwind_cpp_pr0一(list.o):(..._ List_node_base7_M_hookE) 然後指向libc,就是(memcpy和其他),然後鏈接一切。這是一個大型連鎖店和PITA。我只是想要一個容器。 :-) 我也認爲,因爲我有一個全局對象,它需要__static_initialization_and_destruction_0,我沒有想到。謝謝你的幫助。 – emitrax 2012-07-22 12:21:59

2

的問題不是關於STL,它是關於標準庫。

的STL本身是(在某種程度上),但標準庫還包括所有這些流包,似乎還設法在libc以及拉...

問題是標準庫從來沒有打算分開,所以可能沒有太多的關注重新使用從C標準庫的東西...

你應該首先嚐試確定哪些文件被拉入當你編譯(使用stracefor example),這樣你可以驗證你只使用標頭專用文件。

然後,您可以嘗試刪除發生的鏈接。有一些選項可以傳遞給gcc,以確保你想要一個標準庫免費版本,比如--nostdlib,但是我不太瞭解那些在這裏完全指導你的東西。

+0

我已經傳遞到-nostdlib編譯器,用-fno-例外一起,但它似乎沒有工作。 – emitrax 2012-07-22 08:35:00