VirtualBox

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


Ignore:
Timestamp:
Jun 11, 2012 10:21:44 PM (13 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
78464
Message:

DIS,VMM,REM,IPRT: Disassembler API adjustments.

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

Legend:

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

    r41072 r41658  
    55
    66/*
    7  * Copyright (C) 2006-2007 Oracle Corporation
     7 * Copyright (C) 2006-2012 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    282282
    283283/**
    284  * Read callback for disassembly function; supports reading bytes that cross a page boundary
    285  *
    286  * @returns VBox status code.
    287  * @param   pSrc        GC source pointer
    288  * @param   pDest       HC destination pointer
    289  * @param   cb          Number of bytes to read
    290  * @param   dwUserdata  Callback specific user data (pDis)
    291  *
    292  */
    293 static DECLCALLBACK(int) emReadBytes(RTUINTPTR pSrc, uint8_t *pDest, unsigned cb, void *pvUserdata)
    294 {
    295     PDISCPUSTATE  pDis   = (PDISCPUSTATE)pvUserdata;
    296     PEMDISSTATE   pState = (PEMDISSTATE)pDis->apvUserData[0];
     284 * @callback_method_impl{FNDISREADBYTES}
     285 */
     286static DECLCALLBACK(int) emReadBytes(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead)
     287{
     288    PEMDISSTATE   pState = (PEMDISSTATE)pDisState->apvUserData[0];
    297289# ifndef IN_RING0
    298290    PVM           pVM    = pState->pVM;
     
    304296
    305297    if (    pState->GCPtr
    306         &&  pSrc + cb <= pState->GCPtr + sizeof(pState->aOpcode))
    307     {
    308         unsigned offset = pSrc - pState->GCPtr;
    309         Assert(pSrc >= pState->GCPtr);
    310 
    311         for (unsigned i = 0; i < cb; i++)
    312             pDest[i] = pState->aOpcode[offset + i];
     298        &&  uSrcAddr + cbToRead <= pState->GCPtr + sizeof(pState->aOpcode))
     299    {
     300        unsigned offset = uSrcAddr - pState->GCPtr;
     301        Assert(uSrcAddr >= pState->GCPtr);
     302
     303        for (unsigned i = 0; i < cbToRead; i++)
     304            pbDst[i] = pState->aOpcode[offset + i];
    313305        return VINF_SUCCESS;
    314306    }
    315307
    316     rc = PGMPhysSimpleReadGCPtr(pVCpu, pDest, pSrc, cb);
    317     AssertMsgRC(rc, ("PGMPhysSimpleReadGCPtr failed for pSrc=%RGv cb=%x rc=%d\n", pSrc, cb, rc));
     308    rc = PGMPhysSimpleReadGCPtr(pVCpu, pbDst, uSrcAddr, cbToRead);
     309    AssertMsgRC(rc, ("PGMPhysSimpleReadGCPtr failed for uSrcAddr=%RTptr cbToRead=%x rc=%d\n", uSrcAddr, cbToRead, rc));
    318310# elif defined(IN_RING3)
    319     if (!PATMIsPatchGCAddr(pVM, pSrc))
    320     {
    321         int rc = PGMPhysSimpleReadGCPtr(pVCpu, pDest, pSrc, cb);
     311    if (!PATMIsPatchGCAddr(pVM, uSrcAddr))
     312    {
     313        int rc = PGMPhysSimpleReadGCPtr(pVCpu, pbDst, uSrcAddr, cbToRead);
    322314        AssertRC(rc);
    323315    }
    324316    else
    325         memcpy(pDest, PATMR3GCPtrToHCPtr(pVM, pSrc), cb);
     317        memcpy(pbDst, PATMR3GCPtrToHCPtr(pVM, uSrcAddr), cbToRead);
    326318
    327319# elif defined(IN_RC)
    328     if (!PATMIsPatchGCAddr(pVM, pSrc))
    329     {
    330         int rc = MMGCRamRead(pVM, pDest, (void *)(uintptr_t)pSrc, cb);
     320    if (!PATMIsPatchGCAddr(pVM, uSrcAddr))
     321    {
     322        int rc = MMGCRamRead(pVM, pbDst, (void *)(uintptr_t)uSrcAddr, cbToRead);
    331323        if (rc == VERR_ACCESS_DENIED)
    332324        {
    333325            /* Recently flushed; access the data manually. */
    334             rc = PGMPhysSimpleReadGCPtr(pVCpu, pDest, pSrc, cb);
     326            rc = PGMPhysSimpleReadGCPtr(pVCpu, pbDst, uSrcAddr, cbToRead);
    335327            AssertRC(rc);
    336328        }
    337329    }
    338330    else /* the hypervisor region is always present. */
    339         memcpy(pDest, (RTRCPTR)(uintptr_t)pSrc, cb);
     331        memcpy(pbDst, (RTRCPTR)(uintptr_t)uSrcAddr, cbToRead);
    340332
    341333# endif /* IN_RING3 */
     
    343335}
    344336
    345 
    346337#ifndef IN_RC
     338
    347339DECLINLINE(int) emDisCoreOne(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pDis, RTGCUINTPTR InstrGC, uint32_t *pOpsize)
    348340{
     
    467459#endif
    468460
    469     rc = DISCoreOneEx(GCPtrInstr, SELMGetCpuModeFromSelector(pVCpu, pCtxCore->eflags, pCtxCore->cs, (PCPUMSELREGHID)&pCtxCore->csHid),
     461    rc = DISCoreOneEx(GCPtrInstr,
     462                      SELMGetCpuModeFromSelector(pVCpu, pCtxCore->eflags, pCtxCore->cs, (PCPUMSELREGHID)&pCtxCore->csHid),
    470463                      emReadBytes, &State,
    471464                      pDis, pcbInstr);
     
    659652    Assert(!CPUMIsGuestIn64BitCode(pVCpu, pRegFrame));
    660653    /** @todo Rainy day: Test what happens when VERR_EM_INTERPRETER is returned by
    661      *        this function.  Faire that it may guru on us, thus not converted to
     654     *        this function.  Fear that it may guru on us, thus not converted to
    662655     *        IEM. */
    663656
  • trunk/src/VBox/VMM/VMMR3/CPUM.cpp

    r41310 r41658  
    906906            pCPUM->aGuestCpuIdCentaur[i] = pCPUM->GuestCpuIdDef;
    907907
    908     /* 
     908    /*
    909909     * Hypervisor identification.
    910910     *
     
    35253525
    35263526/**
    3527  * Instruction reader.
    3528  *
    3529  * @returns VBox status code.
    3530  * @param   PtrSrc      Address to read from.
    3531  *                      In our case this is relative to the selector pointed to by the 2nd user argument of uDisCpu.
    3532  * @param   pu8Dst      Where to store the bytes.
    3533  * @param   cbRead      Number of bytes to read.
    3534  * @param   uDisCpu     Pointer to the disassembler cpu state.
    3535  *                      In this context it's always pointer to the Core of a DBGFDISASSTATE.
    3536  */
    3537 static DECLCALLBACK(int) cpumR3DisasInstrRead(RTUINTPTR PtrSrc, uint8_t *pu8Dst, unsigned cbRead, void *uDisCpu)
    3538 {
    3539     PDISCPUSTATE pCpu = (PDISCPUSTATE)uDisCpu;
    3540     PCPUMDISASSTATE pState = (PCPUMDISASSTATE)pCpu->apvUserData[0];
    3541     Assert(cbRead > 0);
     3527 * @callback_method_impl{FNDISREADBYTES}
     3528 */
     3529static DECLCALLBACK(int) cpumR3DisasInstrRead(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead)
     3530{
     3531    PCPUMDISASSTATE pState = (PCPUMDISASSTATE)pDisState->apvUserData[0];
     3532    Assert(cbToRead > 0);
    35423533    for (;;)
    35433534    {
    3544         RTGCUINTPTR GCPtr = PtrSrc + pState->GCPtrSegBase;
     3535        RTGCUINTPTR GCPtr = uSrcAddr + pState->GCPtrSegBase;
    35453536
    35463537        /* Need to update the page translation? */
     
    35753566
    35763567        /* check the segment limit */
    3577         if (!pState->f64Bits && PtrSrc > pState->cbSegLimit)
     3568        if (!pState->f64Bits && uSrcAddr > pState->cbSegLimit)
    35783569            return VERR_OUT_OF_SELECTOR_BOUNDS;
    35793570
     
    35863577                cb = cbSeg;
    35873578        }
    3588         if (cb > cbRead)
    3589             cb = cbRead;
     3579        if (cb > cbToRead)
     3580            cb = cbToRead;
    35903581
    35913582        /* read and advance */
    3592         memcpy(pu8Dst, (char *)pState->pvPageR3 + (GCPtr & PAGE_OFFSET_MASK), cb);
    3593         cbRead -= cb;
    3594         if (!cbRead)
     3583        memcpy(pbDst, (char *)pState->pvPageR3 + (GCPtr & PAGE_OFFSET_MASK), cb);
     3584        cbToRead -= cb;
     3585        if (!cbToRead)
    35953586            return VINF_SUCCESS;
    3596         pu8Dst += cb;
    3597         PtrSrc += cb;
     3587        pbDst    += cb;
     3588        uSrcAddr += cb;
    35983589    }
    35993590}
     
    36293620     * Get selector information.
    36303621     */
     3622    DISCPUMODE enmDisCpuMode;
    36313623    if (    (pCtx->cr0 & X86_CR0_PE)
    36323624        &&   pCtx->eflags.Bits.u1VM == 0)
     
    36383630            State.GCPtrSegEnd     = pCtx->csHid.u32Limit + 1 + (RTGCUINTPTR)pCtx->csHid.u64Base;
    36393631            State.cbSegLimit      = pCtx->csHid.u32Limit;
    3640             pCpu->mode            = (State.f64Bits)
     3632            enmDisCpuMode         = (State.f64Bits)
    36413633                                    ? CPUMODE_64BIT
    36423634                                    : pCtx->csHid.Attr.n.u1DefBig
     
    36673659            State.GCPtrSegEnd     = SelInfo.cbLimit + 1 + (RTGCUINTPTR)SelInfo.GCPtrBase;
    36683660            State.cbSegLimit      = SelInfo.cbLimit;
    3669             pCpu->mode            = SelInfo.u.Raw.Gen.u1DefBig ? CPUMODE_32BIT : CPUMODE_16BIT;
     3661            enmDisCpuMode         = SelInfo.u.Raw.Gen.u1DefBig ? CPUMODE_32BIT : CPUMODE_16BIT;
    36703662        }
    36713663    }
     
    36733665    {
    36743666        /* real or V86 mode */
    3675         pCpu->mode            = CPUMODE_16BIT;
     3667        enmDisCpuMode         = CPUMODE_16BIT;
    36763668        State.GCPtrSegBase    = pCtx->cs * 16;
    36773669        State.GCPtrSegEnd     = 0xFFFFFFFF;
     
    36823674     * Disassemble the instruction.
    36833675     */
    3684     pCpu->pfnReadBytes    = cpumR3DisasInstrRead;
    3685     pCpu->apvUserData[0]  = &State;
    3686 
    36873676    uint32_t cbInstr;
    36883677#ifndef LOG_ENABLED
    3689     rc = DISInstr(pCpu, GCPtrPC, 0, &cbInstr, NULL);
     3678    rc = DISInstrWithReader(GCPtrPC, enmDisCpuMode, cpumR3DisasInstrRead, &State, pCpu, &cbInstr, NULL);
    36903679    if (RT_SUCCESS(rc))
    36913680    {
    36923681#else
    36933682    char szOutput[160];
    3694     rc = DISInstr(pCpu, GCPtrPC, 0, &cbInstr, &szOutput[0]);
     3683    rc = DISInstrWithReader(GCPtrPC, enmDisCpuMode, cpumR3DisasInstrRead, &State, pCpu, &cbInstr, szOutput);
    36953684    if (RT_SUCCESS(rc))
    36963685    {
  • trunk/src/VBox/VMM/VMMR3/CSAM.cpp

    r40449 r41658  
    724724
    725725/**
    726  * Read callback for disassembly function; supports reading bytes that cross a page boundary
    727  *
    728  * @returns VBox status code.
    729  * @param   pSrc        GC source pointer
    730  * @param   pDest       HC destination pointer
    731  * @param   size        Number of bytes to read
    732  * @param   dwUserdata  Callback specific user data (pCpu)
    733  *
    734  */
    735 static DECLCALLBACK(int) CSAMR3ReadBytes(RTUINTPTR pSrc, uint8_t *pDest, unsigned size, void *pvUserdata)
    736 {
    737     DISCPUSTATE  *pCpu     = (DISCPUSTATE *)pvUserdata;
    738     PVM           pVM      = (PVM)pCpu->apvUserData[0];
    739     RTHCUINTPTR   pInstrHC = (RTHCUINTPTR)pCpu->apvUserData[1];
    740     RTGCUINTPTR32 pInstrGC = (uintptr_t)pCpu->apvUserData[2];
    741     int           orgsize  = size;
    742     Assert(pVM->cCpus == 1);
    743     PVMCPU        pVCpu = VMMGetCpu0(pVM);
    744 
    745     /* We are not interested in patched instructions, so read the original opcode bytes. */
    746     /** @note single instruction patches (int3) are checked in CSAMR3AnalyseCallback */
    747     for (int i=0;i<orgsize;i++)
    748     {
    749         int rc = PATMR3QueryOpcode(pVM, (RTRCPTR)pSrc, pDest);
    750         if (RT_SUCCESS(rc))
    751         {
    752             pSrc++;
    753             pDest++;
    754             size--;
    755         }
    756         else
     726 * @callback_method_impl{FNDISREADBYTES}
     727 */
     728static DECLCALLBACK(int) CSAMR3ReadBytes(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead)
     729{
     730    PVM           pVM      = (PVM)pDisState->apvUserData[0];
     731    RTHCUINTPTR   pInstrHC = (RTHCUINTPTR)pDisState->apvUserData[1];
     732    RTGCUINTPTR32 pInstrGC = pDisState->uInstrAddr;
     733    int           orgsize  = cbToRead;
     734    PVMCPU        pVCpu    = VMMGetCpu0(pVM);
     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    for (int i = 0; i < orgsize; i++)
     739    {
     740        int rc = PATMR3QueryOpcode(pVM, (RTRCPTR)uSrcAddr, pbDst);
     741        if (RT_FAILURE(rc))
    757742            break;
    758     }
    759     if (size == 0)
     743        uSrcAddr++;
     744        pbDst++;
     745        cbToRead--;
     746    }
     747    if (cbToRead == 0)
    760748        return VINF_SUCCESS;
    761749
    762     if (PAGE_ADDRESS(pInstrGC) != PAGE_ADDRESS(pSrc + size - 1) && !PATMIsPatchGCAddr(pVM, pSrc))
    763     {
    764         return PGMPhysSimpleReadGCPtr(pVCpu, pDest, pSrc, size);
    765     }
    766     else
    767     {
    768         Assert(pInstrHC);
    769 
    770         /* pInstrHC is the base address; adjust according to the GC pointer. */
    771         pInstrHC = pInstrHC + (pSrc - pInstrGC);
    772 
    773         memcpy(pDest, (void *)pInstrHC, size);
    774     }
     750    if (PAGE_ADDRESS(pInstrGC) != PAGE_ADDRESS(uSrcAddr + cbToRead - 1) && !PATMIsPatchGCAddr(pVM, uSrcAddr))
     751        return PGMPhysSimpleReadGCPtr(pVCpu, pbDst, uSrcAddr, cbToRead);
     752
     753    Assert(pInstrHC);
     754
     755    /* pInstrHC is the base address; adjust according to the GC pointer. */
     756    pInstrHC = pInstrHC + (uSrcAddr - pInstrGC);
     757
     758    memcpy(pbDst, (void *)pInstrHC, cbToRead);
    775759
    776760    return VINF_SUCCESS;
    777761}
    778762
    779 inline int CSAMR3DISInstr(PVM pVM, DISCPUSTATE *pCpu, RTRCPTR InstrGC, uint8_t *InstrHC, uint32_t *pOpsize, char *pszOutput)
    780 {
    781     (pCpu)->pfnReadBytes  = CSAMR3ReadBytes;
    782     (pCpu)->apvUserData[0] = pVM;
     763DECLINLINE(int) CSAMR3DISInstr(PVM pVM, RTRCPTR InstrGC, uint8_t *InstrHC, DISCPUMODE enmCpuMode,
     764                               PDISCPUSTATE pCpu, uint32_t *pcbInstr, char *pszOutput)
     765{
    783766    (pCpu)->apvUserData[1] = InstrHC;
    784767    (pCpu)->apvUserData[2] = (void *)(uintptr_t)InstrGC; Assert(sizeof(InstrGC) <= sizeof(pCpu->apvUserData[0]));
    785768#ifdef DEBUG
    786     return DISInstrEx(pCpu, InstrGC, 0, pOpsize, pszOutput, OPTYPE_ALL);
     769    return DISInstrEx(InstrGC, 0, enmCpuMode, CSAMR3ReadBytes, pVM, OPTYPE_ALL,
     770                      pCpu, pcbInstr, pszOutput);
    787771#else
    788772    /* We are interested in everything except harmless stuff */
    789     return DISInstrEx(pCpu, InstrGC, 0, pOpsize, pszOutput, ~(OPTYPE_INVALID | OPTYPE_HARMLESS | OPTYPE_RRM_MASK));
     773    return DISInstrEx(InstrGC, 0, enmCpuMode, CSAMR3ReadBytes, pVM, ~(OPTYPE_INVALID | OPTYPE_HARMLESS | OPTYPE_RRM_MASK),
     774                      pCpu, pcbInstr, pszOutput);
    790775#endif
    791776}
     
    883868                Assert(VALID_PTR(pCurInstrHC));
    884869
    885                 cpu.mode = (fCode32) ? CPUMODE_32BIT : CPUMODE_16BIT;
    886                 rc = CSAMR3DISInstr(pVM, &cpu, pCurInstrGC, pCurInstrHC, &opsize, NULL);
     870                rc = CSAMR3DISInstr(pVM, pCurInstrGC, pCurInstrHC, (fCode32) ? CPUMODE_32BIT : CPUMODE_16BIT,
     871                                    &cpu, &opsize, NULL);
    887872            }
    888873            AssertRC(rc);
     
    10541039             * - push ebp after the filler (can extend this later); aligned at at least a 4 byte boundary
    10551040             */
    1056             for (int j=0;j<16;j++)
     1041            for (int j = 0; j < 16; j++)
    10571042            {
    10581043                uint8_t *pCurInstrHC = (uint8_t *)CSAMGCVirtToHCVirt(pVM, pCacheRec, pCurInstrGC);
     
    10641049                Assert(VALID_PTR(pCurInstrHC));
    10651050
    1066                 cpu.mode = (fCode32) ? CPUMODE_32BIT : CPUMODE_16BIT;
    10671051                STAM_PROFILE_START(&pVM->csam.s.StatTimeDisasm, a);
    10681052#ifdef DEBUG
    1069                 rc2 = CSAMR3DISInstr(pVM, &cpu, pCurInstrGC, pCurInstrHC, &opsize, szOutput);
     1053                rc2 = CSAMR3DISInstr(pVM, pCurInstrGC, pCurInstrHC, (fCode32) ? CPUMODE_32BIT : CPUMODE_16BIT,
     1054                                     &cpu, &opsize, szOutput);
    10701055                if (RT_SUCCESS(rc2)) Log(("CSAM Call Analysis: %s", szOutput));
    10711056#else
    1072                 rc2 = CSAMR3DISInstr(pVM, &cpu, pCurInstrGC, pCurInstrHC, &opsize, NULL);
     1057                rc2 = CSAMR3DISInstr(pVM, pCurInstrGC, pCurInstrHC, (fCode32) ? CPUMODE_32BIT : CPUMODE_16BIT,
     1058                                     &cpu, &opsize, NULL);
    10731059#endif
    10741060                STAM_PROFILE_STOP(&pVM->csam.s.StatTimeDisasm, a);
     
    12761262            Assert(VALID_PTR(pCurInstrHC));
    12771263
    1278             cpu.mode = (fCode32) ? CPUMODE_32BIT : CPUMODE_16BIT;
    12791264            STAM_PROFILE_START(&pVM->csam.s.StatTimeDisasm, a);
    12801265#ifdef DEBUG
    1281             rc2 = CSAMR3DISInstr(pVM, &cpu, pCurInstrGC, pCurInstrHC, &opsize, szOutput);
     1266            rc2 = CSAMR3DISInstr(pVM, pCurInstrGC, pCurInstrHC, (fCode32) ? CPUMODE_32BIT : CPUMODE_16BIT,
     1267                                 &cpu, &opsize, szOutput);
    12821268            if (RT_SUCCESS(rc2)) Log(("CSAM Analysis: %s", szOutput));
    12831269#else
    1284             rc2 = CSAMR3DISInstr(pVM, &cpu, pCurInstrGC, pCurInstrHC, &opsize, NULL);
     1270            rc2 = CSAMR3DISInstr(pVM, &cpu, pCurInstrGC, pCurInstrHC, (fCode32) ? CPUMODE_32BIT : CPUMODE_16BIT,
     1271                                 &cpu, &opsize, NULL);
    12851272#endif
    12861273            STAM_PROFILE_STOP(&pVM->csam.s.StatTimeDisasm, a);
  • trunk/src/VBox/VMM/VMMR3/DBGFDisas.cpp

    r38838 r41658  
    8282*   Internal Functions                                                         *
    8383*******************************************************************************/
    84 static DECLCALLBACK(int) dbgfR3DisasInstrRead(RTUINTPTR pSrc, uint8_t *pDest, uint32_t size, void *pvUserdata);
     84static FNDISREADBYTES dbgfR3DisasInstrRead;
    8585
    8686
     
    199199
    200200/**
    201  * Instruction reader.
    202  *
    203  * @returns VBox status code. (Why this is a int32_t and not just an int is also beyond me.)
    204  * @param   PtrSrc      Address to read from.
    205  *                      In our case this is relative to the selector pointed to by the 2nd user argument of uDisCpu.
    206  * @param   pu8Dst      Where to store the bytes.
    207  * @param   cbRead      Number of bytes to read.
    208  * @param   uDisCpu     Pointer to the disassembler cpu state. (Why this is a VBOXHUINTPTR is beyond me...)
    209  *                      In this context it's always pointer to the Core of a DBGFDISASSTATE.
    210  */
    211 static DECLCALLBACK(int) dbgfR3DisasInstrRead(RTUINTPTR PtrSrc, uint8_t *pu8Dst, uint32_t cbRead, void *pvDisCpu)
    212 {
    213     PDBGFDISASSTATE pState = (PDBGFDISASSTATE)pvDisCpu;
    214     Assert(cbRead > 0);
     201 * @callback_method_impl{FNDISREADBYTES}
     202 *
     203 * @remarks @a uSrcAddr is relative to the base address indicated by
     204 *          DBGFDISASSTATE::GCPtrSegBase.
     205 */
     206static DECLCALLBACK(int) dbgfR3DisasInstrRead(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead)
     207{
     208    PDBGFDISASSTATE pState = (PDBGFDISASSTATE)pDisState;
     209    Assert(cbToRead > 0);
    215210    for (;;)
    216211    {
    217         RTGCUINTPTR GCPtr = PtrSrc + pState->GCPtrSegBase;
     212        RTGCUINTPTR GCPtr = uSrcAddr + pState->GCPtrSegBase;
    218213
    219214        /* Need to update the page translation? */
     
    250245
    251246        /* check the segment limit */
    252         if (!pState->f64Bits && PtrSrc > pState->cbSegLimit)
     247        if (!pState->f64Bits && uSrcAddr > pState->cbSegLimit)
    253248            return VERR_OUT_OF_SELECTOR_BOUNDS;
    254249
     
    261256                cb = cbSeg;
    262257        }
    263         if (cb > cbRead)
    264             cb = cbRead;
     258        if (cb > cbToRead)
     259            cb = cbToRead;
    265260
    266261        /* read and advance */
    267         memcpy(pu8Dst, (char *)pState->pvPageR3 + (GCPtr & PAGE_OFFSET_MASK), cb);
    268         cbRead -= cb;
    269         if (!cbRead)
     262        memcpy(pbDst, (char *)pState->pvPageR3 + (GCPtr & PAGE_OFFSET_MASK), cb);
     263        cbToRead -= cb;
     264        if (!cbToRead)
    270265            return VINF_SUCCESS;
    271         pu8Dst += cb;
    272         PtrSrc += cb;
     266        pbDst    += cb;
     267        uSrcAddr += cb;
    273268    }
    274269}
     
    507502        uint32_t cbBits = State.Cpu.opsize;
    508503        uint8_t *pau8Bits = (uint8_t *)alloca(cbBits);
    509         rc = dbgfR3DisasInstrRead(GCPtr, pau8Bits, cbBits, &State);
     504        rc = dbgfR3DisasInstrRead(&State.Cpu, pau8Bits, GCPtr, cbBits);
    510505        AssertRC(rc);
    511506        if (fFlags & DBGF_DISAS_FLAGS_NO_ADDRESS)
  • trunk/src/VBox/VMM/VMMR3/PATM.cpp

    r39417 r41658  
    517517}
    518518
    519 /**
    520  * Read callback for disassembly function; supports reading bytes that cross a page boundary
    521  *
    522  * @returns VBox status code.
    523  * @param   pSrc        GC source pointer
    524  * @param   pDest       HC destination pointer
    525  * @param   size        Number of bytes to read
    526  * @param   pvUserdata  Callback specific user data (pCpu)
    527  *
    528  */
    529 int patmReadBytes(RTUINTPTR pSrc, uint8_t *pDest, unsigned size, void *pvUserdata)
    530 {
    531     DISCPUSTATE  *pCpu     = (DISCPUSTATE *)pvUserdata;
    532     PATMDISASM   *pDisInfo = (PATMDISASM *)pCpu->apvUserData[0];
    533     int           orgsize  = size;
    534 
    535     Assert(size);
    536     if (size == 0)
     519DECLCALLBACK(int) patmReadBytes(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead)
     520{
     521    PATMDISASM   *pDisInfo = (PATMDISASM *)pDisState->apvUserData[0];
     522    int           orgsize  = cbToRead;
     523
     524    Assert(cbToRead);
     525    if (cbToRead == 0)
    537526        return VERR_INVALID_PARAMETER;
    538527
     
    544533    if (pDisInfo->fReadFlags & PATMREAD_ORGCODE)
    545534    {
    546         for (int i=0;i<orgsize;i++)
    547         {
    548             int rc = PATMR3QueryOpcode(pDisInfo->pVM, (RTRCPTR)pSrc, pDest);
    549             if (RT_SUCCESS(rc))
    550             {
    551                 pSrc++;
    552                 pDest++;
    553                 size--;
    554             }
    555             else break;
    556         }
    557         if (size == 0)
     535        for (int i = 0; i < orgsize; i++)
     536        {
     537            int rc = PATMR3QueryOpcode(pDisInfo->pVM, (RTRCPTR)uSrcAddr, pbDst);
     538            if (RT_FAILURE(rc))
     539                break;
     540            uSrcAddr++;
     541            pbDst++;
     542            cbToRead--;
     543        }
     544        if (cbToRead == 0)
    558545            return VINF_SUCCESS;
    559546#ifdef VBOX_STRICT
     
    561548            &&  !(pDisInfo->fReadFlags & PATMREAD_NOCHECK))
    562549        {
    563             Assert(PATMR3IsInsidePatchJump(pDisInfo->pVM, pSrc, NULL) == false);
    564             Assert(PATMR3IsInsidePatchJump(pDisInfo->pVM, pSrc+size-1, NULL) == false);
     550            Assert(PATMR3IsInsidePatchJump(pDisInfo->pVM, uSrcAddr, NULL) == false);
     551            Assert(PATMR3IsInsidePatchJump(pDisInfo->pVM, uSrcAddr+cbToRead-1, NULL) == false);
    565552        }
    566553#endif
     
    568555
    569556    if (    !pDisInfo->pInstrHC
    570         ||  (   PAGE_ADDRESS(pDisInfo->pInstrGC) != PAGE_ADDRESS(pSrc + size - 1)
    571              && !PATMIsPatchGCAddr(pDisInfo->pVM, pSrc)))
    572     {
    573         Assert(!PATMIsPatchGCAddr(pDisInfo->pVM, pSrc));
    574         return PGMPhysSimpleReadGCPtr(&pDisInfo->pVM->aCpus[0], pDest, pSrc, size);
    575     }
    576     else
    577     {
    578         Assert(pDisInfo->pInstrHC);
    579 
    580         uint8_t *pInstrHC = pDisInfo->pInstrHC;
    581 
    582         Assert(pInstrHC);
    583 
    584         /* pInstrHC is the base address; adjust according to the GC pointer. */
    585         pInstrHC = pInstrHC + (pSrc - pDisInfo->pInstrGC);
    586 
    587         memcpy(pDest, (void *)pInstrHC, size);
    588     }
     557        ||  (   PAGE_ADDRESS(pDisInfo->pInstrGC) != PAGE_ADDRESS(uSrcAddr + cbToRead - 1)
     558             && !PATMIsPatchGCAddr(pDisInfo->pVM, uSrcAddr)))
     559    {
     560        Assert(!PATMIsPatchGCAddr(pDisInfo->pVM, uSrcAddr));
     561        return PGMPhysSimpleReadGCPtr(&pDisInfo->pVM->aCpus[0], pbDst, uSrcAddr, cbToRead);
     562    }
     563
     564    Assert(pDisInfo->pInstrHC);
     565
     566    uint8_t *pInstrHC = pDisInfo->pInstrHC;
     567
     568    Assert(pInstrHC);
     569
     570    /* pInstrHC is the base address; adjust according to the GC pointer. */
     571    pInstrHC = pInstrHC + (uSrcAddr - pDisInfo->pInstrGC);
     572
     573    memcpy(pbDst, (void *)pInstrHC, cbToRead);
    589574
    590575    return VINF_SUCCESS;
     
    28372822    if (pPatch->flags & PATMFL_INT3_REPLACEMENT_BLOCK)
    28382823    {
    2839         /*uint8_t ASMInt3 = 0xCC; - unused */
     2824        /*uint8_t bASMInt3 = 0xCC; - unused */
    28402825
    28412826        Log(("PATMR3PatchBlock %RRv -> int 3 callable patch.\n", pPatch->pPrivInstrGC));
     
    37863771static int patmActivateInt3Patch(PVM pVM, PPATCHINFO pPatch)
    37873772{
    3788     uint8_t ASMInt3 = 0xCC;
     3773    uint8_t bASMInt3 = 0xCC;
    37893774    int     rc;
    37903775
     
    37933778
    37943779    /* Replace first opcode byte with 'int 3'. */
    3795     rc = PGMPhysSimpleDirtyWriteGCPtr(VMMGetCpu0(pVM), pPatch->pPrivInstrGC, &ASMInt3, sizeof(ASMInt3));
     3780    rc = PGMPhysSimpleDirtyWriteGCPtr(VMMGetCpu0(pVM), pPatch->pPrivInstrGC, &bASMInt3, sizeof(bASMInt3));
    37963781    AssertRC(rc);
    37973782
    3798     pPatch->cbPatchJump = sizeof(ASMInt3);
     3783    pPatch->cbPatchJump = sizeof(bASMInt3);
    37993784
    38003785    return rc;
     
    38233808
    38243809/**
    3825  * Replace an instruction with a breakpoint (0xCC), that is handled dynamically in the guest context.
     3810 * Replace an instruction with a breakpoint (0xCC), that is handled dynamically
     3811 * in the raw-mode context.
    38263812 *
    38273813 * @returns VBox status code.
     
    38353821 *
    38363822 */
    3837 VMMR3DECL(int) PATMR3PatchInstrInt3(PVM pVM, RTRCPTR pInstrGC, R3PTRTYPE(uint8_t *) pInstrHC, DISCPUSTATE *pCpu, PPATCHINFO pPatch)
    3838 {
    3839     uint8_t ASMInt3 = 0xCC;
     3823VMMR3DECL(int) PATMR3PatchInstrInt3(PVM pVM, RTRCPTR pInstrGC, R3PTRTYPE(uint8_t *) pInstrHC, DISCPUSTATE *pCpu,
     3824                                    PPATCHINFO pPatch)
     3825{
     3826    uint8_t bASMInt3 = 0xCC;
    38403827    int rc;
    38413828
     
    38553842    rc = PGMPhysSimpleReadGCPtr(VMMGetCpu0(pVM), pPatch->aPrivInstr, pPatch->pPrivInstrGC, pPatch->cbPrivInstr);
    38563843    AssertRC(rc);
    3857     pPatch->cbPatchJump = sizeof(ASMInt3);  /* bit of a misnomer in this case; size of replacement instruction. */
     3844    pPatch->cbPatchJump = sizeof(bASMInt3);  /* bit of a misnomer in this case; size of replacement instruction. */
    38583845
    38593846    pPatch->flags |= PATMFL_INT3_REPLACEMENT;
  • trunk/src/VBox/VMM/VMMR3/VMMSwitcher.cpp

    r39402 r41658  
    837837                uint32_t cbInstr = 0;
    838838                char szDisas[256];
    839                 if (RT_SUCCESS(DISInstr(&Cpu, (uintptr_t)pu8CodeR3 + offCode, uBase - (uintptr_t)pu8CodeR3, &cbInstr, szDisas)))
     839                if (RT_SUCCESS(DISInstrWithOff(&Cpu, (uintptr_t)pu8CodeR3 + offCode, uBase - (uintptr_t)pu8CodeR3,
     840                                               &cbInstr, szDisas)))
    840841                    RTLogPrintf("  %04x: %s", offCode, szDisas); //for whatever reason szDisas includes '\n'.
    841842                else
  • trunk/src/VBox/VMM/VMMRC/PATMRC.cpp

    r40453 r41658  
    11/* $Id$ */
    22/** @file
    3  * PATM - Dynamic Guest OS Patching Manager - Guest Context
     3 * PATM - Dynamic Guest OS Patching Manager - Raw-mode Context.
    44 */
    55
    66/*
    7  * Copyright (C) 2006-2007 Oracle Corporation
     7 * Copyright (C) 2006-2012 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2121*******************************************************************************/
    2222#define LOG_GROUP LOG_GROUP_PATM
     23#include <VBox/vmm/patm.h>
    2324#include <VBox/vmm/cpum.h>
    2425#include <VBox/vmm/stam.h>
    25 #include <VBox/vmm/patm.h>
    2626#include <VBox/vmm/pgm.h>
    2727#include <VBox/vmm/mm.h>
    28 #include <VBox/sup.h>
     28#include <VBox/vmm/em.h>
     29#ifdef VBOX_WITH_IEM
     30# include <VBox/vmm/iem.h>
     31#endif
     32#include <VBox/vmm/selm.h>
    2933#include <VBox/vmm/mm.h>
    30 #include <VBox/param.h>
    31 #include <iprt/avl.h>
    3234#include "PATMInternal.h"
    3335#include "PATMA.h"
     
    3638#include <VBox/dis.h>
    3739#include <VBox/disopcode.h>
    38 #include <VBox/vmm/em.h>
    3940#include <VBox/err.h>
    40 #include <VBox/vmm/selm.h>
    4141#include <VBox/log.h>
    4242#include <iprt/assert.h>
     
    441441 * Checks if the int 3 was caused by a patched instruction
    442442 *
    443  * @returns VBox status
     443 * @returns Strict VBox status, includes all statuses that
     444 *          EMInterpretInstructionDisasState and
     445 * @retval  VINF_SUCCESS
     446 * @retval  VINF_PATM_PATCH_INT3
     447 * @retval  VINF_EM_RAW_EMULATE_INSTR
    444448 *
    445449 * @param   pVM         The VM handle.
    446450 * @param   pCtxCore    The relevant core context.
    447451 */
    448 VMMDECL(int) PATMHandleInt3PatchTrap(PVM pVM, PCPUMCTXCORE pRegFrame)
     452VMMRCDECL(int) PATMRCHandleInt3PatchTrap(PVM pVM, PCPUMCTXCORE pRegFrame)
    449453{
    450454    PPATMPATCHREC pRec;
     
    456460    if (PATMIsPatchGCAddr(pVM, pRegFrame->eip))
    457461    {
    458         /* @note hardcoded assumption about it being a single byte int 3 instruction. */
     462        /* Note! Hardcoded assumption about it being a single byte int 3 instruction. */
    459463        pRegFrame->eip--;
    460464        return VINF_PATM_PATCH_INT3;
     
    512516                return VINF_EM_RAW_EMULATE_INSTR;
    513517            }
    514             rc = DISCoreOne(&cpu, (uintptr_t)&pRec->patch.aPrivInstr[0], &cbOp);
     518
     519#ifdef VBOX_WITH_IEM
     520            VBOXSTRICTRC rcStrict;
     521            rcStrict = IEMExecOneWithOpcodes(VMMGetCpu0(pVM), pRegFrame, pRec->patch.pPrivInstrGC,
     522                                             pRec->patch.aPrivInstr, pRec->patch.cbPrivInstr);
     523            rc = VBOXSTRICTRC_TODO(rcStrict);
     524#else
     525            rc = DISCoreOneEx((uintptr_t)&pRec->patch.aPrivInstr[0], cpu.mode, NULL /*pfnReadBytes*/, NULL /*pvUser*/,
     526                              &cpu, &cbOp);
    515527            if (RT_FAILURE(rc))
    516528            {
     
    523535            rc = EMInterpretInstructionDisasState(VMMGetCpu0(pVM), &cpu, pRegFrame, 0 /* not relevant here */,
    524536                                                  EMCODETYPE_SUPERVISOR);
    525             if (rc != VINF_SUCCESS)
     537#endif
     538            if (RT_FAILURE(rc))
    526539            {
    527540                Log(("EMInterpretInstructionCPU failed with %Rrc\n", rc));
     
    530543                return VINF_EM_RAW_EMULATE_INSTR;
    531544            }
    532             return VINF_SUCCESS;
     545            return rc;
    533546        }
    534547    }
  • trunk/src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp

    r40486 r41658  
    421421        &&  !pRegFrame->eflags.Bits.u1VM)
    422422    {
    423         rc = PATMHandleInt3PatchTrap(pVM, pRegFrame);
    424         if (rc == VINF_SUCCESS || rc == VINF_EM_RAW_EMULATE_INSTR || rc == VINF_PATM_PATCH_INT3 || rc == VINF_PATM_DUPLICATE_FUNCTION)
     423        rc = PATMRCHandleInt3PatchTrap(pVM, pRegFrame);
     424        if (   rc == VINF_SUCCESS
     425            || rc == VINF_EM_RAW_EMULATE_INSTR
     426            || rc == VINF_PATM_PATCH_INT3
     427            || rc == VINF_PATM_DUPLICATE_FUNCTION)
    425428        {
    426429            rc = trpmGCExitTrap(pVM, pVCpu, rc, pRegFrame);
     
    745748            {
    746749                /* Int 3 replacement patch? */
    747                 if (PATMHandleInt3PatchTrap(pVM, pRegFrame) == VINF_SUCCESS)
     750                if (PATMRCHandleInt3PatchTrap(pVM, pRegFrame) == VINF_SUCCESS)
    748751                {
    749752                    AssertFailed();
  • trunk/src/VBox/VMM/include/PATMInternal.h

    r36801 r41658  
    273273    /** Size of the patch jump in the guest code. */
    274274    uint32_t                    cbPatchJump;
    275     /* Only valid for PATMFL_JUMP_CONFLICT patches */
     275    /** Only valid for PATMFL_JUMP_CONFLICT patches */
    276276    RTRCPTR                     pPatchJumpDestGC;
    277277    /** Offset of the patch code from the beginning of the patch memory area. */
     
    675675
    676676
    677 /**
    678  * Read callback for disassembly function; supports reading bytes that cross a page boundary
    679  *
    680  * @returns VBox status code.
    681  * @param   pSrc        GC source pointer
    682  * @param   pDest       HC destination pointer
    683  * @param   size        Number of bytes to read
    684  * @param   pvUserdata  Callback specific user data (pCpu)
    685  *
    686  */
    687 int patmReadBytes(RTUINTPTR pSrc, uint8_t *pDest, unsigned size, void *pvUserdata);
     677FNDISREADBYTES patmReadBytes;
    688678
    689679
     
    706696} PATMDISASM, *PPATMDISASM;
    707697
    708 inline bool PATMR3DISInstr(PVM pVM, PPATCHINFO pPatch, DISCPUSTATE *pCpu, RTRCPTR InstrGC,
    709                            uint8_t *InstrHC, uint32_t *pOpsize, char *pszOutput,
    710                            uint32_t fReadFlags = PATMREAD_ORGCODE)
     698DECLINLINE(bool) PATMR3DISInstr(PVM pVM, PPATCHINFO pPatch, PDISCPUSTATE pCpu, RTRCPTR InstrGC,
     699                                uint8_t *InstrHC, uint32_t *pOpsize, char *pszOutput,
     700                                uint32_t fReadFlags = PATMREAD_ORGCODE)
    711701{
    712702    PATMDISASM disinfo;
     
    718708    (pCpu)->pfnReadBytes = patmReadBytes;
    719709    (pCpu)->apvUserData[0] = &disinfo;
    720     return RT_SUCCESS(DISInstr(pCpu, InstrGC, 0, pOpsize, pszOutput));
     710    return RT_SUCCESS(DISInstrWithReader(InstrGC, pCpu->mode, patmReadBytes, &disinfo, pCpu, pOpsize, pszOutput));
    721711}
    722712#endif /* !IN_RC */
  • trunk/src/VBox/VMM/testcase/tstCompiler.cpp

    r38636 r41658  
    204204
    205205    memset(&Cpu, 0, sizeof(Cpu));
    206     Cpu.mode = CPUMODE_32BIT;
    207206    do
    208207    {
    209208        char        sz[256];
    210209        uint32_t    cbInstr = 0;
    211         if (RT_SUCCESS(DISInstr(&Cpu, uCur, 0, &cbInstr, sz)))
     210        if (RT_SUCCESS(DISInstr(uCur, CPUMODE_32BIT, &Cpu, &cbInstr, sz)))
    212211        {
    213212            RTPrintf("tstBitFields: %s", sz);
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