1、编译过程
预处理(预编译 .i)—> 编译(.s) —> 汇编(.o) —> 链接(可执行文件 .a .so)
命令
预编译
gcc -E hello.c -o hello.i
cpp hello.c > hello.i
编译
gcc -S hello.c -o hello.s
gcc -S hello.i -o hello.s
汇编(获取ELF文件)
as hello.s -o hello.o
gcc -c hello.s -o hello.o
gcc -c hello.c -o hello.o
链接
ld -static a.o b.o … # -static表示静态链接,默认ld使用动态链接
静态链接 动态链接
2、编译器 (需要学习编译原理)
3、目标文件
3.1、目标文件 .o,目标文件包括.o文件和库文件(静态库、动态库)
3.2、目标文件格式,使用file命令可以看到目标文件格式
file foobar.o
3.3、目标文件 section
可执行文件、可重定位文件(.o文件)、共享目标文件(动态库、静态库)、核心转储文件(core dump file)都是ELF文件
.text section
.data section
.bss section
命令
objdump -h SImpleSection.o # 查看SimpleSection.o目标文件的结构,各个section的空间布局 -h header(查看section头)
objdump -s -d SimpleSection.o # -s将所有section以16进制形式打印出来,-d反汇编
objdump -x SimpleSection.o # -x 打印详细信息
readelf -h SimpleSection.o # -h 查看文件ELF header,ELF header里面是文件的基本信息
readelf -S SimpleSection.o # -S 查看ELF文件section信息,显示的是各个段的布局以及基本信息
3.4、 section和section之间是有空隙的(字节对齐的缘故)
3.5、 ELF 文件的section只有在编译和链接的时候才有意义,装载的时候是不看section的,只看可执行文件的访问权限(只读页面,可读可写页面。。。)
3.6、重定位section
readelf -S 查看如果有 rel.text,说明rel.text是一个section,同时是.text的重定位表,在链接之后重定位
rel.xxx都是可重定位表,链接的时候使用,比如在调用函数的地方需要重定位到函数的定义位置
3.7、符号表 弱符号强符号
3.8、调试信息
strip # strip命令可以去掉ELF中的调试信息,是不是strip可以把debug文件编程release文件?
3.9 链接
ld a.o b.o -e main -o ab # -e main表示将main作为程序入口;ld链接器默认程序入口是_start
链接二步:
step1:空间与地址分配
step2:符号解析与重定位
重要!!目标文件&可执行文件&进程空间 映射关系
C08B40F2-1AB1-4135-B8FA-2C098CBC3C79.png3.10、静态库
ar -t libc.a # ar -t 命令查看 libc.a 静态库由哪些目标文件(.o)文件组成
objdump -t libc.a # objdump -t 可以看到 libc.a 静态库中包含了哪些函数以及section
ar -x libc.a # ar -x 可以将 libc.a 静态库解压缩成为多个.o文件
网友评论