Object file: Compiler編譯原始碼產生的檔案
目前常見的可執行檔格式 :
Windows下的PE(Portable Executable)
Linux的ELF(Executable Linkable Format)
Object file就是原始碼編譯過還沒Link的檔案(Windows的.obj和Linux的.o)
廣義來說,Object file和可執行檔的格式其實幾乎是一樣的
Object file被分成好幾個塊Section
Code Section:常見的名稱有.code或是.data
用來存放source code編譯過後產生的instruction
Data Section:global variable和local static variable都存放在這邊
(注意: 不包含local variable以及dynamic variable
前者放在程式被load到memory後配置的stack
後者放在程式被load到memory後配置的heap )
Data Section又分成三個部分
1. .data: 放置已初始化的global variable
以及static local variable
2. .bss: 放置未初始化的global variable
以及static local variable,因為他們的值都是零
不需要花額外空間存放零這個值。bss只是為未初始化
的變數預留位置而已
3. .rodata: 放置Read-Only data,比如說加const修飾過
的變數,或是字串常數。ex: printf("%d", a);的%d
char a[] = "abcd"; 中的abcd
ELF layout(http://en.wikipedia.org/wiki/File:Elf-layout--en.svg)
這邊出一個小問題,請問一下code中 x1和x2會被放在什麼區段中
static int x1 = 0; static int x2 = 1;x1會放在.bss中,x2會放在.data中。x1可以被當作未初始化,compiler最佳化之後
會把x1放到.bss中,節省空間,因為.bss不佔空間。另一個變數x2因為已經初始化
為1,所以放在.data區段中。
除了上述這些比較常用的區段外,ELF還有很多預設的區段。甚至我們可以自己定義區段
比如說我們可以在ELF檔中加入一個"music"的區段,裡面存放一首MP3音樂
程式執行時候可以直接讀取這個區段的MP3資料,把資料加入object file
可以使用objcopy這個指令
ELF檔一開始會有個ELF Header,Header最開頭是ELF的magic number
當OS load可執行檔的時候,會去檢查magic number是否正確
如果錯誤就拒絕載入。Header檔接下來包含一些檔案的資訊
比如說是Little-Endian還是Big-Endian、程式開始執行的的進入點
在unix下,可使用readelf來詳細查看ELF檔案
ELF Header有個e_shoff會定義Section Header Table在ELF檔中的位置
Section Header Table明確的定義這個ELF檔各個區段的資訊
內容包含區段的名稱、所佔的長度、在檔案中的位置、以及讀寫權限等屬性
同樣的,可以使用"readelf -S"來查看Section Header Table的內容
ELF檔還有一些重要的Table如下:
Relocation Table: Linker在Link object file檔的時候會需要對
object file的某些地方作relocation
這時候會參考此表進行relocation
Symbol Table: 儲存所有用到的variable以及function的名稱
可以使用nm列出Object file的Symbol Table
其中包含Sysmbol所在區段、以及所在位置等資訊
沒有留言:
張貼留言