Linux
_start 是否會呼叫我的程序的主要功能和其他必要的設置功能?
我正在閱讀一本描述載入器如何工作的教科書:
當載入器執行時,它將可執行目標文件的塊複製到程式碼和數據段中。接下來,載入程序跳轉到程序的入口點,該入口點始終是
_start
函式的地址。_start函式呼叫系統啟動函式,__libc_start_main
從這個 Stack Overflow question的答案中,我們有以下關於執行流程的虛擬碼:
_start: call __setup_for_c ; set up C environment call __libc_start_main ; set up standard library call _main ; call your main call __libc_stop_main ; tear down standard library call __teardown_for_c ; tear down C environment jmp __exit ; return to OS
我的問題是:
- 我曾經
objdump
檢查程序的彙編程式碼,我發現_start
只有呼叫__libc_start_main
如下圖所示:其餘的函式如
call __setup_for_c
,_main
等呢?特別是我的程序的主要功能,我看不到它是如何被呼叫的。那麼關於執行流程的虛擬碼是否正確? 2.__libc_start_main
設置標準庫是什麼意思?為什麼需要設置標準庫?載入程序時,該標準庫不是只需要由動態連結器連結嗎?
- 連結答案中描述的其他函式呼叫給出了需要發生的事情的概要;GNU C 庫中的實際實現細節是不同的,要麼使用“建構子”(
_dl_start_user
),要麼顯式地在__libc_start_main
.__libc_start_main
還負責呼叫使用者的main
,這就是為什麼你在反彙編中看不到它被呼叫的原因——但是它的地址被傳遞了(參見lea
剛才的callq
)。__libc_start_main
還負責程序退出,並且永遠不會返回;hlt
這就是緊隨其後的原因,callq
如果函式返回,它將使程序崩潰。- 如今,該庫需要進行大量設置:
- 自己搬遷的一些
- 執行緒本地儲存設置
- pthread 設置
- 析構註冊
- vDSO 設置(在 Linux 上)
- ctype 初始化
- 將程序名稱、參數和環境複製到各種庫變數等等。請參閱 x86-64-specific
sysdeps/x86_64/start.S
和 genericcsu/libc-start.c
、csu/init-first.c
等misc/init-misc.c
。