ARM-ELF文件格式與GNU ARM Linker機制

這裏所說的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數據結構

相關文章
相關標籤/搜索