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
This commit is contained in:
		
							parent
							
								
									41df841110
								
							
						
					
					
						commit
						2ba1eeb62c
					
				
							
								
								
									
										39
									
								
								tcg/tcg.c
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								tcg/tcg.c
									
									
									
									
									
								
							| @ -97,6 +97,9 @@ void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type, | ||||
| 
 | ||||
|     l = &s->labels[label_index]; | ||||
|     if (l->has_value) { | ||||
|         /* FIXME: This is wrong.  We can not resolve the relocation
 | ||||
|            immediately because the caller has not yet written the | ||||
|            initial value.  */ | ||||
|         patch_reloc(code_ptr, type, l->u.value + addend); | ||||
|     } else { | ||||
|         /* add a new relocation entry */ | ||||
| @ -1649,8 +1652,7 @@ void dump_op_count(void) | ||||
| 
 | ||||
| 
 | ||||
| static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf, | ||||
|                                       int do_search_pc, | ||||
|                                       const uint8_t *searched_pc) | ||||
|                                       long search_pc) | ||||
| { | ||||
|     int opc, op_index, macro_op_index; | ||||
|     const TCGOpDef *def; | ||||
| @ -1754,7 +1756,7 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf, | ||||
|             } | ||||
| #endif | ||||
|             tcg_reg_alloc_bb_end(s); | ||||
|             if (do_search_pc) { | ||||
|             if (search_pc >= 0) { | ||||
|                 s->code_ptr += def->copy_size; | ||||
|                 args += def->nb_args; | ||||
|             } else { | ||||
| @ -1771,13 +1773,11 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf, | ||||
|         } | ||||
|         args += def->nb_args; | ||||
|     next: ; | ||||
|         if (do_search_pc) { | ||||
|             if (searched_pc < s->code_ptr) { | ||||
|                 if (macro_op_index >= 0) | ||||
|                     return macro_op_index; | ||||
|                 else | ||||
|                     return op_index; | ||||
|             } | ||||
|         if (search_pc >= 0 && search_pc < s->code_ptr - gen_code_buf) { | ||||
|             if (macro_op_index >= 0) | ||||
|                 return macro_op_index; | ||||
|             else | ||||
|                 return op_index; | ||||
|         } | ||||
|         op_index++; | ||||
| #ifndef NDEBUG | ||||
| @ -1802,7 +1802,7 @@ int dyngen_code(TCGContext *s, uint8_t *gen_code_buf) | ||||
|     } | ||||
| #endif | ||||
| 
 | ||||
|     tcg_gen_code_common(s, gen_code_buf, 0, NULL); | ||||
|     tcg_gen_code_common(s, gen_code_buf, -1); | ||||
| 
 | ||||
|     /* flush instruction cache */ | ||||
|     flush_icache_range((unsigned long)gen_code_buf,  | ||||
| @ -1810,11 +1810,16 @@ int dyngen_code(TCGContext *s, uint8_t *gen_code_buf) | ||||
|     return s->code_ptr -  gen_code_buf; | ||||
| } | ||||
| 
 | ||||
| /* return the index of the micro operation such as the pc after is <
 | ||||
|    search_pc. Note: gen_code_buf is accessed during the operation, but | ||||
|    its content should not be modified. Return -1 if not found. */ | ||||
| int dyngen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, | ||||
|                           const uint8_t *searched_pc) | ||||
| static uint8_t *dummy_code_buf; | ||||
| 
 | ||||
| /* Return the index of the micro operation such as the pc after is <
 | ||||
|    offset bytes from the start of the TB. | ||||
|    We have to use a dummy code buffer here to avoid clobbering the | ||||
|    oringinal code.  Because we terminate code generation part way through | ||||
|    we can end up with unresolved relocations.  Return -1 if not found. */ | ||||
| int dyngen_code_search_pc(TCGContext *s, long offset) | ||||
| { | ||||
|     return tcg_gen_code_common(s, gen_code_buf, 1, searched_pc); | ||||
|     if (!dummy_code_buf) | ||||
|         dummy_code_buf = qemu_malloc(code_gen_max_block_size()); | ||||
|     return tcg_gen_code_common(s, dummy_code_buf, offset); | ||||
| } | ||||
|  | ||||
| @ -257,8 +257,7 @@ void tcg_context_init(TCGContext *s); | ||||
| void tcg_func_start(TCGContext *s); | ||||
| 
 | ||||
| int dyngen_code(TCGContext *s, uint8_t *gen_code_buf); | ||||
| int dyngen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, | ||||
|                           const uint8_t *searched_pc); | ||||
| int dyngen_code_search_pc(TCGContext *s, long offset); | ||||
| 
 | ||||
| void tcg_set_frame(TCGContext *s, int reg, | ||||
|                    tcg_target_long start, tcg_target_long size); | ||||
|  | ||||
| @ -187,8 +187,7 @@ int cpu_restore_state(TranslationBlock *tb, | ||||
|     s->tb_jmp_offset = NULL; | ||||
|     s->tb_next = tb->tb_next; | ||||
| #endif | ||||
|     j = dyngen_code_search_pc(s, (uint8_t *)tc_ptr,  | ||||
|                               (void *)searched_pc);  | ||||
|     j = dyngen_code_search_pc(s, searched_pc - tc_ptr); | ||||
|     if (j < 0) | ||||
|         return -1; | ||||
|     /* now find start of instruction before */ | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 pbrook
						pbrook