VirtualBox

Changeset 46955 in vbox for trunk/src/VBox/VMM/VMMAll


Ignore:
Timestamp:
Jul 3, 2013 9:11:19 PM (12 years ago)
Author:
vboxsync
Message:

64-bit mode addressing fix.

File:
1 edited

Legend:

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

    r46953 r46955  
    71827182    } while (0)
    71837183
     7184    if (pIemCpu->enmCpuMode != IEMMODE_64BIT)
     7185    {
    71847186/** @todo Check the effective address size crap! */
    7185     switch (pIemCpu->enmEffAddrMode)
    7186     {
    7187         case IEMMODE_16BIT:
     7187        if (pIemCpu->enmEffAddrMode == IEMMODE_16BIT)
    71887188        {
    71897189            uint16_t u16EffAddr;
     
    72187218
    72197219            *pGCPtrEff = u16EffAddr;
    7220             Log5(("iemOpHlpCalcRmEffAddr: EffAddr=%#06RGv\n", *pGCPtrEff));
    7221             return VINF_SUCCESS;
    72227220        }
    7223 
    7224         case IEMMODE_32BIT:
     7221        else
    72257222        {
     7223            Assert(pIemCpu->enmEffAddrMode == IEMMODE_32BIT);
    72267224            uint32_t u32EffAddr;
    72277225
     
    73197317                *pGCPtrEff = u32EffAddr & UINT16_MAX;
    73207318            }
    7321             Log5(("iemOpHlpCalcRmEffAddr: EffAddr=%#010RGv\n", *pGCPtrEff));
    7322             return VINF_SUCCESS;
    73237319        }
    7324 
    7325         case IEMMODE_64BIT:
     7320    }
     7321    else
     7322    {
     7323        uint64_t u64EffAddr;
     7324
     7325        /* Handle the rip+disp32 form with no registers first. */
     7326        if ((bRm & (X86_MODRM_MOD_MASK | X86_MODRM_RM_MASK)) == 5)
    73267327        {
    7327             uint64_t u64EffAddr;
    7328 
    7329             /* Handle the rip+disp32 form with no registers first. */
    7330             if ((bRm & (X86_MODRM_MOD_MASK | X86_MODRM_RM_MASK)) == 5)
     7328            IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64EffAddr);
     7329            u64EffAddr += pCtx->rip + pIemCpu->offOpcode + cbImm;
     7330        }
     7331        else
     7332        {
     7333            /* Get the register (or SIB) value. */
     7334            switch ((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB)
    73317335            {
    7332                 IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64EffAddr);
    7333                 u64EffAddr += pCtx->rip + pIemCpu->offOpcode + cbImm;
    7334             }
    7335             else
    7336             {
    7337                 /* Get the register (or SIB) value. */
    7338                 switch ((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB)
     7336                case  0: u64EffAddr = pCtx->rax; break;
     7337                case  1: u64EffAddr = pCtx->rcx; break;
     7338                case  2: u64EffAddr = pCtx->rdx; break;
     7339                case  3: u64EffAddr = pCtx->rbx; break;
     7340                case  5: u64EffAddr = pCtx->rbp; SET_SS_DEF(); break;
     7341                case  6: u64EffAddr = pCtx->rsi; break;
     7342                case  7: u64EffAddr = pCtx->rdi; break;
     7343                case  8: u64EffAddr = pCtx->r8;  break;
     7344                case  9: u64EffAddr = pCtx->r9;  break;
     7345                case 10: u64EffAddr = pCtx->r10; break;
     7346                case 11: u64EffAddr = pCtx->r11; break;
     7347                case 13: u64EffAddr = pCtx->r13; break;
     7348                case 14: u64EffAddr = pCtx->r14; break;
     7349                case 15: u64EffAddr = pCtx->r15; break;
     7350                /* SIB */
     7351                case 4:
     7352                case 12:
    73397353                {
    7340                     case  0: u64EffAddr = pCtx->rax; break;
    7341                     case  1: u64EffAddr = pCtx->rcx; break;
    7342                     case  2: u64EffAddr = pCtx->rdx; break;
    7343                     case  3: u64EffAddr = pCtx->rbx; break;
    7344                     case  5: u64EffAddr = pCtx->rbp; SET_SS_DEF(); break;
    7345                     case  6: u64EffAddr = pCtx->rsi; break;
    7346                     case  7: u64EffAddr = pCtx->rdi; break;
    7347                     case  8: u64EffAddr = pCtx->r8;  break;
    7348                     case  9: u64EffAddr = pCtx->r9;  break;
    7349                     case 10: u64EffAddr = pCtx->r10; break;
    7350                     case 11: u64EffAddr = pCtx->r11; break;
    7351                     case 13: u64EffAddr = pCtx->r13; break;
    7352                     case 14: u64EffAddr = pCtx->r14; break;
    7353                     case 15: u64EffAddr = pCtx->r15; break;
    7354                     /* SIB */
    7355                     case 4:
    7356                     case 12:
     7354                    uint8_t bSib; IEM_OPCODE_GET_NEXT_U8(&bSib);
     7355
     7356                    /* Get the index and scale it. */
     7357                    switch (((bSib >> X86_SIB_INDEX_SHIFT) & X86_SIB_INDEX_SMASK) | pIemCpu->uRexIndex)
    73577358                    {
    7358                         uint8_t bSib; IEM_OPCODE_GET_NEXT_U8(&bSib);
    7359 
    7360                         /* Get the index and scale it. */
    7361                         switch (((bSib >> X86_SIB_INDEX_SHIFT) & X86_SIB_INDEX_SMASK) | pIemCpu->uRexIndex)
    7362                         {
    7363                             case  0: u64EffAddr = pCtx->rax; break;
    7364                             case  1: u64EffAddr = pCtx->rcx; break;
    7365                             case  2: u64EffAddr = pCtx->rdx; break;
    7366                             case  3: u64EffAddr = pCtx->rbx; break;
    7367                             case  4: u64EffAddr = 0; /*none */ break;
    7368                             case  5: u64EffAddr = pCtx->rbp; break;
    7369                             case  6: u64EffAddr = pCtx->rsi; break;
    7370                             case  7: u64EffAddr = pCtx->rdi; break;
    7371                             case  8: u64EffAddr = pCtx->r8;  break;
    7372                             case  9: u64EffAddr = pCtx->r9;  break;
    7373                             case 10: u64EffAddr = pCtx->r10; break;
    7374                             case 11: u64EffAddr = pCtx->r11; break;
    7375                             case 12: u64EffAddr = pCtx->r12; break;
    7376                             case 13: u64EffAddr = pCtx->r13; break;
    7377                             case 14: u64EffAddr = pCtx->r14; break;
    7378                             case 15: u64EffAddr = pCtx->r15; break;
    7379                             IEM_NOT_REACHED_DEFAULT_CASE_RET();
    7380                         }
    7381                         u64EffAddr <<= (bSib >> X86_SIB_SCALE_SHIFT) & X86_SIB_SCALE_SMASK;
    7382 
    7383                         /* add base */
    7384                         switch ((bSib & X86_SIB_BASE_MASK) | pIemCpu->uRexB)
    7385                         {
    7386                             case  0: u64EffAddr += pCtx->rax; break;
    7387                             case  1: u64EffAddr += pCtx->rcx; break;
    7388                             case  2: u64EffAddr += pCtx->rdx; break;
    7389                             case  3: u64EffAddr += pCtx->rbx; break;
    7390                             case  4: u64EffAddr += pCtx->rsp; SET_SS_DEF(); break;
    7391                             case  6: u64EffAddr += pCtx->rsi; break;
    7392                             case  7: u64EffAddr += pCtx->rdi; break;
    7393                             case  8: u64EffAddr += pCtx->r8;  break;
    7394                             case  9: u64EffAddr += pCtx->r9;  break;
    7395                             case 10: u64EffAddr += pCtx->r10; break;
    7396                             case 11: u64EffAddr += pCtx->r11; break;
    7397                             case 12: u64EffAddr += pCtx->r12; break;
    7398                             case 14: u64EffAddr += pCtx->r14; break;
    7399                             case 15: u64EffAddr += pCtx->r15; break;
    7400                             /* complicated encodings */
    7401                             case 5:
    7402                             case 13:
    7403                                 if ((bRm & X86_MODRM_MOD_MASK) != 0)
     7359                        case  0: u64EffAddr = pCtx->rax; break;
     7360                        case  1: u64EffAddr = pCtx->rcx; break;
     7361                        case  2: u64EffAddr = pCtx->rdx; break;
     7362                        case  3: u64EffAddr = pCtx->rbx; break;
     7363                        case  4: u64EffAddr = 0; /*none */ break;
     7364                        case  5: u64EffAddr = pCtx->rbp; break;
     7365                        case  6: u64EffAddr = pCtx->rsi; break;
     7366                        case  7: u64EffAddr = pCtx->rdi; break;
     7367                        case  8: u64EffAddr = pCtx->r8;  break;
     7368                        case  9: u64EffAddr = pCtx->r9;  break;
     7369                        case 10: u64EffAddr = pCtx->r10; break;
     7370                        case 11: u64EffAddr = pCtx->r11; break;
     7371                        case 12: u64EffAddr = pCtx->r12; break;
     7372                        case 13: u64EffAddr = pCtx->r13; break;
     7373                        case 14: u64EffAddr = pCtx->r14; break;
     7374                        case 15: u64EffAddr = pCtx->r15; break;
     7375                        IEM_NOT_REACHED_DEFAULT_CASE_RET();
     7376                    }
     7377                    u64EffAddr <<= (bSib >> X86_SIB_SCALE_SHIFT) & X86_SIB_SCALE_SMASK;
     7378
     7379                    /* add base */
     7380                    switch ((bSib & X86_SIB_BASE_MASK) | pIemCpu->uRexB)
     7381                    {
     7382                        case  0: u64EffAddr += pCtx->rax; break;
     7383                        case  1: u64EffAddr += pCtx->rcx; break;
     7384                        case  2: u64EffAddr += pCtx->rdx; break;
     7385                        case  3: u64EffAddr += pCtx->rbx; break;
     7386                        case  4: u64EffAddr += pCtx->rsp; SET_SS_DEF(); break;
     7387                        case  6: u64EffAddr += pCtx->rsi; break;
     7388                        case  7: u64EffAddr += pCtx->rdi; break;
     7389                        case  8: u64EffAddr += pCtx->r8;  break;
     7390                        case  9: u64EffAddr += pCtx->r9;  break;
     7391                        case 10: u64EffAddr += pCtx->r10; break;
     7392                        case 11: u64EffAddr += pCtx->r11; break;
     7393                        case 12: u64EffAddr += pCtx->r12; break;
     7394                        case 14: u64EffAddr += pCtx->r14; break;
     7395                        case 15: u64EffAddr += pCtx->r15; break;
     7396                        /* complicated encodings */
     7397                        case 5:
     7398                        case 13:
     7399                            if ((bRm & X86_MODRM_MOD_MASK) != 0)
     7400                            {
     7401                                if (!pIemCpu->uRexB)
    74047402                                {
    7405                                     if (!pIemCpu->uRexB)
    7406                                     {
    7407                                         u64EffAddr += pCtx->rbp;
    7408                                         SET_SS_DEF();
    7409                                     }
    7410                                     else
    7411                                         u64EffAddr += pCtx->r13;
     7403                                    u64EffAddr += pCtx->rbp;
     7404                                    SET_SS_DEF();
    74127405                                }
    74137406                                else
    7414                                 {
    7415                                     uint32_t u32Disp;
    7416                                     IEM_OPCODE_GET_NEXT_U32(&u32Disp);
    7417                                     u64EffAddr += (int32_t)u32Disp;
    7418                                 }
    7419                                 break;
    7420                             IEM_NOT_REACHED_DEFAULT_CASE_RET();
    7421                         }
    7422                         break;
     7407                                    u64EffAddr += pCtx->r13;
     7408                            }
     7409                            else
     7410                            {
     7411                                uint32_t u32Disp;
     7412                                IEM_OPCODE_GET_NEXT_U32(&u32Disp);
     7413                                u64EffAddr += (int32_t)u32Disp;
     7414                            }
     7415                            break;
     7416                        IEM_NOT_REACHED_DEFAULT_CASE_RET();
    74237417                    }
    7424                     IEM_NOT_REACHED_DEFAULT_CASE_RET();
     7418                    break;
    74257419                }
    7426 
    7427                 /* Get and add the displacement. */
    7428                 switch ((bRm >> X86_MODRM_MOD_SHIFT) & X86_MODRM_MOD_SMASK)
     7420                IEM_NOT_REACHED_DEFAULT_CASE_RET();
     7421            }
     7422
     7423            /* Get and add the displacement. */
     7424            switch ((bRm >> X86_MODRM_MOD_SHIFT) & X86_MODRM_MOD_SMASK)
     7425            {
     7426                case 0:
     7427                    break;
     7428                case 1:
    74297429                {
    7430                     case 0:
    7431                         break;
    7432                     case 1:
    7433                     {
    7434                         int8_t i8Disp;
    7435                         IEM_OPCODE_GET_NEXT_S8(&i8Disp);
    7436                         u64EffAddr += i8Disp;
    7437                         break;
    7438                     }
    7439                     case 2:
    7440                     {
    7441                         uint32_t u32Disp;
    7442                         IEM_OPCODE_GET_NEXT_U32(&u32Disp);
    7443                         u64EffAddr += (int32_t)u32Disp;
    7444                         break;
    7445                     }
    7446                     IEM_NOT_REACHED_DEFAULT_CASE_RET(); /* (caller checked for these) */
     7430                    int8_t i8Disp;
     7431                    IEM_OPCODE_GET_NEXT_S8(&i8Disp);
     7432                    u64EffAddr += i8Disp;
     7433                    break;
    74477434                }
    7448 
     7435                case 2:
     7436                {
     7437                    uint32_t u32Disp;
     7438                    IEM_OPCODE_GET_NEXT_U32(&u32Disp);
     7439                    u64EffAddr += (int32_t)u32Disp;
     7440                    break;
     7441                }
     7442                IEM_NOT_REACHED_DEFAULT_CASE_RET(); /* (caller checked for these) */
    74497443            }
    7450             if (pIemCpu->enmEffAddrMode == IEMMODE_64BIT)
    7451                 *pGCPtrEff = u64EffAddr;
    7452             else
    7453                 *pGCPtrEff = u64EffAddr & UINT16_MAX;
    7454             Log5(("iemOpHlpCalcRmEffAddr: EffAddr=%#010RGv\n", *pGCPtrEff));
    7455             return VINF_SUCCESS;
     7444
    74567445        }
    7457     }
    7458 
    7459     AssertFailedReturn(VERR_INTERNAL_ERROR_3);
     7446
     7447        if (pIemCpu->enmEffAddrMode == IEMMODE_64BIT)
     7448            *pGCPtrEff = u64EffAddr;
     7449        else
     7450        {
     7451            Assert(pIemCpu->enmEffAddrMode == IEMMODE_32BIT);
     7452            *pGCPtrEff = u64EffAddr & UINT32_MAX;
     7453        }
     7454    }
     7455
     7456    Log5(("iemOpHlpCalcRmEffAddr: EffAddr=%#010RGv\n", *pGCPtrEff));
     7457    return VINF_SUCCESS;
    74607458}
    74617459
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