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