My code works, I don’t know why.

國王的耳朵是驢耳朵

Gcc Obj File Symbols

| Comments

自用

測試環境

1
2
3
4
5
6
7
8
9
10
11
12
$ lsb_release -a
No LSB modules are available.
Distributor ID:   Ubuntu
Description:  Ubuntu 18.04.2 LTS
Release:  18.04
Codename: bionic

$ gcc --version
gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0

$ dpkg -l | grep libc6:amd64 
ii  libc6:amd64                                   2.27-3ubuntu1                                amd64        GNU C Library: Shared libraries

目錄

gcc 7

/usr/lib/gcc/x86_64-linux-gnu/7/crtbegin.o:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
0000000000000000 b .bss
0000000000000000 n .comment
0000000000000000 b completed.7697
0000000000000000 a crtstuff.c
0000000000000000 d .data
0000000000000000 t deregister_tm_clones
0000000000000070 t __do_global_dtors_aux
0000000000000000 t __do_global_dtors_aux_fini_array_entry
0000000000000000 D __dso_handle
0000000000000000 t .fini_array
00000000000000a0 t frame_dummy
0000000000000000 t __frame_dummy_init_array_entry
0000000000000000 t .init_array
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
0000000000000000 n .note.GNU-stack
0000000000000030 t register_tm_clones
0000000000000000 t .text
                 U __TMC_END__
0000000000000000 d __TMC_LIST__
0000000000000000 d .tm_clone_table

/usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
0000000000000000 b .bss
0000000000000000 n .comment
0000000000000000 b completed.7697
0000000000000000 a crtstuff.c
                 w __cxa_finalize
0000000000000000 d .data
0000000000000000 d .data.rel.local
0000000000000000 t deregister_tm_clones
0000000000000090 t __do_global_dtors_aux
0000000000000000 t __do_global_dtors_aux_fini_array_entry
0000000000000000 D __dso_handle
0000000000000000 t .fini_array
00000000000000d0 t frame_dummy
0000000000000000 t __frame_dummy_init_array_entry
                 U _GLOBAL_OFFSET_TABLE_
0000000000000000 t .init_array
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
0000000000000000 n .note.GNU-stack
0000000000000040 t register_tm_clones
0000000000000000 t .text
                 U __TMC_END__
0000000000000000 d __TMC_LIST__
0000000000000000 d .tm_clone_table

/usr/lib/gcc/x86_64-linux-gnu/7/crtbeginT.o:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
0000000000000000 b .bss
0000000000000000 n .comment
0000000000000000 b completed.7146
0000000000000000 a crtstuff.c
0000000000000000 d .data
                 w __deregister_frame_info
0000000000000000 t deregister_tm_clones
0000000000000070 t __do_global_dtors_aux
0000000000000000 t __do_global_dtors_aux_fini_array_entry
0000000000000000 D __dso_handle
0000000000000000 r .eh_frame
0000000000000000 r __EH_FRAME_BEGIN__
0000000000000000 t .fini_array
00000000000000b0 t frame_dummy
0000000000000000 t __frame_dummy_init_array_entry
0000000000000000 t .init_array
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
0000000000000000 n .note.GNU-stack
0000000000000020 b object.7151
                 w __register_frame_info
0000000000000030 t register_tm_clones
0000000000000000 t .text
                 U __TMC_END__
0000000000000000 d __TMC_LIST__
0000000000000000 d .tm_clone_table

/usr/lib/gcc/x86_64-linux-gnu/7/crtend.o:

1
2
3
4
5
6
7
8
9
10
0000000000000000 b .bss
0000000000000000 n .comment
0000000000000000 a crtstuff.c
0000000000000000 d .data
0000000000000000 r .eh_frame
0000000000000000 r __FRAME_END__
0000000000000000 n .note.GNU-stack
0000000000000000 t .text
0000000000000000 D __TMC_END__
0000000000000000 d .tm_clone_table

/usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o:

1
2
3
4
5
6
7
8
9
10
0000000000000000 b .bss
0000000000000000 n .comment
0000000000000000 a crtstuff.c
0000000000000000 d .data
0000000000000000 r .eh_frame
0000000000000000 r __FRAME_END__
0000000000000000 n .note.GNU-stack
0000000000000000 t .text
0000000000000000 D __TMC_END__
0000000000000000 d .tm_clone_table

/usr/lib/gcc/x86_64-linux-gnu/7/crtfastmath.o:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
0000000000000000 b .bss
0000000000000000 n .comment
0000000000000000 a crtfastmath.c
0000000000000000 d .data
0000000000000000 N .debug_abbrev
0000000000000000 N .debug_aranges
0000000000000000 N .debug_info
0000000000000000 N .debug_line
0000000000000000 N .debug_loc
0000000000000000 N .debug_ranges
0000000000000000 N .debug_str
0000000000000000 r .eh_frame
0000000000000000 t .init_array
0000000000000000 n .note.GNU-stack
0000000000000000 t set_fast_math
0000000000000000 t .text
0000000000000000 t .text.startup

/usr/lib/gcc/x86_64-linux-gnu/7/crtoffloadbegin.o:

1
2
3
4
5
6
7
8
9
10
0000000000000000 b .bss
0000000000000000 n .comment
0000000000000000 d .data
0000000000000000 r .gnu.offload_funcs
0000000000000000 r .gnu.offload_vars
0000000000000000 n .note.GNU-stack
0000000000000000 R __offload_func_table
0000000000000000 a offloadstuff.c
0000000000000000 R __offload_var_table
0000000000000000 t .text

/usr/lib/gcc/x86_64-linux-gnu/7/crtoffloadend.o:

1
2
3
4
5
6
7
8
9
10
0000000000000000 b .bss
0000000000000000 n .comment
0000000000000000 d .data
0000000000000000 r .gnu.offload_funcs
0000000000000000 r .gnu.offload_vars
0000000000000000 n .note.GNU-stack
0000000000000000 R __offload_funcs_end
0000000000000000 a offloadstuff.c
0000000000000000 R __offload_vars_end
0000000000000000 t .text

/usr/lib/gcc/x86_64-linux-gnu/7/crtoffloadtable.o:

1
2
3
4
5
6
7
8
9
10
11
12
0000000000000000 b .bss
0000000000000000 n .comment
0000000000000000 d .data
0000000000000000 n .note.GNU-stack
                 U __offload_funcs_end
                 U __offload_func_table
0000000000000000 a offloadstuff.c
0000000000000000 R __OFFLOAD_TABLE__
                 U __offload_vars_end
                 U __offload_var_table
0000000000000000 r .rodata
0000000000000000 t .text

/usr/lib/gcc/x86_64-linux-gnu/7/crtprec32.o:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
0000000000000000 b .bss
0000000000000000 n .comment
0000000000000000 a crtprec.c
0000000000000000 d .data
0000000000000000 N .debug_abbrev
0000000000000000 N .debug_aranges
0000000000000000 N .debug_info
0000000000000000 N .debug_line
0000000000000000 N .debug_ranges
0000000000000000 N .debug_str
0000000000000000 r .eh_frame
0000000000000000 t .init_array
0000000000000000 n .note.GNU-stack
0000000000000000 t set_precision
0000000000000000 t .text
0000000000000000 t .text.startup

/usr/lib/gcc/x86_64-linux-gnu/7/crtprec64.o:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
0000000000000000 b .bss
0000000000000000 n .comment
0000000000000000 a crtprec.c
0000000000000000 d .data
0000000000000000 N .debug_abbrev
0000000000000000 N .debug_aranges
0000000000000000 N .debug_info
0000000000000000 N .debug_line
0000000000000000 N .debug_ranges
0000000000000000 N .debug_str
0000000000000000 r .eh_frame
0000000000000000 t .init_array
0000000000000000 n .note.GNU-stack
0000000000000000 t set_precision
0000000000000000 t .text
0000000000000000 t .text.startup

/usr/lib/gcc/x86_64-linux-gnu/7/crtprec80.o:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
0000000000000000 b .bss
0000000000000000 n .comment
0000000000000000 a crtprec.c
0000000000000000 d .data
0000000000000000 N .debug_abbrev
0000000000000000 N .debug_aranges
0000000000000000 N .debug_info
0000000000000000 N .debug_line
0000000000000000 N .debug_ranges
0000000000000000 N .debug_str
0000000000000000 r .eh_frame
0000000000000000 t .init_array
0000000000000000 n .note.GNU-stack
0000000000000000 t set_precision
0000000000000000 t .text
0000000000000000 t .text.startup

/usr/lib/gcc/x86_64-linux-gnu/7/libasan_preinit.o:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
             U __asan_init
0000000000000000 a asan_preinit.cc
0000000000000000 b .bss
0000000000000000 n .comment
0000000000000000 d .data
0000000000000000 N .debug_abbrev
0000000000000000 N .debug_aranges
0000000000000000 N .debug_info
0000000000000000 N .debug_line
0000000000000000 N .debug_str
0000000000000000 D __local_asan_preinit
0000000000000000 n .note.GNU-stack
0000000000000000 d .preinit_array
0000000000000000 t .text

glibc6

/usr/lib/x86_64-linux-gnu/crt1.o:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
0000000000000000 b .bss
0000000000000000 d .data
0000000000000000 D __data_start
0000000000000000 W data_start
0000000000000030 T _dl_relocate_static_pie
0000000000000000 r .eh_frame
                 U _GLOBAL_OFFSET_TABLE_
0000000000000000 R _IO_stdin_used
                 U __libc_csu_fini
                 U __libc_csu_init
                 U __libc_start_main
                 U main
