ELF结构(主要是符号表)

原文出自 : http://blog.chinaunix.net/uid-8473611-id-3184556.html

1.1.1   整体结构

ELF对象格式用于目标文件(.o扩展名)和执行文件. 有些信息只出现在目标文件或执行文件中.

ELF文件由下列部件构成. ELF header必须放在文件的开始;其他部件可以随便排放(ELF header给出了其他部件的偏移量).

ELF文件构件:

Section

描述

ELF header

一般信息.

Program header table

执行文件信息;只出现在执行文件中.

Section data

Section的实际数据;一些section有特殊的含义,

例如: symbol table和string table.

Section headers

不同ELF section信息; 每个section一个.

典型ELF文件结构:

ELF Header

Program Header Table

Section 1 Data

……

Section n Data

Section Header Table

1.1.2   ELF头[ELF Header]

ELF头包含目标文件的一般信息;具有如下结构(from elf.h):

#define EI_NIDENT 16

typedef struct {

unsigned char e_ident[EI_NIDENT];

Elf32_Half e_e_type;

Elf32_Half e_machine;

Elf32_Word e_version;

Elf32_Addr e_entry;

Elf32_Off e_phoff;

Elf32_Off e_shoff;

Elf32_Word e_flags;

Elf32_Half e_ehsize;

Elf32_Half e_phentsize;

Elf32_Half e_phnum;

Elf32_Half e_shentsize;

Elf32_Half e_shnum;

Elf32_Half e_shstrndx;

};

ELF头域描述:

描述

e_ident

16字节串:   4字节标识: '_ELF'

            1字节class: 32位对象->1

            1字节数据编码: litte-endian->1,big-endian->2

            1字节版本: 当前版本->1

            9字节零填充

e_type

文件类型:   可重定位->1,可执行->2

e_machine

目标体系结构: MC68000&ColdFire->4

e_version

目标文件版本: 设定为1.

e_entry

程序入口地址.

e_phoff

Program Header Table的文件偏移.

e_shoff

Section Header Table的文件偏移.

e_flags

未使用.

e_ehsize

ELF头大小.

e_phentsize

Program Header Table中每条目的大小.

e_phnum

Program Header Table中条目个数.

e_shentsize

Section Header Table中每条目的大小.

e_shnum

Section Header Table中条目个数.

e_shstrndx

包含Section名串表的条目的Section Header索引.

1.1.3   程序头[Program Header]

程序头为一结构数组,每个元素描述执行文件的一个可载入段.

元素结构如下(from elf.h):

     typedef struct {

Elf32_Word p_type;

Elf32_Off p_offset;

Elf32_Addr p_vaddr;

Elf32_Addr p_paddr;

Elf32_Word p_filesz;

Elf32_Word p_memsz;

Elf32_Word p_flags;

Elf32_Word p_align;

     } Elf32_Phdr;

    ELF程序头域描述:

描述

p_type

段类型;linker只使用PT_LOAD(1).

p_offset

段raw数据的文件偏移.

p_vaddr

载入时段在内存中的驻留地址.

p_paddr

未使用.

p_filesz

段在文件中的大小;可以为0.

p_memsz

段在内存中的大小;可以为0.

p_flags

包含如下标志组合的Bit mask:

    PF_X (1) Execute

    PF_W (2) Write

    PF_R (4) Read

p_align

段在内存&文件中的对齐方式.

 

1.1.4   Section Headers

   ELF文件中的每个section的都有激励[incitation]头; Section个数由ELF Header中的e_shnum 域指明. Section headers结构如下(from elf.h):

typedef struct {

Elf32_Word sh_name;

Elf32_Word sh_type;

Elf32_Word sh_flags;

Elf32_Addr sh_addr;

Elf32_Off sh_offset;

Elf32_Word sh_size;

Elf32_Word sh_link;

Elf32_Word sh_info;

Elf32_Word sh_addralign;

Elf32_Word sh_entsize;

} Elf32_Shdr;

   ELF section header域描述:

描述

sh_name

指明section名;可作为section header string表的索引.

sh_type

Section类型:   SHT_NULL(0)       inactive header

              SHT_PROGBITS(1)   程序定义的数据或代码

              SHT_SYMTAB(2)     符号表

              SHT_STRTAB(3)     串表

              SHT_RELA(4)       重定位条目

              SHT_NOBITS(8)     未初始化数据

              SHT_COMDAT(12)    似SHT_PROGBITS

sh_flags

如下标志组合:      SHF_WRITE(1)  包含可写数据

              SHF_ALLOC(2)  包含分配数据

              SHF_EXECINSTR(4)  包含可执行指令

