2021年1月9日 星期六

gcc option: --gc-sections -ffunction-sections -fdata-section

the 1st edition: 20191121
--gc-sections -ffunction-sections -fdata-section 這些選項是搭配用的, --gc-sections 是 ld option, -ffunction-sections -fdata-section 是 compiler 用的。
  1. 使用--gc-section编译选项减小程序体积
  2. -ffunction-sections -Wl,--gc-sections
這兩篇文章說明了這些選項的功用, 我主要以實際的例子做個補充。

k.c 有個 abc(), abc() 呼叫了 def(), 但是 def() 沒有定義, 學校教學或是書上的 c 語言書籍一定會跟你說這樣是編譯不過的, 會有 linking error。

k.c
 1 
 2 void def();
 3 
 4 void abc()
 5 {
 6   def();
 7 }
 8 
 9 int xyz(int a)
10 {
11   return a+2; 
12 }
13 
14 int main(void)
15 {
16   return xyz(3);
17 }

但在現實的工程上就是會有些不同, 運用了編譯器/連結器的特異功能, 這個程式是可以正確編譯的。因為 main() 根本沒呼叫 abc(), 如果只編譯/連結 main(), xyz() 應該就可以過關, 這便是 --gc-sections, -ffunction-sections 的組合技用法。

list 2
$ g++ -o k k.cpp
/usr/bin/ld: /tmp/ccLiBePh.o: in function `abc()':
k.cpp:(.text+0x5): undefined reference to `def()'
collect2: error: ld returned 1 exit status

list 3
$ g++ -o k k.cpp -Wl,--gc-sections -ffunction-sections

list 2. 沒有 -Wl,--gc-sections, 有預期的 linking error, 沒有定義 def(); list 3 加入了 -Wl,--gc-sections, 成功 link。

原理就是第一篇文章說的那樣, 需要理解 section 這個東西, 才能理解文章的內容。

來看看他們的 section 有何不同。 list 5 L27 只有 .text section, 並沒有為每一個 function 產生一個 section。

list 5 k.o
 1 ELF Header:
 2   Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
 3   Class:                             ELF64
 4   Data:                              2's complement, little endian
 5   Version:                           1 (current)
 6   OS/ABI:                            UNIX - System V
 7   ABI Version:                       0
 8   Type:                              REL (Relocatable file)
 9   Machine:                           Advanced Micro Devices X86-64
