專(zhuān)利名稱(chēng):一種嵌入式系統(tǒng)運(yùn)行時(shí)堆棧溢出保護(hù)方法
技術(shù)領(lǐng)域:
本發(fā)明涉及嵌入式系統(tǒng)程序編譯技術(shù)領(lǐng)域,特別是涉及一種嵌入式系統(tǒng)運(yùn)行時(shí)堆棧溢出保護(hù)方法。
背景技術(shù):
在最近二、三十年嵌入式領(lǐng)域取得了長(zhǎng)足的發(fā)展,許多行業(yè)的發(fā)展已經(jīng)離不開(kāi)嵌入式領(lǐng)域的參與,如汽車(chē)、航空、重工、機(jī)器人、智能管家等不一而足。這些產(chǎn)業(yè)嵌入式領(lǐng)域的需求,促使了嵌入式系統(tǒng)的發(fā)展,同時(shí)也提出了越來(lái)越高的要求。
目前的嵌入式系統(tǒng)主要分為高端嵌入式系統(tǒng)和低端嵌入式系統(tǒng)兩大類(lèi),所謂高端嵌入式是指那些擁有高處理速度,多應(yīng)用的系統(tǒng),這些系統(tǒng)有高級(jí)的硬件設(shè)備。而低端是指處理速度、功能等方面一般的系統(tǒng)。這些系統(tǒng)往往在內(nèi)存上存在空間限制性的問(wèn)題。由于有不同的特性所以他們被用在不同的環(huán)境,提供不同的功能和效率。
低端的嵌入式系統(tǒng)很大一部分都存在內(nèi)存不足的問(wèn)題,造成這個(gè)問(wèn)題的原因主要來(lái)自?xún)蓚€(gè)方面一是硬件技術(shù)上的限制,二是成本上的限制。內(nèi)存不足嚴(yán)重地影響了運(yùn)行于系統(tǒng)上的程序的安全。一些對(duì)內(nèi)存空間要求比較高的程序會(huì)在無(wú)警告的情況下發(fā)生堆棧溢出錯(cuò)誤,最終導(dǎo)致系統(tǒng)崩潰。雖然對(duì)于小型程序這樣的問(wèn)題發(fā)生的幾率很小,但是只要有這樣的可能,那么系統(tǒng)就有隱患。
多年來(lái),針對(duì)嵌入式系統(tǒng)內(nèi)存限制導(dǎo)致堆棧溢出的研究有很多,但是其中有些太過(guò)理論,可行性太差。如內(nèi)存壓縮。內(nèi)存壓縮的目的就是能在有限的空間存儲(chǔ)更多的信息,但是這種方法花費(fèi)太多的數(shù)據(jù)壓縮時(shí)間和數(shù)據(jù)解壓縮時(shí)間,所以在時(shí)間應(yīng)用種實(shí)效性很差。
發(fā)明內(nèi)容
本發(fā)明的目的在于克服現(xiàn)有技術(shù)中的不足,提供一種嵌入式系統(tǒng)運(yùn)行時(shí)堆棧溢出保護(hù)方法。
本發(fā)明解決其技術(shù)問(wèn)題采用的技術(shù)方案如下嵌入式系統(tǒng)運(yùn)行時(shí)堆棧溢出保護(hù)方法,包括以下步驟(1)編譯器分析掃描原程序,生成程序函數(shù)調(diào)用表,供回卷函數(shù)優(yōu)化時(shí)使用;(2)編譯器在函數(shù)中插入運(yùn)行時(shí)檢測(cè)代碼,檢測(cè)堆棧的使用狀態(tài),并返回信息,供插入的運(yùn)行時(shí)處理代碼使用;(3)編譯器在函數(shù)中插入堆棧運(yùn)行時(shí)處理代碼如果無(wú)運(yùn)行時(shí)堆棧溢出錯(cuò)誤發(fā)生則處理代碼不做任何事;有錯(cuò)誤發(fā)生時(shí)a、若程序發(fā)現(xiàn)堆??臻g底部處有富余可用的空間,則調(diào)整堆棧寄存器的位置和堆?;鶞?zhǔn)寄存器的位置,從而擴(kuò)大堆??臻g,同時(shí)平移原棧中的數(shù)據(jù)到新棧底;恢復(fù)引起錯(cuò)誤的函數(shù)調(diào)用以前的狀態(tài),并重新執(zhí)行函數(shù)調(diào)用;b、在??臻g底部沒(méi)有發(fā)現(xiàn)有用空間,在整個(gè)內(nèi)存空間尋找可用的空間;如果在整個(gè)內(nèi)存空間中存在有用空間,則利用內(nèi)存分配調(diào)用,分配一塊內(nèi)存,并通過(guò)數(shù)據(jù)結(jié)構(gòu)和原堆棧連在一起,形成新堆棧,并平移原棧中的數(shù)據(jù)到新棧底;恢復(fù)引起錯(cuò)誤的函數(shù)調(diào)用以前的狀態(tài),并重新執(zhí)行函數(shù)調(diào)用;c、如果在整個(gè)內(nèi)存空間中沒(méi)有可用空間,則程序被掛起,等到有可用空間時(shí)再次被置入操作系統(tǒng)任務(wù)隊(duì)列中運(yùn)行;(4)采用函數(shù)回卷技術(shù),優(yōu)化在函數(shù)中插入的代碼對(duì)普通函數(shù),不做任何處理;對(duì)嵌套調(diào)用的函數(shù),進(jìn)行函數(shù)回卷優(yōu)化,從函數(shù)調(diào)用表中形成調(diào)用路徑,將路徑中所以的在的函數(shù)中插入的代碼簡(jiǎn)化合并到最頂層的函數(shù)中,簡(jiǎn)化代碼量。
本發(fā)明與背景技術(shù)相比,具有的有益的效果是本發(fā)明主要是采用編譯技術(shù)將運(yùn)行時(shí)檢測(cè)代碼和運(yùn)行時(shí)處理代碼插入到每個(gè)函數(shù)的開(kāi)始處,在出現(xiàn)嵌套函數(shù)調(diào)用時(shí),采用檢測(cè)代碼回卷技術(shù),只在起始調(diào)用函數(shù)中插入代碼,而無(wú)需在每個(gè)嵌套函數(shù)中插入代碼。這樣就大大的減少了代碼量。通過(guò)這樣的方法就能夠在應(yīng)用程序運(yùn)行時(shí)動(dòng)態(tài)檢測(cè)堆棧空間,并做相應(yīng)的處理,排除發(fā)生堆棧運(yùn)行溢出的可能性,最終保證系統(tǒng)可以在安全的前提下運(yùn)行。
圖1是本發(fā)明方法的流程示意圖。
具體實(shí)施例方式
下面結(jié)合附圖和具體實(shí)施例對(duì)本發(fā)明的內(nèi)容進(jìn)行詳細(xì)描述。
在實(shí)施嵌入式系統(tǒng)運(yùn)行時(shí)堆棧溢出保護(hù)方法時(shí),具體方式如下第一步,編譯器分析掃描原程序,生成程序函數(shù)調(diào)用表本方法的核心是在應(yīng)用程序代碼中插入運(yùn)行時(shí)檢測(cè)代碼和程序堆棧處理代碼。但是對(duì)于不同的函數(shù)需要不同的插入方法。如果是普通單函數(shù)調(diào)用,則正常插入就可以。但是對(duì)于嵌套調(diào)用的函數(shù),情況就不一樣,相較簡(jiǎn)單函數(shù)調(diào)用就復(fù)雜許多。下面的代碼就是兩種不同的情況void fun() void fun1(){{//內(nèi)部無(wú)函數(shù)調(diào)用 fun2();//調(diào)用函數(shù)fun2()}}對(duì)于fun()和fun1(),就是兩種不同的情況,需要不同的處理。所以要有函數(shù)調(diào)用表加以分析,得到的函數(shù)調(diào)用表由下面的步驟使用。
第二步,在函數(shù)中插入運(yùn)行時(shí)檢測(cè)代碼運(yùn)行時(shí)檢測(cè)代碼主要的功能是在程序運(yùn)行時(shí)檢測(cè)堆棧的使用狀態(tài),判定是否發(fā)生堆棧運(yùn)行時(shí)溢出,需要做以下檢測(cè)檢測(cè)堆向下生長(zhǎng)位置是否已經(jīng)和棧指針有交叉,如果有交叉說(shuō)明堆棧運(yùn)行時(shí)溢出錯(cuò)誤已經(jīng)發(fā)生。如果沒(méi)有交叉則說(shuō)明運(yùn)行狀態(tài)良好沒(méi)有錯(cuò)誤。返回的信息如下(1)有錯(cuò)誤,返回錯(cuò)誤信息,包括當(dāng)時(shí)堆的位置和引起錯(cuò)誤的函數(shù)調(diào)用信息函數(shù)局部變量、參數(shù)。
(2)無(wú)錯(cuò)誤,返回正確信息。不做任何處理。
代碼由編譯器插入到程序函數(shù)的開(kāi)頭處,以便在程序調(diào)用函數(shù)之后立即進(jìn)行檢測(cè)。
第三步,在函數(shù)中插入運(yùn)行時(shí)處理代碼
運(yùn)行時(shí)處理代碼的功能是根據(jù)第二步返回的結(jié)果對(duì)堆棧進(jìn)行處理,如果第二步返回的結(jié)果沒(méi)有任何問(wèn)題則此部分代碼不做任何處理。如果第二步的返回結(jié)果說(shuō)明堆棧運(yùn)行時(shí)溢出錯(cuò)誤已發(fā)生,則做查看堆棧底部有無(wú)多余可用空間(1)有多余空間,則調(diào)整堆棧底部位置,將堆棧底部向外擴(kuò)展。此時(shí)堆棧內(nèi)部的原來(lái)存儲(chǔ)在棧中的數(shù)據(jù)相對(duì)于棧底的位置發(fā)生了偏移,所以必須將原來(lái)?xiàng)V械臄?shù)據(jù)平移到棧底,并重新設(shè)置?;羔樀綏5孜恢?,棧指針到當(dāng)前站頂位置,重新執(zhí)行由第二步執(zhí)行的引發(fā)錯(cuò)誤的指令。通過(guò)這樣觸發(fā)錯(cuò)誤的函數(shù)調(diào)用將會(huì)被重新調(diào)用,而引起錯(cuò)誤時(shí)的調(diào)用所設(shè)置的數(shù)據(jù)已在第二步中進(jìn)行了記錄,這些記錄被用來(lái)恢復(fù)到錯(cuò)誤狀態(tài)前一步。等堆棧擴(kuò)充過(guò)之后就可以重新調(diào)用引起錯(cuò)誤的調(diào)用,這樣就能將錯(cuò)誤恢復(fù)過(guò)來(lái),保證了程序運(yùn)行的堆棧安全性。
(1)沒(méi)有多余空間,則系統(tǒng)通過(guò)系統(tǒng)調(diào)用,在整個(gè)可用內(nèi)存中尋找可用的內(nèi)存空間,(2)在整個(gè)內(nèi)存里有可用內(nèi)存,則分配一塊內(nèi)存,并將這塊內(nèi)存通過(guò)數(shù)據(jù)結(jié)構(gòu)和原來(lái)的棧底連接起來(lái)并平移原棧中的數(shù)據(jù)到新棧底部,重新設(shè)置棧基指針和棧指針。
(3)在整個(gè)內(nèi)存空間內(nèi)沒(méi)有可用內(nèi)存,則該程序被掛起,等到有可用內(nèi)存后才能再次被置如操作系統(tǒng)任務(wù)隊(duì)列中執(zhí)行。
第四步,插入代碼回卷技術(shù),優(yōu)化插入代碼第一步和第二步的代碼的插入是沒(méi)有優(yōu)化過(guò)的,通過(guò)第一、第二兩步插入的代碼量很大,所以對(duì)在為程序提供堆棧溢出保護(hù)的同時(shí)也增加了程序的代碼量。一個(gè)有效的方法是對(duì)插入代碼進(jìn)行優(yōu)化。優(yōu)化的情況主要分為兩個(gè)部分(1)簡(jiǎn)單函數(shù)優(yōu)化簡(jiǎn)單函數(shù)是指內(nèi)部沒(méi)有其他函數(shù)調(diào)用的函數(shù),這樣的函數(shù),內(nèi)部都是簡(jiǎn)單代碼,沒(méi)有嵌套函數(shù)調(diào)用,所以編譯器插入代碼時(shí)針對(duì)這類(lèi)函數(shù),只需在函數(shù)中簡(jiǎn)單的插入運(yùn)行時(shí)檢測(cè)代碼和運(yùn)行時(shí)處理代碼就可以,所以無(wú)需優(yōu)化。
(2)嵌套函數(shù)優(yōu)化嵌套函數(shù)時(shí)指一個(gè)函數(shù)中有別的函數(shù)調(diào)用,所以整個(gè)函數(shù)調(diào)用會(huì)涉及多處函數(shù)調(diào)用所以,會(huì)因?yàn)檫@一個(gè)函數(shù)的插入代碼需要插入大量的代碼。主要方法是利用第一步生成的函數(shù)調(diào)用表,分類(lèi)簡(jiǎn)單函數(shù)嵌套函數(shù)。在嵌套函數(shù)調(diào)用部分,根據(jù)函數(shù)調(diào)用表,找出函數(shù)調(diào)用路徑。無(wú)論那個(gè)函數(shù)都是簡(jiǎn)單函數(shù)堆砌而成,所以在函數(shù)調(diào)用路徑中,根據(jù)函數(shù)調(diào)用表,找出函數(shù)調(diào)用路徑。從函數(shù)調(diào)用路徑底部開(kāi)始把插入路徑中每個(gè)函數(shù)的代碼,優(yōu)化合并卷回到最頂層函數(shù)。這樣就降低了插入的代碼量,提高了可用性。
最后,還需要注意的是,以上列舉的僅是本發(fā)明的具體實(shí)施例子。顯然,本發(fā)明不限于以上實(shí)施例子,還可以有許多變形。本領(lǐng)域的普通技術(shù)人員能從本發(fā)明公開(kāi)的內(nèi)容直接導(dǎo)出或聯(lián)想到的所有變形,均應(yīng)認(rèn)為是本發(fā)明的保護(hù)范圍。
權(quán)利要求
1.一種嵌入式系統(tǒng)運(yùn)行時(shí)堆棧溢出保護(hù)方法,包括以下步驟(1)編譯器分析掃描原程序,生成程序函數(shù)調(diào)用表,供回卷函數(shù)優(yōu)化時(shí)使用;(2)編譯器在函數(shù)中插入運(yùn)行時(shí)檢測(cè)代碼,檢測(cè)堆棧的使用狀態(tài),并返回信息,供插入的運(yùn)行時(shí)處理代碼使用;(3)編譯器在函數(shù)中插入堆棧運(yùn)行時(shí)處理代碼如果無(wú)運(yùn)行時(shí)堆棧溢出錯(cuò)誤發(fā)生則處理代碼不做任何事;有錯(cuò)誤發(fā)生時(shí)a、若程序發(fā)現(xiàn)堆棧空間底部處有富余可用的空間,則調(diào)整堆棧寄存器的位置和堆棧基準(zhǔn)寄存器的位置,從而擴(kuò)大堆??臻g,同時(shí)平移原棧中的數(shù)據(jù)到新棧底;恢復(fù)引起錯(cuò)誤的函數(shù)調(diào)用以前的狀態(tài),并重新執(zhí)行函數(shù)調(diào)用;b、在??臻g底部沒(méi)有發(fā)現(xiàn)有用空間,在整個(gè)內(nèi)存空間尋找可用的空間;如果在整個(gè)內(nèi)存空間中存在有用空間,則利用內(nèi)存分配調(diào)用,分配一塊內(nèi)存,并通過(guò)數(shù)據(jù)結(jié)構(gòu)和原堆棧連在一起,形成新堆棧,并平移原棧中的數(shù)據(jù)到新棧底;恢復(fù)引起錯(cuò)誤的函數(shù)調(diào)用以前的狀態(tài),并重新執(zhí)行函數(shù)調(diào)用;c、如果在整個(gè)內(nèi)存空間中沒(méi)有可用空間,則程序被掛起,等到有可用空間時(shí)再次被置入操作系統(tǒng)任務(wù)隊(duì)列中運(yùn)行;(4)采用函數(shù)回卷技術(shù),優(yōu)化在函數(shù)中插入的代碼對(duì)普通函數(shù),不做任何處理;對(duì)嵌套調(diào)用的函數(shù),進(jìn)行函數(shù)回卷優(yōu)化,從函數(shù)調(diào)用表中形成調(diào)用路徑,將路徑中所以的在的函數(shù)中插入的代碼簡(jiǎn)化合并到最頂層的函數(shù)中,簡(jiǎn)化代碼量。
全文摘要
本發(fā)明涉及嵌入式系統(tǒng)程序編譯技術(shù)領(lǐng)域,旨在提供一種嵌入式系統(tǒng)運(yùn)行時(shí)堆棧溢出保護(hù)方法。該方法包括(1)編譯器分析掃描原程序,生成程序函數(shù)調(diào)用表,供回卷函數(shù)優(yōu)化時(shí)使用;(2)編譯器在函數(shù)中插入運(yùn)行時(shí)檢測(cè)代碼,檢測(cè)堆棧的使用狀態(tài),并返回信息,供插入的運(yùn)行時(shí)處理代碼使用;(3)編譯器在函數(shù)中插入堆棧運(yùn)行時(shí)處理代碼;(4)采用函數(shù)回卷技術(shù),優(yōu)化在函數(shù)中插入的代碼的步驟。本發(fā)明無(wú)需在每個(gè)嵌套函數(shù)中插入代碼,大大的減少了代碼量。通過(guò)這樣的方法就能夠在應(yīng)用程序運(yùn)行時(shí)動(dòng)態(tài)檢測(cè)堆棧空間,并做相應(yīng)的處理,排除發(fā)生堆棧運(yùn)行溢出的可能性,最終保證系統(tǒng)可以在安全的前提下運(yùn)行。
文檔編號(hào)G06F9/45GK1851648SQ20061005162
公開(kāi)日2006年10月25日 申請(qǐng)日期2006年5月25日 優(yōu)先權(quán)日2006年5月25日
發(fā)明者陳天洲, 沙峰, 謝斌, 趙懿 申請(qǐng)人:浙江大學(xué)