去除可执行文件中没用到的符号或函数

举报
aiot_bigbear 发表于 2022/09/25 02:59:32 2022/09/25
【摘要】 1.编译阶段使用: -ffunction-sections -fdata-sections 2.链接阶段使用: -Wl,--gc-sections 在GCC,LD官方文档中如下讲解: 在GCC,LD官方文档中如下讲解: -ffunction-sections  -fdata-sections  Place eac...

1.编译阶段使用:
-ffunction-sections
-fdata-sections

2.链接阶段使用:
-Wl,--gc-sections

GCC,LD官方文档中如下讲解:
GCC,LD官方文档中如下讲解:
-ffunction-sections 
-fdata-sections 
Place each function or data item into its own section in the outputfile if the target supports arbitrary sections. The name of thefunction or the name of the data item determines the section's namein the output file. Use these options on systems where the linkercan perform optimizations to improve locality of reference in theinstruction space. Most systems using the ELF object format andSPARC processors running Solaris 2 have linkers with suchoptimizations. AIX may have these optimizations in thefuture.
Only use these options when there are significant benefits fromdoing so. When you specify these options, the assembler and linkerwill create larger object and executable files and will also beslower. You will not be able to use gprof on all systems if youspecify this option and you may have problems with debugging if youspecify both this option and -g.

