ELF文件——动态链接

本文详细介绍了ELF文件格式,重点讲解了ELF Header、Section Header Table、Program Header Table在链接器和加载器中的作用。动态链接部分阐述了动态链接的过程,包括动态库的搜索路径、动态符号表、重定位表项以及PLT和GOT在符号查找和重定位中的角色。文章最后提及动态链接的两种模式:立即绑定和延迟绑定。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

下文所示案例为运行在armV7架构、linux平台之下的动态库文件。

ELF文件格式

链接器以ELF文件的固定格式对目标程序进行链接,程序加载器以ELF文件的固定格式对其进行解析。ELF文件的组成框架在链接器和加载器的视角中分别如下:
ELF文件格式
如上图所示,链接器以section为单位对数据进行组织,以section header table对section进行描述,而忽略program header table中的内容;加载器以segment为单位对数据进行组织,以program header table对segment进行描述,而忽略section header table中的内容。其中,加载器中的segment实际由单个或多个链接器中的section组成。ELF文件包含三种类型:可重定位文件(relocatable)—编译器和汇编器产生的.o文件,被Linker所处理;可执行文件(executable)—Linker对.o文件进行处理输出的文件,进程映像;共享对象文件(shared object)—动态库文件.so。

ELF Header

通过readelf工具,查看ELF Header中的内容如下:

ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Shared object file)
  Machine:                           ARM
  Version:                           0x1
  Entry point address:               0x2154
  Start of program headers:          52 (bytes into file)
  Start of section headers:          660064 (bytes into file)
  Flags:                             0x5000400, Version5 EABI, hard-float ABI
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         8
  Size of section headers:           40 (bytes)
  Number of section headers:         38
  Section header string table index: 37

ELF Header记录了该文件的基本信息:该文件类型为动态库文件;程序入口地址为0x2154(偏移),Program Header Table位于文件偏移量为52字节处,包含8个program header,每个program header占用32个字节描述一个segment;Section Header Table位于文件偏移量为660064字节处,包含38个section header,每个section header占用40个字节,用于描述对应的section;section header string table 对应的section header 在Section Header Table中的索引为37(即最后一个,索引值从0开始),该section为记录了各个section名称的符号表。

Section Header Table

Section Header Table中每个section header由如下结构体进行描述:

typedef struct {
	Elf32_Word sh_name; //section 名称,为section header string table的一个偏移量,在该偏移量处保存的以‘\0’结束的字符串即为该section的名称
	Elf32_Word sh_type; //section 类型,不同的section类型保存有不同的数据,
	Elf32_Word sh_flags; //section 属性标志
	Elf32_Addr sh_addr; //section 地址,该section映射到虚拟地址空间的地址,该地址也是文件加载的虚拟地址的偏移
	Elf32_Off sh_offset; //section 偏移,该section在elf文件中的偏移量,为物理偏移,sh_addr可以理解为虚拟地址偏移
	Elf32_Word sh_size; //section 大小
	Elf32_Word sh_link; //与sh_info一样,对于不同的section有不同的含义,但是一般是指本section引用到的section的索引
	Elf32_Word sh_info;
	Elf32_Word sh_addralign; //section 地址对齐
	Elf32_Word sh_entsize; //当section为一个table表时,记录该table表中每一个entry的大小
} Elf32_Shdr;

通过readelf工具查看该文件的Section Header Table,其内容如下:

There are 38 section headers, starting at offset 0xa1260:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .note.gnu.build-i NOTE            00000134 000134 000024 00   A  0   0  4
  [ 2] .gnu.hash         GNU_HASH        00000158 000158 000144 04   A  3   0  4
  [ 3] .dynsym           DYNSYM          0000029c 00029c 0007a0 10   A  4   3  4
  [ 4] .dynstr           STRTAB          00000a3c 000a3c 000c0b 00   A  0   0  1
  [ 5] .gnu.version      VERSYM          00001648 001648 0000f4 02   A  3   0  2
  [ 6] .gnu.version_r    VERNEED         0000173c 00173c 000130 00   A  4   6  4
  [ 7] .rel.dyn          REL             0000186c 00186c 000140 08   A  3   0  4
  [ 8] .rel.plt          REL             000019ac 0019ac 0002f8 08  AI  3  22  4
  [ 9] .init             PROGBITS        00001ca4 001ca4 00000c 00  AX  0   0  4
  [10] .plt              PROGBITS        00001cb0 001cb0 0004a4 04  AX  0   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值