一 点睛
ELF是一种用于二进制文件、可执行文件、目标代码、共享库和核心转储的标准文件格式。
ELF标准的目的是为软件开发人员提供一组二进制接口定义,这些接口可延伸到多种操作系统中,从而减少重新编码、编译程序的需要。
ELF指的是一种文件格式,常用的扩展名为:o,so,elf,prx
二 ELF文件组成部分
ELF文件由4部分组成:
- ELF头(ELF header)
- 程序头表(Program header table)
- 节(Section)
- 节头表(Section header table)
实际上,一个文件中不一定包含全部内容,而且他们的位置也未必如同所示这样安排,只有ELF头的位置是固定的,其余各部分的位置、大小等信息由ELF头中的各项值来决定。
三 ELF文件类型
有三种文件类型
1 可重定位的目标文件
由汇编器汇编生成的.o文件。
参考:
2 可执行文件
链接器拿一个或多个可定位的目标文件作为输入,经链接处理后,生成一个可执行的目标文件。
3 可被共享的目标文件
就是所谓的动态库文件,也即.so文件。
动态库发挥作用的过程必须经过两个步骤:
步骤一:链接器拿动态库和其他可重定位的文件(.o文件)以及其他.so文件作为输入,经过链接后,生成另外的可共享的目标文件(.so)或者可执行的目标文件。
步骤二:在运行时,动态链接器拿它和一个可执行的目标文件以及另外一些可共享的目标文件一起处理,在Linux系统中创建一个进程映像。
四 ELF对象文件组成
有两种视图来说明ELF的组成格式
链接视图 | 执行视图 |
ELF头部 | ELF头部 |
程序头部表(可选) | 程序头部表 |
节区1 | 节区1 |
... | ... |
节区n | 节区n |
... | ... |
... | ... |
节区头部表 | 节区头部表(可选) |
表中展示了左右两个很类似的部分来说明ELF的组成格式。为什么需要两种格式呢?这是因为ELF格式需要使用在两种场景:
场合一:组成不同的重定位文件,以参与可执行文件或者可被共享的对象文件的链接构建。
场合二:组成可执行文件或者可被共享对象文件,以在运行时内存中进程映像的构建。
所以,基本上,表中左边部分表示的是可重定位文件的格式,而右边是可执行文件以及可被共享的对象文件的格式。ELF文件头被固定地放在不同类对象文件的最前面。因此,可以用file命令来看文件是属于哪种ELF文件
五 实战
1 生成各类文件
# 生成add.o和sub.o
g++ -c add.cpp
g++ -c sub.cpp
ar cr libmymath.a sub.o add.o
# 生成main
g++ -o main main.cpp -L.lmymath
# 生成libmymath.so
g++ -fPIC -shared -o libmymath.so add.cpp sub.cpp
2 查看add.o、sub.o、main、libmymath.so属于哪种ELF
[root@localhost 0401]# ll
total 52
-rw-r--r--. 1 root root 62 May 11 11:35 add.cpp
-rw-r--r--. 1 root root 66 May 11 11:34 add.h
-rw-r--r--. 1 root root 1248 May 11 11:26 add.o
-rw-r--r--. 1 root root 2714 May 11 11:42 libmymath.a
-rwxr-xr-x. 1 root root 7928 May 11 11:50 libmymath.so
-rwxr-xr-x. 1 root root 9312 May 11 11:48 main
-rw-r--r--. 1 root root 230 May 11 11:40 main.cpp
-rw-r--r--. 1 root root 61 May 1 08:52 sub.cpp
-rw-r--r--. 1 root root 67 May 1 08:52 sub.h
-rw-r--r--. 1 root root 1248 May 11 11:26 sub.o
# 查看add.o、sub.o、main、libmymath.so的内容
[root@localhost 0401]# file add.o sub.o libmymath.so main
add.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
sub.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
libmymath.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=ce377dde3db662656e8c82c87bb205a883fac582, not stripped
main: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=7983836b44944a18e597635b8088d2926167e671, not stripped
add.o sub.o是可重定位文件。
libmymath.so是可被共享文件。
main是可执行文件。