1/* Verify that unwinding can find SPE registers in signal frames. */ 2/* Origin: Joseph Myers <joseph@codesourcery.com> */ 3/* { dg-do run { target { powerpc*-*-linux* && powerpc_spe } } } */ 4/* { dg-options "-fexceptions -fnon-call-exceptions -O2" } */ 5 6#include <unwind.h> 7#include <stdlib.h> 8#include <signal.h> 9#include <string.h> 10 11int count; 12char *null; 13int found_reg; 14 15typedef int v2si __attribute__((__vector_size__(8))); 16 17v2si v1 = { 123, 234 }; 18v2si v2 = { 345, 456 }; 19 20static _Unwind_Reason_Code 21force_unwind_stop (int version, _Unwind_Action actions, 22 _Unwind_Exception_Class exc_class, 23 struct _Unwind_Exception *exc_obj, 24 struct _Unwind_Context *context, 25 void *stop_parameter) 26{ 27 unsigned int reg; 28 if (actions & _UA_END_OF_STACK) 29 abort (); 30 if (_Unwind_GetGR (context, 1215) == 123) 31 found_reg = 1; 32 return _URC_NO_REASON; 33} 34 35static void force_unwind () 36{ 37 struct _Unwind_Exception *exc = malloc (sizeof (*exc)); 38 memset (&exc->exception_class, 0, sizeof (exc->exception_class)); 39 exc->exception_cleanup = 0; 40 41#ifndef __USING_SJLJ_EXCEPTIONS__ 42 _Unwind_ForcedUnwind (exc, force_unwind_stop, 0); 43#else 44 _Unwind_SjLj_ForcedUnwind (exc, force_unwind_stop, 0); 45#endif 46 47 abort (); 48} 49 50static void counter (void *p __attribute__((unused))) 51{ 52 ++count; 53} 54 55static void handler (void *p __attribute__((unused))) 56{ 57 if (count != 2) 58 abort (); 59 if (!found_reg) 60 abort (); 61 exit (0); 62} 63 64static int __attribute__((noinline)) fn5 () 65{ 66 char dummy __attribute__((cleanup (counter))); 67 force_unwind (); 68 return 0; 69} 70 71static void fn4 (int sig) 72{ 73 char dummy __attribute__((cleanup (counter))); 74 /* Clobber high part without compiler's knowledge so the only saved 75 copy is from the signal frame. */ 76 asm volatile ("evmergelo 15,15,15"); 77 fn5 (); 78 null = NULL; 79} 80 81static void fn3 () 82{ 83 abort (); 84} 85 86static int __attribute__((noinline)) fn2 () 87{ 88 register v2si r15 asm("r15"); 89 r15 = v1; 90 asm volatile ("" : "+r" (r15)); 91 *null = 0; 92 fn3 (); 93 return 0; 94} 95 96static int __attribute__((noinline)) fn1 () 97{ 98 signal (SIGSEGV, fn4); 99 signal (SIGBUS, fn4); 100 fn2 (); 101 return 0; 102} 103 104static int __attribute__((noinline)) fn0 () 105{ 106 char dummy __attribute__((cleanup (handler))); 107 fn1 (); 108 null = 0; 109 return 0; 110} 111 112int main() 113{ 114 fn0 (); 115 abort (); 116} 117