gcc -c
和 gcc -s
- -c:编译或者汇编,但是不链接,此编译产物一般用于构建静态文件。
- -S:仅编译,不会汇编或者链接。
pthread/lpthread
在05年前,有各类不兼容的pthreads API实现,所以必须用lpthread
来指定,但现在的操作系统就没有这个问题就可以使用pthread
。
Xlinker
编译需要链接动/静态文件则需要此参数,等价于Wl。一个是-WL,option
,另一个是-Xlinker option
。
export-dynamic
这个编译选项会让链接动作添加所有符号,不仅仅是使用到的符号,而且还包括动态符号表。
--whole-archive
--whole-archive
可以把在其后面出现的静态库包含的函数和变量输出到动态库, --no-whole-archive则关闭该特性。这两个选项成对出现,要包含的静态库,必须放在这两个选项之间。另外需要注意的是clang里无此参数。
ar crs
将若干.o文件打包成一个静态文件,如ar crs test.a test1.o test2.o
。
符号表
在程序编译成可执行文件后,这个文件中会有一个表专门来保存函数名,变量名,段名和代码或者数据的对应关系,这个表就是符号表。符号表在链接时起着按符号寻址的作用,但在运行的时候就没有什么作用了,因此这个表即使去掉之后,也并不会影响程序的运行。但是如果是动态链接的函数,比如用到了libc的printf函数,那么这个printf符号如果去掉了,在运行的时候就没法找到这函数了,所以这个符号就不能在去符号表的时候被去掉。动态库有动态符号表,静态库没有动态符号表(意味着下游程序链接后可以删除静态库)。
objdump
objdump -t
用来查看符号表,objdump -T
用来查看动态符号表,objdump -R
查看动态重定位信息。
strip
可以用strip 执行文件
来去除符号表信息。实际静态链接文件有符号表,没有动态符号表。用strip
后就没有任何符号表信息。
参考文献
- https://xuanxuanblingbling.github.io/ctf/tools/2019/09/06/symbol/
- https://stackoverflow.com/questions/2156457/why-does-the-export-dynamic-flag-not-apply-to-archives
- https://www.cnblogs.com/rickyk/p/4186902.html
- https://www.cnblogs.com/wujianlundao/archive/2012/06/06/2538125.html