0000000000000000 r .note.ABI-tag
0000000000000000 n .note.GNU-stack
0000000000000000 r .rodata.cst4
0000000000000000 T _start
0000000000000000 t .text

/usr/lib/x86_64-linux-gnu/crti.o:

1
2
3
4
5
6
7
8
9
10
0000000000000000 b .bss
0000000000000000 d .data
0000000000000000 T _fini
0000000000000000 t .fini
                 U _GLOBAL_OFFSET_TABLE_
                 w __gmon_start__
0000000000000000 T _init
0000000000000000 t .init
0000000000000000 n .note.GNU-stack
0000000000000000 t .text

/usr/lib/x86_64-linux-gnu/crtn.o:

1
nm: /usr/lib/x86_64-linux-gnu/crtn.o: no symbols

/usr/lib/x86_64-linux-gnu/gcrt1.o:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
             U atexit
0000000000000000 b .bss
0000000000000000 b called.4604
0000000000000000 d .data
0000000000000000 D __data_start
0000000000000000 W data_start
0000000000000080 T _dl_relocate_static_pie
0000000000000000 r .eh_frame
             U etext
             U __GI_memcpy
             U __GI_memmove
             U __GI_memset
             U _GLOBAL_OFFSET_TABLE_
0000000000000030 T __gmon_start__
0000000000000000 R _IO_stdin_used
             U __libc_csu_fini
             U __libc_csu_init
             U __libc_start_main
             U main
             U _mcleanup
             U __monstartup
0000000000000000 r .note.ABI-tag
0000000000000000 n .note.GNU-stack
0000000000000000 r .rodata.cst4
0000000000000000 T _start
0000000000000000 t .text

/usr/lib/x86_64-linux-gnu/grcrt1.o:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
             U atexit
0000000000000000 b .bss
0000000000000000 b called.4604
0000000000000000 d .data
0000000000000000 D __data_start
0000000000000000 W data_start
0000000000000000 r .eh_frame
             U etext
             U _GLOBAL_OFFSET_TABLE_
0000000000000030 T __gmon_start__
0000000000000000 R _IO_stdin_used
             U __libc_csu_fini
             U __libc_csu_init
             U __libc_start_main
             U main
             U _mcleanup
             U __monstartup
0000000000000000 r .note.ABI-tag
0000000000000000 n .note.GNU-stack
0000000000000000 r .rodata.cst4
0000000000000000 T _start
0000000000000000 t .text

/usr/lib/x86_64-linux-gnu/libtsan_preinit.o:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
0000000000000000 b .bss
0000000000000000 n .comment
0000000000000000 d .data
0000000000000000 N .debug_abbrev
0000000000000000 N .debug_aranges
0000000000000000 N .debug_info
0000000000000000 N .debug_line
0000000000000000 N .debug_str
0000000000000000 D __local_tsan_preinit
0000000000000000 n .note.GNU-stack
0000000000000000 d .preinit_array
0000000000000000 t .text
                 U __tsan_init
0000000000000000 a tsan_preinit.cc

/usr/lib/x86_64-linux-gnu/Mcrt1.o:

1
nm: /usr/lib/x86_64-linux-gnu/Mcrt1.o: no symbols

/usr/lib/x86_64-linux-gnu/rcrt1.o:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
0000000000000000 b .bss
0000000000000000 d .data
0000000000000000 D __data_start
0000000000000000 W data_start
0000000000000000 r .eh_frame
                 U _GLOBAL_OFFSET_TABLE_
0000000000000000 R _IO_stdin_used
                 U __libc_csu_fini
                 U __libc_csu_init
                 U __libc_start_main
                 U main
0000000000000000 r .note.ABI-tag
0000000000000000 n .note.GNU-stack
0000000000000000 r .rodata.cst4
0000000000000000 T _start
0000000000000000 t .text

/usr/lib/x86_64-linux-gnu/Scrt1.o:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
0000000000000000 b .bss
0000000000000000 d .data
0000000000000000 D __data_start
0000000000000000 W data_start
0000000000000000 r .eh_frame
                 U _GLOBAL_OFFSET_TABLE_
0000000000000000 R _IO_stdin_used
                 U __libc_csu_fini
                 U __libc_csu_init
                 U __libc_start_main
                 U main
0000000000000000 r .note.ABI-tag
0000000000000000 n .note.GNU-stack
0000000000000000 r .rodata.cst4
0000000000000000 T _start
0000000000000000 t .text

Hello World 反組譯輸出

| Comments

單純以後剪貼用的。有興趣的朋友可以注意以下觀察重點

  • _init section
  • text section 開頭symbol 為_start
  • _start呼叫__libc_start_main
  • __libc_csu_init section
  • __libc_csu_fini section
  • _fini section
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
$ objdump -d hello

hello:     file format elf64-x86-64


Disassembly of section .init:

00000000000004f0 <_init>:
 4f0: 48 83 ec 08             sub    $0x8,%rsp
 4f4: 48 8b 05 ed 0a 20 00    mov    0x200aed(%rip),%rax        # 200fe8 <__gmon_start__>
 4fb: 48 85 c0                test   %rax,%rax
 4fe: 74 02                   je     502 <_init+0x12>
 500: ff d0                   callq  *%rax
 502: 48 83 c4 08             add    $0x8,%rsp
 506: c3                      retq   

Disassembly of section .plt:

0000000000000510 <.plt>:
 510: ff 35 aa 0a 20 00       pushq  0x200aaa(%rip)        # 200fc0 <_GLOBAL_OFFSET_TABLE_+0x8>
 516: ff 25 ac 0a 20 00       jmpq   *0x200aac(%rip)        # 200fc8 <_GLOBAL_OFFSET_TABLE_+0x10>
 51c: 0f 1f 40 00             nopl   0x0(%rax)

0000000000000520 <printf@plt>:
 520: ff 25 aa 0a 20 00       jmpq   *0x200aaa(%rip)        # 200fd0 <printf@GLIBC_2.2.5>
 526: 68 00 00 00 00          pushq  $0x0
 52b: e9 e0 ff ff ff          jmpq   510 <.plt>

Disassembly of section .plt.got:

0000000000000530 <__cxa_finalize@plt>:
 530: ff 25 c2 0a 20 00       jmpq   *0x200ac2(%rip)        # 200ff8 <__cxa_finalize@GLIBC_2.2.5>
 536: 66 90                   xchg   %ax,%ax

Disassembly of section .text:

0000000000000540 <_start>:
 540: 31 ed                   xor    %ebp,%ebp
 542: 49 89 d1                mov    %rdx,%r9
 545: 5e                      pop    %rsi
 546: 48 89 e2                mov    %rsp,%rdx
 549: 48 83 e4 f0             and    $0xfffffffffffffff0,%rsp
 54d: 50                      push   %rax
 54e: 54                      push   %rsp
 54f: 4c 8d 05 8a 01 00 00    lea    0x18a(%rip),%r8        # 6e0 <__libc_csu_fini>
 556: 48 8d 0d 13 01 00 00    lea    0x113(%rip),%rcx        # 670 <__libc_csu_init>
 55d: 48 8d 3d e6 00 00 00    lea    0xe6(%rip),%rdi        # 64a <main>
 564: ff 15 76 0a 20 00       callq  *0x200a76(%rip)        # 200fe0 <__libc_start_main@GLIBC_2.2.5>
 56a: f4                      hlt    
 56b: 0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)

0000000000000570 <deregister_tm_clones>:
 570: 48 8d 3d 99 0a 20 00    lea    0x200a99(%rip),%rdi        # 201010 <__TMC_END__>
 577: 55                      push   %rbp
 578: 48 8d 05 91 0a 20 00    lea    0x200a91(%rip),%rax        # 201010 <__TMC_END__>
 57f: 48 39 f8                cmp    %rdi,%rax
 582: 48 89 e5                mov    %rsp,%rbp
 585: 74 19                   je     5a0 <deregister_tm_clones+0x30>
 587: 48 8b 05 4a 0a 20 00    mov    0x200a4a(%rip),%rax        # 200fd8 <_ITM_deregisterTMCloneTable>
 58e: 48 85 c0                test   %rax,%rax
 591: 74 0d                   je     5a0 <deregister_tm_clones+0x30>
 593: 5d                      pop    %rbp
 594: ff e0                   jmpq   *%rax
 596: 66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
 59d: 00 00 00 
 5a0: 5d                      pop    %rbp
 5a1: c3                      retq   
 5a2: 0f 1f 40 00             nopl   0x0(%rax)
 5a6: 66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
 5ad: 00 00 00 

00000000000005b0 <register_tm_clones>:
 5b0: 48 8d 3d 59 0a 20 00    lea    0x200a59(%rip),%rdi        # 201010 <__TMC_END__>
 5b7: 48 8d 35 52 0a 20 00    lea    0x200a52(%rip),%rsi        # 201010 <__TMC_END__>
 5be: 55                      push   %rbp
 5bf: 48 29 fe                sub    %rdi,%rsi
 5c2: 48 89 e5                mov    %rsp,%rbp
 5c5: 48 c1 fe 03             sar    $0x3,%rsi
 5c9: 48 89 f0                mov    %rsi,%rax
 5cc: 48 c1 e8 3f             shr    $0x3f,%rax
 5d0: 48 01 c6                add    %rax,%rsi
 5d3: 48 d1 fe                sar    %rsi
 5d6: 74 18                   je     5f0 <register_tm_clones+0x40>
 5d8: 48 8b 05 11 0a 20 00    mov    0x200a11(%rip),%rax        # 200ff0 <_ITM_registerTMCloneTable>
 5df: 48 85 c0                test   %rax,%rax
 5e2: 74 0c                   je     5f0 <register_tm_clones+0x40>
 5e4: 5d                      pop    %rbp
 5e5: ff e0                   jmpq   *%rax
 5e7: 66 0f 1f 84 00 00 00    nopw   0x0(%rax,%rax,1)
 5ee: 00 00 
 5f0: 5d                      pop    %rbp
 5f1: c3                      retq   
 5f2: 0f 1f 40 00             nopl   0x0(%rax)
 5f6: 66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
 5fd: 00 00 00 