--gc-sections 
--no-gc-sections 
Enable garbage collection of unused input sections. It is ignoredon targets that do not support this option. The default behaviour(of not performing this garbage collection) can be restored byspecifying `--no-gc-sections' on the commandline. 
`--gc-sections' decides which input sections are used by examiningsymbols and relocations. The section containing the entry symboland all sections containing symbols undefined on the command-linewill be kept, as will sections containing symbols referenced bydynamic objects. Note that when building shared libraries, thelinker must assume that any visible symbol is referenced. Once thisinitial set of sections has been determined, the linker recursivelymarks as used any section referenced by their relocations. See`--entry' and `--undefined'.
This option can be set when doing a partial link (enabled withoption `-r'). In this case the root of symbols kept must beexplicitly specified either by an `--entry' or `--undefined' optionor by a ENTRY command in the linker script.
 

 

因为GCC链接操作以section作为最小的处理单元,只要一个section中有某个符号被引用,该section就会被加入。
如果我们的某个.c程序中所有function都加入同一个section.则如果用到这个.c生成的.o的其中任何一个function.则必须将所有

function(符号)加入其中。如此,则使用-ffunction-sections -fdata-sections将每个符号创建为一个sections.sections

function,data名保持一致。
则在link阶段,-Wl,--gc-sections申明去掉不用的section。就可以去掉没用的function(符号)了。

 

 

验证如下:

#catmain.c
#include
int data_main[20];
extern int ff(void);

intfun(void)
{
 return 0;
}
int main(void)
{
 ff();
 return 0;
}

#cat ff.c
#include
int data_ff[30];
int ff(void)
{
 printf("ff\n");
 return 0;
}
int jj(void)
{
 printf("jj\n");
 return 0;
}
int hh(void)
{
 printf("hh\n");
 return 0;
}
int gg(void)
{
 printf("gg\n");
 return 0;
}

 

1不去除无用符号

# gcc -c ff.c -off.o
# readelf -S ff.o
There are 11 section headers, starting at offset 0x11c:
Section Headers:
  [Nr]Name             Type           Addr    Off   Size   ES Flg Lk Inf Al
  [0]                  NULL           00000000 000000 00000000     0   0  0
  [ 1].text            PROGBITS       00000000 000034 000064 00  AX 0   0  4
  [ 2].rel.text        REL            00000000 0003d4 00004008     9   1  4
  [ 3].data            PROGBITS       00000000 000098 000000 00  WA 0   0  4
  [ 4].bss             NOBITS         00000000 000098 000000 00  WA 0   0  4
  [ 5].rodata          PROGBITS       00000000 000098 00000c 00  A  0  0  1
  [ 6].comment         PROGBITS       00000000 0000a4 000024 01  MS 0   0  1
  [ 7].note.GNU-stack  PROGBITS       00000000 0000c8 00000000     0   0  1
  [ 8].shstrtab        STRTAB         00000000 0000c8 00005100     0   0  1
  [ 9].symtab          SYMTAB         00000000 0002d4 0000e010    10   8  4
  [10].strtab          STRTAB         00000000 0003b4 00001f00     0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S(strings)
  I (info), L (link order), G (group), x(unknown)
  O (extra OS processing required) o (OSspecific), p (processor specific)

# ls -lff.o
-rw-r--r-- 1 root root 1044 2011-12-06 23:20 ff.o
# gcc ff.o main.c -o main.elf
# nm -S main.elf
08049f20 d _DYNAMIC
08049ff4 d _GLOBAL_OFFSET_TABLE_
0804852c 00000004 R _IO_stdin_used
        w _Jv_RegisterClasses
08049f10 d __CTOR_END__
08049f0c d __CTOR_LIST__
08049f18 D __DTOR_END__
08049f14 d __DTOR_LIST__
0804853c r __FRAME_END__
08049f1c d __JCR_END__
08049f1c d __JCR_LIST__
0804a018 A __bss_start
0804a00c D __data_start
080484e0 t __do_global_ctors_aux
08048360 t __do_global_dtors_aux
0804a010 D __dso_handle
        w __gmon_start__
080484da T __i686.get_pc_thunk.bx
08049f0c d __init_array_end
08049f0c d __init_array_start
08048470 00000005 T __libc_csu_fini
08048480 0000005a T __libc_csu_init
        U 
0804a018 A _edata
0804a0b8 A _end
0804850c T _fini
08048528 00000004 R _fp_hw
080482b8 T _init
08048330 T _start
0804a020 00000001 b completed.7021
0804a014 00000004 D data_a
0804a040 00000078 Bdata_ff
0804a00c W data_start
0804a024 00000004 b dtor_idx.7023
080483e4 00000019 T ff
080483c0 t frame_dummy
08048448 0000000a T fun
0804842f 00000019 T gg
08048416 00000019 T hh
080483fd 00000019 T jj
08048452 00000014 T main
        U

 

 2 去除无用符号

# gcc-ffunction-sections -fdata-sections -c ff.c -o ff.o
# readelf -S ff.o
There are 18 section headers, starting at offset 0x14c:
Section Headers:
  [Nr]Name             Type           Addr    Off   Size   ES Flg Lk Inf Al
  [0]                  NULL           00000000 000000 00000000     0   0  0
  [ 1].text            PROGBITS       00000000 000034 000000 00  AX 0   0  4
  [ 2].data            PROGBITS       00000000 000034 000000 00  WA 0   0  4
  [ 3].bss             NOBITS         00000000 000034 000000 00  WA 0   0  4
  [ 4].rodata          PROGBITS       00000000 000034 00000c 00  A  0  0  1
  [ 5].text.ff         PROGBITS       00000000 000040 000019 00  AX 0   0  1
  [ 6].rel.text.ff     REL            00000000 00055c 00001008    16   5  4
  [ 7].text.jj         PROGBITS       00000000 000059 000019 00  AX 0   0  1
  [ 8].rel.text.jj     REL            00000000 00056c 00001008    16   7  4
  [ 9].text.hh         PROGBITS       00000000 000072 000019 00  AX 0   0  1
  [10].rel.text.hh     REL            00000000 00057c 00001008    16   9  4
  [11].text.gg         PROGBITS       00000000 00008b 000019 00  AX 0   0  1
  [12].rel.text.gg     REL            00000000 00058c 00001008    16  11  4
  [13].comment         PROGBITS       00000000 0000a4 000024 01  MS 0   0  1
  [14].note.GNU-stack  PROGBITS       00000000 0000c8 00000000     0   0  1
  [15].shstrtab        STRTAB         00000000 0000c8 00008100     0   0  1
  [16].symtab          SYMTAB         00000000 00041c 00012010    17  12  4
  [17].strtab          STRTAB         00000000 00053c 00001f00     0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S(strings)
  I (info), L (link order), G (group), x(unknown)
  O (extra OS processing required) o (OSspecific), p (processor specific)

# ls -lff.o
-rw-r--r-- 1 root root 1436 2011-12-06 23:15 ff.o
# gcc -Wl,--gc-sections ff.o main.c -o main.elf
# nm -S main.elf 
08049f20 d _DYNAMIC
08049ff4 d _GLOBAL_OFFSET_TABLE_
080484b8 00000004 R _IO_stdin_used
        w _Jv_RegisterClasses
08049f10 d __CTOR_END__
08049f0c d __CTOR_LIST__
08049f18 D __DTOR_END__
08049f14 d __DTOR_LIST__
080484c8 r __FRAME_END__
08049f1c d __JCR_END__
08049f1c d __JCR_LIST__
0804a00c A __bss_start
08048470 t __do_global_ctors_aux
08048340 t __do_global_dtors_aux
        w __gmon_start__
0804846a T __i686.get_pc_thunk.bx
08049f0c d __init_array_end
08049f0c d __init_array_start
08048400 00000005 T __libc_csu_fini
08048410 0000005a T __libc_csu_init
        U 
0804a00c A _edata
0804a014 A _end
0804849c T _fini
08048298 T _init
08048310 T _start
0804a00c 00000001 b completed.7021
0804a010 00000004 b dtor_idx.7023
080483c3 00000019 T ff
080483a0 t frame_dummy
080483dc 0000000a T fun
080483e6 00000014 T main
        U


 绿色部分为两者的区别,仔细分析即可发现该编译选项的作用。

文章来源: blog.csdn.net,作者:悟空胆好小,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/xushx_bigbear/article/details/9410925

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。