Disasm.cpp revision 513a32f8f69d704a1dd6dff832cbf9fdff987a97
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync/** @file
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync *
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * VBox disassembler:
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Main
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync/*
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync *
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * available from http://www.virtualbox.org. This file is free software;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * you can redistribute it and/or modify it under the terms of the GNU
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * General Public License (GPL) as published by the Free Software
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync *
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * additional information or have any questions.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync/*******************************************************************************
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync* Header Files *
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync*******************************************************************************/
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync#ifdef USING_VISUAL_STUDIO
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync# include <stdafx.h>
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync#endif
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync#include <VBox/dis.h>
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync#include <VBox/disopcode.h>
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync#include <VBox/err.h>
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync#include <iprt/assert.h>
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync#include <iprt/string.h>
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync#include "DisasmInternal.h"
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync#include "DisasmTables.h"
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync/**
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Disassembles a code block.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync *
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @returns VBox error code
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pCpu Pointer to cpu structure which have DISCPUSTATE::mode
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * set correctly.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pvCodeBlock Pointer to the strunction to disassemble.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param cbMax Maximum number of bytes to disassemble.
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync * @param pcbSize Where to store the size of the instruction.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * NULL is allowed.
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync *
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync *
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync * @todo Define output callback.
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync * @todo Using signed integers as sizes is a bit odd. There are still
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync * some GCC warnings about mixing signed and unsigend integers.
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync * @todo Need to extend this interface to include a code address so we
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync * can dissassemble GC code. Perhaps a new function is better...
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync * @remark cbMax isn't respected as a boundry. DISInstr() will read beyond cbMax.
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync * This means *pcbSize >= cbMax sometimes.
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync */
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsyncDISDECL(int) DISBlock(PDISCPUSTATE pCpu, RTUINTPTR pvCodeBlock, unsigned cbMax, unsigned *pSize)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync{
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync unsigned i = 0;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync char szOutput[256];
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync while (i < cbMax)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync {
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync unsigned cbInstr;
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync int rc = DISInstr(pCpu, pvCodeBlock + i, 0, &cbInstr, szOutput);
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync if (VBOX_FAILURE(rc))
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync return rc;
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync i += cbInstr;
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync }
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync if (pSize)
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync *pSize = i;
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync return true;
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync}
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync/**
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Disassembles one instruction
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync *
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @returns VBox error code
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pCpu Pointer to cpu structure which have DISCPUSTATE::mode
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * set correctly.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pu8Instruction Pointer to the strunction to disassemble.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param u32EipOffset Offset to add to instruction address to get the real virtual address
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pcbSize Where to store the size of the instruction.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * NULL is allowed.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pszOutput Storage for disassembled instruction
b9473064e26edc9a65150b4206ea1e52f3ca600avboxsync *
b9473064e26edc9a65150b4206ea1e52f3ca600avboxsync * @todo Define output callback.
b9473064e26edc9a65150b4206ea1e52f3ca600avboxsync */
b9473064e26edc9a65150b4206ea1e52f3ca600avboxsyncDISDECL(int) DISInstr(PDISCPUSTATE pCpu, RTUINTPTR pu8Instruction, unsigned u32EipOffset, unsigned *pcbSize,
b9473064e26edc9a65150b4206ea1e52f3ca600avboxsync char *pszOutput)
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync{
bf8889d6b20936475381d2ed2b80b06eaf2a03d1vboxsync return DISInstrEx(pCpu, pu8Instruction, u32EipOffset, pcbSize, pszOutput, OPTYPE_ALL);
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync}
bf8889d6b20936475381d2ed2b80b06eaf2a03d1vboxsync
bf8889d6b20936475381d2ed2b80b06eaf2a03d1vboxsync/**
bf8889d6b20936475381d2ed2b80b06eaf2a03d1vboxsync * Disassembles one instruction; only fully disassembly an instruction if it matches the filter criteria
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync *
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync * @returns VBox error code
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync * @param pCpu Pointer to cpu structure which have DISCPUSTATE::mode
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync * set correctly.
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync * @param pu8Instruction Pointer to the strunction to disassemble.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param u32EipOffset Offset to add to instruction address to get the real virtual address
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync * @param pcbSize Where to store the size of the instruction.
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync * NULL is allowed.
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync * @param pszOutput Storage for disassembled instruction
e94ff1af89bf631c68367d4e291ddbb491b5e5c0vboxsync * @param uFilter Instruction type filter
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync *
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync * @todo Define output callback.
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsyncDISDECL(int) DISInstrEx(PDISCPUSTATE pCpu, RTUINTPTR pu8Instruction, unsigned u32EipOffset, unsigned *pcbSize,
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync char *pszOutput, unsigned uFilter)
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync{
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync unsigned i = 0, prefixbytes;
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync unsigned idx, inc;
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync const OPCODE *paOneByteMap;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync#ifdef __L4ENV__
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync jmp_buf jumpbuffer;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync#endif
e94ff1af89bf631c68367d4e291ddbb491b5e5c0vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync //reset instruction settings
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync pCpu->prefix = PREFIX_NONE;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync pCpu->prefix_seg = 0;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync pCpu->ModRM.u = 0;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync pCpu->SIB.u = 0;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync pCpu->lastprefix = 0;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync pCpu->param1.parval = 0;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync pCpu->param2.parval = 0;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync pCpu->param3.parval = 0;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync pCpu->param1.szParam[0] = 0;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync pCpu->param2.szParam[0] = 0;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync pCpu->param3.szParam[0] = 0;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync pCpu->param1.size = 0;
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync pCpu->param2.size = 0;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync pCpu->param3.size = 0;
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync pCpu->param1.flags = 0;
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync pCpu->param2.flags = 0;
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync pCpu->param3.flags = 0;
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync pCpu->uFilter = uFilter;
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync pCpu->pfnDisasmFnTable = pfnFullDisasm;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync if (pszOutput)
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync *pszOutput = '\0';
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync if (pCpu->mode == CPUMODE_64BIT)
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync {
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync paOneByteMap = g_aOneByteMapX64;
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync pCpu->addrmode = CPUMODE_64BIT;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync pCpu->opmode = CPUMODE_32BIT;
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync }
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync else
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync {
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync paOneByteMap = g_aOneByteMapX86;
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync pCpu->addrmode = pCpu->mode;
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync pCpu->opmode = pCpu->mode;
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync }
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync prefixbytes = 0;
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync#ifndef __L4ENV__ /* Unfortunately, we have no exception handling in l4env */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync try
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync#else
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync pCpu->pJumpBuffer = &jumpbuffer;
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync if (setjmp(jumpbuffer) == 0)
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync#endif
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync {
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync while(1)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync {
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync uint8_t codebyte = DISReadByte(pCpu, pu8Instruction+i);
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync uint8_t opcode = paOneByteMap[codebyte].opcode;
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync /* Hardcoded assumption about OP_* values!! */
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync if (opcode <= OP_LAST_PREFIX)
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync {
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync /* The REX prefix must precede the opcode byte(s). Any other placement is ignored. */
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync if (opcode != OP_REX)
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync {
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync pCpu->lastprefix = opcode;
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync pCpu->prefix &= ~PREFIX_REX;
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync }
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync switch(opcode)
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync {
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync case OP_INVALID:
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync#if 0 //defined (DEBUG_Sander)
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync AssertMsgFailed(("Invalid opcode!!\n"));
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync#endif
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync return VERR_DIS_INVALID_OPCODE;
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync // segment override prefix byte
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync case OP_SEG:
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync pCpu->prefix_seg = paOneByteMap[codebyte].param1 - OP_PARM_REG_SEG_START;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync /* Segment prefixes for CS, DS, ES and SS are ignored in long mode. */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync if ( pCpu->mode != CPUMODE_64BIT
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync || pCpu->prefix_seg >= OP_PARM_REG_FS)
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync {
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync pCpu->prefix |= PREFIX_SEG;
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync }
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync i += sizeof(uint8_t);
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync prefixbytes++;
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync continue; //fetch the next byte
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync // lock prefix byte
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync case OP_LOCK:
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync pCpu->prefix |= PREFIX_LOCK;
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync i += sizeof(uint8_t);
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync prefixbytes++;
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync continue; //fetch the next byte
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync // address size override prefix byte
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync case OP_ADDRSIZE:
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync pCpu->prefix |= PREFIX_ADDRSIZE;
b9473064e26edc9a65150b4206ea1e52f3ca600avboxsync if (pCpu->mode == CPUMODE_16BIT)
b9473064e26edc9a65150b4206ea1e52f3ca600avboxsync pCpu->addrmode = CPUMODE_32BIT;
b9473064e26edc9a65150b4206ea1e52f3ca600avboxsync else
b9473064e26edc9a65150b4206ea1e52f3ca600avboxsync if (pCpu->mode == CPUMODE_32BIT)
b9473064e26edc9a65150b4206ea1e52f3ca600avboxsync pCpu->addrmode = CPUMODE_16BIT;
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync else
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync pCpu->addrmode = CPUMODE_32BIT; /* 64 bits */
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync i += sizeof(uint8_t);
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync prefixbytes++;
b9473064e26edc9a65150b4206ea1e52f3ca600avboxsync continue; //fetch the next byte
b9473064e26edc9a65150b4206ea1e52f3ca600avboxsync
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync // operand size override prefix byte
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync case OP_OPSIZE:
b9473064e26edc9a65150b4206ea1e52f3ca600avboxsync pCpu->prefix |= PREFIX_OPSIZE;
b9473064e26edc9a65150b4206ea1e52f3ca600avboxsync if (pCpu->mode == CPUMODE_16BIT)
b9473064e26edc9a65150b4206ea1e52f3ca600avboxsync pCpu->opmode = CPUMODE_32BIT;
b9473064e26edc9a65150b4206ea1e52f3ca600avboxsync else
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync pCpu->opmode = CPUMODE_16BIT; /* for 32 and 64 bits mode (there is no 32 bits operand size override prefix) */
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync i += sizeof(uint8_t);
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync prefixbytes++;
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync continue; //fetch the next byte
b9473064e26edc9a65150b4206ea1e52f3ca600avboxsync
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync // rep and repne are not really prefixes, but we'll treat them as such
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync case OP_REPE:
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync pCpu->prefix |= PREFIX_REP;
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync i += sizeof(uint8_t);
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync prefixbytes += sizeof(uint8_t);
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync continue; //fetch the next byte
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync case OP_REPNE:
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync pCpu->prefix |= PREFIX_REPNE;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync i += sizeof(uint8_t);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync prefixbytes += sizeof(uint8_t);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync continue; //fetch the next byte
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync case OP_REX:
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync Assert(pCpu->mode == CPUMODE_64BIT);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync /* REX prefix byte */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync pCpu->prefix |= PREFIX_REX;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync pCpu->prefix_rex = PREFIX_REX_OP_2_FLAGS(paOneByteMap[codebyte].param1);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync i += sizeof(uint8_t);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync prefixbytes += sizeof(uint8_t);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync if (pCpu->prefix_rex & PREFIX_REX_FLAGS_W)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync pCpu->opmode = CPUMODE_64BIT; /* overrides size prefix byte */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync continue; //fetch the next byte
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync }
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync }
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync idx = i;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync i += sizeof(uint8_t); //first opcode byte
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync pCpu->opcode = codebyte;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync /* Prefix byte(s) is/are part of the instruction. */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync pCpu->opaddr = pu8Instruction + idx + u32EipOffset - prefixbytes;
2b114c590cf5a19f8047cd7bde9c7e5ae00aa22bvboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync inc = ParseInstruction(pu8Instruction + i, &paOneByteMap[pCpu->opcode], pCpu);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync pCpu->opsize = prefixbytes + inc + sizeof(uint8_t);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync if(pszOutput) {
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync disasmSprintf(pszOutput, pu8Instruction+i-1-prefixbytes, pCpu, &pCpu->param1, &pCpu->param2, &pCpu->param3);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync }
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync i += inc;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync prefixbytes = 0;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync break;
2b114c590cf5a19f8047cd7bde9c7e5ae00aa22bvboxsync }
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync }
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync#ifndef __L4ENV__
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync catch(...)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync#else
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync else /* setjmp has returned a non-zero value: an exception occured */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync#endif
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync {
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync if (pcbSize)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync *pcbSize = 0;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync return VERR_DIS_GEN_FAILURE;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync }
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync if (pcbSize)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync *pcbSize = i;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync return VINF_SUCCESS;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync}
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync//*****************************************************************************
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync//*****************************************************************************
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsyncchar *DbgBytesToString(PDISCPUSTATE pCpu, RTUINTPTR pBytes, int size, char *pszOutput)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync{
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync char szByte[4];
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync int len = strlen(pszOutput);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync int i;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync for(i = len; i < 40; i++)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync {
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync strcat(pszOutput, " ");
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync }
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync strcat(pszOutput, " [");
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync for(i = 0; i < size; i++)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync {
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync RTStrPrintf(szByte, sizeof(szByte), "%02X ", DISReadByte(pCpu, pBytes+i));
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync RTStrPrintf(&pszOutput[strlen(pszOutput)], 64, szByte);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync }
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync len = strlen(pszOutput);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync pszOutput[len - 1] = 0; //cut off last space
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync strcat(pszOutput, "]");
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync return pszOutput;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync}
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync//*****************************************************************************
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync//*****************************************************************************
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsyncvoid disasmSprintf(char *pszOutput, RTUINTPTR pu8Instruction, PDISCPUSTATE pCpu, OP_PARAMETER *pParam1, OP_PARAMETER *pParam2, OP_PARAMETER *pParam3)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync{
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync const char *lpszFormat = pCpu->pszOpcode;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync int param = 1;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync RTStrPrintf(pszOutput, 64, "%08X: ", (unsigned)pCpu->opaddr);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync if(pCpu->prefix & PREFIX_LOCK)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync {
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync RTStrPrintf(&pszOutput[strlen(pszOutput)], 64, "lock ");
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync }
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync if(pCpu->prefix & PREFIX_REP)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync {
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync RTStrPrintf(&pszOutput[strlen(pszOutput)], 64, "rep(e) ");
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync }
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync else
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync if(pCpu->prefix & PREFIX_REPNE)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync {
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync RTStrPrintf(&pszOutput[strlen(pszOutput)], 64, "repne ");
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync }
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync if(!strcmp("Invalid Opcode", lpszFormat))
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync {
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync RTStrPrintf(&pszOutput[strlen(pszOutput)], 64, "Invalid Opcode [%02X][%02X]", DISReadByte(pCpu, pu8Instruction), DISReadByte(pCpu, pu8Instruction+1) );
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync }
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync else
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync while(*lpszFormat)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync {
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync switch(*lpszFormat)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync {
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync case '%':
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync switch(*(lpszFormat+1))
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync {
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync case 'J': //Relative jump offset
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync {
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync int32_t disp;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync AssertMsg(param == 1, ("Invalid branch parameter nr"));
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync if(pParam1->flags & USE_IMMEDIATE8_REL)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync {
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync disp = (int32_t)(char)pParam1->parval;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync }
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync else
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync if(pParam1->flags & USE_IMMEDIATE16_REL)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync {
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync disp = (int32_t)(uint16_t)pParam1->parval;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync }
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync else
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync if(pParam1->flags & USE_IMMEDIATE32_REL)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync {
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync disp = (int32_t)pParam1->parval;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync }
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync else
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync {
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync AssertMsgFailed(("Oops!\n"));
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync return;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync }
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync uint32_t addr = (uint32_t)(pCpu->opaddr + pCpu->opsize) + disp;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync RTStrPrintf(&pszOutput[strlen(pszOutput)], 64, "[%08X]", addr);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync }
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync //no break;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync case 'A': //direct address
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync case 'C': //control register
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync case 'D': //debug register
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync case 'E': //ModRM specifies parameter
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync case 'F': //Eflags register
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync case 'G': //ModRM selects general register
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync case 'I': //Immediate data
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync case 'M': //ModRM may only refer to memory
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync case 'O': //No ModRM byte
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync case 'P': //ModRM byte selects MMX register
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync case 'Q': //ModRM byte selects MMX register or memory address
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync case 'R': //ModRM byte may only refer to a general register
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync case 'S': //ModRM byte selects a segment register
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync case 'T': //ModRM byte selects a test register
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync case 'V': //ModRM byte selects an XMM/SSE register
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync case 'W': //ModRM byte selects an XMM/SSE register or a memory address
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync case 'X': //DS:SI
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync case 'Y': //ES:DI
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync switch(param)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync {
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync case 1:
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync RTStrPrintf(&pszOutput[strlen(pszOutput)], 64, pParam1->szParam);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync break;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync case 2:
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync RTStrPrintf(&pszOutput[strlen(pszOutput)], 64, pParam2->szParam);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync break;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync case 3:
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync RTStrPrintf(&pszOutput[strlen(pszOutput)], 64, pParam3->szParam);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync break;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync }
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync break;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync case 'e': //register based on operand size (e.g. %eAX)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync if(pCpu->opmode == CPUMODE_32BIT)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync RTStrPrintf(&pszOutput[strlen(pszOutput)], 64, "E");
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync if(pCpu->opmode == CPUMODE_64BIT)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync RTStrPrintf(&pszOutput[strlen(pszOutput)], 64, "R");
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync RTStrPrintf(&pszOutput[strlen(pszOutput)], 64, "%c%c", lpszFormat[2], lpszFormat[3]);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync break;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync default:
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync AssertMsgFailed(("Oops!\n"));
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync break;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync }
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync //Go to the next parameter in the format string
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync while(*lpszFormat && *lpszFormat != ',') lpszFormat++;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync if(*lpszFormat == ',') lpszFormat--;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync break;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync case ',':
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync param++;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync //no break
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync default:
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync RTStrPrintf(&pszOutput[strlen(pszOutput)], 64, "%c", *lpszFormat);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync break;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync }
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync if(*lpszFormat) lpszFormat++;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync }
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync DbgBytesToString(pCpu, pu8Instruction, pCpu->opsize, pszOutput);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync RTStrPrintf(&pszOutput[strlen(pszOutput)], 64, "\n");
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync}
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync//*****************************************************************************
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync//*****************************************************************************
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync