```c
#include <stdio.h>
#include <stdbool.h>
#define STRUCT_INIT 0
static void func_a(void);
static void func_b(void);
typedef struct test_s {
void (*const func_a)(void);
void (*const func_b)(void);
} test_t;
#if STRUCT_INIT == 1
test_t test = {
.func_a = func_a,
.func_b = func_b,
};
#endif
static void func_a(void)
{
printf("%s", __func__);
}
static void func_b(void)
{
printf("%s", __func__);
}
int main(void)
{
#if STRUCT_INIT == 1
#else
test_t test = {.func_a = func_a};
#endif
test.func_a();
return 0;
}
```
反組譯
```bash
$ gcc -fdata-sections -ffunction-sections foo.c -o foo -Wl,--gc-sections
$ objdump -d foo > foo.txt
#$ objdump -d foo > foo_no_init.txt
```
初始化結構(STRUCT_INIT == 1), 函數會加入物件, 有 func_b
```asm
foo: file format elf64-x86-64
Disassembly of section .init:
0000000000001000 <_init>:
1000: f3 0f 1e fa endbr64
1004: 48 83 ec 08 sub $0x8,%rsp
1008: 48 8b 05 d9 2f 00 00 mov 0x2fd9(%rip),%rax # 3fe8 <__gmon_start__>
100f: 48 85 c0 test %rax,%rax
1012: 74 02 je 1016 <_init+0x16>
1014: ff d0 callq *%rax
1016: 48 83 c4 08 add $0x8,%rsp
101a: c3 retq
Disassembly of section .plt:
0000000000001020 <.plt>:
1020: ff 35 9a 2f 00 00 pushq 0x2f9a(%rip) # 3fc0 <_GLOBAL_OFFSET_TABLE_+0x8>
1026: f2 ff 25 9b 2f 00 00 bnd jmpq *0x2f9b(%rip) # 3fc8 <_GLOBAL_OFFSET_TABLE_+0x10>
102d: 0f 1f 00 nopl (%rax)
1030: f3 0f 1e fa endbr64
1034: 68 00 00 00 00 pushq $0x0
1039: f2 e9 e1 ff ff ff bnd jmpq 1020 <.plt>
103f: 90 nop
Disassembly of section .plt.got:
0000000000001040 <__cxa_finalize@plt>:
1040: f3 0f 1e fa endbr64
1044: f2 ff 25 ad 2f 00 00 bnd jmpq *0x2fad(%rip) # 3ff8 <__cxa_finalize@GLIBC_2.2.5>
104b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
Disassembly of section .plt.sec:
0000000000001050 <printf@plt>:
1050: f3 0f 1e fa endbr64
1054: f2 ff 25 75 2f 00 00 bnd jmpq *0x2f75(%rip) # 3fd0 <printf@GLIBC_2.2.5>
105b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
Disassembly of section .text:
0000000000001060 <_start>:
1060: f3 0f 1e fa endbr64
1064: 31 ed xor %ebp,%ebp
1066: 49 89 d1 mov %rdx,%r9
1069: 5e pop %rsi
106a: 48 89 e2 mov %rsp,%rdx
106d: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp
1071: 50 push %rax
1072: 54 push %rsp
1073: 4c 8d 05 a6 01 00 00 lea 0x1a6(%rip),%r8 # 1220 <__libc_csu_fini>
107a: 48 8d 0d 2f 01 00 00 lea 0x12f(%rip),%rcx # 11b0 <__libc_csu_init>
1081: 48 8d 3d 07 01 00 00 lea 0x107(%rip),%rdi # 118f <main>
1088: ff 15 52 2f 00 00 callq *0x2f52(%rip) # 3fe0 <__libc_start_main@GLIBC_2.2.5>
108e: f4 hlt
108f: 90 nop
0000000000001090 <deregister_tm_clones>:
1090: 48 8d 3d 89 2f 00 00 lea 0x2f89(%rip),%rdi # 4020 <__TMC_END__>
1097: 48 8d 05 82 2f 00 00 lea 0x2f82(%rip),%rax # 4020 <__TMC_END__>
109e: 48 39 f8 cmp %rdi,%rax
10a1: 74 15 je 10b8 <deregister_tm_clones+0x28>
10a3: 48 8b 05 2e 2f 00 00 mov 0x2f2e(%rip),%rax # 3fd8 <_ITM_deregisterTMCloneTable>
10aa: 48 85 c0 test %rax,%rax
10ad: 74 09 je 10b8 <deregister_tm_clones+0x28>
10af: ff e0 jmpq *%rax
10b1: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
10b8: c3 retq
10b9: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
00000000000010c0 <register_tm_clones>:
10c0: 48 8d 3d 59 2f 00 00 lea 0x2f59(%rip),%rdi # 4020 <__TMC_END__>
10c7: 48 8d 35 52 2f 00 00 lea 0x2f52(%rip),%rsi # 4020 <__TMC_END__>
10ce: 48 29 fe sub %rdi,%rsi
10d1: 48 89 f0 mov %rsi,%rax
10d4: 48 c1 ee 3f shr $0x3f,%rsi
10d8: 48 c1 f8 03 sar $0x3,%rax
10dc: 48 01 c6 add %rax,%rsi
10df: 48 d1 fe sar %rsi
10e2: 74 14 je 10f8 <register_tm_clones+0x38>
10e4: 48 8b 05 05 2f 00 00 mov 0x2f05(%rip),%rax # 3ff0 <_ITM_registerTMCloneTable>
10eb: 48 85 c0 test %rax,%rax
10ee: 74 08 je 10f8 <register_tm_clones+0x38>
10f0: ff e0 jmpq *%rax
10f2: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)
10f8: c3 retq
10f9: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
0000000000001100 <__do_global_dtors_aux>:
1100: f3 0f 1e fa endbr64
1104: 80 3d 15 2f 00 00 00 cmpb $0x0,0x2f15(%rip) # 4020 <__TMC_END__>
110b: 75 2b jne 1138 <__do_global_dtors_aux+0x38>
110d: 55 push %rbp
110e: 48 83 3d e2 2e 00 00 cmpq $0x0,0x2ee2(%rip) # 3ff8 <__cxa_finalize@GLIBC_2.2.5>
1115: 00
1116: 48 89 e5 mov %rsp,%rbp
1119: 74 0c je 1127 <__do_global_dtors_aux+0x27>
111b: 48 8b 3d de 2e 00 00 mov 0x2ede(%rip),%rdi # 4000 <__dso_handle>
1122: e8 19 ff ff ff callq 1040 <__cxa_finalize@plt>
1127: e8 64 ff ff ff callq 1090 <deregister_tm_clones>
112c: c6 05 ed 2e 00 00 01 movb $0x1,0x2eed(%rip) # 4020 <__TMC_END__>
1133: 5d pop %rbp
1134: c3 retq
1135: 0f 1f 00 nopl (%rax)
1138: c3 retq
1139: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
0000000000001140 <frame_dummy>:
1140: f3 0f 1e fa endbr64
1144: e9 77 ff ff ff jmpq 10c0 <register_tm_clones>
0000000000001149 <func_a>:
1149: f3 0f 1e fa endbr64
114d: 55 push %rbp
114e: 48 89 e5 mov %rsp,%rbp
1151: 48 8d 35 ab 0e 00 00 lea 0xeab(%rip),%rsi # 2003 <__func__.2327>
1158: 48 8d 3d a1 0e 00 00 lea 0xea1(%rip),%rdi # 2000 <_fini+0xdd8>
115f: b8 00 00 00 00 mov $0x0,%eax
1164: e8 e7 fe ff ff callq 1050 <printf@plt>
1169: 90 nop
116a: 5d pop %rbp
116b: c3 retq
000000000000116c <func_b>:
116c: f3 0f 1e fa endbr64
1170: 55 push %rbp
1171: 48 89 e5 mov %rsp,%rbp
1174: 48 8d 35 8f 0e 00 00 lea 0xe8f(%rip),%rsi # 200a <__func__.2331>
117b: 48 8d 3d 7e 0e 00 00 lea 0xe7e(%rip),%rdi # 2000 <_fini+0xdd8>
1182: b8 00 00 00 00 mov $0x0,%eax
1187: e8 c4 fe ff ff callq 1050 <printf@plt>
118c: 90 nop
118d: 5d pop %rbp
118e: c3 retq
000000000000118f <main>:
118f: f3 0f 1e fa endbr64
1193: 55 push %rbp
1194: 48 89 e5 mov %rsp,%rbp
1197: 48 8b 05 72 2e 00 00 mov 0x2e72(%rip),%rax # 4010 <test>
119e: ff d0 callq *%rax
11a0: b8 00 00 00 00 mov $0x0,%eax
11a5: 5d pop %rbp
11a6: c3 retq
11a7: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1)
11ae: 00 00
00000000000011b0 <__libc_csu_init>:
11b0: f3 0f 1e fa endbr64
11b4: 41 57 push %r15
11b6: 4c 8d 3d fb 2b 00 00 lea 0x2bfb(%rip),%r15 # 3db8 <__frame_dummy_init_array_entry>
11bd: 41 56 push %r14
11bf: 49 89 d6 mov %rdx,%r14
11c2: 41 55 push %r13
11c4: 49 89 f5 mov %rsi,%r13
11c7: 41 54 push %r12
11c9: 41 89 fc mov %edi,%r12d
11cc: 55 push %rbp
11cd: 48 8d 2d ec 2b 00 00 lea 0x2bec(%rip),%rbp # 3dc0 <__do_global_dtors_aux_fini_array_entry>
11d4: 53 push %rbx
11d5: 4c 29 fd sub %r15,%rbp
11d8: 48 83 ec 08 sub $0x8,%rsp
11dc: e8 1f fe ff ff callq 1000 <_init>
11e1: 48 c1 fd 03 sar $0x3,%rbp
11e5: 74 1f je 1206 <__libc_csu_init+0x56>
11e7: 31 db xor %ebx,%ebx
11e9: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
11f0: 4c 89 f2 mov %r14,%rdx
11f3: 4c 89 ee mov %r13,%rsi
11f6: 44 89 e7 mov %r12d,%edi
11f9: 41 ff 14 df callq *(%r15,%rbx,8)
11fd: 48 83 c3 01 add $0x1,%rbx
1201: 48 39 dd cmp %rbx,%rbp
1204: 75 ea jne 11f0 <__libc_csu_init+0x40>
1206: 48 83 c4 08 add $0x8,%rsp
120a: 5b pop %rbx
120b: 5d pop %rbp
120c: 41 5c pop %r12
120e: 41 5d pop %r13
1210: 41 5e pop %r14
1212: 41 5f pop %r15
1214: c3 retq
1215: 66 66 2e 0f 1f 84 00 data16 nopw %cs:0x0(%rax,%rax,1)
121c: 00 00 00 00
0000000000001220 <__libc_csu_fini>:
1220: f3 0f 1e fa endbr64
1224: c3 retq
Disassembly of section .fini:
0000000000001228 <_fini>:
1228: f3 0f 1e fa endbr64
122c: 48 83 ec 08 sub $0x8,%rsp
1230: 48 83 c4 08 add $0x8,%rsp
1234: c3 retq
```
初始化結構(STRUCT_INIT == 0), 函數不會加入物件, 無 func_b
```asm
foo: file format elf64-x86-64
Disassembly of section .init:
0000000000001000 <_init>:
1000: f3 0f 1e fa endbr64
1004: 48 83 ec 08 sub $0x8,%rsp
1008: 48 8b 05 d9 2f 00 00 mov 0x2fd9(%rip),%rax # 3fe8 <__gmon_start__>
100f: 48 85 c0 test %rax,%rax
1012: 74 02 je 1016 <_init+0x16>
1014: ff d0 callq *%rax
1016: 48 83 c4 08 add $0x8,%rsp
101a: c3 retq
Disassembly of section .plt:
0000000000001020 <.plt>:
1020: ff 35 9a 2f 00 00 pushq 0x2f9a(%rip) # 3fc0 <_GLOBAL_OFFSET_TABLE_+0x8>
1026: f2 ff 25 9b 2f 00 00 bnd jmpq *0x2f9b(%rip) # 3fc8 <_GLOBAL_OFFSET_TABLE_+0x10>
102d: 0f 1f 00 nopl (%rax)
1030: f3 0f 1e fa endbr64
1034: 68 00 00 00 00 pushq $0x0
1039: f2 e9 e1 ff ff ff bnd jmpq 1020 <.plt>
103f: 90 nop
Disassembly of section .plt.got:
0000000000001040 <__cxa_finalize@plt>:
1040: f3 0f 1e fa endbr64
1044: f2 ff 25 ad 2f 00 00 bnd jmpq *0x2fad(%rip) # 3ff8 <__cxa_finalize@GLIBC_2.2.5>
104b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
Disassembly of section .plt.sec:
0000000000001050 <printf@plt>:
1050: f3 0f 1e fa endbr64
1054: f2 ff 25 75 2f 00 00 bnd jmpq *0x2f75(%rip) # 3fd0 <printf@GLIBC_2.2.5>
105b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
Disassembly of section .text:
0000000000001060 <_start>:
1060: f3 0f 1e fa endbr64
1064: 31 ed xor %ebp,%ebp
1066: 49 89 d1 mov %rdx,%r9
1069: 5e pop %rsi
106a: 48 89 e2 mov %rsp,%rdx
106d: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp
1071: 50 push %rax
1072: 54 push %rsp
1073: 4c 8d 05 96 01 00 00 lea 0x196(%rip),%r8 # 1210 <__libc_csu_fini>
107a: 48 8d 0d 1f 01 00 00 lea 0x11f(%rip),%rcx # 11a0 <__libc_csu_init>
1081: 48 8d 3d e4 00 00 00 lea 0xe4(%rip),%rdi # 116c <main>
1088: ff 15 52 2f 00 00 callq *0x2f52(%rip) # 3fe0 <__libc_start_main@GLIBC_2.2.5>
108e: f4 hlt
108f: 90 nop
0000000000001090 <deregister_tm_clones>:
1090: 48 8d 3d 71 2f 00 00 lea 0x2f71(%rip),%rdi # 4008 <__TMC_END__>
1097: 48 8d 05 6a 2f 00 00 lea 0x2f6a(%rip),%rax # 4008 <__TMC_END__>
109e: 48 39 f8 cmp %rdi,%rax
10a1: 74 15 je 10b8 <deregister_tm_clones+0x28>
10a3: 48 8b 05 2e 2f 00 00 mov 0x2f2e(%rip),%rax # 3fd8 <_ITM_deregisterTMCloneTable>
10aa: 48 85 c0 test %rax,%rax
10ad: 74 09 je 10b8 <deregister_tm_clones+0x28>
10af: ff e0 jmpq *%rax
10b1: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
10b8: c3 retq
10b9: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
00000000000010c0 <register_tm_clones>:
10c0: 48 8d 3d 41 2f 00 00 lea 0x2f41(%rip),%rdi # 4008 <__TMC_END__>
10c7: 48 8d 35 3a 2f 00 00 lea 0x2f3a(%rip),%rsi # 4008 <__TMC_END__>
10ce: 48 29 fe sub %rdi,%rsi
10d1: 48 89 f0 mov %rsi,%rax
10d4: 48 c1 ee 3f shr $0x3f,%rsi
10d8: 48 c1 f8 03 sar $0x3,%rax
10dc: 48 01 c6 add %rax,%rsi
10df: 48 d1 fe sar %rsi
10e2: 74 14 je 10f8 <register_tm_clones+0x38>
10e4: 48 8b 05 05 2f 00 00 mov 0x2f05(%rip),%rax # 3ff0 <_ITM_registerTMCloneTable>
10eb: 48 85 c0 test %rax,%rax
10ee: 74 08 je 10f8 <register_tm_clones+0x38>
10f0: ff e0 jmpq *%rax
10f2: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)
10f8: c3 retq
10f9: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
0000000000001100 <__do_global_dtors_aux>:
1100: f3 0f 1e fa endbr64
1104: 80 3d fd 2e 00 00 00 cmpb $0x0,0x2efd(%rip) # 4008 <__TMC_END__>
110b: 75 2b jne 1138 <__do_global_dtors_aux+0x38>
110d: 55 push %rbp
110e: 48 83 3d e2 2e 00 00 cmpq $0x0,0x2ee2(%rip) # 3ff8 <__cxa_finalize@GLIBC_2.2.5>
1115: 00
1116: 48 89 e5 mov %rsp,%rbp
1119: 74 0c je 1127 <__do_global_dtors_aux+0x27>
111b: 48 8b 3d de 2e 00 00 mov 0x2ede(%rip),%rdi # 4000 <__dso_handle>
1122: e8 19 ff ff ff callq 1040 <__cxa_finalize@plt>
1127: e8 64 ff ff ff callq 1090 <deregister_tm_clones>
112c: c6 05 d5 2e 00 00 01 movb $0x1,0x2ed5(%rip) # 4008 <__TMC_END__>
1133: 5d pop %rbp
1134: c3 retq
1135: 0f 1f 00 nopl (%rax)
1138: c3 retq
1139: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
0000000000001140 <frame_dummy>:
1140: f3 0f 1e fa endbr64
1144: e9 77 ff ff ff jmpq 10c0 <register_tm_clones>
0000000000001149 <func_a>:
1149: f3 0f 1e fa endbr64
114d: 55 push %rbp
114e: 48 89 e5 mov %rsp,%rbp
1151: 48 8d 35 ab 0e 00 00 lea 0xeab(%rip),%rsi # 2003 <__func__.2326>
1158: 48 8d 3d a1 0e 00 00 lea 0xea1(%rip),%rdi # 2000 <_fini+0xde8>
115f: b8 00 00 00 00 mov $0x0,%eax
1164: e8 e7 fe ff ff callq 1050 <printf@plt>
1169: 90 nop
116a: 5d pop %rbp
116b: c3 retq
000000000000116c <main>:
116c: f3 0f 1e fa endbr64
1170: 55 push %rbp
1171: 48 89 e5 mov %rsp,%rbp
1174: 48 83 ec 10 sub $0x10,%rsp
1178: 48 c7 45 f0 00 00 00 movq $0x0,-0x10(%rbp)
117f: 00
1180: 48 c7 45 f8 00 00 00 movq $0x0,-0x8(%rbp)
1187: 00
1188: 48 8d 05 ba ff ff ff lea -0x46(%rip),%rax # 1149 <func_a>
118f: 48 89 45 f0 mov %rax,-0x10(%rbp)
1193: 48 8b 45 f0 mov -0x10(%rbp),%rax
1197: ff d0 callq *%rax
1199: b8 00 00 00 00 mov $0x0,%eax
119e: c9 leaveq
119f: c3 retq
00000000000011a0 <__libc_csu_init>:
11a0: f3 0f 1e fa endbr64
11a4: 41 57 push %r15
11a6: 4c 8d 3d 0b 2c 00 00 lea 0x2c0b(%rip),%r15 # 3db8 <__frame_dummy_init_array_entry>
11ad: 41 56 push %r14
11af: 49 89 d6 mov %rdx,%r14
11b2: 41 55 push %r13
11b4: 49 89 f5 mov %rsi,%r13
11b7: 41 54 push %r12
11b9: 41 89 fc mov %edi,%r12d
11bc: 55 push %rbp
11bd: 48 8d 2d fc 2b 00 00 lea 0x2bfc(%rip),%rbp # 3dc0 <__do_global_dtors_aux_fini_array_entry>
11c4: 53 push %rbx
11c5: 4c 29 fd sub %r15,%rbp
11c8: 48 83 ec 08 sub $0x8,%rsp
11cc: e8 2f fe ff ff callq 1000 <_init>
11d1: 48 c1 fd 03 sar $0x3,%rbp
11d5: 74 1f je 11f6 <__libc_csu_init+0x56>
11d7: 31 db xor %ebx,%ebx
11d9: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
11e0: 4c 89 f2 mov %r14,%rdx
11e3: 4c 89 ee mov %r13,%rsi
11e6: 44 89 e7 mov %r12d,%edi
11e9: 41 ff 14 df callq *(%r15,%rbx,8)
11ed: 48 83 c3 01 add $0x1,%rbx
11f1: 48 39 dd cmp %rbx,%rbp
11f4: 75 ea jne 11e0 <__libc_csu_init+0x40>
11f6: 48 83 c4 08 add $0x8,%rsp
11fa: 5b pop %rbx
11fb: 5d pop %rbp
11fc: 41 5c pop %r12
11fe: 41 5d pop %r13
1200: 41 5e pop %r14
1202: 41 5f pop %r15
1204: c3 retq
1205: 66 66 2e 0f 1f 84 00 data16 nopw %cs:0x0(%rax,%rax,1)
120c: 00 00 00 00
0000000000001210 <__libc_csu_fini>:
1210: f3 0f 1e fa endbr64
1214: c3 retq
Disassembly of section .fini:
0000000000001218 <_fini>:
1218: f3 0f 1e fa endbr64
121c: 48 83 ec 08 sub $0x8,%rsp
1220: 48 83 c4 08 add $0x8,%rsp
1224: c3 retq
```