VirtualBox

Changeset 97441 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Nov 8, 2022 12:07:49 AM (2 years ago)
Author:
vboxsync
Message:

VMM/IEM: Single stepping for short and near jumps (relative) and corrected o16 prefix behaviour on intel CPUs in 64-bit mode (ignored). Also, #DB seems to implicitly clear, or at least not set, the resume flag (RF). bugref:9898

Location:
trunk/src/VBox/VMM
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAll.cpp

    r97406 r97441  
    39273927VBOXSTRICTRC iemRaiseDebugException(PVMCPUCC pVCpu) RT_NOEXCEPT
    39283928{
    3929     /** @todo set/clear RF. */
     3929    /* This always clears RF (via IEM_XCPT_FLAGS_DRx_INSTR_BP). */
    39303930    pVCpu->cpum.GstCtx.dr[7] &= ~X86_DR7_GD;
    3931     return iemRaiseXcptOrInt(pVCpu, 0, X86_XCPT_DB, IEM_XCPT_FLAGS_T_CPU_XCPT, 0, 0);
     3931    return iemRaiseXcptOrInt(pVCpu, 0, X86_XCPT_DB, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_DRx_INSTR_BP, 0, 0);
    39323932}
    39333933
     
    42914291 *
    42924292 * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
     4293 * @param   cbInstr             Instruction size.
    42934294 * @param   offNextInstr        The offset of the next instruction.
    4294  */
    4295 VBOXSTRICTRC iemRegRipRelativeJumpS8(PVMCPUCC pVCpu, int8_t offNextInstr) RT_NOEXCEPT
    4296 {
    4297     switch (pVCpu->iem.s.enmEffOpSize)
     4295 * @param   enmEffOpSize        Effective operand size.
     4296 */
     4297VBOXSTRICTRC iemRegRipRelativeJumpS8AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int8_t offNextInstr,
     4298                                                        IEMMODE enmEffOpSize) RT_NOEXCEPT
     4299{
     4300    switch (enmEffOpSize)
    42984301    {
    42994302        case IEMMODE_16BIT:
    43004303        {
    4301             uint16_t uNewIp = pVCpu->cpum.GstCtx.ip + offNextInstr + IEM_GET_INSTR_LEN(pVCpu);
    4302             if (   uNewIp > pVCpu->cpum.GstCtx.cs.u32Limit
    4303                 && pVCpu->iem.s.enmCpuMode != IEMMODE_64BIT) /* no need to check for non-canonical. */
     4304            uint16_t const uNewIp = pVCpu->cpum.GstCtx.ip + cbInstr + (int16_t)offNextInstr;
     4305            if (RT_LIKELY(   uNewIp <= pVCpu->cpum.GstCtx.cs.u32Limit
     4306                          || pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT /* no CS limit checks in 64-bit mode */))
     4307                pVCpu->cpum.GstCtx.rip = uNewIp;
     4308            else
    43044309                return iemRaiseGeneralProtectionFault0(pVCpu);
    4305             pVCpu->cpum.GstCtx.rip = uNewIp;
    43064310            break;
    43074311        }
     
    43094313        case IEMMODE_32BIT:
    43104314        {
     4315            Assert(pVCpu->iem.s.enmCpuMode != IEMMODE_64BIT);
    43114316            Assert(pVCpu->cpum.GstCtx.rip <= UINT32_MAX);
    4312             Assert(pVCpu->iem.s.enmCpuMode != IEMMODE_64BIT);
    4313 
    4314             uint32_t uNewEip = pVCpu->cpum.GstCtx.eip + offNextInstr + IEM_GET_INSTR_LEN(pVCpu);
    4315             if (uNewEip > pVCpu->cpum.GstCtx.cs.u32Limit)
     4317
     4318            uint32_t const uNewEip = pVCpu->cpum.GstCtx.eip + cbInstr + (int32_t)offNextInstr;
     4319            if (RT_LIKELY(uNewEip <= pVCpu->cpum.GstCtx.cs.u32Limit))
     4320                pVCpu->cpum.GstCtx.rip = uNewEip;
     4321            else
    43164322                return iemRaiseGeneralProtectionFault0(pVCpu);
    4317             pVCpu->cpum.GstCtx.rip = uNewEip;
    43184323            break;
    43194324        }
     
    43234328            Assert(pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT);
    43244329
    4325             uint64_t uNewRip = pVCpu->cpum.GstCtx.rip + offNextInstr + IEM_GET_INSTR_LEN(pVCpu);
    4326             if (!IEM_IS_CANONICAL(uNewRip))
     4330            uint64_t const uNewRip = pVCpu->cpum.GstCtx.rip + cbInstr + (int64_t)offNextInstr;
     4331            if (RT_LIKELY(IEM_IS_CANONICAL(uNewRip)))
     4332                pVCpu->cpum.GstCtx.rip = uNewRip;
     4333            else
    43274334                return iemRaiseGeneralProtectionFault0(pVCpu);
    4328             pVCpu->cpum.GstCtx.rip = uNewRip;
    43294335            break;
    43304336        }
     
    43334339    }
    43344340
    4335     pVCpu->cpum.GstCtx.eflags.Bits.u1RF = 0;
     4341#ifndef IEM_WITH_CODE_TLB
     4342    /* Flush the prefetch buffer. */
     4343    pVCpu->iem.s.cbOpcode = cbInstr;
     4344#endif
     4345
     4346    /*
     4347     * Clear RF and finish the instruction (maybe raise #DB).
     4348     */
     4349    return iemRegFinishClearingRF(pVCpu);
     4350}
     4351
     4352
     4353/**
     4354 * Adds a 16-bit signed jump offset to RIP/EIP/IP.
     4355 *
     4356 * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
     4357 * segment limit.
     4358 *
     4359 * @returns Strict VBox status code.
     4360 * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
     4361 * @param   cbInstr             Instruction size.
     4362 * @param   offNextInstr        The offset of the next instruction.
     4363 */
     4364VBOXSTRICTRC iemRegRipRelativeJumpS16AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int16_t offNextInstr) RT_NOEXCEPT
     4365{
     4366    Assert(pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT);
     4367
     4368    uint16_t const uNewIp = pVCpu->cpum.GstCtx.ip + cbInstr + offNextInstr;
     4369    if (RT_LIKELY(   uNewIp <= pVCpu->cpum.GstCtx.cs.u32Limit
     4370                  || pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT /* no limit checking in 64-bit mode */))
     4371        pVCpu->cpum.GstCtx.rip = uNewIp;
     4372    else
     4373        return iemRaiseGeneralProtectionFault0(pVCpu);
    43364374
    43374375#ifndef IEM_WITH_CODE_TLB
     
    43404378#endif
    43414379
    4342     return VINF_SUCCESS;
    4343 }
    4344 
    4345 
    4346 /**
    4347  * Adds a 16-bit signed jump offset to RIP/EIP/IP.
     4380    /*
     4381     * Clear RF and finish the instruction (maybe raise #DB).
     4382     */
     4383    return iemRegFinishClearingRF(pVCpu);
     4384}
     4385
     4386
     4387/**
     4388 * Adds a 32-bit signed jump offset to RIP/EIP/IP.
    43484389 *
    43494390 * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
     
    43544395 * @param   offNextInstr        The offset of the next instruction.
    43554396 */
    4356 VBOXSTRICTRC iemRegRipRelativeJumpS16(PVMCPUCC pVCpu, int16_t offNextInstr) RT_NOEXCEPT
    4357 {
    4358     Assert(pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT);
    4359 
    4360     uint16_t uNewIp = pVCpu->cpum.GstCtx.ip + offNextInstr + IEM_GET_INSTR_LEN(pVCpu);
    4361     if (   uNewIp > pVCpu->cpum.GstCtx.cs.u32Limit
    4362         && pVCpu->iem.s.enmCpuMode != IEMMODE_64BIT) /* no need to check for non-canonical. */
    4363         return iemRaiseGeneralProtectionFault0(pVCpu);
    4364     /** @todo Test 16-bit jump in 64-bit mode. possible?  */
    4365     pVCpu->cpum.GstCtx.rip = uNewIp;
    4366     pVCpu->cpum.GstCtx.eflags.Bits.u1RF = 0;
     4397VBOXSTRICTRC iemRegRipRelativeJumpS32AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int32_t offNextInstr,
     4398                                                         IEMMODE enmEffOpSize) RT_NOEXCEPT
     4399{
     4400    if (enmEffOpSize == IEMMODE_32BIT)
     4401    {
     4402        Assert(pVCpu->cpum.GstCtx.rip <= UINT32_MAX); Assert(pVCpu->iem.s.enmCpuMode != IEMMODE_64BIT);
     4403
     4404        uint32_t const uNewEip = pVCpu->cpum.GstCtx.eip + cbInstr + offNextInstr;
     4405        if (RT_LIKELY(uNewEip <= pVCpu->cpum.GstCtx.cs.u32Limit))
     4406            pVCpu->cpum.GstCtx.rip = uNewEip;
     4407        else
     4408            return iemRaiseGeneralProtectionFault0(pVCpu);
     4409    }
     4410    else
     4411    {
     4412        Assert(enmEffOpSize == IEMMODE_64BIT);
     4413
     4414        uint64_t const uNewRip = pVCpu->cpum.GstCtx.rip + cbInstr + (int64_t)offNextInstr;
     4415        if (RT_LIKELY(IEM_IS_CANONICAL(uNewRip)))
     4416            pVCpu->cpum.GstCtx.rip = uNewRip;
     4417        else
     4418            return iemRaiseGeneralProtectionFault0(pVCpu);
     4419    }
    43674420
    43684421#ifndef IEM_WITH_CODE_TLB
     
    43714424#endif
    43724425
    4373     return VINF_SUCCESS;
    4374 }
    4375 
    4376 
    4377 /**
    4378  * Adds a 32-bit signed jump offset to RIP/EIP/IP.
    4379  *
    4380  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    4381  * segment limit.
    4382  *
    4383  * @returns Strict VBox status code.
    4384  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4385  * @param   offNextInstr        The offset of the next instruction.
    4386  */
    4387 VBOXSTRICTRC iemRegRipRelativeJumpS32(PVMCPUCC pVCpu, int32_t offNextInstr) RT_NOEXCEPT
    4388 {
    4389     Assert(pVCpu->iem.s.enmEffOpSize != IEMMODE_16BIT);
    4390 
    4391     if (pVCpu->iem.s.enmEffOpSize == IEMMODE_32BIT)
    4392     {
    4393         Assert(pVCpu->cpum.GstCtx.rip <= UINT32_MAX); Assert(pVCpu->iem.s.enmCpuMode != IEMMODE_64BIT);
    4394 
    4395         uint32_t uNewEip = pVCpu->cpum.GstCtx.eip + offNextInstr + IEM_GET_INSTR_LEN(pVCpu);
    4396         if (uNewEip > pVCpu->cpum.GstCtx.cs.u32Limit)
    4397             return iemRaiseGeneralProtectionFault0(pVCpu);
    4398         pVCpu->cpum.GstCtx.rip = uNewEip;
    4399     }
    4400     else
    4401     {
    4402         Assert(pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT);
    4403 
    4404         uint64_t uNewRip = pVCpu->cpum.GstCtx.rip + offNextInstr + IEM_GET_INSTR_LEN(pVCpu);
    4405         if (!IEM_IS_CANONICAL(uNewRip))
    4406             return iemRaiseGeneralProtectionFault0(pVCpu);
    4407         pVCpu->cpum.GstCtx.rip = uNewRip;
    4408     }
    4409     pVCpu->cpum.GstCtx.eflags.Bits.u1RF = 0;
    4410 
    4411 #ifndef IEM_WITH_CODE_TLB
    4412     /* Flush the prefetch buffer. */
    4413     pVCpu->iem.s.cbOpcode = IEM_GET_INSTR_LEN(pVCpu);
    4414 #endif
    4415 
    4416     return VINF_SUCCESS;
     4426    /*
     4427     * Clear RF and finish the instruction (maybe raise #DB).
     4428     */
     4429    return iemRegFinishClearingRF(pVCpu);
    44174430}
    44184431
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsOneByte.cpp.h

    r97370 r97441  
    28002800    int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
    28012801    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    2802     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     2802    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    28032803
    28042804    IEM_MC_BEGIN(0, 0);
     
    28202820    int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
    28212821    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    2822     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     2822    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    28232823
    28242824    IEM_MC_BEGIN(0, 0);
     
    28392839    int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
    28402840    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    2841     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     2841    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    28422842
    28432843    IEM_MC_BEGIN(0, 0);
     
    28592859    int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
    28602860    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    2861     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     2861    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    28622862
    28632863    IEM_MC_BEGIN(0, 0);
     
    28792879    int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
    28802880    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    2881     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     2881    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    28822882
    28832883    IEM_MC_BEGIN(0, 0);
     
    28992899    int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
    29002900    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    2901     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     2901    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    29022902
    29032903    IEM_MC_BEGIN(0, 0);
     
    29192919    int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
    29202920    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    2921     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     2921    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    29222922
    29232923    IEM_MC_BEGIN(0, 0);
     
    29392939    int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
    29402940    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    2941     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     2941    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    29422942
    29432943    IEM_MC_BEGIN(0, 0);
     
    29592959    int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
    29602960    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    2961     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     2961    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    29622962
    29632963    IEM_MC_BEGIN(0, 0);
     
    29792979    int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
    29802980    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    2981     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     2981    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    29822982
    29832983    IEM_MC_BEGIN(0, 0);
     
    29992999    int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
    30003000    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    3001     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     3001    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    30023002
    30033003    IEM_MC_BEGIN(0, 0);
     
    30193019    int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
    30203020    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    3021     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     3021    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    30223022
    30233023    IEM_MC_BEGIN(0, 0);
     
    30393039    int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
    30403040    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    3041     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     3041    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    30423042
    30433043    IEM_MC_BEGIN(0, 0);
     
    30593059    int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
    30603060    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    3061     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     3061    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    30623062
    30633063    IEM_MC_BEGIN(0, 0);
     
    30793079    int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
    30803080    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    3081     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     3081    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    30823082
    30833083    IEM_MC_BEGIN(0, 0);
     
    30993099    int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
    31003100    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    3101     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     3101    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    31023102
    31033103    IEM_MC_BEGIN(0, 0);
     
    1050510505{
    1050610506    IEMOP_MNEMONIC(jmp_Jv, "jmp Jv");
    10507     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     10507    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    1050810508    switch (pVCpu->iem.s.enmEffOpSize)
    1050910509    {
     
    1056010560    int8_t i8Imm; IEM_OPCODE_GET_NEXT_S8(&i8Imm);
    1056110561    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    10562     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     10562    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    1056310563
    1056410564    IEM_MC_BEGIN(0, 0);
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsTwoByte0f.cpp.h

    r97361 r97441  
    76957695    IEMOP_MNEMONIC(jo_Jv, "jo  Jv");
    76967696    IEMOP_HLP_MIN_386();
    7697     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     7697    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    76987698    if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
    76997699    {
     
    77307730    IEMOP_MNEMONIC(jno_Jv, "jno Jv");
    77317731    IEMOP_HLP_MIN_386();
    7732     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     7732    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    77337733    if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
    77347734    {
     
    77657765    IEMOP_MNEMONIC(jc_Jv, "jc/jb/jnae Jv");
    77667766    IEMOP_HLP_MIN_386();
    7767     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     7767    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    77687768    if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
    77697769    {
     
    78007800    IEMOP_MNEMONIC(jnc_Jv, "jnc/jnb/jae Jv");
    78017801    IEMOP_HLP_MIN_386();
    7802     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     7802    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    78037803    if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
    78047804    {
     
    78357835    IEMOP_MNEMONIC(je_Jv, "je/jz Jv");
    78367836    IEMOP_HLP_MIN_386();
    7837     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     7837    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    78387838    if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
    78397839    {
     
    78707870    IEMOP_MNEMONIC(jne_Jv, "jne/jnz Jv");
    78717871    IEMOP_HLP_MIN_386();
    7872     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     7872    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    78737873    if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
    78747874    {
     
    79057905    IEMOP_MNEMONIC(jbe_Jv, "jbe/jna Jv");
    79067906    IEMOP_HLP_MIN_386();
    7907     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     7907    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    79087908    if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
    79097909    {
     
    79407940    IEMOP_MNEMONIC(ja_Jv, "jnbe/ja Jv");
    79417941    IEMOP_HLP_MIN_386();
    7942     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     7942    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    79437943    if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
    79447944    {
     
    79757975    IEMOP_MNEMONIC(js_Jv, "js  Jv");
    79767976    IEMOP_HLP_MIN_386();
    7977     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     7977    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    79787978    if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
    79797979    {
     
    80108010    IEMOP_MNEMONIC(jns_Jv, "jns Jv");
    80118011    IEMOP_HLP_MIN_386();
    8012     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     8012    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    80138013    if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
    80148014    {
     
    80458045    IEMOP_MNEMONIC(jp_Jv, "jp  Jv");
    80468046    IEMOP_HLP_MIN_386();
    8047     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     8047    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    80488048    if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
    80498049    {
     
    80808080    IEMOP_MNEMONIC(jnp_Jv, "jnp Jv");
    80818081    IEMOP_HLP_MIN_386();
    8082     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     8082    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    80838083    if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
    80848084    {
     
    81158115    IEMOP_MNEMONIC(jl_Jv, "jl/jnge Jv");
    81168116    IEMOP_HLP_MIN_386();
    8117     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     8117    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    81188118    if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
    81198119    {
     
    81508150    IEMOP_MNEMONIC(jge_Jv, "jnl/jge Jv");
    81518151    IEMOP_HLP_MIN_386();
    8152     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     8152    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    81538153    if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
    81548154    {
     
    81858185    IEMOP_MNEMONIC(jle_Jv, "jle/jng Jv");
    81868186    IEMOP_HLP_MIN_386();
    8187     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     8187    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    81888188    if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
    81898189    {
     
    82208220    IEMOP_MNEMONIC(jg_Jv, "jnle/jg Jv");
    82218221    IEMOP_HLP_MIN_386();
    8222     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
     8222    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX();
    82238223    if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
    82248224    {
  • trunk/src/VBox/VMM/include/IEMInline.h

    r97408 r97441  
    12881288
    12891289
     1290/**
     1291 * Sets the default operand size to 64-bit and recalculates the effective
     1292 * operand size, with intel ignoring any operand size prefix (AMD respects it).
     1293 *
     1294 * This is for the relative jumps.
     1295 *
     1296 * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
     1297 */
     1298DECLINLINE(void) iemRecalEffOpSize64DefaultAndIntelIgnoresOpSizePrefix(PVMCPUCC pVCpu)
     1299{
     1300    Assert(pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT);
     1301    pVCpu->iem.s.enmDefOpSize = IEMMODE_64BIT;
     1302    if (   (pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_SIZE_REX_W | IEM_OP_PRF_SIZE_OP)) != IEM_OP_PRF_SIZE_OP
     1303        || pVCpu->iem.s.enmCpuVendor == CPUMCPUVENDOR_INTEL)
     1304        pVCpu->iem.s.enmEffOpSize = IEMMODE_64BIT;
     1305    else
     1306        pVCpu->iem.s.enmEffOpSize = IEMMODE_16BIT;
     1307}
     1308
     1309
    12901310
    12911311
     
    15851605    uint64_t const uRipNext = uRipPrev + cbInstr;
    15861606    if (RT_LIKELY(   !((uRipNext ^ uRipPrev) & (RT_BIT_64(32) | RT_BIT_64(16)))
    1587                   || CPUMIsGuestIn64BitCodeEx(&pVCpu->cpum.GstCtx)))
     1607                  || pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT))
    15881608        pVCpu->cpum.GstCtx.rip = uRipNext;
    15891609    else if (IEM_GET_TARGET_CPU(pVCpu) >= IEMTARGETCPU_386)
  • trunk/src/VBox/VMM/include/IEMInternal.h

    r97361 r97441  
    37293729/** @name Register Access.
    37303730 * @{ */
    3731 VBOXSTRICTRC    iemRegRipRelativeJumpS8(PVMCPUCC pVCpu, int8_t offNextInstr) RT_NOEXCEPT;
    3732 VBOXSTRICTRC    iemRegRipRelativeJumpS16(PVMCPUCC pVCpu, int16_t offNextInstr) RT_NOEXCEPT;
    3733 VBOXSTRICTRC    iemRegRipRelativeJumpS32(PVMCPUCC pVCpu, int32_t offNextInstr) RT_NOEXCEPT;
     3731VBOXSTRICTRC    iemRegRipRelativeJumpS8AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int8_t offNextInstr,
     3732                                                           IEMMODE enmEffOpSize) RT_NOEXCEPT;
     3733VBOXSTRICTRC    iemRegRipRelativeJumpS16AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int16_t offNextInstr) RT_NOEXCEPT;
     3734VBOXSTRICTRC    iemRegRipRelativeJumpS32AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int32_t offNextInstr,
     3735                                                            IEMMODE enmEffOpSize) RT_NOEXCEPT;
    37343736VBOXSTRICTRC    iemRegRipJump(PVMCPUCC pVCpu, uint64_t uNewRip) RT_NOEXCEPT;
    37353737/** @} */
  • trunk/src/VBox/VMM/include/IEMMc.h

    r97370 r97441  
    5555/** Advances RIP, finishes the instruction and returns.
    5656 * This may include raising debug exceptions and such. */
    57 #define IEM_MC_ADVANCE_RIP_AND_FINISH()                 return iemRegUpdateRipAndFinishClearingRF(pVCpu)
     57#define IEM_MC_ADVANCE_RIP_AND_FINISH()                 return iemRegAddToRipAndFinishingClearingRF(pVCpu, IEM_GET_INSTR_LEN(pVCpu))
    5858/** Sets RIP (may trigger \#GP), finishes the instruction and returns. */
    59 #define IEM_MC_REL_JMP_S8_AND_FINISH(a_i8)              return iemRegRipRelativeJumpS8(pVCpu, (a_i8))
     59#define IEM_MC_REL_JMP_S8_AND_FINISH(a_i8) \
     60    return iemRegRipRelativeJumpS8AndFinishClearingRF(pVCpu, IEM_GET_INSTR_LEN(pVCpu), (a_i8), pVCpu->iem.s.enmEffOpSize)
     61/** Sets RIP (may trigger \#GP), finishes the instruction and returns.
     62 * @note only usable in 16-bit op size mode.  */
     63#define IEM_MC_REL_JMP_S16_AND_FINISH(a_i16) \
     64    return iemRegRipRelativeJumpS16AndFinishClearingRF(pVCpu, IEM_GET_INSTR_LEN(pVCpu), (a_i16))
    6065/** Sets RIP (may trigger \#GP), finishes the instruction and returns. */
    61 #define IEM_MC_REL_JMP_S16_AND_FINISH(a_i16)            return iemRegRipRelativeJumpS16(pVCpu, (a_i16))
    62 /** Sets RIP (may trigger \#GP), finishes the instruction and returns. */
    63 #define IEM_MC_REL_JMP_S32_AND_FINISH(a_i32)            return iemRegRipRelativeJumpS32(pVCpu, (a_i32))
     66#define IEM_MC_REL_JMP_S32_AND_FINISH(a_i32) \
     67    return iemRegRipRelativeJumpS32AndFinishClearingRF(pVCpu, IEM_GET_INSTR_LEN(pVCpu), (a_i32), pVCpu->iem.s.enmEffOpSize)
    6468/** Sets RIP (may trigger \#GP), finishes the instruction and returns. */
    6569#define IEM_MC_SET_RIP_U16_AND_FINISH(a_u16NewIP)       return iemRegRipJump((pVCpu), (a_u16NewIP))
  • trunk/src/VBox/VMM/include/IEMOpHlp.h

    r96438 r97441  
    367367    } while (0)
    368368
     369/** The instruction defaults to 64-bit operand size if 64-bit mode and intel
     370 *  CPUs ignore the operand size prefix complete (e.g. relative jumps). */
     371#define IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX() \
     372    do \
     373    { \
     374        if (pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT) \
     375            iemRecalEffOpSize64DefaultAndIntelIgnoresOpSizePrefix(pVCpu); \
     376    } while (0)
     377
    369378/** The instruction has 64-bit operand size if 64-bit mode. */
    370379#define IEMOP_HLP_64BIT_OP_SIZE() \
  • trunk/src/VBox/VMM/testcase/tstIEMCheckMc.cpp

    r97357 r97441  
    157157#define IEMOP_HLP_64BIT_OP_SIZE()                           do { } while (0)
    158158#define IEMOP_HLP_DEFAULT_64BIT_OP_SIZE()                   do { } while (0)
     159#define IEMOP_HLP_DEFAULT_64BIT_OP_SIZE_AND_INTEL_IGNORES_OP_SIZE_PREFIX()                          do { } while (0)
    159160#define IEMOP_HLP_CLEAR_REX_NOT_BEFORE_OPCODE(a_szPrf)      do { } while (0)
    160161#define IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX()            do { } while (0)
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette