326 lines · plain
1// This test checks that the SEH directives emit the correct unwind data.2 3// RUN: llvm-mc -triple thumbv7-pc-win32 -filetype=obj %s | llvm-readobj -S -r -u - | FileCheck %s4 5// Check that the output assembler directives also can be parsed, and6// that they produce equivalent output:7 8// RUN: llvm-mc -triple thumbv7-pc-win32 -filetype=asm %s | llvm-mc -triple thumbv7-pc-win32 -filetype=obj - | llvm-readobj -S -r -u - | FileCheck %s9 10// CHECK: Sections [11// CHECK: Section {12// CHECK: Name: .text13// CHECK: RelocationCount: 114// CHECK: Characteristics [15// CHECK-NEXT: ALIGN_4BYTES16// CHECK-NEXT: CNT_CODE17// CHECK-NEXT: MEM_16BIT18// CHECK-NEXT: MEM_EXECUTE19// CHECK-NEXT: MEM_PURGEABLE20// CHECK-NEXT: MEM_READ21// CHECK-NEXT: ]22// CHECK-NEXT: }23// CHECK: Section {24// CHECK: Name: .xdata25// CHECK: RawDataSize: 10026// CHECK: RelocationCount: 127// CHECK: Characteristics [28// CHECK-NEXT: ALIGN_4BYTES29// CHECK-NEXT: CNT_INITIALIZED_DATA30// CHECK-NEXT: MEM_READ31// CHECK-NEXT: ]32// CHECK-NEXT: }33// CHECK: Section {34// CHECK: Name: .pdata35// CHECK: RelocationCount: 1036// CHECK: Characteristics [37// CHECK-NEXT: ALIGN_4BYTES38// CHECK-NEXT: CNT_INITIALIZED_DATA39// CHECK-NEXT: MEM_READ40// CHECK-NEXT: ]41// CHECK-NEXT: }42// CHECK-NEXT: ]43 44// CHECK-NEXT: Relocations [45// CHECK-NEXT: Section (1) .text {46// CHECK-NEXT: 0x5C IMAGE_REL_ARM_BRANCH24T tailcall47// CHECK-NEXT: }48// CHECK-NEXT: Section (4) .xdata {49// CHECK-NEXT: 0x34 IMAGE_REL_ARM_ADDR32NB __C_specific_handler50// CHECK-NEXT: }51// CHECK-NEXT: Section (5) .pdata {52// CHECK-NEXT: 0x0 IMAGE_REL_ARM_ADDR32NB .text53// CHECK-NEXT: 0x4 IMAGE_REL_ARM_ADDR32NB .xdata54// CHECK-NEXT: 0x8 IMAGE_REL_ARM_ADDR32NB .text55// CHECK-NEXT: 0xC IMAGE_REL_ARM_ADDR32NB .xdata56// CHECK-NEXT: 0x10 IMAGE_REL_ARM_ADDR32NB .text57// CHECK-NEXT: 0x14 IMAGE_REL_ARM_ADDR32NB .xdata58// CHECK-NEXT: 0x18 IMAGE_REL_ARM_ADDR32NB .text59// CHECK-NEXT: 0x1C IMAGE_REL_ARM_ADDR32NB .xdata60// CHECK-NEXT: 0x20 IMAGE_REL_ARM_ADDR32NB .text61// CHECK-NEXT: 0x24 IMAGE_REL_ARM_ADDR32NB .xdata62// CHECK-NEXT: }63// CHECK-NEXT: ]64 65// CHECK-NEXT: UnwindInformation [66// CHECK-NEXT: RuntimeFunction {67// CHECK-NEXT: Function: func68// CHECK-NEXT: ExceptionRecord: .xdata69// CHECK-NEXT: ExceptionData {70// CHECK-NEXT: FunctionLength: 8671// CHECK: EpiloguePacked: Yes72// CHECK: Fragment: No73// CHECK: EpilogueOffset: 3174// CHECK: Prologue [75// CHECK-NEXT: 0xed 0xf8 ; push {r3-r7, lr}76// CHECK-NEXT: 0xf6 0x27 ; vpush {d18-d23}77// CHECK-NEXT: 0xf5 0x7e ; vpush {d7-d14}78// CHECK-NEXT: 0xfb ; nop79// CHECK-NEXT: 0xce ; mov r14, sp80// CHECK-NEXT: 0xe3 ; vpush {d8-d11}81// CHECK-NEXT: 0xe6 ; vpush {d8-d14}82// CHECK-NEXT: 0xed 0xf8 ; push {r3-r7, lr}83// CHECK-NEXT: 0xbd 0x50 ; push.w {r4, r6, r8, r10-r12, lr}84// CHECK-NEXT: 0xd7 ; push {r4-r7, lr}85// CHECK-NEXT: 0xdd ; push.w {r4-r9, lr}86// CHECK-NEXT: 0xfa 0x01 0x00 0x00 ; sub.w sp, sp, #(65536 * 4)87// CHECK-NEXT: 0xfc ; nop.w88// CHECK-NEXT: 0xfc ; nop.w89// CHECK-NEXT: 0xf9 0x04 0x00 ; sub.w sp, sp, #(1024 * 4)90// CHECK-NEXT: 0xe8 0x80 ; sub.w sp, #(128 * 4)91// CHECK-NEXT: 0xe8 0x80 ; sub.w sp, #(128 * 4)92// CHECK-NEXT: 0x06 ; sub sp, #(6 * 4)93// CHECK-NEXT: ]94// CHECK-NEXT: Epilogue [95// CHECK-NEXT: 0xfc ; nop.w96// CHECK-NEXT: 0xf7 0x00 0x80 ; add sp, sp, #(128 * 4)97// CHECK-NEXT: 0xfc ; nop.w98// CHECK-NEXT: 0xfc ; nop.w99// CHECK-NEXT: 0xf8 0x01 0x00 0x00 ; add sp, sp, #(65536 * 4)100// CHECK-NEXT: 0x06 ; add sp, #(6 * 4)101// CHECK-NEXT: 0xef 0x04 ; ldr.w lr, [sp], #16102// CHECK-NEXT: 0xfd ; bx <reg>103// CHECK-NEXT: ]104// CHECK-NEXT: ExceptionHandler [105// CHECK-NEXT: Routine: __C_specific_handler106// CHECK-NEXT: Parameter: 0x0107// CHECK-NEXT: ]108// CHECK-NEXT: }109// CHECK-NEXT: }110// CHECK-NEXT: RuntimeFunction {111// CHECK-NEXT: Function: func2112// CHECK: Prologue [113// CHECK-NEXT: 0xd3 ; push {r4-r7}114// CHECK-NEXT: ]115// CHECK-NEXT: Epilogue [116// CHECK-NEXT: 0xd2 ; pop {r4-r6}117// CHECK-NEXT: 0xfe ; b.w <target>118// CHECK-NEXT: ]119// CHECK-NEXT: }120// CHECK-NEXT: }121// CHECK-NEXT: RuntimeFunction {122// CHECK-NEXT: Function: func3123// CHECK: FunctionLength: 8124// CHECK: EpilogueOffset: 2125// CHECK: Prologue [126// CHECK-NEXT: 0xd5 ; push {r4-r5, lr}127// CHECK-NEXT: ]128// CHECK-NEXT: Epilogue [129// CHECK-NEXT: 0xd6 ; pop {r4-r6, pc}130// CHECK-NEXT: ]131// CHECK-NEXT: }132// CHECK-NEXT: }133// CHECK-NEXT: RuntimeFunction {134// CHECK-NEXT: Function: fragment135// CHECK: FunctionLength: 6136// CHECK: Fragment: Yes137// CHECK: Prologue [138// CHECK-NEXT: 0xcb ; mov r11, sp139// CHECK-NEXT: 0x10 ; sub sp, #(16 * 4)140// CHECK-NEXT: 0xd5 ; push {r4-r5, lr}141// CHECK-NEXT: ]142// CHECK-NEXT: Epilogue [143// CHECK-NEXT: 0x10 ; add sp, #(16 * 4)144// CHECK-NEXT: 0xd5 ; pop {r4-r5, pc}145// CHECK-NEXT: ]146// CHECK-NEXT: }147// CHECK-NEXT: }148// CHECK-NEXT: RuntimeFunction {149// CHECK-NEXT: Function: condepilog150// CHECK: FunctionLength: 8151// CHECK: Prologue [152// CHECK-NEXT: 0xd5 ; push {r4-r5, lr}153// CHECK-NEXT: ]154// CHECK-NEXT: EpilogueScopes [155// CHECK-NEXT: EpilogueScope {156// CHECK-NEXT: StartOffset: 3157// CHECK-NEXT: Condition: 10158// CHECK-NEXT: EpilogueStartIndex: 0159// CHECK-NEXT: Opcodes [160// CHECK-NEXT: 0xd5 ; pop {r4-r5, pc}161// CHECK-NEXT: ]162// CHECK-NEXT: }163// CHECK-NEXT: ]164// CHECK-NEXT: }165// CHECK-NEXT: }166// CHECK-NEXT: ]167 168 .text169 .syntax unified170 .globl func171 .def func172 .scl 2173 .type 32174 .endef175 .seh_proc func176func:177 sub sp, sp, #24178 .seh_stackalloc 24179 sub sp, sp, #512180 .seh_stackalloc_w 512181 sub sp, sp, #512182 .seh_stackalloc_w 512183 sub sp, sp, #4096184 .seh_stackalloc_w 4096185 movw r7, #0186 .seh_nop_w187 movt r7, #0x4 // 0x40000188 .seh_nop_w189 sub sp, sp, r7190 .seh_stackalloc_w 0x40000191 push {r4-r8,lr}192 .seh_save_regs_w {r4-r9,lr}193 push {r4-r7,lr}194 .seh_save_regs {r4-r7,lr}195 push {r4,r6,r8,r10,r11,r12,lr}196 .seh_save_regs_w {r4,r6,r8,r10,r11,r12,lr}197 push {r3-r7,lr}198 .seh_save_regs {r3-r7,lr}199 vpush {d8-d14}200 .seh_save_fregs {d8-d14}201 vpush {q4-q5}202 .seh_save_fregs {q4-q5}203 mov lr, sp204 .seh_save_sp lr205 nop206 .seh_nop207 vpush {d7-d14}208 .seh_save_fregs {d7-d14}209 vpush {d18-d23}210 .seh_save_fregs {d18-d23}211 push {r3-r7,lr}212 .seh_custom 0xed, 0xf8213 .seh_endprologue214 nop215 .seh_startepilogue216 mov r7, #512217 .seh_nop_w218 add sp, sp, r7219 .seh_stackalloc 512220 movw r7, #0221 .seh_nop_w222 movt r7, #0x4 // 0x40000223 .seh_nop_w224 add sp, sp, r7225 .seh_stackalloc 0x40000226 add sp, sp, #24227 .seh_stackalloc 24228 ldr lr, [sp], #16229 .seh_save_lr 16230 bx lr231 .seh_nop232 .seh_endepilogue233 .seh_handler __C_specific_handler, %except234 .seh_handlerdata235 .long 0236 .text237 .seh_endproc238 239 .seh_proc func2240func2:241 push {r4-r7}242 .seh_save_regs {r4-r7}243 .seh_endprologue244 nop245 .seh_startepilogue246 pop {r4-r6}247 .seh_save_regs {r4-r6}248 b.w tailcall249 .seh_nop_w250 .seh_endepilogue251 .seh_endproc252 253 .seh_proc func3254func3:255 push {r4-r5,lr}256 .seh_save_regs {r4-r5,lr}257 .seh_endprologue258 nop259 // The p2align causes the length of the function to be unknown.260 .p2align 1261 nop262 .seh_startepilogue263 pop {r4-r6,pc}264 .seh_save_regs {r4-r6,pc}265 .seh_endepilogue266 .seh_endproc267 268 .seh_proc fragment269fragment:270 // Prologue opcodes without matching instructions271 .seh_save_regs {r4-r5,lr}272 .seh_stackalloc 64273 .seh_save_sp r11274 .seh_endprologue_fragment275 nop276 .seh_startepilogue277 add sp, sp, #64278 .seh_stackalloc 64279 pop {r4-r5,pc}280 .seh_save_regs {r4-r5,pc}281 .seh_endepilogue282 .seh_endproc283 284 .seh_proc condepilog285condepilog:286 push {r4-r5,lr}287 .seh_save_regs {r4-r5,lr}288 .seh_endprologue289 nop290 it ge291 .seh_startepilogue_cond ge292 popge {r4-r5,pc}293 .seh_save_regs {r4-r5,pc}294 .seh_endepilogue295 .seh_endproc296 297 // Function with no .seh directives; no pdata/xdata entries are298 // generated.299 .globl smallFunc300 .def smallFunc301 .scl 2302 .type 32303 .endef304 .seh_proc smallFunc305smallFunc:306 bx lr307 .seh_endproc308 309 // Function with no .seh directives, but with .seh_handlerdata.310 // No xdata/pdata entries are generated, but the custom handler data311 // (the .long after .seh_handlerdata) is left orphaned in the xdata312 // section.313 .globl handlerFunc314 .def handlerFunc315 .scl 2316 .type 32317 .endef318 .seh_proc handlerFunc319handlerFunc:320 bx lr321 .seh_handler __C_specific_handler, %except322 .seh_handlerdata323 .long 0324 .text325 .seh_endproc326