1# RUN: llvm-mc -triple=x86_64-windows -filetype=obj < %s | llvm-readobj -codeview | FileCheck %s 2 3# C source to generate the assembly: 4# volatile int unlikely_cond = 0; 5# extern void __declspec(noreturn) abort(); 6# __forceinline void f() { 7# if (unlikely_cond) 8# abort(); 9# } 10# void g() { 11# unlikely_cond = 0; 12# f(); 13# unlikely_cond = 0; 14# } 15 16# This test is interesting because the inlined instructions are discontiguous. 17# LLVM's block layout algorithms will put the 'abort' call last, as it is 18# considered highly unlikely to execute. This is similar to what it does for 19# calls to __asan_report*, for which it is very important to have an accurate 20# stack trace. 21 22# CHECK: GlobalProcIdSym { 23# CHECK: FunctionType: g (0x1003) 24# CHECK: CodeOffset: g+0x0 25# CHECK: DisplayName: g 26# CHECK: LinkageName: g 27# CHECK: } 28# CHECK: InlineSiteSym { 29# CHECK: Inlinee: f (0x1002) 30# CHECK: BinaryAnnotations [ 31# CHECK-NEXT: ChangeCodeOffsetAndLineOffset: {CodeOffset: 0xE, LineOffset: 1} 32# CHECK-NEXT: ChangeCodeLength: 0x9 33# CHECK-NEXT: ChangeCodeOffsetAndLineOffset: {CodeOffset: 0xF, LineOffset: 1} 34# CHECK-NEXT: ChangeCodeLength: 0x7 35# CHECK-NEXT: ] 36 37 .text 38 .globl g 39g: # @g 40.Lfunc_begin0: 41 .cv_func_id 0 42 .cv_file 1 "C:\\src\\llvm\\build\\t.cpp" 43 .cv_loc 0 1 7 0 is_stmt 0 # t.cpp:7:0 44.seh_proc g 45 subq $40, %rsp 46 .seh_stackalloc 40 47 .seh_endprologue 48 .cv_loc 0 1 8 17 # t.cpp:8:17 49 movl $0, unlikely_cond(%rip) 50 .cv_inline_site_id 1 within 0 inlined_at 1 9 3 51 .cv_loc 1 1 4 7 # t.cpp:4:7 52 cmpl $0, unlikely_cond(%rip) 53 jne .LBB0_1 54 .cv_loc 0 1 10 17 # t.cpp:10:17 55 movl $0, unlikely_cond(%rip) 56 .cv_loc 0 1 11 1 # t.cpp:11:1 57 addq $40, %rsp 58 retq 59 60.LBB0_1: # %if.then.i 61 .cv_loc 1 1 5 5 # t.cpp:5:5 62 callq abort 63 ud2 64.Lfunc_end0: 65 .seh_handlerdata 66 .text 67 .seh_endproc 68 69 .bss 70 .globl unlikely_cond # @unlikely_cond 71 .p2align 2 72unlikely_cond: 73 .long 0 # 0x0 74 75 .section .debug$S,"dr" 76 .p2align 2 77 .long 4 # Debug section magic 78 .long 246 # Inlinee lines subsection 79 .long .Ltmp9-.Ltmp8 # Subsection size 80.Ltmp8: 81 .long 0 # Inlinee lines signature 82 83 # Inlined function f starts at t.cpp:3 84 .long 4098 # Type index of inlined function 85 .long 0 # Offset into filechecksum table 86 .long 3 # Starting line number 87.Ltmp9: 88 .p2align 2 89 .long 241 # Symbol subsection for g 90 .long .Ltmp11-.Ltmp10 # Subsection size 91.Ltmp10: 92 .short .Ltmp13-.Ltmp12 # Record length 93.Ltmp12: 94 .short 4423 # Record kind: S_GPROC32_ID 95 .long 0 # PtrParent 96 .long 0 # PtrEnd 97 .long 0 # PtrNext 98 .long .Lfunc_end0-g # Code size 99 .long 0 # Offset after prologue 100 .long 0 # Offset before epilogue 101 .long 4099 # Function type index 102 .secrel32 g # Function section relative address 103 .secidx g # Function section index 104 .byte 0 # Flags 105 .asciz "g" # Function name 106.Ltmp13: 107 .short .Ltmp15-.Ltmp14 # Record length 108.Ltmp14: 109 .short 4429 # Record kind: S_INLINESITE 110 .long 0 # PtrParent 111 .long 0 # PtrEnd 112 .long 4098 # Inlinee type index 113 .cv_inline_linetable 1 1 3 .Lfunc_begin0 .Lfunc_end0 114.Ltmp15: 115 .short 2 # Record length 116 .short 4430 # Record kind: S_INLINESITE_END 117 .short 2 # Record length 118 .short 4431 # Record kind: S_PROC_ID_END 119.Ltmp11: 120 .p2align 2 121 .cv_linetable 0, g, .Lfunc_end0 122 .long 241 # Symbol subsection for globals 123 .long .Ltmp17-.Ltmp16 # Subsection size 124.Ltmp16: 125 .short .Ltmp19-.Ltmp18 # Record length 126.Ltmp18: 127 .short 4365 # Record kind: S_GDATA32 128 .long 4100 # Type 129 .secrel32 unlikely_cond # DataOffset 130 .secidx unlikely_cond # Segment 131 .asciz "unlikely_cond" # Name 132.Ltmp19: 133.Ltmp17: 134 .p2align 2 135 .cv_filechecksums # File index to string table offset subsection 136 .cv_stringtable # String table 137 .section .debug$T,"dr" 138 .p2align 2 139 .long 4 # Debug section magic 140 # ArgList (0x1000) { 141 # TypeLeafKind: LF_ARGLIST (0x1201) 142 # NumArgs: 0 143 # Arguments [ 144 # ] 145 # } 146 .byte 0x06, 0x00, 0x01, 0x12 147 .byte 0x00, 0x00, 0x00, 0x00 148 # Procedure (0x1001) { 149 # TypeLeafKind: LF_PROCEDURE (0x1008) 150 # ReturnType: void (0x3) 151 # CallingConvention: NearC (0x0) 152 # FunctionOptions [ (0x0) 153 # ] 154 # NumParameters: 0 155 # ArgListType: () (0x1000) 156 # } 157 .byte 0x0e, 0x00, 0x08, 0x10 158 .byte 0x03, 0x00, 0x00, 0x00 159 .byte 0x00, 0x00, 0x00, 0x00 160 .byte 0x00, 0x10, 0x00, 0x00 161 # FuncId (0x1002) { 162 # TypeLeafKind: LF_FUNC_ID (0x1601) 163 # ParentScope: 0x0 164 # FunctionType: void () (0x1001) 165 # Name: f 166 # } 167 .byte 0x0e, 0x00, 0x01, 0x16 168 .byte 0x00, 0x00, 0x00, 0x00 169 .byte 0x01, 0x10, 0x00, 0x00 170 .byte 0x66, 0x00, 0xf2, 0xf1 171 # FuncId (0x1003) { 172 # TypeLeafKind: LF_FUNC_ID (0x1601) 173 # ParentScope: 0x0 174 # FunctionType: void () (0x1001) 175 # Name: g 176 # } 177 .byte 0x0e, 0x00, 0x01, 0x16 178 .byte 0x00, 0x00, 0x00, 0x00 179 .byte 0x01, 0x10, 0x00, 0x00 180 .byte 0x67, 0x00, 0xf2, 0xf1 181 # Modifier (0x1004) { 182 # TypeLeafKind: LF_MODIFIER (0x1001) 183 # ModifiedType: int (0x74) 184 # Modifiers [ (0x2) 185 # Volatile (0x2) 186 # ] 187 # } 188 .byte 0x0a, 0x00, 0x01, 0x10 189 .byte 0x74, 0x00, 0x00, 0x00 190 .byte 0x02, 0x00, 0xf2, 0xf1 191 192