diff options
author | blueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-12-11 19:35:45 +0000 |
---|---|---|
committer | blueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-12-11 19:35:45 +0000 |
commit | d07bde88a52bf293c3f8846cfd162e0a57e1557c (patch) | |
tree | 7208f959405bab8a90da93dd175e2ff5161760ed | |
parent | 52df269ca821e8bed49ae2d46fe67486f3ef88de (diff) | |
download | qemu-d07bde88a52bf293c3f8846cfd162e0a57e1557c.zip |
Fix code generation buffer overflow reported by TeLeMan
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3805 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r-- | cpu-exec.c | 2 | ||||
-rw-r--r-- | exec-all.h | 4 | ||||
-rw-r--r-- | exec.c | 4 | ||||
-rw-r--r-- | translate-all.c | 17 |
4 files changed, 20 insertions, 7 deletions
diff --git a/cpu-exec.c b/cpu-exec.c index 3629cacd7c..c92f1f7d72 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -133,7 +133,7 @@ static TranslationBlock *tb_find_slow(target_ulong pc, tb->tc_ptr = tc_ptr; tb->cs_base = cs_base; tb->flags = flags; - cpu_gen_code(env, tb, CODE_GEN_MAX_SIZE, &code_gen_size); + cpu_gen_code(env, tb, &code_gen_size); code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1)); /* check next page if needed */ diff --git a/exec-all.h b/exec-all.h index 285da99b51..e7c4806010 100644 --- a/exec-all.h +++ b/exec-all.h @@ -64,8 +64,9 @@ extern int loglevel; int gen_intermediate_code(CPUState *env, struct TranslationBlock *tb); int gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb); void dump_ops(const uint16_t *opc_buf, const uint32_t *opparam_buf); +unsigned long code_gen_max_block_size(void); int cpu_gen_code(CPUState *env, struct TranslationBlock *tb, - int max_code_size, int *gen_code_size_ptr); + int *gen_code_size_ptr); int cpu_restore_state(struct TranslationBlock *tb, CPUState *env, unsigned long searched_pc, void *puc); @@ -94,7 +95,6 @@ static inline int tlb_set_page(CPUState *env, target_ulong vaddr, return tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu); } -#define CODE_GEN_MAX_SIZE 65536 #define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */ #define CODE_GEN_PHYS_HASH_BITS 15 @@ -56,7 +56,7 @@ #endif /* threshold to flush the translated code buffer */ -#define CODE_GEN_BUFFER_MAX_SIZE (CODE_GEN_BUFFER_SIZE - CODE_GEN_MAX_SIZE) +#define CODE_GEN_BUFFER_MAX_SIZE (CODE_GEN_BUFFER_SIZE - code_gen_max_block_size()) #define SMC_BITMAP_USE_THRESHOLD 10 @@ -622,7 +622,7 @@ static void tb_gen_code(CPUState *env, tb->cs_base = cs_base; tb->flags = flags; tb->cflags = cflags; - cpu_gen_code(env, tb, CODE_GEN_MAX_SIZE, &code_gen_size); + cpu_gen_code(env, tb, &code_gen_size); code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1)); /* check next page if needed */ diff --git a/translate-all.c b/translate-all.c index f4944c06c2..d8b91023e6 100644 --- a/translate-all.c +++ b/translate-all.c @@ -132,14 +132,27 @@ static void dyngen_labels(long *gen_labels, int nb_gen_labels, } } +unsigned long code_gen_max_block_size(void) +{ + static unsigned long max; + + if (max == 0) { +#define DEF(s, n, copy_size) max = copy_size > max? copy_size : max; +#include "opc.h" +#undef DEF + max *= OPC_MAX_SIZE; + } + + return max; +} + /* return non zero if the very first instruction is invalid so that the virtual CPU can trigger an exception. '*gen_code_size_ptr' contains the size of the generated code (host code). */ -int cpu_gen_code(CPUState *env, TranslationBlock *tb, - int max_code_size, int *gen_code_size_ptr) +int cpu_gen_code(CPUState *env, TranslationBlock *tb, int *gen_code_size_ptr) { uint8_t *gen_code_buf; int gen_code_size; |