Changeset 103511 in vbox
- Timestamp:
- Feb 22, 2024 1:16:10 AM (9 months ago)
- Location:
- trunk/src/VBox/Disassembler
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Disassembler/DisasmCore-x86-amd64.cpp
r101539 r103511 39 39 #include <iprt/string.h> 40 40 #include <iprt/stdarg.h> 41 #include <iprt/x86.h> 41 42 #include "DisasmInternal-x86-amd64.h" 42 43 … … 966 967 * encoding of the MOD field in the MODR/M byte. 967 968 */ 968 if (pOp->fOpType & DISOPTYPE_X86_MOD_FIXED_11) 969 if (!(pOp->fOpType & DISOPTYPE_X86_MOD_FIXED_11)) 970 { /* likely */ } 971 else 969 972 pDis->x86.ModRM.Bits.Mod = 3; 970 973 … … 974 977 975 978 /* REX.R extends the Reg field. */ 976 pDis->x86.ModRM.Bits.Reg |= ( (!!(pDis->x86.fRexPrefix & DISPREFIX_REX_FLAGS_R)) << 3);979 pDis->x86.ModRM.Bits.Reg |= (!!(pDis->x86.fRexPrefix & DISPREFIX_REX_FLAGS_R)) << 3; 977 980 978 981 /* REX.B extends the Rm field if there is no SIB byte nor a 32 bits displacement */ 982 #if 1 983 if ( pDis->x86.ModRM.Bits.Mod == 3 /* The register mode has neither SIB nor disp32. */ 984 || ( pDis->x86.ModRM.Bits.Rm != 4 /* SIB */ 985 && ( pDis->x86.ModRM.Bits.Mod != 0 /* disp32/PCREL is mod=0 rm=5 */ 986 || pDis->x86.ModRM.Bits.Rm != 5))) 987 #else 979 988 if (!( pDis->x86.ModRM.Bits.Mod != 3 980 989 && pDis->x86.ModRM.Bits.Rm == 4) … … 982 991 !( pDis->x86.ModRM.Bits.Mod == 0 983 992 && pDis->x86.ModRM.Bits.Rm == 5)) 984 { 985 pDis->x86.ModRM.Bits.Rm |= ((!!(pDis->x86.fRexPrefix & DISPREFIX_REX_FLAGS_B)) << 3); 986 } 993 #endif 994 pDis->x86.ModRM.Bits.Rm |= (!!(pDis->x86.fRexPrefix & DISPREFIX_REX_FLAGS_B)) << 3; 987 995 } 988 996 offInstr = QueryModRM(offInstr, pOp, pDis, pParam); … … 1644 1652 1645 1653 case OP_PARM_B: // Always OP_PARM_By. Change if it is not so. 1646 if ( pDis->x86.bVexWFlag&& pDis->uCpuMode == DISCPUMODE_64BIT)1654 if ((pDis->x86.bVexByte2 & DISPREFIX_VEX_F_W) && pDis->uCpuMode == DISCPUMODE_64BIT) 1647 1655 pParam->fUse |= DISUSE_REG_GEN64; 1648 1656 else … … 2099 2107 uint8_t modrm = disReadByte(pDis, offInstr); 2100 2108 uint8_t reg = MODRM_REG(modrm); 2101 if (pDis->x86.fPrefix & DISPREFIX_OPSIZE) 2102 reg += 8; /* 2nd table */ 2103 2104 pOp = &g_aMapX86_Group13[reg]; 2109 if (!(pDis->x86.fPrefix & DISPREFIX_VEX)) 2110 { 2111 if (pDis->x86.fPrefix & DISPREFIX_OPSIZE) 2112 reg += 8; /* 2nd table */ 2113 pOp = &g_aMapX86_Group13[reg]; 2114 } 2115 else 2116 pOp = &g_aMapX86_VGroup13[(pDis->x86.bVexByte2 & DISPREFIX_VEX_F_PP_MASK) == DISPREFIX_VEX_F_PP_66 ? reg + 8 : reg]; 2105 2117 2106 2118 return disParseInstruction(offInstr, pOp, pDis); … … 2172 2184 RT_NOREF_PV(pOp); RT_NOREF_PV(pParam); 2173 2185 2174 uint8_t byte = disReadByte(pDis, offInstr++); 2175 pDis->x86.bOpCode = disReadByte(pDis, offInstr++); 2176 2177 pDis->x86.bVexDestReg = VEX_2B2INT(byte); 2178 2179 // VEX.R (equivalent to REX.R) 2180 if (pDis->uCpuMode == DISCPUMODE_64BIT && !(byte & 0x80)) 2181 { 2182 /* REX prefix byte */ 2183 pDis->x86.fPrefix |= DISPREFIX_REX; 2184 pDis->x86.fRexPrefix = DISPREFIX_REX_FLAGS_R; 2185 } 2186 2187 PCDISOPMAPDESC const pRange = g_aapVexOpcodesMapRanges[byte & 3][1]; 2186 uint8_t const bVexByte = disReadByte(pDis, offInstr++); 2187 if (pDis->uCpuMode == DISCPUMODE_64BIT) 2188 { 2189 // VEX.~R => REX.R 2190 if (!(bVexByte & 0x80)) 2191 { 2192 pDis->x86.fPrefix |= DISPREFIX_REX; 2193 pDis->x86.fRexPrefix = DISPREFIX_REX_FLAGS_R; 2194 } 2195 } 2196 else if ((bVexByte & X86_MODRM_MOD_MASK) != (X86_MOD_REG << X86_MODRM_MOD_SHIFT)) 2197 return disParseInstruction(offInstr - 1, &g_OpcodeLDS, pDis); /* LDS r,mem */ 2198 2199 /* VEX2.byte1 is the same as VEX3.byte2 with the exception of the 7th bit (~R vs W). */ 2200 pDis->x86.bVexByte2 = bVexByte & (DISPREFIX_VEX_F_PP_MASK | DISPREFIX_VEX_F_L | DISPREFIX_VEX_F_VVVV); 2201 pDis->x86.bVexDestReg = VEX_2B2INT(bVexByte); 2202 pDis->x86.bOpCode = disReadByte(pDis, offInstr++); 2203 pDis->x86.fPrefix |= DISPREFIX_VEX; 2204 2205 PCDISOPMAPDESC const pRange = g_aapVexOpcodesMapRanges[bVexByte & 3][1]; 2188 2206 unsigned const idxOpcode = pDis->x86.bOpCode - pRange->idxFirst; 2189 2207 PCDISOPCODE pOpCode; … … 2201 2219 RT_NOREF_PV(pOp); RT_NOREF_PV(pParam); 2202 2220 2203 uint8_t byte1 = disReadByte(pDis, offInstr++); 2204 uint8_t byte2 = disReadByte(pDis, offInstr++); 2205 pDis->x86.bOpCode = disReadByte(pDis, offInstr++); 2206 pDis->x86.bVexDestReg = VEX_2B2INT(byte2); /** @todo r=bird: why on earth ~vvvv + L; this is obfuscation non-sense. Either split the shit up or just store byte2 raw here! */ 2207 2208 // VEX.W 2209 pDis->x86.bVexWFlag = !!(byte2 & 0x80); /** @todo r=bird: why a whole byte for this one flag? x86.bVexWFlag and bVexDestReg makes little sense. */ 2221 uint8_t const bVexByte1 = disReadByte(pDis, offInstr++); 2222 if (pDis->uCpuMode == DISCPUMODE_64BIT) 2223 { 2224 // VEX.~R~X~B => REX.RXB 2225 pDis->x86.fRexPrefix |= (bVexByte1 >> 5) ^ 7; 2226 if (pDis->x86.fRexPrefix) 2227 pDis->x86.fPrefix |= DISPREFIX_REX; 2228 } 2229 else if ((bVexByte1 & X86_MODRM_MOD_MASK) != (X86_MOD_REG << X86_MODRM_MOD_SHIFT)) 2230 return disParseInstruction(offInstr - 1, &g_OpcodeLES, pDis); /* LES r,mem */ 2231 2232 uint8_t const bVexByte2 = disReadByte(pDis, offInstr++); 2233 pDis->x86.fPrefix |= DISPREFIX_VEX; 2234 pDis->x86.bVexByte2 = bVexByte2; 2235 pDis->x86.bOpCode = disReadByte(pDis, offInstr++); 2236 pDis->x86.bVexDestReg = VEX_2B2INT(bVexByte2); /** @todo r=bird: why on earth ~vvvv + L; this is obfuscation non-sense. Either split the shit up or just store bVexByte2 raw here! */ 2210 2237 2211 2238 /* Hack alert! Assume VEX.W rules over any 66h prefix and that no VEX 2212 2239 encoded instructions ever uses the regular x86.uOpMode w/o VEX.W. */ 2213 pDis->x86.uOpMode = (byte2 & 0x80) && pDis->uCpuMode == DISCPUMODE_64BIT ? DISCPUMODE_64BIT : DISCPUMODE_32BIT; 2214 2215 // VEX.~R~X~B => REX.RXB 2216 if (pDis->uCpuMode == DISCPUMODE_64BIT) 2217 { 2218 pDis->x86.fRexPrefix |= (byte1 >> 5) ^ 7; 2219 if (pDis->x86.fRexPrefix) 2220 pDis->x86.fPrefix |= DISPREFIX_REX; 2221 } 2240 pDis->x86.uOpMode = (bVexByte2 & 0x80) && pDis->uCpuMode == DISCPUMODE_64BIT ? DISCPUMODE_64BIT : DISCPUMODE_32BIT; 2222 2241 2223 2242 PCDISOPCODE pOpCode; 2224 uint8_t const idxVexMap = b yte1 & 0x1f;2225 if (idxVexMap < RT_ELEMENTS(g_aapVexOpcodesMapRanges[b yte2 & 3]))2226 { 2227 PCDISOPMAPDESC const pRange = g_aapVexOpcodesMapRanges[b yte2 & 3][idxVexMap];2243 uint8_t const idxVexMap = bVexByte1 & 0x1f; 2244 if (idxVexMap < RT_ELEMENTS(g_aapVexOpcodesMapRanges[bVexByte2 & 3])) 2245 { 2246 PCDISOPMAPDESC const pRange = g_aapVexOpcodesMapRanges[bVexByte2 & 3][idxVexMap]; 2228 2247 unsigned const idxOpcode = pDis->x86.bOpCode - pRange->idxFirst; 2229 2248 if (idxOpcode < pRange->cOpcodes) … … 2419 2438 } 2420 2439 2421 /* Check if this is a VEX prefix. Not for 32-bit mode. */2422 if (pDis->uCpuMode != DISCPUMODE_64BIT2423 && (enmOpcode == OP_LES || enmOpcode == OP_LDS)2424 && (disReadByte(pDis, offInstr) & 0xc0) == 0xc0)2425 {2426 paOneByteMap = g_aOneByteMapX64;2427 }2428 2429 2440 /* first opcode byte. */ 2430 2441 pDis->x86.bOpCode = bCode; -
trunk/src/VBox/Disassembler/DisasmFormatYasm.cpp
r101546 r103511 640 640 char *pszFmtDst = szTmpFmt; 641 641 if (pszSpace == NULL) pszSpace = strchr(pszDelim, 0); 642 if ( (*pszFmt == '#' && ! pDis->x86.bVexWFlag) /** @todo check this*/642 if ( (*pszFmt == '#' && !(pDis->x86.bVexByte2 & DISPREFIX_VEX_F_W)) /** @todo check this*/ 643 643 || (*pszFmt == '@' && !VEXREG_IS256B(pDis->x86.bVexDestReg)) 644 644 || (*pszFmt == '&' && ( DISUSE_IS_EFFECTIVE_ADDR(pDis->Param1.fUse) … … 723 723 case DISCPUMODE_16BIT: if (OP_PARM_VSUBTYPE(pParam->x86.fParam) != OP_PARM_y) PUT_SZ("word "); break; \ 724 724 case DISCPUMODE_32BIT: \ 725 if (pDis->pCurInstr->uOpcode != OP_GATHER || pDis->x86.bVexWFlag) { PUT_SZ("dword "); break; } \ 725 if (pDis->pCurInstr->uOpcode != OP_GATHER || (pDis->x86.bVexByte2 & DISPREFIX_VEX_F_W)) \ 726 { PUT_SZ("dword "); break; } \ 726 727 RT_FALL_THRU(); \ 727 728 case DISCPUMODE_64BIT: PUT_SZ("qword "); break; \ -
trunk/src/VBox/Disassembler/DisasmInternal-x86-amd64.h
r99236 r103511 131 131 extern const DISOPCODE g_aOneByteMapX64[256]; 132 132 extern const DISOPCODE g_aTwoByteMapX86[256]; 133 extern const DISOPCODE g_OpcodeLES; 134 extern const DISOPCODE g_OpcodeLDS; 133 135 134 136 /** Two byte opcode map with prefix 0x66 */ … … 198 200 extern const DISOPCODE g_aMapX86_Group12[8*2]; 199 201 extern const DISOPCODE g_aMapX86_Group13[8*2]; 202 extern const DISOPCODE g_aMapX86_VGroup13[8*2]; 200 203 extern const DISOPCODE g_aMapX86_Group14[8*2]; 201 204 extern const DISOPCODE g_aMapX86_Group15_mem[8]; -
trunk/src/VBox/Disassembler/DisasmTables-x86-amd64.cpp
r100571 r103511 321 321 OP("retn %Iw", IDX_ParseImmUshort, 0, 0, OP_RETN, OP_PARM_Iw, OP_PARM_NONE, OP_PARM_NONE, DISOPTYPE_CONTROLFLOW | DISOPTYPE_UNCOND_CONTROLFLOW | DISOPTYPE_X86_FORCED_64_OP_SIZE), 322 322 OP("retn", 0, 0, 0, OP_RETN, OP_PARM_NONE, OP_PARM_NONE, OP_PARM_NONE, DISOPTYPE_CONTROLFLOW | DISOPTYPE_UNCOND_CONTROLFLOW | DISOPTYPE_X86_FORCED_64_OP_SIZE), 323 OP(" les %Gv,%Mp", IDX_ParseModRM, IDX_UseModRM, 0, OP_LES, OP_PARM_Gv, OP_PARM_Mp, OP_PARM_NONE, DISOPTYPE_HARMLESS | DISOPTYPE_X86_INVALID_64),324 OP(" lds %Gv,%Mp", IDX_ParseModRM, IDX_UseModRM, 0, OP_LDS, OP_PARM_Gv, OP_PARM_Mp, OP_PARM_NONE, DISOPTYPE_HARMLESS | DISOPTYPE_X86_INVALID_64 | DISOPTYPE_RRM_DANGEROUS),323 OP("vex3b/les %Gv,%Mp", IDX_ParseVex3b, 0, 0, OP_VEX3B, OP_PARM_NONE, OP_PARM_NONE, OP_PARM_NONE, DISOPTYPE_HARMLESS), 324 OP("vex2b/lds %Gv,%Mp", IDX_ParseVex2b, 0, 0, OP_VEX2B, OP_PARM_NONE, OP_PARM_NONE, OP_PARM_NONE, DISOPTYPE_HARMLESS), 325 325 /** @todo these two are actually group11 */ 326 326 OP("mov %Eb,%Ib", IDX_ParseModRM, IDX_ParseImmByte, 0, OP_MOV, OP_PARM_Eb, OP_PARM_Ib, OP_PARM_NONE, DISOPTYPE_HARMLESS), … … 394 394 }; 395 395 396 const DISOPCODE g_OpcodeLES = 397 OP("les %Gv,%Mp", IDX_ParseModRM, IDX_UseModRM, 0, OP_LES, OP_PARM_Gv, OP_PARM_Mp, OP_PARM_NONE, DISOPTYPE_HARMLESS | DISOPTYPE_X86_INVALID_64); 398 const DISOPCODE g_OpcodeLDS = 399 OP("lds %Gv,%Mp", IDX_ParseModRM, IDX_UseModRM, 0, OP_LDS, OP_PARM_Gv, OP_PARM_Mp, OP_PARM_NONE, DISOPTYPE_HARMLESS | DISOPTYPE_X86_INVALID_64 | DISOPTYPE_RRM_DANGEROUS); 396 400 397 401 const DISOPCODE g_aTwoByteMapX86[256] = … … 3190 3194 }; 3191 3195 3196 /* vex map1 0x72 */ 3197 const DISOPCODE g_aMapX86_VGroup13[8*2] = 3198 { 3199 /* 0 format string, parse param #1, parse param #2, parse param #3, parse param #4, opcode, param #1, param #2, param #3, param #4, flags */ 3200 /* No prefix */ 3201 INVALID_OPCODE_MOD_RM(0x00), 3202 INVALID_OPCODE_MOD_RM(0x01), 3203 INVALID_OPCODE_MOD_RM(0x02), 3204 INVALID_OPCODE_MOD_RM(0x03), 3205 INVALID_OPCODE_MOD_RM(0x04), 3206 INVALID_OPCODE_MOD_RM(0x05), 3207 INVALID_OPCODE_MOD_RM(0x06), 3208 INVALID_OPCODE_MOD_RM(0x07), 3209 3210 /* Group 13 with prefix 0x66 */ 3211 INVALID_OPCODE_MOD_RM(0x08), 3212 INVALID_OPCODE_MOD_RM(0x09), 3213 OPVEX("vpsrld %Hx,%Ux,%Ib", IDX_ParseVexDest, IDX_ParseModRM, IDX_ParseImmByte, 0, OP_VPSRLD, OP_PARM_Hx, OP_PARM_Ux, OP_PARM_Ib, OP_PARM_NONE, DISOPTYPE_HARMLESS), 3214 INVALID_OPCODE_MOD_RM(0x0b), 3215 OPVEX("vpsrad %Hx,%Ux,%Ib", IDX_ParseVexDest, IDX_ParseModRM, IDX_ParseImmByte, 0, OP_VPSRAD, OP_PARM_Hx, OP_PARM_Ux, OP_PARM_Ib, OP_PARM_NONE, DISOPTYPE_HARMLESS), 3216 INVALID_OPCODE_MOD_RM(0x0d), 3217 OPVEX("vpslld %Hx,%Ux,%Ib", IDX_ParseVexDest, IDX_ParseModRM, IDX_ParseImmByte, 0, OP_VPSLLD, OP_PARM_Hx, OP_PARM_Ux, OP_PARM_Ib, OP_PARM_NONE, DISOPTYPE_HARMLESS), 3218 INVALID_OPCODE_MOD_RM(0x0f), 3219 /* format string, parse param #1, parse param #2, parse param #3, parse param #4, opcode, param #1, param #2, param #3, param #4, flags */ 3220 }; 3221 3192 3222 /* 0xF 0x73 */ 3193 3223 const DISOPCODE g_aMapX86_Group14[8*2] = … … 3461 3491 OPVEX("vpshufd %Vx,%Wx,%Ib", IDX_ParseModRM, IDX_UseModRM, IDX_ParseImmByte, 0, OP_VPSHUFD, OP_PARM_Vx, OP_PARM_Wx, OP_PARM_Ib, OP_PARM_NONE, DISOPTYPE_HARMLESS), 3462 3492 INVALID_OPCODE, 3463 INVALID_OPCODE,3493 OP("vgroup13", IDX_ParseGrp13, 0, 0, OP_GRP13, OP_PARM_NONE, OP_PARM_NONE, OP_PARM_NONE, DISOPTYPE_HARMLESS), 3464 3494 INVALID_OPCODE, 3465 3495 OPVEX("vpcmpeqb %Vx,%Hx,%Wx", IDX_ParseModRM, IDX_ParseVexDest, IDX_UseModRM, 0, OP_VPCMPEQB, OP_PARM_Vx, OP_PARM_Hx, OP_PARM_Wx, OP_PARM_NONE, DISOPTYPE_HARMLESS), -
trunk/src/VBox/Disassembler/testcase/tstDisasm-1A.asm
r98668 r103511 164 164 paddd xmm1, xmm3 165 165 166 lds eax, [ebx] 167 les ebp, [esp] 166 168 %if __YASM_VERSION_ID__ >= 001030000h ; Old yasm doesn't support the instructions below 167 169 adcx eax, ebx … … 181 183 vgatherqps xmm0,dword [eax+xmm0*2],xmm0 182 184 vgatherqpd xmm0,qword [eax+xmm0*2],xmm0 185 vpsrld ymm5, ymm1, 009h 186 vpslld ymm0, ymm7, 01ah 183 187 %endif 184 188 … … 386 390 vpmovsxbw ymm4,[0x100] 387 391 vgatherqpd xmm0,qword [rbx+xmm11*2],xmm2 392 393 vpsrld ymm5, ymm1, 009h 394 vpsrld ymm8, ymm12, 011h 395 vpslld ymm0, ymm7, 01ah 388 396 %endif 389 397
Note:
See TracChangeset
for help on using the changeset viewer.