第6章 可執(zhí)行文件的裝載與進(jìn)程

MMU(Memory Management Unit):內(nèi)存管理單元惨远,它將虛擬地址轉(zhuǎn)換位物理地址辫红。

6.1進(jìn)程的虛擬地址空間

程序和進(jìn)程的區(qū)別:程序是靜態(tài)的车海,進(jìn)程是動(dòng)態(tài)的。進(jìn)程是程序運(yùn)行時(shí)的一個(gè)過程彬祖,程序是預(yù)先編譯好的指令和數(shù)據(jù)的集合豁跑。

一般來說C語言中的指針大小與虛擬地址空間的位數(shù)相同慧瘤,例如宜雀,Win32平臺(tái)下虛擬地址空間為32位,所以指針大小也是32位埋凯。

程序都是運(yùn)行在虛擬地址空間中的点楼。

一般來講,內(nèi)存空間被分成兩部分——系統(tǒng)區(qū)和用戶區(qū)白对,我們平時(shí)所能操作的都是用戶區(qū)掠廓,系統(tǒng)區(qū)是被禁止的。

32位的CPU最大支持4G內(nèi)存甩恼,這實(shí)際上說的是虛擬地址空間大小蟀瞧,但實(shí)際上你可以將物理地址空間擴(kuò)展到4G以上沉颂。所謂的32位的操作系統(tǒng)也就是支持最大虛擬地址空間為232=4G的操作系統(tǒng)。

6.2裝載的方式

程序在運(yùn)行時(shí)所需要的內(nèi)存往往大于物理內(nèi)存所能提供的悦污。

程序的局部性原理就是說程序在運(yùn)行時(shí)只有一部分需要放進(jìn)內(nèi)存铸屉。

動(dòng)態(tài)裝載的基本原理是程序的局部性原理,它的思想是程序用到哪個(gè)模塊就把哪個(gè)模塊放進(jìn)內(nèi)存切端。

動(dòng)態(tài)裝載的兩種典型的方法是覆蓋裝入和頁映射彻坛。

6.2.1覆蓋裝入

程序員手工編寫用于控制模塊動(dòng)態(tài)裝載的管理代碼,它被稱為覆蓋管理器踏枣。

它的思想是各模塊輪流共用內(nèi)存的一片區(qū)域昌屉,程序員手動(dòng)控制哪個(gè)模塊在某一時(shí)刻該進(jìn)入該區(qū)域。

模塊之間往往存在依賴的關(guān)系茵瀑,這使得獨(dú)一模塊無法完成功能间驮,這種依賴關(guān)系使各模塊間形成了樹狀結(jié)構(gòu)。加載一個(gè)模塊的時(shí)候也必須把存在依賴關(guān)系的模塊马昨,換句話說就是該模塊的組成模塊蜻牢,也一同加載進(jìn)內(nèi)存。這也說明你不要把非組成模塊加載進(jìn)內(nèi)存偏陪。

模塊覆蓋慢,因?yàn)樗枰涯K在內(nèi)存和硬盤之間換進(jìn)換出煮嫌,而且還需要經(jīng)過覆蓋管理器笛谦。

它是一種時(shí)間換空間的解決方案。

6.2.2頁映射

它把磁盤中所有的數(shù)據(jù)和指令以頁為單位進(jìn)行劃分昌阿,裝載用的也是頁饥脑。

比如說現(xiàn)在頁的大小是212=4096byte,內(nèi)存大小為512M=229byte懦冰,所以在某一時(shí)刻該內(nèi)存可容納最多229/212=217個(gè)頁面灶轰,即131072頁。

6.3從操作系統(tǒng)的角度看可執(zhí)行文件的裝載

6.3.1進(jìn)程的建立

虛擬存儲(chǔ)的發(fā)展使得頁映射機(jī)制成為可能刷钢,如果是物理地址直接裝載的話笋颤,那么還需要重定位,好在現(xiàn)階段操作系統(tǒng)已經(jīng)接管了這一工作内地。

一個(gè)進(jìn)程區(qū)別于其他進(jìn)程的特征就是它擁有它自己獨(dú)立的虛擬地址空間伴澄。

創(chuàng)建進(jìn)程通常需要做三件事:

1、創(chuàng)建獨(dú)立的虛擬地址空間阱缓。

2非凌、讀取可執(zhí)行文件,建立虛擬地址空間與可執(zhí)行文件的映射關(guān)系荆针。

3敞嗡、將CPU的指令寄存器設(shè)置為程序執(zhí)行入口颁糟,開始執(zhí)行。

創(chuàng)建虛擬空間并不是創(chuàng)建空間而是創(chuàng)建應(yīng)設(shè)函數(shù)所需要的數(shù)據(jù)結(jié)構(gòu)喉悴,例如Linux只創(chuàng)建一個(gè)也目錄就完事了棱貌。它的作用是創(chuàng)建虛擬地址空間與物理地址空間的映射關(guān)系。

