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

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 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. Use these options on systems where the linker can perform optimizations to improve locality of reference in the instruction space. Most systems using the ELF object format and SPARC processors running Solaris 2 have linkers with such optimizations. AIX may have these optimizations in the future.
Only use these options when there are significant benefits from doing so. When you specify these options, the assembler and linker will create larger object and executable files and will also be slower. You will not be able to use gprof on all systems if you specify this option and you may have problems with debugging if you specify both this option and -g.

--gc-sections
--no-gc-sections
Enable garbage collection of unused input sections. It is ignored on targets that do not support this option. The default behaviour (of not performing this garbage collection) can be restored by specifying `--no-gc-sections' on the command line.
`--gc-sections' decides which input sections are used by examining symbols and relocations. The section containing the entry symbol and all sections containing symbols undefined on the command-line will be kept, as will sections containing symbols referenced by dynamic objects. Note that when building shared libraries, the linker must assume that any visible symbol is referenced. Once this initial set of sections has been determined, the linker recursively marks as used any section referenced by their relocations. See `--entry' and `--undefined'.
This option can be set when doing a partial link (enabled with option `-r'). In this case the root of symbols kept must be explicitly specified either by an `--entry' or `--undefined' option or 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(符号)了。

 

 

验证如下:

#cat main.c
#include <stdio.h>
int data_main[20];
extern int ff(void);

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

#cat ff.c
#include <stdio.h>
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 -o ff.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 000000 00      0   0  0
  [ 1] .text             PROGBITS        00000000 000034 000064 00  AX  0   0  4
  [ 2] .rel.text         REL             00000000 0003d4 000040 08      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 000000 00      0   0  1
  [ 8] .shstrtab         STRTAB          00000000 0000c8 000051 00      0   0  1
  [ 9] .symtab           SYMTAB          00000000 0002d4 0000e0 10     10   8  4
  [10] .strtab           STRTAB          00000000 0003b4 00001f 00      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 (OS specific), p (processor specific)

# ls -l ff.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 000000 00      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 000010 08     16   5  4
  [ 7] .text.jj          PROGBITS        00000000 000059 000019 00  AX  0   0  1
  [ 8] .rel.text.jj      REL             00000000 00056c 000010 08     16   7  4
  [ 9] .text.hh          PROGBITS        00000000 000072 000019 00  AX  0   0  1
  [10] .rel.text.hh      REL             00000000 00057c 000010 08     16   9  4
  [11] .text.gg          PROGBITS        00000000 00008b 000019 00  AX  0   0  1
  [12] .rel.text.gg      REL             00000000 00058c 000010 08     16  11  4
  [13] .comment          PROGBITS        00000000 0000a4 000024 01  MS  0   0  1
  [14] .note.GNU-stack   PROGBITS        00000000 0000c8 000000 00      0   0  1
  [15] .shstrtab         STRTAB          00000000 0000c8 000081 00      0   0  1
  [16] .symtab           SYMTAB          00000000 00041c 000120 10     17  12  4
  [17] .strtab           STRTAB          00000000 00053c 00001f 00      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 (OS specific), p (processor specific)

# ls -l ff.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


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


====

http://hi.baidu.com/vv1133/item/11432a104932ccfa9c778adc

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值