正如man页面所述:
-ffunction-sections
-fdata-sections
如果目标支持任意节段,则将每个函数或数据项放置在其自己的节段中输出到文件中。 函数的名称或数据项的名称决定了输出文件中节段的名称。
编译此代码后:
...
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
...