ELF文件格式与进程地址空间的联系
http://blog.csdn.net/q_l_s/article/details/52597330
三、分析在fork產生新進程中ELF文件格式與進程地址空間的聯系
1、進程的虛擬地址空間
????每個程序都有自己的虛擬地址空間(Virtual Address Space),大小由硬件平臺(CPU位數)決定。 如32位平臺下每個程序都有4G虛擬空間。但4G空間不是都分配給程序的用戶空間,還有系統的虛擬空間。如Linux系統默認情況下高1G為系統的虛擬地址空間,低3G為用戶空間。 這也就是說每個進程原則上最多可使用3G的虛擬空間。
2、?進程裝載
????覆蓋裝入(Overlay)和頁映射(Paging)是兩種典型的動態裝載方法。現在前者已經不用了。???
????創建一個進程,然后裝載相應的可執行文件并且執行。上述過程最開始只需要做三件事情:
①創建一個獨立的虛擬地址空間。主要是分配一個頁目錄(Page Directory)。
②讀取可執行文件的頭,并且建立虛擬空間和可執行文件的映射關系。主要是把可執行文件映射到虛擬地址空間,即做虛擬頁和物理頁的映射,以便“缺頁”時載入。
③將CPU的指令寄存器設置成可執行文件的入口地址,啟動運行。從ELF文件中的入口地址開始執行程序。
3、過程分析
????在bash下執行一個程序時,Linux是怎樣裝載這個ELF文件并執行的呢?
? ??首先bash調用fork()系統調用創建一個新的進程,然后新的進程調用execve()系統調用執行指定的ELF文件。 bash進程繼續返回等待新進程執行結束,然后重新等待用戶輸入命令。execve()系統調用被定義在unistd.h,它的原型如下:
????int execve(const char *filenarne, char *const argv[], char *const envp[]);
????它的三個參數分別是被執行的程序文件名、執行參數和環境變最。Glibc對execvp()系統調用進行了包裝,提供了execl(), execlp(), execle(), execv()和execvp()等5個不同形式的exec系列API,它們只是在調用的參數形式上有所區別,但最終都會調用到execve()這個系統中。
????調用execve()系統調用之后,再調用內核的入口sys_execve()。 sys_execve()進行一些參數的檢查復制之后,調用do_execve()。 因為可執行文件不止ELF一種,還有Java程序和以“#!”開始的腳本程序等, 所以do_execve()會首先檢查被執行文件,讀取前128個字節,特別是開頭4個字節的魔數,用以判斷可執行文件的格式。 如果是解釋型語言的腳本,前兩個字節“#!"就構成了魔數,系統一旦判斷到這兩個字節,就對后面的字符串進行解析,以確定程序解釋器的路徑。
????當do_execve()讀取了這128個字節的文件頭部之后,然后調用search_binary_handle()去搜索和匹配合適的可執行文件裝載處理過程。Linux中所有被支持的可執行文件格式都有相應的裝載處理過程,search_binary_handle()會通過判斷文件頭部的魔數確定文件的格式,并且調用相應的裝載處理過程。如ELF用load_elf_binary(),a.out用load_aout_binary(),腳本用load_script()。其中ELF裝載過程的主要步驟是:
????①檢查ELF可執行文件格式的有效性,比如魔數、程序頭表中段(Segment)的數量。
????②尋找動態鏈接的”.interp”段(該段保存可執行文件所需要的動態鏈接器的路徑),設置動態鏈接器路徑。
????③根據ELF可執行文件的程序頭表的描述,對ELF文件進行映射,比如代碼、數據、只讀數據。
????④初始化ELF進程環境,比如進程啟動時EDX寄存器的地址應該是DT_FINI的地址(結束代碼地址)。
????⑤將系統調用的返回地址修改成ELF可執行文件的入口點,這個入口點取決于程序的鏈接方式,對于靜態鏈接的ELF可執行文件,這個程序入口就是ELF文件的文件頭中e_enEry所指的地址;對于動態鏈接的ELF可執行文件,程序入口點是動態鏈接器。
????當ELF被load_elf_binary()裝載完成后,函數返回至do_execve()在返回至sys_execve()。在load_elf_binary()中(第5步)系統調用的返回地址已經被改成ELF程序的入口地址了。 所以當sys_execve()系統調用從內核態返回到用戶態時,EIP寄存器直接跳轉到了ELF程序的入口地址,于是新的程序開始執行,ELF可執行文件裝載完成。
總結
以上是生活随笔為你收集整理的ELF文件格式与进程地址空间的联系的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JS实现转动随机数抽奖的特效代码
- 下一篇: jsp页面定义的map