Linux下ELF可執行檔案裝載與執行

2021-06-29 01:14:49 字數 2203 閱讀 7605

1、建立子程序

核心建立task_struct資料結構,繼承父程序的虛擬位址空間(virtual memory space,vms)。

2、呼叫execve()系統呼叫執行指定的elf檔案

(1)呼叫核心態函式sys_execve(),動態申請乙個linux_binprm資料結構,並用elf可執行檔案的資料填充這個結構;

(2)呼叫prepare_binprm()函式用位於inode中的資料填充linux_binprm資料結構;

(3)呼叫search_binary_handler()函式遍歷formats鍊錶依次應用其load_binary的方法。對於elf檔案會找到elf_format節點,呼叫load_elf_binary()函式進行如下工作:

1)檢查存放在檔案前128位元組中的魔數以確認可執行格式及其有效性;

2) 讀取可執行檔案的首部;

3)從可執行檔案的.interp段獲得動態鏈結器(dynamic linker,dl)的路徑名;

4)將dl的前128位元組copy到緩衝區;

5)對dl型別進行一致性檢查;

6)呼叫flush_old_exec()函式釋放前一次計算占用的幾乎所有資源(應該是從父程序繼承過來的);

7)呼叫setup_new_exec()函式,進行為新的程序建立程序線性區布局

等工作;

8)呼叫setup_arg_pages()函式為程序的使用者態棧分配乙個新的線性區描述符,並把那個線性區插入到程序的位址空間。

setup_arg_pages()函式還把命令列引數和環境變數串所在的頁框分配給新的線性區。

9)建立新的線性區對映elf中的各個load段,包括**段和資料段;

線性區中的虛擬位址(virtual memory address, vma)與elf中的載入位址(load

memory address, lma

)正常情況下是一樣的,但在有些嵌入式系統中是不一樣的。vma與elf中的大多數段(這些段在對映到vma時都需要建立vma到檔案的對映關係)都是完全對應的,但有一些特殊的段(如.bss)不需要對映到檔案,它們與vma中的位址並不是完全對應的。在對應的段中,其位址與vms中的位址完全一致。鏈結器會負責將各個許可權相同的段合併到一起,以減少裝載並進行頁對映時產生的記憶體浪費。

10)呼叫load_elf_interp()函式裝載dl;

11)呼叫start_thread()函式修改儲存在核心態堆疊但屬於使用者態暫存器的eip和esp的值,以使它們分別指向dl的入口(如果沒有獲得dl則指向elf的入口)和新的使用者態棧的棧頂;

12)返回0值(成功)。

3、execve()系統呼叫返回後,新的程式會從eip暫存器指向的位址開始執行。如果elf沒有鏈結動態庫,則開始執行elf檔案的**;如果elf鏈結了動態庫,則執行動態鏈結;

(1)啟動動態鏈結器本身;

(2)裝載所有需要的共享物件;

依次找到所有共享物件的名字、位置,開啟相應的檔案,將其**段和資料段對映到程序的位址空間中。可執行檔案與動態庫的對映都是通過記憶體對映完成的。在對映時核心為程序建立乙個vm_area_struct資料結構,將其與檔案的資料結構關聯起來。記憶體對映之後核心並沒有立即分配頁框給它,當程序試圖訪問對映的頁時會產生乙個缺頁異常。核心會檢查請求頁是否在快取記憶體中,如果不在則分配乙個新的頁框,把它追加到快取記憶體,並安排乙個i/o操作從磁碟讀入該頁內容;如果請求頁在快取記憶體中,則將頁框與vm_area_struct關聯,並將頁框的引用計數加1。這樣多個使用同一動態庫的程序就能共享動態庫中的唯讀的**段(通過pic(位置無關**)技術可以增加很多能共享的唯讀**),從而實現節約記憶體的目的。而動態庫中的資料段會被對映為私有的,當程序想要寫入資料時,核心會把相應的頁複製,並在程序頁表中用複製的頁替換原來的頁(即寫時複製)。雖然原來的頁框仍然在快取記憶體中,但已經不屬於這個記憶體對映,複製的頁頁不會被插入到頁快取記憶體中,這樣就實現的程序資料的私有。

(3)重定位和初始化。

4、動態鏈結器將程序的控制權交給程式並從其入口並開始執行。

linux核心在編譯時先用64位elf對應的elf_phdr結構體編譯load_elf_binary()相關**,如果核心開啟劉32bit compat編譯選項,則再用32位elf對應的elf_phdr結構體編譯load_elf_binary()相關**,生成乙個compat相關的模組;當執行32位elf檔案時核心會呼叫compat相關的**裝載32位elf。並通過set_personality巨集將程序的執行域設定為32位,從而可以模擬執行32位elf。

注:出於安全考慮,共享庫必須既可讀又可執行。

可執行檔案 ELF 格式

elf executable and linking format 是一種物件檔案的格式,用於定義不同型別的物件檔案 object files 中都放了什麼東西 以及都以什麼樣的格式去放這些東西。它自最早在 system v 系統上出現後,被 unix 世界所廣泛接受,作為預設的二進位制檔案格式來使...

ELF學習 可執行檔案

相比較重定位檔案,可執行檔案的elf header中入口位址是0x8048320.而且除了section header外,還存在program header.program header起始於第52個位元組,因此program header應該是緊接著elf header。可執行檔案的elf 布局如...

Linux下檢視可執行檔案 動態庫的ELF頭等資訊

用法 readelf elf file s 作用 和windows下的pe檔案類似,elf檔案是linux系統下可執行檔案 動態庫檔案 靜態庫檔案的標準格式。有時候我們需要檢視elf檔案的頭資訊,或者動態庫檔案的匯出函式等,這時候readelf命令的作用就來了。例子 查詢elf檔案頭資訊。如下是表明...