日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[转]ELF文件结构简述

發(fā)布時間:2025/3/21 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [转]ELF文件结构简述 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

http://blog.endlesscode.com/2010/05/31/elf-file-structure-short-intro/

ELF文件結(jié)構(gòu)簡述

by?Stephen?posted on?

現(xiàn)在PC平臺流行的可執(zhí)行文件格式主要是Windows下的PE(Portable Executable)和Linux的ELF(Executable Linkable Format),它們都是COFF(Common File Format)格式的變種。目標文件就是源代碼編譯后但未進行鏈接的那些中間文件(Windows的.obj和Linux下的.o),它跟可執(zhí)行文件的內(nèi)容與結(jié)構(gòu)很相似,所以一般跟可執(zhí)行文件格式一起采用一種格式存儲。

Linux的.o/Windows的.obj、/bin/bash或Windows的exe、Linux的.so/Windows的.dll分別是什么文件?

  • Linux的.o和Windows的.obj稱為可重定位文件(Relocatable File),這類文件包含了代碼和數(shù)據(jù),可以被用來鏈接成可執(zhí)行文件共享目標文件靜態(tài)鏈接庫也可以歸為這一類。
  • /bin/bash和Windows的.exe是可以直接執(zhí)行的程序,它的代表就是ELF可執(zhí)行文件,它們一般是沒有擴展名的。
  • Linux的.so和Windows的.dll稱為共享目標文件,這種文件也包含了代碼和數(shù)據(jù),可以在以下兩種情況下使用。一種是鏈接器可以使用這種文件跟其他的可重位文件和共享目標文件鏈接、產(chǎn)生新的目標文件。第二種是動態(tài)鏈接器可以將幾個這種共享目標文件與可執(zhí)行文件結(jié)合,作為進程映像的一部分來執(zhí)行。
  • ELF目標文件的格式是怎樣?

    ELF文件除了包括了上述圖示中的機器指令代碼、數(shù)據(jù),還包括了鏈接時所需要的一些信息,比如符號表、調(diào)試信息、字符串等。這些信息按不同的屬性,以“段“(Segment)的形式存儲。程序源代碼編譯后的機器指令經(jīng)常放在代碼段(Code Section)里,代碼段常見的名字有”.code”或”.text”;全局變量和局部靜態(tài)變量經(jīng)常放在數(shù)據(jù)段(Data Section),數(shù)據(jù)段一句名字叫為”.data”。而ELF文件的開頭是一個“文件頭”,它描述了整個文件的文件屬性,包括文件是否可執(zhí)行、是靜態(tài)鏈接還是地動態(tài)鏈接及入口地址(如果是可執(zhí)行文件)、目標硬件、目標操作系統(tǒng)等信息,文件頭還包括一個段表的位置信息,段表在ELF文件中是一個描述文件中各個段的數(shù)組,包括各個段在文件的偏移位置,段的屬性,段的名稱等等。

    程序源代碼被編譯以后主要分成兩種段:程序指令和程序數(shù)據(jù)。代碼段(.text)屬于程序指令,而數(shù)據(jù)段(.data)和.bss段屬于程序數(shù)據(jù)。 一般C語言的編譯后執(zhí)行語句都編譯成機器代碼,保存在.text段;已初始化的全局變量和局部靜態(tài)變量都保存在.data段;未初始化的全局變量和局部靜 態(tài)變量一般放在.bss段,這些未初始化的全局變量和局部靜態(tài)變量默認值都為0,放在.data段顯示沒有必要,因此放在了.bss段。所以.bss段只 是為未初始化的全局變量和局部靜態(tài)變量預(yù)留位置,它并沒有內(nèi)容,所以它在文件中也不占據(jù)空間。

    一般程序被裝載后,數(shù)據(jù)和指令分別被映射到兩個虛存區(qū)域。由于數(shù)據(jù)區(qū)域?qū)τ谶M程來說是可讀可寫的,而指令區(qū)域?qū)τ谶M程來是只讀的,所以這兩個虛存區(qū)域的權(quán)限可以被分別設(shè)置成可讀寫和只讀。這樣可以防止程序的指令被有意或無意地改寫。

    常用的段名說明
    .rodata1Read Only Data,這種段里存放的是只讀數(shù)據(jù),比如字符串常量、全局const變量。跟”.rodata”一樣
    .comment存放的是編譯器版本信息
    .debug調(diào)試信息
    .dynamic動態(tài)鏈接信息
    .hash符號哈希表
    .line調(diào)試時的行號表
    .note額外的編譯器信息。比如程序的公司名、發(fā)布版本號等
    .strtabString Table.字符串表
    .symtabSymbol Table.符號表
    .shstrtabSection String Table.段名表
    .plt
    .got
    動態(tài)鏈接的跳轉(zhuǎn)表和全局入口表
    .init
    .fini
    程序初始化與終結(jié)代碼段

    其中,”.rodata”段存放的是只讀數(shù)據(jù),一般是程序里面的只讀變量(如const修飾的變量)和字符串常量。單獨設(shè)立”.rodata”段有很多好 處,不光是在語義上支持了C++的const關(guān)鍵字,而且操作系統(tǒng)在加載的時候可以將”.rodata”段的屬性映射成只讀,這樣對于這個段的任何修改操 作都會作為非法操作處理,保證程序的安全性。當然,有些編譯器也會把字符串放到”.data”段,而不會單獨放在”.rodata”段。

    如C中的printf(“%d\nHello World!”)中的字符”%d\nHello World!”是存儲在哪里的?

    ELF文件中用到了很多字符串,比如段名、變量名等。因為字符串的長度往往是不定的,所以用固定的結(jié)構(gòu)來表示它比較困難。一種很常見的做法是把字符串集中起來存放到一個表,然后使用字符串在表中的偏移來引用字符串。如下圖所示:

    通過這種方法,在ELF文件中引用字符串只須給出一個數(shù)字下標即可,不用考慮字符串長度的問題。一般字符串表在ELF文件中也以段的形式保存,常見的段名為”.strtab“或”.shstrtab“。這兩個字符串分別為字符串表(String Table)和段表字符串表(Section Header String Table)。顧名思義,字符串表用來保存普通的字符串,比如符號的名字;段表字符串表用來保存段表中用到的字符串,最常見的就是段名。

    段表是結(jié)構(gòu)是怎樣?存儲了哪些信息?

    段表的結(jié)構(gòu)其實就是一個數(shù)組,數(shù)組的元素是固定的結(jié)構(gòu),每個元素包括了各個段的信息,比如每個段的段名、段的長度、在文件中的偏移、讀寫權(quán)限、段的鏈接信息以及段的其他屬性。其中描述段名的只是一個偏移,是段名字符串在”.shstrtab”段中的偏移。那么如何根據(jù)ELF文件頭和段表來定位文件中的一個段呢?從ELF文件頭中獲取段表在文件中的偏移以及段表的大小,而從獲取到了文件中的段表,再分析段表數(shù)組中的每個元素,得知段的偏移、段的長度和段的類型,就可以準確地定位一個段了。

    字符串表和符號表有什么不同?

    其實是完全不同的兩個表,但是兩個表又有關(guān)聯(lián)。簡單地說,字符串表就是記錄ELF文件中的字符串常量,變量名等等。而符號表的存在意義是體現(xiàn)在多個目標文件進行鏈接的時候,在鏈接中,目標文件之間相互拼合實際上是目標文件之間對地址的引用,即對函數(shù)和變量的地址的引用,而函數(shù)和變量可以統(tǒng)稱為符號(Symbol),函數(shù)名或變量名就是符號名(Symbol Name)。我們可以將符號看作是是鏈接中的粘合劑,整個鏈接過程就是基于符號才能夠正確完成。在符號表”.symtab“中,其也是像段表的結(jié)構(gòu)一樣,是一個數(shù)組,每個數(shù)組元素是一個固定的結(jié)構(gòu)來保存符號的相關(guān)信息,比如符號名(不是字符串,而是該符號名在字符串表的下標)、符號對應(yīng)的值(可能是段中的偏移,也可能是符號的虛擬地址)、符號大小(數(shù)據(jù)類型的大小)等等。符號表中記錄的一般是全局符號,比如全局變量、全局函數(shù)等等。

    Visual Studio里面提示的Undefined Symbol,為什么是類似(?NewL@CHtmlControl@@SAPAV1@PAVCCoeControl@@@Z)這么詭異的symbol?

    程序里面肯定是沒有定義過”?NewL@CHtmlControl@@SAPAV1@PAVCCoeControl@@@Z”這么詭異的變量名的,但為什么變量名會變成這么詭異的?這是因為符號修飾的原因。符號修飾很大程度上是為了防止符號名沖突。比如復(fù)雜的C++擁有類、繼承、虛擬機制、重載、名稱空間等這些特性,如果兩個函數(shù)func(int)和func(float)不進行符號修飾而直接存儲變量名的話,然后只是單單根據(jù)函數(shù)名來判別的話,那么符號表就會出現(xiàn)2個一樣的符號了。根據(jù)函數(shù)簽名來修飾兩個重載函數(shù)就不會出現(xiàn)這樣的符號二義性的問題了。因為符號修飾的規(guī)則是各編譯器廠商都不一樣,因此再詭異也是沒有什么出奇的。

    如果兩個目標文件定義了相同的全局變量?

    在編輯過程中可能會遇到一種情況叫符號重復(fù)定義。這涉及到強符號(Strong Symbol)和弱符號(Weak Symbol)的定義。對于C/C++語言來說,編譯默認函數(shù)和初始化了的全局變量為強符號,未初始化的全局變量為弱符號。我們也可以通過GCC的”__attribute__((weak))”來定義任何一個強符號為弱符號,而用”extern int ext”這樣的方式定義并非弱符號也非弱符號,因為”ext”只是一個外部變量的引用。針對強弱符號的概念,鏈接器一般會按如下規(guī)則選擇全局符號:

    • 不允許強符號被多次定義,否則鏈接器會報符號重復(fù)定義的錯誤。
    • 如果一個符號在某個目標文件中是強符號,在其他文件中都是弱符號,那么選擇強符號。
    • 如果一個符號在所有目標文件中都是弱符號,那么選擇其中占用空間最大的一個。

    預(yù)編譯過程主要做了哪些處理?

  • 將所有的”#define”刪除,并且展開所有的宏定義。
  • 處理所有條件預(yù)編譯指令,比如”#if”, “#ifdef”, “#elif”, “#else”, “endif”。
  • 處理”#include”預(yù)編譯指令,將被包含的文件插入到該預(yù)編譯指令的位置。注意,這個過程是遞歸進行的,也就是說被包含的文件可能還包含其他文件。
  • 刪除所有的注釋”//”和”/**/”。
  • 添加行號和文件名標識,比如#2 “hello.c” 2,以便于編譯時編譯器產(chǎn)生調(diào)試用的行號信息及用于編譯時產(chǎn)生編譯錯誤或警告時能夠顯示行號。
  • 保留所有的#pragma編譯器指令,因為編譯器須要使用它們。
  • 轉(zhuǎn)載于:https://www.cnblogs.com/hengli/archive/2012/09/28/2707060.html

    總結(jié)

    以上是生活随笔為你收集整理的[转]ELF文件结构简述的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 国产福利小视频在线 | ⅹxxxxhd亚洲日本hd老师 | 中国女人内谢69xxxxⅹ视频 | 精品人妻一区二区三区四区不卡 | 漂亮少妇高潮午夜精品 | 黄色成人在线观看 | 欧美精品一区二 | 成人国产精品蜜柚视频 | 国产日韩在线视频 | 亚洲最大网站 | 中国女人毛片 | 免费看的黄色小视频 | 久久久久久69 | 欧美a v在线 | 欧美又粗又长又爽做受 | 国产99久一区二区三区a片 | 风流少妇 | 国产人妻人伦精品1国产 | 国产成人福利视频 | 亚洲视频在线观看视频 | 精品肉丝脚一区二区三区 | 欧美成人aaaaa | 日本女教师电影 | 日韩av在线高清 | 婷婷色六月 | 成年人黄色 | 日本中文在线观看 | 毛片毛片 | 国产精品久久av | 麻豆av免费观看 | 国产寡妇亲子伦一区二区三区四区 | 中文有码在线播放 | 男女激情网址 | 九色蝌蚪91| 婷婷精品一区二区三区 | 国产欧美精品一区二区色综合朱莉 | 2020国产精品| 日韩一区在线观看视频 | www狠狠| 91精品国产综合久 | 久久综合婷婷 | 视频在线亚洲 | 特黄特色大片免费播放器使用方法 | 91人人视频 | 婚后打屁股高h1v1调教 | 国产一区免费 | jizz日本大全| 波多野结衣中文字幕一区二区 | 性色在线 | 天天干,天天操,天天射 | 国产精品久久久99 | 少妇人妻一级a毛片 | 在线观看免费中文字幕 | 日本少妇激情视频 | 久久久久久久久久免费视频 | 69视频在线观看免费 | 毛片一级在线观看 | 日韩亚洲精品视频 | 久久99精品久久久久久噜噜 | 久久高潮视频 | 欧洲mv日韩mv国产 | 少妇精品亚洲一区二区成人 | 红桃av| 日韩黄色网页 | 成人av免费网站 | 日韩av无码一区二区三区不卡 | 青青操在线视频 | 白白色在线观看 | 日韩啊v| 一级黄色大片视频 | 久久一二三四区 | 射一射 | 国产在成人精品线拍偷自揄拍 | av中文字幕免费 | 日本二区在线观看 | 国产丝袜自拍 | 成年免费视频 | 欧美日韩精品一区二区三区 | 91精选 | 日韩乱码人妻无码中文字幕 | 2017天天干 | 黑人巨茎大战欧美白妇 | 国产懂色av| 人人干人人看 | 日韩欧美一区二区三区四区 | 欧美 日韩 成人 | av小次郎收藏| 国产日韩一级片 | 成人国产av一区二区三区 | 国产福利短视频 | 成人av动漫 | 色人阁五月| 亚洲一区二区在线 | 一级特黄aaaaaa大片 | 欧美xx在线 | 哺乳喂奶一二三区乳 | 特黄av | 午夜成人亚洲理伦片在线观看 | 综合视频在线观看 |