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