VirtualBox

Changeset 84477 in vbox for trunk/src


Ignore:
Timestamp:
May 24, 2020 6:18:55 PM (5 years ago)
Author:
vboxsync
Message:

IEM: Implemented dummy MOV to/from TR. Avoids crashes in OS/2 KDB and WDEB386 when emulating a 386.

Location:
trunk/src/VBox/VMM/VMMAll
Files:
2 edited

Legend:

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

    r83771 r84477  
    62636263
    62646264/**
     6265 * Implements mov GReg,TRx.
     6266 *
     6267 * @param   iGReg           The general register to store the
     6268 *                          TRx value in.
     6269 * @param   iTrReg          The TRx register to read (6/7).
     6270 */
     6271IEM_CIMPL_DEF_2(iemCImpl_mov_Rd_Td, uint8_t, iGReg, uint8_t, iTrReg)
     6272{
     6273    /*
     6274     * Check preconditions. NB: This instruction is 386/486 only.
     6275     */
     6276
     6277    /* Raise GPs. */
     6278    if (pVCpu->iem.s.uCpl != 0)
     6279        return iemRaiseGeneralProtectionFault0(pVCpu);
     6280    Assert(!pVCpu->cpum.GstCtx.eflags.Bits.u1VM);
     6281
     6282    if (iTrReg < 6 || iTrReg > 7)
     6283    {
     6284        /** @todo Do Intel CPUs reject this or are the TRs aliased? */
     6285        Log(("mov r%u,tr%u: invalid register -> #GP(0)\n", iGReg, iTrReg));
     6286        return iemRaiseGeneralProtectionFault0(pVCpu);
     6287    }
     6288
     6289    /*
     6290     * Read the test register and store it in the specified general register.
     6291     * This is currently a dummy implementation that only exists to satisfy
     6292     * old debuggers like WDEB386 or OS/2 KDB which unconditionally read the
     6293     * TR6/TR7 registers. Software which actually depends on the TR values
     6294     * (different on 386/486) is exceedingly rare.
     6295     */
     6296    uint64_t trX;
     6297    switch (iTrReg)
     6298    {
     6299        case 6:
     6300            trX = 0;    /* Currently a dummy. */
     6301            break;
     6302        case 7:
     6303            trX = 0;    /* Currently a dummy. */
     6304            break;
     6305        IEM_NOT_REACHED_DEFAULT_CASE_RET(); /* call checks */
     6306    }
     6307
     6308    *(uint64_t *)iemGRegRef(pVCpu, iGReg) = (uint32_t)trX;
     6309
     6310    iemRegAddToRipAndClearRF(pVCpu, cbInstr);
     6311    return VINF_SUCCESS;
     6312}
     6313
     6314
     6315/**
     6316 * Implements mov TRx,GReg.
     6317 *
     6318 * @param   iTrReg          The TRx register to write (valid).
     6319 * @param   iGReg           The general register to load the TRx
     6320 *                          value from.
     6321 */
     6322IEM_CIMPL_DEF_2(iemCImpl_mov_Td_Rd, uint8_t, iTrReg, uint8_t, iGReg)
     6323{
     6324    /*
     6325     * Check preconditions. NB: This instruction is 386/486 only.
     6326     */
     6327
     6328    /* Raise GPs. */
     6329    if (pVCpu->iem.s.uCpl != 0)
     6330        return iemRaiseGeneralProtectionFault0(pVCpu);
     6331    Assert(!pVCpu->cpum.GstCtx.eflags.Bits.u1VM);
     6332
     6333    if (iTrReg < 6 || iTrReg > 7)
     6334    {
     6335        /** @todo Do Intel CPUs reject this or are the TRs aliased? */
     6336        Log(("mov r%u,tr%u: invalid register -> #GP(0)\n", iGReg, iTrReg));
     6337        return iemRaiseGeneralProtectionFault0(pVCpu);
     6338    }
     6339
     6340    /*
     6341     * Read the new value from the source register.
     6342     */
     6343    uint64_t uNewDrX;
     6344    if (pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT)
     6345        uNewDrX = iemGRegFetchU64(pVCpu, iGReg);
     6346    else
     6347        uNewDrX = iemGRegFetchU32(pVCpu, iGReg);
     6348
     6349    /*
     6350     * Here we would do the actual setting if this weren't a dummy implementation.
     6351     * This is currently a dummy implementation that only exists to prevent
     6352     * old debuggers like WDEB386 or OS/2 KDB from crashing.
     6353     */
     6354
     6355    iemRegAddToRipAndClearRF(pVCpu, cbInstr);
     6356    return VINF_SUCCESS;
     6357}
     6358
     6359
     6360/**
    62656361 * Implements 'INVLPG m'.
    62666362 *
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsTwoByte0f.cpp.h

    r82968 r84477  
    22162216{
    22172217    IEMOP_MNEMONIC(mov_Rd_Td, "mov Rd,Td");
    2218     /** @todo works on 386 and 486. */
    2219     /* The RM byte is not considered, see testcase. */
    2220     return IEMOP_RAISE_INVALID_OPCODE();
     2218    IEMOP_HLP_MIN_386();
     2219    uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
     2220    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     2221    if (RT_LIKELY(IEM_GET_TARGET_CPU(pVCpu) >= IEMTARGETCPU_PENTIUM))
     2222        return IEMOP_RAISE_INVALID_OPCODE();
     2223    return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_mov_Rd_Td,
     2224                                   (X86_MODRM_RM_MASK & bRm) | pVCpu->iem.s.uRexB,
     2225                                   ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK));
    22212226}
    22222227
     
    22262231{
    22272232    IEMOP_MNEMONIC(mov_Td_Rd, "mov Td,Rd");
    2228     /** @todo works on 386 and 486. */
    2229     /* The RM byte is not considered, see testcase. */
    2230     return IEMOP_RAISE_INVALID_OPCODE();
     2233    IEMOP_HLP_MIN_386();
     2234    uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
     2235    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     2236    if (RT_LIKELY(IEM_GET_TARGET_CPU(pVCpu) >= IEMTARGETCPU_PENTIUM))
     2237        return IEMOP_RAISE_INVALID_OPCODE();
     2238    return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_mov_Td_Rd,
     2239                                   ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK),
     2240                                   (X86_MODRM_RM_MASK & bRm) | pVCpu->iem.s.uRexB);
    22312241}
    22322242
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