/** @interface_method_impl{PDMDEVHLPR0,pfnPCISetIrq} */ static DECLCALLBACK(void) pdmR0DevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel) { PDMDEV_ASSERT_DEVINS(pDevIns); LogFlow(("pdmR0DevHlp_ISASetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel)); PVM pVM = pDevIns->Internal.s.pVMR0; pdmLock(pVM); uint32_t uTagSrc; if (iLevel & PDM_IRQ_LEVEL_HIGH) { pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing); if (iLevel == PDM_IRQ_LEVEL_HIGH) VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc)); else VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc)); } else uTagSrc = pDevIns->Internal.s.uLastIrqTag; bool fRc = pdmR0IsaSetIrq(pVM, iIrq, iLevel, uTagSrc); if (iLevel == PDM_IRQ_LEVEL_LOW && fRc) VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc)); pdmUnlock(pVM); LogFlow(("pdmR0DevHlp_ISASetIrq: caller=%p/%d: returns void; uTagSrc=%#x\n", pDevIns, pDevIns->iInstance, uTagSrc)); }
/** @interface_method_impl{PDMHPETHLPR3,pfnSetIrq} */ static DECLCALLBACK(int) pdmR3HpetHlp_SetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel) { PDMDEV_ASSERT_DEVINS(pDevIns); LogFlow(("pdmR3HpetHlp_SetIrq: caller='%s'/%d: iIrq=%d iLevel=%d\n", pDevIns->pReg->szName, pDevIns->iInstance, iIrq, iLevel)); PVM pVM = pDevIns->Internal.s.pVMR3; pdmLock(pVM); uint32_t uTagSrc; if (iLevel & PDM_IRQ_LEVEL_HIGH) { pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing); if (iLevel == PDM_IRQ_LEVEL_HIGH) VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc)); else VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc)); } else uTagSrc = pDevIns->Internal.s.uLastIrqTag; PDMIsaSetIrq(pVM, iIrq, iLevel, uTagSrc); /* (The API takes the lock recursively.) */ if (iLevel == PDM_IRQ_LEVEL_LOW) VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc)); pdmUnlock(pVM); return 0; }
/** * Gets the pending interrupt. * * @returns VBox status code. * @param pVCpu Pointer to the VMCPU. * @param pu8Interrupt Where to store the interrupt on success. */ VMMDECL(int) PDMGetInterrupt(PVMCPU pVCpu, uint8_t *pu8Interrupt) { PVM pVM = pVCpu->CTX_SUFF(pVM); pdmLock(pVM); /* * The local APIC has a higher priority than the PIC. */ if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC)) { VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC); Assert(pVM->pdm.s.Apic.CTX_SUFF(pDevIns)); Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnGetInterrupt)); uint32_t uTagSrc; int i = pVM->pdm.s.Apic.CTX_SUFF(pfnGetInterrupt)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu->idCpu, &uTagSrc); AssertMsg(i <= 255 && i >= 0, ("i=%d\n", i)); if (i >= 0) { pdmUnlock(pVM); *pu8Interrupt = (uint8_t)i; VBOXVMM_PDM_IRQ_GET(pVCpu, RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc), i); return VINF_SUCCESS; } } /* * Check the PIC. */ if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC)) { VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC); Assert(pVM->pdm.s.Pic.CTX_SUFF(pDevIns)); Assert(pVM->pdm.s.Pic.CTX_SUFF(pfnGetInterrupt)); uint32_t uTagSrc; int i = pVM->pdm.s.Pic.CTX_SUFF(pfnGetInterrupt)(pVM->pdm.s.Pic.CTX_SUFF(pDevIns), &uTagSrc); AssertMsg(i <= 255 && i >= 0, ("i=%d\n", i)); if (i >= 0) { pdmUnlock(pVM); *pu8Interrupt = (uint8_t)i; VBOXVMM_PDM_IRQ_GET(pVCpu, RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc), i); return VINF_SUCCESS; } } /** @todo Figure out exactly why we can get here without anything being set. (REM) */ pdmUnlock(pVM); return VERR_NO_DATA; }
/** @interface_method_impl{PDMDEVHLPR0,pfnPCISetIrq} */ static DECLCALLBACK(void) pdmR0DevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel) { PDMDEV_ASSERT_DEVINS(pDevIns); LogFlow(("pdmR0DevHlp_PCISetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel)); PVM pVM = pDevIns->Internal.s.pVMR0; PPCIDEVICE pPciDev = pDevIns->Internal.s.pPciDeviceR0; PPDMPCIBUS pPciBus = pDevIns->Internal.s.pPciBusR0; pdmLock(pVM); uint32_t uTagSrc; if (iLevel & PDM_IRQ_LEVEL_HIGH) { pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing); if (iLevel == PDM_IRQ_LEVEL_HIGH) VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc)); else VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc)); } else uTagSrc = pDevIns->Internal.s.uLastIrqTag; if ( pPciDev && pPciBus && pPciBus->pDevInsR0) { pPciBus->pfnSetIrqR0(pPciBus->pDevInsR0, pPciDev, iIrq, iLevel, uTagSrc); pdmUnlock(pVM); if (iLevel == PDM_IRQ_LEVEL_LOW) VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc)); } else { pdmUnlock(pVM); /* queue for ring-3 execution. */ PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueR0); AssertReturnVoid(pTask); pTask->enmOp = PDMDEVHLPTASKOP_PCI_SET_IRQ; pTask->pDevInsR3 = PDMDEVINS_2_R3PTR(pDevIns); pTask->u.SetIRQ.iIrq = iIrq; pTask->u.SetIRQ.iLevel = iLevel; pTask->u.SetIRQ.uTagSrc = uTagSrc; PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueR0, &pTask->Core, 0); } LogFlow(("pdmR0DevHlp_PCISetIrq: caller=%p/%d: returns void; uTagSrc=%#x\n", pDevIns, pDevIns->iInstance, uTagSrc)); }
/** * @copydoc RTNetIPv6PseudoChecksumBits */ DECLINLINE(uint32_t) rtNetIPv6PseudoChecksumBits(PCRTNETADDRIPV6 pSrcAddr, PCRTNETADDRIPV6 pDstAddr, uint8_t bProtocol, uint32_t cbPkt) { uint32_t u32Sum = pSrcAddr->au16[0] + pSrcAddr->au16[1] + pSrcAddr->au16[2] + pSrcAddr->au16[3] + pSrcAddr->au16[4] + pSrcAddr->au16[5] + pSrcAddr->au16[6] + pSrcAddr->au16[7] + pDstAddr->au16[0] + pDstAddr->au16[1] + pDstAddr->au16[2] + pDstAddr->au16[3] + pDstAddr->au16[4] + pDstAddr->au16[5] + pDstAddr->au16[6] + pDstAddr->au16[7] + RT_H2BE_U16(RT_HIWORD(cbPkt)) + RT_H2BE_U16(RT_LOWORD(cbPkt)) + 0 + RT_H2BE_U16(RT_MAKE_U16(bProtocol, 0)); return u32Sum; }
/** @interface_method_impl{PDMAPICHLPR0,pfnCalcIrqTag} */ static DECLCALLBACK(uint32_t) pdmR0ApicHlp_CalcIrqTag(PPDMDEVINS pDevIns, uint8_t u8Level) { PDMDEV_ASSERT_DEVINS(pDevIns); PVM pVM = pDevIns->Internal.s.pVMR0; pdmLock(pVM); uint32_t uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing); if (u8Level == PDM_IRQ_LEVEL_HIGH) VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc)); else VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc)); pdmUnlock(pVM); LogFlow(("pdmR0ApicHlp_CalcIrqTag: caller=%p/%d: returns %#x (u8Level=%d)\n", pDevIns, pDevIns->iInstance, uTagSrc, u8Level)); return uTagSrc; }
/** * Returns the value of the parameter in pParam * * @returns VBox error code * @param pCtx CPU context structure pointer * @param pCpu Pointer to cpu structure which have DISCPUSTATE::mode * set correctly. * @param pParam Pointer to the parameter to parse * @param pParamVal Pointer to parameter value (OUT) * @param parmtype Parameter type * * @note Currently doesn't handle FPU/XMM/MMX/3DNow! parameters correctly!! * */ DISDECL(int) DISQueryParamVal(PCPUMCTXCORE pCtx, PDISCPUSTATE pCpu, POP_PARAMETER pParam, POP_PARAMVAL pParamVal, PARAM_TYPE parmtype) { memset(pParamVal, 0, sizeof(*pParamVal)); if (DIS_IS_EFFECTIVE_ADDR(pParam->flags)) { // Effective address pParamVal->type = PARMTYPE_ADDRESS; pParamVal->size = pParam->size; if (pParam->flags & USE_BASE) { if (pParam->flags & USE_REG_GEN8) { pParamVal->flags |= PARAM_VAL8; if (RT_FAILURE(DISFetchReg8(pCtx, pParam->base.reg_gen, &pParamVal->val.val8))) return VERR_INVALID_PARAMETER; } else if (pParam->flags & USE_REG_GEN16) { pParamVal->flags |= PARAM_VAL16; if (RT_FAILURE(DISFetchReg16(pCtx, pParam->base.reg_gen, &pParamVal->val.val16))) return VERR_INVALID_PARAMETER; } else if (pParam->flags & USE_REG_GEN32) { pParamVal->flags |= PARAM_VAL32; if (RT_FAILURE(DISFetchReg32(pCtx, pParam->base.reg_gen, &pParamVal->val.val32))) return VERR_INVALID_PARAMETER; } else if (pParam->flags & USE_REG_GEN64) { pParamVal->flags |= PARAM_VAL64; if (RT_FAILURE(DISFetchReg64(pCtx, pParam->base.reg_gen, &pParamVal->val.val64))) return VERR_INVALID_PARAMETER; } else { AssertFailed(); return VERR_INVALID_PARAMETER; } } // Note that scale implies index (SIB byte) if (pParam->flags & USE_INDEX) { if (pParam->flags & USE_REG_GEN16) { uint16_t val16; pParamVal->flags |= PARAM_VAL16; if (RT_FAILURE(DISFetchReg16(pCtx, pParam->index.reg_gen, &val16))) return VERR_INVALID_PARAMETER; Assert(!(pParam->flags & USE_SCALE)); /* shouldn't be possible in 16 bits mode */ pParamVal->val.val16 += val16; } else if (pParam->flags & USE_REG_GEN32) { uint32_t val32; pParamVal->flags |= PARAM_VAL32; if (RT_FAILURE(DISFetchReg32(pCtx, pParam->index.reg_gen, &val32))) return VERR_INVALID_PARAMETER; if (pParam->flags & USE_SCALE) val32 *= pParam->scale; pParamVal->val.val32 += val32; } else if (pParam->flags & USE_REG_GEN64) { uint64_t val64; pParamVal->flags |= PARAM_VAL64; if (RT_FAILURE(DISFetchReg64(pCtx, pParam->index.reg_gen, &val64))) return VERR_INVALID_PARAMETER; if (pParam->flags & USE_SCALE) val64 *= pParam->scale; pParamVal->val.val64 += val64; } else AssertFailed(); } if (pParam->flags & USE_DISPLACEMENT8) { if (pCpu->mode == CPUMODE_32BIT) pParamVal->val.val32 += (int32_t)pParam->disp8; else if (pCpu->mode == CPUMODE_64BIT) pParamVal->val.val64 += (int64_t)pParam->disp8; else pParamVal->val.val16 += (int16_t)pParam->disp8; } else if (pParam->flags & USE_DISPLACEMENT16) { if (pCpu->mode == CPUMODE_32BIT) pParamVal->val.val32 += (int32_t)pParam->disp16; else if (pCpu->mode == CPUMODE_64BIT) pParamVal->val.val64 += (int64_t)pParam->disp16; else pParamVal->val.val16 += pParam->disp16; } else if (pParam->flags & USE_DISPLACEMENT32) { if (pCpu->mode == CPUMODE_32BIT) pParamVal->val.val32 += pParam->disp32; else pParamVal->val.val64 += pParam->disp32; } else if (pParam->flags & USE_DISPLACEMENT64) { Assert(pCpu->mode == CPUMODE_64BIT); pParamVal->val.val64 += (int64_t)pParam->disp64; } else if (pParam->flags & USE_RIPDISPLACEMENT32) { Assert(pCpu->mode == CPUMODE_64BIT); /* Relative to the RIP of the next instruction. */ pParamVal->val.val64 += pParam->disp32 + pCtx->rip + pCpu->opsize; } return VINF_SUCCESS; } if (pParam->flags & (USE_REG_GEN8|USE_REG_GEN16|USE_REG_GEN32|USE_REG_GEN64|USE_REG_FP|USE_REG_MMX|USE_REG_XMM|USE_REG_CR|USE_REG_DBG|USE_REG_SEG|USE_REG_TEST)) { if (parmtype == PARAM_DEST) { // Caller needs to interpret the register according to the instruction (source/target, special value etc) pParamVal->type = PARMTYPE_REGISTER; pParamVal->size = pParam->size; return VINF_SUCCESS; } //else PARAM_SOURCE pParamVal->type = PARMTYPE_IMMEDIATE; if (pParam->flags & USE_REG_GEN8) { pParamVal->flags |= PARAM_VAL8; pParamVal->size = sizeof(uint8_t); if (RT_FAILURE(DISFetchReg8(pCtx, pParam->base.reg_gen, &pParamVal->val.val8))) return VERR_INVALID_PARAMETER; } else if (pParam->flags & USE_REG_GEN16) { pParamVal->flags |= PARAM_VAL16; pParamVal->size = sizeof(uint16_t); if (RT_FAILURE(DISFetchReg16(pCtx, pParam->base.reg_gen, &pParamVal->val.val16))) return VERR_INVALID_PARAMETER; } else if (pParam->flags & USE_REG_GEN32) { pParamVal->flags |= PARAM_VAL32; pParamVal->size = sizeof(uint32_t); if (RT_FAILURE(DISFetchReg32(pCtx, pParam->base.reg_gen, &pParamVal->val.val32))) return VERR_INVALID_PARAMETER; } else if (pParam->flags & USE_REG_GEN64) { pParamVal->flags |= PARAM_VAL64; pParamVal->size = sizeof(uint64_t); if (RT_FAILURE(DISFetchReg64(pCtx, pParam->base.reg_gen, &pParamVal->val.val64))) return VERR_INVALID_PARAMETER; } else { // Caller needs to interpret the register according to the instruction (source/target, special value etc) pParamVal->type = PARMTYPE_REGISTER; } Assert(!(pParam->flags & USE_IMMEDIATE)); return VINF_SUCCESS; } if (pParam->flags & USE_IMMEDIATE) { pParamVal->type = PARMTYPE_IMMEDIATE; if (pParam->flags & (USE_IMMEDIATE8|USE_IMMEDIATE8_REL)) { pParamVal->flags |= PARAM_VAL8; if (pParam->size == 2) { pParamVal->size = sizeof(uint16_t); pParamVal->val.val16 = (uint8_t)pParam->parval; } else { pParamVal->size = sizeof(uint8_t); pParamVal->val.val8 = (uint8_t)pParam->parval; } } else if (pParam->flags & (USE_IMMEDIATE16|USE_IMMEDIATE16_REL|USE_IMMEDIATE_ADDR_0_16|USE_IMMEDIATE16_SX8)) { pParamVal->flags |= PARAM_VAL16; pParamVal->size = sizeof(uint16_t); pParamVal->val.val16 = (uint16_t)pParam->parval; AssertMsg(pParamVal->size == pParam->size || ((pParam->size == 1) && (pParam->flags & USE_IMMEDIATE16_SX8)), ("pParamVal->size %d vs %d EIP=%RX32\n", pParamVal->size, pParam->size, pCtx->eip) ); } else if (pParam->flags & (USE_IMMEDIATE32|USE_IMMEDIATE32_REL|USE_IMMEDIATE_ADDR_0_32|USE_IMMEDIATE32_SX8)) { pParamVal->flags |= PARAM_VAL32; pParamVal->size = sizeof(uint32_t); pParamVal->val.val32 = (uint32_t)pParam->parval; Assert(pParamVal->size == pParam->size || ((pParam->size == 1) && (pParam->flags & USE_IMMEDIATE32_SX8)) ); } else if (pParam->flags & (USE_IMMEDIATE64 | USE_IMMEDIATE64_REL | USE_IMMEDIATE64_SX8)) { pParamVal->flags |= PARAM_VAL64; pParamVal->size = sizeof(uint64_t); pParamVal->val.val64 = pParam->parval; Assert(pParamVal->size == pParam->size || ((pParam->size == 1) && (pParam->flags & USE_IMMEDIATE64_SX8)) ); } else if (pParam->flags & (USE_IMMEDIATE_ADDR_16_16)) { pParamVal->flags |= PARAM_VALFARPTR16; pParamVal->size = sizeof(uint16_t)*2; pParamVal->val.farptr.sel = (uint16_t)RT_LOWORD(pParam->parval >> 16); pParamVal->val.farptr.offset = (uint32_t)RT_LOWORD(pParam->parval); Assert(pParamVal->size == pParam->size); }
/** * Returns the value of the parameter in pParam * * @returns VBox error code * @param pCtx CPU context structure pointer * @param pDis Pointer to the disassembler state. * @param pParam Pointer to the parameter to parse * @param pParamVal Pointer to parameter value (OUT) * @param parmtype Parameter type * * @note Currently doesn't handle FPU/XMM/MMX/3DNow! parameters correctly!! * */ DISDECL(int) DISQueryParamVal(PCPUMCTXCORE pCtx, PCDISSTATE pDis, PCDISOPPARAM pParam, PDISQPVPARAMVAL pParamVal, DISQPVWHICH parmtype) { memset(pParamVal, 0, sizeof(*pParamVal)); if (DISUSE_IS_EFFECTIVE_ADDR(pParam->fUse)) { // Effective address pParamVal->type = DISQPV_TYPE_ADDRESS; pParamVal->size = pParam->cb; if (pParam->fUse & DISUSE_BASE) { if (pParam->fUse & DISUSE_REG_GEN8) { pParamVal->flags |= DISQPV_FLAG_8; if (RT_FAILURE(DISFetchReg8(pCtx, pParam->Base.idxGenReg, &pParamVal->val.val8))) return VERR_INVALID_PARAMETER; } else if (pParam->fUse & DISUSE_REG_GEN16) { pParamVal->flags |= DISQPV_FLAG_16; if (RT_FAILURE(DISFetchReg16(pCtx, pParam->Base.idxGenReg, &pParamVal->val.val16))) return VERR_INVALID_PARAMETER; } else if (pParam->fUse & DISUSE_REG_GEN32) { pParamVal->flags |= DISQPV_FLAG_32; if (RT_FAILURE(DISFetchReg32(pCtx, pParam->Base.idxGenReg, &pParamVal->val.val32))) return VERR_INVALID_PARAMETER; } else if (pParam->fUse & DISUSE_REG_GEN64) { pParamVal->flags |= DISQPV_FLAG_64; if (RT_FAILURE(DISFetchReg64(pCtx, pParam->Base.idxGenReg, &pParamVal->val.val64))) return VERR_INVALID_PARAMETER; } else { AssertFailed(); return VERR_INVALID_PARAMETER; } } // Note that scale implies index (SIB byte) if (pParam->fUse & DISUSE_INDEX) { if (pParam->fUse & DISUSE_REG_GEN16) { uint16_t val16; pParamVal->flags |= DISQPV_FLAG_16; if (RT_FAILURE(DISFetchReg16(pCtx, pParam->Index.idxGenReg, &val16))) return VERR_INVALID_PARAMETER; Assert(!(pParam->fUse & DISUSE_SCALE)); /* shouldn't be possible in 16 bits mode */ pParamVal->val.val16 += val16; } else if (pParam->fUse & DISUSE_REG_GEN32) { uint32_t val32; pParamVal->flags |= DISQPV_FLAG_32; if (RT_FAILURE(DISFetchReg32(pCtx, pParam->Index.idxGenReg, &val32))) return VERR_INVALID_PARAMETER; if (pParam->fUse & DISUSE_SCALE) val32 *= pParam->uScale; pParamVal->val.val32 += val32; } else if (pParam->fUse & DISUSE_REG_GEN64) { uint64_t val64; pParamVal->flags |= DISQPV_FLAG_64; if (RT_FAILURE(DISFetchReg64(pCtx, pParam->Index.idxGenReg, &val64))) return VERR_INVALID_PARAMETER; if (pParam->fUse & DISUSE_SCALE) val64 *= pParam->uScale; pParamVal->val.val64 += val64; } else AssertFailed(); } if (pParam->fUse & DISUSE_DISPLACEMENT8) { if (pDis->uCpuMode == DISCPUMODE_32BIT) pParamVal->val.val32 += (int32_t)pParam->uDisp.i8; else if (pDis->uCpuMode == DISCPUMODE_64BIT) pParamVal->val.val64 += (int64_t)pParam->uDisp.i8; else pParamVal->val.val16 += (int16_t)pParam->uDisp.i8; } else if (pParam->fUse & DISUSE_DISPLACEMENT16) { if (pDis->uCpuMode == DISCPUMODE_32BIT) pParamVal->val.val32 += (int32_t)pParam->uDisp.i16; else if (pDis->uCpuMode == DISCPUMODE_64BIT) pParamVal->val.val64 += (int64_t)pParam->uDisp.i16; else pParamVal->val.val16 += pParam->uDisp.i16; } else if (pParam->fUse & DISUSE_DISPLACEMENT32) { if (pDis->uCpuMode == DISCPUMODE_32BIT) pParamVal->val.val32 += pParam->uDisp.i32; else pParamVal->val.val64 += pParam->uDisp.i32; } else if (pParam->fUse & DISUSE_DISPLACEMENT64) { Assert(pDis->uCpuMode == DISCPUMODE_64BIT); pParamVal->val.val64 += pParam->uDisp.i64; } else if (pParam->fUse & DISUSE_RIPDISPLACEMENT32) { Assert(pDis->uCpuMode == DISCPUMODE_64BIT); /* Relative to the RIP of the next instruction. */ pParamVal->val.val64 += pParam->uDisp.i32 + pCtx->rip + pDis->cbInstr; } return VINF_SUCCESS; } if (pParam->fUse & (DISUSE_REG_GEN8|DISUSE_REG_GEN16|DISUSE_REG_GEN32|DISUSE_REG_GEN64|DISUSE_REG_FP|DISUSE_REG_MMX|DISUSE_REG_XMM|DISUSE_REG_CR|DISUSE_REG_DBG|DISUSE_REG_SEG|DISUSE_REG_TEST)) { if (parmtype == DISQPVWHICH_DST) { // Caller needs to interpret the register according to the instruction (source/target, special value etc) pParamVal->type = DISQPV_TYPE_REGISTER; pParamVal->size = pParam->cb; return VINF_SUCCESS; } //else DISQPVWHICH_SRC pParamVal->type = DISQPV_TYPE_IMMEDIATE; if (pParam->fUse & DISUSE_REG_GEN8) { pParamVal->flags |= DISQPV_FLAG_8; pParamVal->size = sizeof(uint8_t); if (RT_FAILURE(DISFetchReg8(pCtx, pParam->Base.idxGenReg, &pParamVal->val.val8))) return VERR_INVALID_PARAMETER; } else if (pParam->fUse & DISUSE_REG_GEN16) { pParamVal->flags |= DISQPV_FLAG_16; pParamVal->size = sizeof(uint16_t); if (RT_FAILURE(DISFetchReg16(pCtx, pParam->Base.idxGenReg, &pParamVal->val.val16))) return VERR_INVALID_PARAMETER; } else if (pParam->fUse & DISUSE_REG_GEN32) { pParamVal->flags |= DISQPV_FLAG_32; pParamVal->size = sizeof(uint32_t); if (RT_FAILURE(DISFetchReg32(pCtx, pParam->Base.idxGenReg, &pParamVal->val.val32))) return VERR_INVALID_PARAMETER; } else if (pParam->fUse & DISUSE_REG_GEN64) { pParamVal->flags |= DISQPV_FLAG_64; pParamVal->size = sizeof(uint64_t); if (RT_FAILURE(DISFetchReg64(pCtx, pParam->Base.idxGenReg, &pParamVal->val.val64))) return VERR_INVALID_PARAMETER; } else { // Caller needs to interpret the register according to the instruction (source/target, special value etc) pParamVal->type = DISQPV_TYPE_REGISTER; } Assert(!(pParam->fUse & DISUSE_IMMEDIATE)); return VINF_SUCCESS; } if (pParam->fUse & DISUSE_IMMEDIATE) { pParamVal->type = DISQPV_TYPE_IMMEDIATE; if (pParam->fUse & (DISUSE_IMMEDIATE8|DISUSE_IMMEDIATE8_REL)) { pParamVal->flags |= DISQPV_FLAG_8; if (pParam->cb == 2) { pParamVal->size = sizeof(uint16_t); pParamVal->val.val16 = (uint8_t)pParam->uValue; } else { pParamVal->size = sizeof(uint8_t); pParamVal->val.val8 = (uint8_t)pParam->uValue; } } else if (pParam->fUse & (DISUSE_IMMEDIATE16|DISUSE_IMMEDIATE16_REL|DISUSE_IMMEDIATE_ADDR_0_16|DISUSE_IMMEDIATE16_SX8)) { pParamVal->flags |= DISQPV_FLAG_16; pParamVal->size = sizeof(uint16_t); pParamVal->val.val16 = (uint16_t)pParam->uValue; AssertMsg(pParamVal->size == pParam->cb || ((pParam->cb == 1) && (pParam->fUse & DISUSE_IMMEDIATE16_SX8)), ("pParamVal->size %d vs %d EIP=%RX32\n", pParamVal->size, pParam->cb, pCtx->eip) ); } else if (pParam->fUse & (DISUSE_IMMEDIATE32|DISUSE_IMMEDIATE32_REL|DISUSE_IMMEDIATE_ADDR_0_32|DISUSE_IMMEDIATE32_SX8)) { pParamVal->flags |= DISQPV_FLAG_32; pParamVal->size = sizeof(uint32_t); pParamVal->val.val32 = (uint32_t)pParam->uValue; Assert(pParamVal->size == pParam->cb || ((pParam->cb == 1) && (pParam->fUse & DISUSE_IMMEDIATE32_SX8)) ); } else if (pParam->fUse & (DISUSE_IMMEDIATE64 | DISUSE_IMMEDIATE64_REL | DISUSE_IMMEDIATE64_SX8)) { pParamVal->flags |= DISQPV_FLAG_64; pParamVal->size = sizeof(uint64_t); pParamVal->val.val64 = pParam->uValue; Assert(pParamVal->size == pParam->cb || ((pParam->cb == 1) && (pParam->fUse & DISUSE_IMMEDIATE64_SX8)) ); } else if (pParam->fUse & (DISUSE_IMMEDIATE_ADDR_16_16)) { pParamVal->flags |= DISQPV_FLAG_FARPTR16; pParamVal->size = sizeof(uint16_t)*2; pParamVal->val.farptr.sel = (uint16_t)RT_LOWORD(pParam->uValue >> 16); pParamVal->val.farptr.offset = (uint32_t)RT_LOWORD(pParam->uValue); Assert(pParamVal->size == pParam->cb); }