可重定位的ELF文件

ELF文件主要有三种类型: (1)可重定位文件包含了代码和数据.可与其它ELF文件建立一个可执行或共享的文件. (2)可执行文件时可直接执行的程序. (3)共享目标文件包括代码和数据.  
这里主要分析一下第1种ELF的文件格式,这东西主要由ELF文件头和具体的各个节区组成.我们
可以通过readelf命令来详细查看ELF文件的各个节区.下面简要介绍一下各个部分的结构
1.ELF文件头
  内核中对ELF文件头 的结 构(32位机)定义在include/linux/Elf.h中

#define EI_NIDENT    16

typedef struct elf32_hdr{

  unsigned char    e_ident[EI_NIDENT];

  Elf32_Half    e_type;
  Elf32_Half    e_machine
;
  Elf32_Word    e_version
;
  Elf32_Addr    e_entry
; /* Entry point */
  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;
} Elf32_Ehdr;

  ELF文件头用来描述整个文件的组织,对可重定位的目标文件而言重要的字段有:文件类型
( e_type) ,节区头部偏移( e_shoff ),文件头大小(e_ehsize),节区头部表表项的大小
(e_shentsize),表项的个数(e_shnum),以及链接的字符节区的索引(e_shstrndx)等信息


2.各个节区
 A.节区头部表
 节区头部表中包含若干个表项,每一个表项都是对本ELF文件中的某个节区的描述,
下面是内核中定义的节区头部表项的数据结构

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

  其中sh_name是被描述的节区的名字,这个值实际是 字符串节区的索引,可以理解为指向
实际的名字的指针;sh_type是节区的类型,一般有字符串节区,符号节区,重定位节区等;sh_flags
示的是节区中包含的内容是修改(SHF_WRITE),执行(SHF_EXECINSTR)或分配空间
(SHF_ALLOC); sh_offset和sh_size是定位被描述的节区在此ELF文件中的位置和大小;sh_link一般
表示被描述的节区需要链接的其他节区的索引,这个字段和sh_info一样根据具体的节区被用于表示不
同的含义.


 B.字符串表 (sh_type=SHT_STRTAB)
 此节区 就是把ELF中将要用到的字符串以'\0'分隔,存到一个连续的区域而成的.
其他节区中需要表示字符串时 一律用字符串表的索引来表示.值得注意的是字符串表可能有多个,因
此其他节区在引用字符串时不只要提供表内的索引,而且还需要提供表的索引.

 C.符号表(sh_type=SHT_SYMTAB)
 ELF文件为符号表由一个个符合表项构成,每个符号表项用来定位重定位程序中
符号定义引用的信息,符号表项数据结构如下
 

typedef struct elf32_sym{
  Elf32_Word    st_name
;
  Elf32_Addr    st_value
;
  Elf32_Word    st_size
;
  unsigned char st_info
;
  unsigned char st_other
;
  Elf32_Half    st_shndx
;
} Elf32_Sym


/*st_info*/

#define ELF32_ST_BIND(x) ((x) >> 4)

#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf)

  其中,st_name是符号名,如前所述他是某个字符串表的表内索引,st_value可能是符号关
联的取值,有可能是符号的地址或符号的值;st_size应该就是符号 相关的尺寸大小,8位的st_info中
储存着两个信息.高4位名曰绑定信息 主要是描述的是符号是全局的(STB_GLOBAL),局部的
(STB_LOCAL),弱符号(STB_WEAK) 还是程序自定义的.低4位是符号的类型 主要描述的是这个符号是
变量(STT_OBJECT),函数(STT_OBJECT)还是其他类型的符号.

 D.重定位表
 重定位表中的每个表项都包含了如何修改某个目标项的信息,一般,同一个重定位表中的表
项都是描述同一个节区中符号的修改信息.下面是重定位表项的数据结构:

typedef struct elf32_rel {
  Elf32_Addr    r_offset
;
  Elf32_Word    r_info
;
} Elf32_Rel
;

typedef struct elf32_rela{
  Elf32_Addr    r_offset
;
  Elf32_Word    r_info
;
  Elf32_Sword   r_addend
;
} Elf32_Rela

 

/* The following are used with relocations */

#define ELF32_R_SYM(x) ((x) >> 8)

#define ELF32_R_TYPE(x) ((x) & 0xff)

 

  其中,r_offset表示的 是从 节区头部开始到将被重定位影响的存储单位之间的字节偏移 即
指明了重定位操作的实施位置;r_info也包含两个信息 一为重定位类型(低8位) 即指明了重定位操作
的方法,二为被实施重定位的符号索引(高24位) 即指明了操作的实施对象.下表是x86结构下重定位操
作的类型和说明.

 x86体系结构下重定位类型

名称

数值

字段

计算

说明

R_386_NONE

0

()

()

R_386_32

1

word32

S+A

R_386_PC32

2

word32

S+A-P

R_386_GOT32

3

word32

G+A-P

此重定位类型计算从全局偏移表基址到符号的全局偏移表项之间的距离。它会通知连接编辑器构造一个全局偏移表。

R_386_PLT32

4

word32

转载于:https://my.oschina.net/alphajay/blog/4957

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值