一.知识储备
1.目标文件概述
目标文件是按照特定的目标文件格式来组织的,各个系统的目标文件格式都不同。现代x86-64 Linux和Unix系统使用可执行可链接格式——ELF,且有以下三种形式:
- 可重定位目标文件
- 可执行目标文件
- 共享目标文件
接下来的主题就是讲解两种视图下的ELF文件的格式
2.需要用到的命令
ps:对于linux系统内的命令,可以用man 命令名称来查看相应文档!
这里用到的查看命令是readelf,其相应的文档可用“ man readelf" 查看。
摘抄用到的命令:
readelf -h
readelf -S
readelf -t
readelf -l
二.查看目标文件
1.文件视图
要查看文件有两种视图:ELF的链接视图和ELF的执行视图,分别对应可重定位的目标文件
和可执行的目标文件,
1)ELF的链接视图
2)ELF的执行视图
2.代码素材+可执行文件生成
C程序1:main.c
/* main.c */
/* $begin main */
int sum(int *a, int n);
int array[2] = {1, 2};
int main()
{
int val = sum(array, 2);
return val;
}
/* $end main */
C程序2:sum.c
/* sum.c */
/* $begin sum */
int sum(int *a, int n)
{
int i, s = 0;
for (i = 0; i < n; i++) {
s += a[i];
}
return s;
}
/* $end sum */
命令:
gcc -c main.c -o main.o
gcc -c sum.c -o sum.o
gcc -static -o progc main.o sum.o
3.命令使用
1)链接视图下的可重定位目标文件
使用readelf -h main.o查看该文件头的信息
文件内容:
1.Magic是一个16字节的数组,前面的四个字节为魔数(确定文件类型或格式):为7f 45 4c 46(不同平台下的目标文件魔数不一样,Unix下的a.out格式的魔数为:01H 07H,Windows下的PE格式的魔数为4DH 5AH)
可以用魔数来确认文件类型是否正确
2.类别:ELF64
3.main.o的格式类别是64位版本的,数据采用补码(带符号数)和小端形式
4.版本为1
5.操作系统是UNIX-System V
6.版本类型为REL(可重定位文件)
7.系统架构::Advanced Micro Devices X86-64
8.程序头起点: 0 (bytes into file)(因为这是一个可重定位文件,不是可执行的)
9.Start of section headers: 696 (bytes into file)指定节头表的偏移地址(下面可以用命令来看的)
10.Size of this header: 64 (bytes)(这个ELF头的大小为64字节)
11.Size of section headers: 64 (bytes) 节头表中每个节的大小
12.Number of section headers: 12 节头表中节的数量
13.Section header string table index: 11 .strtab在节头表中的索引位置
用readelf -S main.o命令来读节头表信息:
和ELF头给出的信息一致,节头表中有12个节!(可结合ELF链接视图和节头表中每项的名称查看具体的节)
每个节给出了:”名称 类型 地址 偏移量 大小 全体大小 旗标 链接 信息 对齐 “ 等信息,每一个表象就是64个字节的数据结构!
具体结构如下:(32位系统)
分析:.strtab这个表项的号为10,说明在节头表的第11项,符合前面结果
2)执行视图下的可执行目标文件
使用readelf -h progc查看可执行目标文件的头(这里的progc是我的一个可执行文件的名称)
注意到可执行文件的格式图,与可重定位文件的格式区别不大,但是有一点区别!
其中:
1.ELF头中的 ”入口点地址:”给除了具体的地址0x401ac0(因为它是可执行的,无需重定位ie可被加载到内存)
2.多了 程序头表,也称段头表,是一个结构数组。
3.多了.init节节,用来定义_init函数,可用于进行可执行文件开始执行时的初始化工作
使用readelf -S progc查看可执行目标文件的节头表(这里的progc是我的一个可执行文件的名称)
这里没有截全,因为通过看ELF头,可知这里有29个节。
使用:readelf -l progc 查看程序头部表
注:
offset:目标文件中的偏移
VirtAddr:虚拟地址
PhysAddr:物理地址
FileSiz:目标文件中的段的大小
MemSiz :内存中的段大小
Flags Align:对齐方式
本博客中部分ppt演示照片引用自中国大学mooc南京大学袁春风老师的ppt
参考资源:
1.中国大学MOOC袁春风的《计算机系统基础(一)》
2.书籍:机械工业出版社——《深入理解计算机系统》