文章目錄
上篇文章: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 文件大小