0000000000000600 <__do_global_dtors_aux>:
 600: 80 3d 09 0a 20 00 00    cmpb   $0x0,0x200a09(%rip)        # 201010 <__TMC_END__>
 607: 75 2f                   jne    638 <__do_global_dtors_aux+0x38>
 609: 48 83 3d e7 09 20 00    cmpq   $0x0,0x2009e7(%rip)        # 200ff8 <__cxa_finalize@GLIBC_2.2.5>
 610: 00 
 611: 55                      push   %rbp
 612: 48 89 e5                mov    %rsp,%rbp
 615: 74 0c                   je     623 <__do_global_dtors_aux+0x23>
 617: 48 8b 3d ea 09 20 00    mov    0x2009ea(%rip),%rdi        # 201008 <__dso_handle>
 61e: e8 0d ff ff ff          callq  530 <__cxa_finalize@plt>
 623: e8 48 ff ff ff          callq  570 <deregister_tm_clones>
 628: c6 05 e1 09 20 00 01    movb   $0x1,0x2009e1(%rip)        # 201010 <__TMC_END__>
 62f: 5d                      pop    %rbp
 630: c3                      retq   
 631: 0f 1f 80 00 00 00 00    nopl   0x0(%rax)
 638: f3 c3                   repz retq 
 63a: 66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)

0000000000000640 <frame_dummy>:
 640: 55                      push   %rbp
 641: 48 89 e5                mov    %rsp,%rbp
 644: 5d                      pop    %rbp
 645: e9 66 ff ff ff          jmpq   5b0 <register_tm_clones>

000000000000064a <main>:
 64a: 55                      push   %rbp
 64b: 48 89 e5                mov    %rsp,%rbp
 64e: 48 8d 3d 9f 00 00 00    lea    0x9f(%rip),%rdi        # 6f4 <_IO_stdin_used+0x4>
 655: b8 00 00 00 00          mov    $0x0,%eax
 65a: e8 c1 fe ff ff          callq  520 <printf@plt>
 65f: b8 00 00 00 00          mov    $0x0,%eax
 664: 5d                      pop    %rbp
 665: c3                      retq   
 666: 66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
 66d: 00 00 00 

0000000000000670 <__libc_csu_init>:
 670: 41 57                   push   %r15
 672: 41 56                   push   %r14
 674: 49 89 d7                mov    %rdx,%r15
 677: 41 55                   push   %r13
 679: 41 54                   push   %r12
 67b: 4c 8d 25 36 07 20 00    lea    0x200736(%rip),%r12        # 200db8 <__frame_dummy_init_array_entry>
 682: 55                      push   %rbp
 683: 48 8d 2d 36 07 20 00    lea    0x200736(%rip),%rbp        # 200dc0 <__init_array_end>
 68a: 53                      push   %rbx
 68b: 41 89 fd                mov    %edi,%r13d
 68e: 49 89 f6                mov    %rsi,%r14
 691: 4c 29 e5                sub    %r12,%rbp
 694: 48 83 ec 08             sub    $0x8,%rsp
 698: 48 c1 fd 03             sar    $0x3,%rbp
 69c: e8 4f fe ff ff          callq  4f0 <_init>
 6a1: 48 85 ed                test   %rbp,%rbp
 6a4: 74 20                   je     6c6 <__libc_csu_init+0x56>
 6a6: 31 db                   xor    %ebx,%ebx
 6a8: 0f 1f 84 00 00 00 00    nopl   0x0(%rax,%rax,1)
 6af: 00 
 6b0: 4c 89 fa                mov    %r15,%rdx
 6b3: 4c 89 f6                mov    %r14,%rsi
 6b6: 44 89 ef                mov    %r13d,%edi
 6b9: 41 ff 14 dc             callq  *(%r12,%rbx,8)
 6bd: 48 83 c3 01             add    $0x1,%rbx
 6c1: 48 39 dd                cmp    %rbx,%rbp
 6c4: 75 ea                   jne    6b0 <__libc_csu_init+0x40>
 6c6: 48 83 c4 08             add    $0x8,%rsp
 6ca: 5b                      pop    %rbx
 6cb: 5d                      pop    %rbp
 6cc: 41 5c                   pop    %r12
 6ce: 41 5d                   pop    %r13
 6d0: 41 5e                   pop    %r14
 6d2: 41 5f                   pop    %r15
 6d4: c3                      retq   
 6d5: 90                      nop
 6d6: 66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
 6dd: 00 00 00 

00000000000006e0 <__libc_csu_fini>:
 6e0: f3 c3                   repz retq 

Disassembly of section .fini:

00000000000006e4 <_fini>:
 6e4: 48 83 ec 08             sub    $0x8,%rsp
 6e8: 48 83 c4 08             add    $0x8,%rsp
 6ec: c3   

田野調查:Ubuntu 18.04.2 產生執行檔細節

| Comments

本篇旨在從command line角度拆解 gcc hello.c -o hello 中間gcc 幫你執行了哪些指令,以及這些執行指令大概在做什麼。每個指令光要分析都要花不少時間,當作以後的作業吧。

目錄

測試環境

1
2
3
4
5
6
$ lsb_release -a
No LSB modules are available.
Distributor ID:   Ubuntu
Description:  Ubuntu 18.04.2 LTS
Release:  18.04
Codename: bionic
1
2
3
4
5
$ gcc --version
gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

(不)完整的gcc 編譯步驟

除了hello.o以外偷塞的object files以及liked libraries

這部份是在連結的時候 gcc 做的事。記得 gcc 全名是 GNU Compiler Collection,也就是說他不是編譯器,是一個通包的程式。直接列出多連結的檔案,要注意的是在連結時似乎有個順序,所以會多次出現--push-state -> --as-needed -> 指定連結函式庫 -> --pop-state 的參數,以後有空再來看這部份。

  • /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o
  • /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o
  • /usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o
  • /lib64/ld-linux-x86-64.so.2
  • /usr/lib/gcc/x86_64-linux-gnu/7/32/libgcc.a
  • /lib/x86_64-linux-gnu/libc.so.6
  • /usr/lib/x86_64-linux-gnu/libc.a
  • /usr/lib/gcc/x86_64-linux-gnu/7/libgcc_s.so.1
  • /usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o
  • /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o
  • /lib/x86_64-linux-gnu/libc.so.6

附錄

cc 指令拆解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/usr/lib/gcc/x86_64-linux-gnu/7/cc1
-quiet
-v
-imultiarch
x86_64-linux-gnu
hello.c
-quiet
-dumpbase
hello.c
-mtune=generic
-march=x86-64
-auxbase
hello
-version
-fstack-protector-strong
-Wformat
-Wformat-security
-o
/tmp/ccUCGQCr.s

as 指令拆解

1
as -v --64 -o /tmp/cct36Qgi.o /tmp/ccUCGQCr.s

collect2 指令拆解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/usr/lib/gcc/x86_64-linux-gnu/7/collect2
-plugin
/usr/lib/gcc/x86_64-linux-gnu/7/liblto_plugin.so
-plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper
-plugin-opt=-fresolution=/tmp/ccizEA38.res
-plugin-opt=-pass-through=-lgcc
-plugin-opt=-pass-through=-lgcc_s
-plugin-opt=-pass-through=-lc
-plugin-opt=-pass-through=-lgcc
-plugin-opt=-pass-through=-lgcc_s
--sysroot=/
--build-id
--eh-frame-hdr
-m
elf_x86_64
--hash-style=gnu
--as-needed
-dynamic-linker
/lib64/ld-linux-x86-64.so.2
-pie
-z
now
-z
relro
-o
hello
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o
/usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o
-L/usr/lib/gcc/x86_64-linux-gnu/7
-L/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu
-L/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib
-L/lib/x86_64-linux-gnu
-L/lib/../lib
-L/usr/lib/x86_64-linux-gnu
-L/usr/lib/../lib
-L/usr/lib/gcc/x86_64-linux-gnu/7/../../..
/tmp/cct36Qgi.o
-lgcc
--push-state
--as-needed
-lgcc_s
--pop-state
-lc
-lgcc
--push-state
--as-needed
-lgcc_s
--pop-state
/usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o

ld 指令拆解

要注意的是ld是由collect2呼叫的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/usr/bin/ld
-plugin
/usr/lib/gcc/x86_64-linux-gnu/7/liblto_plugin.so
-plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper
-plugin-opt=-fresolution=/tmp/ccCwkJOE.res
-plugin-opt=-pass-through=-lgcc
-plugin-opt=-pass-through=-lgcc_s
-plugin-opt=-pass-through=-lc
-plugin-opt=-pass-through=-lgcc
-plugin-opt=-pass-through=-lgcc_s
--sysroot=/
--build-id
--eh-frame-hdr
-m
elf_x86_64
--hash-style=gnu
--as-needed
-dynamic-linker
/lib64/ld-linux-x86-64.so.2
-pie
-z
now
-z
relro
-o
hello
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o
/usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o
-L/usr/lib/gcc/x86_64-linux-gnu/7
-L/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu
-L/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib
-L/lib/x86_64-linux-gnu
-L/lib/../lib
-L/usr/lib/x86_64-linux-gnu
-L/usr/lib/../lib
-L/usr/lib/gcc/x86_64-linux-gnu/7/../../..
/tmp/ccinSYzz.o
-lgcc
--push-state
--as-needed
-lgcc_s
--pop-state
-lc
-lgcc
--push-state
--as-needed
-lgcc_s
--pop-state
/usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o

