本文已参与「新人创作礼」活动,一起开启掘金创作之路。
目标文件
通常目标文件有三种形式:
- 可执行目标文件。即我们通常所认识的,可直接运行的二进制文件。
- 可重定位目标文件。包含了二进制的代码和数据,可以与其他可重定位目标文件合并,并创建一个可执行目标文件。
- 共享目标文件。它是一种在加载或者运行时进行链接的特殊可重定位目标文件。
--- 可执行文件
有各个段起始地址
--- 重定位文件
只有段内偏移地址,标识符无实际地址
不可脱离符号表
编译选项:strip的默认选项会去除.symbol节的内容以及.debug节的内容(.debug_info段为调试信息表)
.o可重定位文件(relocatable)
.ko内核可重定位文件(relocatable)
.a静态库文件(ar)
-- 重定位文件&静态库文件不能strip,否则会造成编译错误
.a静态库文件格式(archive)
环境变量LIBRARY_PATH
如何生成:
ar -rsv lib.a 1.o 2.o
如何查看静态库包含那些.o文件:
ar -t lib.a
静态库的弊端:
缺点1:当同时运行许多应用程序并且它们都使用来自同一个函数库的函数时,就会在内存中有同一函数的多份拷贝,在程序文件自身中也有多份同样的拷贝。这将消耗大量宝贵的内存和磁盘空间
缺点2:使用静态链接的最大危险在与将来版本的操作系统可能与可执行文件所绑定的系统函数库不兼容。它可能会立即崩溃,也可能出现一个不明显的错误
可脱离符号表
ld(链接器)的作用
1.符号解析
2.重定位
-- 在实际的开发中,经常需要对动态库.so进行strip操作,减少占地空间。
.so动态库文件格式(shared object)
环境变量LD_LIBRARY_PATH
如何生成:
gcc -shared -fPIC 1.o 2.o -o lib.so
或者
gcc -shared -fPIC 1.c 2.c -o lib.so
动态库的优势:
有些函数库(如libaio.so、libdl.so、libsys.so、libsolv.so以及librpcsvc.so等)只能以动态链接的形式使用。如果在应用程序中使用了这些函数库中的任何一个,你的程序就必须使用动态链接。最好的策略就是所有的应用程序都是用动态链接,这就可以避免可能产生的问题
相关工具
ldd aaa -查看可执行文件依赖的库文件
size aaa -读取目标文件各段的大小
readelf -S aaa -读取目标文件section head