elf(exective linked file)
elf 格式文件是一種爲 Linux 系統所採用的通用文件格式, 支持動態鏈接和重定位, 有很大的文件頭
flat
flat 格式文件是扁平格式的文件, 對文件頭和一些段信息做了簡化, 可執行程序小, 適於嵌入式系統
文件格式轉換
elf2flt 就是將 elf 格式轉換爲 flt 格式, 在編譯器鏈接的時候可使用 “-elf2flt” 選項直接編譯出 flt 格式的可執行文件
elf 文件的種類
- 可重定位文件(relocatable file), 包括用戶目標文件和其他目標文件(例如 *.o 或 lib*.a), 他們一起用於創建可執行文件或者共享目標文件
- 可執行文件(executable file), 指編譯好的可執行文件(例如 a.out), 用於生成程序映像, 載入內存執行
- 共享目標文件, 指共享庫文件(例如 lib*.so), 用於和其他共享目標文件或者可重定位文件一起生成 elf 目標文件或者和執行文件一起創建程序映像
elf 文件的作用
elf 文件參與程序的鏈接和執行, 所以可以從不同的角度來看待 elf 格式文件的作用
- 如果用於編譯和鏈接(可重定位文件), 則編譯器和鏈接器將把 elf 文件看作是節頭表(section-headers)描述的節的集合, 程序頭表(program-headers)可選
- 如果用於加載執行(可執行文件), 則加載器將把 elf 文件看作是程序頭表(program-headers)描述的段的集合, 一個段可能包含多個節, 節頭表(section-headers)可選
- 如果是共享目標文件, 則兩者都含有, 因爲編譯時需要共享庫中函數的聲明, 程序執行函數調用時也需要執行共享庫中的代碼
elf 文件的組成
elf 文件頭(file-header)描述 elf 文件的總體信息
- 系統相關: elf 文件標識的魔術數, 以及硬件和平臺等相關信息, 增加了 elf 文件的移植性, 使交叉編譯成爲可能
- 類型相關: 可重定向文件, 可執行文件, 共享目標文件
- 加載相關: 程序頭表(program-headers)的相關信息
- 鏈接相關: 節頭表(section-headers)的相關信息
elf 文件的信息查看
- 使用 readelf -S 或 objdump -h 查看程序頭表(段表)
- 使用 readelf -s 或 objdump -t 查看符號表
- 使用 size 命令查看各段大小
table | options | content |
---|---|---|
程序頭表(段表) | -l –program-headers –segments | 顯示程序頭(段頭)信息, 例如記錄 bss 段的大小, 即所有未初始化的變量的總大小 |
節頭表 | -S –section-headers –sections | 顯示節頭信息, 例如記錄 bss 段中每個未初始化的變量的大小 |
符號表 | -s –syms –symbols | 顯示符號表段中的項 |
C 程序鏡像文件
- 連接器(LD)是將所有編譯器和彙編器的輸出文件連接成一個二進制映象文件的工具
- 二進制映象文件有很多種不同格式, 包括: flat, aout, coff, pe, elf 等
無論哪種格式, 鏈接輸出的文件中都會出現三個區域:
- Text(Code) 代碼段, 只讀, 存儲在磁盤鏡像文件中
- Data 初始化數據段, 可讀可寫, 存儲在磁盤鏡像文件中, 舉例來說,你在程序定義了一個變量並給它賦值5,那麼這個“5”就被存儲在 Data 區
- BSS 未初始化數據段, 可讀可寫, 它存儲着未賦任何值的數組, 是一個虛擬的區域, 只記錄大小, 本身不存在於二進制映像中, 當二進制映像被加載後存在於內存中