]> git.pld-linux.org Git - packages/qemu.git/blob - qemu-0.7.2-dyngen-check-stack-clobbers.patch
- gcc 3.4 segfault for mips
[packages/qemu.git] / qemu-0.7.2-dyngen-check-stack-clobbers.patch
1 2005-11-11  Gwenole Beauchesne  <gbeauchesne@mandriva.com>
2
3         * Check for stack clobbers in functions using GOTO_LABEL_PARAM().
4
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)
14  #define MAX_EXITS     5
15  
16  static void
17 @@ -1454,6 +1457,7 @@ trace_i386_insn (const char *name, uint8
18      int is_jmp;
19      int is_exit;
20      int is_pcrel;
21 +    int is_stack;
22      int immed;
23      int seen_rexw;
24      int32_t disp;
25 @@ -1476,6 +1480,7 @@ trace_i386_insn (const char *name, uint8
26      is_exit = 0;
27      seen_rexw = 0;
28      is_pcrel = 0;
29 +    is_stack = 0;
30  
31      while (is_prefix) {
32          op = ptr[insn_size];
33 @@ -1522,6 +1527,7 @@ trace_i386_insn (const char *name, uint8
34                      switch (op & 0x7) {
35                      case 0: /* push fs/gs */
36                      case 1: /* pop fs/gs */
37 +                        is_stack = 1;
38                      case 2: /* cpuid/rsm */
39                          modrm = 0;
40                          break;
41 @@ -1594,6 +1600,7 @@ trace_i386_insn (const char *name, uint8
42  #endif
43          case 5: /* push/pop general register.  */
44              modrm = 0;
45 +            is_stack = 1;
46              break;
47  
48          case 6:
49 @@ -1601,6 +1608,7 @@ trace_i386_insn (const char *name, uint8
50              case 0: /* pusha */
51              case 1: /* popa */
52                  modrm = 0;
53 +                is_stack = 1;
54                  break;
55              case 2: /* bound */
56              case 3: /* arpl */
57 @@ -1620,10 +1628,12 @@ trace_i386_insn (const char *name, uint8
58              case 8: /* push immediate */
59                  immed = op_size;
60                  modrm = 0;
61 +                is_stack = 1;
62                  break;
63              case 10: /* push 8-bit immediate */
64                  immed = 1;
65                  modrm = 0;
66 +                is_stack = 1;
67                  break;
68              case 9: /* imul immediate */
69                  immed = op_size;
70 @@ -1653,8 +1663,22 @@ trace_i386_insn (const char *name, uint8
71                      immed = op_size;
72                  else
73                      immed = 1;
74 +                if (op == 0x81 || op == 0x83) {
75 +                    /* add, sub */
76 +                    op = ptr[insn_size];
77 +                    switch ((op >> 3) & 7) {
78 +                    case 0:
79 +                    case 5:
80 +                        is_stack = (op & 7) == 4;
81 +                        break;
82 +                    }
83 +                }
84              }
85 -            /* else test, xchg, mov, lea or pop general.  */
86 +            else if ((op & 0xf) == 0xf) {
87 +                /* pop general.  */
88 +                is_stack = 1;
89 +            }
90 +            /* else test, xchg, mov, lea.  */
91              break;
92  
93          case 9:
94 @@ -1904,6 +1928,9 @@ trace_i386_insn (const char *name, uint8
95      if (is_exit)
96        flags[insn] |= FLAG_EXIT;
97  
98 +    if (is_stack)
99 +      flags[insn] |= FLAG_STACK;
100 +
101      if (!(is_jmp || is_ret || is_exit))
102        flags[insn + insn_size] |= FLAG_INSN;
103  }
104 @@ -1924,6 +1951,7 @@ static int trace_i386_op(const char * na
105      int num_exits;
106      int len;
107      int last_insn;
108 +    int stack_clobbered;
109  
110      len = *plen;
111      flags = malloc(len + 1);
112 @@ -1947,6 +1975,7 @@ static int trace_i386_op(const char * na
113      retpos = -1;
114      num_exits = 0;
115      last_insn = 0;
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
121              retpos = insn;
122          }
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
130          }
131          if (flags[insn] & FLAG_INSN)
132              last_insn = insn;
133 +        if (flags[insn] & FLAG_STACK)
134 +            stack_clobbered = 1;
135      }
136  
137      exit_addrs[num_exits] = -1;
This page took 0.046486 seconds and 3 git commands to generate.