Home > Blockchain >  What is the purpose for using `-fdata-sections` and `-ffunction-sections` these two options in gcc?
What is the purpose for using `-fdata-sections` and `-ffunction-sections` these two options in gcc?

Time:02-01

As the man page says:

-ffunction-sections
-fdata-sections
  Place each function or data item into its own section in the
  output file if the target supports arbitrary sections. The
  name of the function or the name of the data item determines
  the section's name in the output file.

And after compiling this code:

...

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) {
    ...
}

I got main.o in my folder, then I listed all its sections, it did place each function and data into its own section, but why do developers need these two options? (for example, any special usage to get their work done)

$ 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

  ...

CodePudding user response:

This allows linker to remove the unused sections [source]

The operation of eliminating the unused code and data from the final executable is directly performed by the linker.

In order to do this, it has to work with objects compiled with the following options: -ffunction-sections -fdata-sections.

These options are usable with C and Ada files. They will place respectively each function or data in a separate section in the resulting object file.

Once the objects and static libraries are created with these options, the linker can perform the dead code elimination. You can do this by setting the -Wl,--gc-sections option to gcc command or in the -largs section of gnatmake. This will perform a garbage collection of code and data never referenced.

Additionally, usage guidelines are provided in the documentation of the flags linked to by Haris:

Together with a linker garbage collection (linker --gc-sections option) these options may lead to smaller statically-linked executables (after stripping).

On ELF/DWARF systems these options do not degenerate the quality of the debug information. There could be issues with other object files/debug info formats.

Only use these options when there are significant benefits from doing so. When you specify these options, the assembler and linker create larger object and executable files and are also slower. These options affect code generation. They prevent optimizations by the compiler and assembler using relative locations inside a translation unit since the locations are unknown until link time. An example of such an optimization is relaxing calls to short call instructions.

  • Related