VirtualBox

Changeset 9706 in vbox


Ignore:
Timestamp:
Jun 16, 2008 9:29:30 AM (17 years ago)
Author:
vboxsync
Message:

disCoreOne needs to catch exceptions in ring 3!!!

File:
1 edited

Legend:

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

    r9676 r9706  
    251251 * @param   pcbInstruction  Where to store the instruction size. Can be NULL.
    252252 */
    253 static int disCoreOne(PDISCPUSTATE pCpu, RTUINTPTR InstructionAddr, unsigned *pcbInstruction)
     253int disCoreOne(PDISCPUSTATE pCpu, RTUINTPTR InstructionAddr, unsigned *pcbInstruction)
    254254{
    255255    const OPCODE *paOneByteMap;
     
    274274    }
    275275
    276     while(1)
    277     {
    278         uint8_t codebyte = DISReadByte(pCpu, InstructionAddr+iByte);
    279         uint8_t opcode   = paOneByteMap[codebyte].opcode;
    280 
    281         /* Hardcoded assumption about OP_* values!! */
    282         if (opcode <= OP_LAST_PREFIX)
     276#ifdef IN_RING3
     277# ifndef __L4ENV__  /* Unfortunately, we have no exception handling in l4env */
     278    try
     279# else
     280    pCpu->pJumpBuffer = &jumpbuffer;
     281    if (setjmp(jumpbuffer) == 0)
     282# endif
     283#endif
     284    {
     285        while(1)
    283286        {
    284             /* The REX prefix must precede the opcode byte(s). Any other placement is ignored. */
    285             if (opcode != OP_REX)
     287            uint8_t codebyte = DISReadByte(pCpu, InstructionAddr+iByte);
     288            uint8_t opcode   = paOneByteMap[codebyte].opcode;
     289
     290            /* Hardcoded assumption about OP_* values!! */
     291            if (opcode <= OP_LAST_PREFIX)
    286292            {
    287                 /** Last prefix byte (for SSE2 extension tables); don't include the REX prefix */
    288                 pCpu->lastprefix = opcode;
    289                 pCpu->prefix &= ~PREFIX_REX;
     293                /* The REX prefix must precede the opcode byte(s). Any other placement is ignored. */
     294                if (opcode != OP_REX)
     295                {
     296                    /** Last prefix byte (for SSE2 extension tables); don't include the REX prefix */
     297                    pCpu->lastprefix = opcode;
     298                    pCpu->prefix &= ~PREFIX_REX;
     299                }
     300
     301                switch (opcode)
     302                {
     303                case OP_INVALID:
     304                    AssertMsgFailed(("Invalid opcode!!\n"));
     305                    return VERR_GENERAL_FAILURE; /** @todo better error code. */
     306
     307                // segment override prefix byte
     308                case OP_SEG:
     309                    pCpu->enmPrefixSeg = (DIS_SELREG)(paOneByteMap[codebyte].param1 - OP_PARM_REG_SEG_START);
     310                    /* Segment prefixes for CS, DS, ES and SS are ignored in long mode. */
     311                    if (   pCpu->mode != CPUMODE_64BIT
     312                        || pCpu->enmPrefixSeg >= DIS_SELREG_FS)
     313                    {
     314                        pCpu->prefix    |= PREFIX_SEG;
     315                    }
     316                    iByte += sizeof(uint8_t);
     317                    continue;   //fetch the next byte
     318
     319                // lock prefix byte
     320                case OP_LOCK:
     321                    pCpu->prefix |= PREFIX_LOCK;
     322                    iByte       += sizeof(uint8_t);
     323                    continue;   //fetch the next byte
     324
     325                // address size override prefix byte
     326                case OP_ADDRSIZE:
     327                    pCpu->prefix |= PREFIX_ADDRSIZE;
     328                    if (pCpu->mode == CPUMODE_16BIT)
     329                        pCpu->addrmode = CPUMODE_32BIT;
     330                    else
     331                    if (pCpu->mode == CPUMODE_32BIT)
     332                        pCpu->addrmode = CPUMODE_16BIT;
     333                    else
     334                        pCpu->addrmode = CPUMODE_32BIT;     /* 64 bits */
     335
     336                    iByte        += sizeof(uint8_t);
     337                    continue;   //fetch the next byte
     338
     339                // operand size override prefix byte
     340                case OP_OPSIZE:
     341                    pCpu->prefix |= PREFIX_OPSIZE;
     342                    if (pCpu->mode == CPUMODE_16BIT)
     343                        pCpu->opmode = CPUMODE_32BIT;
     344                    else
     345                        pCpu->opmode = CPUMODE_16BIT;  /* for 32 and 64 bits mode (there is no 32 bits operand size override prefix) */
     346
     347                    iByte        += sizeof(uint8_t);
     348                    continue;   //fetch the next byte
     349
     350                // rep and repne are not really prefixes, but we'll treat them as such
     351                case OP_REPE:
     352                    pCpu->prefix |= PREFIX_REP;
     353                    iByte       += sizeof(uint8_t);
     354                    continue;   //fetch the next byte
     355
     356                case OP_REPNE:
     357                    pCpu->prefix |= PREFIX_REPNE;
     358                    iByte       += sizeof(uint8_t);
     359                    continue;   //fetch the next byte
     360
     361                case OP_REX:
     362                    Assert(pCpu->mode == CPUMODE_64BIT);
     363                    /* REX prefix byte */
     364                    pCpu->prefix    |= PREFIX_REX;
     365                    pCpu->prefix_rex = PREFIX_REX_OP_2_FLAGS(paOneByteMap[codebyte].param1);
     366                    iByte           += sizeof(uint8_t);
     367
     368                    if (pCpu->prefix_rex & PREFIX_REX_FLAGS_W)
     369                        pCpu->opmode = CPUMODE_64BIT;  /* overrides size prefix byte */
     370                    continue;   //fetch the next byte
     371                }
    290372            }
    291373
    292             switch (opcode)
    293             {
    294             case OP_INVALID:
    295                 AssertMsgFailed(("Invalid opcode!!\n"));
    296                 return VERR_GENERAL_FAILURE; /** @todo better error code. */
    297 
    298             // segment override prefix byte
    299             case OP_SEG:
    300                 pCpu->enmPrefixSeg = (DIS_SELREG)(paOneByteMap[codebyte].param1 - OP_PARM_REG_SEG_START);
    301                 /* Segment prefixes for CS, DS, ES and SS are ignored in long mode. */
    302                 if (   pCpu->mode != CPUMODE_64BIT
    303                     || pCpu->enmPrefixSeg >= DIS_SELREG_FS)
    304                 {
    305                     pCpu->prefix    |= PREFIX_SEG;
    306                 }
    307                 iByte += sizeof(uint8_t);
    308                 continue;   //fetch the next byte
    309 
    310             // lock prefix byte
    311             case OP_LOCK:
    312                 pCpu->prefix |= PREFIX_LOCK;
    313                 iByte       += sizeof(uint8_t);
    314                 continue;   //fetch the next byte
    315 
    316             // address size override prefix byte
    317             case OP_ADDRSIZE:
    318                 pCpu->prefix |= PREFIX_ADDRSIZE;
    319                 if (pCpu->mode == CPUMODE_16BIT)
    320                     pCpu->addrmode = CPUMODE_32BIT;
    321                 else
    322                 if (pCpu->mode == CPUMODE_32BIT)
    323                     pCpu->addrmode = CPUMODE_16BIT;
    324                 else
    325                     pCpu->addrmode = CPUMODE_32BIT;     /* 64 bits */
    326 
    327                 iByte        += sizeof(uint8_t);
    328                 continue;   //fetch the next byte
    329 
    330             // operand size override prefix byte
    331             case OP_OPSIZE:
    332                 pCpu->prefix |= PREFIX_OPSIZE;
    333                 if (pCpu->mode == CPUMODE_16BIT)
    334                     pCpu->opmode = CPUMODE_32BIT;
    335                 else
    336                     pCpu->opmode = CPUMODE_16BIT;  /* for 32 and 64 bits mode (there is no 32 bits operand size override prefix) */
    337 
    338                 iByte        += sizeof(uint8_t);
    339                 continue;   //fetch the next byte
    340 
    341             // rep and repne are not really prefixes, but we'll treat them as such
    342             case OP_REPE:
    343                 pCpu->prefix |= PREFIX_REP;
    344                 iByte       += sizeof(uint8_t);
    345                 continue;   //fetch the next byte
    346 
    347             case OP_REPNE:
    348                 pCpu->prefix |= PREFIX_REPNE;
    349                 iByte       += sizeof(uint8_t);
    350                 continue;   //fetch the next byte
    351 
    352             case OP_REX:
    353                 Assert(pCpu->mode == CPUMODE_64BIT);
    354                 /* REX prefix byte */
    355                 pCpu->prefix    |= PREFIX_REX;
    356                 pCpu->prefix_rex = PREFIX_REX_OP_2_FLAGS(paOneByteMap[codebyte].param1);
    357                 iByte           += sizeof(uint8_t);
    358 
    359                 if (pCpu->prefix_rex & PREFIX_REX_FLAGS_W)
    360                     pCpu->opmode = CPUMODE_64BIT;  /* overrides size prefix byte */
    361                 continue;   //fetch the next byte
    362             }
    363         }
    364 
    365         unsigned uIdx = iByte;
    366         iByte += sizeof(uint8_t); //first opcode byte
    367 
    368         pCpu->opaddr = InstructionAddr + uIdx;
    369         pCpu->opcode = codebyte;
    370 
    371         cbInc = ParseInstruction(InstructionAddr + iByte, &paOneByteMap[pCpu->opcode], pCpu);
    372         iByte += cbInc;
    373         break;
    374     }
     374            unsigned uIdx = iByte;
     375            iByte += sizeof(uint8_t); //first opcode byte
     376
     377            pCpu->opaddr = InstructionAddr + uIdx;
     378            pCpu->opcode = codebyte;
     379
     380            cbInc = ParseInstruction(InstructionAddr + iByte, &paOneByteMap[pCpu->opcode], pCpu);
     381            iByte += cbInc;
     382            break;
     383        }
     384    }
     385#ifdef IN_RING3
     386# ifndef __L4ENV__
     387    catch(...)
     388# else
     389    else  /* setjmp has returned a non-zero value: an exception occured */
     390# endif
     391    {
     392        pCpu->opsize = 0;
     393        return VERR_DIS_GEN_FAILURE;
     394    }
     395#endif
    375396
    376397    pCpu->opsize = iByte;
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