VirtualBox

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


Ignore:
Timestamp:
Jun 19, 2012 12:43:29 PM (12 years ago)
Author:
vboxsync
Message:

DIS: Fixed disReadQWordSlow bug found by parfait. Correct the instruction length limit and made the slow paths work with DIS_MAX_INSTR_LENGTH < sizeof(DISCPUSTATE::abInstr).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Disassembler/DisasmCore.cpp

    r41796 r41822  
    3535*   Defined Constants And Macros                                               *
    3636*******************************************************************************/
    37 /** This must be less or equal to DISSTATE::abInstr. */
    38 #define DIS_MAX_INSTR_LENGTH 16
     37/** This must be less or equal to DISSTATE::abInstr.
     38 * See Vol3A/Table 6-2 and Vol3B/Section22.25 for instance.  */
     39#define DIS_MAX_INSTR_LENGTH    15
    3940
    4041/** Whether we can do unaligned access. */
     
    311312        Log(("disReadByte: too long instruction...\n"));
    312313        pDis->rc = VERR_DIS_TOO_LONG_INSTR;
     314        RTINTPTR cbLeft = sizeof(pDis->abInstr) - offInstr;
     315        if (cbLeft > 0)
     316            return pDis->abInstr[offInstr];
    313317        return 0;
    314318    }
     
    349353        Log(("disReadWord: too long instruction...\n"));
    350354        pDis->rc = VERR_DIS_TOO_LONG_INSTR;
    351         if (offInstr < DIS_MAX_INSTR_LENGTH)
    352             return pDis->abInstr[offInstr];
    353         return 0;
     355        RTINTPTR cbLeft = sizeof(pDis->abInstr) - offInstr;
     356        switch (cbLeft)
     357        {
     358            case 1:
     359                return pDis->abInstr[offInstr];
     360            default:
     361                if (cbLeft >= 2)
     362                    return RT_MAKE_U16(pDis->abInstr[offInstr], pDis->abInstr[offInstr + 1]);
     363                return 0;
     364        }
    354365    }
    355366
     
    398409        Log(("disReadDWord: too long instruction...\n"));
    399410        pDis->rc = VERR_DIS_TOO_LONG_INSTR;
    400         switch ((RTUINTPTR)DIS_MAX_INSTR_LENGTH - offInstr)
     411        RTINTPTR cbLeft = sizeof(pDis->abInstr) - offInstr;
     412        switch (cbLeft)
    401413        {
    402414            case 1:
     
    406418            case 3:
    407419                return RT_MAKE_U32_FROM_U8(pDis->abInstr[offInstr], pDis->abInstr[offInstr + 1], pDis->abInstr[offInstr + 2], 0);
    408         }
    409         return 0;
     420            default:
     421                if (cbLeft >= 4)
     422                    return RT_MAKE_U32_FROM_U8(pDis->abInstr[offInstr    ], pDis->abInstr[offInstr + 1],
     423                                               pDis->abInstr[offInstr + 2], pDis->abInstr[offInstr + 3]);
     424                return 0;
     425        }
    410426    }
    411427
     
    456472        Log(("disReadQWord: too long instruction...\n"));
    457473        pDis->rc = VERR_DIS_TOO_LONG_INSTR;
    458         switch ((RTUINTPTR)DIS_MAX_INSTR_LENGTH - offInstr)
     474        RTINTPTR cbLeft = sizeof(pDis->abInstr) - offInstr;
     475        switch (cbLeft)
    459476        {
    460477            case 1:
     
    468485                return RT_MAKE_U64_FROM_U8(pDis->abInstr[offInstr    ], pDis->abInstr[offInstr + 1],
    469486                                           pDis->abInstr[offInstr + 2], pDis->abInstr[offInstr + 3],
    470                                            pDis->abInstr[offInstr + 4], 0, 0, 0);
     487                                           0, 0, 0, 0);
    471488            case 5:
    472489                return RT_MAKE_U64_FROM_U8(pDis->abInstr[offInstr    ], pDis->abInstr[offInstr + 1],
    473490                                           pDis->abInstr[offInstr + 2], pDis->abInstr[offInstr + 3],
    474                                            pDis->abInstr[offInstr + 4], pDis->abInstr[offInstr + 5], 0, 0);
     491                                           pDis->abInstr[offInstr + 4], 0, 0, 0);
    475492            case 6:
    476493                return RT_MAKE_U64_FROM_U8(pDis->abInstr[offInstr    ], pDis->abInstr[offInstr + 1],
    477494                                           pDis->abInstr[offInstr + 2], pDis->abInstr[offInstr + 3],
    478495                                           pDis->abInstr[offInstr + 4], pDis->abInstr[offInstr + 5],
     496                                           0, 0);
     497            case 7:
     498                return RT_MAKE_U64_FROM_U8(pDis->abInstr[offInstr    ], pDis->abInstr[offInstr + 1],
     499                                           pDis->abInstr[offInstr + 2], pDis->abInstr[offInstr + 3],
     500                                           pDis->abInstr[offInstr + 4], pDis->abInstr[offInstr + 5],
    479501                                           pDis->abInstr[offInstr + 6], 0);
    480         }
    481         return 0;
     502            default:
     503                if (cbLeft >= 8)
     504                    return RT_MAKE_U64_FROM_U8(pDis->abInstr[offInstr    ], pDis->abInstr[offInstr + 1],
     505                                               pDis->abInstr[offInstr + 2], pDis->abInstr[offInstr + 3],
     506                                               pDis->abInstr[offInstr + 4], pDis->abInstr[offInstr + 5],
     507                                               pDis->abInstr[offInstr + 6], pDis->abInstr[offInstr + 7]);
     508                return 0;
     509        }
    482510    }
    483511
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