红联Linux门户
Linux帮助

Linux编译出的进程内没有新编写的函数

发布时间:2017-07-26 15:47:12来源:linux网站作者:xingyeping
今日一位同事在代码里新增了一个.c文件,加了几个调试函数,运行后发现无法使用。通过objdump反汇编看到汇编代码里确实没有该c文件中的调试函数。一开始以为编译有问题,经排查,发现.o确实生成,并且和其他.o生成的.a中也能反汇编出这些函数,在编译输出中也能看到链接.a的信息。
 
后来发现,应该是没有调用过此.c中的函数,导致链接优化掉了这些函数。经网上搜索,有如下可用信息:
不把未调用的函数link进image.
方法是在complier命令中增加-ffunction-sections,linker命令中增加-Wl,–gc-sections.
-ffunction-sections:不用此参数时,.o里代码部分只有.text段;使用此参数,则会使每个函数单独成为一段,比如函数func1()成为.text.func1段,但对链接后代码大小没影响。
–gc-sections:这是avr-ld的参数,通过-Wl,由gcc把option里的参数传递给avr-ld。它使得链接器ld链接时删除不用的段。
这样,因为每个函数自成一段(即可以看作函数=段),如果有某个函数未被任何函数/段调用,则ld不会链接它。
对于一个文件A,里面有很多函数,但是main函数只调用了其中的一个,其他函数也会被编译,也会被“打包”到最后的可执行文件中,要从中分离出不要的函数,方法如下:
1.执行gcc -function-sections name.c。其中-function-sections的意思是,将不同函数编译到不同的section上面。如果没有这个选项,所有的函数都会编译到一个section上面,于是函数就不能被“剥离”
2.执行ld –gc-sections object。表示把不要的函数section去掉。 可以比较一下,传统方法做出来的可执行文件更大。而这样做的更小。
 
自己测试了下:
test1.c
#include <stdio.h>
#include <string.h>
int main()
{
return 0;
}
 
test2.c
int func1()
{
return 1;
}
 
正常编译:
gcc -c test2.c
gcc -o test1 test1.c -Wl,--gc-sections test2.o
gcc -o test2 test1.c -Wl,test2.o
 
通过ll看一下文件大小
-rwxr-xr-x. 1 root root 8145 Jul 26 10:06 test1
-rw-r–r–. 1 root root 67 Jul 26 09:45 test1.c
-rwxr-xr-x. 1 root root 8515 Jul 26 10:06 test2
-rw-r–r–. 1 root root 29 Jul 26 09:45 test2.c
-rw-r–r–. 1 root root 1232 Jul 26 10:06 test2.o
可以看到test1比test2小。反汇编看一下,确实没有func1。
 
本文永久更新地址:http://www.linuxdiyf.com/linux/32132.html