1 2005-11-11 Gwenole Beauchesne <gbeauchesne@mandriva.com>
3 * Check for stack clobbers in functions using GOTO_LABEL_PARAM().
5 --- qemu-0.7.2/dyngen.c.dyngen-check-stack-clobbers 2005-11-11 16:26:33.000000000 +0100
6 +++ qemu-0.7.2/dyngen.c 2005-11-11 17:30:29.000000000 +0100
7 @@ -1414,6 +1414,9 @@ int arm_emit_ldr_info(const char *name,
8 #define FLAG_TARGET (1 << 3)
9 /* This is a magic instruction that needs fixing up. */
10 #define FLAG_EXIT (1 << 4)
11 +/* This instruction clobbers the stack pointer. */
12 +/* XXX only supports push, pop, add/sub $imm,%esp */
13 +#define FLAG_STACK (1 << 5)
17 @@ -1454,6 +1457,7 @@ trace_i386_insn (const char *name, uint8
25 @@ -1476,6 +1480,7 @@ trace_i386_insn (const char *name, uint8
33 @@ -1522,6 +1527,7 @@ trace_i386_insn (const char *name, uint8
35 case 0: /* push fs/gs */
36 case 1: /* pop fs/gs */
38 case 2: /* cpuid/rsm */
41 @@ -1594,6 +1600,7 @@ trace_i386_insn (const char *name, uint8
43 case 5: /* push/pop general register. */
49 @@ -1601,6 +1608,7 @@ trace_i386_insn (const char *name, uint8
57 @@ -1620,10 +1628,12 @@ trace_i386_insn (const char *name, uint8
58 case 8: /* push immediate */
63 case 10: /* push 8-bit immediate */
68 case 9: /* imul immediate */
70 @@ -1653,8 +1663,22 @@ trace_i386_insn (const char *name, uint8
74 + if (op == 0x81 || op == 0x83) {
76 + op = ptr[insn_size];
77 + switch ((op >> 3) & 7) {
80 + is_stack = (op & 7) == 4;
85 - /* else test, xchg, mov, lea or pop general. */
86 + else if ((op & 0xf) == 0xf) {
90 + /* else test, xchg, mov, lea. */
94 @@ -1904,6 +1928,9 @@ trace_i386_insn (const char *name, uint8
96 flags[insn] |= FLAG_EXIT;
99 + flags[insn] |= FLAG_STACK;
101 if (!(is_jmp || is_ret || is_exit))
102 flags[insn + insn_size] |= FLAG_INSN;
104 @@ -1924,6 +1951,7 @@ static int trace_i386_op(const char * na
108 + int stack_clobbered;
111 flags = malloc(len + 1);
112 @@ -1947,6 +1975,7 @@ static int trace_i386_op(const char * na
116 + stack_clobbered = 0;
117 for (insn = 0; insn < len; insn++) {
118 if (flags[insn] & FLAG_RET) {
119 /* ??? In theory it should be possible to handle multiple return
120 @@ -1956,6 +1985,8 @@ static int trace_i386_op(const char * na
123 if (flags[insn] & FLAG_EXIT) {
124 + if (stack_clobbered)
125 + error("Stack clobbered in %s", name);
126 if (num_exits == MAX_EXITS)
127 error("Too many block exits in %s", name);
128 exit_addrs[num_exits] = insn;
129 @@ -1963,6 +1994,8 @@ static int trace_i386_op(const char * na
131 if (flags[insn] & FLAG_INSN)
133 + if (flags[insn] & FLAG_STACK)
134 + stack_clobbered = 1;
137 exit_addrs[num_exits] = -1;