Changeset 41791 in vbox for trunk/src/VBox/Disassembler
- Timestamp:
- Jun 16, 2012 11:02:09 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Disassembler/DisasmCore.cpp
r41790 r41791 48 48 *******************************************************************************/ 49 49 static void disasmModRMReg(PDISSTATE pDis, PCDISOPCODE pOp, unsigned idx, PDISOPPARAM pParam, int fRegAddr); 50 static void disasmModRMReg16(PDISSTATE pDis, PCDISOPCODE pOp, unsigned idx, PDISOPPARAM pParam);51 static void disasmModRMSReg(PDISSTATE pDis, PCDISOPCODE pOp, unsigned idx, PDISOPPARAM pParam);52 50 53 51 … … 214 212 215 213 216 //***************************************************************************** 217 /* Read functions for getting the opcode bytes */ 218 //***************************************************************************** 219 214 /******************************************************************************************************************************** 215 * 216 * 217 * Read functions for getting the opcode bytes 218 * 219 * 220 ********************************************************************************************************************************/ 220 221 221 222 /** … … 593 594 static size_t ParseEscFP(size_t offInstr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISSTATE pDis) 594 595 { 595 int index;596 size_t size = 0; 596 597 PCDISOPCODE fpop; 597 size_t size = 0;598 unsigned ModRM;599 598 NOREF(pOp); 600 599 601 ModRM = disReadByte(pDis, offInstr); 602 603 index = pDis->bOpCode - 0xD8; 600 unsigned ModRM = disReadByte(pDis, offInstr); 601 unsigned index = pDis->bOpCode - 0xD8; 604 602 if (ModRM <= 0xBF) 605 603 { 606 604 fpop = &(g_apMapX86_FP_Low[index])[MODRM_REG(ModRM)]; 607 pDis->pCurInstr = (PCDISOPCODE)fpop;605 pDis->pCurInstr = fpop; 608 606 609 607 // Should contain the parameter type on input … … 614 612 { 615 613 fpop = &(g_apMapX86_FP_High[index])[ModRM - 0xC0]; 616 pDis->pCurInstr = (PCDISOPCODE)fpop;614 pDis->pCurInstr = fpop; 617 615 } 618 616 … … 644 642 645 643 if (fpop->idxParse1 != IDX_ParseNop) 646 size += pDis->pfnDisasmFnTable[fpop->idxParse1](offInstr+size, (PCDISOPCODE)fpop, pParam, pDis);644 size += pDis->pfnDisasmFnTable[fpop->idxParse1](offInstr+size, fpop, pParam, pDis); 647 645 648 646 if (fpop->idxParse2 != IDX_ParseNop) 649 size += pDis->pfnDisasmFnTable[fpop->idxParse2](offInstr+size, (PCDISOPCODE)fpop, pParam, pDis);647 size += pDis->pfnDisasmFnTable[fpop->idxParse2](offInstr+size, fpop, pParam, pDis); 650 648 651 649 return size; 652 650 } 653 //***************************************************************************** 654 // SIB byte: (not 16-bit mode) 655 // 7 - 6 5 - 3 2-0 656 // Scale Index Base 657 //***************************************************************************** 651 652 653 /******************************************************************************************************************************** 654 * 655 * 656 * SIB byte: (not 16-bit mode) 657 * 7 - 6 5 - 3 2-0 658 * Scale Index Base 659 * 660 * 661 ********************************************************************************************************************************/ 658 662 static void UseSIB(size_t offInstr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISSTATE pDis) 659 663 { … … 703 707 return; /* Already fetched everything in ParseSIB; no size returned */ 704 708 } 705 //***************************************************************************** 706 //***************************************************************************** 709 710 707 711 static size_t ParseSIB(size_t offInstr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISSTATE pDis) 708 712 { 709 713 unsigned size = sizeof(uint8_t); 710 unsigned SIB;711 714 NOREF(pOp); NOREF(pParam); 712 715 713 SIB = disReadByte(pDis, offInstr);716 unsigned SIB = disReadByte(pDis, offInstr); 714 717 offInstr += size; 715 718 … … 722 725 /* REX.B extends the Base field if not scaled index + disp32 */ 723 726 if (!(pDis->SIB.Bits.Base == 5 && pDis->ModRM.Bits.Mod == 0)) 724 pDis->SIB.Bits.Base |= ( (!!(pDis->fRexPrefix & DISPREFIX_REX_FLAGS_B)) << 3);725 726 pDis->SIB.Bits.Index |= ( (!!(pDis->fRexPrefix & DISPREFIX_REX_FLAGS_X)) << 3);727 pDis->SIB.Bits.Base |= (!!(pDis->fRexPrefix & DISPREFIX_REX_FLAGS_B)) << 3; 728 729 pDis->SIB.Bits.Index |= (!!(pDis->fRexPrefix & DISPREFIX_REX_FLAGS_X)) << 3; 727 730 } 728 731 … … 736 739 return size; 737 740 } 738 //***************************************************************************** 739 //***************************************************************************** 741 742 740 743 static size_t ParseSIB_SizeOnly(size_t offInstr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISSTATE pDis) 741 744 { 742 745 unsigned size = sizeof(uint8_t); 743 unsigned SIB;744 746 NOREF(pOp); NOREF(pParam); 745 747 746 SIB = disReadByte(pDis, offInstr);748 unsigned SIB = disReadByte(pDis, offInstr); 747 749 748 750 pDis->SIB.Bits.Base = SIB_BASE(SIB); … … 766 768 return size; 767 769 } 768 //***************************************************************************** 769 // ModR/M byte: 770 // 7 - 6 5 - 3 2-0 771 // Mod Reg/Opcode R/M 772 //***************************************************************************** 770 771 772 773 /******************************************************************************************************************************** 774 * 775 * 776 * ModR/M byte: 777 * 7 - 6 5 - 3 2-0 778 * Mod Reg/Opcode R/M 779 * 780 * 781 ********************************************************************************************************************************/ 782 static void disasmModRMReg(PDISSTATE pDis, PCDISOPCODE pOp, unsigned idx, PDISOPPARAM pParam, int fRegAddr) 783 { 784 NOREF(pOp); NOREF(pDis); 785 786 unsigned mod = pDis->ModRM.Bits.Mod; 787 788 unsigned type = OP_PARM_VTYPE(pParam->fParam); 789 unsigned subtype = OP_PARM_VSUBTYPE(pParam->fParam); 790 if (fRegAddr) 791 subtype = (pDis->uAddrMode == DISCPUMODE_64BIT) ? OP_PARM_q : OP_PARM_d; 792 else 793 if (subtype == OP_PARM_v || subtype == OP_PARM_NONE) 794 { 795 switch (pDis->uOpMode) 796 { 797 case DISCPUMODE_32BIT: 798 subtype = OP_PARM_d; 799 break; 800 case DISCPUMODE_64BIT: 801 subtype = OP_PARM_q; 802 break; 803 case DISCPUMODE_16BIT: 804 subtype = OP_PARM_w; 805 break; 806 default: 807 /* make gcc happy */ 808 break; 809 } 810 } 811 812 switch (subtype) 813 { 814 case OP_PARM_b: 815 Assert(idx < (pDis->fPrefix & DISPREFIX_REX ? 16U : 8U)); 816 817 /* AH, BH, CH & DH map to DIL, SIL, EBL & SPL when a rex prefix is present. */ 818 /* Intel® 64 and IA-32 Architectures Software Developers Manual: 3.4.1.1 */ 819 if ( (pDis->fPrefix & DISPREFIX_REX) 820 && idx >= DISGREG_AH 821 && idx <= DISGREG_BH) 822 { 823 idx += (DISGREG_SPL - DISGREG_AH); 824 } 825 826 pParam->fUse |= DISUSE_REG_GEN8; 827 pParam->Base.idxGenReg = idx; 828 break; 829 830 case OP_PARM_w: 831 Assert(idx < (pDis->fPrefix & DISPREFIX_REX ? 16U : 8U)); 832 833 pParam->fUse |= DISUSE_REG_GEN16; 834 pParam->Base.idxGenReg = idx; 835 break; 836 837 case OP_PARM_d: 838 Assert(idx < (pDis->fPrefix & DISPREFIX_REX ? 16U : 8U)); 839 840 pParam->fUse |= DISUSE_REG_GEN32; 841 pParam->Base.idxGenReg = idx; 842 break; 843 844 case OP_PARM_q: 845 pParam->fUse |= DISUSE_REG_GEN64; 846 pParam->Base.idxGenReg = idx; 847 break; 848 849 default: 850 Log(("disasmModRMReg %x:%x failed!!\n", type, subtype)); 851 pDis->rc = VERR_DIS_INVALID_MODRM; 852 break; 853 } 854 } 855 856 static void disasmModRMReg16(PDISSTATE pDis, PCDISOPCODE pOp, unsigned idx, PDISOPPARAM pParam) 857 { 858 static const uint8_t s_auBaseModRMReg16[8] = 859 { DISGREG_BX, DISGREG_BX, DISGREG_BP, DISGREG_BP, DISGREG_SI, DISGREG_DI, DISGREG_BP, DISGREG_BX }; 860 861 NOREF(pDis); NOREF(pOp); 862 pParam->fUse |= DISUSE_REG_GEN16; 863 pParam->Base.idxGenReg = s_auBaseModRMReg16[idx]; 864 if (idx < 4) 865 { 866 static const uint8_t s_auIndexModRMReg16[4] = { DISGREG_SI, DISGREG_DI, DISGREG_SI, DISGREG_DI }; 867 pParam->fUse |= DISUSE_INDEX; 868 pParam->Index.idxGenReg = s_auIndexModRMReg16[idx]; 869 } 870 } 871 //***************************************************************************** 872 //***************************************************************************** 873 static void disasmModRMSReg(PDISSTATE pDis, PCDISOPCODE pOp, unsigned idx, PDISOPPARAM pParam) 874 { 875 NOREF(pOp); 876 if (idx >= DISSELREG_END) 877 { 878 Log(("disasmModRMSReg %d failed!!\n", idx)); 879 pDis->rc = VERR_DIS_INVALID_PARAMETER; 880 return; 881 } 882 883 pParam->fUse |= DISUSE_REG_SEG; 884 pParam->Base.idxSegReg = (DISSELREG)idx; 885 } 886 887 773 888 static size_t UseModRM(size_t offInstr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISSTATE pDis) 774 889 { … … 1972 2087 unsigned reg = MODRM_REG(modrm); 1973 2088 1974 pOp = (PCDISOPCODE)&g_aMapX86_Group1[idx+reg];2089 pOp = &g_aMapX86_Group1[idx+reg]; 1975 2090 //little hack to make sure the ModRM byte is included in the returned size 1976 2091 if (pOp->idxParse1 != IDX_ParseModRM && pOp->idxParse2 != IDX_ParseModRM) … … 2032 2147 unsigned reg = MODRM_REG(modrm); 2033 2148 2034 pOp = (PCDISOPCODE)&g_aMapX86_Group3[idx+reg];2149 pOp = &g_aMapX86_Group3[idx+reg]; 2035 2150 2036 2151 //little hack to make sure the ModRM byte is included in the returned size … … 2052 2167 unsigned reg = MODRM_REG(modrm); 2053 2168 2054 pOp = (PCDISOPCODE)&g_aMapX86_Group4[reg];2169 pOp = &g_aMapX86_Group4[reg]; 2055 2170 2056 2171 //little hack to make sure the ModRM byte is included in the returned size … … 2072 2187 unsigned reg = MODRM_REG(modrm); 2073 2188 2074 pOp = (PCDISOPCODE)&g_aMapX86_Group5[reg];2189 pOp = &g_aMapX86_Group5[reg]; 2075 2190 2076 2191 //little hack to make sure the ModRM byte is included in the returned size … … 2106 2221 uint8_t opcode = disReadByte(pDis, offInstr+sizeof(uint8_t)+modrmsize); 2107 2222 2108 pOp = (PCDISOPCODE)&g_aTwoByteMapX86_3DNow[opcode];2223 pOp = &g_aTwoByteMapX86_3DNow[opcode]; 2109 2224 2110 2225 //little hack to make sure the ModRM byte is included in the returned size … … 2132 2247 unsigned reg = MODRM_REG(modrm); 2133 2248 2134 pOp = (PCDISOPCODE)&g_aMapX86_Group6[reg];2249 pOp = &g_aMapX86_Group6[reg]; 2135 2250 2136 2251 //little hack to make sure the ModRM byte is included in the returned size … … 2155 2270 2156 2271 if (mod == 3 && rm == 0) 2157 pOp = (PCDISOPCODE)&g_aMapX86_Group7_mod11_rm000[reg];2272 pOp = &g_aMapX86_Group7_mod11_rm000[reg]; 2158 2273 else 2159 2274 if (mod == 3 && rm == 1) 2160 pOp = (PCDISOPCODE)&g_aMapX86_Group7_mod11_rm001[reg];2161 else 2162 pOp = (PCDISOPCODE)&g_aMapX86_Group7_mem[reg];2275 pOp = &g_aMapX86_Group7_mod11_rm001[reg]; 2276 else 2277 pOp = &g_aMapX86_Group7_mem[reg]; 2163 2278 2164 2279 //little hack to make sure the ModRM byte is included in the returned size … … 2180 2295 unsigned reg = MODRM_REG(modrm); 2181 2296 2182 pOp = (PCDISOPCODE)&g_aMapX86_Group8[reg];2297 pOp = &g_aMapX86_Group8[reg]; 2183 2298 2184 2299 //little hack to make sure the ModRM byte is included in the returned size … … 2200 2315 unsigned reg = MODRM_REG(modrm); 2201 2316 2202 pOp = (PCDISOPCODE)&g_aMapX86_Group9[reg];2317 pOp = &g_aMapX86_Group9[reg]; 2203 2318 2204 2319 //little hack to make sure the ModRM byte is included in the returned size … … 2220 2335 unsigned reg = MODRM_REG(modrm); 2221 2336 2222 pOp = (PCDISOPCODE)&g_aMapX86_Group10[reg];2337 pOp = &g_aMapX86_Group10[reg]; 2223 2338 2224 2339 //little hack to make sure the ModRM byte is included in the returned size … … 2243 2358 reg += 8; //2nd table 2244 2359 2245 pOp = (PCDISOPCODE)&g_aMapX86_Group12[reg];2360 pOp = &g_aMapX86_Group12[reg]; 2246 2361 2247 2362 //little hack to make sure the ModRM byte is included in the returned size … … 2264 2379 reg += 8; //2nd table 2265 2380 2266 pOp = (PCDISOPCODE)&g_aMapX86_Group13[reg];2381 pOp = &g_aMapX86_Group13[reg]; 2267 2382 2268 2383 //little hack to make sure the ModRM byte is included in the returned size … … 2286 2401 reg += 8; //2nd table 2287 2402 2288 pOp = (PCDISOPCODE)&g_aMapX86_Group14[reg];2403 pOp = &g_aMapX86_Group14[reg]; 2289 2404 2290 2405 //little hack to make sure the ModRM byte is included in the returned size … … 2309 2424 2310 2425 if (mod == 3 && rm == 0) 2311 pOp = (PCDISOPCODE)&g_aMapX86_Group15_mod11_rm000[reg];2312 else 2313 pOp = (PCDISOPCODE)&g_aMapX86_Group15_mem[reg];2426 pOp = &g_aMapX86_Group15_mod11_rm000[reg]; 2427 else 2428 pOp = &g_aMapX86_Group15_mem[reg]; 2314 2429 2315 2430 //little hack to make sure the ModRM byte is included in the returned size … … 2330 2445 unsigned reg = MODRM_REG(modrm); 2331 2446 2332 pOp = (PCDISOPCODE)&g_aMapX86_Group16[reg];2447 pOp = &g_aMapX86_Group16[reg]; 2333 2448 2334 2449 //little hack to make sure the ModRM byte is included in the returned size … … 2338 2453 size += disParseInstruction(offInstr, pOp, pDis); 2339 2454 return size; 2340 }2341 //*****************************************************************************2342 //*****************************************************************************2343 static void disasmModRMReg(PDISSTATE pDis, PCDISOPCODE pOp, unsigned idx, PDISOPPARAM pParam, int fRegAddr)2344 {2345 NOREF(pOp); NOREF(pDis);2346 2347 unsigned mod = pDis->ModRM.Bits.Mod;2348 2349 unsigned type = OP_PARM_VTYPE(pParam->fParam);2350 unsigned subtype = OP_PARM_VSUBTYPE(pParam->fParam);2351 if (fRegAddr)2352 subtype = (pDis->uAddrMode == DISCPUMODE_64BIT) ? OP_PARM_q : OP_PARM_d;2353 else2354 if (subtype == OP_PARM_v || subtype == OP_PARM_NONE)2355 {2356 switch (pDis->uOpMode)2357 {2358 case DISCPUMODE_32BIT:2359 subtype = OP_PARM_d;2360 break;2361 case DISCPUMODE_64BIT:2362 subtype = OP_PARM_q;2363 break;2364 case DISCPUMODE_16BIT:2365 subtype = OP_PARM_w;2366 break;2367 default:2368 /* make gcc happy */2369 break;2370 }2371 }2372 2373 switch (subtype)2374 {2375 case OP_PARM_b:2376 Assert(idx < (pDis->fPrefix & DISPREFIX_REX ? 16U : 8U));2377 2378 /* AH, BH, CH & DH map to DIL, SIL, EBL & SPL when a rex prefix is present. */2379 /* Intel® 64 and IA-32 Architectures Software Developers Manual: 3.4.1.1 */2380 if ( (pDis->fPrefix & DISPREFIX_REX)2381 && idx >= DISGREG_AH2382 && idx <= DISGREG_BH)2383 {2384 idx += (DISGREG_SPL - DISGREG_AH);2385 }2386 2387 pParam->fUse |= DISUSE_REG_GEN8;2388 pParam->Base.idxGenReg = idx;2389 break;2390 2391 case OP_PARM_w:2392 Assert(idx < (pDis->fPrefix & DISPREFIX_REX ? 16U : 8U));2393 2394 pParam->fUse |= DISUSE_REG_GEN16;2395 pParam->Base.idxGenReg = idx;2396 break;2397 2398 case OP_PARM_d:2399 Assert(idx < (pDis->fPrefix & DISPREFIX_REX ? 16U : 8U));2400 2401 pParam->fUse |= DISUSE_REG_GEN32;2402 pParam->Base.idxGenReg = idx;2403 break;2404 2405 case OP_PARM_q:2406 pParam->fUse |= DISUSE_REG_GEN64;2407 pParam->Base.idxGenReg = idx;2408 break;2409 2410 default:2411 Log(("disasmModRMReg %x:%x failed!!\n", type, subtype));2412 pDis->rc = VERR_DIS_INVALID_MODRM;2413 break;2414 }2415 }2416 //*****************************************************************************2417 static const uint8_t g_auBaseModRMReg16[8] =2418 { DISGREG_BX, DISGREG_BX, DISGREG_BP, DISGREG_BP, DISGREG_SI, DISGREG_DI, DISGREG_BP, DISGREG_BX};2419 static const uint8_t g_auIndexModRMReg16[4] = { DISGREG_SI, DISGREG_DI, DISGREG_SI, DISGREG_DI };2420 //*****************************************************************************2421 static void disasmModRMReg16(PDISSTATE pDis, PCDISOPCODE pOp, unsigned idx, PDISOPPARAM pParam)2422 {2423 NOREF(pDis); NOREF(pOp);2424 pParam->fUse |= DISUSE_REG_GEN16;2425 pParam->Base.idxGenReg = g_auBaseModRMReg16[idx];2426 if (idx < 4)2427 {2428 pParam->fUse |= DISUSE_INDEX;2429 pParam->Index.idxGenReg = g_auIndexModRMReg16[idx];2430 }2431 }2432 //*****************************************************************************2433 //*****************************************************************************2434 static void disasmModRMSReg(PDISSTATE pDis, PCDISOPCODE pOp, unsigned idx, PDISOPPARAM pParam)2435 {2436 NOREF(pOp);2437 if (idx >= DISSELREG_END)2438 {2439 Log(("disasmModRMSReg %d failed!!\n", idx));2440 pDis->rc = VERR_DIS_INVALID_PARAMETER;2441 return;2442 }2443 2444 pParam->fUse |= DISUSE_REG_SEG;2445 pParam->Base.idxSegReg = (DISSELREG)idx;2446 2455 } 2447 2456 … … 2657 2666 PFNDISREADBYTES pfnReadBytes, void *pvUser) 2658 2667 { 2659 /* 2660 * Note! The RT_BZERO make ASSUMPTIONS about the placement of pvUser2. 2661 */ 2662 RT_BZERO(pDis, RT_OFFSETOF(DISSTATE, pvUser2)); 2668 RT_ZERO(*pDis); 2663 2669 2664 2670 #ifdef VBOX_STRICT /* poison */ … … 2747 2753 * @param fFilter Instruction type filter. 2748 2754 * @param pvUser User argument for the instruction reader. (Ends up in pvUser.) 2749 * @param pDis Pointer to CPU structure. With the exception of 2750 * DISSTATE::pvUser2, the structure will be 2751 * completely initialized by this API, i.e. no input is 2752 * taken from it. 2755 * @param pDis Pointer to disassembler state (output). 2753 2756 * @param pcbInstr Where to store the size of the instruction. (This 2754 2757 * is also stored in PDISSTATE::cbInstr.) Optional. … … 2779 2782 * @param fFilter Instruction type filter. 2780 2783 * @param pvUser User argument for the instruction reader. (Ends up in pvUser.) 2781 * @param pDis Pointer to CPU structure. With the exception of 2782 * DISSTATE::pvUser2, the structure will be 2783 * completely initialized by this API, i.e. no input is 2784 * taken from it. 2784 * @param pDis Pointer to disassembler state (output). 2785 2785 * @param pcbInstr Where to store the size of the instruction. (This 2786 2786 * is also stored in PDISSTATE::cbInstr.) Optional.
Note:
See TracChangeset
for help on using the changeset viewer.