sh_addr

若section将载入内存, section的地址.

sh_offset

Section的raw数据的文件偏移;注意SHT_NOBIT section没有raw数据,它将由操作系统初始化.

Sh_size

Section大小;

即使SHT_NOBITS section未占任何文件空间,也可能非零.

sh_link

连接到其他section头的索引.

       SHT_COMDAT,SHT_NOBITS,SHT_PROGBITS,

    SHT_RELA 符号表; SHT_SYMTAB 串表.

sh_info

包含如下信息:

       SHT_RELA   重定位应用到该section

    SHT_SYMTAB 第一个非本地符号索引

sh_addralign

对齐要求.

sh_entsize

包含固定大小条目的section的条目大小,如符号表.

1.1.5   Special Sections

一些典型section的名和内容解释如下表所示:

名称

内容

.text

机器指令, 常值数据和常值串.

.data

初始化数据.

.sdata

小初始化数据.

.bss

未初始化变量.

.sbss

小未初始化变量.

.comment

Comments from #ident directives in C.

.init

Main()函数之前执行的代码.

.fini

程序执行完成后执行的代码.

.eini

.fini代码的最后指令;.init,.fini和eini section应以序放入内存.

.debug

DWARF格式的符号调试信息.

.line

符号调试的行号信息.

.relaname

Section name的重定位信息.

.shstrtab

Section名.

.strtab

串表for符号表中的符号.

.symtab

包含符号表.

1.1.6   重定位信息[Relocation Information]

重定位信息section包含关于非确定引用[unresolved references]的信息.因为编译器[compilers]和汇编器[assemblers]不知道符号将分配的绝对内存地址,和别的文件的符号定义;所以对符号的每个引用都将创建一个重定位条目. 该条目指向地址(where the reference is being made), 和指向包含被引用符号的符号表. 连接器[linker]给所有符号分配地址之后, 将使用重定位信息添入正确的地址. 执行文件没有重定位section.

例如: 汇编表示符号加上偏移:

    move.l var+16,d0

偏移量存储在r_addend域,这样,符号真实地址加上该地址域将产生一个正确的引用.

    重定位条目有如下结构(from elf.h):

typedef struct {

Elf32_Addr r_offset;

Elf32_Word r_info;

Elf32_Sword r_addend;

} Elf32_Rel;

ELF重定位条目的域描述:

描述

r_offset

Area在当前section的相对地址(to be patched with正确地址).

r_info >> 8

r_info的高24位是符号表的索引;

指向描述在r_offset引用的符号的条目.

r_info & 255

低8位是重定位类型,用来描述寻址模式[绝对|相对,大小].

r_addend

加到符号上的常数,用于计算放在重定位域的值.

1.1.7   符号表

符号表section .symtab为一数组,数组元素包含关于被ELF文件引用的符号的信息.

符号表条目有如下结构(from elf.h):

typedef struct {

ELF32_Word st_name;

ELF32_Addr st_value;

ELF32_Word st_size;

unsigned char st_info;

unsigned char st_other;

Elf32_Half sth_shndx;

} Elf32_Sym;

ELF符号表域说明:

描述

st_name

符号串表索引. 串表用于保存符号名.

st_value

符号值:

符号的section索引为SHN_COMMON:符号对齐要求.

重定位文件:离section起始位置的偏移.

执行文件:符号的地址.

st_size

对象大小.

st_info >> 4

高4位定义符号的绑定[binding ]:

    STB_LOCAL (0) symbol is local to the file

    STB_GLOBAL (1) symbol is visible to all object files

    STB_WEAK (2) symbol is global with lower precedence

st_info & 15

低4位定义符号的类型:

    STT_NOTYPE (0)    无类型

    STT_OBJECT (1)    数据对象(变量)

    STT_FUNC (2)      函数

    STT_SECTION (3)   section名

    STT_FILE (4)      文件名

st_other

未使用.

st_shndx

定义符号sectiond的索引.特殊的section数包括:

    SHN_UNDEF (0x0000)   未定义section

    SHN_ABS (0xfff1)     绝对, 不可重定位符号

    SHN_COMMON (0xfff2) 不分配, 外部变量

1.1.8   串表

串表sections( .strtab.shstrtab) 包含符号表中符号名和section名.名都以null结束. 这些符号通过偏移指向[point into]串表. 串表的第一字节总是零, 其后所有串顺序存放.


猜你喜欢

转载自blog.csdn.net/lonely_devil/article/details/51088761
今日推荐