10   Version:                           0x1
11   Entry point address:               0x0
12   Start of program headers:          0 (bytes into file)
13   Start of section headers:          840 (bytes into file)
14   Flags:                             0x0
15   Size of this header:               64 (bytes)
16   Size of program headers:           0 (bytes)
17   Number of program headers:         0
18   Size of section headers:           64 (bytes)
19   Number of section headers:         12
20   Section header string table index: 11
21 
22 Section Headers:
23   [Nr] Name              Type             Address           Offset
24        Size              EntSize          Flags  Link  Info  Align
25   [ 0]                   NULL             0000000000000000  00000000
26        0000000000000000  0000000000000000           0     0     0
27   [ 1] .text             PROGBITS         0000000000000000  00000040
28        0000000000000030  0000000000000000  AX       0     0     1
29   [ 2] .rela.text        RELA             0000000000000000  00000270
30        0000000000000030  0000000000000018   I       9     1     8
31   [ 3] .data             PROGBITS         0000000000000000  00000070
32        0000000000000000  0000000000000000  WA       0     0     1
33   [ 4] .bss              NOBITS           0000000000000000  00000070
34        0000000000000000  0000000000000000  WA       0     0     1
35   [ 5] .comment          PROGBITS         0000000000000000  00000070
36        000000000000001e  0000000000000001  MS       0     0     1
37   [ 6] .note.GNU-stack   PROGBITS         0000000000000000  0000008e
38        0000000000000000  0000000000000000           0     0     1
39   [ 7] .eh_frame         PROGBITS         0000000000000000  00000090
40        0000000000000078  0000000000000000   A       0     0     8
41   [ 8] .rela.eh_frame    RELA             0000000000000000  000002a0
42        0000000000000048  0000000000000018   I       9     7     8
43   [ 9] .symtab           SYMTAB           0000000000000000  00000108
44        0000000000000138  0000000000000018          10     8     8
45   [10] .strtab           STRTAB           0000000000000000  00000240
46        000000000000002c  0000000000000000           0     0     1
47   [11] .shstrtab         STRTAB           0000000000000000  000002e8
48        0000000000000059  0000000000000000           0     0     1
49 Key to Flags:
50   W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
51   L (link order), O (extra OS processing required), G (group), T (TLS),
52   C (compressed), x (unknown), o (OS specific), E (exclude),
53   l (large), p (processor specific)
54 
55 There are no section groups in this file.
56 
57 There are no program headers in this file.
58 
59 There is no dynamic section in this file.
60 
61 Relocation section '.rela.text' at offset 0x270 contains 2 entries:
62   Offset          Info           Type           Sym. Value    Sym. Name + Addend
63 00000000000a  000a00000004 R_X86_64_PLT32    0000000000000000 def - 4
64 00000000002a  000b00000004 R_X86_64_PLT32    0000000000000011 xyz - 4
65 
66 Relocation section '.rela.eh_frame' at offset 0x2a0 contains 3 entries:
67   Offset          Info           Type           Sym. Value    Sym. Name + Addend
68 000000000020  000200000002 R_X86_64_PC32     0000000000000000 .text + 0
69 000000000040  000200000002 R_X86_64_PC32     0000000000000000 .text + 11
70 000000000060  000200000002 R_X86_64_PC32     0000000000000000 .text + 20
71 
72 The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.
73 
74 Symbol table '.symtab' contains 13 entries:
75    Num:    Value          Size Type    Bind   Vis      Ndx Name
76      0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
77      1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS k.c
78      2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
79      3: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
80      4: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
81      5: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 
82      6: 0000000000000000     0 SECTION LOCAL  DEFAULT    7 
83      7: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
84      8: 0000000000000000    17 FUNC    GLOBAL DEFAULT    1 abc
85      9: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND _GLOBAL_OFFSET_TABLE_
86     10: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND def
87     11: 0000000000000011    15 FUNC    GLOBAL DEFAULT    1 xyz
88     12: 0000000000000020    16 FUNC    GLOBAL DEFAULT    1 main
89 
90 No version information found in this file.

list 6 L33, 37, 39 為每一個 function 產生一個 section, 這樣 linker 就可以把 .text.abc section 移除, 就可以輸出 elf 執行檔。