strace 觀察 gcc hello.c -o hello 會呼叫哪些執行檔

1
2
3
4
5
6
7
8
9
10
$ strace -s 8192 -f gcc  -o hello hello.c 2>&1 | grep execve
execve("/usr/bin/gcc", ["gcc", "-o", "hello", "hello.c"], 0x7fff89e3d720 /* 71 vars */) = 0
[pid 23886] execve("/usr/lib/gcc/x86_64-linux-gnu/7/cc1", ["/usr/lib/gcc/x86_64-linux-gnu/7/cc1", "-quiet", "-imultiarch", "x86_64-linux-gnu", "hello.c", "-quiet", "-dumpbase", "hello.c", "-mtune=generic", "-march=x86-64", "-auxbase", "hello", "-fstack-protector-strong", "-Wformat", "-Wformat-security", "-o", "/tmp/ccLpZPzY.s"], 0x211e8c0 /* 76 vars */ <unfinished ...>
[pid 23886] <... execve resumed> )      = 0
[pid 23887] execve("/usr/bin/as", ["as", "--64", "-o", "/tmp/cceDpnfo.o", "/tmp/ccLpZPzY.s"], 0x211e8c0 /* 76 vars */ <unfinished ...>
[pid 23887] <... execve resumed> )      = 0
[pid 23888] execve("/usr/lib/gcc/x86_64-linux-gnu/7/collect2", ["/usr/lib/gcc/x86_64-linux-gnu/7/collect2", "-plugin", "/usr/lib/gcc/x86_64-linux-gnu/7/liblto_plugin.so", "-plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper", "-plugin-opt=-fresolution=/tmp/ccN3BxWN.res", "-plugin-opt=-pass-through=-lgcc", "-plugin-opt=-pass-through=-lgcc_s", "-plugin-opt=-pass-through=-lc", "-plugin-opt=-pass-through=-lgcc", "-plugin-opt=-pass-through=-lgcc_s", "--sysroot=/", "--build-id", "--eh-frame-hdr", "-m", "elf_x86_64", "--hash-style=gnu", "--as-needed", "-dynamic-linker", "/lib64/ld-linux-x86-64.so.2", "-pie", "-z", "now", "-z", "relro", "-o", "hello", "/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o", "/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o", "/usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o", "-L/usr/lib/gcc/x86_64-linux-gnu/7", "-L/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu", "-L/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib", "-L/lib/x86_64-linux-gnu", "-L/lib/../lib", "-L/usr/lib/x86_64-linux-gnu", "-L/usr/lib/../lib", "-L/usr/lib/gcc/x86_64-linux-gnu/7/../../..", "/tmp/cceDpnfo.o", "-lgcc", "--push-state", "--as-needed", "-lgcc_s", "--pop-state", "-lc", "-lgcc", "--push-state", "--as-needed", "-lgcc_s", "--pop-state", "/usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o", "/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o"], 0x211f750 /* 78 vars */ <unfinished ...>
[pid 23888] <... execve resumed> )      = 0
[pid 23889] execve("/usr/bin/ld", ["/usr/bin/ld", "-plugin", "/usr/lib/gcc/x86_64-linux-gnu/7/liblto_plugin.so", "-plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper", "-plugin-opt=-fresolution=/tmp/ccN3BxWN.res", "-plugin-opt=-pass-through=-lgcc", "-plugin-opt=-pass-through=-lgcc_s", "-plugin-opt=-pass-through=-lc", "-plugin-opt=-pass-through=-lgcc", "-plugin-opt=-pass-through=-lgcc_s", "--sysroot=/", "--build-id", "--eh-frame-hdr", "-m", "elf_x86_64", "--hash-style=gnu", "--as-needed", "-dynamic-linker", "/lib64/ld-linux-x86-64.so.2", "-pie", "-z", "now", "-z", "relro", "-o", "hello", "/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o", "/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o", "/usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o", "-L/usr/lib/gcc/x86_64-linux-gnu/7", "-L/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu", "-L/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib", "-L/lib/x86_64-linux-gnu", "-L/lib/../lib", "-L/usr/lib/x86_64-linux-gnu", "-L/usr/lib/../lib", "-L/usr/lib/gcc/x86_64-linux-gnu/7/../../..", "/tmp/cceDpnfo.o", "-lgcc", "--push-state", "--as-needed", "-lgcc_s", "--pop-state", "-lc", "-lgcc", "--push-state", "--as-needed", "-lgcc_s", "--pop-state", "/usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o", "/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o"], 0x7ffc38ceec88 /* 78 vars */ <unfinished ...>
[pid 23889] <... execve resumed> )      = 0

完整的 gcc -v -o hello hello.c 輸出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
$ gcc -v -o hello hello.c
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.4.0-1ubuntu1~18.04.1' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1) 
COLLECT_GCC_OPTIONS='-v' '-o' 'hello' '-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-linux-gnu/7/cc1 -quiet -v -imultiarch x86_64-linux-gnu hello.c -quiet -dumpbase hello.c -mtune=generic -march=x86-64 -auxbase hello -version -fstack-protector-strong -Wformat -Wformat-security -o /tmp/ccUCGQCr.s
GNU C11 (Ubuntu 7.4.0-1ubuntu1~18.04.1) version 7.4.0 (x86_64-linux-gnu)
  compiled by GNU C version 7.4.0, GMP version 6.1.2, MPFR version 4.0.1, MPC version 1.1.0, isl version isl-0.19-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/7/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/x86_64-linux-gnu/7/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/7/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
GNU C11 (Ubuntu 7.4.0-1ubuntu1~18.04.1) version 7.4.0 (x86_64-linux-gnu)
  compiled by GNU C version 7.4.0, GMP version 6.1.2, MPFR version 4.0.1, MPC version 1.1.0, isl version isl-0.19-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: fa57db1fe2d756b22d454aa8428fd3bd
COLLECT_GCC_OPTIONS='-v' '-o' 'hello' '-mtune=generic' '-march=x86-64'
 as -v --64 -o /tmp/cct36Qgi.o /tmp/ccUCGQCr.s
GNU assembler version 2.30 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.30
COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-o' 'hello' '-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-linux-gnu/7/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/7/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper -plugin-opt=-fresolution=/tmp/ccizEA38.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --sysroot=/ --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o hello /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/7 -L/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/7/../../.. /tmp/cct36Qgi.o -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o
COLLECT_GCC_OPTIONS='-v' '-o' 'hello' '-mtune=generic' '-march=x86-64'

collect2 說明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
$ /usr/lib/gcc/x86_64-linux-gnu/7/collect2 --help
Usage: collect2 [options]
 Wrap linker and generate constructor code if needed.
 Options:
  -debug          Enable debug output
  --help          Display this information
  -v, --version   Display this program's version number

Overview: http://gcc.gnu.org/onlinedocs/gccint/Collect2.html
Report bugs: <file:///usr/share/doc/gcc-7/README.Bugs>

