VirtualBox

Changeset 53563 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Dec 18, 2014 2:31:37 AM (10 years ago)
Author:
vboxsync
Message:

cidet: More hacking.

Location:
trunk/src/VBox/ValidationKit/utils/cpu
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/utils/cpu/cidet-app.cpp

    r53548 r53563  
    103103    /** Data buffers (runs parallel to g_aDataBufCfgs). */
    104104    CIDETAPPBUF     aDataBuffers[CIDETAPP_DATA_BUF_COUNT];
     105
     106    /** The lowest stack address. */
     107    uint8_t        *pbStackLow;
     108    /** The end of the stack allocation (highest address). */
     109    uint8_t        *pbStackEnd;
     110    /** Stack size (= pbStackEnd - pbStackLow). */
     111    uint32_t        cbStack;
    105112} CIDETAPP;
    106113/** Pointer to a CIDET driver app instance. */
     
    347354}
    348355
     356
     357/**
     358 * Vectored exception handler.
     359 *
     360 * @returns Long jumps or terminates the process.
     361 * @param   pXcptPtrs   The exception record.
     362 */
     363static LONG CALLBACK CidetAppVectoredXcptHandler(EXCEPTION_POINTERS *pXcptPtrs)
     364{
     365    RTStrmPrintf(g_pStdErr, "CidetAppVectoredXcptHandler!\n");
     366    CidetAppXcptFilter(pXcptPtrs);
     367
     368    /* won't get here. */
     369    return EXCEPTION_CONTINUE_SEARCH;
     370}
     371
     372
     373/**
     374 * Unhandled exception filter.
     375 *
     376 * @returns Long jumps or terminates the process.
     377 * @param   pXcptPtrs   The exception record.
     378 */
     379static LONG CALLBACK CidetAppUnhandledXcptFilter(EXCEPTION_POINTERS *pXcptPtrs)
     380{
     381    RTStrmPrintf(g_pStdErr, "CidetAppUnhandledXcptFilter!\n");
     382    CidetAppXcptFilter(pXcptPtrs);
     383
     384    /* won't get here. */
     385    return EXCEPTION_CONTINUE_SEARCH;
     386}
     387
     388
    349389#elif defined(USE_SIGNALS)
    350390/**
     
    395435 *
    396436 */
    397 
    398 static void CidetAppDeleteBuffer(PCIDETAPPBUF pBuf)
    399 {
    400     RTMemPageFree(pBuf->pbNormal - PAGE_SIZE, PAGE_SIZE + pBuf->cb + PAGE_SIZE);
    401     if (pBuf->pbLow != pBuf->pbNormal && pBuf->pbLow)
    402         RTMemFreeEx(pBuf->pbLow, pBuf->cb);
    403 }
    404 
    405437
    406438static int cidetAppAllocateAndConfigureOneBuffer(PCIDETAPP pThis, PCIDETAPPBUF pBuf, uint16_t idxBuf, bool fIsCode,
     
    500532
    501533
     534static void CidetAppDeleteBuffer(PCIDETAPPBUF pBuf)
     535{
     536    RTMemProtect(pBuf->pbNormal - PAGE_SIZE, PAGE_SIZE + pBuf->cb + PAGE_SIZE, RTMEM_PROT_READ | RTMEM_PROT_WRITE);
     537    RTMemPageFree(pBuf->pbNormal - PAGE_SIZE, PAGE_SIZE + pBuf->cb + PAGE_SIZE);
     538    if (pBuf->pbLow != pBuf->pbNormal && pBuf->pbLow)
     539    {
     540        RTMemProtect(pBuf->pbLow, pBuf->cb, RTMEM_PROT_READ | RTMEM_PROT_WRITE);
     541        RTMemFreeEx(pBuf->pbLow, pBuf->cb);
     542    }
     543}
    502544
    503545
     
    532574    }
    533575    pAppBuf->fArmed = false;
    534     return false;
     576    return true;
    535577}
    536578
     
    544586    PCIDETAPPBUF pAppBuf  = &pThisApp->aDataBuffers[pBuf->idxCfg];
    545587    Assert(CIDETBUF_IS_DATA(pBuf->pCfg->fFlags));
    546     Assert(!pAppBuf->fArmed);
    547588
    548589    /*
     
    680721     */
    681722    uint16_t cbPrologue = 0;
    682     uint16_t cbEpilogue = ARCH_BITS == 64 ? 0x3b : 0x36;
     723    uint16_t cbEpilogue = ARCH_BITS == 64 ? 0x56 : 0x4e;
    683724    if (pThis->InCtx.fTrickyStack)
    684     {
    685         /** @todo tricky stack.   */
    686         AssertReleaseFailedReturn(false);
    687     }
    688 
     725        cbEpilogue = 16;
    689726
    690727    /*
     
    743780     * Emit epilogue code.
    744781     */
    745     /* Restore working stack if necessary. */
    746     if (pThis->InCtx.fTrickyStack)
    747     {
    748         /** @todo emit code for establishing a working stack. */
    749         AssertReleaseFailedReturn(false);
    750     }
    751     else
     782    if (!pThis->InCtx.fTrickyStack)
    752783    {
    753784        /*
    754785         * The stack is reasonably good, do minimal work.
     786         *
     787         * Note! Ideally, we would just fill in 16 int3s here and check that
     788         *       we hit the first right one.  However, if we wish to run this
     789         *       code with IEM, we better skip unnecessary trips to ring-0.
    755790         */
     791
     792        /* jmp      $+6 */
     793        *pbDst++ = 0xeb;
     794        *pbDst++ = 0x06;        /* This is a push es, so if the decoder is one off, we'll hit the int 3 below. */
     795
     796        /* Six int3s for trapping incorrectly decoded instructions. */
     797        *pbDst++ = 0xcc;
     798        *pbDst++ = 0xcc;
     799        *pbDst++ = 0xcc;
     800        *pbDst++ = 0xcc;
     801        *pbDst++ = 0xcc;
     802        *pbDst++ = 0xcc;
     803
     804        /* push     rip / call $+0 */
     805        *pbDst++ = 0xe8;
     806        *pbDst++ = 0x00;
     807        *pbDst++ = 0x00;
     808        *pbDst++ = 0x00;
     809        *pbDst++ = 0x00;
    756810
    757811        /* push     xCX */
    758812        *pbDst++ = 0x51;
     813
     814        /* mov      xCX, [xSP + xCB] */
     815        *pbDst++ = 0x48;
     816        *pbDst++ = 0x8b;
     817        *pbDst++ = 0x4c;
     818        *pbDst++ = 0x24;
     819        *pbDst++ = 0x08;
     820
     821        /* lea      xCX, [xCX - 14] */
     822        *pbDst++ = 0x48;
     823        *pbDst++ = 0x8d;
     824        *pbDst++ = 0x49;
     825        *pbDst++ = 0xf2;
     826
     827        /* mov      xCX, [xSP + xCB] */
     828        *pbDst++ = 0x48;
     829        *pbDst++ = 0x89;
     830        *pbDst++ = 0x4c;
     831        *pbDst++ = 0x24;
     832        *pbDst++ = 0x08;
    759833
    760834        /* mov      xCX, &pThis->ActualCtx */
     
    778852        *pbDst++ = 0x48;
    779853#endif
    780         *pbDst++ = 0x85;
     854        *pbDst++ = 0x89;
    781855        *pbDst++ = 0x51;
    782856        *pbDst++ = RT_OFFSETOF(CIDETCPUCTX, aGRegs[X86_GREG_xDX]);
     
    819893        *(uintptr_t *)pbDst = (uintptr_t)CidetAppSaveAndRestoreCtx;
    820894        pbDst  += sizeof(uintptr_t);
    821     }
    822 
    823 
    824     *pbDst++ = 0xcc; /* int3 */
     895
     896        /* int3 */
     897        *pbDst++ = 0xcc;
     898    }
     899    else
     900    {
     901        /*
     902         * Tricky stack, so just make it raise #UD after a successful run.
     903         */
     904        *pbDst++ = 0xf0;         /* lock prefix */
     905        //*pbDst++ = 0xcc;         /* lock prefix */
     906        memset(pbDst, 0xcc, 15); /* int3 */
     907        pbDst += 15;
     908    }
     909
    825910    AssertMsg(pbDst == &pAppBuf->pbNormal[pBuf->offActive + pBuf->cb + pBuf->cbEpilogue],
    826911              ("cbEpilogue=%#x, actual %#x\n", pBuf->cbEpilogue, pbDst - &pAppBuf->pbNormal[pBuf->offActive + pBuf->cb]));
     
    834919
    835920/**
    836  * @interface_method_impl{CIDETCORE::pfnSetupBuf}
    837  */
    838 static DECLCALLBACK(void) CidetAppCbExecute(PCIDETCORE pThis)
    839 {
     921 * @interface_method_impl{CIDETCORE::pfnExecute}
     922 */
     923static DECLCALLBACK(bool) CidetAppCbExecute(PCIDETCORE pThis)
     924{
     925#if defined(RT_OS_WINDOWS)
     926    /* Skip tricky stack because windows cannot dispatch exception if RSP/ESP is bad. */
     927    if (pThis->InCtx.fTrickyStack)
     928        return false;
     929#endif
     930
    840931    g_pExecutingThis = (PCIDETAPP)pThis;
    841932#ifdef RT_OS_WINDOWS
     
    852943#endif
    853944    g_pExecutingThis = NULL;
     945
     946    return true;
    854947}
    855948
     
    879972static int cidetAppAllocateAndConfigureBuffers(PCIDETAPP pThis)
    880973{
     974    /*
     975     * Code buffers.
     976     */
    881977    for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCodeBuffers); i++)
    882978    {
     
    887983    }
    888984
     985    /*
     986     * Data buffers.
     987     */
    889988    for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aDataBuffers); i++)
    890989    {
     
    894993            return rc;
    895994    }
     995
     996    /*
     997     * Stack.
     998     */
     999    pThis->cbStack    = _32K;
     1000    pThis->pbStackLow = (uint8_t *)RTMemPageAlloc(pThis->cbStack);
     1001    if (!pThis->pbStackLow)
     1002    {
     1003        RTTestIFailed("Failed to allocate %u bytes for stack\n", pThis->cbStack);
     1004        return false;
     1005    }
     1006    pThis->pbStackEnd = pThis->pbStackLow + pThis->cbStack;
     1007
    8961008    return true;
    8971009}
     
    9431055                    pThis->Core.InTemplateCtx.aSRegs[X86_SREG_GS] = ASMGetGS();
    9441056                    pThis->Core.InTemplateCtx.aSRegs[X86_SREG_SS] = ASMGetSS();
     1057                    pThis->Core.InTemplateCtx.aGRegs[X86_GREG_xSP] = (uintptr_t)pThis->pbStackEnd - 64;
    9451058
    9461059                    *ppThis = pThis;
     
    9731086    for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aDataBuffers); i++)
    9741087        CidetAppDeleteBuffer(&pThis->aDataBuffers[i]);
     1088    RTMemPageFree(pThis->pbStackLow, pThis->cbStack);
     1089
    9751090    RTMemFree(pThis);
    9761091}
     
    10301145#ifdef USE_SIGNALS
    10311146    /*
    1032      * Set up signal handlers.
    1033      */
     1147     * Set up signal handlers with alternate stack.
     1148     */
     1149    /* Alternative stack so we can play with esp/rsp. */
     1150    struct sigaltstack AltStack;
     1151    RT_ZERO(AltStack);
     1152    AltStack.ss_flags = SS_ONSTACK;
     1153# ifdef SIGSTKSZ
     1154    AltStack.ss_size  = RT_MAX(SIGSTKSZ, _128K);
     1155# else
     1156    AltStack.ss_size  = _128K;
     1157# endif
     1158    AltStack.ss_sp    = RTMemPageAlloc(AltStack.ss_size);
     1159    RTTESTI_CHECK_RET(AltStack.ss_sp != NULL, RTEXITCODE_FAILURE);
     1160    RTTESTI_CHECK_RC_RET(sigaltstack(&AltStack, NULL), 0, RTEXITCODE_FAILURE);
     1161
     1162    /* Default signal action config. */
    10341163    struct sigaction Act;
    10351164    RT_ZERO(Act);
    1036     Act.sa_sigaction = CidetAppSigHandler;
    1037     Act.sa_flags     = SA_SIGINFO;
     1165    Act.sa_sigaction  = CidetAppSigHandler;
     1166    Act.sa_flags      = SA_SIGINFO | SA_ONSTACK;
    10381167    sigfillset(&Act.sa_mask);
    10391168
     1169    /* Hook the signals we might need. */
    10401170    sigaction(SIGILL,  &Act, NULL);
    10411171    sigaction(SIGTRAP, &Act, NULL);
     
    10461176    sigaction(SIGBUS,  &Act, NULL);
    10471177    sigaction(SIGSEGV, &Act, NULL);
     1178
     1179#elif defined(RT_OS_WINDOWS)
     1180    /*
     1181     * Register vectored exception handler and override the default unhandled
     1182     * exception filter, just to be on the safe side...
     1183     */
     1184    RTTESTI_CHECK(AddVectoredExceptionHandler(1 /* first */, CidetAppVectoredXcptHandler) != NULL);
     1185    SetUnhandledExceptionFilter(CidetAppUnhandledXcptFilter);
    10481186#endif
    10491187
  • trunk/src/VBox/ValidationKit/utils/cpu/cidet-appA.asm

    r53548 r53563  
    5757        ;
    5858        mov     [xCX + CIDETCPUCTX.aGRegs + X86_GREG_xAX * 8], xAX ; need scratch register.
    59         mov     [xCX + CIDETCPUCTX.aGRegs + X86_GREG_xSP * 8], xSP
     59        lea     xAX, [xSP + xCB]
     60        mov     [xCX + CIDETCPUCTX.aGRegs + X86_GREG_xSP * 8], xAX
    6061        mov     word [xCX + CIDETCPUCTX.aSRegs + X86_SREG_SS * 2], ss
    6162        mov     word [xCX + CIDETCPUCTX.aSRegs + X86_SREG_CS * 2], cs
     
    145146
    146147        ;
    147         ; Restore the other state.
     148        ; Restore the other state (pointer in xDX).
    148149        ;
    149150NAME(CidetAppSaveAndRestoreCtx_Restore):
     
    240241        mov     [xCX + CIDETCPUCTX.aGRegs + X86_GREG_xDX * 8], xDX
    241242        mov     [xCX + CIDETCPUCTX.aGRegs + X86_GREG_xCX * 8], xCX
    242         mov     [xDX + CIDETCPUCTX.aGRegs + X86_GREG_xSP * 8], xSP
    243243        jmp     NAME(CidetAppSaveAndRestoreCtx)
    244244ENDPROC     CidetAppExecute
     
    254254%elifdef ASM_CALL64_GCC
    255255        mov     rdx, rdi
    256 %elifndef ASM_CALL64_MSC
     256%elifdef ASM_CALL64_MSC
     257        mov     rdx, rcx
     258%else
    257259 %error "unsupport arch."
    258260%endif
  • trunk/src/VBox/ValidationKit/utils/cpu/cidet-core.cpp

    r53548 r53563  
    6161/** @def CIDET_DPRINTF
    6262 * Debug printf. */
    63 #ifdef DEBUG_bird
    64 # define CIDET_DPRINTF(a)   RTPrintf a
     63#if 0 //def DEBUG_bird
     64# define CIDET_DPRINTF(a)   do { RTPrintf a; } while (0)
    6565#else
    6666# define CIDET_DPRINTF(a)   do { } while (0)
     67#endif
     68
     69/** @def CIDET_DEBUG_DISAS
     70 * Enables instruction disassembly. */
     71#if defined(DOXYGEN_RUNNING)
     72# define CIDET_DEBUG_DISAS 1
    6773#endif
    6874
     
    107113};
    108114
     115/** Converts operand sizes in bytes to 64-bit signed max values. */
     116static const int64_t g_ai64ByteSizeToMax[] =
     117{
     118    INT64_C(0x0000000000000000),
     119    INT64_C(0x000000000000007f),
     120    INT64_C(0x0000000000007fff),
     121    INT64_C(0x00000000007fffff),
     122    INT64_C(0x000000007fffffff),
     123    INT64_C(0x0000007fffffffff),
     124    INT64_C(0x00007fffffffffff),
     125    INT64_C(0x007fffffffffffff),
     126    INT64_C(0x7fffffffffffffff),
     127};
     128
    109129
    110130bool CidetInstrHasMrmMemOperand(PCCIDETINSTR pInstr)
     
    240260                                           | ((uint32_t)i << 12)
    241261                                           | ((uint32_t)i << 8);
    242 
    243262    i = RT_ELEMENTS(pThis->InTemplateCtx.aSRegs);
    244263    while (i-- > 0)
     
    282301        case CIDETMODE_PAE_32:
    283302        //case CIDETMODE_PAE_V86:
    284         //case CIDETMODE_LM_16:
     303        //case CIDETMODE_LM_S16:
    285304        //case CIDETMODE_LM_32:
    286305        case CIDETMODE_LM_64:
     
    488507        pThis->aOperands[pThis->idxMrmRmOp].fIsMem          = false;
    489508        pThis->aOperands[pThis->idxMrmRmOp].fIsRipRelative  = false;
     509        pThis->aOperands[pThis->idxMrmRmOp].fIsHighByteRegister = false;
     510        pThis->aOperands[pThis->idxMrmRmOp].cbMemDisp       = 0;
    490511        pThis->aOperands[pThis->idxMrmRmOp].iMemBaseReg     = UINT8_MAX;
    491512        pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg    = UINT8_MAX;
    492513        pThis->aOperands[pThis->idxMrmRmOp].uMemScale       = 1;
     514        pThis->aOperands[pThis->idxMrmRmOp].iEffSeg         = UINT8_MAX;
    493515        pThis->bModRm                     &= ~(X86_MODRM_RM_MASK | X86_MODRM_MOD_MASK);
    494516        pThis->bModRm                     |= 3 << X86_MODRM_MOD_SHIFT;
     
    501523        pThis->fHasRegCollisionMemBase     = false;
    502524        pThis->fHasRegCollisionMemIndex    = false;
     525        pThis->fHasStackRegInMrmRmBase     = false;
    503526    }
    504527    else
     
    508531        pThis->aOperands[pThis->idxMrmRmOp].fIsMem          = true;
    509532        pThis->aOperands[pThis->idxMrmRmOp].fIsRipRelative  = false;
     533        pThis->aOperands[pThis->idxMrmRmOp].fIsHighByteRegister = false;
     534        pThis->aOperands[pThis->idxMrmRmOp].cbMemDisp       = 0;
    510535        pThis->aOperands[pThis->idxMrmRmOp].iMemBaseReg     = X86_GREG_xBX;
    511536        pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg    = X86_GREG_xSI;
    512537        pThis->aOperands[pThis->idxMrmRmOp].uMemScale       = 1;
     538        pThis->aOperands[pThis->idxMrmRmOp].iEffSeg         = UINT8_MAX;
    513539        pThis->bModRm                     &= ~(X86_MODRM_RM_MASK | X86_MODRM_MOD_MASK);
    514540        pThis->fRexB                       = false;
     
    519545        pThis->fHasRegCollisionMemIndex    = iReg == X86_GREG_xSI && CIDET_OF_K_IS_GPR(pThis->fMrmRegOp);
    520546        pThis->fHasRegCollisionMem         = pThis->fHasRegCollisionMemBase || pThis->fHasRegCollisionMemIndex;
     547        pThis->fHasStackRegInMrmRmBase     = false;
    521548    }
    522549}
     
    554581            pThis->fHasRegCollisionDirect = iRm == iReg
    555582                                        && CIDET_OF_K_IS_SAME(pThis->fMrmRmOp, pThis->fMrmRegOp);
     583            pThis->fHasStackRegInMrmRmBase = iRm == X86_GREG_xSP && CIDET_OF_K_IS_GPR(pThis->fMrmRmOp);
    556584            return true;
    557585        }
     
    648676    pThis->fHasMemoryOperand = true;
    649677    pThis->fHasRegCollisionDirect = false;
     678    pThis->fHasStackRegInMrmRmBase = false;
    650679    if (CIDET_OF_K_IS_GPR(pThis->fMrmRmOp))
    651680    {
     
    672701        pThis->aOperands[pThis->idxMrmRmOp].fIsMem          = false;
    673702        pThis->aOperands[pThis->idxMrmRmOp].fIsRipRelative  = false;
     703        pThis->aOperands[pThis->idxMrmRmOp].fIsHighByteRegister = false;
     704        pThis->aOperands[pThis->idxMrmRmOp].cbMemDisp       = 0;
    674705        pThis->aOperands[pThis->idxMrmRmOp].iMemBaseReg     = UINT8_MAX;
    675706        pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg    = UINT8_MAX;
    676707        pThis->aOperands[pThis->idxMrmRmOp].uMemScale       = 1;
     708        pThis->aOperands[pThis->idxMrmRmOp].iEffSeg         = UINT8_MAX;
    677709        pThis->bModRm                     &= ~(X86_MODRM_RM_MASK | X86_MODRM_MOD_MASK);
    678710        pThis->bModRm                     |= 3 << X86_MODRM_MOD_SHIFT;
     
    685717        pThis->fHasRegCollisionMemBase     = false;
    686718        pThis->fHasRegCollisionMemIndex    = false;
     719        pThis->fHasStackRegInMrmRmBase     = false;
    687720    }
    688721    else
     
    692725        pThis->aOperands[pThis->idxMrmRmOp].fIsMem          = true;
    693726        pThis->aOperands[pThis->idxMrmRmOp].fIsRipRelative  = false;
     727        pThis->aOperands[pThis->idxMrmRmOp].fIsHighByteRegister = false;
     728        pThis->aOperands[pThis->idxMrmRmOp].cbMemDisp       = 0;
    694729        pThis->aOperands[pThis->idxMrmRmOp].iMemBaseReg     = 0;
    695730        pThis->aOperands[pThis->idxMrmRmOp].iMemIndexReg    = UINT8_MAX;
    696731        pThis->aOperands[pThis->idxMrmRmOp].uMemScale       = 1;
     732        pThis->aOperands[pThis->idxMrmRmOp].iEffSeg         = UINT8_MAX;
    697733        pThis->bModRm                     &= ~(X86_MODRM_RM_MASK | X86_MODRM_MOD_MASK);
    698734        pThis->fRexB                       = false;
     
    703739        pThis->fHasRegCollisionMemBase     = iReg == 0 && CIDET_OF_K_IS_GPR(pThis->fMrmRegOp);
    704740        pThis->fHasRegCollisionMem         = pThis->fHasRegCollisionMemBase;
     741        pThis->fHasStackRegInMrmRmBase     = false;
    705742    }
    706743}
     
    761798                    pThis->fHasRegCollisionDirect = CIDET_OF_K_IS_GPR(pThis->fMrmRegOp)
    762799                                                 && iRm == iReg - pThis->fHasHighByteRegInMrmReg * 4;
     800                    pThis->fHasStackRegInMrmRmBase = iRm == X86_GREG_xSP && CIDET_OF_K_IS_GPR(pThis->fMrmRegOp);
    763801                }
    764802                else
     
    779817                        pThis->fHasRegCollisionDirect = CIDET_OF_K_IS_GPR(pThis->fMrmRegOp)
    780818                                                     && iRm - 4 == iReg - pThis->fHasHighByteRegInMrmReg * 4;
     819                        pThis->fHasStackRegInMrmRmBase = false;
    781820
    782821                    }
     
    787826                        pThis->fHasRegCollisionDirect = CIDET_OF_K_IS_GPR(pThis->fMrmRegOp)
    788827                                                     && iRm == iReg - pThis->fHasHighByteRegInMrmReg * 4;
     828                        pThis->fHasStackRegInMrmRmBase = iRm == X86_GREG_xSP && CIDET_OF_K_IS_GPR(pThis->fMrmRegOp);
    789829                    }
    790830                }
     
    803843                pThis->fHasRegCollisionDirect = iRm == iReg - pThis->fHasHighByteRegInMrmReg * 4
    804844                                            && CIDET_OF_K_IS_SAME(pThis->fMrmRmOp, pThis->fMrmRegOp);
     845                pThis->fHasStackRegInMrmRmBase = iRm == X86_GREG_xSP && CIDET_OF_K_IS_GPR(pThis->fMrmRegOp);
    805846            }
    806847            return true;
     
    826867        Assert(pThis->idxMrmRmOp < RT_ELEMENTS(pThis->aOperands) && pThis->aOperands[pThis->idxMrmRmOp].fIsMem);
    827868        Assert(pThis->fHasMemoryOperand);
     869        Assert(!pThis->fHasStackRegInMrmRmBase);
    828870        if (iRm < (CIDETMODE_IS_64BIT(pThis->bMode) && !pThis->fNoRexPrefix ? 15 : 7))
    829871        {
     
    894936    pThis->fHasRegCollisionMemBase = iReg == X86_GREG_xAX && CIDET_OF_K_IS_GPR(pThis->fMrmRmOp);
    895937    pThis->fHasRegCollisionMem = pThis->fHasRegCollisionMemBase;
     938    pThis->fHasStackRegInMrmRmBase = false;
    896939    return true;
    897940}
     
    949992                                  && CIDET_OF_K_IS_GPR(pThis->fMrmRegOp);
    950993    pThis->fHasRegCollisionMem = pThis->fHasRegCollisionMemBase || pThis->fHasRegCollisionMemIndex;
     994    pThis->fHasStackRegInMrmRmBase = iBase == X86_GREG_xSP;
    951995
    952996    return iBase != 0;
     
    12101254    pThis->fHasRegCollisionMemBase  = false;
    12111255    pThis->fHasRegCollisionMemIndex = false;
    1212     pThis->fHasRegCollisionDirect   = false;
     1256    pThis->fHasStackRegInMrmRmBase  = false;
    12131257
    12141258    /*
     
    15361580            else if (iMemBaseReg != UINT8_MAX)
    15371581            {
    1538                 /* [base] or [base + disp] or [base + index * scale] or [base + index * scale + disp] */
    1539                 if (pThis->aOperands[idxOp].cbMemDisp > 0)
     1582                if (   iMemBaseReg != iMemIndexReg
     1583                    || pThis->fUsesVexIndexRegs)
    15401584                {
    1541                     pThis->aOperands[idxOp].uImmDispValue = CidetCoreGetRandS64(pThis, pThis->aOperands[idxOp].cbMemDisp);
    1542                     offSeg -= pThis->aOperands[idxOp].uImmDispValue;
     1585                    /* [base] or [base + disp] or [base + index * scale] or [base + index * scale + disp] */
     1586                    if (pThis->aOperands[idxOp].cbMemDisp > 0)
     1587                    {
     1588                        pThis->aOperands[idxOp].uImmDispValue = CidetCoreGetRandS64(pThis, pThis->aOperands[idxOp].cbMemDisp);
     1589                        offSeg -= (int64_t)pThis->aOperands[idxOp].uImmDispValue;
     1590                    }
     1591
     1592                    if (iMemIndexReg != UINT8_MAX)
     1593                    {
     1594                        pThis->aOperands[idxOp].uMemIndexRegValue = CidetCoreGetRandU64(pThis, pThis->cbAddrMode);
     1595                        offSeg -= pThis->aOperands[idxOp].uMemIndexRegValue * pThis->aOperands[idxOp].uMemScale;
     1596                    }
     1597
     1598                    pThis->aOperands[idxOp].uMemBaseRegValue = offSeg & g_au64ByteSizeToMask[pThis->cbAddrMode];
    15431599                }
    1544 
    1545                 if (iMemIndexReg != UINT8_MAX)
     1600                else
    15461601                {
    1547                     pThis->aOperands[idxOp].uMemIndexRegValue = CidetCoreGetRandU64(pThis, pThis->cbAddrMode);
    1548                     offSeg -= pThis->aOperands[idxOp].uMemIndexRegValue * pThis->aOperands[idxOp].uMemScale;
     1602                    /* base == index;  [base + index * scale] or [base * (scale + 1)]. */
     1603                    uint8_t const uEffScale = pThis->aOperands[idxOp].uMemScale + 1;
     1604                    if (pThis->aOperands[idxOp].cbMemDisp > 0)
     1605                    {
     1606                        pThis->aOperands[idxOp].uImmDispValue = CidetCoreGetRandS64(pThis, pThis->aOperands[idxOp].cbMemDisp);
     1607                        offSeg -= (int64_t)pThis->aOperands[idxOp].uImmDispValue;
     1608                        offSeg &= g_au64ByteSizeToMask[pThis->cbAddrMode];
     1609                        uint8_t uRemainder = offSeg % uEffScale;
     1610                        if (uRemainder != 0)
     1611                        {
     1612                            Assert(pThis->aOperands[idxOp].cbMemDisp < 8);
     1613                            Assert(   (int64_t)pThis->aOperands[idxOp].uImmDispValue
     1614                                   <= g_ai64ByteSizeToMax[pThis->aOperands[idxOp].cbMemDisp]);
     1615                            pThis->aOperands[idxOp].uImmDispValue = (int64_t)pThis->aOperands[idxOp].uImmDispValue
     1616                                                                  + uRemainder;
     1617                            offSeg -= uRemainder;
     1618                            if (  (int64_t)pThis->aOperands[idxOp].uImmDispValue
     1619                                > g_ai64ByteSizeToMax[pThis->aOperands[idxOp].cbMemDisp])
     1620                            {
     1621                                pThis->aOperands[idxOp].uImmDispValue -= uEffScale;
     1622                                offSeg += uEffScale;
     1623                            }
     1624                            Assert(offSeg % uEffScale == 0);
     1625                        }
     1626                    }
     1627                    else
     1628                    {
     1629                        offSeg &= g_au64ByteSizeToMask[pThis->cbAddrMode];
     1630                        if (offSeg % uEffScale != 0)
     1631                            return false;
     1632                    }
     1633                    offSeg /= uEffScale;
     1634                    pThis->aOperands[idxOp].uMemBaseRegValue = pThis->aOperands[idxOp].uMemIndexRegValue = offSeg;
    15491635                }
    1550 
    1551                 pThis->aOperands[idxOp].uMemBaseRegValue = offSeg & g_au64ByteSizeToMask[pThis->cbAddrMode];
    15521636            }
    15531637            else if (iMemIndexReg != UINT8_MAX)
     
    15571641                {
    15581642                    pThis->aOperands[idxOp].uImmDispValue = CidetCoreGetRandS64(pThis, pThis->aOperands[idxOp].cbMemDisp);
    1559                     offSeg -= pThis->aOperands[idxOp].uImmDispValue;
     1643                    offSeg -= (int64_t)pThis->aOperands[idxOp].uImmDispValue;
    15601644                    pThis->aOperands[idxOp].uImmDispValue += offSeg & (RT_BIT_64(pThis->aOperands[idxOp].uMemScale) - 1);
    15611645                    offSeg &= ~(RT_BIT_64(pThis->aOperands[idxOp].uMemScale) - 1);
     
    19982082    {
    19992083        //CIDET_DPRINTF(("%04u: %.*Rhxs\n", i, pThis->cbInstr, pThis->abInstr));
     2084#ifdef CIDET_DEBUG_DISAS
    20002085        DISCPUSTATE Dis;
    20012086        char        szInstr[80] = {0};
     
    20122097        CIDET_DPRINTF(("%04u: %s", iSubTest, szInstr));
    20132098        Assert(cbInstr == pThis->cbInstr);
    2014 
     2099#endif
    20152100        if (pThis->pfnSetupCodeBuf(pThis, &pThis->CodeBuf, pThis->abInstr))
    20162101        {
     
    20512136                     */
    20522137                    pThis->InCtx        = pThis->InTemplateCtx;
    2053                     pThis->ExpectedCtx  = pThis->InTemplateCtx;
     2138                    pThis->InCtx.fTrickyStack = pThis->fHasStackRegInMrmRmBase || pThis->fHasStackRegInMrmReg;
     2139                    pThis->ExpectedCtx  = pThis->InCtx;
    20542140                    if (   CidetCoreReInitCodeBuf(pThis)
    20552141                        && CidetCoreSetupInOut(pThis)
     
    20572143                       )
    20582144                    {
    2059                         pThis->pfnExecute(pThis);
    2060                         cExecuted++;
     2145                        if (pThis->pfnExecute(pThis))
     2146                        {
     2147                            cExecuted++;
     2148
     2149                            /*
     2150                             * Check the result against our expectations.
     2151                             */
     2152                            /** @todo check result. */
     2153
     2154                        }
     2155                        else
     2156                            cSkipped++;
    20612157                    }
    20622158                    else
  • trunk/src/VBox/ValidationKit/utils/cpu/cidet.h

    r53548 r53563  
    843843     * Executes the code indicated by InCtx, returning the result in ActualCtx.
    844844     *
     845     * @returns true if execute, false if skipped.
    845846     * @param   pThis           Pointer to the core structure.
    846847     */
    847     DECLCALLBACKMEMBER(void, pfnExecute)(struct CIDETCORE *pThis);
     848    DECLCALLBACKMEMBER(bool, pfnExecute)(struct CIDETCORE *pThis);
    848849
    849850    /**
     
    916917    /** Indicator: Helper indicator for tracking SIB.BASE collision. */
    917918    bool                fHasRegCollisionMemBase : 1;
    918     /** Indicator: Helper indicator for tracking SIB.BASE collision. */
     919    /** Indicator: Helper indicator for tracking SIB.INDEX collision. */
    919920    bool                fHasRegCollisionMemIndex : 1;
    920921    /** Indicator: Set if a register is used directly in more than one operand. */
    921922    bool                fHasRegCollisionDirect : 1;
     923
     924    /** Indicator: Set if MODRM.REG is the stack register. */
     925    bool                fHasStackRegInMrmReg : 1;
     926    /** Indicator: Set if MODRM.RM or SIB.BASE is the stack register. */
     927    bool                fHasStackRegInMrmRmBase: 1;
     928
    922929    /** Indicator: High byte-register specified by MODRM.REG. */
    923930    bool                fHasHighByteRegInMrmReg : 1;
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