diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /gcc/testsuite/g++.dg/torture/stackalign/test-unwind.h | |
download | cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2 cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig;
imported gcc-4.6.4 source tree from verified upstream tarball.
downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.
if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
Diffstat (limited to 'gcc/testsuite/g++.dg/torture/stackalign/test-unwind.h')
-rw-r--r-- | gcc/testsuite/g++.dg/torture/stackalign/test-unwind.h | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/test-unwind.h b/gcc/testsuite/g++.dg/torture/stackalign/test-unwind.h new file mode 100644 index 000000000..ff5602784 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/stackalign/test-unwind.h @@ -0,0 +1,142 @@ +#include "check.h" + + +#define ASMNAME(cname) ASMNAME2 (__USER_LABEL_PREFIX__, cname) +#define ASMNAME2(prefix, cname) STRING (prefix) cname +#define STRING(x) #x + +#ifdef __cplusplus +extern "C" void abort (void); +#else +extern void abort (void); +#endif + +extern void foo(void); + +#define INIT_EDI 1 +#define INIT_ESI 2 +#define INIT_EBX 3 + +/* Set DI/SI/BX to wrong value + Use following template so that RA will save/restore callee + save registers in prologue/epilogue */ +#define ALTER_REGS() \ + { \ + int dummy; \ + __asm__ __volatile__ (\ + "movl %1, %0" : "=D" (dummy) : "i" (-INIT_EDI)\ + );\ + __asm__ __volatile__ (\ + "movl %1, %0" : "=S" (dummy) : "i" (-INIT_ESI)\ + );\ + __asm__ __volatile__ (\ + "movl %1, %0" : "=b" (dummy) : "i" (-INIT_EBX)\ + );\ + } + +#if defined __PIC__ || defined __USING_SJLJ_EXCEPTIONS__ +int +main () +{ + return 0; +} +#else +void __attribute__ ((noinline)) +copy (char *p, int size) +{ + __builtin_strncpy (p, "good", size); +} + +int g_edi __attribute__((externally_visible)) =INIT_EDI; +int g_esi __attribute__((externally_visible)) =INIT_ESI; +int g_ebx __attribute__((externally_visible)) = INIT_EBX; +int g_ebp __attribute__((externally_visible)); +int g_esp __attribute__((externally_visible)); +int g_ebp_save __attribute__((externally_visible)); +int g_esp_save __attribute__((externally_visible)); +int n_error; + +int +main() +{ + int dummy; + // Init registers to correct value. + // Use following template so that RA will save/restore callee + // save registers in prologue/epilogue + __asm__ __volatile__ ( + "movl %1, %0" + : "=D" (dummy) + : "i" (INIT_EDI) + ); + __asm__ __volatile__ ( + "movl %1, %0" + : "=S" (dummy) + : "i" (INIT_ESI) + ); + __asm__ __volatile__ ( + "movl %1, %0" + : "=b" (dummy) + : "i" (INIT_EBX) + ); + __asm__ __volatile__ ( + "movl %ebp," ASMNAME("g_ebp_save")"\n\t" + "movl %esp," ASMNAME("g_esp_save")"\n\t" + ); + try { + foo(); + } + catch (...) + { + } + + // Get DI/SI/BX register value after exception caught + __asm__ __volatile__ ( + "movl %edi," ASMNAME("g_edi")"\n\t" + "movl %esi," ASMNAME("g_esi")"\n\t" + "movl %ebx," ASMNAME("g_ebx")"\n\t" + "movl %ebp," ASMNAME("g_ebp")"\n\t" + "movl %esp," ASMNAME("g_esp")"\n\t" + ); + + // Check if DI/SI/BX register value are the same as before calling + // foo. + if (g_edi != INIT_EDI) + { + n_error++; +#ifdef DEBUG + printf("edi=%d, correct value:%d\n", g_edi, INIT_EDI); +#endif + } + if (g_esi != INIT_ESI) + { + n_error++; +#ifdef DEBUG + printf("esi=%d, correct value:%d\n", g_esi, INIT_ESI); +#endif + } + if (g_ebx != INIT_EBX) + { + n_error++; +#ifdef DEBUG + printf("ebx=%d, correct value:%d\n", g_ebx, INIT_EBX); +#endif + } + if (g_ebp != g_ebp_save) + { + n_error++; +#ifdef DEBUG + printf("ebp=0x%x, correct value:0x%x\n", g_ebp, g_ebp_save); +#endif + } + if (g_esp != g_esp_save) + { + n_error++; +#ifdef DEBUG + printf("esp=0x%x, correct value:0x%x\n", g_esp, g_esp_save); +#endif + } + if (n_error !=0) + abort(); + return 0; +} +#endif |