-
参考文档
-
gcc -ffunction-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 have linkers with such optimizations. On AIX, the linker rearranges sections (CSECTs) based on the call graph. The performance impact varies. 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. '''
-
翻译
- 如果目标文件支持任意数量的段,那么为每个函数和全局,静态变量创建一个段,并存放对应代码.段名是
.text | .data
前缀,后跟对应的名字.函数对应.text
开头,变量对应.data
开头. gcc -c test.c -ffunction-sections -fdata-sections && readelf -e test.o
,注意test.c
里面的函数变量尽量不要和API
重名了.否则结果会异常.- 链接器可以执行将调用依赖的代码紧密的拼凑在一起.以此优化本地指令空间. 大多数
ELF
系统都支持这个选项.有的系统甚至根据调用图来对代码顺序进行重排. - 和
ld
的--gc-sectioins
选项,可以创建一个静态链接的文件,代码区仅仅包含自己用到的变量和函数.没有其他额外的符号. ELF/DWARF
格式的调试信息和这个编译选项不存在冲突.但是其他格式的可能存在冲突.- 真的可以通过这个编译选项获得好处的时候才用,不然,尽量不要用. 这个编译选项会导致汇编器和链接器生成的文件变大,而且可执行文件也会执行得更慢. 这些文件还会影响代码生成. 这个代码禁止相对路径优化. 因为都变成了段代码,不知道位置,只有链接的时候才知道.
- 如果目标文件支持任意数量的段,那么为每个函数和全局,静态变量创建一个段,并存放对应代码.段名是
-
-
案例
-
代码
void show(){ } void cool(){ } int main() { show(); cool(); }
gcc -c test.c -ffunction-sections -fdata-sections
-
段
test.o: file format elf64-x86-64 Disassembly of section .text.show: 0000000000000000 <show>: 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: 5d pop %rbp 5: c3 retq Disassembly of section .text.cool: 0000000000000000 <cool>: 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: 5d pop %rbp 5: c3 retq Disassembly of section .text.main: 0000000000000000 <main>: 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: b8 00 00 00 00 mov $0x0,%eax 9: e8 00 00 00 00 callq e <main+0xe> e: b8 00 00 00 00 mov $0x0,%eax 13: e8 00 00 00 00 callq 18 <main+0x18> 18: 5d pop %rbp 19: c3 retq
objdump -d test.o
-
说明
- 生成了函数对应的段.
-
去掉
main
中的show
- 编译后的代码
gcc -Wl,--gc-sections test.o -o test.out
- 编译后的代码
-
-
-
ld --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. Note that garbage collection for COFF and PE format targets is supported, but the implementation is currently considered to be experimental. ‘--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’, ‘--undefined’, and ‘--gc-keep-exported’. 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 one of the options ‘--entry’, ‘--undefined’, or ‘--gc-keep-exported’ or by a ENTRY command in the linker script. As a GNU extension, ELF input sections marked with the SHF_GNU_RETAIN flag will not be garbage collected.
-
翻译
- 允许垃圾回收机制回收未使用的段
(即用到的段才放入最终生成产物,没有用到的就删除掉.)
.对于不支持的平台,这个参数会被ld
忽略.默认不开启,可以对一些.o
文件开启,对一些关闭(ld --gc-sections a.o --no-gc-sections,就只有a.o才会进行选择性提取)
.垃圾收集机制对于COFF,PE
格式的.o
文件同样支持,但是目前是开发体验版,不建议用. --gc-sections
会检测哪些断和符号被用到了. 符号表相关的段保留;段中有通过指令指定的未定义的符号(ld -u name指定的符号,表示强制未定义)
;段中的符号被其他动态对象引用. 编译共享库,所有可见的符号都被当成是被引用了(可以使用可见性控制机制来编译,__attribute__的形式指定某几个,或者编译时 -fvisibility=xxx 设置整个)
. 第一阶段处理完保留的段,第二阶段就是递归的检测引用到的代码,即间接依赖的段.- 当只需要链接部分内容的时候可以使用这个选(
-r选项是编译可重定位类型,即.o
),那么保留的符号就可以使用--entry,--undefined,--gc-keep-exported,ENTRY
来设定.
- 允许垃圾回收机制回收未使用的段
-
总结
- 保留用到的,并且保留依赖的.
- 一般和
-ffunction-sections,-fdata-sections
使用.
-
-
-
编译案例
-
普通
-
代码
void show(){ } void cool(){ } int main() { cool(); }
-
编译后
- 编译:
gcc -c test.c -ffunction-sections -fdata-sections
objdump -d test.o | less
test.o: file format elf64-x86-64 Disassembly of section .text.show: 0000000000000000 <show>: 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: 5d pop %rbp 5: c3 retq Disassembly of section .text.cool: 0000000000000000 <cool>: 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: 5d pop %rbp 5: c3 retq Disassembly of section .text.main: 0000000000000000 <main>: 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: b8 00 00 00 00 mov $0x0,%eax 9: e8 00 00 00 00 callq e <main+0xe> e: 5d pop %rbp f: c3 retq
- 生成:
gcc test.o -Wl,-gc-sections -o test.out
- 查看:
objdump -d test.out
test.out: file format elf64-x86-64 Disassembly of section .text: 00000000004000b0 <cool>: 4000b0: 55 push %rbp 4000b1: 48 89 e5 mov %rsp,%rbp 4000b4: 5d pop %rbp 4000b5: c3 retq 00000000004000b6 <main>: 4000b6: 55 push %rbp 4000b7: 48 89 e5 mov %rsp,%rbp 4000ba: b8 00 00 00 00 mov $0x0,%eax 4000bf: e8 ec ff ff ff callq 4000b0 <cool> 4000c4: 5d pop %rbp 4000c5: c3 retq
- 测试实际指令
gcc -c test.c -ffunction-sections -fdata-sections -fno-builtin ld test.o --gc-sections -static -o test.out -e main objdump -d test.out | less
- 编译:
-
-
共享库
-
代码
- 同上
-
编译后
gcc -fPIC -shared -c test.c -ffunction-sections -fdata-sections -fno-builtin
ld test.o -fPIC -shared --gc-sections -static -o test.so
test.so: file format elf64-x86-64 Disassembly of section .plt: 0000000000000280 <.plt>: 280: ff 35 82 0d 20 00 pushq 0x200d82(%rip) # 201008 <_GLOBAL_OFFSET_TABLE_+0x8> 286: ff 25 84 0d 20 00 jmpq *0x200d84(%rip) # 201010 <_GLOBAL_OFFSET_TABLE_+0x10> 28c: 0f 1f 40 00 nopl 0x0(%rax) 0000000000000290 <cool@plt>: 290: ff 25 82 0d 20 00 jmpq *0x200d82(%rip) # 201018 <cool+0x200d72> 296: 68 00 00 00 00 pushq $0x0 29b: e9 e0 ff ff ff jmpq 280 <.plt> Disassembly of section .text: 00000000000002a0 <show>: 2a0: 55 push %rbp 2a1: 48 89 e5 mov %rsp,%rbp 2a4: 5d pop %rbp 2a5: c3 retq 00000000000002a6 <cool>: 2a6: 55 push %rbp 2a7: 48 89 e5 mov %rsp,%rbp 2aa: 5d pop %rbp 2ab: c3 retq 00000000000002ac <main>: 2ac: 55 push %rbp 2ad: 48 89 e5 mov %rsp,%rbp 2b0: b8 00 00 00 00 mov $0x0,%eax 2b5: e8 d6 ff ff ff callq 290 <cool@plt> 2ba: 5d pop %rbp 2bb: c3 retq
- 这里没有设置可见性.默认都可见.
-
-
不可见
-
说明
- 所有符号都不可见
-
代码
//#pragma GCC visibility push(hidden) void show(){ } void cool(){ } //#pragma GCC visibility pop int __attribute__((visibility("default"))) main() { //show(); cool(); }
-
编译
gcc -fPIC -shared -c test.c -ffunction-sections -fdata-sections -fno-builtin -fvisibility=hidden
ld test.o -fPIC -shared --gc-sections -static -o test.so -u main
-
-
-
可见性控制
编译一个尽量小的so
猜你喜欢
转载自blog.csdn.net/rubikchen/article/details/119223445
今日推荐
周排行