[英]Is -ffunction-sections -fdata-sections and --gc-sections not working?
[英]What is the purpose for using `-fdata-sections` and `-ffunction-sections` these two options in gcc?
正如手册页所说:
-ffunction-sections
-f数据部分
将每个 function 或数据项放入其自己的部分
如果目标支持任意部分,则为输出文件。 这
function 的名称或数据项的名称确定
output 文件中该部分的名称。
编译这段代码后:
...
int bss_var_1 = 0;
int bss_var_2;
int bss_var_3;
int data_var_1 = 90;
int data_var_2 = 47;
int data_var_3[128] = {212};
int foo() {
printf("hello, foo()\n");
}
int func() {
printf("hello, func()\n");
}
int main(void) {
...
}
我在我的文件夹中得到了main.o
,然后我列出了它的所有部分,它确实将每个 function 和数据放入了它自己的部分,但为什么开发人员需要这两个选项? (例如,完成工作的任何特殊用途)
$ readelf build/main.o -S
There are 34 section headers, starting at offset 0xeb0:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00000000 000034 000000 00 AX 0 0 2
[ 2] .data PROGBITS 00000000 000034 000000 00 WA 0 0 1
[ 3] .bss NOBITS 00000000 000034 000000 00 WA 0 0 1
[ 4] .bss.bss_var_1 NOBITS 00000000 000034 000004 00 WA 0 0 4
[ 5] .bss.bss_var_2 NOBITS 00000000 000034 000004 00 WA 0 0 4
[ 6] .bss.bss_var_3 NOBITS 00000000 000034 000004 00 WA 0 0 4
[ 7] .data.data_var_1 PROGBITS 00000000 000034 000004 00 WA 0 0 4
[ 8] .data.data_var_2 PROGBITS 00000000 000038 000004 00 WA 0 0 4
[ 9] .data.data_var_3 PROGBITS 00000000 00003c 000200 00 WA 0 0 4
[10] .rodata PROGBITS 00000000 00023c 000047 00 A 0 0 4
[11] .text.foo PROGBITS 00000000 000284 000014 00 AX 0 0 4
[12] .rel.text.foo REL 00000000 000b78 000010 08 I 31 11 4
[13] .text.func PROGBITS 00000000 000298 000014 00 AX 0 0 4
[14] .rel.text.func REL 00000000 000b88 000010 08 I 31 13 4
[15] .text.main PROGBITS 00000000 0002ac 000028 00 AX 0 0 4
[16] .rel.text.main REL 00000000 000b98 000020 08 I 31 15 4
...
这允许 linker 删除未使用的部分 [ 来源]
从最终可执行文件中删除未使用的代码和数据的操作由 linker 直接执行。
为此,它必须使用使用以下选项编译的对象:-ffunction-sections -fdata-sections。
这些选项可用于 C 和 Ada 文件。 他们将分别将每个 function 或数据放在生成的 object 文件的单独部分中。
一旦使用这些选项创建了对象和 static 库,linker 就可以执行死代码消除。 您可以通过将 -Wl,--gc-sections 选项设置为 gcc 命令或在 gnatmake 的 -largs 部分中执行此操作。 这将对从未引用过的代码和数据执行垃圾回收。
此外,Haris 链接到的标志的文档中提供了使用指南:
与 linker 垃圾收集(链接器 --gc-sections 选项)一起,这些选项可能会导致更小的静态链接可执行文件(剥离后)。
在 ELF/DWARF 系统上,这些选项不会降低调试信息的质量。 其他 object 文件/调试信息格式可能存在问题。
只有在这样做有显着好处时才使用这些选项。 当您指定这些选项时,汇编程序和 linker 会创建更大的 object 和可执行文件,并且速度也会变慢。 这些选项影响代码生成。 它们阻止编译器和汇编器使用翻译单元内的相对位置进行优化,因为这些位置在链接时间之前是未知的。 这种优化的一个例子是放宽对短调用指令的调用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.