Commit 2ba1eeb62c29d23238b95dc7e9ade3444b49f0a1

Authored by pbrook
1 parent 41df8411

Fix TCG relocation bug (exposed by fault after brcond op). Add FIXME for

annother potential bug.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3968 c046a42c-6fe2-441c-8c8c-71466251a162
tcg/tcg.c
@@ -97,6 +97,9 @@ void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type, @@ -97,6 +97,9 @@ void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type,
97 97
98 l = &s->labels[label_index]; 98 l = &s->labels[label_index];
99 if (l->has_value) { 99 if (l->has_value) {
  100 + /* FIXME: This is wrong. We can not resolve the relocation
  101 + immediately because the caller has not yet written the
  102 + initial value. */
100 patch_reloc(code_ptr, type, l->u.value + addend); 103 patch_reloc(code_ptr, type, l->u.value + addend);
101 } else { 104 } else {
102 /* add a new relocation entry */ 105 /* add a new relocation entry */
@@ -1649,8 +1652,7 @@ void dump_op_count(void) @@ -1649,8 +1652,7 @@ void dump_op_count(void)
1649 1652
1650 1653
1651 static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf, 1654 static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
1652 - int do_search_pc,  
1653 - const uint8_t *searched_pc) 1655 + long search_pc)
1654 { 1656 {
1655 int opc, op_index, macro_op_index; 1657 int opc, op_index, macro_op_index;
1656 const TCGOpDef *def; 1658 const TCGOpDef *def;
@@ -1754,7 +1756,7 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf, @@ -1754,7 +1756,7 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
1754 } 1756 }
1755 #endif 1757 #endif
1756 tcg_reg_alloc_bb_end(s); 1758 tcg_reg_alloc_bb_end(s);
1757 - if (do_search_pc) { 1759 + if (search_pc >= 0) {
1758 s->code_ptr += def->copy_size; 1760 s->code_ptr += def->copy_size;
1759 args += def->nb_args; 1761 args += def->nb_args;
1760 } else { 1762 } else {
@@ -1771,13 +1773,11 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf, @@ -1771,13 +1773,11 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
1771 } 1773 }
1772 args += def->nb_args; 1774 args += def->nb_args;
1773 next: ; 1775 next: ;
1774 - if (do_search_pc) {  
1775 - if (searched_pc < s->code_ptr) {  
1776 - if (macro_op_index >= 0)  
1777 - return macro_op_index;  
1778 - else  
1779 - return op_index;  
1780 - } 1776 + if (search_pc >= 0 && search_pc < s->code_ptr - gen_code_buf) {
  1777 + if (macro_op_index >= 0)
  1778 + return macro_op_index;
  1779 + else
  1780 + return op_index;
1781 } 1781 }
1782 op_index++; 1782 op_index++;
1783 #ifndef NDEBUG 1783 #ifndef NDEBUG
@@ -1802,7 +1802,7 @@ int dyngen_code(TCGContext *s, uint8_t *gen_code_buf) @@ -1802,7 +1802,7 @@ int dyngen_code(TCGContext *s, uint8_t *gen_code_buf)
1802 } 1802 }
1803 #endif 1803 #endif
1804 1804
1805 - tcg_gen_code_common(s, gen_code_buf, 0, NULL); 1805 + tcg_gen_code_common(s, gen_code_buf, -1);
1806 1806
1807 /* flush instruction cache */ 1807 /* flush instruction cache */
1808 flush_icache_range((unsigned long)gen_code_buf, 1808 flush_icache_range((unsigned long)gen_code_buf,
@@ -1810,11 +1810,16 @@ int dyngen_code(TCGContext *s, uint8_t *gen_code_buf) @@ -1810,11 +1810,16 @@ int dyngen_code(TCGContext *s, uint8_t *gen_code_buf)
1810 return s->code_ptr - gen_code_buf; 1810 return s->code_ptr - gen_code_buf;
1811 } 1811 }
1812 1812
1813 -/* return the index of the micro operation such as the pc after is <  
1814 - search_pc. Note: gen_code_buf is accessed during the operation, but  
1815 - its content should not be modified. Return -1 if not found. */  
1816 -int dyngen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf,  
1817 - const uint8_t *searched_pc) 1813 +static uint8_t *dummy_code_buf;
  1814 +
  1815 +/* Return the index of the micro operation such as the pc after is <
  1816 + offset bytes from the start of the TB.
  1817 + We have to use a dummy code buffer here to avoid clobbering the
  1818 + oringinal code. Because we terminate code generation part way through
  1819 + we can end up with unresolved relocations. Return -1 if not found. */
  1820 +int dyngen_code_search_pc(TCGContext *s, long offset)
1818 { 1821 {
1819 - return tcg_gen_code_common(s, gen_code_buf, 1, searched_pc); 1822 + if (!dummy_code_buf)
  1823 + dummy_code_buf = qemu_malloc(code_gen_max_block_size());
  1824 + return tcg_gen_code_common(s, dummy_code_buf, offset);
1820 } 1825 }
tcg/tcg.h
@@ -257,8 +257,7 @@ void tcg_context_init(TCGContext *s); @@ -257,8 +257,7 @@ void tcg_context_init(TCGContext *s);
257 void tcg_func_start(TCGContext *s); 257 void tcg_func_start(TCGContext *s);
258 258
259 int dyngen_code(TCGContext *s, uint8_t *gen_code_buf); 259 int dyngen_code(TCGContext *s, uint8_t *gen_code_buf);
260 -int dyngen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf,  
261 - const uint8_t *searched_pc); 260 +int dyngen_code_search_pc(TCGContext *s, long offset);
262 261
263 void tcg_set_frame(TCGContext *s, int reg, 262 void tcg_set_frame(TCGContext *s, int reg,
264 tcg_target_long start, tcg_target_long size); 263 tcg_target_long start, tcg_target_long size);
translate-all.c
@@ -187,8 +187,7 @@ int cpu_restore_state(TranslationBlock *tb, @@ -187,8 +187,7 @@ int cpu_restore_state(TranslationBlock *tb,
187 s->tb_jmp_offset = NULL; 187 s->tb_jmp_offset = NULL;
188 s->tb_next = tb->tb_next; 188 s->tb_next = tb->tb_next;
189 #endif 189 #endif
190 - j = dyngen_code_search_pc(s, (uint8_t *)tc_ptr,  
191 - (void *)searched_pc); 190 + j = dyngen_code_search_pc(s, searched_pc - tc_ptr);
192 if (j < 0) 191 if (j < 0)
193 return -1; 192 return -1;
194 /* now find start of instruction before */ 193 /* now find start of instruction before */