Usage: /usr/bin/ld [options] file...
Options:
  -a KEYWORD                  Shared library control for HP/UX compatibility
  -A ARCH, --architecture ARCH
                              Set architecture
  -b TARGET, --format TARGET  Specify target for following input files
  -c FILE, --mri-script FILE  Read MRI format linker script
  -d, -dc, -dp                Force common symbols to be defined
  --force-group-allocation    Force group members out of groups
  -e ADDRESS, --entry ADDRESS Set start address
  -E, --export-dynamic        Export all dynamic symbols
  --no-export-dynamic         Undo the effect of --export-dynamic
  -EB                         Link big-endian objects
  -EL                         Link little-endian objects
  -f SHLIB, --auxiliary SHLIB Auxiliary filter for shared object symbol table
  -F SHLIB, --filter SHLIB    Filter for shared object symbol table
  -g                          Ignored
  -G SIZE, --gpsize SIZE      Small data size (if no size, same as --shared)
  -h FILENAME, -soname FILENAME
                              Set internal name of shared library
  -I PROGRAM, --dynamic-linker PROGRAM
                              Set PROGRAM as the dynamic linker to use
  --no-dynamic-linker         Produce an executable with no program interpreter header
  -l LIBNAME, --library LIBNAME
                              Search for library LIBNAME
  -L DIRECTORY, --library-path DIRECTORY
                              Add DIRECTORY to library search path
  --sysroot=<DIRECTORY>       Override the default sysroot location
  -m EMULATION                Set emulation
  -M, --print-map             Print map file on standard output
  -n, --nmagic                Do not page align data
  -N, --omagic                Do not page align data, do not make text readonly
  --no-omagic                 Page align data, make text readonly
  -o FILE, --output FILE      Set output file name
  -O                          Optimize output file
  --out-implib FILE           Generate import library
  -plugin PLUGIN              Load named plugin
  -plugin-opt ARG             Send arg to last-loaded plugin
  -flto                       Ignored for GCC LTO option compatibility
  -flto-partition=            Ignored for GCC LTO option compatibility
  -fuse-ld=                   Ignored for GCC linker option compatibility
  --map-whole-files           Ignored for gold option compatibility
  --no-map-whole-files        Ignored for gold option compatibility
  -Qy                         Ignored for SVR4 compatibility
  -q, --emit-relocs           Generate relocations in final output
  -r, -i, --relocatable       Generate relocatable output
  -R FILE, --just-symbols FILE
                              Just link symbols (if directory, same as --rpath)
  -s, --strip-all             Strip all symbols
  -S, --strip-debug           Strip debugging symbols
  --strip-discarded           Strip symbols in discarded sections
  --no-strip-discarded        Do not strip symbols in discarded sections
  -t, --trace                 Trace file opens
  -T FILE, --script FILE      Read linker script
  --default-script FILE, -dT  Read default linker script
  -u SYMBOL, --undefined SYMBOL
                              Start with undefined reference to SYMBOL
  --require-defined SYMBOL    Require SYMBOL be defined in the final output
  --unique [=SECTION]         Don't merge input [SECTION | orphan] sections
  -Ur                         Build global constructor/destructor tables
  -v, --version               Print version information
  -V                          Print version and emulation information
  -x, --discard-all           Discard all local symbols
  -X, --discard-locals        Discard temporary local symbols (default)
  --discard-none              Don't discard any local symbols
  -y SYMBOL, --trace-symbol SYMBOL
                              Trace mentions of SYMBOL
  -Y PATH                     Default search path for Solaris compatibility
  -(, --start-group           Start a group
  -), --end-group             End a group
  --accept-unknown-input-arch Accept input files whose architecture cannot be determined
  --no-accept-unknown-input-arch
                              Reject input files whose architecture is unknown
  --as-needed                 Only set DT_NEEDED for following dynamic libs if used
  --no-as-needed              Always set DT_NEEDED for dynamic libraries mentioned on
                                the command line
  -assert KEYWORD             Ignored for SunOS compatibility
  -Bdynamic, -dy, -call_shared
                              Link against shared libraries
  -Bstatic, -dn, -non_shared, -static
                              Do not link against shared libraries
  -Bsymbolic                  Bind global references locally
  -Bsymbolic-functions        Bind global function references locally
  --check-sections            Check section addresses for overlaps (default)
  --no-check-sections         Do not check section addresses for overlaps
  --copy-dt-needed-entries    Copy DT_NEEDED links mentioned inside DSOs that follow
  --no-copy-dt-needed-entries Do not copy DT_NEEDED links mentioned inside DSOs that follow
  --cref                      Output cross reference table
  --defsym SYMBOL=EXPRESSION  Define a symbol
  --demangle [=STYLE]         Demangle symbol names [using STYLE]
  --embedded-relocs           Generate embedded relocs
  --fatal-warnings            Treat warnings as errors
  --no-fatal-warnings         Do not treat warnings as errors (default)
  -fini SYMBOL                Call SYMBOL at unload-time
  --force-exe-suffix          Force generation of file with .exe suffix
  --gc-sections               Remove unused sections (on some targets)
  --no-gc-sections            Don't remove unused sections (default)
  --print-gc-sections         List removed unused sections on stderr
  --no-print-gc-sections      Do not list removed unused sections
  --gc-keep-exported          Keep exported symbols when removing unused sections
  --hash-size=<NUMBER>        Set default hash table size close to <NUMBER>
  --help                      Print option help
  -init SYMBOL                Call SYMBOL at load-time
  -Map FILE                   Write a map file
  --no-define-common          Do not define Common storage
  --no-demangle               Do not demangle symbol names
  --no-keep-memory            Use less memory and more disk I/O
  --no-undefined              Do not allow unresolved references in object files
  --allow-shlib-undefined     Allow unresolved references in shared libraries
  --no-allow-shlib-undefined  Do not allow unresolved references in shared libs
  --allow-multiple-definition Allow multiple definitions
  --no-undefined-version      Disallow undefined version
  --default-symver            Create default symbol version
  --default-imported-symver   Create default symbol version for imported symbols
  --no-warn-mismatch          Don't warn about mismatched input files
  --no-warn-search-mismatch   Don't warn on finding an incompatible library
  --no-whole-archive          Turn off --whole-archive
  --noinhibit-exec            Create an output file even if errors occur
  -nostdlib                   Only use library directories specified on
                                the command line
  --oformat TARGET            Specify target of output file
  --print-output-format       Print default output format
  --print-sysroot             Print current sysroot
  -qmagic                     Ignored for Linux compatibility
  --reduce-memory-overheads   Reduce memory overheads, possibly taking much longer
  --relax                     Reduce code size by using target specific optimizations
  --no-relax                  Do not use relaxation techniques to reduce code size
  --retain-symbols-file FILE  Keep only symbols listed in FILE
  -rpath PATH                 Set runtime shared library search path
  -rpath-link PATH            Set link time shared library search path
  -shared, -Bshareable        Create a shared library
  -pie, --pic-executable      Create a position independent executable
  --sort-common [=ascending|descending]
                              Sort common symbols by alignment [in specified order]
  --sort-section name|alignment
                              Sort sections by name or maximum alignment
  --spare-dynamic-tags COUNT  How many tags to reserve in .dynamic section
  --split-by-file [=SIZE]     Split output sections every SIZE octets
  --split-by-reloc [=COUNT]   Split output sections every COUNT relocs
  --stats                     Print memory usage statistics
  --target-help               Display target specific options
  --task-link SYMBOL          Do task level linking
  --traditional-format        Use same format as native linker
  --section-start SECTION=ADDRESS
                              Set address of named section
  -Tbss ADDRESS               Set address of .bss section
  -Tdata ADDRESS              Set address of .data section
  -Ttext ADDRESS              Set address of .text section
  -Ttext-segment ADDRESS      Set address of text segment
  -Trodata-segment ADDRESS    Set address of rodata segment
  -Tldata-segment ADDRESS     Set address of ldata segment
  --unresolved-symbols=<method>
                              How to handle unresolved symbols.  <method> is:
                                ignore-all, report-all, ignore-in-object-files,
                                ignore-in-shared-libs
  --verbose [=NUMBER]         Output lots of information during link
  --version-script FILE       Read version information script
  --version-exports-section SYMBOL
                              Take export symbols list from .exports, using
                                SYMBOL as the version.
  --dynamic-list-data         Add data symbols to dynamic list
  --dynamic-list-cpp-new      Use C++ operator new/delete dynamic list
  --dynamic-list-cpp-typeinfo Use C++ typeinfo dynamic list
  --dynamic-list FILE         Read dynamic list
  --warn-common               Warn about duplicate common symbols
  --warn-constructors         Warn if global constructors/destructors are seen
  --warn-multiple-gp          Warn if the multiple GP values are used
  --warn-once                 Warn only once per undefined symbol
  --warn-section-align        Warn if start of section changes due to alignment
  --warn-shared-textrel       Warn if shared object has DT_TEXTREL
  --warn-alternate-em         Warn if an object has alternate ELF machine code
  --warn-unresolved-symbols   Report unresolved symbols as warnings
  --error-unresolved-symbols  Report unresolved symbols as errors
  --whole-archive             Include all objects from following archives
  --wrap SYMBOL               Use wrapper functions for SYMBOL
  --ignore-unresolved-symbol SYMBOL
                              Unresolved SYMBOL will not cause an error or warning
  --push-state                Push state of flags governing input file handling
  --pop-state                 Pop state of flags governing input file handling
  --print-memory-usage        Report target memory usage
  --orphan-handling =MODE     Control how orphan sections are handled.
  @FILE                       Read options from FILE
/usr/bin/ld: supported targets: elf64-x86-64 elf32-i386 elf32-iamcu elf32-x86-64 a.out-i386-linux pei-i386 pei-x86-64 elf64-l1om elf64-k1om elf64-little elf64-big elf32-little elf32-big pe-x86-64 pe-bigobj-x86-64 pe-i386 plugin srec symbolsrec verilog tekhex binary ihex
/usr/bin/ld: supported emulations: elf_x86_64 elf32_x86_64 elf_i386 elf_iamcu i386linux elf_l1om elf_k1om i386pep i386pe
/usr/bin/ld: emulation specific options:
ELF emulations:
  --ld-generated-unwind-info  Generate exception handling info for PLT
  --no-ld-generated-unwind-info
                              Don't generate exception handling info for PLT
  --build-id[=STYLE]          Generate build ID note
  --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi]
                              Compress DWARF debug sections using zlib
                               Default: none
  -z common-page-size=SIZE    Set common page size to SIZE
  -z max-page-size=SIZE       Set maximum page size to SIZE
  -z defs                     Report unresolved symbols in object files.
  -z muldefs                  Allow multiple definitions
  -z execstack                Mark executable as requiring executable stack
  -z noexecstack              Mark executable as not requiring executable stack
  -z globalaudit              Mark executable requiring global auditing
  --audit=AUDITLIB            Specify a library to use for auditing
  -Bgroup                     Selects group name lookup rules for DSO
  --disable-new-dtags         Disable new dynamic tags
  --enable-new-dtags          Enable new dynamic tags
  --eh-frame-hdr              Create .eh_frame_hdr section
  --no-eh-frame-hdr           Do not create .eh_frame_hdr section
  --exclude-libs=LIBS         Make all symbols in LIBS hidden
  --hash-style=STYLE          Set hash style to sysv, gnu or both
  -P AUDITLIB, --depaudit=AUDITLIB
                Specify a library to use for auditing dependencies
  -z combreloc                Merge dynamic relocs into one section and sort
  -z nocombreloc              Don't merge dynamic relocs into one section
  -z global                   Make symbols in DSO available for subsequently
                 loaded objects
  -z initfirst                Mark DSO to be initialized first at runtime
  -z interpose                Mark object to interpose all DSOs but executable
  -z lazy                     Mark object lazy runtime binding (default)
  -z loadfltr                 Mark object requiring immediate process
  -z nocopyreloc              Don't create copy relocs
  -z nodefaultlib             Mark object not to use default search paths
  -z nodelete                 Mark DSO non-deletable at runtime
  -z nodlopen                 Mark DSO not available to dlopen
  -z nodump                   Mark DSO not available to dldump
  -z now                      Mark object non-lazy runtime binding
  -z origin                   Mark object requiring immediate $ORIGIN
              processing at runtime
  -z relro                    Create RELRO program header (default)
  -z norelro                  Don't create RELRO program header
  -z separate-code            Create separate code program header
  -z noseparate-code          Don't create separate code program header (default)
  -z common                   Generate common symbols with STT_COMMON type
  -z nocommon                 Generate common symbols with STT_OBJECT type
  -z stack-size=SIZE          Set size of stack segment
  -z text                     Treat DT_TEXTREL in shared object as error
  -z notext                   Don't treat DT_TEXTREL in shared object as error
  -z textoff                  Don't treat DT_TEXTREL in shared object as error
