前往顾页
以后地位: 主页 > 收集编程 > Php实例教程 >

gcc -ffunction-sections -fdata-sections -Wl,–gc-sections 参

时候:2018-11-24 21:39来源:知行网www.zhixing123.cn 编辑:麦田守望者

背景

偶然我们的法度会定义一些临时利用不上的服从和函数,固然我们不利用这些服从和函数,但它们常常会浪费我们的ROM和RAM的空间。这在利用静态库时,表现的更加严峻。偶然,我们只利用了静态库独一的几个服从,但是体系默许会主动把全部静态库全数链接到可履行法度中,造成可履行法度的年夜大年夜年夜增加。

参数详解

为体味决前面阐发的问题,我们引入了题目中的几个参数。GCC链接操纵是以section作为最小的措置单位,只需一个section中的某个标记被援引,该section就会被插手到可履行法度中去。是以,GCC在编译时可利用 -ffunction-sections和 -fdata-sections 将每个函数或标记建立为一个sections,此中每个sections名与function或data名保持分歧。而在链接阶段, -Wl,–gc-sections 唆使链接器去失落不消的section(此中-wl, 表示前面的参数 -gc-sections 通报给链接器),如许就可以减少终究的可履行法度的年夜小了。

我们常常利用下面的建设启用这个服从:


CFLAGS += -ffunction-sections -fdata-sections
LDFLAGS += -Wl,--gc-sections

例子

main.c 文件以下:


#include <stdio.h>

int fun_0(void)
{
printf("%s: %d\n", __FUNCTION__, __LINE__);
return 0;
}

int fun_1(void)
{
printf("%s: %d\n", __FUNCTION__, __LINE__);
return 0;
}

int fun_2(void)
{
printf("%s: %d\n", __FUNCTION__, __LINE__);
return 0;
}

int fun_3(void)
{
printf("%s: %d\n", __FUNCTION__, __LINE__);
return 0;
}

void main(void)
{
fun_0();
fun_3();
}

Makefile文件以下:


main_sections:
gcc -ffunction-sections -fdata-sections -c main.c
gcc -Wl,--gc-sections -o $@ main.o

main_normal:
gcc -c main.c
gcc -o $@ main.o

clean:
rm -rf *.o main_sections main_normal

考证

运行


$ make main_sections
gcc -ffunction-sections -fdata-sections -c main.c
gcc -Wl,--gc-sections -o main_sections main.o
$ make main_normal
gcc -c main.c
gcc -o main_normal main.o

比较年夜小


$ ll main_*
-rwxrwxr-x 1 8896 2月 16 00:42 main_normal*
-rwxrwxr-x 1 8504 2月 16 00:42 main_sections*

可以瞥见利用该服从的二进制文件要小于不利用该服从的二进制文件

阐发sections


$ make clean
rm -rf *.o main_sections main_normal
$ make main_sections
gcc -ffunction-sections -fdata-sections -c main.c
gcc -Wl,--gc-sections -o main_sections main.o
$ readelf -t main.o
...
[ 5] .text.fun_0
PROGBITS PROGBITS 0000000000000000 0000000000000048 0
0000000000000024 0000000000000000 0 1
[0000000000000006]: ALLOC, EXEC
[ 6] .rela.text.fun_0
RELA RELA 0000000000000000 0000000000000508 24
0000000000000048 0000000000000018 5 8
[0000000000000040]: INFO LINK
[ 7] .text.fun_1
PROGBITS PROGBITS 0000000000000000 000000000000006c 0
0000000000000024 0000000000000000 0 1
[0000000000000006]: ALLOC, EXEC
[ 8] .rela.text.fun_1
RELA RELA 0000000000000000 0000000000000550 24
0000000000000048 0000000000000018 7 8
[0000000000000040]: INFO LINK
[ 9] .text.fun_2
PROGBITS PROGBITS 0000000000000000 0000000000000090 0
0000000000000024 0000000000000000 0 1
[0000000000000006]: ALLOC, EXEC
[10] .rela.text.fun_2
RELA RELA 0000000000000000 0000000000000598 24
0000000000000048 0000000000000018 9 8
[0000000000000040]: INFO LINK
[11] .text.fun_3
PROGBITS PROGBITS 0000000000000000 00000000000000b4 0
0000000000000024 0000000000000000 0 1
[0000000000000006]: ALLOC, EXEC
[12] .rela.text.fun_3
RELA RELA 0000000000000000 00000000000005e0 24
0000000000000048 0000000000000018 11 8
[0000000000000040]: INFO LINK

从object文件中可以发明,fun_0 ~ fun_3 每个函数都是一个自力的section. 

而如果利用 make main_normal 天生的object文件,则共享一个默许的sections(.text)。

阐发elf文件


$ readelf -a main_normal | grep fun_
52: 0000000000400526 36 FUNC GLOBAL DEFAULT 14 fun_0
55: 000000000040056e 36 FUNC GLOBAL DEFAULT 14 fun_2
65: 0000000000400592 36 FUNC GLOBAL DEFAULT 14 fun_3
66: 000000000040054a 36 FUNC GLOBAL DEFAULT 14 fun_1
$ readelf -a main_sections | grep fun_
49: 0000000000400526 36 FUNC GLOBAL DEFAULT 14 fun_0
57: 000000000040054a 36 FUNC GLOBAL DEFAULT 14 fun_3

可以瞥见,在终究的目标文件中,未利用的函数并未被链接进终究的目标文件。

------分开线----------------------------
标签(Tag):php
------分开线----------------------------
保举内容
猜你感兴趣