1// http://gcc.gnu.org/viewcvs/gcc/trunk/gcc/testsuite/gcc.dg/cleanup-13.c?view=co&content-type=text%2Fplain 2 3/* HP-UX libunwind.so doesn't provide _UA_END_OF_STACK */ 4/* { dg-do run } */ 5/* { dg-options "-fexceptions" } */ 6/* { dg-skip-if "" { "ia64-*-hpux11.*" } { "*" } { "" } } */ 7/* Verify DW_OP_* handling in the unwinder. */ 8 9#include <unwind.h> 10#include <stdlib.h> 11#include <string.h> 12 13/* #define OP_addr(x) 0x06, ... */ 14#define OP_deref 0x06, 15#define SLEB128(x) (x)&0x7f /* Assume here the value is -0x40 ... 0x3f. */ 16#define ULEB128(x) (x)&0x7f /* Assume here the value is 0 ... 0x7f. */ 17#define VAL1(x) (x)&0xff 18#if defined (__BIG_ENDIAN__) 19#define VAL2(x) ((x)>>8)&0xff,(x)&0xff 20#define VAL4(x) ((x)>>24)&0xff,((x)>>16)&0xff,((x)>>8)&0xff,(x)&0xff 21#define VAL8(x) ((x)>>56)&0xff,((x)>>48)&0xff,((x)>>40)&0xff,((x)>>32)&0xff,((x)>>24)&0xff,((x)>>16)&0xff,((x)>>8)&0xff,(x)&0xff 22#elif defined(__LITTLE_ENDIAN__) || defined(__x86_64__) || defined(__i386__) 23#define VAL2(x) (x)&0xff,((x)>>8)&0xff 24#define VAL4(x) (x)&0xff,((x)>>8)&0xff,((x)>>16)&0xff,((x)>>24)&0xff 25#define VAL8(x) (x)&0xff,((x)>>8)&0xff,((x)>>16)&0xff,((x)>>24)&0xff,((x)>>32)&0xff,((x)>>40)&0xff,((x)>>48)&0xff,((x)>>56)&0xff 26#endif 27#define OP_const1u(x) 0x08,VAL1(x), 28#define OP_const1s(x) 0x09,VAL1(x), 29#define OP_const2u(x) 0x0a,VAL2(x), 30#define OP_const2s(x) 0x0b,VAL2(x), 31#define OP_const4u(x) 0x0c,VAL4(x), 32#define OP_const4s(x) 0x0d,VAL4(x), 33#define OP_const8u(x) 0x0e,VAL8(x), 34#define OP_const8s(x) 0x0f,VAL8(x), 35#define OP_constu(x) 0x10,ULEB128(x), 36#define OP_consts(x) 0x11,SLEB128(x), 37#define OP_dup 0x12, 38#define OP_drop 0x13, 39#define OP_over 0x14, 40#define OP_pick(x) 0x15,VAL1(x), 41#define OP_swap 0x16, 42#define OP_rot 0x17, 43#define OP_xderef 0x18, 44#define OP_abs 0x19, 45#define OP_and 0x1a, 46#define OP_div 0x1b, 47#define OP_minus 0x1c, 48#define OP_mod 0x1d, 49#define OP_mul 0x1e, 50#define OP_neg 0x1f, 51#define OP_not 0x20, 52#define OP_or 0x21, 53#define OP_plus 0x22, 54#define OP_plus_uconst(x) 0x23,ULEB128(x), 55#define OP_shl 0x24, 56#define OP_shr 0x25, 57#define OP_shra 0x26, 58#define OP_xor 0x27, 59#define OP_bra(x) 0x28,VAL2(x), 60#define OP_eq 0x29, 61#define OP_ge 0x2a, 62#define OP_gt 0x2b, 63#define OP_le 0x2c, 64#define OP_lt 0x2d, 65#define OP_ne 0x2e, 66#define OP_skip(x) 0x2f,VAL2(x), 67#define OP_lit0 0x30, 68#define OP_lit1 0x31, 69#define OP_lit2 0x32, 70#define OP_lit3 0x33, 71#define OP_lit4 0x34, 72#define OP_lit5 0x35, 73#define OP_lit6 0x36, 74#define OP_lit7 0x37, 75#define OP_lit8 0x38, 76#define OP_lit9 0x39, 77#define OP_lit10 0x3a, 78#define OP_lit11 0x3b, 79#define OP_lit12 0x3c, 80#define OP_lit13 0x3d, 81#define OP_lit14 0x3e, 82#define OP_lit15 0x3f, 83#define OP_lit16 0x40, 84#define OP_lit17 0x41, 85#define OP_lit18 0x42, 86#define OP_lit19 0x43, 87#define OP_lit20 0x44, 88#define OP_lit21 0x45, 89#define OP_lit22 0x46, 90#define OP_lit23 0x47, 91#define OP_lit24 0x48, 92#define OP_lit25 0x49, 93#define OP_lit26 0x4a, 94#define OP_lit27 0x4b, 95#define OP_lit28 0x4c, 96#define OP_lit29 0x4d, 97#define OP_lit30 0x4e, 98#define OP_lit31 0x4f, 99#define OP_reg0 0x50, 100#define OP_reg1 0x51, 101#define OP_reg2 0x52, 102#define OP_reg3 0x53, 103#define OP_reg4 0x54, 104#define OP_reg5 0x55, 105#define OP_reg6 0x56, 106#define OP_reg7 0x57, 107#define OP_reg8 0x58, 108#define OP_reg9 0x59, 109#define OP_reg10 0x5a, 110#define OP_reg11 0x5b, 111#define OP_reg12 0x5c, 112#define OP_reg13 0x5d, 113#define OP_reg14 0x5e, 114#define OP_reg15 0x5f, 115#define OP_reg16 0x60, 116#define OP_reg17 0x61, 117#define OP_reg18 0x62, 118#define OP_reg19 0x63, 119#define OP_reg20 0x64, 120#define OP_reg21 0x65, 121#define OP_reg22 0x66, 122#define OP_reg23 0x67, 123#define OP_reg24 0x68, 124#define OP_reg25 0x69, 125#define OP_reg26 0x6a, 126#define OP_reg27 0x6b, 127#define OP_reg28 0x6c, 128#define OP_reg29 0x6d, 129#define OP_reg30 0x6e, 130#define OP_reg31 0x6f, 131#define OP_breg0(x) 0x70,SLEB128(x), 132#define OP_breg1(x) 0x71,SLEB128(x), 133#define OP_breg2(x) 0x72,SLEB128(x), 134#define OP_breg3(x) 0x73,SLEB128(x), 135#define OP_breg4(x) 0x74,SLEB128(x), 136#define OP_breg5(x) 0x75,SLEB128(x), 137#define OP_breg6(x) 0x76,SLEB128(x), 138#define OP_breg7(x) 0x77,SLEB128(x), 139#define OP_breg8(x) 0x78,SLEB128(x), 140#define OP_breg9(x) 0x79,SLEB128(x), 141#define OP_breg10(x) 0x7a,SLEB128(x), 142#define OP_breg11(x) 0x7b,SLEB128(x), 143#define OP_breg12(x) 0x7c,SLEB128(x), 144#define OP_breg13(x) 0x7d,SLEB128(x), 145#define OP_breg14(x) 0x7e,SLEB128(x), 146#define OP_breg15(x) 0x7f,SLEB128(x), 147#define OP_breg16(x) 0x80,SLEB128(x), 148#define OP_breg17(x) 0x81,SLEB128(x), 149#define OP_breg18(x) 0x82,SLEB128(x), 150#define OP_breg19(x) 0x83,SLEB128(x), 151#define OP_breg20(x) 0x84,SLEB128(x), 152#define OP_breg21(x) 0x85,SLEB128(x), 153#define OP_breg22(x) 0x86,SLEB128(x), 154#define OP_breg23(x) 0x87,SLEB128(x), 155#define OP_breg24(x) 0x88,SLEB128(x), 156#define OP_breg25(x) 0x89,SLEB128(x), 157#define OP_breg26(x) 0x8a,SLEB128(x), 158#define OP_breg27(x) 0x8b,SLEB128(x), 159#define OP_breg28(x) 0x8c,SLEB128(x), 160#define OP_breg29(x) 0x8d,SLEB128(x), 161#define OP_breg30(x) 0x8e,SLEB128(x), 162#define OP_breg31(x) 0x8f,SLEB128(x), 163#define OP_regx(x) 0x90,SLEB128(x), 164#define OP_fbreg(x) 0x91,SLEB128(x), 165#define OP_bregx(x,y) 0x92,ULEB128(x),SLEB128(y), 166#define OP_piece(x) 0x93,ULEB128(x), 167#define OP_deref_size(x) 0x94,VAL1(x), 168#define OP_xderef_size(x) 0x95,VAL1(x), 169#define OP_nop 0x96, 170#define OP_nop_termination 0x96 171#define OP_push_object_address 0x97, 172#define OP_call2(x) 0x98,VAL2(x), 173#define OP_call4(x) 0x99,VAL4(x), 174/* #define OP_call_ref(x) 0x9a,... */ 175#define OP_form_tls_address(x) 0x9b, 176#define OP_call_frame_cfa 0x9c, 177#define OP_bit_piece(x) 0x9d,ULEB128(x), 178/* #define OP_implicit_value(x...) 0x9e,... */ 179#define OP_stack_value 0x9f, 180#define OP_GNU_push_tls_address 0xe0, 181/* #define OP_GNU_encoded_addr(x...) 0xf1, */ 182 183#define ASSERT_TOS_NON0 OP_bra(3) OP_skip(-3) 184#define ASSERT_TOS_0 OP_lit0 OP_eq ASSERT_TOS_NON0 185 186/* Initially there is CFA value on the stack, we want to 187 keep it there at the end. */ 188#define CFI_PROGRAM \ 189OP_lit0 OP_nop ASSERT_TOS_0 \ 190OP_lit1 ASSERT_TOS_NON0 \ 191OP_lit1 OP_const1u(1) OP_eq ASSERT_TOS_NON0 \ 192OP_lit16 OP_const2u(16) OP_eq ASSERT_TOS_NON0 \ 193OP_lit31 OP_const4u(31) OP_ne ASSERT_TOS_0 \ 194OP_lit1 OP_neg OP_const1s(-1) OP_eq ASSERT_TOS_NON0 \ 195OP_lit16 OP_neg OP_const2s(-16) OP_ne ASSERT_TOS_0 \ 196OP_lit31 OP_const4s(-31) OP_neg OP_ne ASSERT_TOS_0 \ 197OP_lit7 OP_dup OP_plus_uconst(2) OP_lit9 OP_eq ASSERT_TOS_NON0 \ 198 OP_lit7 OP_eq ASSERT_TOS_NON0 \ 199OP_lit20 OP_lit1 OP_drop OP_lit20 OP_eq ASSERT_TOS_NON0 \ 200OP_lit17 OP_lit19 OP_over OP_lit17 OP_eq ASSERT_TOS_NON0 \ 201 OP_lit19 OP_eq ASSERT_TOS_NON0 OP_lit17 OP_eq ASSERT_TOS_NON0 \ 202OP_lit1 OP_lit2 OP_lit3 OP_lit4 OP_pick(2) OP_lit2 OP_eq ASSERT_TOS_NON0\ 203 OP_lit4 OP_eq ASSERT_TOS_NON0 OP_lit3 OP_eq ASSERT_TOS_NON0 \ 204 OP_pick(0) OP_lit2 OP_eq ASSERT_TOS_NON0 \ 205 OP_lit2 OP_eq ASSERT_TOS_NON0 OP_lit1 OP_eq ASSERT_TOS_NON0 \ 206OP_lit6 OP_lit12 OP_swap OP_lit6 OP_eq ASSERT_TOS_NON0 \ 207 OP_lit12 OP_eq ASSERT_TOS_NON0 \ 208OP_lit7 OP_lit8 OP_lit9 OP_rot OP_lit8 OP_eq ASSERT_TOS_NON0 \ 209 OP_lit7 OP_eq ASSERT_TOS_NON0 OP_lit9 OP_eq ASSERT_TOS_NON0 \ 210OP_lit7 OP_abs OP_lit7 OP_eq ASSERT_TOS_NON0 \ 211OP_const1s(-123) OP_abs OP_const1u(123) OP_eq ASSERT_TOS_NON0 \ 212OP_lit3 OP_lit6 OP_and OP_lit2 OP_eq ASSERT_TOS_NON0 \ 213OP_lit3 OP_lit6 OP_or OP_lit7 OP_eq ASSERT_TOS_NON0 \ 214OP_lit17 OP_lit2 OP_minus OP_lit15 OP_eq ASSERT_TOS_NON0 \ 215/* Divide is signed truncating toward zero. */ \ 216OP_const1s(-6) OP_const1s(-2) OP_div OP_lit3 OP_eq ASSERT_TOS_NON0 \ 217OP_const1s(-7) OP_const1s(3) OP_div OP_const1s(-2) \ 218 OP_eq ASSERT_TOS_NON0 \ 219/* Modulo is unsigned. */ \ 220OP_const1s(-6) OP_const1s(-4) OP_mod OP_const1s(-6) \ 221 OP_eq ASSERT_TOS_NON0 \ 222OP_const1s(-6) OP_lit4 OP_mod OP_lit2 OP_eq ASSERT_TOS_NON0 \ 223OP_lit6 OP_const1s(-4) OP_mod OP_lit6 OP_eq ASSERT_TOS_NON0 \ 224/* Signed modulo can be implemented using "over over div mul minus". */\ 225OP_const1s(-6) OP_const1s(-4) OP_over OP_over OP_div OP_mul OP_minus \ 226 OP_const1s(-2) OP_eq ASSERT_TOS_NON0 \ 227OP_const1s(-7) OP_lit3 OP_over OP_over OP_div OP_mul OP_minus \ 228 OP_const1s(-1) OP_eq ASSERT_TOS_NON0 \ 229OP_lit7 OP_const1s(-3) OP_over OP_over OP_div OP_mul OP_minus \ 230 OP_lit1 OP_eq ASSERT_TOS_NON0 \ 231OP_lit16 OP_lit31 OP_plus_uconst(1) OP_mul OP_const2u(512) \ 232 OP_eq ASSERT_TOS_NON0 \ 233OP_lit5 OP_not OP_lit31 OP_and OP_lit26 OP_eq ASSERT_TOS_NON0 \ 234OP_lit12 OP_lit31 OP_plus OP_const1u(43) OP_eq ASSERT_TOS_NON0 \ 235OP_const1s(-6) OP_lit2 OP_plus OP_const1s(-4) OP_eq ASSERT_TOS_NON0 \ 236OP_const1s(-6) OP_plus_uconst(3) OP_const1s(-3) OP_eq ASSERT_TOS_NON0 \ 237OP_lit16 OP_lit4 OP_shl OP_const2u(256) OP_eq ASSERT_TOS_NON0 \ 238OP_lit16 OP_lit3 OP_shr OP_lit2 OP_eq ASSERT_TOS_NON0 \ 239OP_const1s(-16) OP_lit3 OP_shra OP_const1s(-2) OP_eq ASSERT_TOS_NON0 \ 240OP_lit3 OP_lit6 OP_xor OP_lit5 OP_eq ASSERT_TOS_NON0 \ 241OP_lit3 OP_lit6 OP_le ASSERT_TOS_NON0 \ 242OP_lit3 OP_lit3 OP_le ASSERT_TOS_NON0 \ 243OP_lit6 OP_lit3 OP_le ASSERT_TOS_0 \ 244OP_lit3 OP_lit6 OP_lt ASSERT_TOS_NON0 \ 245OP_lit3 OP_lit3 OP_lt ASSERT_TOS_0 \ 246OP_lit6 OP_lit3 OP_lt ASSERT_TOS_0 \ 247OP_lit3 OP_lit6 OP_ge ASSERT_TOS_0 \ 248OP_lit3 OP_lit3 OP_ge ASSERT_TOS_NON0 \ 249OP_lit6 OP_lit3 OP_ge ASSERT_TOS_NON0 \ 250OP_lit3 OP_lit6 OP_gt ASSERT_TOS_0 \ 251OP_lit3 OP_lit3 OP_gt ASSERT_TOS_0 \ 252OP_lit6 OP_lit3 OP_gt ASSERT_TOS_NON0 \ 253OP_const1s(-6) OP_lit1 OP_shr OP_lit0 OP_gt ASSERT_TOS_NON0 \ 254OP_const1s(-6) OP_lit1 OP_shra OP_lit0 OP_lt ASSERT_TOS_NON0 255 256#define CFI_ESCAPE_VAL_2(VALUES...) #VALUES 257#define CFI_ESCAPE_VAL_1(VALUES...) CFI_ESCAPE_VAL_2(VALUES) 258#define CFI_ESCAPE_VAL(VALUES...) CFI_ESCAPE_VAL_1(VALUES) 259#define CFI_ESCAPE do { } while (0) 260#define CFI_ARCH_PROGRAM OP_nop_termination 261#ifdef __GCC_HAVE_DWARF2_CFI_ASM 262#if defined (__x86_64__) 263#undef CFI_ESCAPE 264#undef CFI_ARCH_PROGRAM 265#define CFI_ARCH_PROGRAM CFI_PROGRAM OP_lit8 OP_minus OP_nop_termination 266unsigned char cfi_arch_program[] = { CFI_ARCH_PROGRAM }; 267extern char verify_it[sizeof (cfi_arch_program) - 0x80 < 0x3f80 ? 1 : -1]; 268/* DW_CFA_expression %rip, uleb128(l2-l1), l1: program DW_OP_lit8 DW_OP_minus DW_OP_nop l2: */ 269#define CFI_ESCAPE \ 270 asm volatile (".cfi_escape 0x10, 0x10, (%P0&0x7f)+0x80, %P0>>7, " \ 271 CFI_ESCAPE_VAL (CFI_ARCH_PROGRAM) \ 272 : : "i" (sizeof (cfi_arch_program))) 273#elif defined (__i386__) 274#undef CFI_ESCAPE 275#undef CFI_ARCH_PROGRAM 276#define CFI_ARCH_PROGRAM CFI_PROGRAM OP_lit4 OP_minus OP_nop_termination 277unsigned char cfi_arch_program[] = { CFI_ARCH_PROGRAM }; 278extern char verify_it[sizeof (cfi_arch_program) - 0x80 < 0x3f80 ? 1 : -1]; 279/* DW_CFA_expression %eip, uleb128(l2-l1), l1: program DW_OP_lit4 DW_OP_minus DW_OP_nop l2: */ 280#define CFI_ESCAPE \ 281 asm volatile (".cfi_escape 0x10, 8, (%P0&0x7f)+0x80, %P0>>7, " \ 282 CFI_ESCAPE_VAL (CFI_ARCH_PROGRAM) \ 283 : : "i" (sizeof (cfi_arch_program))) 284#endif 285#endif 286 287/* The original GCC testcase tests the runtime unwinder using 288 _Unwind_ForcedUnwind, we just inspect the child when it aborts. */ 289 290static void force_unwind () 291{ 292 abort (); 293} 294 295static void handler (void *p __attribute__((unused))) 296{ 297 exit (0); 298} 299 300__attribute__((noinline)) static void callme () 301{ 302 CFI_ESCAPE; 303 force_unwind (); 304} 305 306__attribute__((noinline)) static void doit () 307{ 308 char dummy __attribute__((cleanup (handler))); 309 callme (); 310} 311 312int main() 313{ 314 doit (); 315 abort (); 316} 317