elf_x86_64: 
  -z noextern-protected-data  Do not treat protected data symbol as external
  -z dynamic-undefined-weak   Make undefined weak symbols dynamic
  -z nodynamic-undefined-weak Do not make undefined weak symbols dynamic
  -z noreloc-overflow         Disable relocation overflow check
  -z call-nop=PADDING         Use PADDING as 1-byte NOP for branch
  -z ibtplt                   Generate IBT-enabled PLT entries
  -z ibt                      Generate GNU_PROPERTY_X86_FEATURE_1_IBT
  -z shstk                    Generate GNU_PROPERTY_X86_FEATURE_1_SHSTK
  -z bndplt                   Always generate BND prefix in PLT entries
elf32_x86_64: 
  -z noextern-protected-data  Do not treat protected data symbol as external
  -z dynamic-undefined-weak   Make undefined weak symbols dynamic
  -z nodynamic-undefined-weak Do not make undefined weak symbols dynamic
  -z noreloc-overflow         Disable relocation overflow check
  -z call-nop=PADDING         Use PADDING as 1-byte NOP for branch
  -z ibtplt                   Generate IBT-enabled PLT entries
  -z ibt                      Generate GNU_PROPERTY_X86_FEATURE_1_IBT
  -z shstk                    Generate GNU_PROPERTY_X86_FEATURE_1_SHSTK
elf_i386: 
  -z noextern-protected-data  Do not treat protected data symbol as external
  -z dynamic-undefined-weak   Make undefined weak symbols dynamic
  -z nodynamic-undefined-weak Do not make undefined weak symbols dynamic
  -z call-nop=PADDING         Use PADDING as 1-byte NOP for branch
  -z ibtplt                   Generate IBT-enabled PLT entries
  -z ibt                      Generate GNU_PROPERTY_X86_FEATURE_1_IBT
  -z shstk                    Generate GNU_PROPERTY_X86_FEATURE_1_SHSTK
elf_iamcu: 
  -z noextern-protected-data  Do not treat protected data symbol as external
  -z dynamic-undefined-weak   Make undefined weak symbols dynamic
  -z nodynamic-undefined-weak Do not make undefined weak symbols dynamic
  -z call-nop=PADDING         Use PADDING as 1-byte NOP for branch
elf_l1om: 
  -z noextern-protected-data  Do not treat protected data symbol as external
  -z dynamic-undefined-weak   Make undefined weak symbols dynamic
  -z nodynamic-undefined-weak Do not make undefined weak symbols dynamic
  -z call-nop=PADDING         Use PADDING as 1-byte NOP for branch
elf_k1om: 
  -z noextern-protected-data  Do not treat protected data symbol as external
  -z dynamic-undefined-weak   Make undefined weak symbols dynamic
  -z nodynamic-undefined-weak Do not make undefined weak symbols dynamic
  -z call-nop=PADDING         Use PADDING as 1-byte NOP for branch
i386pep: 
  --base_file <basefile>             Generate a base file for relocatable DLLs
  --dll                              Set image base to the default for DLLs
  --file-alignment <size>            Set file alignment
  --heap <size>                      Set initial size of the heap
  --image-base <address>             Set start address of the executable
  --major-image-version <number>     Set version number of the executable
  --major-os-version <number>        Set minimum required OS version
  --major-subsystem-version <number> Set minimum required OS subsystem version
  --minor-image-version <number>     Set revision number of the executable
  --minor-os-version <number>        Set minimum required OS revision
  --minor-subsystem-version <number> Set minimum required OS subsystem revision
  --section-alignment <size>         Set section alignment
  --stack <size>                     Set size of the initial stack
  --subsystem <name>[:<version>]     Set required OS subsystem [& version]
  --support-old-code                 Support interworking with old code
  --[no-]leading-underscore          Set explicit symbol underscore prefix mode
  --[no-]insert-timestamp            Use a real timestamp rather than zero. (default)
                                     This makes binaries non-deterministic
  --add-stdcall-alias                Export symbols with and without @nn
  --disable-stdcall-fixup            Don't link _sym to _sym@nn
  --enable-stdcall-fixup             Link _sym to _sym@nn without warnings
  --exclude-symbols sym,sym,...      Exclude symbols from automatic export
  --exclude-all-symbols              Exclude all symbols from automatic export
  --exclude-libs lib,lib,...         Exclude libraries from automatic export
  --exclude-modules-for-implib mod,mod,...
                                     Exclude objects, archive members from auto
                                     export, place into import library instead.
  --export-all-symbols               Automatically export all globals to DLL
  --kill-at                          Remove @nn from exported symbols
  --output-def <file>                Generate a .DEF file for the built DLL
  --warn-duplicate-exports           Warn about duplicate exports.
  --compat-implib                    Create backward compatible import libs;
                                       create __imp_<SYMBOL> as well.
  --enable-auto-image-base           Automatically choose image base for DLLs
                                       unless user specifies one
  --disable-auto-image-base          Do not auto-choose image base. (default)
  --dll-search-prefix=<string>       When linking dynamically to a dll without
                                       an importlib, use <string><basename>.dll
                                       in preference to lib<basename>.dll 
  --enable-auto-import               Do sophisticated linking of _sym to
                                       __imp_sym for DATA references
  --disable-auto-import              Do not auto-import DATA items from DLLs
  --enable-runtime-pseudo-reloc      Work around auto-import limitations by
                                       adding pseudo-relocations resolved at
                                       runtime.
  --disable-runtime-pseudo-reloc     Do not add runtime pseudo-relocations for
                                       auto-imported DATA.
  --enable-extra-pep-debug            Enable verbose debug output when building
                                       or linking to DLLs (esp. auto-import)
  --enable-long-section-names        Use long COFF section names even in
                                       executable image files
  --disable-long-section-names       Never use long COFF section names, even
                                       in object files
  --high-entropy-va                  Image is compatible with 64-bit address space
                                       layout randomization (ASLR)
  --dynamicbase            Image base address may be relocated using
                     address space layout randomization (ASLR)
  --forceinteg         Code integrity checks are enforced
  --nxcompat       Image is compatible with data execution prevention
  --no-isolation       Image understands isolation but do not isolate the image
  --no-seh             Image does not use SEH. No SE handler may
                     be called in this image
  --no-bind            Do not bind this image
  --wdmdriver      Driver uses the WDM model
  --tsaware                  Image is Terminal Server aware
  --build-id[=STYLE]         Generate build ID
i386pe: 
  --base_file <basefile>             Generate a base file for relocatable DLLs
  --dll                              Set image base to the default for DLLs
  --file-alignment <size>            Set file alignment
  --heap <size>                      Set initial size of the heap
  --image-base <address>             Set start address of the executable
  --major-image-version <number>     Set version number of the executable
  --major-os-version <number>        Set minimum required OS version
  --major-subsystem-version <number> Set minimum required OS subsystem version
  --minor-image-version <number>     Set revision number of the executable
  --minor-os-version <number>        Set minimum required OS revision
  --minor-subsystem-version <number> Set minimum required OS subsystem revision
  --section-alignment <size>         Set section alignment
  --stack <size>                     Set size of the initial stack
  --subsystem <name>[:<version>]     Set required OS subsystem [& version]
  --support-old-code                 Support interworking with old code
  --[no-]leading-underscore          Set explicit symbol underscore prefix mode
  --thumb-entry=<symbol>             Set the entry point to be Thumb <symbol>
  --[no-]insert-timestamp            Use a real timestamp rather than zero (default).
                                     This makes binaries non-deterministic
  --add-stdcall-alias                Export symbols with and without @nn
  --disable-stdcall-fixup            Don't link _sym to _sym@nn
  --enable-stdcall-fixup             Link _sym to _sym@nn without warnings
  --exclude-symbols sym,sym,...      Exclude symbols from automatic export
  --exclude-all-symbols              Exclude all symbols from automatic export
  --exclude-libs lib,lib,...         Exclude libraries from automatic export
  --exclude-modules-for-implib mod,mod,...
                                     Exclude objects, archive members from auto
                                     export, place into import library instead.
  --export-all-symbols               Automatically export all globals to DLL
  --kill-at                          Remove @nn from exported symbols
  --output-def <file>                Generate a .DEF file for the built DLL
  --warn-duplicate-exports           Warn about duplicate exports
  --compat-implib                    Create backward compatible import libs;
                                       create __imp_<SYMBOL> as well.
  --enable-auto-image-base[=<address>] Automatically choose image base for DLLs
                                       (optionally starting with address) unless
                                       specifically set with --image-base
  --disable-auto-image-base          Do not auto-choose image base. (default)
  --dll-search-prefix=<string>       When linking dynamically to a dll without
                                       an importlib, use <string><basename>.dll
                                       in preference to lib<basename>.dll 
  --enable-auto-import               Do sophisticated linking of _sym to
                                       __imp_sym for DATA references
  --disable-auto-import              Do not auto-import DATA items from DLLs
  --enable-runtime-pseudo-reloc      Work around auto-import limitations by
                                       adding pseudo-relocations resolved at
                                       runtime.
  --disable-runtime-pseudo-reloc     Do not add runtime pseudo-relocations for
                                       auto-imported DATA.
  --enable-extra-pe-debug            Enable verbose debug output when building
                                       or linking to DLLs (esp. auto-import)
  --large-address-aware              Executable supports virtual addresses
                                       greater than 2 gigabytes
  --disable-large-address-aware      Executable does not support virtual
                                       addresses greater than 2 gigabytes
  --enable-long-section-names        Use long COFF section names even in
                                       executable image files
  --disable-long-section-names       Never use long COFF section names, even
                                       in object files
  --dynamicbase            Image base address may be relocated using
                     address space layout randomization (ASLR)
  --forceinteg         Code integrity checks are enforced
  --nxcompat       Image is compatible with data execution prevention
  --no-isolation       Image understands isolation but do not isolate the image
  --no-seh             Image does not use SEH. No SE handler may
                     be called in this image
  --no-bind            Do not bind this image
  --wdmdriver      Driver uses the WDM model
  --tsaware                  Image is Terminal Server aware
  --build-id[=STYLE]         Generate build ID

