VirtualBox

Changeset 84476 in vbox


Ignore:
Timestamp:
May 24, 2020 6:17:04 PM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
138193
Message:

IEM: Reworked LOOP instruction so that it only shortcuts when logging is on to avoid WfW 3.11/Win95 crashes (see bugref:9735).

File:
1 edited

Legend:

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

    r84247 r84476  
    1028610286     * using the 32-bit operand size override.  How can that be restarted?  See
    1028710287     * weird pseudo code in intel manual. */
     10288
     10289    /** NB: At least Windows for Workgroups 3.11 (NDIS.386) and Windows 95 (NDIS.VXD, IOS)
     10290     * use LOOP $-2 to implement NdisStallExecution and other CPU stall APIs. Shortcutting
     10291     * the loop causes guest crashes, but when logging it's nice to skip a few million
     10292     * lines of useless output. */
     10293#if defined(LOG_ENABLED)
     10294    if ((LogIs3Enabled() || LogIs4Enabled()) && (-(int8_t)IEM_GET_INSTR_LEN(pVCpu) == i8Imm))
     10295        switch (pVCpu->iem.s.enmEffAddrMode)
     10296        {
     10297            case IEMMODE_16BIT:
     10298                IEM_MC_BEGIN(0,0);
     10299                IEM_MC_STORE_GREG_U16_CONST(X86_GREG_xCX, 0);
     10300                IEM_MC_ADVANCE_RIP();
     10301                IEM_MC_END();
     10302                return VINF_SUCCESS;
     10303
     10304            case IEMMODE_32BIT:
     10305                IEM_MC_BEGIN(0,0);
     10306                IEM_MC_STORE_GREG_U32_CONST(X86_GREG_xCX, 0);
     10307                IEM_MC_ADVANCE_RIP();
     10308                IEM_MC_END();
     10309                return VINF_SUCCESS;
     10310
     10311            case IEMMODE_64BIT:
     10312                IEM_MC_BEGIN(0,0);
     10313                IEM_MC_STORE_GREG_U64_CONST(X86_GREG_xCX, 0);
     10314                IEM_MC_ADVANCE_RIP();
     10315                IEM_MC_END();
     10316                return VINF_SUCCESS;
     10317
     10318            IEM_NOT_REACHED_DEFAULT_CASE_RET();
     10319        }
     10320#endif
     10321
    1028810322    switch (pVCpu->iem.s.enmEffAddrMode)
    1028910323    {
    1029010324        case IEMMODE_16BIT:
    1029110325            IEM_MC_BEGIN(0,0);
    10292             if (-(int8_t)IEM_GET_INSTR_LEN(pVCpu) != i8Imm) /** @todo Harmfull to windows 3.11 for workgroups and such. Make optional. */
    10293             {
    10294                 IEM_MC_SUB_GREG_U16(X86_GREG_xCX, 1);
    10295                 IEM_MC_IF_CX_IS_NZ() {
    10296                     IEM_MC_REL_JMP_S8(i8Imm);
    10297                 } IEM_MC_ELSE() {
    10298                     IEM_MC_ADVANCE_RIP();
    10299                 } IEM_MC_ENDIF();
    10300             }
    10301             else
    10302             {
    10303                 IEM_MC_STORE_GREG_U16_CONST(X86_GREG_xCX, 0);
     10326
     10327            IEM_MC_SUB_GREG_U16(X86_GREG_xCX, 1);
     10328            IEM_MC_IF_CX_IS_NZ() {
     10329                IEM_MC_REL_JMP_S8(i8Imm);
     10330            } IEM_MC_ELSE() {
    1030410331                IEM_MC_ADVANCE_RIP();
    10305             }
     10332            } IEM_MC_ENDIF();
    1030610333            IEM_MC_END();
    1030710334            return VINF_SUCCESS;
     
    1030910336        case IEMMODE_32BIT:
    1031010337            IEM_MC_BEGIN(0,0);
    10311             if (-(int8_t)IEM_GET_INSTR_LEN(pVCpu) != i8Imm)
    10312             {
    10313                 IEM_MC_SUB_GREG_U32(X86_GREG_xCX, 1);
    10314                 IEM_MC_IF_ECX_IS_NZ() {
    10315                     IEM_MC_REL_JMP_S8(i8Imm);
    10316                 } IEM_MC_ELSE() {
    10317                     IEM_MC_ADVANCE_RIP();
    10318                 } IEM_MC_ENDIF();
    10319             }
    10320             else
    10321             {
    10322                 IEM_MC_STORE_GREG_U32_CONST(X86_GREG_xCX, 0);
     10338            IEM_MC_SUB_GREG_U32(X86_GREG_xCX, 1);
     10339            IEM_MC_IF_ECX_IS_NZ() {
     10340                IEM_MC_REL_JMP_S8(i8Imm);
     10341            } IEM_MC_ELSE() {
    1032310342                IEM_MC_ADVANCE_RIP();
    10324             }
     10343            } IEM_MC_ENDIF();
    1032510344            IEM_MC_END();
    1032610345            return VINF_SUCCESS;
     
    1032810347        case IEMMODE_64BIT:
    1032910348            IEM_MC_BEGIN(0,0);
    10330             if (-(int8_t)IEM_GET_INSTR_LEN(pVCpu) != i8Imm)
    10331             {
    10332                 IEM_MC_SUB_GREG_U64(X86_GREG_xCX, 1);
    10333                 IEM_MC_IF_RCX_IS_NZ() {
    10334                     IEM_MC_REL_JMP_S8(i8Imm);
    10335                 } IEM_MC_ELSE() {
    10336                     IEM_MC_ADVANCE_RIP();
    10337                 } IEM_MC_ENDIF();
    10338             }
    10339             else
    10340             {
    10341                 IEM_MC_STORE_GREG_U64_CONST(X86_GREG_xCX, 0);
     10349            IEM_MC_SUB_GREG_U64(X86_GREG_xCX, 1);
     10350            IEM_MC_IF_RCX_IS_NZ() {
     10351                IEM_MC_REL_JMP_S8(i8Imm);
     10352            } IEM_MC_ELSE() {
    1034210353                IEM_MC_ADVANCE_RIP();
    10343             }
     10354            } IEM_MC_ENDIF();
    1034410355            IEM_MC_END();
    1034510356            return VINF_SUCCESS;
Note: See TracChangeset for help on using the changeset viewer.

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