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

mzaanser  于 2023-02-01  发布在  C#
关注(0)|答案(1)|浏览(244)

正如手册页所述:

  • 功能段
  • fdata-截面
    将每个函数或数据项放置到
    如果目标支持任意节,则返回输出文件。
    函数的名称或数据项的名称确定
    输出文件中节的名称。
    编译完这些代码后:
...

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放进了我的文件夹,然后我列出了它的所有部分,它确实把每个函数和数据都放进了自己的部分,但是开发人员为什么需要这两个选项呢?(例如,完成工作的任何特殊用法)

$ 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

  ...
nimxete2

nimxete21#

这允许链接器删除未使用的节[source]
从最终可执行文件中消除未使用的代码和数据的操作直接由链接器执行。
为此,它必须使用通过以下选项编译的对象:- 函数段-fdata段。
这些选项可用于C和Ada文件。它们将把每个函数或数据分别放在结果目标文件的单独部分中。
一旦使用这些选项创建了对象和静态库,链接器就可以执行死代码消除。您可以通过将-Wl,--gc-sections选项设置为gcc命令或gnatmake的-largs部分来执行此操作。这将对从未引用的代码和数据执行垃圾收集。
此外,Haris链接到的标志的文档中提供了使用指南:
这些选项与链接器垃圾收集(linker --gc-sections选项)一起可能会导致静态链接的可执行文件变小(剥离后)。
在ELF/DWARF系统上,这些选项不会降低调试信息的质量。其他目标文件/调试信息格式可能会有问题。
仅当使用这些选项有显著好处时才使用它们。指定这些选项时,汇编器和链接器创建的对象和可执行文件较大,速度也较慢。2这些选项影响代码生成。3它们阻止编译器和汇编器使用翻译单元内的相对位置进行优化,因为位置在链接之前是未知的。这种优化的示例是放松对短调用指令的调用。

相关问题