文章目录
上篇文章:ARM 嵌入式 编译系列 10 – GCC 编译缩减可执行文件 elf 文件大小
接着上篇文章 ARM 嵌入式 编译系列 10 – GCC 编译缩减可执行文件 elf 文件大小 的介绍,我们看下如何进一步缩小可执行文件test
的大小。上篇文章通过 strip --strip-debug test
已经将 可执行文件 test 的大小从 17464
减小到了15912
bytes 。
加下继续缩减就是删除 符号表了,使用:strip
命令,或者strip --strip-all
命令:
$ strip --strip-all test
ls -rtl test
-rwxrwxr-x 1 sam sam 14472 8月 14 12:34 test
此时的可执行程序test已经从15912 bytes
进一步减小到了14472bytes
了。
此时符号表已经不在了:
sam@sam-Think:~$ nm test
nm: test: no symbols
symtab
和strtab
2 个 section不见了,section 从31
个减少到了29
个:
sam@sam-Think:~$ readelf -S test
There are 29 section headers, starting at offset 0x3148:Section Headers:[Nr] Name Type Address OffsetSize EntSize Flags Link Info Align[ 0] NULL 0000000000000000 000000000000000000000000 0000000000000000 0 0 0[ 1] .interp PROGBITS 0000000000000318 00000318000000000000001c 0000000000000000 A 0 0 1[ 2] .note.gnu.pr[...] NOTE 0000000000000338 000003380000000000000030 0000000000000000 A 0 0 8[ 3] .note.gnu.bu[...] NOTE 0000000000000368 000003680000000000000024 0000000000000000 A 0 0 4[ 4] .note.ABI-tag NOTE 000000000000038c 0000038c0000000000000020 0000000000000000 A 0 0 4[ 5] .gnu.hash GNU_HASH 00000000000003b0 000003b00000000000000024 0000000000000000 A 6 0 8[ 6] .dynsym DYNSYM 00000000000003d8 000003d800000000000000c0 0000000000000018 A 7 1 8[ 7] .dynstr STRTAB 0000000000000498 000004980000000000000094 0000000000000000 A 0 0 1[ 8] .gnu.version VERSYM 000000000000052c 0000052c0000000000000010 0000000000000002 A 6 0 2[ 9] .gnu.version_r VERNEED 0000000000000540 000005400000000000000030 0000000000000000 A 7 1 8[10] .rela.dyn RELA 0000000000000570 0000057000000000000000c0 0000000000000018 A 6 0 8[11] .rela.plt RELA 0000000000000630 000006300000000000000030 0000000000000018 AI 6 24 8[12] .init PROGBITS 0000000000001000 00001000000000000000001b 0000000000000000 AX 0 0 4[13] .plt PROGBITS 0000000000001020 000010200000000000000030 0000000000000010 AX 0 0 16[14] .plt.got PROGBITS 0000000000001050 000010500000000000000010 0000000000000010 AX 0 0 16[15] .plt.sec PROGBITS 0000000000001060 000010600000000000000020 0000000000000010 AX 0 0 16[16] .text PROGBITS 0000000000001080 00001080000000000000017b 0000000000000000 AX 0 0 16[17] .fini PROGBITS 00000000000011fc 000011fc000000000000000d 0000000000000000 AX 0 0 4[18] .rodata PROGBITS 0000000000002000 000020000000000000000055 0000000000000000 A 0 0 4[19] .eh_frame_hdr PROGBITS 0000000000002058 000020580000000000000044 0000000000000000 A 0 0 4[20] .eh_frame PROGBITS 00000000000020a0 000020a000000000000000ec 0000000000000000 A 0 0 8[21] .init_array INIT_ARRAY 0000000000003db0 00002db00000000000000008 0000000000000008 WA 0 0 8[22] .fini_array FINI_ARRAY 0000000000003db8 00002db80000000000000008 0000000000000008 WA 0 0 8[23] .dynamic DYNAMIC 0000000000003dc0 00002dc000000000000001f0 0000000000000010 WA 7 0 8[24] .got PROGBITS 0000000000003fb0 00002fb00000000000000050 0000000000000008 WA 0 0 8[25] .data PROGBITS 0000000000004000 000030000000000000000010 0000000000000000 WA 0 0 8[26] .bss NOBITS 0000000000004010 000030100000000000000008 0000000000000000 WA 0 0 1[27] .comment PROGBITS 0000000000000000 00003010000000000000002b 0000000000000001 MS 0 0 1[28] .shstrtab STRTAB 0000000000000000 0000303b000000000000010a 0000000000000000 0 0 1
能不能进一步缩减可执行文件的 size 呢? 答案是肯定的。
上面 section中 .note.ABI-tag
, .gnu.version
,.plt
, .plt.got
, .comment
都是可以移除,移除后的信息如下,
:~$ objcopy -R .note.ABI-tag -R .gnu.version -R .gnu.version_r -R .comment test
:~$ nm test
nm: test: no symbols
:~$ readelf -S test
There are 25 section headers, starting at offset 0x30e8:Section Headers:[Nr] Name Type Address OffsetSize EntSize Flags Link Info Align[ 0] NULL 0000000000000000 000000000000000000000000 0000000000000000 0 0 0[ 1] .interp PROGBITS 0000000000000318 00000318000000000000001c 0000000000000000 A 0 0 1[ 2] .note.gnu.pr[...] NOTE 0000000000000338 000003380000000000000030 0000000000000000 A 0 0 8[ 3] .note.gnu.bu[...] NOTE 0000000000000368 000003680000000000000024 0000000000000000 A 0 0 4[ 4] .gnu.hash GNU_HASH 00000000000003b0 000003b00000000000000024 0000000000000000 A 5 0 8[ 5] .dynsym DYNSYM 00000000000003d8 000003d800000000000000c0 0000000000000018 A 6 1 8[ 6] .dynstr STRTAB 0000000000000498 000004980000000000000094 0000000000000000 A 0 0 1[ 7] .rela.dyn RELA 0000000000000570 0000057000000000000000c0 0000000000000018 A 5 0 8[ 8] .rela.plt RELA 0000000000000630 000006300000000000000030 0000000000000018 AI 5 21 8[ 9] .init PROGBITS 0000000000001000 00001000000000000000001b 0000000000000000 AX 0 0 4[10] .plt PROGBITS 0000000000001020 000010200000000000000030 0000000000000010 AX 0 0 16[11] .plt.got PROGBITS 0000000000001050 000010500000000000000010 0000000000000010 AX 0 0 16[12] .plt.sec PROGBITS 0000000000001060 000010600000000000000020 0000000000000010 AX 0 0 16[13] .text PROGBITS 0000000000001080 00001080000000000000017b 0000000000000000 AX 0 0 16[14] .fini PROGBITS 00000000000011fc 000011fc000000000000000d 0000000000000000 AX 0 0 4[15] .rodata PROGBITS 0000000000002000 000020000000000000000055 0000000000000000 A 0 0 4[16] .eh_frame_hdr PROGBITS 0000000000002058 000020580000000000000044 0000000000000000 A 0 0 4[17] .eh_frame PROGBITS 00000000000020a0 000020a000000000000000ec 0000000000000000 A 0 0 8[18] .init_array INIT_ARRAY 0000000000003db0 00002db00000000000000008 0000000000000008 WA 0 0 8[19] .fini_array FINI_ARRAY 0000000000003db8 00002db80000000000000008 0000000000000008 WA 0 0 8[20] .dynamic DYNAMIC 0000000000003dc0 00002dc000000000000001f0 0000000000000010 WA 6 0 8[21] .got PROGBITS 0000000000003fb0 00002fb00000000000000050 0000000000000008 WA 0 0 8[22] .data PROGBITS 0000000000004000 000030000000000000000010 0000000000000000 WA 0 0 8[23] .bss NOBITS 0000000000004010 000030100000000000000008 0000000000000000 WA 0 0 1[24] .shstrtab STRTAB 0000000000000000 0000301000000000000000d7 0000000000000000
ls -rtl test
-rwxrwxr-x 1 selab selab 14120 8月 14 12:44 test
可以看到 test
可执行程序再次减小了,从 14472bytes
减小到了 14120bytes
, 到目前位置,程序依然是可执行的:
:~$ ./test
I am main, I wll can foo
I am foo,I will call bar
I am bar,I will core dump
Segmentation fault (core dumped)
当然了,这种操作其实没必要,对于大型程序而言,用 strip
移除符号表,文件会变小很多,但是用objcopy移除上面几个个 section,节省不了多少空间。
到目前为止,文件越来越小,节省了大量的空间。现在我们把符号表移除了,如果发生了coredump我们将无法定位信息:
:~$ gdb -c /tmp/corefile/core.test.1691988924.1181895
Core was generated by `./test'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x000055621e1941ab in ?? ()
(gdb) bt
#0 0x000055621e1941ab in ?? ()
#1 0x00007ffdc95cf768 in ?? ()
#2 0x0000000000000000 in ?? ()
(gdb)
那么接下来如何处理呢? 请见下篇文章。
上篇文章:ARM 嵌入式 编译系列 10 – GCC 编译缩减可执行文件 elf 文件大小