VirtualBox

Changeset 41760 in vbox


Ignore:
Timestamp:
Jun 15, 2012 3:56:20 PM (12 years ago)
Author:
vboxsync
Message:

DIS: Chagned FNDISREADBYTES to permit reading more bytes that the immeidate request. Not using the read-ahead feature in any important code path yet, that's comming next, bit by bit.

Location:
trunk
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/dis.h

    r41747 r41760  
    497497
    498498/**
    499  * Callback for reading opcode bytes.
    500  *
    501  * @param   pDisState       Pointer to the CPU state.  The primary user argument
    502  *                          can be retrived from DISCPUSTATE::pvUser. If
    503  *                          more is required these can be passed in the
    504  *                          subsequent slots.
    505  * @param   pbDst           Pointer to output buffer.
    506  * @param   uSrcAddr        The address to start reading at.
    507  * @param   cbToRead        The number of bytes to read.
    508  */
    509 typedef DECLCALLBACK(int) FNDISREADBYTES(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead);
     499 * Callback for reading instruction bytes.
     500 *
     501 * @returns VBox status code, bytes in DISCPUSTATE::abInstr and byte count in
     502 *          DISCPUSTATE::cbCachedInstr.
     503 * @param   pDis            Pointer to the disassembler state.  The user
     504 *                          argument can be found in DISCPUSTATE::pvUser if
     505 *                          needed.
     506 * @param   offInstr        The offset relative to the start of the instruction.
     507 *
     508 *                          To get the source address, add this to
     509 *                          DISCPUSTATE::uInstrAddr.
     510 *
     511 *                          To calculate the destination buffer address, use it
     512 *                          as an index into DISCPUSTATE::abInstr.
     513 *
     514 * @param   cbMinRead       The minimum number of bytes to read.
     515 * @param   cbMaxRead       The maximum number of bytes that may be read.
     516 */
     517typedef DECLCALLBACK(int) FNDISREADBYTES(PDISCPUSTATE pDis, uint8_t offInstr, uint8_t cbMinRead, uint8_t cbMaxRead);
    510518/** Pointer to a opcode byte reader. */
    511519typedef FNDISREADBYTES *PFNDISREADBYTES;
  • trunk/src/VBox/Devices/PC/BIOS-new/MakeDebianBiosAssembly.cpp

    r41734 r41760  
    908908 * @remarks @a uSrcAddr is the flat address.
    909909 */
    910 static DECLCALLBACK(int) disReadOpcodeBytes(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead)
    911 {
    912     if (uSrcAddr + cbToRead >= VBOX_BIOS_BASE + _64K)
    913     {
    914         RT_BZERO(pbDst, cbToRead);
    915         if (uSrcAddr >= VBOX_BIOS_BASE + _64K)
     910static DECLCALLBACK(int) disReadOpcodeBytes(PDISCPUSTATE pDis, uint8_t offInstr, uint8_t cbMinRead, uint8_t cbMaxRead)
     911{
     912    RTUINTPTR   offBios  = pDis->uInstrAddr + offInstr - VBOX_BIOS_BASE;
     913    size_t      cbToRead = cbMaxRead;
     914    if (offBios + cbToRead > _64K)
     915    {
     916        if (offBios >= _64K)
    916917            cbToRead = 0;
    917918        else
    918             cbToRead = VBOX_BIOS_BASE + _64K - uSrcAddr;
    919     }
    920     memcpy(pbDst, &g_pbImg[uSrcAddr - VBOX_BIOS_BASE], cbToRead);
    921     NOREF(pDisState);
     919            cbToRead = _64K - offBios;
     920    }
     921    memcpy(&pDis->abInstr[offInstr], &g_pbImg[offBios], cbToRead);
     922    pDis->cbCachedInstr = offInstr + cbToRead;
    922923    return VINF_SUCCESS;
    923924}
  • trunk/src/VBox/Disassembler/DisasmCore.cpp

    r41753 r41760  
    6565static uint32_t disReadDWord(PDISCPUSTATE pCpu, RTUINTPTR pAddress);
    6666static uint64_t disReadQWord(PDISCPUSTATE pCpu, RTUINTPTR pAddress);
    67 static DECLCALLBACK(int) disReadBytesDefault(PDISCPUSTATE pCpu, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead);
     67static DECLCALLBACK(int) disReadBytesDefault(PDISCPUSTATE pDis, uint8_t offInstr, uint8_t cbMinRead, uint8_t cbMaxRead);
    6868
    6969
     
    23902390
    23912391
    2392 static DECLCALLBACK(int) disReadBytesDefault(PDISCPUSTATE pCpu, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead)
     2392static DECLCALLBACK(int) disReadBytesDefault(PDISCPUSTATE pDis, uint8_t offInstr, uint8_t cbMinRead, uint8_t cbMaxRead)
    23932393{
    23942394#ifdef IN_RING0
    23952395    AssertMsgFailed(("disReadWord with no read callback in ring 0!!\n"));
    2396     RT_BZERO(pbDst, cbToRead);
     2396    RT_BZERO(&pDis->abInstr[offInstr], cbMaxRead);
     2397    pDis->cbCachedInstr = offInstr + cbMaxRead;
    23972398    return VERR_DIS_NO_READ_CALLBACK;
    23982399#else
    2399     memcpy(pbDst, (void const *)(uintptr_t)uSrcAddr, cbToRead);
     2400    memcpy(&pDis->abInstr[offInstr], (uint8_t const *)(uintptr_t)pDis->uInstrAddr + offInstr, cbMaxRead);
     2401    pDis->cbCachedInstr = offInstr + cbMaxRead;
    24002402    return VINF_SUCCESS;
    24012403#endif
     
    24372439
    24382440    /*
    2439      * Do the read.  No need to zero anything, abInstr is already zeroed by the
    2440      * DISInstrEx API.
     2441     * Do the read.
     2442     * (No need to zero anything on failure as abInstr is already zeroed by the
     2443     * DISInstrEx API.)
    24412444     */
    2442     /** @todo Change the callback API so it can read more, thus avoid lots of
    2443      *        calls or it doing its own caching. */
    2444     int rc = pCpu->pfnReadBytes(pCpu, &pCpu->abInstr[off], pCpu->uInstrAddr + off, cbMin);
    2445     if (RT_FAILURE(rc))
     2445    int rc = pCpu->pfnReadBytes(pCpu, off, cbMin, sizeof(pCpu->abInstr) - off);
     2446    if (RT_SUCCESS(rc))
     2447    {
     2448        Assert(pCpu->cbCachedInstr >= off + cbMin);
     2449        Assert(pCpu->cbCachedInstr <= sizeof(pCpu->abInstr));
     2450    }
     2451    else
    24462452    {
    24472453        Log(("disReadMore failed with rc=%Rrc!!\n", rc));
    24482454        pCpu->rc = VERR_DIS_MEM_READ;
    24492455    }
    2450     pCpu->cbCachedInstr = off + cbMin;
    24512456}
    24522457
  • trunk/src/VBox/Disassembler/testcase/tstDisasm-2.cpp

    r41737 r41760  
    167167/**
    168168 * Callback for reading bytes.
    169  *
    170  * @todo This should check that the disassembler doesn't do unnecessary reads,
    171  *       however the current doesn't do this and is just complicated...
    172  */
    173 static DECLCALLBACK(int) MyDisasInstrRead(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead)
    174 {
    175     PMYDISSTATE pState = (PMYDISSTATE)pDisState;
     169 */
     170static DECLCALLBACK(int) MyDisasInstrRead(PDISCPUSTATE pDis, uint8_t offInstr, uint8_t cbMinRead, uint8_t cbMaxRead)
     171{
     172    PMYDISSTATE pState   = (PMYDISSTATE)pDis;
     173    RTUINTPTR   uSrcAddr = pState->Cpu.uInstrAddr + offInstr;
    176174    if (RT_LIKELY(   pState->uNextAddr == uSrcAddr
    177                   && pState->cbLeft >= cbToRead))
     175                  && pState->cbLeft >= cbMinRead))
    178176    {
    179177        /*
    180178         * Straight forward reading.
    181179         */
    182         if (cbToRead == 1)
     180        //size_t cbToRead    = cbMaxRead;
     181        size_t cbToRead    = cbMinRead;
     182        memcpy(&pState->Cpu.abInstr[offInstr], pState->pbNext, cbToRead);
     183        pState->Cpu.cbCachedInstr = offInstr + cbToRead;
     184        pState->pbNext    += cbToRead;
     185        pState->cbLeft    -= cbToRead;
     186        pState->uNextAddr += cbToRead;
     187        return VINF_SUCCESS;
     188    }
     189
     190    if (pState->uNextAddr == uSrcAddr)
     191    {
     192        /*
     193         * Reading too much.
     194         */
     195        if (pState->cbLeft > 0)
    183196        {
    184             pState->cbLeft--;
    185             *pbDst = *pState->pbNext++;
    186             pState->uNextAddr++;
     197            memcpy(&pState->Cpu.abInstr[offInstr], pState->pbNext, pState->cbLeft);
     198            offInstr          += (uint8_t)pState->cbLeft;
     199            cbMinRead         -= (uint8_t)pState->cbLeft;
     200            pState->pbNext    += pState->cbLeft;
     201            pState->uNextAddr += pState->cbLeft;
     202            pState->cbLeft     = 0;
    187203        }
    188         else
    189         {
    190             memcpy(pbDst, pState->pbNext, cbToRead);
    191             pState->pbNext += cbToRead;
    192             pState->cbLeft -= cbToRead;
    193             pState->uNextAddr += cbToRead;
    194         }
     204        memset(&pState->Cpu.abInstr[offInstr], 0xcc, cbMinRead);
     205        pState->rc = VERR_EOF;
    195206    }
    196207    else
    197208    {
    198209        /*
    199          * Jumping up the stream.
    200          * This occurs when the byte sequence is added to the output string.
     210         * Non-sequential read, that's an error.
    201211         */
    202         uint64_t offReq64 = uSrcAddr - pState->uAddress;
    203         if (offReq64 < 32)
    204         {
    205             uint32_t offReq = offReq64;
    206             uintptr_t off = pState->pbNext - pState->pbInstr;
    207             if (off + pState->cbLeft <= offReq)
    208             {
    209                 pState->pbNext += pState->cbLeft;
    210                 pState->uNextAddr += pState->cbLeft;
    211                 pState->cbLeft = 0;
    212 
    213                 memset(pbDst, 0xcc, cbToRead);
    214                 pState->rc = VERR_EOF;
    215                 return VERR_EOF;
    216             }
    217 
    218             /* reset the stream. */
    219             pState->cbLeft += off;
    220             pState->pbNext = pState->pbInstr;
    221             pState->uNextAddr = pState->uAddress;
    222 
    223             /* skip ahead. */
    224             pState->cbLeft -= offReq;
    225             pState->pbNext += offReq;
    226             pState->uNextAddr += offReq;
    227 
    228             /* do the reading. */
    229             if (pState->cbLeft >= cbToRead)
    230             {
    231                 memcpy(pbDst, pState->pbNext, cbToRead);
    232                 pState->cbLeft -= cbToRead;
    233                 pState->pbNext += cbToRead;
    234                 pState->uNextAddr += cbToRead;
    235             }
    236             else
    237             {
    238                 if (pState->cbLeft > 0)
    239                 {
    240                     memcpy(pbDst, pState->pbNext, pState->cbLeft);
    241                     pbDst += pState->cbLeft;
    242                     cbToRead -= (uint32_t)pState->cbLeft;
    243                     pState->pbNext += pState->cbLeft;
    244                     pState->uNextAddr += pState->cbLeft;
    245                     pState->cbLeft = 0;
    246                 }
    247                 memset(pbDst, 0xcc, cbToRead);
    248                 pState->rc = VERR_EOF;
    249                 return VERR_EOF;
    250             }
    251         }
    252         else
    253         {
    254             RTStrmPrintf(g_pStdErr, "Reading before current instruction!\n");
    255             memset(pbDst, 0x90, cbToRead);
    256             pState->rc = VERR_INTERNAL_ERROR;
    257             return VERR_INTERNAL_ERROR;
    258         }
    259     }
    260 
    261     return VINF_SUCCESS;
     212        RTStrmPrintf(g_pStdErr, "Reading before current instruction!\n");
     213        memset(&pState->Cpu.abInstr[offInstr], 0x90, cbMinRead);
     214        pState->rc = VERR_INTERNAL_ERROR;
     215    }
     216    pState->Cpu.cbCachedInstr = offInstr + cbMinRead;
     217    return pState->rc;
    262218}
    263219
     
    340296                          || State.Cpu.pCurInstr->uOpcode == OP_INVALID
    341297                          || State.Cpu.pCurInstr->uOpcode == OP_ILLUD2
    342                           || (    State.enmUndefOp == kUndefOp_DefineByte
     298                          || (   State.enmUndefOp == kUndefOp_DefineByte
    343299                              && !MyDisasIsValidInstruction(&State.Cpu));
    344300            if (State.fUndefOp && State.enmUndefOp == kUndefOp_DefineByte)
     
    347303                {
    348304                    State.Cpu.abInstr[0] = 0;
    349                     State.Cpu.pfnReadBytes(&State.Cpu, &State.Cpu.abInstr[0], State.uAddress, 1);
     305                    State.Cpu.pfnReadBytes(&State.Cpu, 0, 1, 1);
    350306                    State.cbInstr = 1;
    351307                }
  • trunk/src/VBox/Runtime/testcase/tstLdr-3.cpp

    r41736 r41760  
    147147 * @callback_method_impl{FNDISREADBYTES}
    148148 */
    149 static DECLCALLBACK(int) MyReadBytes(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead)
    150 {
    151     memcpy(pbDst, (uint8_t const *)((uintptr_t)uSrcAddr + (uintptr_t)pDisState->pvUser), cbToRead);
     149static DECLCALLBACK(int) MyReadBytes(PDISCPUSTATE pDis, uint8_t offInstr, uint8_t cbMinRead, uint8_t cbMaxRead)
     150{
     151    uint8_t const *pbSrc = (uint8_t const *)((uintptr_t)pDis->uInstrAddr + (uintptr_t)pDis->pvUser + offInstr);
     152    memcpy(&pDis->abInstr[offInstr], pbSrc, cbMinRead);
     153    pDis->cbCachedInstr = offInstr + cbMinRead;
    152154    return VINF_SUCCESS;
    153155}
  • trunk/src/VBox/Runtime/testcase/tstLdr-4.cpp

    r38636 r41760  
    6161    else if (!strcmp(pszSymbol, "RTAssertMsg2Weak")     || !strcmp(pszSymbol, "_RTAssertMsg2Weak"))
    6262        *pValue = (uintptr_t)RTAssertMsg1Weak;
     63    else if (!strcmp(pszSymbol, "RTAssertMsg1")         || !strcmp(pszSymbol, "_RTAssertMsg1"))
     64        *pValue = (uintptr_t)RTAssertMsg1;
     65    else if (!strcmp(pszSymbol, "RTAssertMsg2")         || !strcmp(pszSymbol, "_RTAssertMsg2"))
     66        *pValue = (uintptr_t)RTAssertMsg2;
     67    else if (!strcmp(pszSymbol, "RTAssertMsg2V")        || !strcmp(pszSymbol, "_RTAssertMsg2V"))
     68        *pValue = (uintptr_t)RTAssertMsg2V;
     69    else if (!strcmp(pszSymbol, "RTAssertMayPanic")     || !strcmp(pszSymbol, "_RTAssertMayPanic"))
     70        *pValue = (uintptr_t)RTAssertMayPanic;
    6371    else if (!strcmp(pszSymbol, "RTLogDefaultInstance") || !strcmp(pszSymbol, "_RTLogDefaultInstance"))
    6472        *pValue = (uintptr_t)RTLogDefaultInstance;
  • trunk/src/VBox/Runtime/testcase/tstLdrDisasmTest.cpp

    r41737 r41760  
    8383 * @callback_method_impl{FNDISREADBYTES}
    8484 */
    85 static DECLCALLBACK(int) DisasmTest1ReadCode(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead)
     85static DECLCALLBACK(int) DisasmTest1ReadCode(PDISCPUSTATE pDis, uint8_t offInstr, uint8_t cbMinRead, uint8_t cbMaxRead)
    8686{
    87     NOREF(pDisState);
    88     while (cbToRead > 0)
    89     {
    90         *pbDst = g_ab32BitCode[uSrcAddr];
    91 
    92         /* next */
    93         pbDst++;
    94         uSrcAddr++;
    95         cbToRead--;
    96     }
    97     return 0;
     87    size_t cb = cbMaxRead;
     88    if (cb + pDis->uInstrAddr + offInstr > sizeof(g_ab32BitCode))
     89        cb = cbMinRead;
     90    memcpy(&pDis->abInstr[offInstr], &g_ab32BitCode[pDis->uInstrAddr + offInstr], cb);
     91    pDis->cbCachedInstr = offInstr + cb;
     92    return VINF_SUCCESS;
    9893}
    9994
  • trunk/src/VBox/VMM/VMMAll/EMAll.cpp

    r41744 r41760  
    284284 * @callback_method_impl{FNDISREADBYTES}
    285285 */
    286 static DECLCALLBACK(int) emReadBytes(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead)
    287 {
    288     PEMDISSTATE   pState = (PEMDISSTATE)pDisState->pvUser;
     286static DECLCALLBACK(int) emReadBytes(PDISCPUSTATE pDis, uint8_t offInstr, uint8_t cbMinRead, uint8_t cbMaxRead)
     287{
     288    PEMDISSTATE   pState = (PEMDISSTATE)pDis->pvUser;
    289289# ifndef IN_RING0
    290290    PVM           pVM    = pState->pVM;
    291291# endif
    292292    PVMCPU        pVCpu  = pState->pVCpu;
     293    /** @todo Rewrite this to make full use of the abInstr buffer and drop our extra
     294     *        caching buffer.  Just playing safe at first... */
     295    uint8_t      *pbDst    = &pDis->abInstr[offInstr];
     296    RTUINTPTR     uSrcAddr = pDis->uInstrAddr + offInstr;
     297    size_t        cbToRead = cbMinRead;
    293298
    294299# ifdef IN_RING0
    295     int rc;
     300    int           rc;
    296301
    297302    if (    pState->GCPtr
     
    303308        for (unsigned i = 0; i < cbToRead; i++)
    304309            pbDst[i] = pState->aOpcode[offset + i];
     310        pDis->cbCachedInstr = offInstr + cbToRead;
    305311        return VINF_SUCCESS;
    306312    }
     
    308314    rc = PGMPhysSimpleReadGCPtr(pVCpu, pbDst, uSrcAddr, cbToRead);
    309315    AssertMsgRC(rc, ("PGMPhysSimpleReadGCPtr failed for uSrcAddr=%RTptr cbToRead=%x rc=%d\n", uSrcAddr, cbToRead, rc));
     316
    310317# elif defined(IN_RING3)
    311318    if (!PATMIsPatchGCAddr(pVM, uSrcAddr))
     
    332339
    333340# endif /* IN_RING3 */
     341    pDis->cbCachedInstr = offInstr + cbToRead;
    334342    return VINF_SUCCESS;
    335343}
  • trunk/src/VBox/VMM/VMMR3/CPUM.cpp

    r41731 r41760  
    55
    66/*
    7  * Copyright (C) 2006-2010 Oracle Corporation
     7 * Copyright (C) 2006-2012 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    35273527 * @callback_method_impl{FNDISREADBYTES}
    35283528 */
    3529 static DECLCALLBACK(int) cpumR3DisasInstrRead(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead)
    3530 {
    3531     PCPUMDISASSTATE pState = (PCPUMDISASSTATE)pDisState->pvUser;
    3532     Assert(cbToRead > 0);
     3529static DECLCALLBACK(int) cpumR3DisasInstrRead(PDISCPUSTATE pDis, uint8_t offInstr, uint8_t cbMinRead, uint8_t cbMaxRead)
     3530{
     3531    PCPUMDISASSTATE pState = (PCPUMDISASSTATE)pDis->pvUser;
    35333532    for (;;)
    35343533    {
    3535         RTGCUINTPTR GCPtr = uSrcAddr + pState->GCPtrSegBase;
    3536 
    3537         /* Need to update the page translation? */
    3538         if (    !pState->pvPageR3
    3539             ||  (GCPtr >> PAGE_SHIFT) != (pState->pvPageGC >> PAGE_SHIFT))
     3534        RTGCUINTPTR GCPtr = pDis->uInstrAddr + offInstr + pState->GCPtrSegBase;
     3535
     3536        /*
     3537         * Need to update the page translation?
     3538         */
     3539        if (   !pState->pvPageR3
     3540            || (GCPtr >> PAGE_SHIFT) != (pState->pvPageGC >> PAGE_SHIFT))
    35403541        {
    35413542            int rc = VINF_SUCCESS;
     
    35653566        }
    35663567
    3567         /* check the segment limit */
    3568         if (!pState->f64Bits && uSrcAddr > pState->cbSegLimit)
     3568        /*
     3569         * Check the segment limit.
     3570         */
     3571        if (!pState->f64Bits && pDis->uInstrAddr + offInstr > pState->cbSegLimit)
    35693572            return VERR_OUT_OF_SELECTOR_BOUNDS;
    35703573
    3571         /* calc how much we can read */
     3574        /*
     3575         * Calc how much we can read.
     3576         */
    35723577        uint32_t cb = PAGE_SIZE - (GCPtr & PAGE_OFFSET_MASK);
    35733578        if (!pState->f64Bits)
     
    35773582                cb = cbSeg;
    35783583        }
    3579         if (cb > cbToRead)
    3580             cb = cbToRead;
    3581 
    3582         /* read and advance */
    3583         memcpy(pbDst, (char *)pState->pvPageR3 + (GCPtr & PAGE_OFFSET_MASK), cb);
    3584         cbToRead -= cb;
    3585         if (!cbToRead)
     3584        /** @todo read more later. */
     3585        //if (cb > cbMaxRead) - later
     3586        //    cb = cbMaxRead;
     3587        if (cb > cbMinRead)
     3588            cb = cbMinRead;
     3589
     3590        /*
     3591         * Read and advance or exit.
     3592         */
     3593        memcpy(&pDis->abInstr[offInstr], (uint8_t *)pState->pvPageR3 + (GCPtr & PAGE_OFFSET_MASK), cb);
     3594        offInstr  += (uint8_t)cb;
     3595        if (cb >= cbMinRead)
     3596        {
     3597            pDis->cbCachedInstr = offInstr;
    35863598            return VINF_SUCCESS;
    3587         pbDst    += cb;
    3588         uSrcAddr += cb;
     3599        }
     3600        cbMinRead -= (uint8_t)cb;
     3601        cbMaxRead -= (uint8_t)cb;
    35893602    }
    35903603}
  • trunk/src/VBox/VMM/VMMR3/CSAM.cpp

    r41741 r41760  
    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
     
    726726 * @callback_method_impl{FNDISREADBYTES}
    727727 */
    728 static DECLCALLBACK(int) CSAMR3ReadBytes(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead)
    729 {
    730     PVM           pVM      = (PVM)pDisState->pvUser;
    731     RTHCUINTPTR   pInstrHC = (RTHCUINTPTR)pDisState->pvUser2;
    732     RTGCUINTPTR32 pInstrGC = pDisState->uInstrAddr;
    733     int           orgsize  = cbToRead;
    734     PVMCPU        pVCpu    = VMMGetCpu0(pVM);
     728static DECLCALLBACK(int) CSAMR3ReadBytes(PDISCPUSTATE pDis, uint8_t offInstr, uint8_t cbMinRead, uint8_t cbMaxRead)
     729{
     730    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. */
    735735
    736736    /* We are not interested in patched instructions, so read the original opcode bytes.
    737737       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))
     738    while (cbMinRead > 0)
     739    {
     740        int rc2 = PATMR3QueryOpcode(pVM, (RTRCPTR)pDis->uInstrAddr + offInstr, &pDis->abInstr[offInstr]);
     741        if (RT_FAILURE(rc2))
    742742            break;
    743         uSrcAddr++;
    744         pbDst++;
    745         cbToRead--;
    746     }
    747     if (cbToRead == 0)
    748         return VINF_SUCCESS;
    749 
    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);
    759 
    760     return VINF_SUCCESS;
     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        }
     769    }
     770
     771    pDis->cbCachedInstr = offInstr;
     772    return rc;
    761773}
    762774
  • trunk/src/VBox/VMM/VMMR3/DBGFDisas.cpp

    r41732 r41760  
    6767    void const     *pvPageR3;
    6868    /** Pointer to the current page - GC Ptr. */
    69     RTGCPTR         pvPageGC;
     69    RTGCPTR         GCPtrPage;
    7070    /** Pointer to the next instruction (relative to GCPtrSegBase). */
    7171    RTGCUINTPTR     GCPtrNext;
     
    105105    pState->cbSegLimit      = pSelInfo->cbLimit;
    106106    pState->enmMode         = enmMode;
    107     pState->pvPageGC        = 0;
     107    pState->GCPtrPage       = 0;
    108108    pState->pvPageR3        = NULL;
    109109    pState->hAs             = pSelInfo->fFlags & DBGFSELINFO_FLAGS_HYPER /** @todo Deal more explicitly with RC in DBGFR3Disas*. */
     
    201201 * @callback_method_impl{FNDISREADBYTES}
    202202 *
    203  * @remarks @a uSrcAddr is relative to the base address indicated by
     203 * @remarks The source is relative to the base address indicated by
    204204 *          DBGFDISASSTATE::GCPtrSegBase.
    205205 */
    206 static DECLCALLBACK(int) dbgfR3DisasInstrRead(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead)
    207 {
    208     PDBGFDISASSTATE pState = (PDBGFDISASSTATE)pDisState;
    209     Assert(cbToRead > 0);
     206static DECLCALLBACK(int) dbgfR3DisasInstrRead(PDISCPUSTATE pDis, uint8_t offInstr, uint8_t cbMinRead, uint8_t cbMaxRead)
     207{
     208    PDBGFDISASSTATE pState = (PDBGFDISASSTATE)pDis;
    210209    for (;;)
    211210    {
    212         RTGCUINTPTR GCPtr = uSrcAddr + pState->GCPtrSegBase;
    213 
    214         /* Need to update the page translation? */
     211        RTGCUINTPTR GCPtr = pDis->uInstrAddr + offInstr + pState->GCPtrSegBase;
     212
     213        /*
     214         * Need to update the page translation?
     215         */
    215216        if (    !pState->pvPageR3
    216             ||  (GCPtr >> PAGE_SHIFT) != (pState->pvPageGC >> PAGE_SHIFT))
     217            ||  (GCPtr >> PAGE_SHIFT) != (pState->GCPtrPage >> PAGE_SHIFT))
    217218        {
    218219            int rc = VINF_SUCCESS;
    219220
    220221            /* translate the address */
    221             pState->pvPageGC = GCPtr & PAGE_BASE_GC_MASK;
    222             if (MMHyperIsInsideArea(pState->pVM, pState->pvPageGC))
     222            pState->GCPtrPage = GCPtr & PAGE_BASE_GC_MASK;
     223            if (MMHyperIsInsideArea(pState->pVM, pState->GCPtrPage))
    223224            {
    224                 pState->pvPageR3 = MMHyperRCToR3(pState->pVM, (RTRCPTR)pState->pvPageGC);
     225                pState->pvPageR3 = MMHyperRCToR3(pState->pVM, (RTRCPTR)pState->GCPtrPage);
    225226                if (!pState->pvPageR3)
    226227                    rc = VERR_INVALID_POINTER;
     
    232233
    233234                if (pState->enmMode <= PGMMODE_PROTECTED)
    234                     rc = PGMPhysGCPhys2CCPtrReadOnly(pState->pVM, pState->pvPageGC, &pState->pvPageR3, &pState->PageMapLock);
     235                    rc = PGMPhysGCPhys2CCPtrReadOnly(pState->pVM, pState->GCPtrPage, &pState->pvPageR3, &pState->PageMapLock);
    235236                else
    236                     rc = PGMPhysGCPtr2CCPtrReadOnly(pState->pVCpu, pState->pvPageGC, &pState->pvPageR3, &pState->PageMapLock);
     237                    rc = PGMPhysGCPtr2CCPtrReadOnly(pState->pVCpu, pState->GCPtrPage, &pState->pvPageR3, &pState->PageMapLock);
    237238                pState->fLocked = RT_SUCCESS_NP(rc);
    238239            }
     
    244245        }
    245246
    246         /* check the segment limit */
    247         if (!pState->f64Bits && uSrcAddr > pState->cbSegLimit)
     247        /*
     248         * Check the segment limit.
     249         */
     250        if (!pState->f64Bits && pDis->uInstrAddr + offInstr > pState->cbSegLimit)
    248251            return VERR_OUT_OF_SELECTOR_BOUNDS;
    249252
    250         /* calc how much we can read */
     253        /*
     254         * Calc how much we can read, maxing out the read.
     255         */
    251256        uint32_t cb = PAGE_SIZE - (GCPtr & PAGE_OFFSET_MASK);
    252257        if (!pState->f64Bits)
     
    256261                cb = cbSeg;
    257262        }
    258         if (cb > cbToRead)
    259             cb = cbToRead;
    260 
    261         /* read and advance */
    262         memcpy(pbDst, (char *)pState->pvPageR3 + (GCPtr & PAGE_OFFSET_MASK), cb);
    263         cbToRead -= cb;
    264         if (!cbToRead)
     263        if (cb > cbMaxRead)
     264            cb = cbMaxRead;
     265
     266        /*
     267         * Read and advance,
     268         */
     269        memcpy(&pDis->abInstr[offInstr], (char *)pState->pvPageR3 + (GCPtr & PAGE_OFFSET_MASK), cb);
     270        offInstr  += (uint8_t)cb;
     271        if (cb >= cbMinRead)
     272        {
     273            pDis->cbCachedInstr = offInstr;
    265274            return VINF_SUCCESS;
    266         pbDst    += cb;
    267         uSrcAddr += cb;
     275        }
     276        cbMaxRead -= (uint8_t)cb;
     277        cbMinRead -= (uint8_t)cb;
    268278    }
    269279}
     
    500510    else
    501511    {
    502         uint32_t cbBits = State.Cpu.cbInstr;
    503         uint8_t *pau8Bits = (uint8_t *)alloca(cbBits);
    504         rc = dbgfR3DisasInstrRead(&State.Cpu, pau8Bits, GCPtr, cbBits);
    505         AssertRC(rc);
     512        uint32_t        cbInstr  = State.Cpu.cbInstr;
     513        uint8_t const  *pabInstr = State.Cpu.abInstr;
    506514        if (fFlags & DBGF_DISAS_FLAGS_NO_ADDRESS)
    507515            RTStrPrintf(pszOutput, cbOutput, "%.*Rhxs%*s %s",
    508                         cbBits, pau8Bits, cbBits < 8 ? (8 - cbBits) * 3 : 0, "",
     516                        cbInstr, pabInstr, cbInstr < 8 ? (8 - cbInstr) * 3 : 0, "",
    509517                        szBuf);
    510518        else if (fRealModeAddress)
    511519            RTStrPrintf(pszOutput, cbOutput, "%04x:%04x %.*Rhxs%*s %s",
    512520                        Sel, (unsigned)GCPtr,
    513                         cbBits, pau8Bits, cbBits < 8 ? (8 - cbBits) * 3 : 0, "",
     521                        cbInstr, pabInstr, cbInstr < 8 ? (8 - cbInstr) * 3 : 0, "",
    514522                        szBuf);
    515523        else if (Sel == DBGF_SEL_FLAT)
     
    518526                RTStrPrintf(pszOutput, cbOutput, "%RGv %.*Rhxs%*s %s",
    519527                            GCPtr,
    520                             cbBits, pau8Bits, cbBits < 8 ? (8 - cbBits) * 3 : 0, "",
     528                            cbInstr, pabInstr, cbInstr < 8 ? (8 - cbInstr) * 3 : 0, "",
    521529                            szBuf);
    522530            else
    523531                RTStrPrintf(pszOutput, cbOutput, "%08RX32 %.*Rhxs%*s %s",
    524532                            (uint32_t)GCPtr,
    525                             cbBits, pau8Bits, cbBits < 8 ? (8 - cbBits) * 3 : 0, "",
     533                            cbInstr, pabInstr, cbInstr < 8 ? (8 - cbInstr) * 3 : 0, "",
    526534                            szBuf);
    527535        }
     
    531539                RTStrPrintf(pszOutput, cbOutput, "%04x:%RGv %.*Rhxs%*s %s",
    532540                            Sel, GCPtr,
    533                             cbBits, pau8Bits, cbBits < 8 ? (8 - cbBits) * 3 : 0, "",
     541                            cbInstr, pabInstr, cbInstr < 8 ? (8 - cbInstr) * 3 : 0, "",
    534542                            szBuf);
    535543            else
    536544                RTStrPrintf(pszOutput, cbOutput, "%04x:%08RX32 %.*Rhxs%*s %s",
    537545                            Sel, (uint32_t)GCPtr,
    538                             cbBits, pau8Bits, cbBits < 8 ? (8 - cbBits) * 3 : 0, "",
     546                            cbInstr, pabInstr, cbInstr < 8 ? (8 - cbInstr) * 3 : 0, "",
    539547                            szBuf);
    540548        }
  • trunk/src/VBox/VMM/VMMR3/PATM.cpp

    r41744 r41760  
    8080    PVM                  pVM;
    8181    PPATCHINFO           pPatchInfo;
    82     R3PTRTYPE(uint8_t *) pInstrHC;
     82    R3PTRTYPE(uint8_t *) pbInstrHC;
    8383    RTRCPTR              pInstrGC;
    8484    uint32_t             fReadFlags;
     
    534534}
    535535
    536 DECLCALLBACK(int) patmReadBytes(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead)
    537 {
    538     PATMDISASM   *pDisInfo = (PATMDISASM *)pDisState->pvUser;
    539     int           orgsize  = cbToRead;
    540 
    541     Assert(cbToRead);
    542     if (cbToRead == 0)
    543         return VERR_INVALID_PARAMETER;
    544 
     536/**
     537 * @callback_method_impl{FNDISREADBYTES}
     538 */
     539static DECLCALLBACK(int) patmReadBytes(PDISCPUSTATE pDis, uint8_t offInstr, uint8_t cbMinRead, uint8_t cbMaxRead)
     540{
     541    PATMDISASM   *pDisInfo = (PATMDISASM *)pDis->pvUser;
     542
     543/** @todo change this to read more! */
    545544    /*
    546545     * Trap/interrupt handler typically call common code on entry. Which might already have patches inserted.
     
    550549    if (pDisInfo->fReadFlags & PATMREAD_ORGCODE)
    551550    {
    552         for (int i = 0; i < orgsize; i++)
    553         {
    554             int rc = PATMR3QueryOpcode(pDisInfo->pVM, (RTRCPTR)uSrcAddr, pbDst);
     551        for (;;)
     552        {
     553            int rc = PATMR3QueryOpcode(pDisInfo->pVM, (RTGCPTR32)pDis->uInstrAddr + offInstr, &pDis->abInstr[offInstr]);
    555554            if (RT_FAILURE(rc))
    556                 break;
    557             uSrcAddr++;
    558             pbDst++;
    559             cbToRead--;
    560         }
    561         if (cbToRead == 0)
    562             return VINF_SUCCESS;
     555                break; /* VERR_PATCH_NOT_FOUND */
     556            offInstr++;
     557            cbMinRead--;
     558            if (cbMinRead == 0)
     559            {
     560                pDis->cbCachedInstr = offInstr;
     561                return VINF_SUCCESS;
     562            }
     563            cbMaxRead--;
     564        }
     565
    563566#ifdef VBOX_STRICT
    564         if (    !(pDisInfo->pPatchInfo->flags & (PATMFL_DUPLICATE_FUNCTION|PATMFL_IDTHANDLER))
    565             &&  !(pDisInfo->fReadFlags & PATMREAD_NOCHECK))
    566         {
    567             Assert(PATMR3IsInsidePatchJump(pDisInfo->pVM, uSrcAddr, NULL) == false);
    568             Assert(PATMR3IsInsidePatchJump(pDisInfo->pVM, uSrcAddr+cbToRead-1, NULL) == false);
     567        if (   !(pDisInfo->pPatchInfo->flags & (PATMFL_DUPLICATE_FUNCTION|PATMFL_IDTHANDLER))
     568            && !(pDisInfo->fReadFlags & PATMREAD_NOCHECK))
     569        {
     570            Assert(PATMR3IsInsidePatchJump(pDisInfo->pVM, pDis->uInstrAddr + offInstr, NULL) == false);
     571            Assert(PATMR3IsInsidePatchJump(pDisInfo->pVM, pDis->uInstrAddr + offInstr + cbMinRead-1, NULL) == false);
    569572        }
    570573#endif
    571574    }
    572575
    573     if (    !pDisInfo->pInstrHC
    574         ||  (   PAGE_ADDRESS(pDisInfo->pInstrGC) != PAGE_ADDRESS(uSrcAddr + cbToRead - 1)
    575              && !PATMIsPatchGCAddr(pDisInfo->pVM, uSrcAddr)))
     576    int       rc       = VINF_SUCCESS;
     577    RTGCPTR32 uSrcAddr = (RTGCPTR32)pDis->uInstrAddr + offInstr;
     578    if (   !pDisInfo->pbInstrHC
     579        || (   PAGE_ADDRESS(pDisInfo->pInstrGC) != PAGE_ADDRESS(uSrcAddr + cbMinRead - 1)
     580            && !PATMIsPatchGCAddr(pDisInfo->pVM, uSrcAddr)))
    576581    {
    577582        Assert(!PATMIsPatchGCAddr(pDisInfo->pVM, uSrcAddr));
    578         return PGMPhysSimpleReadGCPtr(&pDisInfo->pVM->aCpus[0], pbDst, uSrcAddr, cbToRead);
    579     }
    580 
    581     Assert(pDisInfo->pInstrHC);
    582 
    583     uint8_t *pInstrHC = pDisInfo->pInstrHC;
    584 
    585     Assert(pInstrHC);
    586 
    587     /* pInstrHC is the base address; adjust according to the GC pointer. */
    588     pInstrHC = pInstrHC + (uSrcAddr - pDisInfo->pInstrGC);
    589 
    590     memcpy(pbDst, (void *)pInstrHC, cbToRead);
    591 
    592     return VINF_SUCCESS;
     583        rc = PGMPhysSimpleReadGCPtr(&pDisInfo->pVM->aCpus[0], &pDis->abInstr[offInstr], uSrcAddr, cbMinRead);
     584        offInstr += cbMinRead;
     585    }
     586    else
     587    {
     588        /* pbInstrHC is the base address; adjust according to the GC pointer. */
     589        uint8_t const *pbInstrHC = pDisInfo->pbInstrHC; AssertPtr(pbInstrHC);
     590        pbInstrHC += uSrcAddr - pDisInfo->pInstrGC;
     591
     592        memcpy(&pDis->abInstr[offInstr], pbInstrHC, cbMinRead);
     593        offInstr += cbMinRead;
     594    }
     595
     596    pDis->cbCachedInstr = offInstr;
     597    return rc;
    593598}
    594599
     
    600605    disinfo.pVM         = pVM;
    601606    disinfo.pPatchInfo  = pPatch;
    602     disinfo.pInstrHC    = pbInstrHC;
     607    disinfo.pbInstrHC   = pbInstrHC;
    603608    disinfo.pInstrGC    = InstrGCPtr32;
    604609    disinfo.fReadFlags  = fReadFlags;
     
    616621    disinfo.pVM         = pVM;
    617622    disinfo.pPatchInfo  = pPatch;
    618     disinfo.pInstrHC    = pbInstrHC;
     623    disinfo.pbInstrHC   = pbInstrHC;
    619624    disinfo.pInstrGC    = InstrGCPtr32;
    620625    disinfo.fReadFlags  = fReadFlags;
     
    633638    disinfo.pVM         = pVM;
    634639    disinfo.pPatchInfo  = pPatch;
    635     disinfo.pInstrHC    = pbInstrHC;
     640    disinfo.pbInstrHC   = pbInstrHC;
    636641    disinfo.pInstrGC    = InstrGCPtr32;
    637642    disinfo.fReadFlags  = fReadFlags;
  • trunk/src/VBox/VMM/include/PATMInternal.h

    r41741 r41760  
    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
     
    675675
    676676
    677 FNDISREADBYTES patmReadBytes;
    678 
    679677
    680678RT_C_DECLS_BEGIN
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