(2021) 18 [代码讲解] 可执行文件
(2021) 18 [代碼講解] 可執(zhí)行文件
南京大學(xué)操作系統(tǒng)課蔣炎巖老師網(wǎng)絡(luò)課程筆記。
視頻:https://www.bilibili.com/video/BV1HN41197Ko?p=18
講義:http://jyywiki.cn/OS/2021/slides/C8.slides#/
背景
回顧
程序 = 狀態(tài)機(jī)
- 狀態(tài)機(jī)執(zhí)行 = 狀態(tài)機(jī)上的路徑
- 狀態(tài)機(jī)管理API:
- fork - 復(fù)制
- execve - 重置
- exit - 終止
狀態(tài)機(jī) = 可執(zhí)行文件
一直以來(lái) “最神秘” 的一種文件,雙擊即可打開,這時(shí)為什么?
本次課的內(nèi)容與目標(biāo)
理解靜態(tài)鏈接的可執(zhí)行文件
- 可執(zhí)行文件的加載
- xv6加載器
可執(zhí)行文件的加載
小知識(shí):可執(zhí)行文件 不等同于 ELF文件
考慮腳本文件,它也是可執(zhí)行文件:
#!/bin/bash -x echo Hello #!/usr/bin/env python3 print('Hello') #!./a.out為什么是/usr/bin/env?
-
因?yàn)?#! 需要絕對(duì)路徑 (背后是 execve)
-
Shebang 究竟發(fā)生了什么?
- 不妨 strace 一下!
可以參考筆者的這篇博客:Linux中的二進(jìn)制可執(zhí)行文件和腳本可執(zhí)行文件及Shebang。
進(jìn)程(ELF)初始化
虛假的進(jìn)程(ELF)初始化
execve(path, argc, envp):重置一個(gè)狀態(tài)機(jī),為它傳入?yún)?shù)argv和envp,概念好理解,但究竟什么叫 傳入?
我們知道程序(狀態(tài)機(jī))的狀態(tài)無(wú)非就是保存在寄存器或者內(nèi)存中(M,G),傳入?yún)?shù)肯定是傳到了內(nèi)存的某個(gè)地方,但究竟是哪里呢?
一定要能靜下心來(lái)讀手冊(cè),多嘗試去靜下心來(lái)去手冊(cè),很快就能適應(yīng)它了。 RTFM
-
[System V ABI (x86-64)][http://jyywiki.cn/pages/OS/manuals/sysv-abi.pdf]
Section 3.4: Process Initialization
- 之前用 gdb 調(diào)試過(guò) “初始狀態(tài)”
- 看到了寄存器的初始值
- 手冊(cè)完整規(guī)定了 execve 后的進(jìn)程狀態(tài)
- libc 會(huì)使用它
- 根據(jù) ABI,你可以開發(fā)自己的 libc !
- libc 會(huì)使用它
- 之前用 gdb 調(diào)試過(guò) “初始狀態(tài)”
-
Gitlab repo
挑戰(zhàn):不使用 execve 加載 ELF
理論上把可執(zhí)行文件 (ELF) 指定的數(shù)據(jù)搬運(yùn)到內(nèi)存,就可以實(shí)現(xiàn)二進(jìn)制文件的加載。
試一試?loader.zip: 加載靜態(tài)鏈接的 ELF (glibc)
execve 本質(zhì)上是 “多余” 的,只要我們能按照手冊(cè),把可執(zhí)行文件中的內(nèi)容正確地搬運(yùn)到內(nèi)存中,就可以替換掉execve。
- 可以用 mmap/munmap + 一小段 trampoline code 實(shí)現(xiàn)
- 這個(gè)系統(tǒng)調(diào)用可以被庫(kù)函數(shù) (和其他系統(tǒng)調(diào)用) “模擬”
模擬系統(tǒng)調(diào)用(1):互相模擬,互相傷害
既然完全可以 “自己加載” 可執(zhí)行文件。我們也可以在一個(gè)操作系統(tǒng)里實(shí)現(xiàn)另一個(gè)操作系統(tǒng)的 API 啊,只要能夠在本系統(tǒng)內(nèi)模擬另一個(gè)系統(tǒng)的系統(tǒng)調(diào)用就行。指令面前系統(tǒng)平等 (Linux, Windows, …)。
WSL (Windows Subsystem for Linux)
- Windows 執(zhí)行 ELF64; 在 Windows 中實(shí)現(xiàn) Linux 系統(tǒng)調(diào)用
Wine (POSIX Subsystem for Windows 😂)
- 支持 Windows PE (Portable Executable) 格式
- 實(shí)現(xiàn) Windows API (Overview)
模擬系統(tǒng)調(diào)用(2):把系統(tǒng)調(diào)用挪到用戶空間
操作系統(tǒng)可以只提供一組最基本的硬件層的抽象(如mmap)。其他的全都交給應(yīng)用程序。
“微內(nèi)核” (Microkernel)
- 操作系統(tǒng)只提供非常有限的 API 和權(quán)限管理
- 進(jìn)程/線程創(chuàng)建和通信
- 內(nèi)存映射
- 設(shè)備寄存器
- 其他都實(shí)現(xiàn)在用戶程序
- 例如內(nèi)核里沒(méi)有文件系統(tǒng)
- 想打開文件?發(fā)消息給服務(wù)器吧
“外核” (Exokernel)
- 操作系統(tǒng) = 庫(kù)函數(shù)
- 一個(gè)硬件上可以跑多個(gè) libOS
灌雞湯:《操作系統(tǒng)》這門課究竟學(xué)什么?
相比知識(shí)點(diǎn)本身,獲得知識(shí)的方法和對(duì)系統(tǒng)的掌控力更重要。
本課程想要帶給大家的:
狀態(tài)機(jī)視角
- 程序 = 狀態(tài)機(jī)
- 操作系統(tǒng) = 狀態(tài)機(jī)的虛擬化
機(jī)器永遠(yuǎn)是對(duì)的
- 只要按照 spec 實(shí)現(xiàn),就絕對(duì)能 work
- 地址空間里的每一個(gè)地址都有解釋 (vdso, vvar, …)
- CPU: 指令實(shí)現(xiàn)對(duì)了,仙劍就能跑、操作系統(tǒng)就能跑
- System-V ABI: 實(shí)現(xiàn)對(duì)了,不用 execve 也可以加載可執(zhí)行文件
xv6 加載器
- TODO
總結(jié)
本次課內(nèi)容與目標(biāo)
- 理解靜態(tài)鏈接的可執(zhí)行文件
- 可執(zhí)行文件的加載
- xv6 加載器
Take-away messages
- RTFM; RTFSC
- 紙面上的理解都是片面的
總結(jié)
以上是生活随笔為你收集整理的(2021) 18 [代码讲解] 可执行文件的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: nst股票是什么意思
- 下一篇: uc3842改可调电源教程_明纬开关电源