天天看點

elf檔案格式_ELF 格式詳解(一)

elf檔案格式_ELF 格式詳解(一)
ELF 全稱 “Executable and Linkable Format”,即可執行可連結檔案格式,目前常見的Linux、 Android可執行檔案、共享庫(.so)、目标檔案( .o)以及Core 檔案(吐核)均為此格式。 檔案布局

常見的ELF檔案大緻結構如下:

elf檔案格式_ELF 格式詳解(一)

常見的ELF格式如上圖所示,左邊為連結視圖,右邊為執行視圖。

連結視圖:

靜态連結器(即編譯後參與生成最終ELF過程的連結器,如ld )會以連結視圖解析ELF。編譯時生成的 .o(目标檔案)以及連結後的 .so (共享庫)均可通過連結視圖解析,連結視圖可以沒有段表(如目标檔案不會有段表)。

執行視圖:

動态連結器(即加載器,如x86架構 linux下的 /lib/ld-linux.so.2或者安卓系統下的 /system/linker均為動态連結器)會以執行視圖解析ELF并動态連結,執行視圖可以沒有節表。

檔案頭

ELF的結構聲明位于系統頭檔案 elf.h 中,ELF格式分為32位與64位兩種,除了重定位類型稍有差別,其它大緻相同,為了簡化描述,後續說明将省略32/64字樣。

ELF Header的聲明如下 :

#define EI_NIDENT (16)
typedef struct
{
    unsigned char	e_ident[EI_NIDENT];	/* Magic number and other info */
    Elf_Half		e_type;			/* Object file type */
    Elf_Half		e_machine;		/* Architecture */
    Elf_Word	        e_version;		/* Object file version */
    Elf_Addr		e_entry;		/* Entry point virtual address */
    Elf_Off		e_phoff;		/* Program header table file offset */
    Elf_Off		e_shoff;		/* Section header table file offset */
    Elf_Word	        e_flags;		/* Processor-specific flags */
    Elf_Half		e_ehsize;		/* ELF header size in bytes */
    Elf_Half		e_phentsize;		/* Program header table entry size */
    Elf_Half		e_phnum;		/* Program header table entry count */
    Elf_Half		e_shentsize;		/* Section header table entry size */
    Elf_Half		e_shnum;		/* Section header table entry count */
    Elf_Half		e_shstrndx;		/* Section header string table index */
} Elf_Ehdr;
           
e_ident
包含了Maigc Number和其它資訊,共16位元組。	
0~3:前4位元組為Magic Number,固定為ELFMAG。
4(EI_CLASS):ELFCLASS32代表是32位ELF,ELFCLASS64 代表64位ELF。
5(EI_DATA):ELFDATA2LSB代表小端,ELFDATA2MSB代表大端。
6(EI_VERSION):固定為EV_CURRENT(1)。
7(EI_OSABI):作業系統ABI辨別(實際未使用)。
8(EI_ABIVERSION):ABI版本(實際 未使用)。
9~15:對齊填充,無實際意義。
           
e_type
ELF的檔案類型,定義如下:
     ET_REL		可重定位文 件(如目标檔案)
     ET_EXEC	        可執行檔案(可直接執行的檔案)
     DT_DYN	        共享目标檔案(如SO庫)
     DT_CORE	        Core檔案(吐核檔案)
注:GCC使用編譯選項 -pie 編譯的可執行檔案實際 也是DT_DYN類型。
           

e_machine

e_verison

檔案版本,目前常見的ELF 檔案版本均為EV_CURRENT(1)。

e_entry

入口虛拟位址。

e_phoff

段表檔案偏移。

e_shoff

節表檔案偏移。

e_flags

處理器特定的标志,一般為0。

e_ehsize

Elf_Header的大小(位元組)

e_phentsize

段頭(Program Header)的大小(位元組)。

e_phnum

段的數量。

e_shentsize

節頭(Section Header)的大小(位元組)。

e_shnum

字的數量。

e_shstrndx

節字元串表的節索引。

更多技術相關文章:Virbox技術部落格