1/* { dg-do run { target *-*-linux* } } */ 2/* { dg-require-effective-target lp64 } */ 3/* { dg-options "-fexceptions -fnon-call-exceptions -fasynchronous-unwind-tables -O2" } */ 4/* Test complex CFA value expressions. */ 5 6#include <unwind.h> 7#include <stdlib.h> 8#include <string.h> 9#include <stdio.h> 10#include <unistd.h> 11 12static _Unwind_Reason_Code 13force_unwind_stop (int version, _Unwind_Action actions, 14 _Unwind_Exception_Class exc_class, 15 struct _Unwind_Exception *exc_obj, 16 struct _Unwind_Context *context, 17 void *stop_parameter) 18{ 19 if (actions & _UA_END_OF_STACK) 20 abort (); 21 return _URC_NO_REASON; 22} 23 24static void 25force_unwind () 26{ 27 struct _Unwind_Exception *exc = malloc (sizeof (*exc)); 28 memset (&exc->exception_class, 0, sizeof (exc->exception_class)); 29 exc->exception_cleanup = 0; 30 31 _Unwind_ForcedUnwind (exc, force_unwind_stop, 0); 32 abort (); 33} 34 35int count; 36 37static void 38counter (void *p __attribute__((unused))) 39{ 40 ++count; 41} 42 43static void 44handler (void *p __attribute__((unused))) 45{ 46 if (count != 2) 47 abort (); 48 _exit (0); 49} 50 51static int __attribute__((noinline)) 52fn5 (void) 53{ 54 char dummy __attribute__((cleanup (counter))); 55 force_unwind (); 56 return 0; 57} 58 59void 60bar (void) 61{ 62 char dummy __attribute__((cleanup (counter))); 63 fn5 (); 64} 65 66void __attribute__((noinline)) 67foo (int x) 68{ 69 char buf[256]; 70#ifdef __x86_64__ 71 __asm ( 72 "testl %0, %0\n\t" 73 "jnz 1f\n\t" 74 ".subsection 1\n\t" 75 ".type _L_mutex_lock_%=, @function\n" 76"_L_mutex_lock_%=:\n" 77"1:\t" "leaq %1, %%rdi\n" 78"2:\t" "subq $128, %%rsp\n" 79"3:\t" "call bar\n" 80"4:\t" "addq $128, %%rsp\n" 81"5:\t" "jmp 21f\n" 82"6:\t" ".size _L_mutex_lock_%=, .-_L_mutex_lock_%=\n\t" 83 ".previous\n\t" 84 ".section .eh_frame,\"a\",@progbits\n" 85"7:\t" ".long 9f-8f # Length of Common Information Entry\n" 86"8:\t" ".long 0x0 # CIE Identifier Tag\n\t" 87 ".byte 0x1 # CIE Version\n\t" 88 ".ascii \"zR\\0\" # CIE Augmentation\n\t" 89 ".uleb128 0x1 # CIE Code Alignment Factor\n\t" 90 ".sleb128 -8 # CIE Data Alignment Factor\n\t" 91 ".byte 0x10 # CIE RA Column\n\t" 92 ".uleb128 0x1 # Augmentation size\n\t" 93 ".byte 0x1b # FDE Encoding (pcrel sdata4)\n\t" 94 ".byte 0xc # DW_CFA_def_cfa\n\t" 95 ".uleb128 0x7\n\t" 96 ".uleb128 0x0\n\t" 97 ".align 8\n" 98"9:\t" ".long 20f-10f # FDE Length\n" 99"10:\t" ".long 10b-7b # FDE CIE offset\n\t" 100 ".long 1b-. # FDE initial location\n\t" 101 ".long 6b-1b # FDE address range\n\t" 102 ".uleb128 0x0 # Augmentation size\n\t" 103 /* This CFA expression computes the address right 104 past the jnz instruction above, from %rip somewhere 105 within the _L_mutex_lock_%= subsection. */ 106 ".byte 0x16 # DW_CFA_val_expression\n\t" 107 ".uleb128 0x10\n\t" 108 ".uleb128 19f-11f\n" 109"11:\t" ".byte 0x80 # DW_OP_breg16\n\t" 110 ".sleb128 0\n" 111"12:\t" ".byte 0x12 # DW_OP_dup\n\t" 112 ".byte 0x94 # DW_OP_deref_size\n\t" 113 ".byte 1\n\t" 114 ".byte 0x12 # DW_OP_dup\n\t" 115 ".byte 0x08 # DW_OP_const1u\n\t" 116 ".byte 0x48\n\t" 117 ".byte 0x2e # DW_OP_ne\n\t" 118 ".byte 0x28 # DW_OP_bra\n\t" 119 ".2byte 16f-13f\n" 120"13:\t" ".byte 0x13 # DW_OP_drop\n\t" 121 ".byte 0x23 # DW_OP_plus_uconst\n\t" 122 ".uleb128 1\n\t" 123 ".byte 0x12 # DW_OP_dup\n\t" 124 ".byte 0x94 # DW_OP_deref_size\n\t" 125 ".byte 1\n\t" 126 ".byte 0x08 # DW_OP_const1u\n\t" 127 ".byte 0x81\n\t" 128 ".byte 0x2e # DW_OP_ne\n\t" 129 ".byte 0x28 # DW_OP_bra\n\t" 130 ".2byte 15f-14f\n" 131"14:\t" ".byte 0x23 # DW_OP_plus_uconst\n\t" 132 ".uleb128 3b-2b-1\n\t" 133 ".byte 0x2f # DW_OP_skip\n\t" 134 ".2byte 12b-15f\n" 135"15:\t" ".byte 0x23 # DW_OP_plus_uconst\n\t" 136 ".uleb128 2b-1b-1\n\t" 137 ".byte 0x2f # DW_OP_skip\n\t" 138 ".2byte 12b-16f\n" 139"16:\t" ".byte 0x08 # DW_OP_const1u\n\t" 140 ".byte 0xe8\n\t" 141 ".byte 0x2e # DW_OP_ne\n\t" 142 ".byte 0x28 # DW_OP_bra\n\t" 143 ".2byte 18f-17f\n" 144"17:\t" ".byte 0x23 # DW_OP_plus_uconst\n\t" 145 ".uleb128 4b-3b\n\t" 146 ".byte 0x2f # DW_OP_skip\n\t" 147 ".2byte 12b-18f\n" 148"18:\t" ".byte 0x23 # DW_OP_plus_uconst\n\t" 149 ".uleb128 1\n\t" 150 ".byte 0x12 # DW_OP_dup\n\t" 151 ".byte 0x94 # DW_OP_deref_size\n\t" 152 ".byte 4\n\t" 153 ".byte 0x08 # DW_OP_const1u\n\t" 154 ".byte 72 - (6b-5b) * 8 # (6b-5b) == 5 ? 32 : 56\n\t" 155 ".byte 0x24 # DW_OP_shl\n\t" 156 ".byte 0x08 # DW_OP_const1u\n\t" 157 ".byte 72 - (6b-5b) * 8 # (6b-5b) == 5 ? 32 : 56\n\t" 158 ".byte 0x26 # DW_OP_shra\n\t" 159 ".byte 0x22 # DW_OP_plus\n\t" 160 ".byte 0x23 # DW_OP_plus_uconst\n\t" 161 ".uleb128 6b-5b-1\n" 162"19:\t" ".byte 0x40 + (3b-1b) # DW_CFA_advance_loc\n\t" 163 ".byte 0xe # DW_CFA_def_cfa_offset\n\t" 164 ".uleb128 128\n\t" 165 ".byte 0x40 + (5b-3b) # DW_CFA_advance_loc\n\t" 166 ".byte 0xe # DW_CFA_def_cfa_offset\n\t" 167 ".uleb128 0\n\t" 168 ".align 8\n" 169"20:\t" ".previous\n" 170"21:" 171 : : "r" (x), "m" (x), "r" (buf) 172 : "memory", "rax", "rdx", "rcx", "rsi", "rdi", 173 "r8", "r9", "r10", "r11"); 174#else 175# error Unsupported test architecture 176#endif 177} 178 179static int __attribute__((noinline)) 180fn2 (void) 181{ 182 foo (3); 183 return 0; 184} 185 186static int __attribute__((noinline)) 187fn1 (void) 188{ 189 fn2 (); 190 return 0; 191} 192 193static void * 194fn0 (void) 195{ 196 char dummy __attribute__((cleanup (handler))); 197 fn1 (); 198 return 0; 199} 200 201int 202main (void) 203{ 204 fn0 (); 205 return 0; 206} 207