[读书笔记]程序员的自我修养--静态链接

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.png

3.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文件

你可能感兴趣的:([读书笔记]程序员的自我修养--静态链接)