Index: test/tools/llvm-cfi-verify/X86/Inputs/protected-lineinfo.s =================================================================== --- /dev/null +++ test/tools/llvm-cfi-verify/X86/Inputs/protected-lineinfo.s @@ -0,0 +1,195 @@ +# Source (tiny.cc): +# void a() {} +# void b() {} +# int main(int argc, char** argv) { +# void(*ptr)(); +# if (argc == 1) +# ptr = &a; +# else +# ptr = &b; +# ptr(); +# } +# Compile with (output is in tiny.s.0): +# clang++ -flto -fsanitize=cfi -fvisibility=hidden -c tiny.cc -o tiny.o -gmlt +# clang++ tiny.o -o tiny -flto -fuse-ld=gold -Wl,-plugin-opt,save-temps +# clang++ -fsanitize=cfi -flto -fvisibility=hidden -c tiny.cc -o tiny.o -gmlt +# llvm-lto2 run @tiny.resolution.txt -o tiny.s -filetype=asm + + .text + .file "ld-temp.o" + .p2align 4, 0x90 + .type _Z1av.cfi,@function +_Z1av.cfi: +.Lfunc_begin0: + .file 1 "tiny.cc" + .loc 1 1 0 + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp0: + .loc 1 1 11 prologue_end + popq %rbp + retq +.Ltmp1: +.Lfunc_end0: + .size _Z1av.cfi, .Lfunc_end0-_Z1av.cfi + .cfi_endproc + + .p2align 4, 0x90 + .type _Z1bv.cfi,@function +_Z1bv.cfi: +.Lfunc_begin1: + .loc 1 2 0 + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp2: + .loc 1 2 11 prologue_end + popq %rbp + retq +.Ltmp3: +.Lfunc_end1: + .size _Z1bv.cfi, .Lfunc_end1-_Z1bv.cfi + .cfi_endproc + + .hidden main + .globl main + .p2align 4, 0x90 + .type main,@function +main: +.Lfunc_begin2: + .loc 1 4 0 + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + subq $32, %rsp + movl $0, -8(%rbp) + movl %edi, -4(%rbp) + movq %rsi, -24(%rbp) +.Ltmp4: + .loc 1 6 12 prologue_end + cmpl $1, -4(%rbp) + .loc 1 6 7 is_stmt 0 + jne .LBB2_2 + .loc 1 0 7 + leaq _Z1av(%rip), %rax + .loc 1 7 9 is_stmt 1 + movq %rax, -16(%rbp) + .loc 1 7 5 is_stmt 0 + jmp .LBB2_3 +.LBB2_2: + .loc 1 0 5 + leaq _Z1bv(%rip), %rax + .loc 1 9 9 is_stmt 1 + movq %rax, -16(%rbp) +.LBB2_3: + .loc 1 0 9 is_stmt 0 + leaq .L.cfi.jumptable(%rip), %rcx + .loc 1 11 3 is_stmt 1 + movq -16(%rbp), %rax + movq %rax, %rdx + subq %rcx, %rdx + movq %rdx, %rcx + shrq $3, %rcx + shlq $61, %rdx + orq %rcx, %rdx + cmpq $1, %rdx + jbe .LBB2_5 + ud2 +.LBB2_5: + callq *%rax + .loc 1 12 1 + movl -8(%rbp), %eax + addq $32, %rsp + popq %rbp + retq +.Ltmp5: +.Lfunc_end2: + .size main, .Lfunc_end2-main + .cfi_endproc + + .p2align 3, 0x90 + .type .L.cfi.jumptable,@function +.L.cfi.jumptable: +.Lfunc_begin3: + .cfi_startproc + #APP + jmp _Z1av.cfi@PLT + int3 + int3 + int3 + jmp _Z1bv.cfi@PLT + int3 + int3 + int3 + + #NO_APP +.Lfunc_end3: + .size .L.cfi.jumptable, .Lfunc_end3-.L.cfi.jumptable + .cfi_endproc + + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 6.0.0 (trunk 316774)" +.Linfo_string1: + .asciz "tiny.cc" +.Linfo_string2: + .asciz "" + .section .debug_abbrev,"",@progbits + .byte 1 + .byte 17 + .byte 0 + .byte 37 + .byte 14 + .byte 19 + .byte 5 + .byte 3 + .byte 14 + .byte 16 + .byte 23 + .byte 27 + .byte 14 + .byte 17 + .byte 1 + .byte 18 + .byte 6 + .byte 0 + .byte 0 + .byte 0 + .section .debug_info,"",@progbits +.Lcu_begin0: + .long 38 + .short 4 + .long .debug_abbrev + .byte 8 + .byte 1 + .long .Linfo_string0 + .short 4 + .long .Linfo_string1 + .long .Lline_table_start0 + .long .Linfo_string2 + .quad .Lfunc_begin0 + .long .Lfunc_end2-.Lfunc_begin0 + .section .debug_ranges,"",@progbits + .section .debug_macinfo,"",@progbits +.Lcu_macro_begin0: + .byte 0 + + .type _Z1av,@function +_Z1av = .L.cfi.jumptable + .type _Z1bv,@function +_Z1bv = .L.cfi.jumptable+8 + .ident "clang version 6.0.0 (trunk 316774)" + .section ".note.GNU-stack","",@progbits + .section .debug_line,"",@progbits +.Lline_table_start0: + Index: test/tools/llvm-cfi-verify/X86/Inputs/unprotected-fullinfo.s =================================================================== --- /dev/null +++ test/tools/llvm-cfi-verify/X86/Inputs/unprotected-fullinfo.s @@ -0,0 +1,380 @@ +# Source (tiny.cc): +# void a() {} +# void b() {} +# int main(int argc, char** argv) { +# void(*ptr)(); +# if (argc == 1) +# ptr = &a; +# else +# ptr = &b; +# ptr(); +# } +# Compile with: +# clang++ -g tiny.cc -S -o tiny.s + + .text + .file "tiny.cc" + .globl _Z1av # -- Begin function _Z1av + .p2align 4, 0x90 + .type _Z1av,@function +_Z1av: # @_Z1av +.Lfunc_begin0: + .file 1 "tiny.cc" + .loc 1 1 0 # tiny.cc:1:0 + .cfi_startproc +# BB#0: + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp0: + .loc 1 1 11 prologue_end # tiny.cc:1:11 + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size _Z1av, .Lfunc_end0-_Z1av + .cfi_endproc + # -- End function + .globl _Z1bv # -- Begin function _Z1bv + .p2align 4, 0x90 + .type _Z1bv,@function +_Z1bv: # @_Z1bv +.Lfunc_begin1: + .loc 1 2 0 # tiny.cc:2:0 + .cfi_startproc +# BB#0: + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp2: + .loc 1 2 11 prologue_end # tiny.cc:2:11 + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp3: +.Lfunc_end1: + .size _Z1bv, .Lfunc_end1-_Z1bv + .cfi_endproc + # -- End function + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin2: + .loc 1 4 0 # tiny.cc:4:0 + .cfi_startproc +# BB#0: + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + subq $32, %rsp + movl $0, -4(%rbp) + movl %edi, -8(%rbp) + movq %rsi, -16(%rbp) +.Ltmp4: + .loc 1 6 12 prologue_end # tiny.cc:6:12 + cmpl $1, -8(%rbp) +.Ltmp5: + .loc 1 6 7 is_stmt 0 # tiny.cc:6:7 + jne .LBB2_2 +# BB#1: + .loc 1 0 7 # tiny.cc:0:7 + movabsq $_Z1av, %rax +.Ltmp6: + .loc 1 7 9 is_stmt 1 # tiny.cc:7:9 + movq %rax, -24(%rbp) + .loc 1 7 5 is_stmt 0 # tiny.cc:7:5 + jmp .LBB2_3 +.LBB2_2: + .loc 1 0 5 # tiny.cc:0:5 + movabsq $_Z1bv, %rax + .loc 1 9 9 is_stmt 1 # tiny.cc:9:9 + movq %rax, -24(%rbp) +.Ltmp7: +.LBB2_3: + .loc 1 11 3 # tiny.cc:11:3 + callq *-24(%rbp) + .loc 1 12 1 # tiny.cc:12:1 + movl -4(%rbp), %eax + addq $32, %rsp + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp8: +.Lfunc_end2: + .size main, .Lfunc_end2-main + .cfi_endproc + # -- End function + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 6.0.0 (trunk 317104)" # string offset=0 +.Linfo_string1: + .asciz "tiny.cc" # string offset=35 +.Linfo_string2: + .asciz "/tmp/a/b" # string offset=43 +.Linfo_string3: + .asciz "_Z1av" # string offset=52 +.Linfo_string4: + .asciz "a" # string offset=58 +.Linfo_string5: + .asciz "_Z1bv" # string offset=60 +.Linfo_string6: + .asciz "b" # string offset=66 +.Linfo_string7: + .asciz "main" # string offset=68 +.Linfo_string8: + .asciz "int" # string offset=73 +.Linfo_string9: + .asciz "argc" # string offset=77 +.Linfo_string10: + .asciz "argv" # string offset=82 +.Linfo_string11: + .asciz "char" # string offset=87 +.Linfo_string12: + .asciz "ptr" # string offset=92 + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 14 # DW_FORM_strp + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 14 # DW_FORM_strp + .ascii "\264B" # DW_AT_GNU_pubnames + .byte 25 # DW_FORM_flag_present + .byte 17 # DW_AT_low_pc + .byte 1 # DW_FORM_addr + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 0 # DW_CHILDREN_no + .byte 17 # DW_AT_low_pc + .byte 1 # DW_FORM_addr + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 110 # DW_AT_linkage_name + .byte 14 # DW_FORM_strp + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 1 # DW_FORM_addr + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 6 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 7 # Abbreviation Code + .byte 15 # DW_TAG_pointer_type + .byte 0 # DW_CHILDREN_no + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 8 # Abbreviation Code + .byte 21 # DW_TAG_subroutine_type + .byte 0 # DW_CHILDREN_no + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long 187 # Length of Unit + .short 4 # DWARF version number + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 8 # Address Size (in bytes) + .byte 1 # Abbrev [1] 0xb:0xb4 DW_TAG_compile_unit + .long .Linfo_string0 # DW_AT_producer + .short 4 # DW_AT_language + .long .Linfo_string1 # DW_AT_name + .long .Lline_table_start0 # DW_AT_stmt_list + .long .Linfo_string2 # DW_AT_comp_dir + # DW_AT_GNU_pubnames + .quad .Lfunc_begin0 # DW_AT_low_pc + .long .Lfunc_end2-.Lfunc_begin0 # DW_AT_high_pc + .byte 2 # Abbrev [2] 0x2a:0x19 DW_TAG_subprogram + .quad .Lfunc_begin0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .long .Linfo_string3 # DW_AT_linkage_name + .long .Linfo_string4 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + # DW_AT_external + .byte 2 # Abbrev [2] 0x43:0x19 DW_TAG_subprogram + .quad .Lfunc_begin1 # DW_AT_low_pc + .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .long .Linfo_string5 # DW_AT_linkage_name + .long .Linfo_string6 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + # DW_AT_external + .byte 3 # Abbrev [3] 0x5c:0x44 DW_TAG_subprogram + .quad .Lfunc_begin2 # DW_AT_low_pc + .long .Lfunc_end2-.Lfunc_begin2 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .long .Linfo_string7 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 4 # DW_AT_decl_line + .long 160 # DW_AT_type + # DW_AT_external + .byte 4 # Abbrev [4] 0x75:0xe DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 120 + .long .Linfo_string9 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 4 # DW_AT_decl_line + .long 160 # DW_AT_type + .byte 4 # Abbrev [4] 0x83:0xe DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 112 + .long .Linfo_string10 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 4 # DW_AT_decl_line + .long 167 # DW_AT_type + .byte 5 # Abbrev [5] 0x91:0xe DW_TAG_variable + .byte 2 # DW_AT_location + .byte 145 + .byte 104 + .long .Linfo_string12 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 5 # DW_AT_decl_line + .long 184 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 6 # Abbrev [6] 0xa0:0x7 DW_TAG_base_type + .long .Linfo_string8 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 7 # Abbrev [7] 0xa7:0x5 DW_TAG_pointer_type + .long 172 # DW_AT_type + .byte 7 # Abbrev [7] 0xac:0x5 DW_TAG_pointer_type + .long 177 # DW_AT_type + .byte 6 # Abbrev [6] 0xb1:0x7 DW_TAG_base_type + .long .Linfo_string11 # DW_AT_name + .byte 6 # DW_AT_encoding + .byte 1 # DW_AT_byte_size + .byte 7 # Abbrev [7] 0xb8:0x5 DW_TAG_pointer_type + .long 189 # DW_AT_type + .byte 8 # Abbrev [8] 0xbd:0x1 DW_TAG_subroutine_type + .byte 0 # End Of Children Mark + .section .debug_ranges,"",@progbits + .section .debug_macinfo,"",@progbits +.Lcu_macro_begin0: + .byte 0 # End Of Macro List Mark + .section .debug_pubnames,"",@progbits + .long .LpubNames_end0-.LpubNames_begin0 # Length of Public Names Info +.LpubNames_begin0: + .short 2 # DWARF Version + .long .Lcu_begin0 # Offset of Compilation Unit Info + .long 191 # Compilation Unit Length + .long 42 # DIE offset + .asciz "a" # External Name + .long 67 # DIE offset + .asciz "b" # External Name + .long 92 # DIE offset + .asciz "main" # External Name + .long 0 # End Mark +.LpubNames_end0: + .section .debug_pubtypes,"",@progbits + .long .LpubTypes_end0-.LpubTypes_begin0 # Length of Public Types Info +.LpubTypes_begin0: + .short 2 # DWARF Version + .long .Lcu_begin0 # Offset of Compilation Unit Info + .long 191 # Compilation Unit Length + .long 160 # DIE offset + .asciz "int" # External Name + .long 177 # DIE offset + .asciz "char" # External Name + .long 0 # End Mark +.LpubTypes_end0: + + .ident "clang version 6.0.0 (trunk 317104)" + .section ".note.GNU-stack","",@progbits + .section .debug_line,"",@progbits +.Lline_table_start0: Index: test/tools/llvm-cfi-verify/X86/Inputs/unprotected-lineinfo.s =================================================================== --- /dev/null +++ test/tools/llvm-cfi-verify/X86/Inputs/unprotected-lineinfo.s @@ -0,0 +1,159 @@ +# Source (tiny.cc): +# void a() {} +# void b() {} +# int main(int argc, char** argv) { +# void(*ptr)(); +# if (argc == 1) +# ptr = &a; +# else +# ptr = &b; +# ptr(); +# } +# Compile with: +# clang++ -gmlt tiny.cc -S -o tiny.s + + .text + .file "tiny.cc" + .globl _Z1av # -- Begin function _Z1av + .p2align 4, 0x90 + .type _Z1av,@function +_Z1av: # @_Z1av +.Lfunc_begin0: + .file 1 "tiny.cc" + .loc 1 1 0 # tiny.cc:1:0 + .cfi_startproc +# BB#0: + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp0: + .loc 1 1 11 prologue_end # tiny.cc:1:11 + popq %rbp + retq +.Ltmp1: +.Lfunc_end0: + .size _Z1av, .Lfunc_end0-_Z1av + .cfi_endproc + # -- End function + .globl _Z1bv # -- Begin function _Z1bv + .p2align 4, 0x90 + .type _Z1bv,@function +_Z1bv: # @_Z1bv +.Lfunc_begin1: + .loc 1 2 0 # tiny.cc:2:0 + .cfi_startproc +# BB#0: + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp2: + .loc 1 2 11 prologue_end # tiny.cc:2:11 + popq %rbp + retq +.Ltmp3: +.Lfunc_end1: + .size _Z1bv, .Lfunc_end1-_Z1bv + .cfi_endproc + # -- End function + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin2: + .loc 1 4 0 # tiny.cc:4:0 + .cfi_startproc +# BB#0: + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + subq $32, %rsp + movl $0, -4(%rbp) + movl %edi, -8(%rbp) + movq %rsi, -16(%rbp) +.Ltmp4: + .loc 1 6 12 prologue_end # tiny.cc:6:12 + cmpl $1, -8(%rbp) + .loc 1 6 7 is_stmt 0 # tiny.cc:6:7 + jne .LBB2_2 +# BB#1: + .loc 1 0 7 # tiny.cc:0:7 + movabsq $_Z1av, %rax + .loc 1 7 9 is_stmt 1 # tiny.cc:7:9 + movq %rax, -24(%rbp) + .loc 1 7 5 is_stmt 0 # tiny.cc:7:5 + jmp .LBB2_3 +.LBB2_2: + .loc 1 0 5 # tiny.cc:0:5 + movabsq $_Z1bv, %rax + .loc 1 9 9 is_stmt 1 # tiny.cc:9:9 + movq %rax, -24(%rbp) +.LBB2_3: + .loc 1 11 3 # tiny.cc:11:3 + callq *-24(%rbp) + .loc 1 12 1 # tiny.cc:12:1 + movl -4(%rbp), %eax + addq $32, %rsp + popq %rbp + retq +.Ltmp5: +.Lfunc_end2: + .size main, .Lfunc_end2-main + .cfi_endproc + # -- End function + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 6.0.0 (trunk 316774)" # string offset=0 +.Linfo_string1: + .asciz "tiny.cc" # string offset=35 +.Linfo_string2: + .asciz "/tmp/a/b" # string offset=43 + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 0 # DW_CHILDREN_no + .byte 37 # DW_AT_producer + .byte 14 # DW_FORM_strp + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 14 # DW_FORM_strp + .byte 17 # DW_AT_low_pc + .byte 1 # DW_FORM_addr + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long 38 # Length of Unit + .short 4 # DWARF version number + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 8 # Address Size (in bytes) + .byte 1 # Abbrev [1] 0xb:0x1f DW_TAG_compile_unit + .long .Linfo_string0 # DW_AT_producer + .short 4 # DW_AT_language + .long .Linfo_string1 # DW_AT_name + .long .Lline_table_start0 # DW_AT_stmt_list + .long .Linfo_string2 # DW_AT_comp_dir + .quad .Lfunc_begin0 # DW_AT_low_pc + .long .Lfunc_end2-.Lfunc_begin0 # DW_AT_high_pc + .section .debug_ranges,"",@progbits + .section .debug_macinfo,"",@progbits +.Lcu_macro_begin0: + .byte 0 # End Of Macro List Mark + + .ident "clang version 6.0.0 (trunk 316774)" + .section ".note.GNU-stack","",@progbits + .section .debug_line,"",@progbits +.Lline_table_start0: Index: test/tools/llvm-cfi-verify/X86/Inputs/unprotected-nolineinfo.s =================================================================== --- /dev/null +++ test/tools/llvm-cfi-verify/X86/Inputs/unprotected-nolineinfo.s @@ -0,0 +1,87 @@ +# Source (tiny.cc): +# void a() {} +# void b() {} +# int main(int argc, char** argv) { +# void(*ptr)(); +# if (argc == 1) +# ptr = &a; +# else +# ptr = &b; +# ptr(); +# } +# Compile with: +# clang++ tiny.cc -S -o tiny.s + + .text + .file "tiny.cc" + .globl _Z1av # -- Begin function _Z1av + .p2align 4, 0x90 + .type _Z1av,@function +_Z1av: # @_Z1av + .cfi_startproc +# BB#0: + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + popq %rbp + retq +.Lfunc_end0: + .size _Z1av, .Lfunc_end0-_Z1av + .cfi_endproc + # -- End function + .globl _Z1bv # -- Begin function _Z1bv + .p2align 4, 0x90 + .type _Z1bv,@function +_Z1bv: # @_Z1bv + .cfi_startproc +# BB#0: + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + popq %rbp + retq +.Lfunc_end1: + .size _Z1bv, .Lfunc_end1-_Z1bv + .cfi_endproc + # -- End function + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main + .cfi_startproc +# BB#0: + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + subq $32, %rsp + movl $0, -4(%rbp) + movl %edi, -8(%rbp) + movq %rsi, -16(%rbp) + cmpl $1, -8(%rbp) + jne .LBB2_2 +# BB#1: + movabsq $_Z1av, %rax + movq %rax, -24(%rbp) + jmp .LBB2_3 +.LBB2_2: + movabsq $_Z1bv, %rax + movq %rax, -24(%rbp) +.LBB2_3: + callq *-24(%rbp) + movl -4(%rbp), %eax + addq $32, %rsp + popq %rbp + retq +.Lfunc_end2: + .size main, .Lfunc_end2-main + .cfi_endproc + # -- End function + + .ident "clang version 6.0.0 (trunk 316774)" + .section ".note.GNU-stack","",@progbits Index: test/tools/llvm-cfi-verify/X86/blacklist-expected-unprotected.s =================================================================== --- /dev/null +++ test/tools/llvm-cfi-verify/X86/blacklist-expected-unprotected.s @@ -0,0 +1,17 @@ +# RUN: llvm-mc %S/Inputs/unprotected-lineinfo.s -filetype obj \ +# RUN: -triple x86_64-linux-elf -o %t.o +# RUN: echo "src:*tiny*" > %t.blacklist.txt +# RUN: llvm-cfi-verify %t.o %t.blacklist.txt | FileCheck %s + +# CHECK-LABEL: U +# CHECK-NEXT: tiny.cc:11 +# CHECK-NEXT: BLACKLIST MATCH, 'src' +# CHECK-NEXT: ====> Expected Unprotected + +# CHECK: Expected Protected: 0 (0.00%) +# CHECK: Unexpected Protected: 0 (0.00%) +# CHECK: Expected Unprotected: 1 (100.00%) +# CHECK: Unexpected Unprotected (BAD): 0 (0.00%) + +# Source: (blacklist.txt): +# src:*tiny* Index: test/tools/llvm-cfi-verify/X86/blacklist-match-fun.s =================================================================== --- /dev/null +++ test/tools/llvm-cfi-verify/X86/blacklist-match-fun.s @@ -0,0 +1,17 @@ +# RUN: llvm-mc %S/Inputs/unprotected-fullinfo.s -filetype obj \ +# RUN: -triple x86_64-linux-elf -o %t.o +# RUN: echo "fun:*main*" > %t.blacklist.txt +# RUN: llvm-cfi-verify %t.o %t.blacklist.txt | FileCheck %s + +# CHECK-LABEL: U +# CHECK-NEXT: tiny.cc:11 +# CHECK-NEXT: BLACKLIST MATCH, 'fun' +# CHECK-NEXT: ====> Expected Unprotected + +# CHECK: Expected Protected: 0 (0.00%) +# CHECK: Unexpected Protected: 0 (0.00%) +# CHECK: Expected Unprotected: 1 (100.00%) +# CHECK: Unexpected Unprotected (BAD): 0 (0.00%) + +# Source: (blacklist.txt): +# fun:*main* Index: test/tools/llvm-cfi-verify/X86/blacklist-unexpected-protected.s =================================================================== --- /dev/null +++ test/tools/llvm-cfi-verify/X86/blacklist-unexpected-protected.s @@ -0,0 +1,17 @@ +# RUN: llvm-mc %S/Inputs/protected-lineinfo.s -filetype obj \ +# RUN: -triple x86_64-linux-elf -o %t.o +# RUN: echo "src:*tiny*" > %t.blacklist.txt +# RUN: llvm-cfi-verify %t.o %t.blacklist.txt | FileCheck %s + +# CHECK-LABEL: P +# CHECK-NEXT: tiny.cc:11 +# CHECK-NEXT: BLACKLIST MATCH, 'src' +# CHECK-NEXT: ====> Unexpected Protected + +# CHECK: Expected Protected: 0 (0.00%) +# CHECK: Unexpected Protected: 1 (100.00%) +# CHECK: Expected Unprotected: 0 (0.00%) +# CHECK: Unexpected Unprotected (BAD): 0 (0.00%) + +# Source: (blacklist.txt): +# src:*tiny* Index: test/tools/llvm-cfi-verify/X86/indirect-cf-elimination.s =================================================================== --- test/tools/llvm-cfi-verify/X86/indirect-cf-elimination.s +++ test/tools/llvm-cfi-verify/X86/indirect-cf-elimination.s @@ -10,7 +10,10 @@ # reporting of the cfi-verify program. It should only find a single indirect CF # instruction at `tiny.cc:11` (see protected-lineinfo.s for the source). -# CHECK: Unprotected: 0 (0.00%), Protected: 1 (100.00%) +# CHECK: Expected Protected: 1 (100.00%) +# CHECK: Unexpected Protected: 0 (0.00%) +# CHECK: Expected Unprotected: 0 (0.00%) +# CHECK: Unexpected Unprotected (BAD): 0 (0.00%) .text .file "ld-temp.o" Index: test/tools/llvm-cfi-verify/X86/protected-lineinfo.s =================================================================== --- test/tools/llvm-cfi-verify/X86/protected-lineinfo.s +++ test/tools/llvm-cfi-verify/X86/protected-lineinfo.s @@ -1,203 +1,11 @@ -# RUN: llvm-mc %s -filetype obj -triple x86_64-linux-elf -o %t.o +# RUN: llvm-mc %S/Inputs/protected-lineinfo.s -filetype obj \ +# RUN: -triple x86_64-linux-elf -o %t.o # RUN: llvm-cfi-verify %t.o | FileCheck %s # CHECK-LABEL: P # CHECK-NEXT: tiny.cc:11 -# CHECK: Unprotected: 0 (0.00%), Protected: 1 (100.00%) - -# Source (tiny.cc): -# void a() {} -# void b() {} -# int main(int argc, char** argv) { -# void(*ptr)(); -# if (argc == 1) -# ptr = &a; -# else -# ptr = &b; -# ptr(); -# } -# Compile with (output is in tiny.s.0): -# clang++ -flto -fsanitize=cfi -fvisibility=hidden -c tiny.cc -o tiny.o -gmlt -# clang++ tiny.o -o tiny -flto -fuse-ld=gold -Wl,-plugin-opt,save-temps -# clang++ -fsanitize=cfi -flto -fvisibility=hidden -c tiny.cc -o tiny.o -gmlt -# llvm-lto2 run @tiny.resolution.txt -o tiny.s -filetype=asm - - .text - .file "ld-temp.o" - .p2align 4, 0x90 - .type _Z1av.cfi,@function -_Z1av.cfi: -.Lfunc_begin0: - .file 1 "tiny.cc" - .loc 1 1 0 - .cfi_startproc - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp -.Ltmp0: - .loc 1 1 11 prologue_end - popq %rbp - retq -.Ltmp1: -.Lfunc_end0: - .size _Z1av.cfi, .Lfunc_end0-_Z1av.cfi - .cfi_endproc - - .p2align 4, 0x90 - .type _Z1bv.cfi,@function -_Z1bv.cfi: -.Lfunc_begin1: - .loc 1 2 0 - .cfi_startproc - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp -.Ltmp2: - .loc 1 2 11 prologue_end - popq %rbp - retq -.Ltmp3: -.Lfunc_end1: - .size _Z1bv.cfi, .Lfunc_end1-_Z1bv.cfi - .cfi_endproc - - .hidden main - .globl main - .p2align 4, 0x90 - .type main,@function -main: -.Lfunc_begin2: - .loc 1 4 0 - .cfi_startproc - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp - subq $32, %rsp - movl $0, -8(%rbp) - movl %edi, -4(%rbp) - movq %rsi, -24(%rbp) -.Ltmp4: - .loc 1 6 12 prologue_end - cmpl $1, -4(%rbp) - .loc 1 6 7 is_stmt 0 - jne .LBB2_2 - .loc 1 0 7 - leaq _Z1av(%rip), %rax - .loc 1 7 9 is_stmt 1 - movq %rax, -16(%rbp) - .loc 1 7 5 is_stmt 0 - jmp .LBB2_3 -.LBB2_2: - .loc 1 0 5 - leaq _Z1bv(%rip), %rax - .loc 1 9 9 is_stmt 1 - movq %rax, -16(%rbp) -.LBB2_3: - .loc 1 0 9 is_stmt 0 - leaq .L.cfi.jumptable(%rip), %rcx - .loc 1 11 3 is_stmt 1 - movq -16(%rbp), %rax - movq %rax, %rdx - subq %rcx, %rdx - movq %rdx, %rcx - shrq $3, %rcx - shlq $61, %rdx - orq %rcx, %rdx - cmpq $1, %rdx - jbe .LBB2_5 - ud2 -.LBB2_5: - callq *%rax - .loc 1 12 1 - movl -8(%rbp), %eax - addq $32, %rsp - popq %rbp - retq -.Ltmp5: -.Lfunc_end2: - .size main, .Lfunc_end2-main - .cfi_endproc - - .p2align 3, 0x90 - .type .L.cfi.jumptable,@function -.L.cfi.jumptable: -.Lfunc_begin3: - .cfi_startproc - #APP - jmp _Z1av.cfi@PLT - int3 - int3 - int3 - jmp _Z1bv.cfi@PLT - int3 - int3 - int3 - - #NO_APP -.Lfunc_end3: - .size .L.cfi.jumptable, .Lfunc_end3-.L.cfi.jumptable - .cfi_endproc - - .section .debug_str,"MS",@progbits,1 -.Linfo_string0: - .asciz "clang version 6.0.0 (trunk 316774)" -.Linfo_string1: - .asciz "tiny.cc" -.Linfo_string2: - .asciz "" - .section .debug_abbrev,"",@progbits - .byte 1 - .byte 17 - .byte 0 - .byte 37 - .byte 14 - .byte 19 - .byte 5 - .byte 3 - .byte 14 - .byte 16 - .byte 23 - .byte 27 - .byte 14 - .byte 17 - .byte 1 - .byte 18 - .byte 6 - .byte 0 - .byte 0 - .byte 0 - .section .debug_info,"",@progbits -.Lcu_begin0: - .long 38 - .short 4 - .long .debug_abbrev - .byte 8 - .byte 1 - .long .Linfo_string0 - .short 4 - .long .Linfo_string1 - .long .Lline_table_start0 - .long .Linfo_string2 - .quad .Lfunc_begin0 - .long .Lfunc_end2-.Lfunc_begin0 - .section .debug_ranges,"",@progbits - .section .debug_macinfo,"",@progbits -.Lcu_macro_begin0: - .byte 0 - - .type _Z1av,@function -_Z1av = .L.cfi.jumptable - .type _Z1bv,@function -_Z1bv = .L.cfi.jumptable+8 - .ident "clang version 6.0.0 (trunk 316774)" - .section ".note.GNU-stack","",@progbits - .section .debug_line,"",@progbits -.Lline_table_start0: - +# CHECK: Expected Protected: 1 (100.00%) +# CHECK: Unexpected Protected: 0 (0.00%) +# CHECK: Expected Unprotected: 0 (0.00%) +# CHECK: Unexpected Unprotected (BAD): 0 (0.00%) Index: test/tools/llvm-cfi-verify/X86/unprotected-lineinfo.s =================================================================== --- test/tools/llvm-cfi-verify/X86/unprotected-lineinfo.s +++ test/tools/llvm-cfi-verify/X86/unprotected-lineinfo.s @@ -1,167 +1,11 @@ -# RUN: llvm-mc %s -filetype obj -triple x86_64-linux-elf -o %t.o +# RUN: llvm-mc %S/Inputs/unprotected-lineinfo.s -filetype obj \ +# RUN: -triple x86_64-linux-elf -o %t.o # RUN: llvm-cfi-verify %t.o | FileCheck %s # CHECK-LABEL: U # CHECK-NEXT: tiny.cc:11 -# CHECK: Unprotected: 1 (100.00%), Protected: 0 (0.00%) - -# Source (tiny.cc): -# void a() {} -# void b() {} -# int main(int argc, char** argv) { -# void(*ptr)(); -# if (argc == 1) -# ptr = &a; -# else -# ptr = &b; -# ptr(); -# } -# Compile with: -# clang++ -gmlt tiny.cc -S -o tiny.s - - .text - .file "tiny.cc" - .globl _Z1av # -- Begin function _Z1av - .p2align 4, 0x90 - .type _Z1av,@function -_Z1av: # @_Z1av -.Lfunc_begin0: - .file 1 "tiny.cc" - .loc 1 1 0 # tiny.cc:1:0 - .cfi_startproc -# BB#0: - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp -.Ltmp0: - .loc 1 1 11 prologue_end # tiny.cc:1:11 - popq %rbp - retq -.Ltmp1: -.Lfunc_end0: - .size _Z1av, .Lfunc_end0-_Z1av - .cfi_endproc - # -- End function - .globl _Z1bv # -- Begin function _Z1bv - .p2align 4, 0x90 - .type _Z1bv,@function -_Z1bv: # @_Z1bv -.Lfunc_begin1: - .loc 1 2 0 # tiny.cc:2:0 - .cfi_startproc -# BB#0: - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp -.Ltmp2: - .loc 1 2 11 prologue_end # tiny.cc:2:11 - popq %rbp - retq -.Ltmp3: -.Lfunc_end1: - .size _Z1bv, .Lfunc_end1-_Z1bv - .cfi_endproc - # -- End function - .globl main # -- Begin function main - .p2align 4, 0x90 - .type main,@function -main: # @main -.Lfunc_begin2: - .loc 1 4 0 # tiny.cc:4:0 - .cfi_startproc -# BB#0: - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp - subq $32, %rsp - movl $0, -4(%rbp) - movl %edi, -8(%rbp) - movq %rsi, -16(%rbp) -.Ltmp4: - .loc 1 6 12 prologue_end # tiny.cc:6:12 - cmpl $1, -8(%rbp) - .loc 1 6 7 is_stmt 0 # tiny.cc:6:7 - jne .LBB2_2 -# BB#1: - .loc 1 0 7 # tiny.cc:0:7 - movabsq $_Z1av, %rax - .loc 1 7 9 is_stmt 1 # tiny.cc:7:9 - movq %rax, -24(%rbp) - .loc 1 7 5 is_stmt 0 # tiny.cc:7:5 - jmp .LBB2_3 -.LBB2_2: - .loc 1 0 5 # tiny.cc:0:5 - movabsq $_Z1bv, %rax - .loc 1 9 9 is_stmt 1 # tiny.cc:9:9 - movq %rax, -24(%rbp) -.LBB2_3: - .loc 1 11 3 # tiny.cc:11:3 - callq *-24(%rbp) - .loc 1 12 1 # tiny.cc:12:1 - movl -4(%rbp), %eax - addq $32, %rsp - popq %rbp - retq -.Ltmp5: -.Lfunc_end2: - .size main, .Lfunc_end2-main - .cfi_endproc - # -- End function - .section .debug_str,"MS",@progbits,1 -.Linfo_string0: - .asciz "clang version 6.0.0 (trunk 316774)" # string offset=0 -.Linfo_string1: - .asciz "tiny.cc" # string offset=35 -.Linfo_string2: - .asciz "/tmp/a/b" # string offset=43 - .section .debug_abbrev,"",@progbits - .byte 1 # Abbreviation Code - .byte 17 # DW_TAG_compile_unit - .byte 0 # DW_CHILDREN_no - .byte 37 # DW_AT_producer - .byte 14 # DW_FORM_strp - .byte 19 # DW_AT_language - .byte 5 # DW_FORM_data2 - .byte 3 # DW_AT_name - .byte 14 # DW_FORM_strp - .byte 16 # DW_AT_stmt_list - .byte 23 # DW_FORM_sec_offset - .byte 27 # DW_AT_comp_dir - .byte 14 # DW_FORM_strp - .byte 17 # DW_AT_low_pc - .byte 1 # DW_FORM_addr - .byte 18 # DW_AT_high_pc - .byte 6 # DW_FORM_data4 - .byte 0 # EOM(1) - .byte 0 # EOM(2) - .byte 0 # EOM(3) - .section .debug_info,"",@progbits -.Lcu_begin0: - .long 38 # Length of Unit - .short 4 # DWARF version number - .long .debug_abbrev # Offset Into Abbrev. Section - .byte 8 # Address Size (in bytes) - .byte 1 # Abbrev [1] 0xb:0x1f DW_TAG_compile_unit - .long .Linfo_string0 # DW_AT_producer - .short 4 # DW_AT_language - .long .Linfo_string1 # DW_AT_name - .long .Lline_table_start0 # DW_AT_stmt_list - .long .Linfo_string2 # DW_AT_comp_dir - .quad .Lfunc_begin0 # DW_AT_low_pc - .long .Lfunc_end2-.Lfunc_begin0 # DW_AT_high_pc - .section .debug_ranges,"",@progbits - .section .debug_macinfo,"",@progbits -.Lcu_macro_begin0: - .byte 0 # End Of Macro List Mark - - .ident "clang version 6.0.0 (trunk 316774)" - .section ".note.GNU-stack","",@progbits - .section .debug_line,"",@progbits -.Lline_table_start0: +# CHECK: Expected Protected: 0 (0.00%) +# CHECK: Unexpected Protected: 0 (0.00%) +# CHECK: Expected Unprotected: 0 (0.00%) +# CHECK: Unexpected Unprotected (BAD): 1 (100.00%) Index: test/tools/llvm-cfi-verify/X86/unprotected-nolineinfo.s =================================================================== --- test/tools/llvm-cfi-verify/X86/unprotected-nolineinfo.s +++ test/tools/llvm-cfi-verify/X86/unprotected-nolineinfo.s @@ -1,92 +1,5 @@ -# RUN: llvm-mc %s -filetype obj -triple x86_64-linux-elf -o %t.o +# RUN: llvm-mc %S/Inputs/unprotected-nolineinfo.s -filetype obj \ +# RUN: -triple x86_64-linux-elf -o %t.o # RUN: not llvm-cfi-verify %t.o 2>&1 | FileCheck %s # CHECK: DWARF line information missing. Did you compile with '-g'? - -# Source (tiny.cc): -# void a() {} -# void b() {} -# int main(int argc, char** argv) { -# void(*ptr)(); -# if (argc == 1) -# ptr = &a; -# else -# ptr = &b; -# ptr(); -# } -# Compile with: -# clang++ tiny.cc -S -o tiny.s - - .text - .file "tiny.cc" - .globl _Z1av # -- Begin function _Z1av - .p2align 4, 0x90 - .type _Z1av,@function -_Z1av: # @_Z1av - .cfi_startproc -# BB#0: - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp - popq %rbp - retq -.Lfunc_end0: - .size _Z1av, .Lfunc_end0-_Z1av - .cfi_endproc - # -- End function - .globl _Z1bv # -- Begin function _Z1bv - .p2align 4, 0x90 - .type _Z1bv,@function -_Z1bv: # @_Z1bv - .cfi_startproc -# BB#0: - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp - popq %rbp - retq -.Lfunc_end1: - .size _Z1bv, .Lfunc_end1-_Z1bv - .cfi_endproc - # -- End function - .globl main # -- Begin function main - .p2align 4, 0x90 - .type main,@function -main: # @main - .cfi_startproc -# BB#0: - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp - subq $32, %rsp - movl $0, -4(%rbp) - movl %edi, -8(%rbp) - movq %rsi, -16(%rbp) - cmpl $1, -8(%rbp) - jne .LBB2_2 -# BB#1: - movabsq $_Z1av, %rax - movq %rax, -24(%rbp) - jmp .LBB2_3 -.LBB2_2: - movabsq $_Z1bv, %rax - movq %rax, -24(%rbp) -.LBB2_3: - callq *-24(%rbp) - movl -4(%rbp), %eax - addq $32, %rsp - popq %rbp - retq -.Lfunc_end2: - .size main, .Lfunc_end2-main - .cfi_endproc - # -- End function - - .ident "clang version 6.0.0 (trunk 316774)" - .section ".note.GNU-stack","",@progbits Index: tools/llvm-cfi-verify/CMakeLists.txt =================================================================== --- tools/llvm-cfi-verify/CMakeLists.txt +++ tools/llvm-cfi-verify/CMakeLists.txt @@ -4,11 +4,11 @@ AllTargetsDescs AllTargetsDisassemblers AllTargetsInfos - DebugInfoDWARF MC MCParser Object Support + Symbolize ) add_llvm_tool(llvm-cfi-verify Index: tools/llvm-cfi-verify/LLVMBuild.txt =================================================================== --- tools/llvm-cfi-verify/LLVMBuild.txt +++ tools/llvm-cfi-verify/LLVMBuild.txt @@ -19,4 +19,4 @@ type = Tool name = llvm-cfi-verify parent = Tools -required_libraries = all-targets DebugInfoDWARF MC MCDisassembler MCParser Support +required_libraries = all-targets MC MCDisassembler MCParser Support Symbolize Index: tools/llvm-cfi-verify/lib/CMakeLists.txt =================================================================== --- tools/llvm-cfi-verify/lib/CMakeLists.txt +++ tools/llvm-cfi-verify/lib/CMakeLists.txt @@ -11,5 +11,6 @@ MC MCParser Object - Support) + Support + Symbolize) target_link_libraries(LLVMCFIVerify ${libs}) Index: tools/llvm-cfi-verify/lib/FileAnalysis.h =================================================================== --- tools/llvm-cfi-verify/lib/FileAnalysis.h +++ tools/llvm-cfi-verify/lib/FileAnalysis.h @@ -12,7 +12,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/BinaryFormat/ELF.h" -#include "llvm/DebugInfo/DWARF/DWARFContext.h" +#include "llvm/DebugInfo/Symbolize/Symbolize.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" @@ -44,6 +44,8 @@ namespace llvm { namespace cfi_verify { +extern bool IgnoreDWARFFlag; + // Disassembler and analysis tool for machine code files. Keeps track of non- // sequential control flows, including indirect control flow instructions. class FileAnalysis { @@ -120,6 +122,7 @@ const MCRegisterInfo *getRegisterInfo() const; const MCInstrInfo *getMCInstrInfo() const; const MCInstrAnalysis *getMCInstrAnalysis() const; + symbolize::LLVMSymbolizer &getSymbolizer(); // Returns true if this class is using DWARF line tables for elimination. bool hasLineTableInfo() const; @@ -175,8 +178,8 @@ std::unique_ptr MIA; std::unique_ptr Printer; - // DWARF debug information. - std::unique_ptr DWARF; + // Symbolizer used for debug information parsing. + std::unique_ptr Symbolizer; // A mapping between the virtual memory address to the instruction metadata // struct. TODO(hctim): Reimplement this as a sorted vector to avoid per- Index: tools/llvm-cfi-verify/lib/FileAnalysis.cpp =================================================================== --- tools/llvm-cfi-verify/lib/FileAnalysis.cpp +++ tools/llvm-cfi-verify/lib/FileAnalysis.cpp @@ -39,22 +39,20 @@ #include using Instr = llvm::cfi_verify::FileAnalysis::Instr; +using LLVMSymbolizer = llvm::symbolize::LLVMSymbolizer; namespace llvm { namespace cfi_verify { -static cl::opt IgnoreDWARF( +bool IgnoreDWARFFlag; + +static cl::opt IgnoreDWARFArg( "ignore-dwarf", cl::desc( "Ignore all DWARF data. This relaxes the requirements for all " "statically linked libraries to have been compiled with '-g', but " "will result in false positives for 'CFI unprotected' instructions."), - cl::init(false)); - -cl::opt DWARFSearchRange( - "dwarf-search-range", - cl::desc("Address search range used to determine if instruction is valid."), - cl::init(0x10)); + cl::location(IgnoreDWARFFlag), cl::init(false)); Expected FileAnalysis::Create(StringRef Filename) { // Open the filename provided. @@ -256,12 +254,16 @@ return MIA.get(); } +LLVMSymbolizer &FileAnalysis::getSymbolizer() { return *Symbolizer; } + Error FileAnalysis::initialiseDisassemblyMembers() { std::string TripleName = ObjectTriple.getTriple(); ArchName = ""; MCPU = ""; std::string ErrorString; + Symbolizer.reset(new LLVMSymbolizer()); + ObjectTarget = TargetRegistry::lookupTarget(ArchName, ObjectTriple, ErrorString); if (!ObjectTarget) @@ -308,8 +310,8 @@ } Error FileAnalysis::parseCodeSections() { - if (!IgnoreDWARF) { - DWARF.reset(DWARFContext::create(*Object).release()); + if (!IgnoreDWARFFlag) { + std::unique_ptr DWARF = DWARFContext::create(*Object); if (!DWARF) return make_error("Could not create DWARF information.", inconvertibleErrorCode()); @@ -347,21 +349,9 @@ return Error::success(); } -DILineInfoTable FileAnalysis::getLineInfoForAddressRange(uint64_t Address) { - if (!hasLineTableInfo()) - return DILineInfoTable(); - - return DWARF->getLineInfoForAddressRange(Address, DWARFSearchRange); -} - -bool FileAnalysis::hasValidLineInfoForAddressRange(uint64_t Address) { - return !getLineInfoForAddressRange(Address).empty(); -} - -bool FileAnalysis::hasLineTableInfo() const { return DWARF != nullptr; } - void FileAnalysis::parseSectionContents(ArrayRef SectionBytes, uint64_t SectionAddress) { + assert(Symbolizer && "Symbolizer is uninitialised."); MCInst Instruction; Instr InstrMeta; uint64_t InstructionSize; @@ -381,8 +371,19 @@ InstrMeta.Valid = ValidInstruction; // Check if this instruction exists in the range of the DWARF metadata. - if (hasLineTableInfo() && !hasValidLineInfoForAddressRange(VMAddress)) - continue; + if (!IgnoreDWARFFlag) { + auto LineInfo = + Symbolizer->symbolizeCode(Object->getFileName(), VMAddress); + if (!LineInfo) { + handleAllErrors(LineInfo.takeError(), [](const ErrorInfoBase &E) { + errs() << "Symbolizer failed to get line: " << E.message() << "\n"; + }); + continue; + } + + if (LineInfo->FileName == "") + continue; + } addInstruction(InstrMeta); Index: tools/llvm-cfi-verify/lib/LLVMBuild.txt =================================================================== --- tools/llvm-cfi-verify/lib/LLVMBuild.txt +++ tools/llvm-cfi-verify/lib/LLVMBuild.txt @@ -19,4 +19,4 @@ type = Library name = CFIVerify parent = Libraries -required_libraries = DebugInfoDWARF MC MCDisassembler MCParser Support +required_libraries = DebugInfoDWARF MC MCDisassembler MCParser Support Symbolize Index: tools/llvm-cfi-verify/llvm-cfi-verify.cpp =================================================================== --- tools/llvm-cfi-verify/llvm-cfi-verify.cpp +++ tools/llvm-cfi-verify/llvm-cfi-verify.cpp @@ -23,6 +23,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Error.h" #include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/SpecialCaseList.h" #include @@ -32,48 +33,122 @@ cl::opt InputFilename(cl::Positional, cl::desc(""), cl::Required); +cl::opt BlacklistFilename(cl::Positional, + cl::desc("[blacklist file]"), + cl::init("-")); ExitOnError ExitOnErr; -void printIndirectCFInstructions(FileAnalysis &Analysis) { - uint64_t ProtectedCount = 0; - uint64_t UnprotectedCount = 0; +void printIndirectCFInstructions(FileAnalysis &Analysis, + const SpecialCaseList *SpecialCaseList) { + uint64_t ExpectedProtected = 0; + uint64_t UnexpectedProtected = 0; + uint64_t ExpectedUnprotected = 0; + uint64_t UnexpectedUnprotected = 0; + + symbolize::LLVMSymbolizer &Symbolizer = Analysis.getSymbolizer(); for (uint64_t Address : Analysis.getIndirectInstructions()) { const auto &InstrMeta = Analysis.getInstructionOrDie(Address); + bool CFIProtected = false; + if (Analysis.isIndirectInstructionCFIProtected(Address)) { outs() << "P "; - ProtectedCount++; + CFIProtected = true; } else { outs() << "U "; - UnprotectedCount++; } outs() << format_hex(Address, 2) << " | " << Analysis.getMCInstrInfo()->getName( InstrMeta.Instruction.getOpcode()) - << " "; - outs() << "\n"; - - if (Analysis.hasLineTableInfo()) { - for (const auto &LineKV : Analysis.getLineInfoForAddressRange(Address)) { - outs() << " " << format_hex(LineKV.first, 2) << " = " - << LineKV.second.FileName << ":" << LineKV.second.Line << ":" - << LineKV.second.Column << " (" << LineKV.second.FunctionName - << ")\n"; + << " \n"; + + if (IgnoreDWARFFlag) { + if (CFIProtected) + ExpectedProtected++; + else + UnexpectedUnprotected++; + continue; + } + + auto InliningInfo = Symbolizer.symbolizeInlinedCode(InputFilename, Address); + if (!InliningInfo || InliningInfo->getNumberOfFrames() == 0) { + errs() << "Failed to symbolise " << format_hex(Address, 2) + << " with line tables from " << InputFilename << "\n"; + exit(EXIT_FAILURE); + } + + const auto &LineInfo = + InliningInfo->getFrame(InliningInfo->getNumberOfFrames() - 1); + + // Print the inlining symbolisation of this instruction. + for (uint32_t i = 0; i < InliningInfo->getNumberOfFrames(); ++i) { + const auto &Line = InliningInfo->getFrame(i); + outs() << " " << format_hex(Address, 2) << " = " << Line.FileName << ":" + << Line.Line << ":" << Line.Column << " (" << Line.FunctionName + << ")\n"; + } + + if (!SpecialCaseList) { + if (CFIProtected) + ExpectedProtected++; + else + UnexpectedUnprotected++; + continue; + } + + bool MatchesBlacklistRule = false; + if (SpecialCaseList->inSection("cfi-icall", "src", LineInfo.FileName) || + SpecialCaseList->inSection("cfi-vcall", "src", LineInfo.FileName)) { + outs() << "BLACKLIST MATCH, 'src'\n"; + MatchesBlacklistRule = true; + } + + if (SpecialCaseList->inSection("cfi-icall", "fun", LineInfo.FunctionName) || + SpecialCaseList->inSection("cfi-vcall", "fun", LineInfo.FunctionName)) { + outs() << "BLACKLIST MATCH, 'fun'\n"; + MatchesBlacklistRule = true; + } + + if (MatchesBlacklistRule) { + if (CFIProtected) { + UnexpectedProtected++; + outs() << "====> Unexpected Protected\n"; + } else { + ExpectedUnprotected++; + outs() << "====> Expected Unprotected\n"; + } + } else { + if (CFIProtected) { + ExpectedProtected++; + outs() << "====> Expected Protected\n"; + } else { + UnexpectedUnprotected++; + outs() << "====> Unexpected Unprotected\n"; } } } - if (ProtectedCount || UnprotectedCount) - outs() << formatv( - "Unprotected: {0} ({1:P}), Protected: {2} ({3:P})\n", UnprotectedCount, - (((double)UnprotectedCount) / (UnprotectedCount + ProtectedCount)), - ProtectedCount, - (((double)ProtectedCount) / (UnprotectedCount + ProtectedCount))); - else + uint64_t IndirectCFInstructions = ExpectedProtected + UnexpectedProtected + + ExpectedUnprotected + UnexpectedUnprotected; + + if (IndirectCFInstructions == 0) outs() << "No indirect CF instructions found.\n"; + + outs() << formatv("Expected Protected: {0} ({1:P})\n" + "Unexpected Protected: {2} ({3:P})\n" + "Expected Unprotected: {4} ({5:P})\n" + "Unexpected Unprotected (BAD): {6} ({7:P})\n", + ExpectedProtected, + ((double)ExpectedProtected) / IndirectCFInstructions, + UnexpectedProtected, + ((double)UnexpectedProtected) / IndirectCFInstructions, + ExpectedUnprotected, + ((double)ExpectedUnprotected) / IndirectCFInstructions, + UnexpectedUnprotected, + ((double)UnexpectedUnprotected) / IndirectCFInstructions); } int main(int argc, char **argv) { @@ -89,8 +164,18 @@ InitializeAllAsmParsers(); InitializeAllDisassemblers(); + std::unique_ptr SpecialCaseList; + if (BlacklistFilename != "-") { + std::string Error; + SpecialCaseList = SpecialCaseList::create({BlacklistFilename}, Error); + if (!SpecialCaseList) { + errs() << "Failed to get blacklist: " << Error << "\n"; + exit(EXIT_FAILURE); + } + } + FileAnalysis Analysis = ExitOnErr(FileAnalysis::Create(InputFilename)); - printIndirectCFInstructions(Analysis); + printIndirectCFInstructions(Analysis, SpecialCaseList.get()); return EXIT_SUCCESS; } Index: unittests/tools/llvm-cfi-verify/CMakeLists.txt =================================================================== --- unittests/tools/llvm-cfi-verify/CMakeLists.txt +++ unittests/tools/llvm-cfi-verify/CMakeLists.txt @@ -8,6 +8,7 @@ MCParser Object Support + Symbolize ) add_llvm_unittest(CFIVerifyTests Index: unittests/tools/llvm-cfi-verify/FileAnalysis.cpp =================================================================== --- unittests/tools/llvm-cfi-verify/FileAnalysis.cpp +++ unittests/tools/llvm-cfi-verify/FileAnalysis.cpp @@ -64,6 +64,7 @@ class BasicFileAnalysisTest : public ::testing::Test { protected: virtual void SetUp() { + IgnoreDWARFFlag = true; SuccessfullyInitialised = true; if (auto Err = Analysis.initialiseDisassemblyMembers()) { handleAllErrors(std::move(Err), [&](const UnsupportedDisassembly &E) { Index: unittests/tools/llvm-cfi-verify/GraphBuilder.cpp =================================================================== --- unittests/tools/llvm-cfi-verify/GraphBuilder.cpp +++ unittests/tools/llvm-cfi-verify/GraphBuilder.cpp @@ -126,6 +126,7 @@ class BasicGraphBuilderTest : public ::testing::Test { protected: virtual void SetUp() { + IgnoreDWARFFlag = true; SuccessfullyInitialised = true; if (auto Err = Analysis.initialiseDisassemblyMembers()) { handleAllErrors(std::move(Err), [&](const UnsupportedDisassembly &E) {