簡體   English   中英

gcc `-shared` 選項如何影響輸出?

[英]How does gcc `-shared` option affect the output?

從技術上講,就文件內容而言, gcc -fPIC -shared src.cgcc -fPIC src.c的輸出有什么區別?

假設在src.c定義了int main(int, char**)以便兩個編譯都成功。 但是按預期執行由gcc -shared src.c生成的a.out會出現以下錯誤:

-bash: ./a_shared.out: cannot execute binary file

就算有一個main函數吧。

另外,如何使用otoolobjdump等工具檢查輸出文件中的差異?

非常感謝。

共享庫和可執行文件使用相同的格式:它們都是可加載的圖像。 然而,

  1. 共享庫通常與位置無關,可執行文件通常不是。 這會影響代碼生成:對於位置無關,您必須使用相對地址加載全局變量或跳轉到函數。

  2. 可執行文件有一個“入口點”,它是執行開始的地方。 這通常不是main() ,因為main()是一個函數,函數返回,但執行永遠不應該從入口點返回。

現在,這並沒有回答關於-shared做什么的問題。 您可以使用-v標志詢問 GCC。 以下是我的系統上不帶和帶-shared的調用之間的差異。

參數collect2-shared

-dynamic-linker
/lib64/ld-linux-x86-64.so.2
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crt1.o
/usr/lib/gcc/x86_64-linux-gnu/4.7/crtbegin.o
/usr/lib/gcc/x86_64-linux-gnu/4.7/crtend.o

對於參數collect2-shared

-shared
/usr/lib/gcc/x86_64-linux-gnu/4.7/crtbeginS.o
/usr/lib/gcc/x86_64-linux-gnu/4.7/crtendS.o

觀察

看起來代碼生成不受影響:您仍然必須使用-fpic-fPIC

您可以看到crt1.o (“C 運行時”)僅在鏈接可執行文件時包含在內。 使用nm ,我們可以找出它包含的內容:

$ nm /usr/lib/x86_64-linux-gnu/crt1.o
0000000000000000 R _IO_stdin_used
0000000000000000 D __data_start
                 U __libc_csu_fini
                 U __libc_csu_init
                 U __libc_start_main
0000000000000000 T _start
0000000000000000 W data_start
                 U main

所以你可以看到它似乎定義了一些與stdin以及_start (它是入口點)有關的東西,並且它有一個對main的未定義引用。

我不確定其余的文件是什么,但至少您知道如何找到它們,並且可以隨意瀏覽,或者如果您願意,可以查看源代碼。

根據https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html#Link-Options -shared選項執行以下操作

  • 生成一個共享對象,然后可以將其與其他對象鏈接以形成可執行文件。

  • 並非所有系統都支持此選項。

  • 對於可預測的結果,您還必須在指定此鏈接器選項時指定用於編譯的相同選項集(-fpic、-fPIC 或模型子選項)。

按照-shared和輪候冊的區別,-shared的GCC選項傳遞到-shared GCC可以啟用或鏈接時禁止其他標志。

根據我的理解,如果可執行文件具有共享庫,則可執行文件的大小非常小 在共享庫存在並正確鏈接之前,可執行文件不會運行。 使用共享庫的好處是如果我們有一個非常大的代碼庫,我們不需要每次都構建整個代碼 我們只需要重建 .so 文件並將其鏈接到可執行文件。 節省了大量時間

對於沒有共享庫的可執行文件,可執行文件的大小將非常大 對於每次代碼更改,都需要構建完整的代碼,這可能非常耗時

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM