llvm.org GIT mirror llvm / 79eed69
[cfi-verify] Add blacklist parsing for result filtering. Adds blacklist parsing behaviour for filtering results into four categories: - Expected Protected: Things that are not in the blacklist and are protected. - Unexpected Protected: Things that are in the blacklist and are protected. - Expected Unprotected: Things that are in the blacklist and are unprotected. - Unexpected Unprotected: Things that are not in the blacklist and are unprotected. now can optionally be invoked with a second command line argument, which specifies the blacklist file that the binary was built with. Current statistics for chromium: Reviewers: vlad.tsyrklevich Subscribers: mgorny, llvm-commits, pcc, kcc Differential Revision: https://reviews.llvm.org/D39525 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@317364 91177308-0d34-0410-b5e6-96231b3b80d8 Mitch Phillips 1 year, 9 months ago
21 changed file(s) with 1036 addition(s) and 505 deletion(s). Raw diff Collapse all Expand all
0 # Source (tiny.cc):
1 # void a() {}
2 # void b() {}
3 # int main(int argc, char** argv) {
4 # void(*ptr)();
5 # if (argc == 1)
6 # ptr = &a;
7 # else
8 # ptr = &b;
9 # ptr();
10 # }
11 # Compile with (output is in tiny.s.0):
12 # clang++ -flto -fsanitize=cfi -fvisibility=hidden -c tiny.cc -o tiny.o -gmlt
13 # clang++ tiny.o -o tiny -flto -fuse-ld=gold -Wl,-plugin-opt,save-temps
14 # clang++ -fsanitize=cfi -flto -fvisibility=hidden -c tiny.cc -o tiny.o -gmlt
15 # llvm-lto2 run @tiny.resolution.txt -o tiny.s -filetype=asm
16
17 .text
18 .file "ld-temp.o"
19 .p2align 4, 0x90
20 .type _Z1av.cfi,@function
21 _Z1av.cfi:
22 .Lfunc_begin0:
23 .file 1 "tiny.cc"
24 .loc 1 1 0
25 .cfi_startproc
26 pushq %rbp
27 .cfi_def_cfa_offset 16
28 .cfi_offset %rbp, -16
29 movq %rsp, %rbp
30 .cfi_def_cfa_register %rbp
31 .Ltmp0:
32 .loc 1 1 11 prologue_end
33 popq %rbp
34 retq
35 .Ltmp1:
36 .Lfunc_end0:
37 .size _Z1av.cfi, .Lfunc_end0-_Z1av.cfi
38 .cfi_endproc
39
40 .p2align 4, 0x90
41 .type _Z1bv.cfi,@function
42 _Z1bv.cfi:
43 .Lfunc_begin1:
44 .loc 1 2 0
45 .cfi_startproc
46 pushq %rbp
47 .cfi_def_cfa_offset 16
48 .cfi_offset %rbp, -16
49 movq %rsp, %rbp
50 .cfi_def_cfa_register %rbp
51 .Ltmp2:
52 .loc 1 2 11 prologue_end
53 popq %rbp
54 retq
55 .Ltmp3:
56 .Lfunc_end1:
57 .size _Z1bv.cfi, .Lfunc_end1-_Z1bv.cfi
58 .cfi_endproc
59
60 .hidden main
61 .globl main
62 .p2align 4, 0x90
63 .type main,@function
64 main:
65 .Lfunc_begin2:
66 .loc 1 4 0
67 .cfi_startproc
68 pushq %rbp
69 .cfi_def_cfa_offset 16
70 .cfi_offset %rbp, -16
71 movq %rsp, %rbp
72 .cfi_def_cfa_register %rbp
73 subq $32, %rsp
74 movl $0, -8(%rbp)
75 movl %edi, -4(%rbp)
76 movq %rsi, -24(%rbp)
77 .Ltmp4:
78 .loc 1 6 12 prologue_end
79 cmpl $1, -4(%rbp)
80 .loc 1 6 7 is_stmt 0
81 jne .LBB2_2
82 .loc 1 0 7
83 leaq _Z1av(%rip), %rax
84 .loc 1 7 9 is_stmt 1
85 movq %rax, -16(%rbp)
86 .loc 1 7 5 is_stmt 0
87 jmp .LBB2_3
88 .LBB2_2:
89 .loc 1 0 5
90 leaq _Z1bv(%rip), %rax
91 .loc 1 9 9 is_stmt 1
92 movq %rax, -16(%rbp)
93 .LBB2_3:
94 .loc 1 0 9 is_stmt 0
95 leaq .L.cfi.jumptable(%rip), %rcx
96 .loc 1 11 3 is_stmt 1
97 movq -16(%rbp), %rax
98 movq %rax, %rdx
99 subq %rcx, %rdx
100 movq %rdx, %rcx
101 shrq $3, %rcx
102 shlq $61, %rdx
103 orq %rcx, %rdx
104 cmpq $1, %rdx
105 jbe .LBB2_5
106 ud2
107 .LBB2_5:
108 callq *%rax
109 .loc 1 12 1
110 movl -8(%rbp), %eax
111 addq $32, %rsp
112 popq %rbp
113 retq
114 .Ltmp5:
115 .Lfunc_end2:
116 .size main, .Lfunc_end2-main
117 .cfi_endproc
118
119 .p2align 3, 0x90
120 .type .L.cfi.jumptable,@function
121 .L.cfi.jumptable:
122 .Lfunc_begin3:
123 .cfi_startproc
124 #APP
125 jmp _Z1av.cfi@PLT
126 int3
127 int3
128 int3
129 jmp _Z1bv.cfi@PLT
130 int3
131 int3
132 int3
133
134 #NO_APP
135 .Lfunc_end3:
136 .size .L.cfi.jumptable, .Lfunc_end3-.L.cfi.jumptable
137 .cfi_endproc
138
139 .section .debug_str,"MS",@progbits,1
140 .Linfo_string0:
141 .asciz "clang version 6.0.0 (trunk 316774)"
142 .Linfo_string1:
143 .asciz "tiny.cc"
144 .Linfo_string2:
145 .asciz ""
146 .section .debug_abbrev,"",@progbits
147 .byte 1
148 .byte 17
149 .byte 0
150 .byte 37
151 .byte 14
152 .byte 19
153 .byte 5
154 .byte 3
155 .byte 14
156 .byte 16
157 .byte 23
158 .byte 27
159 .byte 14
160 .byte 17
161 .byte 1
162 .byte 18
163 .byte 6
164 .byte 0
165 .byte 0
166 .byte 0
167 .section .debug_info,"",@progbits
168 .Lcu_begin0:
169 .long 38
170 .short 4
171 .long .debug_abbrev
172 .byte 8
173 .byte 1
174 .long .Linfo_string0
175 .short 4
176 .long .Linfo_string1
177 .long .Lline_table_start0
178 .long .Linfo_string2
179 .quad .Lfunc_begin0
180 .long .Lfunc_end2-.Lfunc_begin0
181 .section .debug_ranges,"",@progbits
182 .section .debug_macinfo,"",@progbits
183 .Lcu_macro_begin0:
184 .byte 0
185
186 .type _Z1av,@function
187 _Z1av = .L.cfi.jumptable
188 .type _Z1bv,@function
189 _Z1bv = .L.cfi.jumptable+8
190 .ident "clang version 6.0.0 (trunk 316774)"
191 .section ".note.GNU-stack","",@progbits
192 .section .debug_line,"",@progbits
193 .Lline_table_start0:
194
0 # Source (tiny.cc):
1 # void a() {}
2 # void b() {}
3 # int main(int argc, char** argv) {
4 # void(*ptr)();
5 # if (argc == 1)
6 # ptr = &a;
7 # else
8 # ptr = &b;
9 # ptr();
10 # }
11 # Compile with:
12 # clang++ -g tiny.cc -S -o tiny.s
13
14 .text
15 .file "tiny.cc"
16 .globl _Z1av # -- Begin function _Z1av
17 .p2align 4, 0x90
18 .type _Z1av,@function
19 _Z1av: # @_Z1av
20 .Lfunc_begin0:
21 .file 1 "tiny.cc"
22 .loc 1 1 0 # tiny.cc:1:0
23 .cfi_startproc
24 # BB#0:
25 pushq %rbp
26 .cfi_def_cfa_offset 16
27 .cfi_offset %rbp, -16
28 movq %rsp, %rbp
29 .cfi_def_cfa_register %rbp
30 .Ltmp0:
31 .loc 1 1 11 prologue_end # tiny.cc:1:11
32 popq %rbp
33 .cfi_def_cfa %rsp, 8
34 retq
35 .Ltmp1:
36 .Lfunc_end0:
37 .size _Z1av, .Lfunc_end0-_Z1av
38 .cfi_endproc
39 # -- End function
40 .globl _Z1bv # -- Begin function _Z1bv
41 .p2align 4, 0x90
42 .type _Z1bv,@function
43 _Z1bv: # @_Z1bv
44 .Lfunc_begin1:
45 .loc 1 2 0 # tiny.cc:2:0
46 .cfi_startproc
47 # BB#0:
48 pushq %rbp
49 .cfi_def_cfa_offset 16
50 .cfi_offset %rbp, -16
51 movq %rsp, %rbp
52 .cfi_def_cfa_register %rbp
53 .Ltmp2:
54 .loc 1 2 11 prologue_end # tiny.cc:2:11
55 popq %rbp
56 .cfi_def_cfa %rsp, 8
57 retq
58 .Ltmp3:
59 .Lfunc_end1:
60 .size _Z1bv, .Lfunc_end1-_Z1bv
61 .cfi_endproc
62 # -- End function
63 .globl main # -- Begin function main
64 .p2align 4, 0x90
65 .type main,@function
66 main: # @main
67 .Lfunc_begin2:
68 .loc 1 4 0 # tiny.cc:4:0
69 .cfi_startproc
70 # BB#0:
71 pushq %rbp
72 .cfi_def_cfa_offset 16
73 .cfi_offset %rbp, -16
74 movq %rsp, %rbp
75 .cfi_def_cfa_register %rbp
76 subq $32, %rsp
77 movl $0, -4(%rbp)
78 movl %edi, -8(%rbp)
79 movq %rsi, -16(%rbp)
80 .Ltmp4:
81 .loc 1 6 12 prologue_end # tiny.cc:6:12
82 cmpl $1, -8(%rbp)
83 .Ltmp5:
84 .loc 1 6 7 is_stmt 0 # tiny.cc:6:7
85 jne .LBB2_2
86 # BB#1:
87 .loc 1 0 7 # tiny.cc:0:7
88 movabsq $_Z1av, %rax
89 .Ltmp6:
90 .loc 1 7 9 is_stmt 1 # tiny.cc:7:9
91 movq %rax, -24(%rbp)
92 .loc 1 7 5 is_stmt 0 # tiny.cc:7:5
93 jmp .LBB2_3
94 .LBB2_2:
95 .loc 1 0 5 # tiny.cc:0:5
96 movabsq $_Z1bv, %rax
97 .loc 1 9 9 is_stmt 1 # tiny.cc:9:9
98 movq %rax, -24(%rbp)
99 .Ltmp7:
100 .LBB2_3:
101 .loc 1 11 3 # tiny.cc:11:3
102 callq *-24(%rbp)
103 .loc 1 12 1 # tiny.cc:12:1
104 movl -4(%rbp), %eax
105 addq $32, %rsp
106 popq %rbp
107 .cfi_def_cfa %rsp, 8
108 retq
109 .Ltmp8:
110 .Lfunc_end2:
111 .size main, .Lfunc_end2-main
112 .cfi_endproc
113 # -- End function
114 .section .debug_str,"MS",@progbits,1
115 .Linfo_string0:
116 .asciz "clang version 6.0.0 (trunk 317104)" # string offset=0
117 .Linfo_string1:
118 .asciz "tiny.cc" # string offset=35
119 .Linfo_string2:
120 .asciz "/tmp/a/b" # string offset=43
121 .Linfo_string3:
122 .asciz "_Z1av" # string offset=52
123 .Linfo_string4:
124 .asciz "a" # string offset=58
125 .Linfo_string5:
126 .asciz "_Z1bv" # string offset=60
127 .Linfo_string6:
128 .asciz "b" # string offset=66
129 .Linfo_string7:
130 .asciz "main" # string offset=68
131 .Linfo_string8:
132 .asciz "int" # string offset=73
133 .Linfo_string9:
134 .asciz "argc" # string offset=77
135 .Linfo_string10:
136 .asciz "argv" # string offset=82
137 .Linfo_string11:
138 .asciz "char" # string offset=87
139 .Linfo_string12:
140 .asciz "ptr" # string offset=92
141 .section .debug_abbrev,"",@progbits
142 .byte 1 # Abbreviation Code
143 .byte 17 # DW_TAG_compile_unit
144 .byte 1 # DW_CHILDREN_yes
145 .byte 37 # DW_AT_producer
146 .byte 14 # DW_FORM_strp
147 .byte 19 # DW_AT_language
148 .byte 5 # DW_FORM_data2
149 .byte 3 # DW_AT_name
150 .byte 14 # DW_FORM_strp
151 .byte 16 # DW_AT_stmt_list
152 .byte 23 # DW_FORM_sec_offset
153 .byte 27 # DW_AT_comp_dir
154 .byte 14 # DW_FORM_strp
155 .ascii "\264B" # DW_AT_GNU_pubnames
156 .byte 25 # DW_FORM_flag_present
157 .byte 17 # DW_AT_low_pc
158 .byte 1 # DW_FORM_addr
159 .byte 18 # DW_AT_high_pc
160 .byte 6 # DW_FORM_data4
161 .byte 0 # EOM(1)
162 .byte 0 # EOM(2)
163 .byte 2 # Abbreviation Code
164 .byte 46 # DW_TAG_subprogram
165 .byte 0 # DW_CHILDREN_no
166 .byte 17 # DW_AT_low_pc
167 .byte 1 # DW_FORM_addr
168 .byte 18 # DW_AT_high_pc
169 .byte 6 # DW_FORM_data4
170 .byte 64 # DW_AT_frame_base
171 .byte 24 # DW_FORM_exprloc
172 .byte 110 # DW_AT_linkage_name
173 .byte 14 # DW_FORM_strp
174 .byte 3 # DW_AT_name
175 .byte 14 # DW_FORM_strp
176 .byte 58 # DW_AT_decl_file
177 .byte 11 # DW_FORM_data1
178 .byte 59 # DW_AT_decl_line
179 .byte 11 # DW_FORM_data1
180 .byte 63 # DW_AT_external
181 .byte 25 # DW_FORM_flag_present
182 .byte 0 # EOM(1)
183 .byte 0 # EOM(2)
184 .byte 3 # Abbreviation Code
185 .byte 46 # DW_TAG_subprogram
186 .byte 1 # DW_CHILDREN_yes
187 .byte 17 # DW_AT_low_pc
188 .byte 1 # DW_FORM_addr
189 .byte 18 # DW_AT_high_pc
190 .byte 6 # DW_FORM_data4
191 .byte 64 # DW_AT_frame_base
192 .byte 24 # DW_FORM_exprloc
193 .byte 3 # DW_AT_name
194 .byte 14 # DW_FORM_strp
195 .byte 58 # DW_AT_decl_file
196 .byte 11 # DW_FORM_data1
197 .byte 59 # DW_AT_decl_line
198 .byte 11 # DW_FORM_data1
199 .byte 73 # DW_AT_type
200 .byte 19 # DW_FORM_ref4
201 .byte 63 # DW_AT_external
202 .byte 25 # DW_FORM_flag_present
203 .byte 0 # EOM(1)
204 .byte 0 # EOM(2)
205 .byte 4 # Abbreviation Code
206 .byte 5 # DW_TAG_formal_parameter
207 .byte 0 # DW_CHILDREN_no
208 .byte 2 # DW_AT_location
209 .byte 24 # DW_FORM_exprloc
210 .byte 3 # DW_AT_name
211 .byte 14 # DW_FORM_strp
212 .byte 58 # DW_AT_decl_file
213 .byte 11 # DW_FORM_data1
214 .byte 59 # DW_AT_decl_line
215 .byte 11 # DW_FORM_data1
216 .byte 73 # DW_AT_type
217 .byte 19 # DW_FORM_ref4
218 .byte 0 # EOM(1)
219 .byte 0 # EOM(2)
220 .byte 5 # Abbreviation Code
221 .byte 52 # DW_TAG_variable
222 .byte 0 # DW_CHILDREN_no
223 .byte 2 # DW_AT_location
224 .byte 24 # DW_FORM_exprloc
225 .byte 3 # DW_AT_name
226 .byte 14 # DW_FORM_strp
227 .byte 58 # DW_AT_decl_file
228 .byte 11 # DW_FORM_data1
229 .byte 59 # DW_AT_decl_line
230 .byte 11 # DW_FORM_data1
231 .byte 73 # DW_AT_type
232 .byte 19 # DW_FORM_ref4
233 .byte 0 # EOM(1)
234 .byte 0 # EOM(2)
235 .byte 6 # Abbreviation Code
236 .byte 36 # DW_TAG_base_type
237 .byte 0 # DW_CHILDREN_no
238 .byte 3 # DW_AT_name
239 .byte 14 # DW_FORM_strp
240 .byte 62 # DW_AT_encoding
241 .byte 11 # DW_FORM_data1
242 .byte 11 # DW_AT_byte_size
243 .byte 11 # DW_FORM_data1
244 .byte 0 # EOM(1)
245 .byte 0 # EOM(2)
246 .byte 7 # Abbreviation Code
247 .byte 15 # DW_TAG_pointer_type
248 .byte 0 # DW_CHILDREN_no
249 .byte 73 # DW_AT_type
250 .byte 19 # DW_FORM_ref4
251 .byte 0 # EOM(1)
252 .byte 0 # EOM(2)
253 .byte 8 # Abbreviation Code
254 .byte 21 # DW_TAG_subroutine_type
255 .byte 0 # DW_CHILDREN_no
256 .byte 0 # EOM(1)
257 .byte 0 # EOM(2)
258 .byte 0 # EOM(3)
259 .section .debug_info,"",@progbits
260 .Lcu_begin0:
261 .long 187 # Length of Unit
262 .short 4 # DWARF version number
263 .long .debug_abbrev # Offset Into Abbrev. Section
264 .byte 8 # Address Size (in bytes)
265 .byte 1 # Abbrev [1] 0xb:0xb4 DW_TAG_compile_unit
266 .long .Linfo_string0 # DW_AT_producer
267 .short 4 # DW_AT_language
268 .long .Linfo_string1 # DW_AT_name
269 .long .Lline_table_start0 # DW_AT_stmt_list
270 .long .Linfo_string2 # DW_AT_comp_dir
271 # DW_AT_GNU_pubnames
272 .quad .Lfunc_begin0 # DW_AT_low_pc
273 .long .Lfunc_end2-.Lfunc_begin0 # DW_AT_high_pc
274 .byte 2 # Abbrev [2] 0x2a:0x19 DW_TAG_subprogram
275 .quad .Lfunc_begin0 # DW_AT_low_pc
276 .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
277 .byte 1 # DW_AT_frame_base
278 .byte 86
279 .long .Linfo_string3 # DW_AT_linkage_name
280 .long .Linfo_string4 # DW_AT_name
281 .byte 1 # DW_AT_decl_file
282 .byte 1 # DW_AT_decl_line
283 # DW_AT_external
284 .byte 2 # Abbrev [2] 0x43:0x19 DW_TAG_subprogram
285 .quad .Lfunc_begin1 # DW_AT_low_pc
286 .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc
287 .byte 1 # DW_AT_frame_base
288 .byte 86
289 .long .Linfo_string5 # DW_AT_linkage_name
290 .long .Linfo_string6 # DW_AT_name
291 .byte 1 # DW_AT_decl_file
292 .byte 2 # DW_AT_decl_line
293 # DW_AT_external
294 .byte 3 # Abbrev [3] 0x5c:0x44 DW_TAG_subprogram
295 .quad .Lfunc_begin2 # DW_AT_low_pc
296 .long .Lfunc_end2-.Lfunc_begin2 # DW_AT_high_pc
297 .byte 1 # DW_AT_frame_base
298 .byte 86
299 .long .Linfo_string7 # DW_AT_name
300 .byte 1 # DW_AT_decl_file
301 .byte 4 # DW_AT_decl_line
302 .long 160 # DW_AT_type
303 # DW_AT_external
304 .byte 4 # Abbrev [4] 0x75:0xe DW_TAG_formal_parameter
305 .byte 2 # DW_AT_location
306 .byte 145
307 .byte 120
308 .long .Linfo_string9 # DW_AT_name
309 .byte 1 # DW_AT_decl_file
310 .byte 4 # DW_AT_decl_line
311 .long 160 # DW_AT_type
312 .byte 4 # Abbrev [4] 0x83:0xe DW_TAG_formal_parameter
313 .byte 2 # DW_AT_location
314 .byte 145
315 .byte 112
316 .long .Linfo_string10 # DW_AT_name
317 .byte 1 # DW_AT_decl_file
318 .byte 4 # DW_AT_decl_line
319 .long 167 # DW_AT_type
320 .byte 5 # Abbrev [5] 0x91:0xe DW_TAG_variable
321 .byte 2 # DW_AT_location
322 .byte 145
323 .byte 104
324 .long .Linfo_string12 # DW_AT_name
325 .byte 1 # DW_AT_decl_file
326 .byte 5 # DW_AT_decl_line
327 .long 184 # DW_AT_type
328 .byte 0 # End Of Children Mark
329 .byte 6 # Abbrev [6] 0xa0:0x7 DW_TAG_base_type
330 .long .Linfo_string8 # DW_AT_name
331 .byte 5 # DW_AT_encoding
332 .byte 4 # DW_AT_byte_size
333 .byte 7 # Abbrev [7] 0xa7:0x5 DW_TAG_pointer_type
334 .long 172 # DW_AT_type
335 .byte 7 # Abbrev [7] 0xac:0x5 DW_TAG_pointer_type
336 .long 177 # DW_AT_type
337 .byte 6 # Abbrev [6] 0xb1:0x7 DW_TAG_base_type
338 .long .Linfo_string11 # DW_AT_name
339 .byte 6 # DW_AT_encoding
340 .byte 1 # DW_AT_byte_size
341 .byte 7 # Abbrev [7] 0xb8:0x5 DW_TAG_pointer_type
342 .long 189 # DW_AT_type
343 .byte 8 # Abbrev [8] 0xbd:0x1 DW_TAG_subroutine_type
344 .byte 0 # End Of Children Mark
345 .section .debug_ranges,"",@progbits
346 .section .debug_macinfo,"",@progbits
347 .Lcu_macro_begin0:
348 .byte 0 # End Of Macro List Mark
349 .section .debug_pubnames,"",@progbits
350 .long .LpubNames_end0-.LpubNames_begin0 # Length of Public Names Info
351 .LpubNames_begin0:
352 .short 2 # DWARF Version
353 .long .Lcu_begin0 # Offset of Compilation Unit Info
354 .long 191 # Compilation Unit Length
355 .long 42 # DIE offset
356 .asciz "a" # External Name
357 .long 67 # DIE offset
358 .asciz "b" # External Name
359 .long 92 # DIE offset
360 .asciz "main" # External Name
361 .long 0 # End Mark
362 .LpubNames_end0:
363 .section .debug_pubtypes,"",@progbits
364 .long .LpubTypes_end0-.LpubTypes_begin0 # Length of Public Types Info
365 .LpubTypes_begin0:
366 .short 2 # DWARF Version
367 .long .Lcu_begin0 # Offset of Compilation Unit Info
368 .long 191 # Compilation Unit Length
369 .long 160 # DIE offset
370 .asciz "int" # External Name
371 .long 177 # DIE offset
372 .asciz "char" # External Name
373 .long 0 # End Mark
374 .LpubTypes_end0:
375
376 .ident "clang version 6.0.0 (trunk 317104)"
377 .section ".note.GNU-stack","",@progbits
378 .section .debug_line,"",@progbits
379 .Lline_table_start0:
0 # Source (tiny.cc):
1 # void a() {}
2 # void b() {}
3 # int main(int argc, char** argv) {
4 # void(*ptr)();
5 # if (argc == 1)
6 # ptr = &a;
7 # else
8 # ptr = &b;
9 # ptr();
10 # }
11 # Compile with:
12 # clang++ -gmlt tiny.cc -S -o tiny.s
13
14 .text
15 .file "tiny.cc"
16 .globl _Z1av # -- Begin function _Z1av
17 .p2align 4, 0x90
18 .type _Z1av,@function
19 _Z1av: # @_Z1av
20 .Lfunc_begin0:
21 .file 1 "tiny.cc"
22 .loc 1 1 0 # tiny.cc:1:0
23 .cfi_startproc
24 # BB#0:
25 pushq %rbp
26 .cfi_def_cfa_offset 16
27 .cfi_offset %rbp, -16
28 movq %rsp, %rbp
29 .cfi_def_cfa_register %rbp
30 .Ltmp0:
31 .loc 1 1 11 prologue_end # tiny.cc:1:11
32 popq %rbp
33 retq
34 .Ltmp1:
35 .Lfunc_end0:
36 .size _Z1av, .Lfunc_end0-_Z1av
37 .cfi_endproc
38 # -- End function
39 .globl _Z1bv # -- Begin function _Z1bv
40 .p2align 4, 0x90
41 .type _Z1bv,@function
42 _Z1bv: # @_Z1bv
43 .Lfunc_begin1:
44 .loc 1 2 0 # tiny.cc:2:0
45 .cfi_startproc
46 # BB#0:
47 pushq %rbp
48 .cfi_def_cfa_offset 16
49 .cfi_offset %rbp, -16
50 movq %rsp, %rbp
51 .cfi_def_cfa_register %rbp
52 .Ltmp2:
53 .loc 1 2 11 prologue_end # tiny.cc:2:11
54 popq %rbp
55 retq
56 .Ltmp3:
57 .Lfunc_end1:
58 .size _Z1bv, .Lfunc_end1-_Z1bv
59 .cfi_endproc
60 # -- End function
61 .globl main # -- Begin function main
62 .p2align 4, 0x90
63 .type main,@function
64 main: # @main
65 .Lfunc_begin2:
66 .loc 1 4 0 # tiny.cc:4:0
67 .cfi_startproc
68 # BB#0:
69 pushq %rbp
70 .cfi_def_cfa_offset 16
71 .cfi_offset %rbp, -16
72 movq %rsp, %rbp
73 .cfi_def_cfa_register %rbp
74 subq $32, %rsp
75 movl $0, -4(%rbp)
76 movl %edi, -8(%rbp)
77 movq %rsi, -16(%rbp)
78 .Ltmp4:
79 .loc 1 6 12 prologue_end # tiny.cc:6:12
80 cmpl $1, -8(%rbp)
81 .loc 1 6 7 is_stmt 0 # tiny.cc:6:7
82 jne .LBB2_2
83 # BB#1:
84 .loc 1 0 7 # tiny.cc:0:7
85 movabsq $_Z1av, %rax
86 .loc 1 7 9 is_stmt 1 # tiny.cc:7:9
87 movq %rax, -24(%rbp)
88 .loc 1 7 5 is_stmt 0 # tiny.cc:7:5
89 jmp .LBB2_3
90 .LBB2_2:
91 .loc 1 0 5 # tiny.cc:0:5
92 movabsq $_Z1bv, %rax
93 .loc 1 9 9 is_stmt 1 # tiny.cc:9:9
94 movq %rax, -24(%rbp)
95 .LBB2_3:
96 .loc 1 11 3 # tiny.cc:11:3
97 callq *-24(%rbp)
98 .loc 1 12 1 # tiny.cc:12:1
99 movl -4(%rbp), %eax
100 addq $32, %rsp
101 popq %rbp
102 retq
103 .Ltmp5:
104 .Lfunc_end2:
105 .size main, .Lfunc_end2-main
106 .cfi_endproc
107 # -- End function
108 .section .debug_str,"MS",@progbits,1
109 .Linfo_string0:
110 .asciz "clang version 6.0.0 (trunk 316774)" # string offset=0
111 .Linfo_string1:
112 .asciz "tiny.cc" # string offset=35
113 .Linfo_string2:
114 .asciz "/tmp/a/b" # string offset=43
115 .section .debug_abbrev,"",@progbits
116 .byte 1 # Abbreviation Code
117 .byte 17 # DW_TAG_compile_unit
118 .byte 0 # DW_CHILDREN_no
119 .byte 37 # DW_AT_producer
120 .byte 14 # DW_FORM_strp
121 .byte 19 # DW_AT_language
122 .byte 5 # DW_FORM_data2
123 .byte 3 # DW_AT_name
124 .byte 14 # DW_FORM_strp
125 .byte 16 # DW_AT_stmt_list
126 .byte 23 # DW_FORM_sec_offset
127 .byte 27 # DW_AT_comp_dir
128 .byte 14 # DW_FORM_strp
129 .byte 17 # DW_AT_low_pc
130 .byte 1 # DW_FORM_addr
131 .byte 18 # DW_AT_high_pc
132 .byte 6 # DW_FORM_data4
133 .byte 0 # EOM(1)
134 .byte 0 # EOM(2)
135 .byte 0 # EOM(3)
136 .section .debug_info,"",@progbits
137 .Lcu_begin0:
138 .long 38 # Length of Unit
139 .short 4 # DWARF version number
140 .long .debug_abbrev # Offset Into Abbrev. Section
141 .byte 8 # Address Size (in bytes)
142 .byte 1 # Abbrev [1] 0xb:0x1f DW_TAG_compile_unit
143 .long .Linfo_string0 # DW_AT_producer
144 .short 4 # DW_AT_language
145 .long .Linfo_string1 # DW_AT_name
146 .long .Lline_table_start0 # DW_AT_stmt_list
147 .long .Linfo_string2 # DW_AT_comp_dir
148 .quad .Lfunc_begin0 # DW_AT_low_pc
149 .long .Lfunc_end2-.Lfunc_begin0 # DW_AT_high_pc
150 .section .debug_ranges,"",@progbits
151 .section .debug_macinfo,"",@progbits
152 .Lcu_macro_begin0:
153 .byte 0 # End Of Macro List Mark
154
155 .ident "clang version 6.0.0 (trunk 316774)"
156 .section ".note.GNU-stack","",@progbits
157 .section .debug_line,"",@progbits
158 .Lline_table_start0:
0 # Source (tiny.cc):
1 # void a() {}
2 # void b() {}
3 # int main(int argc, char** argv) {
4 # void(*ptr)();
5 # if (argc == 1)
6 # ptr = &a;
7 # else
8 # ptr = &b;
9 # ptr();
10 # }
11 # Compile with:
12 # clang++ tiny.cc -S -o tiny.s
13
14 .text
15 .file "tiny.cc"
16 .globl _Z1av # -- Begin function _Z1av
17 .p2align 4, 0x90
18 .type _Z1av,@function
19 _Z1av: # @_Z1av
20 .cfi_startproc
21 # BB#0:
22 pushq %rbp
23 .cfi_def_cfa_offset 16
24 .cfi_offset %rbp, -16
25 movq %rsp, %rbp
26 .cfi_def_cfa_register %rbp
27 popq %rbp
28 retq
29 .Lfunc_end0:
30 .size _Z1av, .Lfunc_end0-_Z1av
31 .cfi_endproc
32 # -- End function
33 .globl _Z1bv # -- Begin function _Z1bv
34 .p2align 4, 0x90
35 .type _Z1bv,@function
36 _Z1bv: # @_Z1bv
37 .cfi_startproc
38 # BB#0:
39 pushq %rbp
40 .cfi_def_cfa_offset 16
41 .cfi_offset %rbp, -16
42 movq %rsp, %rbp
43 .cfi_def_cfa_register %rbp
44 popq %rbp
45 retq
46 .Lfunc_end1:
47 .size _Z1bv, .Lfunc_end1-_Z1bv
48 .cfi_endproc
49 # -- End function
50 .globl main # -- Begin function main
51 .p2align 4, 0x90
52 .type main,@function
53 main: # @main
54 .cfi_startproc
55 # BB#0:
56 pushq %rbp
57 .cfi_def_cfa_offset 16
58 .cfi_offset %rbp, -16
59 movq %rsp, %rbp
60 .cfi_def_cfa_register %rbp
61 subq $32, %rsp
62 movl $0, -4(%rbp)
63 movl %edi, -8(%rbp)
64 movq %rsi, -16(%rbp)
65 cmpl $1, -8(%rbp)
66 jne .LBB2_2
67 # BB#1:
68 movabsq $_Z1av, %rax
69 movq %rax, -24(%rbp)
70 jmp .LBB2_3
71 .LBB2_2:
72 movabsq $_Z1bv, %rax
73 movq %rax, -24(%rbp)
74 .LBB2_3:
75 callq *-24(%rbp)
76 movl -4(%rbp), %eax
77 addq $32, %rsp
78 popq %rbp
79 retq
80 .Lfunc_end2:
81 .size main, .Lfunc_end2-main
82 .cfi_endproc
83 # -- End function
84
85 .ident "clang version 6.0.0 (trunk 316774)"
86 .section ".note.GNU-stack","",@progbits
0 # RUN: llvm-mc %S/Inputs/unprotected-lineinfo.s -filetype obj \
1 # RUN: -triple x86_64-linux-elf -o %t.o
2 # RUN: echo "src:*tiny*" > %t.blacklist.txt
3 # RUN: llvm-cfi-verify %t.o %t.blacklist.txt | FileCheck %s
4
5 # CHECK-LABEL: U
6 # CHECK-NEXT: tiny.cc:11
7 # CHECK-NEXT: BLACKLIST MATCH, 'src'
8 # CHECK-NEXT: ====> Expected Unprotected
9
10 # CHECK: Expected Protected: 0 (0.00%)
11 # CHECK: Unexpected Protected: 0 (0.00%)
12 # CHECK: Expected Unprotected: 1 (100.00%)
13 # CHECK: Unexpected Unprotected (BAD): 0 (0.00%)
14
15 # Source: (blacklist.txt):
16 # src:*tiny*
0 # RUN: llvm-mc %S/Inputs/unprotected-fullinfo.s -filetype obj \
1 # RUN: -triple x86_64-linux-elf -o %t.o
2 # RUN: echo "fun:*main*" > %t.blacklist.txt
3 # RUN: llvm-cfi-verify %t.o %t.blacklist.txt | FileCheck %s
4
5 # CHECK-LABEL: U
6 # CHECK-NEXT: tiny.cc:11
7 # CHECK-NEXT: BLACKLIST MATCH, 'fun'
8 # CHECK-NEXT: ====> Expected Unprotected
9
10 # CHECK: Expected Protected: 0 (0.00%)
11 # CHECK: Unexpected Protected: 0 (0.00%)
12 # CHECK: Expected Unprotected: 1 (100.00%)
13 # CHECK: Unexpected Unprotected (BAD): 0 (0.00%)
14
15 # Source: (blacklist.txt):
16 # fun:*main*
0 # RUN: llvm-mc %S/Inputs/protected-lineinfo.s -filetype obj \
1 # RUN: -triple x86_64-linux-elf -o %t.o
2 # RUN: echo "src:*tiny*" > %t.blacklist.txt
3 # RUN: llvm-cfi-verify %t.o %t.blacklist.txt | FileCheck %s
4
5 # CHECK-LABEL: P
6 # CHECK-NEXT: tiny.cc:11
7 # CHECK-NEXT: BLACKLIST MATCH, 'src'
8 # CHECK-NEXT: ====> Unexpected Protected
9
10 # CHECK: Expected Protected: 0 (0.00%)
11 # CHECK: Unexpected Protected: 1 (100.00%)
12 # CHECK: Expected Unprotected: 0 (0.00%)
13 # CHECK: Unexpected Unprotected (BAD): 0 (0.00%)
14
15 # Source: (blacklist.txt):
16 # src:*tiny*
99 # reporting of the cfi-verify program. It should only find a single indirect CF
1010 # instruction at `tiny.cc:11` (see protected-lineinfo.s for the source).
1111
12 # CHECK: Unprotected: 0 (0.00%), Protected: 1 (100.00%)
12 # CHECK: Expected Protected: 1 (100.00%)
13 # CHECK: Unexpected Protected: 0 (0.00%)
14 # CHECK: Expected Unprotected: 0 (0.00%)
15 # CHECK: Unexpected Unprotected (BAD): 0 (0.00%)
1316
1417 .text
1518 .file "ld-temp.o"
None # RUN: llvm-mc %s -filetype obj -triple x86_64-linux-elf -o %t.o
0 # RUN: llvm-mc %S/Inputs/protected-lineinfo.s -filetype obj \
1 # RUN: -triple x86_64-linux-elf -o %t.o
12 # RUN: llvm-cfi-verify %t.o | FileCheck %s
23
34 # CHECK-LABEL: P
45 # CHECK-NEXT: tiny.cc:11
56
6 # CHECK: Unprotected: 0 (0.00%), Protected: 1 (100.00%)
7
8 # Source (tiny.cc):
9 # void a() {}
10 # void b() {}
11 # int main(int argc, char** argv) {
12 # void(*ptr)();
13 # if (argc == 1)
14 # ptr = &a;
15 # else
16 # ptr = &b;
17 # ptr();
18 # }
19 # Compile with (output is in tiny.s.0):
20 # clang++ -flto -fsanitize=cfi -fvisibility=hidden -c tiny.cc -o tiny.o -gmlt
21 # clang++ tiny.o -o tiny -flto -fuse-ld=gold -Wl,-plugin-opt,save-temps
22 # clang++ -fsanitize=cfi -flto -fvisibility=hidden -c tiny.cc -o tiny.o -gmlt
23 # llvm-lto2 run @tiny.resolution.txt -o tiny.s -filetype=asm
24
25 .text
26 .file "ld-temp.o"
27 .p2align 4, 0x90
28 .type _Z1av.cfi,@function
29 _Z1av.cfi:
30 .Lfunc_begin0:
31 .file 1 "tiny.cc"
32 .loc 1 1 0
33 .cfi_startproc
34 pushq %rbp
35 .cfi_def_cfa_offset 16
36 .cfi_offset %rbp, -16
37 movq %rsp, %rbp
38 .cfi_def_cfa_register %rbp
39 .Ltmp0:
40 .loc 1 1 11 prologue_end
41 popq %rbp
42 retq
43 .Ltmp1:
44 .Lfunc_end0:
45 .size _Z1av.cfi, .Lfunc_end0-_Z1av.cfi
46 .cfi_endproc
47
48 .p2align 4, 0x90
49 .type _Z1bv.cfi,@function
50 _Z1bv.cfi:
51 .Lfunc_begin1:
52 .loc 1 2 0
53 .cfi_startproc
54 pushq %rbp
55 .cfi_def_cfa_offset 16
56 .cfi_offset %rbp, -16
57 movq %rsp, %rbp
58 .cfi_def_cfa_register %rbp
59 .Ltmp2:
60 .loc 1 2 11 prologue_end
61 popq %rbp
62 retq
63 .Ltmp3:
64 .Lfunc_end1:
65 .size _Z1bv.cfi, .Lfunc_end1-_Z1bv.cfi
66 .cfi_endproc
67
68 .hidden main
69 .globl main
70 .p2align 4, 0x90
71 .type main,@function
72 main:
73 .Lfunc_begin2:
74 .loc 1 4 0
75 .cfi_startproc
76 pushq %rbp
77 .cfi_def_cfa_offset 16
78 .cfi_offset %rbp, -16
79 movq %rsp, %rbp
80 .cfi_def_cfa_register %rbp
81 subq $32, %rsp
82 movl $0, -8(%rbp)
83 movl %edi, -4(%rbp)
84 movq %rsi, -24(%rbp)
85 .Ltmp4:
86 .loc 1 6 12 prologue_end
87 cmpl $1, -4(%rbp)
88 .loc 1 6 7 is_stmt 0
89 jne .LBB2_2
90 .loc 1 0 7
91 leaq _Z1av(%rip), %rax
92 .loc 1 7 9 is_stmt 1
93 movq %rax, -16(%rbp)
94 .loc 1 7 5 is_stmt 0
95 jmp .LBB2_3
96 .LBB2_2:
97 .loc 1 0 5
98 leaq _Z1bv(%rip), %rax
99 .loc 1 9 9 is_stmt 1
100 movq %rax, -16(%rbp)
101 .LBB2_3:
102 .loc 1 0 9 is_stmt 0
103 leaq .L.cfi.jumptable(%rip), %rcx
104 .loc 1 11 3 is_stmt 1
105 movq -16(%rbp), %rax
106 movq %rax, %rdx
107 subq %rcx, %rdx
108 movq %rdx, %rcx
109 shrq $3, %rcx
110 shlq $61, %rdx
111 orq %rcx, %rdx
112 cmpq $1, %rdx
113 jbe .LBB2_5
114 ud2
115 .LBB2_5:
116 callq *%rax
117 .loc 1 12 1
118 movl -8(%rbp), %eax
119 addq $32, %rsp
120 popq %rbp
121 retq
122 .Ltmp5:
123 .Lfunc_end2:
124 .size main, .Lfunc_end2-main
125 .cfi_endproc
126
127 .p2align 3, 0x90
128 .type .L.cfi.jumptable,@function
129 .L.cfi.jumptable:
130 .Lfunc_begin3:
131 .cfi_startproc
132 #APP
133 jmp _Z1av.cfi@PLT
134 int3
135 int3
136 int3
137 jmp _Z1bv.cfi@PLT
138 int3
139 int3
140 int3
141
142 #NO_APP
143 .Lfunc_end3:
144 .size .L.cfi.jumptable, .Lfunc_end3-.L.cfi.jumptable
145 .cfi_endproc
146
147 .section .debug_str,"MS",@progbits,1
148 .Linfo_string0:
149 .asciz "clang version 6.0.0 (trunk 316774)"
150 .Linfo_string1:
151 .asciz "tiny.cc"
152 .Linfo_string2:
153 .asciz ""
154 .section .debug_abbrev,"",@progbits
155 .byte 1
156 .byte 17
157 .byte 0
158 .byte 37
159 .byte 14
160 .byte 19
161 .byte 5
162 .byte 3
163 .byte 14
164 .byte 16
165 .byte 23
166 .byte 27
167 .byte 14
168 .byte 17
169 .byte 1
170 .byte 18
171 .byte 6
172 .byte 0
173 .byte 0
174 .byte 0
175 .section .debug_info,"",@progbits
176 .Lcu_begin0:
177 .long 38
178 .short 4
179 .long .debug_abbrev
180 .byte 8
181 .byte 1
182 .long .Linfo_string0
183 .short 4
184 .long .Linfo_string1
185 .long .Lline_table_start0
186 .long .Linfo_string2
187 .quad .Lfunc_begin0
188 .long .Lfunc_end2-.Lfunc_begin0
189 .section .debug_ranges,"",@progbits
190 .section .debug_macinfo,"",@progbits
191 .Lcu_macro_begin0:
192 .byte 0
193
194 .type _Z1av,@function
195 _Z1av = .L.cfi.jumptable
196 .type _Z1bv,@function
197 _Z1bv = .L.cfi.jumptable+8
198 .ident "clang version 6.0.0 (trunk 316774)"
199 .section ".note.GNU-stack","",@progbits
200 .section .debug_line,"",@progbits
201 .Lline_table_start0:
202
7 # CHECK: Expected Protected: 1 (100.00%)
8 # CHECK: Unexpected Protected: 0 (0.00%)
9 # CHECK: Expected Unprotected: 0 (0.00%)
10 # CHECK: Unexpected Unprotected (BAD): 0 (0.00%)
None # RUN: llvm-mc %s -filetype obj -triple x86_64-linux-elf -o %t.o
0 # RUN: llvm-mc %S/Inputs/unprotected-lineinfo.s -filetype obj \
1 # RUN: -triple x86_64-linux-elf -o %t.o
12 # RUN: llvm-cfi-verify %t.o | FileCheck %s
23
34 # CHECK-LABEL: U
45 # CHECK-NEXT: tiny.cc:11
56
6 # CHECK: Unprotected: 1 (100.00%), Protected: 0 (0.00%)
7
8 # Source (tiny.cc):
9 # void a() {}
10 # void b() {}
11 # int main(int argc, char** argv) {
12 # void(*ptr)();
13 # if (argc == 1)
14 # ptr = &a;
15 # else
16 # ptr = &b;
17 # ptr();
18 # }
19 # Compile with:
20 # clang++ -gmlt tiny.cc -S -o tiny.s
21
22 .text
23 .file "tiny.cc"
24 .globl _Z1av # -- Begin function _Z1av
25 .p2align 4, 0x90
26 .type _Z1av,@function
27 _Z1av: # @_Z1av
28 .Lfunc_begin0:
29 .file 1 "tiny.cc"
30 .loc 1 1 0 # tiny.cc:1:0
31 .cfi_startproc
32 # BB#0:
33 pushq %rbp
34 .cfi_def_cfa_offset 16
35 .cfi_offset %rbp, -16
36 movq %rsp, %rbp
37 .cfi_def_cfa_register %rbp
38 .Ltmp0:
39 .loc 1 1 11 prologue_end # tiny.cc:1:11
40 popq %rbp
41 retq
42 .Ltmp1:
43 .Lfunc_end0:
44 .size _Z1av, .Lfunc_end0-_Z1av
45 .cfi_endproc
46 # -- End function
47 .globl _Z1bv # -- Begin function _Z1bv
48 .p2align 4, 0x90
49 .type _Z1bv,@function
50 _Z1bv: # @_Z1bv
51 .Lfunc_begin1:
52 .loc 1 2 0 # tiny.cc:2:0
53 .cfi_startproc
54 # BB#0:
55 pushq %rbp
56 .cfi_def_cfa_offset 16
57 .cfi_offset %rbp, -16
58 movq %rsp, %rbp
59 .cfi_def_cfa_register %rbp
60 .Ltmp2:
61 .loc 1 2 11 prologue_end # tiny.cc:2:11
62 popq %rbp
63 retq
64 .Ltmp3:
65 .Lfunc_end1:
66 .size _Z1bv, .Lfunc_end1-_Z1bv
67 .cfi_endproc
68 # -- End function
69 .globl main # -- Begin function main
70 .p2align 4, 0x90
71 .type main,@function
72 main: # @main
73 .Lfunc_begin2:
74 .loc 1 4 0 # tiny.cc:4:0
75 .cfi_startproc
76 # BB#0:
77 pushq %rbp
78 .cfi_def_cfa_offset 16
79 .cfi_offset %rbp, -16
80 movq %rsp, %rbp
81 .cfi_def_cfa_register %rbp
82 subq $32, %rsp
83 movl $0, -4(%rbp)
84 movl %edi, -8(%rbp)
85 movq %rsi, -16(%rbp)
86 .Ltmp4:
87 .loc 1 6 12 prologue_end # tiny.cc:6:12
88 cmpl $1, -8(%rbp)
89 .loc 1 6 7 is_stmt 0 # tiny.cc:6:7
90 jne .LBB2_2
91 # BB#1:
92 .loc 1 0 7 # tiny.cc:0:7
93 movabsq $_Z1av, %rax
94 .loc 1 7 9 is_stmt 1 # tiny.cc:7:9
95 movq %rax, -24(%rbp)
96 .loc 1 7 5 is_stmt 0 # tiny.cc:7:5
97 jmp .LBB2_3
98 .LBB2_2:
99 .loc 1 0 5 # tiny.cc:0:5
100 movabsq $_Z1bv, %rax
101 .loc 1 9 9 is_stmt 1 # tiny.cc:9:9
102 movq %rax, -24(%rbp)
103 .LBB2_3:
104 .loc 1 11 3 # tiny.cc:11:3
105 callq *-24(%rbp)
106 .loc 1 12 1 # tiny.cc:12:1
107 movl -4(%rbp), %eax
108 addq $32, %rsp
109 popq %rbp
110 retq
111 .Ltmp5:
112 .Lfunc_end2:
113 .size main, .Lfunc_end2-main
114 .cfi_endproc
115 # -- End function
116 .section .debug_str,"MS",@progbits,1
117 .Linfo_string0:
118 .asciz "clang version 6.0.0 (trunk 316774)" # string offset=0
119 .Linfo_string1:
120 .asciz "tiny.cc" # string offset=35
121 .Linfo_string2:
122 .asciz "/tmp/a/b" # string offset=43
123 .section .debug_abbrev,"",@progbits
124 .byte 1 # Abbreviation Code
125 .byte 17 # DW_TAG_compile_unit
126 .byte 0 # DW_CHILDREN_no
127 .byte 37 # DW_AT_producer
128 .byte 14 # DW_FORM_strp
129 .byte 19 # DW_AT_language
130 .byte 5 # DW_FORM_data2
131 .byte 3 # DW_AT_name
132 .byte 14 # DW_FORM_strp
133 .byte 16 # DW_AT_stmt_list
134 .byte 23 # DW_FORM_sec_offset
135 .byte 27 # DW_AT_comp_dir
136 .byte 14 # DW_FORM_strp
137 .byte 17 # DW_AT_low_pc
138 .byte 1 # DW_FORM_addr
139 .byte 18 # DW_AT_high_pc
140 .byte 6 # DW_FORM_data4
141 .byte 0 # EOM(1)
142 .byte 0 # EOM(2)
143 .byte 0 # EOM(3)
144 .section .debug_info,"",@progbits
145 .Lcu_begin0:
146 .long 38 # Length of Unit
147 .short 4 # DWARF version number
148 .long .debug_abbrev # Offset Into Abbrev. Section
149 .byte 8 # Address Size (in bytes)
150 .byte 1 # Abbrev [1] 0xb:0x1f DW_TAG_compile_unit
151 .long .Linfo_string0 # DW_AT_producer
152 .short 4 # DW_AT_language
153 .long .Linfo_string1 # DW_AT_name
154 .long .Lline_table_start0 # DW_AT_stmt_list
155 .long .Linfo_string2 # DW_AT_comp_dir
156 .quad .Lfunc_begin0 # DW_AT_low_pc
157 .long .Lfunc_end2-.Lfunc_begin0 # DW_AT_high_pc
158 .section .debug_ranges,"",@progbits
159 .section .debug_macinfo,"",@progbits
160 .Lcu_macro_begin0:
161 .byte 0 # End Of Macro List Mark
162
163 .ident "clang version 6.0.0 (trunk 316774)"
164 .section ".note.GNU-stack","",@progbits
165 .section .debug_line,"",@progbits
166 .Lline_table_start0:
7 # CHECK: Expected Protected: 0 (0.00%)
8 # CHECK: Unexpected Protected: 0 (0.00%)
9 # CHECK: Expected Unprotected: 0 (0.00%)
10 # CHECK: Unexpected Unprotected (BAD): 1 (100.00%)
None # RUN: llvm-mc %s -filetype obj -triple x86_64-linux-elf -o %t.o
0 # RUN: llvm-mc %S/Inputs/unprotected-nolineinfo.s -filetype obj \
1 # RUN: -triple x86_64-linux-elf -o %t.o
12 # RUN: not llvm-cfi-verify %t.o 2>&1 | FileCheck %s
23
34 # CHECK: DWARF line information missing. Did you compile with '-g'?
4
5 # Source (tiny.cc):
6 # void a() {}
7 # void b() {}
8 # int main(int argc, char** argv) {
9 # void(*ptr)();
10 # if (argc == 1)
11 # ptr = &a;
12 # else
13 # ptr = &b;
14 # ptr();
15 # }
16 # Compile with:
17 # clang++ tiny.cc -S -o tiny.s
18
19 .text
20 .file "tiny.cc"
21 .globl _Z1av # -- Begin function _Z1av
22 .p2align 4, 0x90
23 .type _Z1av,@function
24 _Z1av: # @_Z1av
25 .cfi_startproc
26 # BB#0:
27 pushq %rbp
28 .cfi_def_cfa_offset 16
29 .cfi_offset %rbp, -16
30 movq %rsp, %rbp
31 .cfi_def_cfa_register %rbp
32 popq %rbp
33 retq
34 .Lfunc_end0:
35 .size _Z1av, .Lfunc_end0-_Z1av
36 .cfi_endproc
37 # -- End function
38 .globl _Z1bv # -- Begin function _Z1bv
39 .p2align 4, 0x90
40 .type _Z1bv,@function
41 _Z1bv: # @_Z1bv
42 .cfi_startproc
43 # BB#0:
44 pushq %rbp
45 .cfi_def_cfa_offset 16
46 .cfi_offset %rbp, -16
47 movq %rsp, %rbp
48 .cfi_def_cfa_register %rbp
49 popq %rbp
50 retq
51 .Lfunc_end1:
52 .size _Z1bv, .Lfunc_end1-_Z1bv
53 .cfi_endproc
54 # -- End function
55 .globl main # -- Begin function main
56 .p2align 4, 0x90
57 .type main,@function
58 main: # @main
59 .cfi_startproc
60 # BB#0:
61 pushq %rbp
62 .cfi_def_cfa_offset 16
63 .cfi_offset %rbp, -16
64 movq %rsp, %rbp
65 .cfi_def_cfa_register %rbp
66 subq $32, %rsp
67 movl $0, -4(%rbp)
68 movl %edi, -8(%rbp)
69 movq %rsi, -16(%rbp)
70 cmpl $1, -8(%rbp)
71 jne .LBB2_2
72 # BB#1:
73 movabsq $_Z1av, %rax
74 movq %rax, -24(%rbp)
75 jmp .LBB2_3
76 .LBB2_2:
77 movabsq $_Z1bv, %rax
78 movq %rax, -24(%rbp)
79 .LBB2_3:
80 callq *-24(%rbp)
81 movl -4(%rbp), %eax
82 addq $32, %rsp
83 popq %rbp
84 retq
85 .Lfunc_end2:
86 .size main, .Lfunc_end2-main
87 .cfi_endproc
88 # -- End function
89
90 .ident "clang version 6.0.0 (trunk 316774)"
91 .section ".note.GNU-stack","",@progbits
33 AllTargetsDescs
44 AllTargetsDisassemblers
55 AllTargetsInfos
6 DebugInfoDWARF
76 MC
87 MCParser
98 Object
109 Support
10 Symbolize
1111 )
1212
1313 add_llvm_tool(llvm-cfi-verify
1818 type = Tool
1919 name = llvm-cfi-verify
2020 parent = Tools
21 required_libraries = all-targets DebugInfoDWARF MC MCDisassembler MCParser Support
21 required_libraries = all-targets MC MCDisassembler MCParser Support Symbolize
1010 MC
1111 MCParser
1212 Object
13 Support)
13 Support
14 Symbolize)
1415 target_link_libraries(LLVMCFIVerify ${libs})
3838 #include
3939
4040 using Instr = llvm::cfi_verify::FileAnalysis::Instr;
41 using LLVMSymbolizer = llvm::symbolize::LLVMSymbolizer;
4142
4243 namespace llvm {
4344 namespace cfi_verify {
4445
45 static cl::opt IgnoreDWARF(
46 bool IgnoreDWARFFlag;
47
48 static cl::opt IgnoreDWARFArg(
4649 "ignore-dwarf",
4750 cl::desc(
4851 "Ignore all DWARF data. This relaxes the requirements for all "
4952 "statically linked libraries to have been compiled with '-g', but "
5053 "will result in false positives for 'CFI unprotected' instructions."),
51 cl::init(false));
52
53 cl::opt DWARFSearchRange(
54 "dwarf-search-range",
55 cl::desc("Address search range used to determine if instruction is valid."),
56 cl::init(0x10));
54 cl::location(IgnoreDWARFFlag), cl::init(false));
5755
5856 Expected FileAnalysis::Create(StringRef Filename) {
5957 // Open the filename provided.
255253 return MIA.get();
256254 }
257255
256 LLVMSymbolizer &FileAnalysis::getSymbolizer() { return *Symbolizer; }
257
258258 Error FileAnalysis::initialiseDisassemblyMembers() {
259259 std::string TripleName = ObjectTriple.getTriple();
260260 ArchName = "";
261261 MCPU = "";
262262 std::string ErrorString;
263
264 Symbolizer.reset(new LLVMSymbolizer());
263265
264266 ObjectTarget =
265267 TargetRegistry::lookupTarget(ArchName, ObjectTriple, ErrorString);
307309 }
308310
309311 Error FileAnalysis::parseCodeSections() {
310 if (!IgnoreDWARF) {
311 DWARF.reset(DWARFContext::create(*Object).release());
312 if (!IgnoreDWARFFlag) {
313 std::unique_ptr DWARF = DWARFContext::create(*Object);
312314 if (!DWARF)
313315 return make_error("Could not create DWARF information.",
314316 inconvertibleErrorCode());
346348 return Error::success();
347349 }
348350
349 DILineInfoTable FileAnalysis::getLineInfoForAddressRange(uint64_t Address) {
350 if (!hasLineTableInfo())
351 return DILineInfoTable();
352
353 return DWARF->getLineInfoForAddressRange(Address, DWARFSearchRange);
354 }
355
356 bool FileAnalysis::hasValidLineInfoForAddressRange(uint64_t Address) {
357 return !getLineInfoForAddressRange(Address).empty();
358 }
359
360 bool FileAnalysis::hasLineTableInfo() const { return DWARF != nullptr; }
361
362351 void FileAnalysis::parseSectionContents(ArrayRef SectionBytes,
363352 uint64_t SectionAddress) {
353 assert(Symbolizer && "Symbolizer is uninitialised.");
364354 MCInst Instruction;
365355 Instr InstrMeta;
366356 uint64_t InstructionSize;
380370 InstrMeta.Valid = ValidInstruction;
381371
382372 // Check if this instruction exists in the range of the DWARF metadata.
383 if (hasLineTableInfo() && !hasValidLineInfoForAddressRange(VMAddress))
384 continue;
373 if (!IgnoreDWARFFlag) {
374 auto LineInfo =
375 Symbolizer->symbolizeCode(Object->getFileName(), VMAddress);
376 if (!LineInfo) {
377 handleAllErrors(LineInfo.takeError(), [](const ErrorInfoBase &E) {
378 errs() << "Symbolizer failed to get line: " << E.message() << "\n";
379 });
380 continue;
381 }
382
383 if (LineInfo->FileName == "")
384 continue;
385 }
385386
386387 addInstruction(InstrMeta);
387388
1111
1212 #include "llvm/ADT/DenseMap.h"
1313 #include "llvm/BinaryFormat/ELF.h"
14 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
14 #include "llvm/DebugInfo/Symbolize/Symbolize.h"
1515 #include "llvm/MC/MCAsmInfo.h"
1616 #include "llvm/MC/MCContext.h"
1717 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
4343 namespace llvm {
4444 namespace cfi_verify {
4545
46 extern bool IgnoreDWARFFlag;
47
4648 // Disassembler and analysis tool for machine code files. Keeps track of non-
4749 // sequential control flows, including indirect control flow instructions.
4850 class FileAnalysis {
119121 const MCRegisterInfo *getRegisterInfo() const;
120122 const MCInstrInfo *getMCInstrInfo() const;
121123 const MCInstrAnalysis *getMCInstrAnalysis() const;
124 symbolize::LLVMSymbolizer &getSymbolizer();
122125
123126 // Returns true if this class is using DWARF line tables for elimination.
124127 bool hasLineTableInfo() const;
174177 std::unique_ptr MIA;
175178 std::unique_ptr Printer;
176179
177 // DWARF debug information.
178 std::unique_ptr DWARF;
180 // Symbolizer used for debug information parsing.
181 std::unique_ptr Symbolizer;
179182
180183 // A mapping between the virtual memory address to the instruction metadata
181184 // struct. TODO(hctim): Reimplement this as a sorted vector to avoid per-
1818 type = Library
1919 name = CFIVerify
2020 parent = Libraries
21 required_libraries = DebugInfoDWARF MC MCDisassembler MCParser Support
21 required_libraries = DebugInfoDWARF MC MCDisassembler MCParser Support Symbolize
2222 #include "llvm/Support/CommandLine.h"
2323 #include "llvm/Support/Error.h"
2424 #include "llvm/Support/FormatVariadic.h"
25 #include "llvm/Support/SpecialCaseList.h"
2526
2627 #include
2728
3132
3233 cl::opt InputFilename(cl::Positional, cl::desc(""),
3334 cl::Required);
35 cl::opt BlacklistFilename(cl::Positional,
36 cl::desc("[blacklist file]"),
37 cl::init("-"));
3438
3539 ExitOnError ExitOnErr;
3640
37 void printIndirectCFInstructions(FileAnalysis &Analysis) {
38 uint64_t ProtectedCount = 0;
39 uint64_t UnprotectedCount = 0;
41 void printIndirectCFInstructions(FileAnalysis &Analysis,
42 const SpecialCaseList *SpecialCaseList) {
43 uint64_t ExpectedProtected = 0;
44 uint64_t UnexpectedProtected = 0;
45 uint64_t ExpectedUnprotected = 0;
46 uint64_t UnexpectedUnprotected = 0;
47
48 symbolize::LLVMSymbolizer &Symbolizer = Analysis.getSymbolizer();
4049
4150 for (uint64_t Address : Analysis.getIndirectInstructions()) {
4251 const auto &InstrMeta = Analysis.getInstructionOrDie(Address);
4352
44 if (Analysis.isIndirectInstructionCFIProtected(Address)) {
53 bool CFIProtected = Analysis.isIndirectInstructionCFIProtected(Address);
54
55 if (CFIProtected)
4556 outs() << "P ";
46 ProtectedCount++;
47 } else {
57 else
4858 outs() << "U ";
49 UnprotectedCount++;
50 }
5159
5260 outs() << format_hex(Address, 2) << " | "
5361 << Analysis.getMCInstrInfo()->getName(
5462 InstrMeta.Instruction.getOpcode())
55 << " ";
56 outs() << "\n";
63 << " \n";
5764
58 if (Analysis.hasLineTableInfo()) {
59 for (const auto &LineKV : Analysis.getLineInfoForAddressRange(Address)) {
60 outs() << " " << format_hex(LineKV.first, 2) << " = "
61 << LineKV.second.FileName << ":" << LineKV.second.Line << ":"
62 << LineKV.second.Column << " (" << LineKV.second.FunctionName
63 << ")\n";
65 if (IgnoreDWARFFlag) {
66 if (CFIProtected)
67 ExpectedProtected++;
68 else
69 UnexpectedUnprotected++;
70 continue;
71 }
72
73 auto InliningInfo = Symbolizer.symbolizeInlinedCode(InputFilename, Address);
74 if (!InliningInfo || InliningInfo->getNumberOfFrames() == 0) {
75 errs() << "Failed to symbolise " << format_hex(Address, 2)
76 << " with line tables from " << InputFilename << "\n";
77 exit(EXIT_FAILURE);
78 }
79
80 const auto &LineInfo =
81 InliningInfo->getFrame(InliningInfo->getNumberOfFrames() - 1);
82
83 // Print the inlining symbolisation of this instruction.
84 for (uint32_t i = 0; i < InliningInfo->getNumberOfFrames(); ++i) {
85 const auto &Line = InliningInfo->getFrame(i);
86 outs() << " " << format_hex(Address, 2) << " = " << Line.FileName << ":"
87 << Line.Line << ":" << Line.Column << " (" << Line.FunctionName
88 << ")\n";
89 }
90
91 if (!SpecialCaseList) {
92 if (CFIProtected)
93 ExpectedProtected++;
94 else
95 UnexpectedUnprotected++;
96 continue;
97 }
98
99 bool MatchesBlacklistRule = false;
100 if (SpecialCaseList->inSection("cfi-icall", "src", LineInfo.FileName) ||
101 SpecialCaseList->inSection("cfi-vcall", "src", LineInfo.FileName)) {
102 outs() << "BLACKLIST MATCH, 'src'\n";
103 MatchesBlacklistRule = true;
104 }
105
106 if (SpecialCaseList->inSection("cfi-icall", "fun", LineInfo.FunctionName) ||
107 SpecialCaseList->inSection("cfi-vcall", "fun", LineInfo.FunctionName)) {
108 outs() << "BLACKLIST MATCH, 'fun'\n";
109 MatchesBlacklistRule = true;
110 }
111
112 if (MatchesBlacklistRule) {
113 if (CFIProtected) {
114 UnexpectedProtected++;
115 outs() << "====> Unexpected Protected\n";
116 } else {
117 ExpectedUnprotected++;
118 outs() << "====> Expected Unprotected\n";
119 }
120 } else {
121 if (CFIProtected) {
122 ExpectedProtected++;
123 outs() << "====> Expected Protected\n";
124 } else {
125 UnexpectedUnprotected++;
126 outs() << "====> Unexpected Unprotected\n";
64127 }
65128 }
66129 }
67130
68 if (ProtectedCount || UnprotectedCount)
69 outs() << formatv(
70 "Unprotected: {0} ({1:P}), Protected: {2} ({3:P})\n", UnprotectedCount,
71 (((double)UnprotectedCount) / (UnprotectedCount + ProtectedCount)),
72 ProtectedCount,
73 (((double)ProtectedCount) / (UnprotectedCount + ProtectedCount)));
74 else
131 uint64_t IndirectCFInstructions = ExpectedProtected + UnexpectedProtected +
132 ExpectedUnprotected + UnexpectedUnprotected;
133
134 if (IndirectCFInstructions == 0)
75135 outs() << "No indirect CF instructions found.\n";
136
137 outs() << formatv("Expected Protected: {0} ({1:P})\n"
138 "Unexpected Protected: {2} ({3:P})\n"
139 "Expected Unprotected: {4} ({5:P})\n"
140 "Unexpected Unprotected (BAD): {6} ({7:P})\n",
141 ExpectedProtected,
142 ((double)ExpectedProtected) / IndirectCFInstructions,
143 UnexpectedProtected,
144 ((double)UnexpectedProtected) / IndirectCFInstructions,
145 ExpectedUnprotected,
146 ((double)ExpectedUnprotected) / IndirectCFInstructions,
147 UnexpectedUnprotected,
148 ((double)UnexpectedUnprotected) / IndirectCFInstructions);
76149 }
77150
78151 int main(int argc, char **argv) {
88161 InitializeAllAsmParsers();
89162 InitializeAllDisassemblers();
90163
164 std::unique_ptr SpecialCaseList;
165 if (BlacklistFilename != "-") {
166 std::string Error;
167 SpecialCaseList = SpecialCaseList::create({BlacklistFilename}, Error);
168 if (!SpecialCaseList) {
169 errs() << "Failed to get blacklist: " << Error << "\n";
170 exit(EXIT_FAILURE);
171 }
172 }
173
91174 FileAnalysis Analysis = ExitOnErr(FileAnalysis::Create(InputFilename));
92 printIndirectCFInstructions(Analysis);
175 printIndirectCFInstructions(Analysis, SpecialCaseList.get());
93176
94177 return EXIT_SUCCESS;
95178 }
77 MCParser
88 Object
99 Support
10 Symbolize
1011 )
1112
1213 add_llvm_unittest(CFIVerifyTests
6363 class BasicFileAnalysisTest : public ::testing::Test {
6464 protected:
6565 virtual void SetUp() {
66 IgnoreDWARFFlag = true;
6667 SuccessfullyInitialised = true;
6768 if (auto Err = Analysis.initialiseDisassemblyMembers()) {
6869 handleAllErrors(std::move(Err), [&](const UnsupportedDisassembly &E) {
125125 class BasicGraphBuilderTest : public ::testing::Test {
126126 protected:
127127 virtual void SetUp() {
128 IgnoreDWARFFlag = true;
128129 SuccessfullyInitialised = true;
129130 if (auto Err = Analysis.initialiseDisassemblyMembers()) {
130131 handleAllErrors(std::move(Err), [&](const UnsupportedDisassembly &E) {