當(dāng)程序執(zhí)行到某一處時(shí)發(fā)現(xiàn)它所需要的指令和數(shù)據(jù)不在內(nèi)存中粥惧,這時(shí)候就產(chǎn)生了缺頁中斷键畴,操作系統(tǒng)捕獲到該中斷就磁盤中的可執(zhí)行文件中的該頁換入到內(nèi)存中。但是問題是該把可執(zhí)行文件中的哪一頁還進(jìn)內(nèi)存呢突雪?解決方案是把虛擬地址空間和可執(zhí)行文件之間建立映射關(guān)系起惕。這種映射關(guān)系保存在操作系統(tǒng)中的一個(gè)數(shù)據(jù)結(jié)構(gòu)中,在Linux下叫VMA(Virtual

Memory Area)咏删,在Windows下叫VS(Virtual

Section)惹想。這里邊存儲(chǔ)著ELF的虛擬地址空間的起始和終止地址、段名督函、段的屬性等嘀粱。

然后操作系統(tǒng)控制CPU將控制權(quán)轉(zhuǎn)交給程序,具體來講是跳轉(zhuǎn)到程序入口辰狡,自此程序開始執(zhí)行锋叨。

6.4進(jìn)程虛存空間的分布

6.4.1

ELF文件鏈接視圖和執(zhí)行視圖

ELF文件中的段大小是頁的整數(shù)倍,頁比段小宛篇。

操作系統(tǒng)關(guān)心的只是段的權(quán)限娃磺,即,只讀叫倍、只寫偷卧、讀寫。

把相同權(quán)限的段合并到一起進(jìn)行映射吆倦,可以頁面碎片听诸,節(jié)省內(nèi)存空間。ELF就是這樣做的蚕泽。從虛擬存儲(chǔ)的角度講ELF分成若干segment晌梨,每個(gè)segment又分成若干section。

ELF被劃分成3個(gè)segment须妻,它們是可讀可執(zhí)行的VMA0派任、可讀可寫VMA1和調(diào)試信息+字符串表。

section是ELF的鏈接視圖而segment是ELF的執(zhí)行視圖璧南。

在裝載時(shí)指的是ELF的執(zhí)行視圖掌逛,即,segment司倚。

segment的信息保存在ELF文件中的程序頭表中豆混。

由于ELF目標(biāo)文件不會(huì)被裝載篓像,因此目標(biāo)文件沒有程序頭表,剩下的像可執(zhí)行文件和共享庫文件都是由程序頭表的皿伺。和前面講的結(jié)構(gòu)一樣员辩,程序頭表也是個(gè)結(jié)構(gòu)體,它的名字叫Elf32_Phdr鸵鸥。

6.4.2堆和棧

操作系統(tǒng)還通過VMA對(duì)進(jìn)程的地址空間進(jìn)行管理奠滑,比如堆和棧。

AVMA(Anonymous Virtual Memory Area)是沒有映射到文件中的VMA妒穴。幾乎每個(gè)進(jìn)程都有3個(gè)AVMA宋税,它們是堆、棧和vdso讼油。其中杰赛,vdso是進(jìn)程與內(nèi)核通信的模塊。

P192~P193之間對(duì)進(jìn)程與VMA之間的關(guān)系做了簡(jiǎn)要的總結(jié)概括矮台。

從圖6-9可以看出內(nèi)存虛擬地址空間中從低地址到高地址依次分布著code乏屯、data、heap和stack等幾個(gè)區(qū)域瘦赫。

6.4.3堆的最大申請(qǐng)數(shù)量

堆主管動(dòng)態(tài)空間分配辰晕,它最多能分配的空間受操作系統(tǒng)版本、程序本身大小确虱、動(dòng)態(tài)/共享庫數(shù)量含友、程序棧數(shù)量大小等因素影響。

6.4.4段地址對(duì)齊

這一點(diǎn)決定了虛擬起址必須是頁大小的整數(shù)倍蝉娜,于是這就存在一個(gè)優(yōu)化的問題。即扎唾,如何優(yōu)化才能使空間利用率提高召川。

當(dāng)一個(gè)頁面的實(shí)際大小不足一頁但卻非要占去一個(gè)頁空間的話會(huì)浪費(fèi)很大的頁面。

為此UNIX提出了一個(gè)解決方案胸遇。它讓兩個(gè)段之間相鄰的部分共享一塊物理內(nèi)存區(qū)域荧呐,然后再把這塊區(qū)域映射到各段各自的虛擬地址空間中去。

