blob: ff5602784935067b3a3ed5d18886835b8907a876 [file] [log] [blame]
#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