繁体   English   中英

gcc中使用`-fdata-sections`和`-ffunction-sections`这两个选项的目的是什么?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM