中間跳過了Winods PE/COFF這一節(jié)低斋,以及最后Windows內(nèi)核裝載也會(huì)省略掉俐筋。因?yàn)槲覀冎饕嫦虻腗ac静秆、Linux。這一節(jié)介紹可執(zhí)行文件的裝載與進(jìn)程巡李。
本文導(dǎo)圖
進(jìn)程虛擬地址(操作系統(tǒng)講得比較多)
程序(可執(zhí)行文件)是一個(gè)靜態(tài)的概念抚笔,不知是一些預(yù)先編譯好的指令和數(shù)據(jù)集合的一個(gè)文件;而進(jìn)程是一個(gè)動(dòng)態(tài)的概念侨拦,它是程序運(yùn)行時(shí)的一個(gè)過程殊橙。一個(gè)比方:把程序與進(jìn)程的概念跟廚房做菜比較
- 程序就是菜譜
- CPU就是人
- 廚具就是其他硬件
- 整個(gè)炒菜就是一個(gè)進(jìn)程
計(jì)算機(jī)按此程序指令把數(shù)據(jù)加工成輸出數(shù)據(jù),就像菜譜指導(dǎo)人把原料做成菜肴一樣
每個(gè)程序被運(yùn)行起來以后狱从,它將擁有獨(dú)立的虛擬地址空間膨蛮。從程序角度來講,C語(yǔ)言程序中指針?biāo)加玫目臻g來計(jì)算虛擬地址空間位數(shù)大小季研。一般來將敞葛,C語(yǔ)言指針大小與虛擬空間的位數(shù)相同,如32位平臺(tái)与涡,指針就是32位惹谐,既4字節(jié)。
進(jìn)程只能使用那些操作系統(tǒng)分配給地址空間驼卖,如果訪問了未經(jīng)許可的空間氨肌,那么操作系統(tǒng)就會(huì)捕獲這些訪問,將進(jìn)程這種訪問視為非法訪問款慨,并強(qiáng)制結(jié)束進(jìn)程儒飒。
如32位中,整個(gè)4GB被劃分為兩個(gè)部分檩奠,從地址0xC000 0000到0xFFFF FFFF共1GB桩了。剩下的從0x0000 0000地址到0xBFFF FFFF共3GB空間都是給進(jìn)程用的,其實(shí)這3GB還要減去一些物理設(shè)備的RAM大小埠戳。
PAE
32位CPU最大的尋址能力是0到4GB井誉;Intel1995年就開始采用36位的物理地址,也就是可以訪問64GB的物理內(nèi)存整胃,并且修改了頁(yè)映射方式颗圣,使得新的映射方式可以訪問到更多的物理內(nèi)存,這種地址擴(kuò)展方式叫做PAE(Physical Address Extensio)屁使。
雖然擴(kuò)展了物理地址空間在岂,但是對(duì)于普通的應(yīng)用程序而言感覺不到它的存在,因?yàn)椴僮飨到y(tǒng)會(huì)處理好映射關(guān)系蛮寂。操作系統(tǒng)提供一個(gè)窗口映射的方法蔽午,把額外的內(nèi)存映射到進(jìn)程地址空間中來。
裝載方式
靜態(tài)裝載酬蹋,也就是把程序所有的數(shù)據(jù)和指令裝載到內(nèi)存中及老。但是很浪費(fèi)資源抽莱。因?yàn)槌绦蜻\(yùn)行有局部性原理,可以吧最常用的部分駐留在內(nèi)存中骄恶,將不太常用的數(shù)據(jù)存在磁盤中食铐。——虛擬內(nèi)存
覆蓋裝入
以一個(gè)程序?yàn)閱挝贿M(jìn)行內(nèi)存的換入換出僧鲁。詳細(xì)內(nèi)容直接去看操作系統(tǒng)虐呻。
頁(yè)映射方式
將換入換出的粒度變得更小,以一頁(yè)的大小為單位進(jìn)程換入換出悔捶。
一個(gè)列子:
程序剛剛執(zhí)行的入口是P0铃慷,這時(shí)裝載掛你器發(fā)現(xiàn)P0不在內(nèi)存中单芜,于是將F0分配給P0蜕该,并且將P0內(nèi)容裝載到F0,運(yùn)行一段時(shí)候后發(fā)現(xiàn)需要用到P5洲鸠,于是裝載器將P5裝入F1堂淡,依次類推當(dāng)程序需要用到P3和P6的時(shí)候,分別被載入到F2扒腕,F(xiàn)3中绢淀。——有點(diǎn)類似懶加載
如果程序只需要這4個(gè)頁(yè)瘾腰,那么程序就能夠一直運(yùn)行下去皆的,但是,如果程序要訪問P4蹋盆,那么必須舍棄4個(gè)內(nèi)存頁(yè)其中的一個(gè)來裝載P4费薄。至于選擇哪一個(gè)頁(yè),可以根據(jù)算法選擇栖雾。比如先進(jìn)先出楞抡,LUR(最少使用算法)
現(xiàn)代的操作系統(tǒng)都是按照這樣的方式裝載可執(zhí)行文件。
操作系統(tǒng)角度理解可執(zhí)行文件的裝載
如上面所示析藕,程序使用物理地址直接操作召廷,每次頁(yè)被載入時(shí)都需要重定位。在虛擬內(nèi)存中現(xiàn)代的硬件MMU(內(nèi)存管理單元)提供了地址轉(zhuǎn)換功能账胧,有了硬件地址轉(zhuǎn)換和頁(yè)映射機(jī)制竞慢,可執(zhí)行文件加載動(dòng)態(tài)加載方式和靜態(tài)加載有非常大的不同。
進(jìn)程的建立(三步)
從操作系統(tǒng)的角度來講治泥,一個(gè)進(jìn)程最關(guān)鍵的特征就是它有獨(dú)立的虛擬地址空間筹煮,因此有別于其他進(jìn)程。
創(chuàng)建一個(gè)進(jìn)程车摄,裝載之后然后執(zhí)行需要下面三個(gè)步驟:
- 創(chuàng)建一個(gè)獨(dú)立的虛擬地址空間:創(chuàng)建映射函數(shù)所需要的相應(yīng)數(shù)據(jù)結(jié)構(gòu)寺谤,在Linux下仑鸥,創(chuàng)建虛擬地址實(shí)際上只是分配了一個(gè)頁(yè)目錄,還沒有頁(yè)映射变屁,映射關(guān)系等到后面程序發(fā)生頁(yè)錯(cuò)誤的時(shí)候在設(shè)置眼俊。
- 讀取可執(zhí)行文件頭,建立虛擬地址與可執(zhí)行文件的映射關(guān)系:上一步是頁(yè)映射關(guān)系函數(shù)時(shí)虛擬地址到物理地址的映射粟关,這一步是虛擬地址與可執(zhí)行文件的映射疮胖。當(dāng)程序執(zhí)行發(fā)生頁(yè)錯(cuò)誤的時(shí)候,操作系統(tǒng)將從物理內(nèi)存中分配一個(gè)物理頁(yè)闷板,然后將該
缺頁(yè)
從磁盤中讀取到內(nèi)存中澎灸,在設(shè)置缺頁(yè)的虛擬頁(yè)和物理頁(yè)的映射關(guān)系≌谕恚——當(dāng)操作系統(tǒng)捕獲到缺頁(yè)錯(cuò)誤的時(shí)候性昭,知道當(dāng)前程序所需要的頁(yè)在可執(zhí)行文件哪一個(gè)位置,這就是虛擬空間與可執(zhí)行文件映射關(guān)系县遣。 - 將CPU的指令寄存器設(shè)置成可執(zhí)行文件入口地址糜颠,啟動(dòng)運(yùn)行:操作系統(tǒng)通過設(shè)置CPU指令的寄存器將控制權(quán)交給進(jìn)程,由此進(jìn)程開始執(zhí)行萧求。ELF文件頭中保存了入口地址其兴。
現(xiàn)在對(duì)第二個(gè)步驟說明一下。假設(shè)現(xiàn)在EFL文件有一個(gè)代碼段.text
夸政,虛擬地址是0x0804 8000元旬,文件大小為0x00021,對(duì)齊為0x1000(4096守问,也就是一個(gè)虛擬頁(yè)的大性裙椤)。因?yàn)樵?text段不到一個(gè)頁(yè)酪碘,考慮到對(duì)齊該段占用一個(gè)段朋譬,所以可執(zhí)行完一旦被裝載,映射關(guān)系如下:
這種映射關(guān)系只是保存在操作系統(tǒng)內(nèi)部的一個(gè)數(shù)據(jù)結(jié)構(gòu)兴垦,Linux將進(jìn)程虛擬空間中的一段叫做虛擬內(nèi)存區(qū)域(VMA)——一種數(shù)據(jù)結(jié)構(gòu).
頁(yè)錯(cuò)誤(懶加載的方式)
上面步驟執(zhí)行完之后可執(zhí)行文件的指令并沒有被裝載到內(nèi)存中徙赢,只是通過可執(zhí)行文件頭部的信息建立可執(zhí)行文件和進(jìn)程虛擬內(nèi)存之間的映射關(guān)系而已。也就是先占個(gè)位置探越。
具體流程:如上面的例子狡赐,程序入口地址為0x08048000,剛好是.text
段的起始地址钦幔,當(dāng)CPU執(zhí)行這個(gè)地址的指令時(shí)枕屉,發(fā)現(xiàn)頁(yè)面0x0804 8000 到 0x0804 9000 是個(gè)空頁(yè),也是認(rèn)為這個(gè)是頁(yè)錯(cuò)誤鲤氢,CPU將控制權(quán)給操作系統(tǒng)搀擂,操作系統(tǒng)有專門處理頁(yè)錯(cuò)誤的例程西潘。這個(gè)時(shí)候操作系統(tǒng)將會(huì)查詢剛才第二步中建立的數(shù)據(jù)結(jié)構(gòu)(映射關(guān)系),找到空白頁(yè)所在VMA哨颂,計(jì)算出相應(yīng)頁(yè)面在可執(zhí)行文件中的偏移喷市,然后在物理內(nèi)存中分配一個(gè)物理頁(yè)面,將進(jìn)程中該虛擬頁(yè)與分配的物理頁(yè)之間建立映射關(guān)系威恼,然后再把控制權(quán)給進(jìn)程品姓,進(jìn)程從剛才的頁(yè)錯(cuò)誤重新執(zhí)行。——遇到錯(cuò)誤頁(yè)——》控制區(qū)給操作系統(tǒng)——》確定映射關(guān)系——》控制權(quán)交給進(jìn)程——》從錯(cuò)誤頁(yè)重新執(zhí)行
也就是可執(zhí)行文件和虛擬內(nèi)存建立先建立映射關(guān)系箫措,然后在發(fā)生錯(cuò)誤頁(yè)的時(shí)候根據(jù)之前建立映射的數(shù)據(jù)結(jié)構(gòu)確定物理頁(yè)與虛擬內(nèi)存的映射關(guān)系腹备。
隨著進(jìn)程的執(zhí)行,錯(cuò)誤頁(yè)不斷產(chǎn)生斤蔓,操作系統(tǒng)也會(huì)為進(jìn)程分配相應(yīng)的物理頁(yè)來滿足進(jìn)程的執(zhí)行需求植酥。簡(jiǎn)單來講如下圖所示:
進(jìn)程虛擬內(nèi)存分布(合并)
ELF文件鏈接視圖和執(zhí)行視圖
上面的例子中是以一個(gè).text
為例,然后被操作系統(tǒng)裝載到進(jìn)程空間附迷,對(duì)應(yīng)一個(gè)VMA惧互。但是一般可執(zhí)行文件由很多段,就會(huì)產(chǎn)生空間浪費(fèi)喇伯。因?yàn)镋LF文件映射到VMA中是以頁(yè)長(zhǎng)為單位的,每個(gè)段映射之后的長(zhǎng)度都是系統(tǒng)頁(yè)長(zhǎng)的整數(shù)倍拨与,不足的就會(huì)補(bǔ)足多用的部分稻据,造成空間浪費(fèi)。
最終是通過合并來解決上面的問題买喧。操作系統(tǒng)并不關(guān)心實(shí)際各個(gè)段包含的內(nèi)容捻悯,只關(guān)心一些跟裝載相關(guān)的問題,比如各個(gè)段的讀寫權(quán)限等淤毛。段可以分為:
- 以代碼段為代表的可讀可執(zhí)行段
- 以數(shù)據(jù)段今缚、BBS段為代表的可讀可寫段
- 以只讀數(shù)據(jù)段為代表的權(quán)限為只讀的段。
對(duì)于相同權(quán)限的段低淡,把它們合并到一起當(dāng)做一個(gè)段進(jìn)行映射姓言。——合并
如下圖所示如果.text
段為4097.init
段為512蔗蹋。那么這兩個(gè)段就需要三個(gè)頁(yè)大小何荚。如果把它們合并只需要兩個(gè)頁(yè)大小。
Segment(合并段的稱號(hào))
ELF可執(zhí)行文中引入了一個(gè)概念叫做
Segment
猪杭,一個(gè)Segment包含一個(gè)或多個(gè)屬性類型的Section餐塘。上面的例子中如果將.text
和.init
段合并在一起看作一個(gè)segment,那么裝載的時(shí)候就可以將他們看作一個(gè)整體一起映射——也就是映射以后在進(jìn)程的虛擬地址空間只有一個(gè)相對(duì)應(yīng)的VMA皂吮〗渖担可以減少頁(yè)面內(nèi)部碎片税手,節(jié)省內(nèi)存空間。
這里可能把Segment和Section弄混了需纳。
- Segment是從裝載的角度重新劃分了ELF的各個(gè)段
- 目標(biāo)文件鏈接成可執(zhí)行文件的時(shí)候冈止,鏈接器會(huì)把相同權(quán)限相同的段分在同一個(gè)空間,如可讀可執(zhí)行的段放在一起(代碼段)候齿,可讀可寫放在一起(數(shù)據(jù)段)熙暴,把這些屬性相似的、又連在一起的段叫做segment
- 系統(tǒng)按照Segmen而不是Section來映射可執(zhí)行文件慌盯。
也就是Section適用于目標(biāo)文件周霉,Segment適用于可執(zhí)行文件。
一個(gè)列子:
可以使用readelf命令查看ELFD額segment亚皂,類比之前的section屬性結(jié)構(gòu)俱箱,相應(yīng)的segment的結(jié)構(gòu)叫做程序頭,描述了ELF文件改如何被操作系統(tǒng)映射到進(jìn)程的虛擬空間中灭必。
根據(jù)上面的圖狞谱,這個(gè)可執(zhí)行文件最終有5個(gè)segment。目前只關(guān)心加載相關(guān)的Load類型的Segment禁漓,只有它是被需要映射的跟衅。
可執(zhí)行文件重新被換房了三個(gè)部分,一些短被歸入了可讀可執(zhí)行的播歼,統(tǒng)一被映射到VMA0伶跷;可讀可寫的映射到了VMA1;還有一部分段在程序裝載的時(shí)候沒有被映射秘狞,比如一些調(diào)試信息和字符串表等叭莫,這些段在程序執(zhí)行時(shí)沒有作用,所以不需要映射烁试」统酰——所有相同的section都被歸類到了一個(gè)segment中,映射到同一個(gè)VMA
在ELF的時(shí)候减响,段指的是segment靖诗,其他情況都是值section。
ELF可執(zhí)行文件有一個(gè)專門的數(shù)據(jù)結(jié)構(gòu)叫做程序頭用來保存Segment信息辩蛋,因?yàn)槟繕?biāo)文件不需要裝載所以沒有程序頭呻畸,動(dòng)態(tài)庫(kù)和ELF可執(zhí)行文件都有。類似于段表悼院,程序頭同樣是一個(gè)結(jié)構(gòu)體數(shù)組伤为。——對(duì)整個(gè)可執(zhí)行文的segment的說明
各個(gè)字段的含義如下:
堆和棧
堆和棧在進(jìn)程的虛擬空間同樣是以VMA的形式存在,分別都有一個(gè)對(duì)應(yīng)的VMA绞愚。Linux下可以使用/proc
來查看進(jìn)程的而虛擬空間分別叙甸。
解釋:可以看到該進(jìn)程有5個(gè)VMA,只有前兩個(gè)被映射到了可執(zhí)行文件宏的兩個(gè)segment位衩,另外三個(gè)沒有映射裆蒸,這三個(gè)叫做匿名虛擬內(nèi)存區(qū)域。可以看到還有兩個(gè)區(qū)域分別是heap和stack大小分別是140kb糖驴,88kb僚祷,這兩個(gè)區(qū)域在所有進(jìn)程中都存在。
每個(gè)線程都有屬于自己的堆棧贮缕,對(duì)于單線程的程序來講辙谜,這個(gè)VMA堆棧就全歸它使用。
操作系統(tǒng)通過給進(jìn)程空間劃分一個(gè)VMA來掛你進(jìn)程的虛擬空間感昼,將相同權(quán)限装哆、有相同映射文件的合成一個(gè)VMA。一個(gè)進(jìn)程基本上有如下幾種VMA:
- 代碼VMA定嗓,只讀蜕琴、可執(zhí)行,有映射文件
- 數(shù)據(jù)VMA宵溅,可讀可寫凌简、可執(zhí)行,有映射文件
- 堆VMA层玲,可讀可行号醉、可執(zhí)行,無映射文件辛块,匿名,可向上擴(kuò)展
- 棧VMA铅碍,可讀可行润绵、不可執(zhí)行,無映射文件胞谈,匿名尘盼,可向下擴(kuò)展
段地址對(duì)齊
這里的段值Segment。前面講過裝載過程是通過虛擬內(nèi)存額頁(yè)映射機(jī)制完成的烦绳,也是映射的最小單位卿捎,大小是4096。所以映射的物理內(nèi)存和虛擬內(nèi)存都徐亞是4096的整數(shù)倍径密。由于長(zhǎng)度和起始地址的顯示午阵,應(yīng)該盡可能的優(yōu)化空間和地址安排,節(jié)省空間。
假設(shè)現(xiàn)在一個(gè)ELF可執(zhí)行文件有三個(gè)段底桂,SEG0植袍,SEG1,SEG2籽懦,長(zhǎng)度和偏移如下:
每個(gè)段的長(zhǎng)度都不是頁(yè)長(zhǎng)度的整數(shù)倍于个,一種簡(jiǎn)單的思路就是把每個(gè)段分開映射但是會(huì)導(dǎo)致非常多內(nèi)存碎片的,因?yàn)殚L(zhǎng)度不足4096的需要補(bǔ)足4096暮顺。
在UNIX中厅篓,采用的是讓各個(gè)段接壤部分共享一個(gè)物理頁(yè)面,然后將該物理頁(yè)面分別映射兩次捶码,比如SGE0和SGE1接壤的那個(gè)物理頁(yè)羽氮,系統(tǒng)將它們映射兩份到虛擬地址空間。UNIX中系統(tǒng)將ELF的文件頭也看做是系統(tǒng)的一個(gè)段(可以從下面的圖中看到)宙项,也會(huì)映射到虛擬地址空間乏苦,這樣進(jìn)程中的某一段區(qū)域就是整個(gè)ELF文件的鏡像了,這就操作ELF文件頭就可以直接讀寫內(nèi)存的來實(shí)現(xiàn)操作尤筐。
ELF文件從開始到某個(gè)點(diǎn)結(jié)束也4096位單位劃分為若干個(gè)塊汇荐,每個(gè)塊單獨(dú)裝載到物理內(nèi)存中,如果位于段中間的塊盆繁,就會(huì)被映射兩次掀淘。
這樣內(nèi)次空間就得到了充分的利用,上面例子看出本來用到5個(gè)物理頁(yè)油昂,現(xiàn)在只需要3個(gè)革娄。一個(gè)極端情況,如果文件頭冕碟、代碼段拦惋、數(shù)據(jù)段加起來都沒有4096那么只需要一個(gè)物理頁(yè)就夠了。
進(jìn)程棧初始化
進(jìn)程剛開始啟動(dòng)的時(shí)候安寺,需要知道一些進(jìn)程運(yùn)行的環(huán)境厕妖,最基本的就是系統(tǒng)環(huán)境變量和進(jìn)程運(yùn)行參數(shù)。常見的做法就是操作系統(tǒng)在進(jìn)程啟動(dòng)前將這些信息提前保存到虛擬空間的棧中(也就是VMA中的Stack VMA)挑庶⊙越眨——系統(tǒng)環(huán)境變量,進(jìn)程運(yùn)行參數(shù)
假設(shè)有如下環(huán)境變量:
HOME=/home/user
PATH=/usr/bin
假設(shè)堆棧段底部地址為0xBF80 2000迎捺,那么進(jìn)程初始化后的堆棧就如下圖所示:
- 棧頂寄存器esp指向的位置是初始化以后堆棧的頂部举畸,最前面4個(gè)字節(jié)表示命令行參數(shù)的數(shù)量。
- 對(duì)應(yīng)這個(gè)例子是
prog 123
- 緊跟著的就是分布指向這兩個(gè)參數(shù)字符串的指針凳枝,后面跟了一個(gè)0
- 緊接著是兩個(gè)指向環(huán)境變量的字符串指針抄沮,分別指向字符串
HOME=/home/user
和PATH=/usr/bin
- 后面緊跟著一個(gè)0表示結(jié)束。
進(jìn)程啟動(dòng)之后,程序的庫(kù)會(huì)把堆棧里面的初始化信息中的參數(shù)信息傳遞給main()函數(shù)合是,也就是我們熟知的argc和argv連個(gè)參數(shù)了罪,兩個(gè)參數(shù)分別對(duì)應(yīng)這里的命令參數(shù)數(shù)量和命令行參數(shù)字符串指針數(shù)組。
Linux內(nèi)核裝載ELF過程(可以省略聪全,有點(diǎn)深)
當(dāng)在Linux系統(tǒng)bash下輸入一個(gè)命令執(zhí)行ELF程序時(shí).
首先在用戶層面泊藕,bash進(jìn)程會(huì)調(diào)用fork,系統(tǒng)會(huì)創(chuàng)建一個(gè)新的進(jìn)程难礼,新的進(jìn)程會(huì)用exeve()系統(tǒng)調(diào)用指定ELF文件娃圆,原先bash進(jìn)程繼續(xù)返回等待剛才啟動(dòng)新進(jìn)程結(jié)束,開始等待用戶輸入命令蛾茉。
最終會(huì)調(diào)用到execve讼呢,函數(shù)原型
int execve(const char * __file, char * const * __argv, char * const * __envp)
。三個(gè)參數(shù)分別是:
- 可執(zhí)行文件名
- 執(zhí)行參數(shù)
- 環(huán)境變量
調(diào)用過程中還會(huì)調(diào)用到do_excve()
谦炬,do_excve()
會(huì)讀取文件的前128個(gè)字節(jié)悦屏,判斷文件格式,特別是開頭的四個(gè)字節(jié)常常被稱作魔數(shù)键思,通過魔數(shù)可以判斷文件的格式及類型础爬。
上面步驟可以確定文件的類型及格式了,然后調(diào)用search_binary——handle()
去搜索和匹配合適的可執(zhí)行文件裝載處理過程吼鳞。匹配過程是通過判斷文件頭部的魔數(shù)確定的看蚜,比如ELF可執(zhí)行文件裝載處理過程叫做load_elf_binary(),a.out可執(zhí)行文件的裝載處理過程叫做load_aout_binary(),可執(zhí)行腳本處理過程叫做load_script()赔桌。比如load_elf_binary()主要經(jīng)歷了如下步驟供炎。
- 檢查ELF可執(zhí)行危機(jī)格式的有效性。如魔數(shù)疾党,程序頭表中段的數(shù)量
- 尋找動(dòng)態(tài)鏈接的
.interp
段音诫,設(shè)置動(dòng)態(tài)鏈接路徑 - 根據(jù)ELF可執(zhí)行文件的程序頭表描述,對(duì)ELF文件進(jìn)行映射雪位,比如代碼數(shù)據(jù)纽竣,只讀數(shù)據(jù)
- 初始化ELF進(jìn)程環(huán)境,比如進(jìn)程啟動(dòng)是EDX寄存器地址應(yīng)該是DT_FINI地址(動(dòng)態(tài)鏈接會(huì)講)
- 將系統(tǒng)調(diào)用的返回地址修改成ELF可執(zhí)行文件的入口點(diǎn)茧泪,這個(gè)入口點(diǎn)取決于程序的鏈接方式。對(duì)于靜態(tài)鏈接的ELF可執(zhí)行文件聋袋,入口點(diǎn)就是ELF文件的文件頭中e_entry所指的地址队伟;動(dòng)態(tài)鏈接的ELF,入口點(diǎn)就是動(dòng)態(tài)鏈接器
當(dāng)load_elf_binary執(zhí)行完畢幽勒,返回到do_execve在返回到sys_exevce()時(shí)嗜侮,第5步中已經(jīng)把系統(tǒng)調(diào)用的返回地址改為了被裝載的ELF的程序入口 地址。所以當(dāng)sys_execve()從內(nèi)核態(tài)返回到用戶態(tài)的時(shí)候,EIP寄存器直接跳到ELF程序入口地址锈颗,新的程序開始執(zhí)行顷霹。
總結(jié)
關(guān)于可執(zhí)行文件的裝載和進(jìn)程進(jìn)程就介紹到這里。很多東西如果去深究击吱,會(huì)發(fā)現(xiàn)是個(gè)無底洞淋淀。生有涯而學(xué)無涯!