2011-12-14 85 views
3

假設我正在用GCC編譯一個簡單的Hello World程序。鏈接器如何知道哪些檔案鏈接在一起?

gcc -v hello-world.c運行,我們可以得到從產生ELF二進制輸出的最後一行:

/usr/libexec/gcc/x86_64-pc-linux-gnu/4.5.3/collect2 --eh-frame-hdr -m 
elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/../../../../lib64/crt1.o 
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/../../../../lib64/crti.o 
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/crtbegin.o 
-L/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3 -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/../../../../x86_64-pc-linux-gnu/lib 
-L/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/../../.. /tmp/ccRykv97.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/crtend.o /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/../../../../lib64/crtn.o 

從這個輸出我們可以看到,像crtbegin.ocrtend.o一些物體被連接在一起。但是,鏈接器如何知道這些文件應該鏈接到實體?

一個單獨但相似的問題是,如果我不想使用標準C庫,當給定一個包含這些函數定義的目標文件的目錄時,如何知道需要傳遞的文件鏈接器,以便它不會抱怨未知的符號?

回答

3

,我們可以得到從輸出的最後一行生成的ELF二進制

其實是不實際的命令生成的ELF程序。 collect依次調用ld命令生成二進制文件。

如何鏈接知道這些文件應與

事實並非如此。 GCC 告訴它(通過在命令行上提供它們)。

GCC有一個彙編的specs文件,它是一個特定領域的語言小程序,它告訴GCC它應該提供給鏈接器的參數。您可以使用gcc -dumpspecs檢查內置specs。您會看到該程序實際上非常複雜,並且crtbegin.o僅在-static-pie-shared不適用時纔會使用。 -shared意味着crtbeginS.o,而-static意味着crtbeginT.o

如果我不希望使用標準C庫

使用-nostdlib標誌在這種情況下。

考慮到包含這些功能的定義,對象文件的目錄,如何知道所需要的文件傳遞給鏈接器

定義您所使用的功能的人。 This可能會有所幫助。