On 13 February 2011 17:14, felix.matenaar@rwth-aachen <felix.maten...@rwth-aachen.de> wrote: > To be more specific on my env update problem, here an example: > > push ebp > mv esp,ebp > /* do something */ > call 0xfoo > test eax,eax > /* do something */ > ret > > The first line is the start of a block. What I did was adding a > gen_helper_instrument_call in the 'call' opcode cases in disas_insn() > which will call my analysis code to examine from where the call is > launched, where it will go and what is the address we will return to > after (in this case regarding to call 0xfoo). > Because in this case, usage of tcg_const_i32(pc_start) and providing > CPU_T[0] as parameters to my generated helper, I can provide all three > values. But what I would _assume_ is that after > gen_helper_instrument_call is executed, env->eip would point towards > 'call 0xfoo', but it points to 'push ebp'.
Ah, you should have said you were talking about EIP; you've hit an optimisation case. If we updated env->eip after every instruction then this would slow things down. Instead, since we know what the value is statically at translate time, we can just use that calculated value mostly. We only update env->eip: * at the end of the TB * when we translate jump commands (usually ends the TB) * when we translate something that will raise an exception or some other thing we know will need an accurate env->eip Unexpected interrupts (typically faults on load/store) are handled by constructing a mapping from host PC to guest PC and then looking up the host fault address in it and resetting env->eip (in gen_pc_load()). Which registers are dealt with like this varies from target to target; on target-arm we do this for both r15 (pc) and the IT state bits in the CPSR, for instance. The other case to watch out for is where the value of some register is kept in env, but as a broken out set of components which are only reassembled into the actual register value when the target needs to read it; see for example the comment in target-i386/cpu.h about env->eflags. If the registers you care about aren't in either of these categories you should be able to trust them in a helper fn. This typically includes most of the general purpose registers. -- PMM