1#include "check.h" 2 3 4#define ASMNAME(cname) ASMNAME2 (__USER_LABEL_PREFIX__, cname) 5#define ASMNAME2(prefix, cname) STRING (prefix) cname 6#define STRING(x) #x 7 8#ifdef __cplusplus 9extern "C" void abort (void); 10#else 11extern void abort (void); 12#endif 13 14extern void foo(void); 15 16#define INIT_EDI 1 17#define INIT_ESI 2 18#define INIT_EBX 3 19 20/* Set DI/SI/BX to wrong value 21 Use following template so that RA will save/restore callee 22 save registers in prologue/epilogue */ 23#define ALTER_REGS() \ 24 { \ 25 int dummy; \ 26 __asm__ __volatile__ (\ 27 "movl %1, %0" : "=D" (dummy) : "i" (-INIT_EDI)\ 28 );\ 29 __asm__ __volatile__ (\ 30 "movl %1, %0" : "=S" (dummy) : "i" (-INIT_ESI)\ 31 );\ 32 __asm__ __volatile__ (\ 33 "movl %1, %0" : "=b" (dummy) : "i" (-INIT_EBX)\ 34 );\ 35 } 36 37#if defined __PIC__ || defined __USING_SJLJ_EXCEPTIONS__ 38int 39main () 40{ 41 return 0; 42} 43#else 44void __attribute__ ((noinline)) 45copy (char *p, int size) 46{ 47 __builtin_strncpy (p, "good", size); 48} 49 50int g_edi=INIT_EDI, g_esi=INIT_ESI, g_ebx=INIT_EBX; 51int g_ebp, g_ebp_save, g_esp, g_esp_save; 52int n_error; 53 54int 55main() 56{ 57 int dummy; 58 // Init registers to correct value. 59 // Use following template so that RA will save/restore callee 60 // save registers in prologue/epilogue 61 __asm__ __volatile__ ( 62 "movl %1, %0" 63 : "=D" (dummy) 64 : "i" (INIT_EDI) 65 ); 66 __asm__ __volatile__ ( 67 "movl %1, %0" 68 : "=S" (dummy) 69 : "i" (INIT_ESI) 70 ); 71 __asm__ __volatile__ ( 72 "movl %1, %0" 73 : "=b" (dummy) 74 : "i" (INIT_EBX) 75 ); 76 __asm__ __volatile__ ( 77 "movl %ebp," ASMNAME("g_ebp_save")"\n\t" 78 "movl %esp," ASMNAME("g_esp_save")"\n\t" 79 ); 80 try { 81 foo(); 82 } 83 catch (...) 84 { 85 } 86 87 // Get DI/SI/BX register value after exception caught 88 __asm__ __volatile__ ( 89 "movl %edi," ASMNAME("g_edi")"\n\t" 90 "movl %esi," ASMNAME("g_esi")"\n\t" 91 "movl %ebx," ASMNAME("g_ebx")"\n\t" 92 "movl %ebp," ASMNAME("g_ebp")"\n\t" 93 "movl %esp," ASMNAME("g_esp")"\n\t" 94 ); 95 96 // Check if DI/SI/BX register value are the same as before calling 97 // foo. 98 if (g_edi != INIT_EDI) 99 { 100 n_error++; 101#ifdef DEBUG 102 printf("edi=%d, correct value:%d\n", g_edi, INIT_EDI); 103#endif 104 } 105 if (g_esi != INIT_ESI) 106 { 107 n_error++; 108#ifdef DEBUG 109 printf("esi=%d, correct value:%d\n", g_esi, INIT_ESI); 110#endif 111 } 112 if (g_ebx != INIT_EBX) 113 { 114 n_error++; 115#ifdef DEBUG 116 printf("ebx=%d, correct value:%d\n", g_ebx, INIT_EBX); 117#endif 118 } 119 if (g_ebp != g_ebp_save) 120 { 121 n_error++; 122#ifdef DEBUG 123 printf("ebp=0x%x, correct value:0x%x\n", g_ebp, g_ebp_save); 124#endif 125 } 126 if (g_esp != g_esp_save) 127 { 128 n_error++; 129#ifdef DEBUG 130 printf("esp=0x%x, correct value:0x%x\n", g_esp, g_esp_save); 131#endif 132 } 133 if (n_error !=0) 134 abort(); 135 return 0; 136} 137#endif 138