2012-08-29 67 views
6

我正在構建一個構建多個共享庫和可執行文件的項目。所有用於構建這些二進制文件的源文件都位於單個/ src目錄中。因此,找出哪些源文件用於構建每個二進制文件(存在多對多關係)並不明顯。如何找出用於構建二進制文件的* .c和* .h文件?

我的目標是編寫一個腳本來解析每個二進制文件的一組C文件,並確保只從它們調用正確的函數。

一個選項似乎是試圖從Makefile中提取這些信息。但是這對於生成的文件和標題(由於依賴於包含)而不起作用。

另一種方法是簡單瀏覽調用圖,但這會變得複雜,因爲很多函數都是通過函數指針調用的。

還有其他想法嗎?

+1

只是出於好奇:你爲什麼試圖這樣做? – stefan

+0

分發包機制知道所有依賴關係... –

+0

您是否確切地定義了「正確的函數被調用」的含義?這並不明顯,並不簡單。 –

回答

6

您可以先使用調試信息(gcc -g)編譯您的項目並使用objdump來獲取包含哪些源文件。

objdump -W <some_compiled_binary> 

矮人格式應該包含您正在查找的信息。

<0><b>: Abbrev Number: 1 (DW_TAG_compile_unit) 
    < c> DW_AT_producer : (indirect string, offset: 0x5f): GNU C 4.4.3 
    <10> DW_AT_language : 1 (ANSI C) 
    <11> DW_AT_name  : (indirect string, offset: 0x28): test_3.c  
    <15> DW_AT_comp_dir : (indirect string, offset: 0x36): /home/auselen/trials  
    <19> DW_AT_low_pc  : 0x82f0 
    <1d> DW_AT_high_pc  : 0x8408 
    <21> DW_AT_stmt_list : 0x0 

在這個例子中,我編譯從test_3目標文件,並且它位於... /試驗目錄。那麼當然你需要編寫一些腳本來收集相關的源文件名。

2

這是一個想法,需要根據您的具體構建進行細化。進行構建,使用腳本記錄它(例如script log.txt make clean all)。最後(或最後一個)步驟應該是目標文件的鏈接。 (提示:尋找cc -o <your_binary_name>)。該行應鏈接所有.o文件,這些文件應在您的樹中具有相應的.c文件。然後爲所有包含的頭文件grep那些.c文件。

如果您的樹中.c文件中有重複的名稱,那麼我們需要查看鏈接器行中的完整路徑或從Makefile開始工作。

馬哈茂德在下面提出的建議也應該起作用。如果你有一個帶有符號的圖像,strings <debug_image> | grep <full_path_of_src_directory>應該給你一個C文件列表。

+0

好主意。但是我對GCC的Makefiles不熟悉,但是我用VS和VS做的事情不會在很多細節上顯示這一步,它將簡單地列出您鏈接的庫文件。 –

2

首先,您需要從剛剛編譯的二進制文件中分離調試符號。檢查這個問題如何做到這一點: How to generate gcc debug symbol outside the build target?

然後你可以嘗試解析這個文件在你自己的。我知道如何爲Visual Studio做到這一點,但是當您使用GCC時,我無法爲您提供更多幫助。

+0

這也應該工作! – jman

1

您可以使用unix nm工具。它顯示在對象中定義的所有符號。所以,你需要:

  1. 運行nm您的二進制和抓住所有未定義的符號
  2. 運行ldd上的二進制抓住所有動態依賴列表(.so文件來您的二進制文件鏈接)
  3. 每個.so文件運行nm在步驟2中

這會給你的動態符號,你的二進制文件使用的完整列表youf發現。

實施例:

nm -C --dynamic /bin/ls 
....skipping..... 
00000000006186d0 A _edata 
0000000000618c70 A _end 
       U _exit 
0000000000410e34 T _fini 
0000000000401d88 T _init 
       U _obstack_begin 
       U _obstack_newchunk 
       U _setjmp 
       U abort 
       U acl_extended_file 
       U bindtextdomain 
       U calloc 
       U clock_gettime 
       U closedir 
       U dcgettext 
       U dirfd 

凡是具有資本符號 「U」 是由ls命令使用。

1

如果您的目標是分析C源文件,可以通過自定義GCC編譯器來完成。您可以使用MELT(MELT是擴展GCC的高級別領域特定語言) - 添加您自己的GCC-內的MELT編碼分析階段,但您應該首先了解GCC中端內部表示(Gimple,Tree ,...)。

定製GCC需要幾天的工作(主要是因爲GCC內部的細節相當複雜)。

隨意問我更多關於MELT的信息。