static void testDisas(const char *pszSub, uint8_t const *pabInstrs, uintptr_t uEndPtr, DISCPUMODE enmDisCpuMode) { RTTestISub(pszSub); size_t const cbInstrs = uEndPtr - (uintptr_t)pabInstrs; for (size_t off = 0; off < cbInstrs;) { uint32_t const cErrBefore = RTTestIErrorCount(); uint32_t cb = 1; DISSTATE Dis; char szOutput[256] = {0}; int rc = DISInstrToStr(&pabInstrs[off], enmDisCpuMode, &Dis, &cb, szOutput, sizeof(szOutput)); RTTESTI_CHECK_RC(rc, VINF_SUCCESS); RTTESTI_CHECK(cb == Dis.cbInstr); RTTESTI_CHECK(cb > 0); RTTESTI_CHECK(cb <= 16); RTStrStripR(szOutput); RTTESTI_CHECK(szOutput[0]); if (szOutput[0]) { char *pszBytes = strchr(szOutput, '['); RTTESTI_CHECK(pszBytes); if (pszBytes) { RTTESTI_CHECK(pszBytes[-1] == ' '); RTTESTI_CHECK(RT_C_IS_XDIGIT(pszBytes[1])); RTTESTI_CHECK(pszBytes[cb * 3] == ']'); RTTESTI_CHECK(pszBytes[cb * 3 + 1] == ' '); size_t cch = strlen(szOutput); RTTESTI_CHECK(szOutput[cch - 1] != ','); } } if (cErrBefore != RTTestIErrorCount()) RTTestIFailureDetails("rc=%Rrc, off=%#x (%u) cbInstr=%u enmDisCpuMode=%d\n", rc, off, Dis.cbInstr, enmDisCpuMode); RTTestIPrintf(RTTESTLVL_ALWAYS, "%s\n", szOutput); /* Check with size-only. */ uint32_t cbOnly = 1; DISSTATE DisOnly; rc = DISInstrWithPrefetchedBytes((uintptr_t)&pabInstrs[off], enmDisCpuMode, 0 /*fFilter - none */, Dis.abInstr, Dis.cbCachedInstr, NULL, NULL, &DisOnly, &cbOnly); RTTESTI_CHECK_RC(rc, VINF_SUCCESS); RTTESTI_CHECK(cbOnly == DisOnly.cbInstr); RTTESTI_CHECK_MSG(cbOnly == cb, ("%#x vs %#x\n", cbOnly, cb)); off += cb; } }
bool MyDisBlock(uint8_t const *pbCodeBlock, int32_t cbMax) { DISCPUSTATE Cpu; int32_t i = 0; while (i < cbMax) { char szOutput[256]; uint32_t cbInstr; if (RT_FAILURE(DISInstrToStr(pbCodeBlock + i, DISCPUMODE_32BIT, &Cpu, &cbInstr, szOutput, sizeof(szOutput)))) return false; RTPrintf("%s", szOutput); /* next */ i += cbInstr; } return true; }