VirtualBox

Ignore:
Timestamp:
Jun 15, 2012 7:16:10 PM (12 years ago)
Author:
vboxsync
Message:

CSAM: Made csamR3ReadBytes return the maximum number of bytes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/CSAM.cpp

    r41760 r41769  
    726726 * @callback_method_impl{FNDISREADBYTES}
    727727 */
    728 static DECLCALLBACK(int) CSAMR3ReadBytes(PDISCPUSTATE pDis, uint8_t offInstr, uint8_t cbMinRead, uint8_t cbMaxRead)
     728static DECLCALLBACK(int) csamR3ReadBytes(PDISCPUSTATE pDis, uint8_t offInstr, uint8_t cbMinRead, uint8_t cbMaxRead)
    729729{
    730730    PVM pVM = (PVM)pDis->pvUser;
    731     int rc  = VINF_SUCCESS;
    732 
    733 /** @todo Optimize this code to read more when possible! Add a new PATM call for
    734  *        reading more than one byte. */
    735 
    736     /* We are not interested in patched instructions, so read the original opcode bytes.
    737        Note! single instruction patches (int3) are checked in CSAMR3AnalyseCallback */
    738     while (cbMinRead > 0)
    739     {
    740         int rc2 = PATMR3QueryOpcode(pVM, (RTRCPTR)pDis->uInstrAddr + offInstr, &pDis->abInstr[offInstr]);
    741         if (RT_FAILURE(rc2))
    742             break;
    743         offInstr++;
    744         cbMinRead--;
    745         cbMaxRead--;
    746     }
    747     if (cbMinRead > 0)
    748     {
    749         /*
    750          * The current byte isn't a patch instruction byte...
    751          */
    752         uint8_t const  *pbInstr  = (uint8_t const *)pDis->pvUser2;
    753         RTUINTPTR       uSrcAddr = pDis->uInstrAddr + offInstr;
    754         if (   PAGE_ADDRESS(pDis->uInstrAddr) != PAGE_ADDRESS(uSrcAddr + cbMinRead - 1)
    755             && !PATMIsPatchGCAddr(pVM, uSrcAddr)) /** @todo does CSAM actually analyze patch code, or is this just a copy&past check? */
    756         {
    757             /* Crossed page boundrary, pbInstr is no good.. */
    758             PVMCPU      pVCpu    = VMMGetCpu0(pVM);
    759             rc = PGMPhysSimpleReadGCPtr(pVCpu, &pDis->abInstr[offInstr], uSrcAddr, cbMinRead);
    760             offInstr += cbMinRead;
    761         }
    762         else
    763         {
    764             /* pbInstr is eqvivalent to uInstrAddr. */
    765             AssertPtr(pbInstr);
    766             memcpy(&pDis->abInstr[offInstr], &pbInstr[offInstr], cbMinRead);
    767             offInstr += cbMinRead;
    768         }
     731
     732    /*
     733     * We are not interested in patched instructions, so read the original opcode bytes.
     734     *
     735     * Note! single instruction patches (int3) are checked in CSAMR3AnalyseCallback
     736     *
     737     * Since we're decoding one instruction at the time, we don't need to be
     738     * concerned about any patched instructions following the first one.  We
     739     * could in fact probably skip this PATM call for offInstr != 0.
     740     */
     741    size_t      cbRead   = cbMaxRead;
     742    RTUINTPTR   uSrcAddr = pDis->uInstrAddr + offInstr;
     743    int rc = PATMR3ReadOrgInstr(pVM, pDis->uInstrAddr + offInstr, &pDis->abInstr[offInstr], cbRead, &cbRead);
     744    if (RT_SUCCESS(rc))
     745    {
     746        if (cbRead >= cbMinRead)
     747        {
     748            pDis->cbCachedInstr = offInstr + cbRead;
     749            return rc;
     750        }
     751
     752        cbMinRead -= cbRead;
     753        cbMaxRead -= cbRead;
     754        offInstr  += cbRead;
     755        uSrcAddr  += cbRead;
     756    }
     757
     758    /*
     759     * The current byte isn't a patch instruction byte.
     760     */
     761    uint8_t const  *pbSrcInstr = (uint8_t const *)pDis->pvUser2; AssertPtr(pbSrcInstr);
     762    if ((pDis->uInstrAddr >> PAGE_SHIFT) == ((uSrcAddr + cbMaxRead - 1) >> PAGE_SHIFT))
     763    {
     764        memcpy(&pDis->abInstr[offInstr], &pbSrcInstr[offInstr], cbMaxRead);
     765        offInstr += cbMaxRead;
     766        rc = VINF_SUCCESS;
     767    }
     768    else if (   (pDis->uInstrAddr >> PAGE_SHIFT) == ((uSrcAddr + cbMinRead - 1) >> PAGE_SHIFT)
     769             || PATMIsPatchGCAddr(pVM, uSrcAddr) /** @todo does CSAM actually analyze patch code, or is this just a copy&past check? */
     770            )
     771    {
     772        memcpy(&pDis->abInstr[offInstr], &pbSrcInstr[offInstr], cbMaxRead);
     773        offInstr += cbMinRead;
     774        rc = VINF_SUCCESS;
     775    }
     776    else
     777    {
     778        /* Crossed page boundrary, pbSrcInstr is no good... */
     779        rc = PGMPhysSimpleReadGCPtr(VMMGetCpu0(pVM), &pDis->abInstr[offInstr], uSrcAddr, cbMinRead);
     780        offInstr += cbMinRead;
    769781    }
    770782
     
    773785}
    774786
    775 DECLINLINE(int) CSAMR3DISInstr(PVM pVM, RTRCPTR InstrGC, uint8_t *InstrHC, DISCPUMODE enmCpuMode,
     787DECLINLINE(int) csamR3DISInstr(PVM pVM, RTRCPTR InstrGC, uint8_t *InstrHC, DISCPUMODE enmCpuMode,
    776788                               PDISCPUSTATE pCpu, uint32_t *pcbInstr, char *pszOutput, size_t cbOutput)
    777789{
     790    /** @todo Put pVM and pbInstrHC in a stack structure and pass it to
     791     *        csamR3ReadBytes via pvUser. This is the last pvUser2 usage. */
    778792    pCpu->pvUser2 = InstrHC;
    779793#ifdef DEBUG
    780     return DISInstrToStrEx(InstrGC, enmCpuMode, CSAMR3ReadBytes, pVM, DISOPTYPE_ALL,
     794    return DISInstrToStrEx(InstrGC, enmCpuMode, csamR3ReadBytes, pVM, DISOPTYPE_ALL,
    781795                           pCpu, pcbInstr, pszOutput, cbOutput);
    782796#else
    783797    /* We are interested in everything except harmless stuff */
    784798    if (pszOutput)
    785         return DISInstrToStrEx(InstrGC, enmCpuMode, CSAMR3ReadBytes, pVM, ~(DISOPTYPE_INVALID | DISOPTYPE_HARMLESS | DISOPTYPE_RRM_MASK),
     799        return DISInstrToStrEx(InstrGC, enmCpuMode, csamR3ReadBytes, pVM, ~(DISOPTYPE_INVALID | DISOPTYPE_HARMLESS | DISOPTYPE_RRM_MASK),
    786800                               pCpu, pcbInstr, pszOutput, cbOutput);
    787     return DISInstEx(InstrGC, enmCpuMode, ~(DISOPTYPE_INVALID | DISOPTYPE_HARMLESS | DISOPTYPE_RRM_MASK), CSAMR3ReadBytes, pVM,
     801    return DISInstEx(InstrGC, enmCpuMode, ~(DISOPTYPE_INVALID | DISOPTYPE_HARMLESS | DISOPTYPE_RRM_MASK), csamR3ReadBytes, pVM,
    788802                     pCpu, pcbInstr);
    789803#endif
     
    882896                Assert(VALID_PTR(pCurInstrHC));
    883897
    884                 rc = CSAMR3DISInstr(pVM, pCurInstrGC, pCurInstrHC, (fCode32) ? DISCPUMODE_32BIT : DISCPUMODE_16BIT,
     898                rc = csamR3DISInstr(pVM, pCurInstrGC, pCurInstrHC, (fCode32) ? DISCPUMODE_32BIT : DISCPUMODE_16BIT,
    885899                                    &cpu, &cbCurInstr, NULL, 0);
    886900            }
     
    10651079                STAM_PROFILE_START(&pVM->csam.s.StatTimeDisasm, a);
    10661080#ifdef DEBUG
    1067                 rc2 = CSAMR3DISInstr(pVM, pCurInstrGC, pCurInstrHC, (fCode32) ? DISCPUMODE_32BIT : DISCPUMODE_16BIT,
     1081                rc2 = csamR3DISInstr(pVM, pCurInstrGC, pCurInstrHC, (fCode32) ? DISCPUMODE_32BIT : DISCPUMODE_16BIT,
    10681082                                     &cpu, &cbInstr, szOutput, sizeof(szOutput));
    10691083                if (RT_SUCCESS(rc2)) Log(("CSAM Call Analysis: %s", szOutput));
    10701084#else
    1071                 rc2 = CSAMR3DISInstr(pVM, pCurInstrGC, pCurInstrHC, (fCode32) ? DISCPUMODE_32BIT : DISCPUMODE_16BIT,
     1085                rc2 = csamR3DISInstr(pVM, pCurInstrGC, pCurInstrHC, (fCode32) ? DISCPUMODE_32BIT : DISCPUMODE_16BIT,
    10721086                                     &cpu, &cbInstr, NULL, 0);
    10731087#endif
     
    12781292            STAM_PROFILE_START(&pVM->csam.s.StatTimeDisasm, a);
    12791293#ifdef DEBUG
    1280             rc2 = CSAMR3DISInstr(pVM, pCurInstrGC, pCurInstrHC, fCode32 ? DISCPUMODE_32BIT : DISCPUMODE_16BIT,
     1294            rc2 = csamR3DISInstr(pVM, pCurInstrGC, pCurInstrHC, fCode32 ? DISCPUMODE_32BIT : DISCPUMODE_16BIT,
    12811295                                 &cpu, &cbInstr, szOutput, sizeof(szOutput));
    12821296            if (RT_SUCCESS(rc2)) Log(("CSAM Analysis: %s", szOutput));
    12831297#else
    1284             rc2 = CSAMR3DISInstr(pVM, pCurInstrGC, pCurInstrHC, fCode32 ? DISCPUMODE_32BIT : DISCPUMODE_16BIT,
     1298            rc2 = csamR3DISInstr(pVM, pCurInstrGC, pCurInstrHC, fCode32 ? DISCPUMODE_32BIT : DISCPUMODE_16BIT,
    12851299                                 &cpu, &cbInstr, NULL, 0);
    12861300#endif
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