Report bugs to <http://www.sourceware.org/bugzilla/>

觀察編譯glibc的產出

| Comments

這次介紹編譯glibc 並安裝後的一些發現

目錄

測試環境

1
2
3
4
5
6
$ lsb_release -a
No LSB modules are available.
Distributor ID:   Ubuntu
Description:  Ubuntu 18.04.2 LTS
Release:  18.04
Codename: bionic

安裝步驟

  • 下載套件
1
2
3
git clone http://sourceware.org/git/glibc.git
cd glibc
git checkout --track origin/release/2.27
  • 在新的目錄編譯 glibc,你可以自行指定安裝路徑,一定要指定安裝路徑,以免發生嚴重悲劇。

本次設定主要是針對除錯最佳化,以及避免覆蓋系統原本的 glibc

1
2
3
4
5
6
7
8
9
10
11
12
13
cd ../
mkdir out
mkdir rootfs
cd out

# 設定
CFLAGS=-Og CPPFLAGS=-Og CXXFLAGS=-Og ../glibc/configure  --disable-werror --prefix=/tmp/rootfs/

# 編譯
make

# 安裝
make install

觀察與結論

本來想說 libc 用來提供 C 標準函式庫的 binary,那麼了不起就是 libc.solibc.a 以及對應的 header files。安裝完畢後先看一下目錄,事情果然沒有像本組裝工想的那麼簡單。列出第一層目錄如下,除了預期中的libinclude以外,竟然還有不少預期以外的目錄。

1
2
3
4
5
6
7
8
9
10
$ tree -L 1 -d /tmp/rootfs
.
├── bin
├── etc
├── include
├── lib
├── libexec
├── sbin
├── share
└── var

那麼我們來看一下這些目錄下面有什麼東西吧。

/lib

先來看目錄結構,多了和多國語言相關的函式庫目錄還有 trace shared object PLT (Procedure linkage table) 工具會用到的audio目錄

1
2
3
4
$ tree lib -d
lib
├── audit
└── gconv

接下來看/lib的檔案

列出幾個我有興趣的檔案

  • *.o

    • /lib裏面會發現幾個object file,它們檔名都有crt,crt全名是 C runtime,顯然和執行的時候有關。我有空會再找時間了解。先列出來介紹幾個如下
  • Scrt1.o: 這邊我們可以看到T _start以及U main,望文生義按圖說故事我們可以猜測執行程式的起始點其實是_start,做了一些事情後才會去呼叫你寫的main(),我做了一個實驗,想知道一個應用程式會連結哪些系統上的object檔案請參考這邊

1
2
3
4
5
6
7
8
9
10
$ nm Scrt1.o 
0000000000000000 D __data_start
0000000000000000 W data_start
                 U _GLOBAL_OFFSET_TABLE_
0000000000000000 R _IO_stdin_used
                 U __libc_csu_fini
                 U __libc_csu_init
                 U __libc_start_main
                 U main
0000000000000000 T _start
  • crtn.o: 用nm去看會發現沒有symbol,不過反組譯後會發現有兩個section,看起來和main啟動前和使用者程式結束後會有關係。有空會再探討。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ objdump -d crtn.o 

crtn.o:     file format elf64-x86-64


Disassembly of section .init:

0000000000000000 <.init>:
   0: 48 83 c4 08             add    $0x8,%rsp
   4: c3                      retq   

Disassembly of section .fini:

0000000000000000 <.fini>:
   0: 48 83 c4 08             add    $0x8,%rsp
   4: c3                      retq   
  • ld-linux-x86_64.so.2
    • 就是ld.so,這個檔案有趣的點是他是一個shared object,但是同時又是可以執行。如果我的懶病沒有發作以後會常常看到這個東西。
  • libc.*:
    • 直接看symbol就知道,T, U的定義請翻前面文章,我懶得找。
1
2
3
4
5
6
7
8
9
10
11
12
$ nm libc.a | grep "^printf.o:" -A 10
printf.o:
0000000000000000 T _IO_printf
0000000000000000 T printf
0000000000000000 T __printf
                 U stdout
                 U __vfprintf_internal

snprintf.o:
0000000000000000 W snprintf
0000000000000000 T __snprintf
                 U __vsnprintf_internal    
  • libm.*: 一樣看symbol節錄
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$ nm libm.so.6 |grep " sin"
000000000002eb24 i sin
0000000000034532 W sincos
00000000000419cc i sincosf
0000000000054f26 W sincosf128
00000000000419cc i sincosf32
0000000000034532 W sincosf32x
0000000000034532 W sincosf64
00000000000175c8 W sincosf64x
00000000000175c8 W sincosl
000000000004131e i sinf
0000000000054148 W sinf128
000000000004131e i sinf32
000000000002eb24 i sinf32x
000000000002eb24 i sinf64
0000000000016ead W sinf64x
000000000000ed11 W sinh
000000000001205d W sinhf
0000000000060407 W sinhf128
000000000001205d W sinhf32
000000000000ed11 W sinhf32x
000000000000ed11 W sinhf64
000000000000d9a4 W sinhf64x
000000000000d9a4 W sinhl
0000000000016ead W sinl
00000000000144b5 t sin_pi
0000000000027776 t sin_pi
  • libdl
    • 動態載入函式庫相關函數如dlvsym, dlsym,

完整檔案如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ ls lib
audit                         libc.a                 libmemusage.so              libnss_dns.so               librt-2.28.9000.so
crt1.o                        libc_nonshared.a       libm.so                     libnss_dns.so.2             librt.a
crti.o                        libcrypt-2.28.9000.so  libm.so.6                   libnss_files-2.28.9000.so   librt.so
crtn.o                        libcrypt.a             libmvec-2.28.9000.so        libnss_files.so             librt.so.1
gconv                         libcrypt.so            libmvec.a                   libnss_files.so.2           libSegFault.so
gcrt1.o                       libcrypt.so.1          libmvec_nonshared.a         libnss_hesiod-2.28.9000.so  libthread_db-1.0.so
ld-2.28.9000.so               libc.so                libmvec.so                  libnss_hesiod.so            libthread_db.so
ld-linux-x86-64.so.2          libc.so.6              libmvec.so.1                libnss_hesiod.so.2          libthread_db.so.1
libanl-2.28.9000.so           libdl-2.28.9000.so     libnsl-2.28.9000.so         libpcprofile.so             libutil-2.28.9000.so
libanl.a                      libdl.a                libnsl.so.1                 libpthread-2.28.9000.so     libutil.a
libanl.so                     libdl.so               libnss_compat-2.28.9000.so  libpthread.a                libutil.so
libanl.so.1                   libdl.so.2             libnss_compat.so            libpthread.so               libutil.so.1
libBrokenLocale-2.28.9000.so  libg.a                 libnss_compat.so.2          libpthread.so.0             Mcrt1.o
libBrokenLocale.a             libm-2.28.9000.a       libnss_db-2.28.9000.so      libresolv-2.28.9000.so      Scrt1.o
libBrokenLocale.so            libm-2.28.9000.so      libnss_db.so                libresolv.a
libBrokenLocale.so.1          libm.a                 libnss_db.so.2              libresolv.so
libc-2.28.9000.so             libmcheck.a            libnss_dns-2.28.9000.so     libresolv.so.2

/bin

是除了 ldd以外,我全部沒印象。有些甚至不在Ubuntu的預設安裝中。使用者需要另外安裝,如xtrace等。

列出幾個我有興趣的工具

  • pldd: 列出process使用的shared library。奇怪的是我自己用卻只有列出process的執行檔名稱而已。
  • sotruss: 經由PLT (Procedure Linkage Table) trace shared library calls
  • sprof: share object 的profile 工具
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
bin
├── catchsegv
├── gencat
├── getconf
├── getent
├── iconv
├── ldd
├── locale
├── localedef
├── makedb
├── mtrace
├── pcprofiledump
├── pldd
├── sotruss
├── sprof
├── tzselect
└── xtrace