list 6. k.gc-section.o
  1 ELF Header:
  2   Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  3   Class:                             ELF64
  4   Data:                              2's complement, little endian
  5   Version:                           1 (current)
  6   OS/ABI:                            UNIX - System V
  7   ABI Version:                       0
  8   Type:                              REL (Relocatable file)
  9   Machine:                           Advanced Micro Devices X86-64
 10   Version:                           0x1
 11   Entry point address:               0x0
 12   Start of program headers:          0 (bytes into file)
 13   Start of section headers:          944 (bytes into file)
 14   Flags:                             0x0
 15   Size of this header:               64 (bytes)
 16   Size of program headers:           0 (bytes)
 17   Number of program headers:         0
 18   Size of section headers:           64 (bytes)
 19   Number of section headers:         16
 20   Section header string table index: 15
 21 
 22 Section Headers:
 23   [Nr] Name              Type             Address           Offset
 24        Size              EntSize          Flags  Link  Info  Align
 25   [ 0]                   NULL             0000000000000000  00000000
 26        0000000000000000  0000000000000000           0     0     0
 27   [ 1] .text             PROGBITS         0000000000000000  00000040
 28        0000000000000000  0000000000000000  AX       0     0     1
 29   [ 2] .data             PROGBITS         0000000000000000  00000040
 30        0000000000000000  0000000000000000  WA       0     0     1
 31   [ 3] .bss              NOBITS           0000000000000000  00000040
 32        0000000000000000  0000000000000000  WA       0     0     1
 33   [ 4] .text.abc         PROGBITS         0000000000000000  00000040
 34        0000000000000011  0000000000000000  AX       0     0     1
 35   [ 5] .rela.text.abc    RELA             0000000000000000  000002b8
 36        0000000000000018  0000000000000018   I      13     4     8
 37   [ 6] .text.xyz         PROGBITS         0000000000000000  00000051
 38        000000000000000f  0000000000000000  AX       0     0     1
 39   [ 7] .text.main        PROGBITS         0000000000000000  00000060
 40        0000000000000010  0000000000000000  AX       0     0     1
 41   [ 8] .rela.text.main   RELA             0000000000000000  000002d0
 42        0000000000000018  0000000000000018   I      13     7     8
 43   [ 9] .comment          PROGBITS         0000000000000000  00000070
 44        000000000000001e  0000000000000001  MS       0     0     1
 45   [10] .note.GNU-stack   PROGBITS         0000000000000000  0000008e
 46        0000000000000000  0000000000000000           0     0     1
 47   [11] .eh_frame         PROGBITS         0000000000000000  00000090
 48        0000000000000078  0000000000000000   A       0     0     8
 49   [12] .rela.eh_frame    RELA             0000000000000000  000002e8
 50        0000000000000048  0000000000000018   I      13    11     8
 51   [13] .symtab           SYMTAB           0000000000000000  00000108
 52        0000000000000180  0000000000000018          14    11     8
 53   [14] .strtab           STRTAB           0000000000000000  00000288
 54        000000000000002c  0000000000000000           0     0     1
 55   [15] .shstrtab         STRTAB           0000000000000000  00000330
 56        000000000000007d  0000000000000000           0     0     1
 57 Key to Flags:
 58   W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
 59   L (link order), O (extra OS processing required), G (group), T (TLS),
 60   C (compressed), x (unknown), o (OS specific), E (exclude),
 61   l (large), p (processor specific)
 62 
 63 There are no section groups in this file.
 64 
 65 There are no program headers in this file.
 66 
 67 There is no dynamic section in this file.
 68 
 69 Relocation section '.rela.text.abc' at offset 0x2b8 contains 1 entry:
 70   Offset          Info           Type           Sym. Value    Sym. Name + Addend
 71 00000000000a  000d00000004 R_X86_64_PLT32    0000000000000000 def - 4
 72 
 73 Relocation section '.rela.text.main' at offset 0x2d0 contains 1 entry:
 74   Offset          Info           Type           Sym. Value    Sym. Name + Addend
 75 00000000000a  000e00000004 R_X86_64_PLT32    0000000000000000 xyz - 4
 76 
 77 Relocation section '.rela.eh_frame' at offset 0x2e8 contains 3 entries:
 78   Offset          Info           Type           Sym. Value    Sym. Name + Addend
 79 000000000020  000500000002 R_X86_64_PC32     0000000000000000 .text.abc + 0
 80 000000000040  000600000002 R_X86_64_PC32     0000000000000000 .text.xyz + 0
 81 000000000060  000700000002 R_X86_64_PC32     0000000000000000 .text.main + 0
 82 
 83 The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.
 84 
 85 Symbol table '.symtab' contains 16 entries:
 86    Num:    Value          Size Type    Bind   Vis      Ndx Name
 87      0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
 88      1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS k.c
 89      2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
 90      3: 0000000000000000     0 SECTION LOCAL  DEFAULT    2 
 91      4: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
 92      5: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
 93      6: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 
 94      7: 0000000000000000     0 SECTION LOCAL  DEFAULT    7 
 95      8: 0000000000000000     0 SECTION LOCAL  DEFAULT   10 
 96      9: 0000000000000000     0 SECTION LOCAL  DEFAULT   11 
 97     10: 0000000000000000     0 SECTION LOCAL  DEFAULT    9 
 98     11: 0000000000000000    17 FUNC    GLOBAL DEFAULT    4 abc
 99     12: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND _GLOBAL_OFFSET_TABLE_
100     13: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND def
101     14: 0000000000000000    15 FUNC    GLOBAL DEFAULT    6 xyz
102     15: 0000000000000000    16 FUNC    GLOBAL DEFAULT    7 main
103 
104 No version information found in this file.

沒有留言:

張貼留言

使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。

我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。