Commit d07bde88a52bf293c3f8846cfd162e0a57e1557c
1 parent
52df269c
Fix code generation buffer overflow reported by TeLeMan
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3805 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
20 additions
and
7 deletions
cpu-exec.c
| @@ -133,7 +133,7 @@ static TranslationBlock *tb_find_slow(target_ulong pc, | @@ -133,7 +133,7 @@ static TranslationBlock *tb_find_slow(target_ulong pc, | ||
| 133 | tb->tc_ptr = tc_ptr; | 133 | tb->tc_ptr = tc_ptr; |
| 134 | tb->cs_base = cs_base; | 134 | tb->cs_base = cs_base; |
| 135 | tb->flags = flags; | 135 | tb->flags = flags; |
| 136 | - cpu_gen_code(env, tb, CODE_GEN_MAX_SIZE, &code_gen_size); | 136 | + cpu_gen_code(env, tb, &code_gen_size); |
| 137 | code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1)); | 137 | code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1)); |
| 138 | 138 | ||
| 139 | /* check next page if needed */ | 139 | /* check next page if needed */ |
exec-all.h
| @@ -64,8 +64,9 @@ extern int loglevel; | @@ -64,8 +64,9 @@ extern int loglevel; | ||
| 64 | int gen_intermediate_code(CPUState *env, struct TranslationBlock *tb); | 64 | int gen_intermediate_code(CPUState *env, struct TranslationBlock *tb); |
| 65 | int gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb); | 65 | int gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb); |
| 66 | void dump_ops(const uint16_t *opc_buf, const uint32_t *opparam_buf); | 66 | void dump_ops(const uint16_t *opc_buf, const uint32_t *opparam_buf); |
| 67 | +unsigned long code_gen_max_block_size(void); | ||
| 67 | int cpu_gen_code(CPUState *env, struct TranslationBlock *tb, | 68 | int cpu_gen_code(CPUState *env, struct TranslationBlock *tb, |
| 68 | - int max_code_size, int *gen_code_size_ptr); | 69 | + int *gen_code_size_ptr); |
| 69 | int cpu_restore_state(struct TranslationBlock *tb, | 70 | int cpu_restore_state(struct TranslationBlock *tb, |
| 70 | CPUState *env, unsigned long searched_pc, | 71 | CPUState *env, unsigned long searched_pc, |
| 71 | void *puc); | 72 | void *puc); |
| @@ -94,7 +95,6 @@ static inline int tlb_set_page(CPUState *env, target_ulong vaddr, | @@ -94,7 +95,6 @@ static inline int tlb_set_page(CPUState *env, target_ulong vaddr, | ||
| 94 | return tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu); | 95 | return tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu); |
| 95 | } | 96 | } |
| 96 | 97 | ||
| 97 | -#define CODE_GEN_MAX_SIZE 65536 | ||
| 98 | #define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */ | 98 | #define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */ |
| 99 | 99 | ||
| 100 | #define CODE_GEN_PHYS_HASH_BITS 15 | 100 | #define CODE_GEN_PHYS_HASH_BITS 15 |
exec.c
| @@ -56,7 +56,7 @@ | @@ -56,7 +56,7 @@ | ||
| 56 | #endif | 56 | #endif |
| 57 | 57 | ||
| 58 | /* threshold to flush the translated code buffer */ | 58 | /* threshold to flush the translated code buffer */ |
| 59 | -#define CODE_GEN_BUFFER_MAX_SIZE (CODE_GEN_BUFFER_SIZE - CODE_GEN_MAX_SIZE) | 59 | +#define CODE_GEN_BUFFER_MAX_SIZE (CODE_GEN_BUFFER_SIZE - code_gen_max_block_size()) |
| 60 | 60 | ||
| 61 | #define SMC_BITMAP_USE_THRESHOLD 10 | 61 | #define SMC_BITMAP_USE_THRESHOLD 10 |
| 62 | 62 | ||
| @@ -622,7 +622,7 @@ static void tb_gen_code(CPUState *env, | @@ -622,7 +622,7 @@ static void tb_gen_code(CPUState *env, | ||
| 622 | tb->cs_base = cs_base; | 622 | tb->cs_base = cs_base; |
| 623 | tb->flags = flags; | 623 | tb->flags = flags; |
| 624 | tb->cflags = cflags; | 624 | tb->cflags = cflags; |
| 625 | - cpu_gen_code(env, tb, CODE_GEN_MAX_SIZE, &code_gen_size); | 625 | + cpu_gen_code(env, tb, &code_gen_size); |
| 626 | code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1)); | 626 | code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1)); |
| 627 | 627 | ||
| 628 | /* check next page if needed */ | 628 | /* check next page if needed */ |
translate-all.c
| @@ -132,14 +132,27 @@ static void dyngen_labels(long *gen_labels, int nb_gen_labels, | @@ -132,14 +132,27 @@ static void dyngen_labels(long *gen_labels, int nb_gen_labels, | ||
| 132 | } | 132 | } |
| 133 | } | 133 | } |
| 134 | 134 | ||
| 135 | +unsigned long code_gen_max_block_size(void) | ||
| 136 | +{ | ||
| 137 | + static unsigned long max; | ||
| 138 | + | ||
| 139 | + if (max == 0) { | ||
| 140 | +#define DEF(s, n, copy_size) max = copy_size > max? copy_size : max; | ||
| 141 | +#include "opc.h" | ||
| 142 | +#undef DEF | ||
| 143 | + max *= OPC_MAX_SIZE; | ||
| 144 | + } | ||
| 145 | + | ||
| 146 | + return max; | ||
| 147 | +} | ||
| 148 | + | ||
| 135 | /* return non zero if the very first instruction is invalid so that | 149 | /* return non zero if the very first instruction is invalid so that |
| 136 | the virtual CPU can trigger an exception. | 150 | the virtual CPU can trigger an exception. |
| 137 | 151 | ||
| 138 | '*gen_code_size_ptr' contains the size of the generated code (host | 152 | '*gen_code_size_ptr' contains the size of the generated code (host |
| 139 | code). | 153 | code). |
| 140 | */ | 154 | */ |
| 141 | -int cpu_gen_code(CPUState *env, TranslationBlock *tb, | ||
| 142 | - int max_code_size, int *gen_code_size_ptr) | 155 | +int cpu_gen_code(CPUState *env, TranslationBlock *tb, int *gen_code_size_ptr) |
| 143 | { | 156 | { |
| 144 | uint8_t *gen_code_buf; | 157 | uint8_t *gen_code_buf; |
| 145 | int gen_code_size; | 158 | int gen_code_size; |