/sbin

  • 除了ldconfig外其他的不認識
1
2
3
4
5
6
7
8
9
10
11
$ tree sbin/
sbin/
├── iconvconfig
├── ldconfig
├── nscd
├── sln
├── zdump
etc
├── ld.so.conf
└── rpc
└── zic

/etc

很有趣,竟然有rpc (remote procedure call)的檔案,紀錄rpc通訊協定的資訊。

1
2
3
etc
├── ld.so.conf
└── rpc

/share

  • 存放時區以及多國語言相關檔案

/var

跳過

/libexec

跳過

/include

跳過

參考資料

附錄

  • 編譯hello.c 囉唆資訊節錄
1
/usr/lib/gcc/x86_64-linux-gnu/7/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/7/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper -plugin-opt=-fresolution=/tmp/ccnUW8Qj.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --sysroot=/ --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o hello /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/7 -L/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/7/../../.. /tmp/ccTxSMPW.o -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o
  • 會連結系統提供的object檔案列出如下
    • crtn.o
    • Scrt1.o
    • crti.o
    • crtendS.o
    • crtbeginS.o

在Ubuntu 18.04.2 Trace 程式呼叫 Glibc 函數

| Comments

不囉唆,直接上懶人包。

環境設定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash
# 其實直接在剪下指令貼在終端機就就可以了
# 安裝套件並下載libcsource code
DBG_PATH=~/tmp/lib_debug
sudo apt install -y libc6-dbg
mkdir -p $DBG_PATH
cd $DBG_PATH
apt source libc6-dev
rm glibc_2.27-3ubuntu1.debian.tar.xz  glibc_2.27.orig.tar.xz glibc_2.27-3ubuntu1.dsc

# 設定load directory
LIBC_PATH=${DBG_PATH}/glibc-2.27
EX_FILES=~/tmp/lib_debug/ld_dir.ex
rm -f $EX_FILES
for i in $(find ${LIBC_PATH}/* -maxdepth 0 -type d); \
  do echo "directory $i" >> $EX_FILES ; 
done

使用方式

1
gdb 你的執行檔 -x ~/tmp/lib_debug/ld_dir.ex

範例

程式

1
2
3
4
5
6
7
8
#include <stdio.h>

int main(void)
{
    printf("Hello world\n");

    return 0;
}

示範操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ gdb ./hello -x ~/tmp/lib_debug/ld_dir.ex
GNU gdb (Ubuntu 8.1-0ubuntu3) 8.1.0.20180409-git
....
Reading symbols from ./hello...done.
(gdb) b main
Breakpoint 1 at 0x63e: file hello.c, line 5.
(gdb) r
Starting program: /tmp/hello 

Breakpoint 1, main () at hello.c:5
5     printf("Hello world\n");
(gdb) s
_IO_puts (str=0x5555555546e4 "Hello world") at ioputs.c:33
33    {
(gdb) 

參考資料

從gdb Dump Process 記憶體資料

| Comments

無聊在trace vdso 找到的技巧。整理如下

方法說明

  • gdb 你要的程式
  • gdb 設常用的 system callopen
  • 執行程式
  • 中斷後
    • info proc mappings
    • dump memory 檔名 開始位址 結束位址
    • 離開
  • 剩下看你拿要dump 的檔案做啥了

範例: dump process中的vdso記憶體區塊,觀察vdso symbol

  • gdb 你要的程式
1
2
3
4
5
$ gdb /bin/ls
GNU gdb (Ubuntu 8.1-0ubuntu3) 8.1.0.20180409-git
...
Reading symbols from /bin/ls...(no debugging symbols found)...done.
(gdb) 
  • gdb 設常用的 system callopen
1
2
(gdb) b open
Breakpoint 1 at 0x3d30
  • 執行程式
1
2
3
4
5
6
(gdb) r
Starting program: /bin/ls 

Breakpoint 1, __libc_open64 (file=file@entry=0x7ffff7df6428 "/etc/ld.so.cache", oflag=oflag@entry=524288)
    at ../sysdeps/unix/sysv/linux/open64.c:39
39    ../sysdeps/unix/sysv/linux/open64.c: No such file or directory.
  • info proc mapings
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(gdb) info proc mappings 
process 30094
Mapped address spaces:

          Start Addr           End Addr       Size     Offset objfile
      0x555555554000     0x555555573000    0x1f000        0x0 /bin/ls
      0x555555772000     0x555555775000     0x3000    0x1e000 /bin/ls
      0x555555775000     0x555555776000     0x1000        0x0 [heap]
      0x7ffff7dd5000     0x7ffff7dfc000    0x27000        0x0 /lib/x86_64-linux-gnu/ld-2.27.so
      0x7ffff7ff7000     0x7ffff7ffa000     0x3000        0x0 [vvar]
      0x7ffff7ffa000     0x7ffff7ffc000     0x2000        0x0 [vdso]
      0x7ffff7ffc000     0x7ffff7ffe000     0x2000    0x27000 /lib/x86_64-linux-gnu/ld-2.27.so
      0x7ffff7ffe000     0x7ffff7fff000     0x1000        0x0 
      0x7ffffffde000     0x7ffffffff000    0x21000        0x0 [stack]
  0xffffffffff600000 0xffffffffff601000     0x1000        0x0 [vsyscall]
  • dump memory 檔名 開始位址 結束位址
1
2
3
4
5
6
7
(gdb) dump memory vdso 0x7ffff7ffa000  0x7ffff7ffc000
(gdb) quit
A debugging session is active.

  Inferior 1 [process 30094] will be killed.

Quit anyway? (y or n) y
  • 看dump 檔案 symbol
1
2
3
4
5
6
7
8
9
10
11
12
$ file vdso 
vdso: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=cef5ed3c3dc2b39082ae093560c168a8b427ebb6, stripped
$ nm -D vdso 
0000000000000a30 W clock_gettime
0000000000000f30 W getcpu
0000000000000d40 W gettimeofday
0000000000000000 A LINUX_2.6
0000000000000f10 W time
0000000000000a30 T __vdso_clock_gettime
0000000000000f30 T __vdso_getcpu
0000000000000d40 T __vdso_gettimeofday
0000000000000f10 T __vdso_time

加碼,觀察ASLR

懶的說明ASLR,請自行參考連結。 另外請自行比較下面兩個 cat 的記憶體區塊位址。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ cat /proc/self/maps
5601e5311000-5601e5319000 r-xp 00000000 103:02 13631603                  /bin/cat
...
5601e6814000-5601e6835000 rw-p 00000000 00:00 0                          [heap]
...
7ffe6edcf000-7ffe6edf0000 rw-p 00000000 00:00 0                          [stack]
7ffe6edfb000-7ffe6edfe000 r--p 00000000 00:00 0                          [vvar]
7ffe6edfe000-7ffe6ee00000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]


$ cat /proc/self/maps
556ef8185000-556ef818d000 r-xp 00000000 103:02 13631603                  /bin/cat
...
556ef91df000-556ef9200000 rw-p 00000000 00:00 0                          [heap]
...
7ffc83c55000-7ffc83c76000 rw-p 00000000 00:00 0                          [stack]
7ffc83d4a000-7ffc83d4d000 r--p 00000000 00:00 0                          [vvar]
7ffc83d4d000-7ffc83d4f000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

Linux Binary 縮寫和連結

| Comments

整理目前看過的資料縮寫以及網路連結,可能會更新。

ELF header

  • hdr: header
  • Ehdr: ELF header
  • EI: ELF ident
  • ET: ELF type
  • EM: ELF machine

Program header

  • Phdr: Program header
  • PT: Program header type
  • PF: Prgram header flag

Section header

  • Shdr: Section header
  • SHN: Section header index
  • sh_: Section header
  • SHT: Section header type
  • SHF: Section header flag

Symbol table

  • st: Symbol table
  • STT: Symbol table type
  • STV: Symbol table visibility

Dynamic section

  • DT: Dynamic section type

Note section

  • NT: Note type

Auxiliary vector

  • AT: auxiliary vector type

資源

Ubuntu 16.04更新到Ubuntu 18.04後Octopress 環境變動

| Comments

本來想要寫一些東西,結果發現rake在Ubuntu 無法執行,只好先處理了。

主要的問題是更新後Ruby版本從16.04使用的2.3升級成2.5了。以下是我紀錄過的測試指令,必須承認這是網路上的東西剪貼,我不想知道後面的原理,後果自行負責。寫這篇文章另一個目的是確定上傳到網路上後可以正常發佈才證明真的解決問題了。

預安裝套件

1
sudo apt install -y gcc libcurl4-openssl-dev libxml2-dev

Ruby 相關更新,完全不知道做啥

1
2
3
sudo gem install bundler
bundle install
sudo gem install rake

更新Octopress Gemfile

由於更新後rake版本也從10.5.0變成12.3.1,所以一跑rake就會出現版本不合的錯誤,因此我把Gemfile rake的版本檢查改成12,diff 檔案如下

1
2
3
4
5
6
7
8
9
10
11
12
13
diff --git a/Gemfile b/Gemfile
index 153dd3d..9f5048b 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,7 +1,7 @@
 source "https://rubygems.org"

 group :development do
-  gem 'rake', '~> 10.0'
+  gem 'rake', '~> 12.0'
   gem 'jekyll', '~> 2.0'
   gem 'octopress-hooks', '~> 2.2'
   gem 'octopress-date-format', '~> 2.0'

參考資料