309 lines · plain
1// This test checks that we emit unwind info correctly for epilogs that:2// 1. mirror the prolog; or3// 2. are subsequence at the end of the prolog; or4// 3. neither of above two.5// in the same segment. 6// RUN: llvm-mc -triple aarch64-pc-win32 -filetype=obj %s -o %t.o7// RUN: llvm-readobj -S -r -u %t.o | FileCheck %s8 9// CHECK: Section {10// CHECK: Number: 411// CHECK-NEXT: Name: .xdata (2E 78 64 61 74 61 00 00)12// CHECK-NEXT: VirtualSize: 0x013// CHECK-NEXT: VirtualAddress: 0x014// CHECK-NEXT: RawDataSize: 8015// CHECK-NEXT: PointerToRawData: 0x1251AC16// CHECK-NEXT: PointerToRelocations: 0x017// CHECK-NEXT: PointerToLineNumbers: 0x018// CHECK-NEXT: RelocationCount: 019// CHECK-NEXT: LineNumberCount: 020// CHECK-NEXT: Characteristics [ (0x40300040)21// CHECK-NEXT: IMAGE_SCN_ALIGN_4BYTES (0x300000)22// CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)23// CHECK-NEXT: IMAGE_SCN_MEM_READ (0x40000000)24// CHECK-NEXT: ]25// CHECK-NEXT: }26// CHECK-NEXT: Section {27// CHECK-NEXT: Number: 528// CHECK-NEXT: Name: .pdata (2E 70 64 61 74 61 00 00)29// CHECK-NEXT: VirtualSize: 0x030// CHECK-NEXT: VirtualAddress: 0x031// CHECK-NEXT: RawDataSize: 1632// CHECK-NEXT: PointerToRawData: 0x1251FC33// CHECK-NEXT: PointerToRelocations: 0x12520C34// CHECK-NEXT: PointerToLineNumbers: 0x035// CHECK-NEXT: RelocationCount: 436// CHECK-NEXT: LineNumberCount: 037// CHECK-NEXT: Characteristics [ (0x40300040)38// CHECK-NEXT: IMAGE_SCN_ALIGN_4BYTES (0x300000)39// CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)40// CHECK-NEXT: IMAGE_SCN_MEM_READ (0x40000000)41// CHECK-NEXT: ]42// CHECK-NEXT: }43// CHECK-NEXT:]44// CHECK-LABEL:Relocations [45// CHECK-NEXT: Section (1) .text {46// CHECK-NEXT: 0x94 IMAGE_REL_ARM64_BRANCH26 foo (12)47// CHECK-NEXT: 0x125068 IMAGE_REL_ARM64_BRANCH26 foo (12)48// CHECK-NEXT: }49// CHECK-NEXT: Section (5) .pdata {50// CHECK-NEXT: 0x0 IMAGE_REL_ARM64_ADDR32NB .text (0)51// CHECK-NEXT: 0x4 IMAGE_REL_ARM64_ADDR32NB .xdata (7)52// CHECK-NEXT: 0x8 IMAGE_REL_ARM64_ADDR32NB .text (0)53// CHECK-NEXT: 0xC IMAGE_REL_ARM64_ADDR32NB .xdata (7)54// CHECK-NEXT: }55// CHECK-NEXT:]56// CHECK-LABEL:UnwindInformation [57// CHECK-NEXT: RuntimeFunction {58// CHECK-NEXT: Function: multi_epilog (0x0)59// CHECK-NEXT: ExceptionRecord: .xdata (0x0)60// CHECK-NEXT: ExceptionData {61// CHECK-NEXT: FunctionLength: 104857262// CHECK-NEXT: Version: 063// CHECK-NEXT: ExceptionData: No64// CHECK-NEXT: EpiloguePacked: No65// CHECK-NEXT: EpilogueScopes: 366// CHECK-NEXT: ByteCodeLength: 2467// CHECK-NEXT: Prologue [68// CHECK-NEXT: 0xe1 ; mov fp, sp69// CHECK-NEXT: 0xca16 ; stp x27, x28, [sp, #176]70// CHECK-NEXT: 0xc998 ; stp x25, x26, [sp, #192]71// CHECK-NEXT: 0xc91a ; stp x23, x24, [sp, #208]72// CHECK-NEXT: 0xc89c ; stp x21, x22, [sp, #224]73// CHECK-NEXT: 0xc81e ; stp x19, x20, [sp, #240]74// CHECK-NEXT: 0x9f ; stp x29, x30, [sp, #-256]!75// CHECK-NEXT: 0xe4 ; end76// CHECK-NEXT: ]77// CHECK-NEXT: EpilogueScopes [78// CHECK-NEXT: EpilogueScope {79// CHECK-NEXT: StartOffset: 3880// CHECK-NEXT: EpilogueStartIndex: 081// CHECK-NEXT: Opcodes [82// CHECK-NEXT: 0xe1 ; mov sp, fp83// CHECK-NEXT: 0xca16 ; ldp x27, x28, [sp, #176]84// CHECK-NEXT: 0xc998 ; ldp x25, x26, [sp, #192]85// CHECK-NEXT: 0xc91a ; ldp x23, x24, [sp, #208]86// CHECK-NEXT: 0xc89c ; ldp x21, x22, [sp, #224]87// CHECK-NEXT: 0xc81e ; ldp x19, x20, [sp, #240]88// CHECK-NEXT: 0x9f ; ldp x29, x30, [sp], #25689// CHECK-NEXT: 0xe4 ; end90// CHECK-NEXT: ]91// CHECK-NEXT: }92// CHECK-NEXT: EpilogueScope {93// CHECK-NEXT: StartOffset: 4694// CHECK-NEXT: EpilogueStartIndex: 395// CHECK-NEXT: Opcodes [96// CHECK-NEXT: 0xc998 ; ldp x25, x26, [sp, #192]97// CHECK-NEXT: 0xc91a ; ldp x23, x24, [sp, #208]98// CHECK-NEXT: 0xc89c ; ldp x21, x22, [sp, #224]99// CHECK-NEXT: 0xc81e ; ldp x19, x20, [sp, #240]100// CHECK-NEXT: 0x9f ; ldp x29, x30, [sp], #256101// CHECK-NEXT: 0xe4 ; end102// CHECK-NEXT: ]103// CHECK-NEXT: }104// CHECK-NEXT: EpilogueScope {105// CHECK-NEXT: StartOffset: 52106// CHECK-NEXT: EpilogueStartIndex: 13107// CHECK-NEXT: Opcodes [108// CHECK-NEXT: 0xe1 ; mov sp, fp109// CHECK-NEXT: 0xc91a ; ldp x23, x24, [sp, #208]110// CHECK-NEXT: 0xc89c ; ldp x21, x22, [sp, #224]111// CHECK-NEXT: 0xc81e ; ldp x19, x20, [sp, #240]112// CHECK-NEXT: 0x9f ; ldp x29, x30, [sp], #256113// CHECK-NEXT: 0xe4 ; end114// CHECK-NEXT: ]115// CHECK-NEXT: }116// CHECK-NEXT: ]117// CHECK-NEXT: }118// CHECK-NEXT: }119// CHECK-NEXT: RuntimeFunction {120// CHECK-NEXT: Function: multi_epilog +0xFFFFC (0xFFFFC)121// CHECK-NEXT: ExceptionRecord: .xdata +0x28 (0x28)122// CHECK-NEXT: ExceptionData {123// CHECK-NEXT: FunctionLength: 151744124// CHECK-NEXT: Version: 0125// CHECK-NEXT: ExceptionData: No126// CHECK-NEXT: EpiloguePacked: No127// CHECK-NEXT: EpilogueScopes: 3128// CHECK-NEXT: ByteCodeLength: 24129// CHECK-NEXT: Prologue [130// CHECK-NEXT: 0xe5 ; end_c131// CHECK-NEXT: 0xe1 ; mov fp, sp132// CHECK-NEXT: 0xca16 ; stp x27, x28, [sp, #176]133// CHECK-NEXT: 0xc998 ; stp x25, x26, [sp, #192]134// CHECK-NEXT: 0xc91a ; stp x23, x24, [sp, #208]135// CHECK-NEXT: 0xc89c ; stp x21, x22, [sp, #224]136// CHECK-NEXT: 0xc81e ; stp x19, x20, [sp, #240]137// CHECK-NEXT: 0x9f ; stp x29, x30, [sp, #-256]!138// CHECK-NEXT: 0xe4 ; end139// CHECK-NEXT: ]140// CHECK-NEXT: EpilogueScopes [141// CHECK-NEXT: EpilogueScope {142// CHECK-NEXT: StartOffset: 37916143// CHECK-NEXT: EpilogueStartIndex: 1144// CHECK-NEXT: Opcodes [145// CHECK-NEXT: 0xe1 ; mov sp, fp146// CHECK-NEXT: 0xca16 ; ldp x27, x28, [sp, #176]147// CHECK-NEXT: 0xc998 ; ldp x25, x26, [sp, #192]148// CHECK-NEXT: 0xc91a ; ldp x23, x24, [sp, #208]149// CHECK-NEXT: 0xc89c ; ldp x21, x22, [sp, #224]150// CHECK-NEXT: 0xc81e ; ldp x19, x20, [sp, #240]151// CHECK-NEXT: 0x9f ; ldp x29, x30, [sp], #256152// CHECK-NEXT: 0xe4 ; end153// CHECK-NEXT: ]154// CHECK-NEXT: }155// CHECK-NEXT: EpilogueScope {156// CHECK-NEXT: StartOffset: 37924157// CHECK-NEXT: EpilogueStartIndex: 4158// CHECK-NEXT: Opcodes [159// CHECK-NEXT: 0xc998 ; ldp x25, x26, [sp, #192]160// CHECK-NEXT: 0xc91a ; ldp x23, x24, [sp, #208]161// CHECK-NEXT: 0xc89c ; ldp x21, x22, [sp, #224]162// CHECK-NEXT: 0xc81e ; ldp x19, x20, [sp, #240]163// CHECK-NEXT: 0x9f ; ldp x29, x30, [sp], #256164// CHECK-NEXT: 0xe4 ; end165// CHECK-NEXT: ]166// CHECK-NEXT: }167// CHECK-NEXT: EpilogueScope {168// CHECK-NEXT: StartOffset: 37930169// CHECK-NEXT: EpilogueStartIndex: 14170// CHECK-NEXT: Opcodes [171// CHECK-NEXT: 0xe1 ; mov sp, fp172// CHECK-NEXT: 0xc91a ; ldp x23, x24, [sp, #208]173// CHECK-NEXT: 0xc89c ; ldp x21, x22, [sp, #224]174// CHECK-NEXT: 0xc81e ; ldp x19, x20, [sp, #240]175// CHECK-NEXT: 0x9f ; ldp x29, x30, [sp], #256176// CHECK-NEXT: 0xe4 ; end177// CHECK-NEXT: ]178// CHECK-NEXT: }179// CHECK-NEXT: ]180// CHECK-NEXT: }181// CHECK-NEXT: }182// CHECK-NEXT:]183 184 .text185 .global multi_epilog186 .p2align 2187 .seh_proc multi_epilog188multi_epilog:189 stp x29, lr, [sp, #-256]!190 .seh_save_fplr_x 256191 stp x19, x20, [sp, #240]192 .seh_save_regp x19, 240193 stp x21, x22, [sp, #224]194 .seh_save_regp x21, 224195 stp x23, x24, [sp, #208]196 .seh_save_regp x23, 208197 stp x25, x26, [sp, #192]198 .seh_save_regp x25, 192199 stp x27, x28, [sp, #176]200 .seh_save_regp x27, 176201 mov x29, fp202 .seh_set_fp203 .seh_endprologue204 .rept 30205 nop206 .endr207 bl foo208// Epilogs 1, 2 and 3 are in the same segment as prolog.209// epilog1 - mirroring prolog210 .seh_startepilogue211 mov sp, x29212 .seh_set_fp213 stp x27, x28, [sp, #176]214 .seh_save_regp x27, 176215 stp x25, x26, [sp, #192]216 .seh_save_regp x25, 192217 stp x23, x24, [sp, #208]218 .seh_save_regp x23, 208219 stp x21, x22, [sp, #224]220 .seh_save_regp x21, 224221 ldp x19, x20, [sp, #240]222 .seh_save_regp x19, 240223 ldp x29, lr, [sp], #256224 .seh_save_fplr_x 256225 .seh_endepilogue226 ret227// epilog2 - a subsequence at the end of prolog, can use prolog's opcodes.228 .seh_startepilogue229 stp x25, x26, [sp, #192]230 .seh_save_regp x25, 192231 stp x23, x24, [sp, #208]232 .seh_save_regp x23, 208233 stp x21, x22, [sp, #224]234 .seh_save_regp x21, 224235 ldp x19, x20, [sp, #240]236 .seh_save_regp x19, 240237 ldp x29, lr, [sp], #256238 .seh_save_fplr_x 256239 .seh_endepilogue240 ret241// epilog3 - cannot use prolog's opcode.242 .seh_startepilogue243 mov sp, x29244 .seh_set_fp245 stp x23, x24, [sp, #208]246 .seh_save_regp x23, 208247 stp x21, x22, [sp, #224]248 .seh_save_regp x21, 224249 ldp x19, x20, [sp, #240]250 .seh_save_regp x19, 240251 ldp x29, lr, [sp], #256252 .seh_save_fplr_x 256253 .seh_endepilogue254 ret255 .rept 300000256 nop257 .endr258 bl foo259// Epilogs below are in a segment without prolog260// epilog4 - mirroring prolog, its start index should be 1, counting the end_c. 261 .seh_startepilogue262 mov sp, x29263 .seh_set_fp264 stp x27, x28, [sp, #176]265 .seh_save_regp x27, 176266 stp x25, x26, [sp, #192]267 .seh_save_regp x25, 192268 stp x23, x24, [sp, #208]269 .seh_save_regp x23, 208270 stp x21, x22, [sp, #224]271 .seh_save_regp x21, 224272 ldp x19, x20, [sp, #240]273 .seh_save_regp x19, 240274 ldp x29, lr, [sp], #256275 .seh_save_fplr_x 256276 .seh_endepilogue277 ret278// epilog5 - same as epilog2, its start index should be: 1 + epilog2's index.279 .seh_startepilogue280 stp x25, x26, [sp, #192]281 .seh_save_regp x25, 192282 stp x23, x24, [sp, #208]283 .seh_save_regp x23, 208284 stp x21, x22, [sp, #224]285 .seh_save_regp x21, 224286 ldp x19, x20, [sp, #240]287 .seh_save_regp x19, 240288 ldp x29, lr, [sp], #256289 .seh_save_fplr_x 256290 .seh_endepilogue291 ret292// epilog6 - same as epilog3, cannot use prolog's opcode. Again its start index293// should be: 1 + epilog3's index.294 .seh_startepilogue295 mov sp, x29296 .seh_set_fp297 stp x23, x24, [sp, #208]298 .seh_save_regp x23, 208299 stp x21, x22, [sp, #224]300 .seh_save_regp x21, 224301 ldp x19, x20, [sp, #240]302 .seh_save_regp x19, 240303 ldp x29, lr, [sp], #256304 .seh_save_fplr_x 256305 .seh_endepilogue306 ret307 .seh_endfunclet308 .seh_endproc309