VirtualBox

Changeset 41760 in vbox for trunk/src/VBox/Disassembler


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/src/VBox/Disassembler
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • 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                }
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