比如seg0和seg1是相鄰的纸镊,seg0獨(dú)立的部分被映射在5Page處倍阐,seg1和seg0相鄰的地方被映射在4Page處,seg1獨(dú)立的部分被映射在3Page處逗威。由于4Page處是共享的部分峰搪,所以它要被映射到seg0和seg1各自的虛擬空間中去。即凯旭,seg0的虛擬地址空間=seg0獨(dú)立的虛擬地址空間+seg0與seg1相鄰的虛擬地址空間概耻。而seg1的虛擬地址空間=seg1獨(dú)立的虛擬地址空間+ seg0與seg1相鄰的虛擬地址空間使套。

從這張圖也可以看出可執(zhí)行文件的各個(gè)段是先被映射成物理地址空間,然后再被映射成虛擬地址空間的鞠柄。

6.4.5進(jìn)程棧初始化

它是一種系統(tǒng)提供的程序運(yùn)行的環(huán)境侦高,進(jìn)程棧中保存著系統(tǒng)環(huán)境變量和運(yùn)行參數(shù),它也同樣是在虛擬地址空間中厌杜。

圖6-12展示了Linux進(jìn)程初始化棧的布局奉呛。

ESP(Extended stack pointer):棧頂指針。

6.5

Linux內(nèi)核裝載ELF過程簡(jiǎn)介

bash:unix下的shell夯尽。

bash調(diào)用fork()創(chuàng)建新進(jìn)程瞧壮,新進(jìn)程再調(diào)用execve()系統(tǒng)調(diào)用執(zhí)行ELF文件。

在內(nèi)核中execve()的入口是sys_execve()呐萌,sys_execve()在進(jìn)行一些參數(shù)檢查復(fù)制后調(diào)用do_ execve()馁痴。

do_ execve()會(huì)檢查可執(zhí)行文件的前128字節(jié)的內(nèi)容以判斷該文件的格式。每種可執(zhí)行文件的前4個(gè)字節(jié)被稱為魔數(shù)肺孤,每種可執(zhí)行文件的魔術(shù)都是不同的罗晕。

然后,do_

execve()再調(diào)用search_binary_handle()查找和匹配相應(yīng)的可執(zhí)行文件的裝載處理過程赠堵,這一過程是由search_binary_handle()檢查魔數(shù)來完成的小渊。

裝過處理過程所要做的事情可參見P199所述內(nèi)容。

以上過程完成以后EIP(Extend

Instruction Pointer)寄存器就指向了ELF程序的入口茫叭,于是ELF程序開始執(zhí)行酬屉。

6.6

Windows PE的裝載

PE文件中的段的起始地址和長(zhǎng)度都是頁的整數(shù)倍。

PE文件中段的數(shù)量比ELF文件中的段數(shù)量少很多揍愁,一般只有代碼段呐萨、數(shù)據(jù)段、只讀數(shù)據(jù)段和BSS等幾個(gè)莽囤。

RVA(Relative Virtual Address):它是相對(duì)于PE文件裝載基址的偏移地址谬擦。

每個(gè)PE文件都會(huì)被裝載到某一特定地址,改地址被稱為目標(biāo)地址朽缎,也就是基地址惨远,這個(gè)基地址不是固定的。

PE文件的裝載過程可參見P200~P201所述部分话肖。

與PE文件裝載有關(guān)的信息都在PE擴(kuò)展頭(PE Optional Header)和段表中北秽。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市最筒,隨后出現(xiàn)的幾起案子贺氓,更是在濱河造成了極大的恐慌,老刑警劉巖床蜘,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件掠归,死亡現(xiàn)場(chǎng)離奇詭異缅叠,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)虏冻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門肤粱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人厨相,你說我怎么就攤上這事领曼。” “怎么了蛮穿?”我有些...
    開封第一講書人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵庶骄,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我践磅,道長(zhǎng)单刁,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任府适,我火速辦了婚禮羔飞,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘檐春。我一直安慰自己逻淌,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開白布疟暖。 她就那樣靜靜地躺著卡儒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪俐巴。 梳的紋絲不亂的頭發(fā)上骨望,一...
    開封第一講書人閱讀 51,624評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音欣舵,去河邊找鬼擎鸠。 笑死,一個(gè)胖子當(dāng)著我的面吹牛邻遏,可吹牛的內(nèi)容都是我干的糠亩。 我是一名探鬼主播虐骑,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼准验,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了廷没?” 一聲冷哼從身側(cè)響起糊饱,我...
    開封第一講書人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎颠黎,沒想到半個(gè)月后另锋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體滞项,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年夭坪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了文判。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡室梅,死狀恐怖戏仓,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情亡鼠,我是刑警寧澤赏殃,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站间涵,受9級(jí)特大地震影響仁热,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜勾哩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一抗蠢、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧钳幅,春花似錦物蝙、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至钠导,卻和暖如春震嫉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背牡属。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來泰國打工票堵, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人逮栅。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓悴势,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親措伐。 傳聞我的和親對(duì)象是個(gè)殘疾皇子特纤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容