ELF文件的格式和加载过程
(一) ELF 文件的格式
????? ELF 文件類型 (1) 可重定位文件( .o 目標(biāo)文件) : 用于鏈接創(chuàng)建可執(zhí)行文件或 so 文件
??????????????????????????? (2) 可執(zhí)行文件 ????? ????????????? : 用于執(zhí)行
??????????????????????????? (3)so( 共享對(duì)象 ) 文件 ?????????? : 用于鏈接
??????
?????? 注 :?? 一個(gè) Program Header 對(duì)應(yīng)一個(gè) Segment
?????? ?? ? 一個(gè) Section Header 對(duì)應(yīng)一個(gè) Section
????????????? Segment 由 Section 構(gòu)成
?
Segment 類型 :#define PT_NULL???????? 0??????????? ?????? unused
#define PT_LOAD ??????? 1??????????? ?????? 可加載段 ( 代碼節(jié)和數(shù)據(jù)節(jié) )
#define PT_DYNAMIC 2??????????? ?????? 動(dòng)態(tài)鏈接段 ( 動(dòng)態(tài)鏈接信息 )
#define PT_INTERP ????? 3??????????? ?????? 解釋器段 ( 動(dòng)態(tài)鏈接器路徑 )
#define PT_NOTE???????? 4??????????? ?????? auxiliary information
#define PT_SHLIB 5??????????? ????????????? reserved - purpose undefined
#define PT_PHDR???????? 6??????????? ?????? program header
#define PT_NUM????????? 7??????????? ?????? Number of segment types
#define PT_LOOS???????? 0x60000000??? reserved range for OS
#define PT_HIOS????????? 0x6fffffff?????? ?????? specific segment types
#define PT_LOPROC??? 0x70000000??? reserved range for processor
#define PT_HIPROC???? 0x7fffffff?????? ?????? specific segment types
?
Section 類型 : ? #define ELF_BSS??????? ?? ".bss"???????????? uninitialized data
#define ELF_DATA?????? ?? ".data "?????????? 數(shù)據(jù)節(jié) initialized data
#define ELF_DEBUG???? ?? ".debug"? ?????? debug
#define ELF_DYNAMIC?? ? ".dynamic "? 動(dòng)態(tài)鏈接節(jié) dynamic linking information
#define ELF_DYNSTR ".dynstr"? ?????? dynamic string table
#define ELF_DYNSYM ?????? ".dynsym"????? dynamic symbol table
#define ELF_FINI??? ???????? ".fini"???????????? termination code
#define ELF_GOT??????? ? ".got"???????????? global offset table
#define ELF_HASH?????? ? ".hash"?????????? symbol hash table
#define ELF_INIT??????? ? ".init"???????????? initialization code
#define ELF_REL_DATA?? ? ".rel.data"?????? relocation data
#define ELF_REL_FINI??? ".rel.fini"? ?????? relocation termination code
#define ELF_REL_INIT??? ".rel.init"? ?????? relocation initialization code
#define ELF_REL_DYN?? ?? ".rel.dyn" ?????? relocaltion dynamic link info
#define ELF_REL_RODATA? ".rel.rodata"??? relocation read-only data
#define ELF_REL_TEXT?? ".rel.text" ?????? relocation code
#define ELF_RODATA???? ".rodata"? ?????? read-only data
#define ELF_SHSTRTAB?? ".shstrtab"?????? section header string table
#define ELF_STRTAB???? ? ".strtab"?? ?????? string table
#define ELF_SYMTAB??? ?? ".symtab"?????? ?????? symbol table
#define ELF_TEXT?????? ? ".text "??????????? 代碼節(jié) code
?
?
?
?
(二) ELF 文件的加載過程
源文件 Trunk/System/ElfLoader/dll/elfloader.c
LoadElfExec() 函數(shù)
?
加載的具體過程
1. 打開文件 open_library(char* filename)
?????? 系統(tǒng)調(diào)用 open(): 創(chuàng)建 File 結(jié)構(gòu)體 , 放入進(jìn)程打開文件表 , 返回 ( 打開文件表 ) 下標(biāo)
2. 讀出文件頭和程序頭表 IsElfFormat(FILE)
?????? 讀出 ELF 文件頭 ( 同時(shí)讀出了程序頭表 Program Header Table), 判斷 ELF 格式根據(jù)文件頭中的 e_ident 來比較判斷 .
3. 加載文件 load_library(char * filename,int fd)
?????? (1) 計(jì)算所有 segment 占用內(nèi)存大小 get_lib_extents()
通過遍歷程序頭表 (Program Header Table), 算出所有 segment 將占用的內(nèi)存大小 extents_size
(2) 分配內(nèi)存 alloc_mem_region(extents_size)
?????? 匿名映射一塊非共享的私有內(nèi)存 ( 不涉及文件 )
(3) 分配 soinfo 結(jié)構(gòu)體 alloc_info(char *filename)
?????? 從全局靜態(tài) soinfo 結(jié)構(gòu)體數(shù)組中分配 soinfo 結(jié)構(gòu)體 ( 描述整個(gè) ELF 文件 )
(4) 加載 segment
load_segment(int fd,void* header,soinfo*si)
(1) 可加載段 (PT_LOAD): 映射到內(nèi)存
mmap(void * start,size_t len, int prot,int flags,int fd,off_t offsize)
把 ELF 文件 offsize 處的 segment 映射到已分配內(nèi)存的 start 處
????????????? (2) 動(dòng)態(tài)鏈接段
???????????????????? 由動(dòng)態(tài)鏈接節(jié)設(shè)置 soinfo 中的動(dòng)態(tài)鏈接信息
?????? (5) 設(shè)置 soinfo 結(jié)構(gòu)體
4. 加載依賴的動(dòng)態(tài)鏈接庫
5.重定位(自身符號(hào))
?? 重定位表項(xiàng):?? Elf32_Addr???? r_offset?? (重定位)內(nèi)存地址(offset of relocation)
?????? ???????????????????? Elf32_Word??? r_info????? 符號(hào)表下標(biāo)和類型(symbol table index and type)
??????
?? 符號(hào)表項(xiàng):????? Elf32_Word??? st_name? 符號(hào)名(name - index into string table)
?????? ???????????????????? Elf32_Addr???? st_value?? 符號(hào)值(symbol value)
?????? ???????????????????? Elf32_Word??? st_size???? ???? ?????? symbol size
?????? ???????????????????? unsigned char st_info??? ?????? ?????? type and binding
?????? ???????????????????? unsigned char st_other?? ???? ?????? 0 - no defined meaning
?????? ???????????????????? Elf32_Half????? st_shndx;????????????? ?????? section header index
?
?????? 根據(jù)重定位表(表項(xiàng))查符號(hào)表,得到符號(hào)內(nèi)存地址,修改(重定位)內(nèi)存值
?
最后得到soinfo結(jié)構(gòu)體數(shù)組描述了所有加載的文件
6.如果入口地址不為零,調(diào)用入口函數(shù)
?
?
?
?
總結(jié)
以上是生活随笔為你收集整理的ELF文件的格式和加载过程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 内存映射(mmap系统调用)
- 下一篇: css盒模型和元素绘制