這裏所說的ARM系統基本文件格式,都是在基於ARM的嵌入式系統開發中常會碰到的文件格式。
ARM系統基本文件格式有三種:
1) BIN,平板式二進制格式,通常用於直接燒寫到Flash中,也能夠用於加載到monitor程序中。
2) ELF,EXECUTABLE AND LINKABLE FORMAT,一種通用的OBJECT文件格式,通常由GNU COMPILER COLLECTION (GCC)產生。
3) AXF,BIN格式的擴展版,主體部分同BIN,在文件頭和尾加入了調試用的信息,用於AXD。
本文主要討論BIN與ELF。
首先說明,ELF格式是一種OBJECT文件格式。通常OBJECT文件均可以分紅三類:可重定位OBJECT文件,可執行OBJECT文件,共享OBJECT文件。ELF格式文件也能夠分紅這三種。
首
先說說可重定位OBJECT文件。這種OBJECT文件通常由GCC中的ASSEMBLER(as)產生(請不要認爲GCC只是編譯器),裏面除了二進制
的機器代碼,還有一些可用於進行重定位的信息。它主要是做爲LINKER(ld)的輸入,LINKER將跟據這些信息,將須要重定位的符號重定位,進而產
生可執行的OBJECT文件。ELF格式的可重定位OBJECT文件由header與section組成。
Header 包括
ELF header 與 section header. ELF header 位於文件的頭部,用於存儲目標機器的架構,大小端配
置,ELF header大小,object文件類型,section header 在文件中的偏移,section header 的大
小,section header 中的項目數等信息。Section header 則定義了文件中每一個section 的類型,位置,大小等信息。
Linker就是經過查找ELF header,找到section header 的入口,再在section header 中找到相應的
section 入口,進而定位到目標section 的。
Section 包括
.text :通過編譯的機器代碼。
.rodata :只讀的數據,例如printf(「hello!」)中的字符串hello。
.data :已初始化的全局變量,局部變量將在運行時被存放在堆棧中,不會在.data或 .bss段中出現。
.bss :未初始化的全局變量,在這裏只是一個佔位符,在object文件中並無實際的存儲空間。
.symtab :符號表,用於存放程序中被定義的或被引用到的全局變量和函數的信息。
.rel.text :
一個保存着一系列在.text中的位置的列表。這些位置將在linker把這個文件與其它object文件合併時被修改,通常來講,這些位置都是保存着一
些引用到全局變量或者外部函數的指令。引用局部變量或者本地函數的指令是不須要被修改的,由於局部變量和本地函數的地址通常都是使用PC相對偏移地址的。
須要注意的是,這個section 和下面的.rel.data在運行時並不須要,生成可執行的ELF object文件時會去掉這個section。
.rel.data :保存全局變量的重定位信息。通常來講,若是一個全局變量它的初 始化值是另外一個全局變量的地址,或者是外部函數的地址,那麼它就須要被重定位。
.debug :保存debug信息。
.strtab : 一
個字符串表,保存着.symtab和.debug ,和各個section的名字。.symtab,.debug 和section table裏面,凡
是保存name的域,其實都是保存了一個偏移值,經過這個偏移值在這個字符串表裏面能夠找到相應得字符串。
下面仔細討論一下.symtab:
每個可重定位的object文件,都會有一個.symtab。這個符號表保存了在這個object文件中全部被定義的和被引用的符號。當源程序是C 語言程序時,.symtab 中的符號直接來源於C編譯器(cc1)。這裏所說的符號主要有三種:
1) 在這個object文件中被定義的能夠被其餘object文件全局符號。在C語言源程序中,主要就是那些非靜態(沒有static 修飾的)的全局變量和非靜態的函數。在ARM彙編語言中,就是那些 被EXPORT 指令導出的變量。
2) 在這個object文件中引用到,可是在其餘文件中定義的全局變量。在ARM彙編語言中就是經過IMPORT命令引入的變量
3) 本
地變量。本地變量只在本object文件內可見。這裏的本地變量指的是鏈接器本地變量,應該和通常的程序本地變量做區別。這裏所指的本地變量,包括用
static 修飾的全局變量,object文件中section名稱,源代碼文件名稱。通常意義上的本地變量,是在運行時由系統的運行時環境管理
的,linker並不關心。
每一個符合上面條件的符號在.symtab文件中都會有一個數據項。這個數據項的數據結構是:
Typedef struct{
int name;//符號名稱,其實就是.strtab的偏移值
int value;//在section中的位置,以相對section地址的偏移表示
int size;//大小
char type;//類型,通常是數據或函數
char binding;//是本地變量仍是全局變量
char reserved;//保留的位
char section;//符號所屬的section。可選有:.text(用數字1表明),.data(用數
//3表明),ABS(不該被重定位的符號),UND(在本object文件
//中未定義的符號,可能在別的文件中定義),COM(通常的未初//始化的變量符號)。
}ELF_sym數據結構