各种讲解elf文件格式一上来就是各种数据类型,看了半天却不知道这些数据类型是干啥的,所以咱就先找个例子直接上手,这样对elf文件格式有个具体而生动的了解。
然后再去看那些手册,就完全不惧了~。
我们使用一个汇编程序max.s并对其进行编译链接产生的两个elf文件来对比分析elf文件。
例子程序max.s来自《Linux C 一站式编程》。
ps:这是一本看完可以真正可以深入理解C语言精华的书,涵盖面极广,上到数据结构、linux系统、网络通信,下到编译链接、汇编语言、内存寻址。真的很好的哦亲。
汇编程序max.s用于取一组正整数的最大值,使用的是AT&T语法,程序源代码如下
.section .data
data_items:
.long 3,67,34,222,45,75,54,34,44,33,22,11,66,0
.section .text
.globl _start
_start:
movl $0, %edi
movl data_items(,%edi,4), %eax # data_items+ 4*(edi) --> eax
movl %eax, %ebx # (eax) --> ebx
start_loop: # ebx store the max value
cmpl $0, %eax
je loop_exit
incl %edi
movl data_items(,%edi,4), %eax # data_items+ 4*(edi) --> eax
cmpl %ebx, %eax
jle start_loop # eax <= ebx
movl %eax, %ebx # eax > ebx
jmp start_loop
loop_exit:
movl $1, %eax # exit system call.
int $0x80
程序解释:
在源代码中定义了2个section,一个是section名字叫.data,另一个section叫.text, 声明了_start为全局的符号。
在.data section中定义了一个符号data_items,在.text section中定义了3个符号_start 、 start_loop、loop_exit。其中 _start符号被定义为全局符号。
程序逻辑也很简单,依次遍历数组并比较就得出了最大值,将最大值存储在ebx中,最后使用系统调用退出。
编译$as -o max.o max.s
链接
$ld -o max max.o
执行并测试程序
$./max
$echo $?
222
222就是max.s运行返回的最大值。
下面先来分析编译出的max.o文件
$ du -b max.o
704 max.o #此elf文件大小为704B
$ readelf -a max.o #读取elf文件
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: REL (Relocatable file)
Machine: Intel 80386 #运行机器
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 200 (bytes into file) #section headers table在文件中的偏移
Flags: 0x0
Size of this header: 52 (bytes) #elf header在文件中占了52个字节
Size of program headers: 0 (by