summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorblueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162>2007-12-11 19:35:45 +0000
committerblueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162>2007-12-11 19:35:45 +0000
commitd07bde88a52bf293c3f8846cfd162e0a57e1557c (patch)
tree7208f959405bab8a90da93dd175e2ff5161760ed
parent52df269ca821e8bed49ae2d46fe67486f3ef88de (diff)
downloadqemu-d07bde88a52bf293c3f8846cfd162e0a57e1557c.tar.gz
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.c2
-rw-r--r--exec-all.h4
-rw-r--r--exec.c4
-rw-r--r--translate-all.c17
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
diff --git a/exec.c b/exec.c
index 3fe340ae74..fd08ec9278 100644
--- a/exec.c
+++ b/exec.c
@@ -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;