#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