VirtualBox

Changeset 41658 in vbox


Ignore:
Timestamp:
Jun 11, 2012 10:21:44 PM (13 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
78464
Message:

DIS,VMM,REM,IPRT: Disassembler API adjustments.

Location:
trunk
Files:
31 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/dis.h

    r41501 r41658  
    44
    55/*
    6  * Copyright (C) 2006-2007 Oracle Corporation
     6 * Copyright (C) 2006-2012 Oracle Corporation
    77 *
    88 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    370370typedef struct OP_PARAMETER
    371371{
    372     /** @todo switch param and parval and move disp64 and flags up here with the other 64-bit vars to get more natural alignment and save space. */
    373     int             param;
    374372    uint64_t        parval;
    375 #ifndef DIS_SEPARATE_FORMATTER
    376     char            szParam[32];
    377 #endif
    378 
    379     int32_t         disp8, disp16, disp32;
     373    uint64_t        flags;
     374    int64_t         disp64;
     375    int32_t         disp32;
     376    int32_t         disp16;
     377    int32_t         disp8;
    380378    uint32_t        size;
    381 
    382     int64_t         disp64;
    383     uint64_t        flags;
     379    int32_t         param;
    384380
    385381    union
     
    409405    uint32_t scale;
    410406
     407#ifndef DIS_SEPARATE_FORMATTER
     408    char            szParam[32];
     409#endif
    411410} OP_PARAMETER;
    412411/** Pointer to opcode parameter. */
     
    421420typedef const struct OPCODE *PCOPCODE;
    422421
    423 typedef DECLCALLBACK(int) FN_DIS_READBYTES(RTUINTPTR pSrc, uint8_t *pDest, unsigned size, void *pvUserdata);
    424 typedef FN_DIS_READBYTES *PFN_DIS_READBYTES;
     422/**
     423 * Callback for reading opcode bytes.
     424 *
     425 * @param   pDisState       Pointer to the CPU state.  The primary user argument
     426 *                          can be retrived from DISCPUSTATE::apvUserData[0]. If
     427 *                          more is required these can be passed in the
     428 *                          subsequent slots.
     429 * @param   pbDst           Pointer to output buffer.
     430 * @param   uSrcAddr        The address to start reading at.
     431 * @param   cbToRead        The number of bytes to read.
     432 */
     433typedef DECLCALLBACK(int) FNDISREADBYTES(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead);
     434/** Pointer to a opcode byte reader. */
     435typedef FNDISREADBYTES *PFNDISREADBYTES;
    425436
    426437/** Parser callback.
     
    431442typedef struct DISCPUSTATE
    432443{
    433     /* Global setting */
     444    /** Global setting. */
    434445    DISCPUMODE      mode;
    435446
    436     /* Per instruction prefix settings */
     447    /** Per instruction prefix settings. */
    437448    uint32_t        prefix;
    438449    /** segment prefix value. */
     
    452463    union
    453464    {
    454         /* Bitfield view */
     465        /** Bitfield view */
    455466        struct
    456467        {
     
    459470            unsigned        Mod : 2;
    460471        } Bits;
    461         /* unsigned view */
     472        /** unsigned view */
    462473        unsigned            u;
    463474    } ModRM;
     
    466477    union
    467478    {
    468         /* Bitfield view */
     479        /** Bitfield view */
    469480        struct
    470481        {
     
    473484            unsigned        Scale : 2;
    474485        } Bits;
    475         /* unsigned view */
     486        /** unsigned view */
    476487        unsigned            u;
    477488    } SIB;
    478 
    479     int32_t         disp;
     489    int32_t         i32SibDisp;
     490
     491    /** The instruction size. */
     492    uint32_t        opsize;
     493    /** The address of the instruction. */
     494    RTUINTPTR       uInstrAddr;
     495    /** The offsetted address of the instruction. */
     496    RTUINTPTR       opaddr;
     497    /** The size of the prefix bytes. */
     498    uint8_t         cbPrefix;
    480499
    481500    /** First opcode byte of instruction. */
    482501    uint8_t         opcode;
    483     /** Last prefix byte (for SSE2 extension tables) */
     502    /** Last prefix byte (for SSE2 extension tables). */
    484503    uint8_t         lastprefix;
    485     RTUINTPTR       opaddr;
    486     uint32_t        opsize;
     504    /** The instruction bytes. */
     505    uint8_t         abInstr[16];
     506
     507    /** Internal: pointer to disassembly function table */
     508    PFNDISPARSE    *pfnDisasmFnTable;
     509    /** Internal: instruction filter */
     510    uint32_t        uFilter;
     511    /** Return code set by a worker function like the opcode bytes readers. */
     512    int32_t         rc;
     513
     514    /** Pointer to the current instruction. */
     515    PCOPCODE        pCurInstr;
    487516#ifndef DIS_CORE_ONLY
    488517    /** Opcode format string for current instruction. */
     
    490519#endif
    491520
    492     /** Internal: pointer to disassembly function table */
    493     PFNDISPARSE    *pfnDisasmFnTable;
    494     /** Internal: instruction filter */
    495     uint32_t        uFilter;
    496 
    497     /** Pointer to the current instruction. */
    498     PCOPCODE        pCurInstr;
    499 
     521    /** Optional read function */
     522    PFNDISREADBYTES pfnReadBytes;
     523    /** User data slots for the read callback.  The first entry is used for the
     524     *  pvUser argument, the rest are up for grabs.
     525     * @remarks This must come last so that we can memset everything before this. */
    500526    void           *apvUserData[3];
    501 
    502     /** Optional read function */
    503     PFN_DIS_READBYTES pfnReadBytes;
    504 #ifdef __L4ENV__
    505     jmp_buf *pJumpBuffer;
    506 #endif /* __L4ENV__ */
    507527} DISCPUSTATE;
    508528
     
    531551
    532552
    533 /**
    534  * Disassembles a code block.
    535  *
    536  * @returns VBox error code
    537  * @param   pCpu            Pointer to cpu structure which have DISCPUSTATE::mode
    538  *                          set correctly.
    539  * @param   pvCodeBlock     Pointer to the structure to disassemble.
    540  * @param   cbMax           Maximum number of bytes to disassemble.
    541  * @param   pcbSize         Where to store the size of the instruction.
    542  *                          NULL is allowed.
    543  *
    544  *
    545  * @todo    Define output callback.
    546  * @todo    Using signed integers as sizes is a bit odd. There are still
    547  *          some GCC warnings about mixing signed and unsigned integers.
    548  * @todo    Need to extend this interface to include a code address so we
    549  *          can disassemble GC code. Perhaps a new function is better...
    550  * @remark  cbMax isn't respected as a boundary. DISInstr() will read beyond cbMax.
    551  *          This means *pcbSize >= cbMax sometimes.
    552  */
    553 DISDECL(int) DISBlock(PDISCPUSTATE pCpu, RTUINTPTR pvCodeBlock, unsigned cbMax, unsigned *pSize);
    554 
    555 /**
    556  * Disassembles one instruction
    557  *
    558  * @returns VBox error code
    559  * @param   pCpu            Pointer to cpu structure which have DISCPUSTATE::mode
    560  *                          set correctly.
    561  * @param   pu8Instruction  Pointer to the instrunction to disassemble.
    562  * @param   u32EipOffset    Offset to add to instruction address to get the real virtual address
    563  * @param   pcbSize         Where to store the size of the instruction.
    564  *                          NULL is allowed.
    565  * @param   pszOutput       Storage for disassembled instruction
    566  *
    567  * @todo    Define output callback.
    568  */
    569 DISDECL(int) DISInstr(PDISCPUSTATE pCpu, RTUINTPTR pu8Instruction, unsigned u32EipOffset, unsigned *pcbSize, char *pszOutput);
    570 
    571 /**
    572  * Disassembles one instruction
    573  *
    574  * @returns VBox error code
    575  * @param   pCpu            Pointer to cpu structure which have DISCPUSTATE::mode
    576  *                          set correctly.
    577  * @param   pu8Instruction  Pointer to the structure to disassemble.
    578  * @param   u32EipOffset    Offset to add to instruction address to get the real virtual address
    579  * @param   pcbSize         Where to store the size of the instruction.
    580  *                          NULL is allowed.
    581  * @param   pszOutput       Storage for disassembled instruction
    582  * @param   uFilter         Instruction type filter
    583  *
    584  * @todo    Define output callback.
    585  */
    586 DISDECL(int) DISInstrEx(PDISCPUSTATE pCpu, RTUINTPTR pu8Instruction, uint32_t u32EipOffset, uint32_t *pcbSize,
    587                          char *pszOutput, unsigned uFilter);
    588 
    589 /**
    590  * Parses one instruction.
    591  * The result is found in pCpu.
    592  *
    593  * @returns VBox error code
    594  * @param   pCpu            Pointer to cpu structure which has DISCPUSTATE::mode set correctly.
    595  * @param   InstructionAddr Pointer to the instruction to parse.
    596  * @param   pcbInstruction  Where to store the size of the instruction.
    597  *                          NULL is allowed.
    598  */
    599 DISDECL(int) DISCoreOne(PDISCPUSTATE pCpu, RTUINTPTR InstructionAddr, unsigned *pcbInstruction);
    600 
    601 /**
    602  * Parses one guest instruction.
    603  * The result is found in pCpu and pcbInstruction.
    604  *
    605  * @returns VBox status code.
    606  * @param   InstructionAddr Address of the instruction to decode. What this means
    607  *                          is left to the pfnReadBytes function.
    608  * @param   enmCpuMode      The CPU mode. CPUMODE_32BIT, CPUMODE_16BIT, or CPUMODE_64BIT.
    609  * @param   pfnReadBytes    Callback for reading instruction bytes.
    610  * @param   pvUser          User argument for the instruction reader. (Ends up in apvUserData[0].)
    611  * @param   pCpu            Pointer to cpu structure. Will be initialized.
    612  * @param   pcbInstruction  Where to store the size of the instruction.
    613  *                          NULL is allowed.
    614  */
    615 DISDECL(int) DISCoreOneEx(RTUINTPTR InstructionAddr, DISCPUMODE enmCpuMode, PFN_DIS_READBYTES pfnReadBytes, void *pvUser,
    616                           PDISCPUSTATE pCpu, unsigned *pcbInstruction);
     553DISDECL(int) DISInstr(RTUINTPTR uInstrAddr, DISCPUMODE enmCpuMode, PDISCPUSTATE pCpu, uint32_t *pcbSize, char *pszOutput);
     554DISDECL(int) DISInstrWithOff(PDISCPUSTATE pCpu, RTUINTPTR uInstrAddr, RTUINTPTR offRealAddr, uint32_t *pcbSize, char *pszOutput);
     555DISDECL(int) DISInstrWithReader(RTUINTPTR uInstrAddr, DISCPUMODE enmCpuMode, PFNDISREADBYTES pfnReadBytes, void *pvUser,
     556                                PDISCPUSTATE pCpu, uint32_t *pcbSize, char *pszOutput);
     557DISDECL(int) DISInstrEx(RTUINTPTR uInstrAddr, RTUINTPTR offRealAddr, DISCPUMODE enmCpuMode,
     558                        PFNDISREADBYTES pfnReadBytes, void *pvUser, uint32_t uFilter,
     559                        PDISCPUSTATE pCpu, uint32_t *pcbSize, char *pszOutput);
     560
     561DISDECL(int) DISCoreOne(PDISCPUSTATE pCpu, RTUINTPTR InstructionAddr, uint32_t *pcbInstruction);
     562DISDECL(int) DISCoreOneEx(RTUINTPTR InstructionAddr, DISCPUMODE enmCpuMode, PFNDISREADBYTES pfnReadBytes, void *pvUser,
     563                          PDISCPUSTATE pCpu, uint32_t *pcbInstruction);
    617564
    618565DISDECL(int)        DISGetParamSize(PDISCPUSTATE pCpu, POP_PARAMETER pParam);
     
    620567DISDECL(uint8_t)    DISQuerySegPrefixByte(PDISCPUSTATE pCpu);
    621568
    622 /**
    623  * Returns the value of the parameter in pParam
    624  *
    625  * @returns VBox error code
    626  * @param   pCtx            Exception structure pointer
    627  * @param   pCpu            Pointer to cpu structure which have DISCPUSTATE::mode
    628  *                          set correctly.
    629  * @param   pParam          Pointer to the parameter to parse
    630  * @param   pParamVal       Pointer to parameter value (OUT)
    631  * @param   parmtype        Parameter type
    632  *
    633  * @note    Currently doesn't handle FPU/XMM/MMX/3DNow! parameters correctly!!
    634  *
    635  */
    636569DISDECL(int) DISQueryParamVal(PCPUMCTXCORE pCtx, PDISCPUSTATE pCpu, POP_PARAMETER pParam, POP_PARAMVAL pParamVal, PARAM_TYPE parmtype);
    637570DISDECL(int) DISQueryParamRegPtr(PCPUMCTXCORE pCtx, PDISCPUSTATE pCpu, POP_PARAMETER pParam, void **ppReg, size_t *pcbSize);
  • trunk/include/VBox/err.h

    r41573 r41658  
    19321932/** Generic failure during disassembly. */
    19331933#define VERR_DIS_GEN_FAILURE                        (-4201)
     1934/** No read callback. */
     1935#define VERR_DIS_NO_READ_CALLBACK                   (-4202)
     1936/** Invalid Mod/RM. */
     1937#define VERR_DIS_INVALID_MODRM                      (-4203)
     1938/** Invalid parameter index. */
     1939#define VERR_DIS_INVALID_PARAMETER                  (-4204)
     1940/** Reading opcode bytes failed. */
     1941#define VERR_DIS_MEM_READ                           (-4205)
    19341942/** @} */
    19351943
  • trunk/include/VBox/vmm/iem.h

    r40453 r41658  
    4141VMMDECL(VBOXSTRICTRC)       IEMExecOne(PVMCPU pVCpu);
    4242VMMDECL(VBOXSTRICTRC)       IEMExecOneEx(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, uint32_t *pcbWritten);
     43VMMDECL(VBOXSTRICTRC)       IEMExecOneWithOpcodes(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore,
     44                                                  RTGCPTR GCPtrOpcodeBytes, const void *pvOpcodeBytes, size_t cbOpcodeBytes);
    4345VMMDECL(VBOXSTRICTRC)       IEMExecLots(PVMCPU pVCpu);
    4446VMM_INT_DECL(VBOXSTRICTRC)  IEMInjectTrap(PVMCPU pVCpu, uint8_t u8TrapNo, TRPMEVENT enmType, uint16_t uErrCode, RTGCPTR uCr2);
  • trunk/include/VBox/vmm/patm.h

    r40453 r41658  
    238238 * @param   pCtxCore    The relevant core context.
    239239 */
    240 VMMDECL(int) PATMHandleInt3PatchTrap(PVM pVM, PCPUMCTXCORE pRegFrame);
     240VMMRCDECL(int) PATMRCHandleInt3PatchTrap(PVM pVM, PCPUMCTXCORE pRegFrame);
    241241
    242242/**
  • trunk/src/VBox/Devices/PC/BIOS-new/MakeDebianBiosAssembly.cpp

    r41609 r41658  
    904904
    905905/**
    906  * Disassembler callback for reading opcode bytes.
    907  *
    908  * @returns VINF_SUCCESS.
    909  * @param   uFlatAddr           The address to read at.
    910  * @param   pbDst               Where to store them.
    911  * @param   cbToRead            How many to read.
    912  * @param   pvUser              Unused.
    913  */
    914 static DECLCALLBACK(int) disReadOpcodeBytes(RTUINTPTR uFlatAddr, uint8_t *pbDst, unsigned cbToRead, void *pvUser)
    915 {
    916     if (uFlatAddr + cbToRead >= VBOX_BIOS_BASE + _64K)
     906 * @callback_method_impl{FNDISREADBYTES}
     907 *
     908 * @remarks @a uSrcAddr is the flat address.
     909 */
     910static DECLCALLBACK(int) disReadOpcodeBytes(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead)
     911{
     912    if (uSrcAddr + cbToRead >= VBOX_BIOS_BASE + _64K)
    917913    {
    918914        RT_BZERO(pbDst, cbToRead);
    919         if (uFlatAddr >= VBOX_BIOS_BASE + _64K)
     915        if (uSrcAddr >= VBOX_BIOS_BASE + _64K)
    920916            cbToRead = 0;
    921917        else
    922             cbToRead = VBOX_BIOS_BASE + _64K - uFlatAddr;
    923     }
    924     memcpy(pbDst, &g_pbImg[uFlatAddr - VBOX_BIOS_BASE], cbToRead);
    925     NOREF(pvUser);
     918            cbToRead = VBOX_BIOS_BASE + _64K - uSrcAddr;
     919    }
     920    memcpy(pbDst, &g_pbImg[uSrcAddr - VBOX_BIOS_BASE], cbToRead);
     921    NOREF(pDisState);
    926922    return VINF_SUCCESS;
    927923}
  • trunk/src/VBox/Disassembler/Disasm.cpp

    r33540 r41658  
    3434
    3535/**
    36  * Disassembles a code block.
     36 * Disassembles one instruction
    3737 *
    3838 * @returns VBox error code
    3939 * @param   pCpu            Pointer to cpu structure which have DISCPUSTATE::mode
    4040 *                          set correctly.
    41  * @param   pvCodeBlock     Pointer to the structure to disassemble.
    42  * @param   cbMax           Maximum number of bytes to disassemble.
     41 * @param   uInstrAddr      Pointer to the structure to disassemble.
    4342 * @param   pcbSize         Where to store the size of the instruction.
    4443 *                          NULL is allowed.
    45  *
     44 * @param   pszOutput       Storage for disassembled instruction
    4645 *
    4746 * @todo    Define output callback.
    48  * @todo    Using signed integers as sizes is a bit odd. There are still
    49  *          some GCC warnings about mixing signed and unsigned integers.
    50  * @todo    Need to extend this interface to include a code address so we
    51  *          can disassemble GC code. Perhaps a new function is better...
    52  * @remark  cbMax isn't respected as a boundary. DISInstr() will read beyond cbMax.
    53  *          This means *pcbSize >= cbMax sometimes.
    54  */
    55 DISDECL(int) DISBlock(PDISCPUSTATE pCpu, RTUINTPTR pvCodeBlock, unsigned cbMax, unsigned *pSize)
    56 {
    57     unsigned i = 0;
    58     char szOutput[256];
    59 
    60     while (i < cbMax)
    61     {
    62         unsigned cbInstr;
    63         int rc = DISInstr(pCpu, pvCodeBlock + i, 0, &cbInstr, szOutput);
    64         if (RT_FAILURE(rc))
    65             return rc;
    66 
    67         i += cbInstr;
    68     }
    69 
    70     if (pSize)
    71         *pSize = i;
    72     return true;
     47 */
     48DISDECL(int) DISInstr(RTUINTPTR uInstrAddr, DISCPUMODE enmCpuMode, PDISCPUSTATE pCpu, uint32_t *pcbSize, char *pszOutput)
     49{
     50    return DISInstrEx(uInstrAddr, 0, enmCpuMode, NULL, NULL, OPTYPE_ALL,
     51                      pCpu, pcbSize, pszOutput);
    7352}
    7453
     
    7958 * @param   pCpu            Pointer to cpu structure which have DISCPUSTATE::mode
    8059 *                          set correctly.
    81  * @param   pu8Instruction  Pointer to the structure to disassemble.
    82  * @param   u32EipOffset    Offset to add to instruction address to get the real virtual address
     60 * @param   uInstrAddr      Pointer to the structure to disassemble.
     61 * @param   offRealAddr     Offset to add to instruction address to get the real
     62 *                          virtual address.
    8363 * @param   pcbSize         Where to store the size of the instruction.
    8464 *                          NULL is allowed.
     
    8767 * @todo    Define output callback.
    8868 */
    89 DISDECL(int) DISInstr(PDISCPUSTATE pCpu, RTUINTPTR pu8Instruction, unsigned u32EipOffset, unsigned *pcbSize,
    90                       char *pszOutput)
    91 {
    92     return DISInstrEx(pCpu, pu8Instruction, u32EipOffset, pcbSize, pszOutput, OPTYPE_ALL);
     69DISDECL(int) DISInstrWithOff(PDISCPUSTATE pCpu, RTUINTPTR uInstrAddr, RTUINTPTR offRealAddr,
     70                             unsigned *pcbSize, char *pszOutput)
     71{
     72    return DISInstrEx(uInstrAddr, offRealAddr, pCpu->mode, pCpu->pfnReadBytes, pCpu->apvUserData[0], OPTYPE_ALL,
     73                      pCpu, pcbSize, pszOutput);
     74}
     75
     76/**
     77 * Disassembles one instruction with a byte fetcher caller.
     78 *
     79 * @returns VBox error code
     80 * @param   uInstrAddr      Pointer to the structure to disassemble.
     81 * @param   enmCpuMode      The CPU mode.
     82 * @param   pfnCallback     The byte fetcher callback.
     83 * @param   pvUser          The user argument (found in
     84 *                          DISCPUSTATE::apvUserData[0]).
     85 * @param   pCpu            Where to return the disassembled instruction.
     86 * @param   pcbSize         Where to store the size of the instruction.
     87 *                          NULL is allowed.
     88 * @param   pszOutput       Storage for disassembled instruction
     89 *
     90 * @todo    Define output callback.
     91 */
     92DISDECL(int) DISInstrWithReader(RTUINTPTR uInstrAddr, DISCPUMODE enmCpuMode, PFNDISREADBYTES pfnReadBytes, void *pvUser,
     93                                PDISCPUSTATE pCpu, uint32_t *pcbSize, char *pszOutput)
     94
     95{
     96    return DISInstrEx(uInstrAddr, 0, enmCpuMode, pfnReadBytes, pvUser, OPTYPE_ALL,
     97                      pCpu, pcbSize, pszOutput);
    9398}
    9499
     
    99104 * @param   pCpu            Pointer to cpu structure which have DISCPUSTATE::mode
    100105 *                          set correctly.
    101  * @param   pu8Instruction  Pointer to the structure to disassemble.
     106 * @param   uInstrAddr      Pointer to the structure to disassemble.
    102107 * @param   u32EipOffset    Offset to add to instruction address to get the real virtual address
    103108 * @param   pcbSize         Where to store the size of the instruction.
     
    108113 * @todo    Define output callback.
    109114 */
    110 DISDECL(int) DISInstrEx(PDISCPUSTATE pCpu, RTUINTPTR pu8Instruction, unsigned u32EipOffset, unsigned *pcbSize,
    111                         char *pszOutput, unsigned uFilter)
    112 {
    113     unsigned i = 0, prefixbytes;
    114     unsigned idx, inc;
    115     const OPCODE *paOneByteMap;
    116 #ifdef __L4ENV__
    117     jmp_buf jumpbuffer;
    118 #endif
    119 
    120     //reset instruction settings
    121     pCpu->prefix        = PREFIX_NONE;
    122     pCpu->enmPrefixSeg  = DIS_SELREG_DS;
    123     pCpu->ModRM.u       = 0;
    124     pCpu->SIB.u         = 0;
    125     pCpu->lastprefix    = 0;
    126     pCpu->param1.parval = 0;
    127     pCpu->param2.parval = 0;
    128     pCpu->param3.parval = 0;
    129     pCpu->param1.szParam[0] = 0;
    130     pCpu->param2.szParam[0] = 0;
    131     pCpu->param3.szParam[0] = 0;
    132     pCpu->param1.size   = 0;
    133     pCpu->param2.size   = 0;
    134     pCpu->param3.size   = 0;
    135     pCpu->param1.flags  = 0;
    136     pCpu->param2.flags  = 0;
    137     pCpu->param3.flags  = 0;
    138     pCpu->uFilter       = uFilter;
    139     pCpu->pfnDisasmFnTable = pfnFullDisasm;
    140 
    141     if (pszOutput)
    142         *pszOutput = '\0';
    143 
    144     if (pCpu->mode == CPUMODE_64BIT)
     115DISDECL(int) DISInstrEx(RTUINTPTR uInstrAddr, RTUINTPTR offRealAddr, DISCPUMODE enmCpuMode,
     116                        PFNDISREADBYTES pfnReadBytes, void *pvUser, uint32_t uFilter,
     117                        PDISCPUSTATE pCpu, uint32_t *pcbSize, char *pszOutput)
     118{
     119    const OPCODE   *paOneByteMap;
     120
     121    /*
     122     * Initialize the CPU state.
     123     * Note! The RT_BZERO make ASSUMPTIONS about the placement of apvUserData.
     124     */
     125    RT_BZERO(pCpu, RT_OFFSETOF(DISCPUSTATE, apvUserData));
     126
     127    pCpu->mode              = enmCpuMode;
     128    if (enmCpuMode == CPUMODE_64BIT)
    145129    {
    146         paOneByteMap     = g_aOneByteMapX64;
    147         pCpu->addrmode   = CPUMODE_64BIT;
    148         pCpu->opmode     = CPUMODE_32BIT;
     130        paOneByteMap        = g_aOneByteMapX64;
     131        pCpu->addrmode      = CPUMODE_64BIT;
     132        pCpu->opmode        = CPUMODE_32BIT;
    149133    }
    150134    else
    151135    {
    152         paOneByteMap     = g_aOneByteMapX86;
    153         pCpu->addrmode   = pCpu->mode;
    154         pCpu->opmode     = pCpu->mode;
     136        paOneByteMap        = g_aOneByteMapX86;
     137        pCpu->addrmode      = enmCpuMode;
     138        pCpu->opmode        = enmCpuMode;
    155139    }
    156 
    157     prefixbytes = 0;
    158 #ifndef __L4ENV__  /* Unfortunately, we have no exception handling in l4env */
    159     try
    160 #else
    161     pCpu->pJumpBuffer = &jumpbuffer;
    162     if (setjmp(jumpbuffer) == 0)
    163 #endif
     140    pCpu->prefix            = PREFIX_NONE;
     141    pCpu->enmPrefixSeg      = DIS_SELREG_DS;
     142    pCpu->uInstrAddr        = uInstrAddr;
     143    pCpu->opaddr            = uInstrAddr + offRealAddr;
     144    pCpu->pfnDisasmFnTable  = pfnFullDisasm;
     145    pCpu->uFilter           = uFilter;
     146    pCpu->rc                = VINF_SUCCESS;
     147    pCpu->pfnReadBytes      = pfnReadBytes ? pfnReadBytes : disReadBytesDefault;
     148    pCpu->apvUserData[0]    = pvUser;
     149
     150    /*
     151     * Parse the instruction byte by byte.
     152     */
     153    unsigned i        = 0;
     154    unsigned cbPrefix = 0; /** @todo this isn't really needed, is it? Seems to be a bit too many variables tracking the same stuff here. cbInc, i, cbPrefix, idx... */
     155    for (;;)
    164156    {
    165         while(1)
     157        uint8_t codebyte = DISReadByte(pCpu, uInstrAddr+i);
     158        uint8_t opcode   = paOneByteMap[codebyte].opcode;
     159
     160        /* Hardcoded assumption about OP_* values!! */
     161        if (opcode <= OP_LAST_PREFIX)
    166162        {
    167             uint8_t codebyte = DISReadByte(pCpu, pu8Instruction+i);
    168             uint8_t opcode   = paOneByteMap[codebyte].opcode;
    169 
    170             /* Hardcoded assumption about OP_* values!! */
    171             if (opcode <= OP_LAST_PREFIX)
     163            /* The REX prefix must precede the opcode byte(s). Any other placement is ignored. */
     164            if (opcode != OP_REX)
    172165            {
    173                 /* The REX prefix must precede the opcode byte(s). Any other placement is ignored. */
    174                 if (opcode != OP_REX)
    175                 {
    176                     pCpu->lastprefix = opcode;
    177                     pCpu->prefix &= ~PREFIX_REX;
    178                 }
    179 
    180                 switch(opcode)
    181                 {
    182                 case OP_INVALID:
    183 #if 0 //defined (DEBUG_Sander)
    184                     AssertMsgFailed(("Invalid opcode!!\n"));
    185 #endif
    186                     return VERR_DIS_INVALID_OPCODE;
    187 
    188                 // segment override prefix byte
    189                 case OP_SEG:
    190                     pCpu->enmPrefixSeg = (DIS_SELREG)(paOneByteMap[codebyte].param1 - OP_PARM_REG_SEG_START);
    191                     /* Segment prefixes for CS, DS, ES and SS are ignored in long mode. */
    192                     if (   pCpu->mode != CPUMODE_64BIT
    193                         || pCpu->enmPrefixSeg >= DIS_SELREG_FS)
    194                     {
    195                         pCpu->prefix    |= PREFIX_SEG;
    196                     }
    197                     i += sizeof(uint8_t);
    198                     prefixbytes++;
    199                     continue;   //fetch the next byte
    200 
    201                 // lock prefix byte
    202                 case OP_LOCK:
    203                     pCpu->prefix |= PREFIX_LOCK;
    204                     i += sizeof(uint8_t);
    205                     prefixbytes++;
    206                     continue;   //fetch the next byte
    207 
    208                 // address size override prefix byte
    209                 case OP_ADDRSIZE:
    210                     pCpu->prefix |= PREFIX_ADDRSIZE;
    211                     if (pCpu->mode == CPUMODE_16BIT)
    212                         pCpu->addrmode = CPUMODE_32BIT;
    213                     else
    214                     if (pCpu->mode == CPUMODE_32BIT)
    215                         pCpu->addrmode = CPUMODE_16BIT;
    216                     else
    217                         pCpu->addrmode = CPUMODE_32BIT;     /* 64 bits */
    218 
    219                     i += sizeof(uint8_t);
    220                     prefixbytes++;
    221                     continue;   //fetch the next byte
    222 
    223                 // operand size override prefix byte
    224                 case OP_OPSIZE:
    225                     pCpu->prefix |= PREFIX_OPSIZE;
    226                     if (pCpu->mode == CPUMODE_16BIT)
    227                         pCpu->opmode = CPUMODE_32BIT;
    228                     else
    229                         pCpu->opmode = CPUMODE_16BIT;  /* for 32 and 64 bits mode (there is no 32 bits operand size override prefix) */
    230 
    231                     i += sizeof(uint8_t);
    232                     prefixbytes++;
    233                     continue;   //fetch the next byte
    234 
    235                 // rep and repne are not really prefixes, but we'll treat them as such
    236                 case OP_REPE:
    237                     pCpu->prefix |= PREFIX_REP;
    238                     i += sizeof(uint8_t);
    239                     prefixbytes += sizeof(uint8_t);
    240                     continue;   //fetch the next byte
    241 
    242                 case OP_REPNE:
    243                     pCpu->prefix |= PREFIX_REPNE;
    244                     i += sizeof(uint8_t);
    245                     prefixbytes += sizeof(uint8_t);
    246                     continue;   //fetch the next byte
    247 
    248                 case OP_REX:
    249                     Assert(pCpu->mode == CPUMODE_64BIT);
    250                     /* REX prefix byte */
    251                     pCpu->prefix    |= PREFIX_REX;
    252                     pCpu->prefix_rex = PREFIX_REX_OP_2_FLAGS(paOneByteMap[codebyte].param1);
    253                     i += sizeof(uint8_t);
    254                     prefixbytes += sizeof(uint8_t);
    255 
    256                     if (pCpu->prefix_rex & PREFIX_REX_FLAGS_W)
    257                         pCpu->opmode = CPUMODE_64BIT;  /* overrides size prefix byte */
    258                     continue;   //fetch the next byte
    259                 }
     166                pCpu->lastprefix = opcode;
     167                pCpu->prefix &= ~PREFIX_REX;
    260168            }
    261169
    262             idx = i;
    263             i += sizeof(uint8_t); //first opcode byte
    264 
    265             pCpu->opcode = codebyte;
    266             /* Prefix byte(s) is/are part of the instruction. */
    267             pCpu->opaddr = pu8Instruction + idx + u32EipOffset - prefixbytes;
    268 
    269             inc = ParseInstruction(pu8Instruction + i, &paOneByteMap[pCpu->opcode], pCpu);
    270 
    271             pCpu->opsize = prefixbytes + inc + sizeof(uint8_t);
    272 
    273             if(pszOutput) {
    274                 disasmSprintf(pszOutput, pu8Instruction+i-1-prefixbytes, pCpu, &pCpu->param1, &pCpu->param2, &pCpu->param3);
     170            switch (opcode)
     171            {
     172            case OP_INVALID:
     173                if (pcbSize)
     174                    *pcbSize = pCpu->opsize;
     175                return pCpu->rc = VERR_DIS_INVALID_OPCODE;
     176
     177            // segment override prefix byte
     178            case OP_SEG:
     179                pCpu->enmPrefixSeg = (DIS_SELREG)(paOneByteMap[codebyte].param1 - OP_PARM_REG_SEG_START);
     180                /* Segment prefixes for CS, DS, ES and SS are ignored in long mode. */
     181                if (   pCpu->mode != CPUMODE_64BIT
     182                    || pCpu->enmPrefixSeg >= DIS_SELREG_FS)
     183                    pCpu->prefix |= PREFIX_SEG;
     184                i += sizeof(uint8_t);
     185                cbPrefix++;
     186                continue;   //fetch the next byte
     187
     188            // lock prefix byte
     189            case OP_LOCK:
     190                pCpu->prefix |= PREFIX_LOCK;
     191                i += sizeof(uint8_t);
     192                cbPrefix++;
     193                continue;   //fetch the next byte
     194
     195            // address size override prefix byte
     196            case OP_ADDRSIZE:
     197                pCpu->prefix |= PREFIX_ADDRSIZE;
     198                if (pCpu->mode == CPUMODE_16BIT)
     199                    pCpu->addrmode = CPUMODE_32BIT;
     200                else
     201                if (pCpu->mode == CPUMODE_32BIT)
     202                    pCpu->addrmode = CPUMODE_16BIT;
     203                else
     204                    pCpu->addrmode = CPUMODE_32BIT;     /* 64 bits */
     205
     206                i += sizeof(uint8_t);
     207                cbPrefix++;
     208                continue;   //fetch the next byte
     209
     210            // operand size override prefix byte
     211            case OP_OPSIZE:
     212                pCpu->prefix |= PREFIX_OPSIZE;
     213                if (pCpu->mode == CPUMODE_16BIT)
     214                    pCpu->opmode = CPUMODE_32BIT;
     215                else
     216                    pCpu->opmode = CPUMODE_16BIT;  /* for 32 and 64 bits mode (there is no 32 bits operand size override prefix) */
     217
     218                i += sizeof(uint8_t);
     219                cbPrefix++;
     220                continue;   //fetch the next byte
     221
     222            // rep and repne are not really prefixes, but we'll treat them as such
     223            case OP_REPE:
     224                pCpu->prefix |= PREFIX_REP;
     225                i += sizeof(uint8_t);
     226                cbPrefix += sizeof(uint8_t);
     227                continue;   //fetch the next byte
     228
     229            case OP_REPNE:
     230                pCpu->prefix |= PREFIX_REPNE;
     231                i += sizeof(uint8_t);
     232                cbPrefix += sizeof(uint8_t);
     233                continue;   //fetch the next byte
     234
     235            case OP_REX:
     236                Assert(pCpu->mode == CPUMODE_64BIT);
     237                /* REX prefix byte */
     238                pCpu->prefix    |= PREFIX_REX;
     239                pCpu->prefix_rex = PREFIX_REX_OP_2_FLAGS(paOneByteMap[codebyte].param1);
     240                i += sizeof(uint8_t);
     241                cbPrefix += sizeof(uint8_t);
     242
     243                if (pCpu->prefix_rex & PREFIX_REX_FLAGS_W)
     244                    pCpu->opmode = CPUMODE_64BIT;  /* overrides size prefix byte */
     245                continue;   //fetch the next byte
    275246            }
    276 
    277             i += inc;
    278             prefixbytes = 0;
    279             break;
    280247        }
    281     }
    282 #ifndef __L4ENV__
    283     catch(...)
    284 #else
    285     else  /* setjmp has returned a non-zero value: an exception occurred */
    286 #endif
    287     {
    288         if (pcbSize)
    289             *pcbSize = 0;
    290         return VERR_DIS_GEN_FAILURE;
     248
     249        pCpu->cbPrefix = i; Assert(cbPrefix == i);
     250        pCpu->opcode   = codebyte;
     251
     252        unsigned idx = i;
     253        i += sizeof(uint8_t); //first opcode byte
     254
     255        unsigned cbInc = ParseInstruction(uInstrAddr + i, &paOneByteMap[pCpu->opcode], pCpu);
     256
     257        AssertMsg(pCpu->opsize == cbPrefix + cbInc + sizeof(uint8_t),
     258                  ("%u %u\n", pCpu->opsize, cbPrefix + cbInc + sizeof(uint8_t)));
     259        pCpu->opsize = cbPrefix + cbInc + sizeof(uint8_t);
     260
     261        if (pszOutput)
     262            disasmSprintf(pszOutput, uInstrAddr+i-1-cbPrefix, pCpu, &pCpu->param1, &pCpu->param2, &pCpu->param3);
     263
     264        i += cbInc;
     265        cbPrefix = 0;
     266        break;
    291267    }
    292268
     
    297273        disValidateLockSequence(pCpu);
    298274
    299     return VINF_SUCCESS;
    300 }
    301 //*****************************************************************************
    302 //*****************************************************************************
    303 char *DbgBytesToString(PDISCPUSTATE pCpu, RTUINTPTR pBytes, int size, char *pszOutput)
    304 {
    305     char   *psz = strchr(pszOutput, '\0');
    306     size_t  len;
    307     int     i;
    308 
    309     for(len = psz - pszOutput; len < 40; len++)
    310         *psz++ = ' ';
    311     *psz++ = ' ';
    312     *psz++ = '[';
    313 
    314     for(i = 0; (int)i < size; i++)
    315         psz += RTStrPrintf(psz, 64, "%02X ", DISReadByte(pCpu, pBytes+i));
    316 
    317     psz[-1] = ']';  // replaces space
    318 
    319     return pszOutput;
    320 }
    321 //*****************************************************************************
    322 //*****************************************************************************
    323 void disasmSprintf(char *pszOutput, RTUINTPTR pu8Instruction, PDISCPUSTATE pCpu, OP_PARAMETER *pParam1, OP_PARAMETER *pParam2, OP_PARAMETER *pParam3)
    324 {
    325     const char *lpszFormat = pCpu->pszOpcode;
     275    return pCpu->rc;
     276}
     277//*****************************************************************************
     278//*****************************************************************************
     279static size_t DbgBytesToString(PDISCPUSTATE pCpu, char *pszOutput, size_t offStart)
     280{
     281    unsigned off = offStart;
     282
     283    while (off < 40)
     284        pszOutput[off++] = ' ';
     285    pszOutput[off++] = ' ';
     286    pszOutput[off++] = '[';
     287
     288    for (unsigned i = 0; i < pCpu->opsize; i++)
     289        off += RTStrPrintf(&pszOutput[off], 64, "%02X ", pCpu->abInstr[i]);
     290
     291    pszOutput[off - 1] = ']';  // replaces space
     292    return off - offStart;
     293}
     294//*****************************************************************************
     295//*****************************************************************************
     296void disasmSprintf(char *pszOutput, RTUINTPTR uInstrAddr, PDISCPUSTATE pCpu,
     297                   OP_PARAMETER *pParam1, OP_PARAMETER *pParam2, OP_PARAMETER *pParam3)
     298{
     299    const char *pszFormat = pCpu->pszOpcode;
    326300    int   param = 1;
    327301
    328     RTStrPrintf(pszOutput, 64, "%08X:  ", (unsigned)pCpu->opaddr);
    329     if(pCpu->prefix & PREFIX_LOCK)
     302
     303    size_t off = RTStrPrintf(pszOutput, 64, "%08RTptr:  ", pCpu->opaddr);
     304    if (pCpu->prefix & PREFIX_LOCK)
     305        off += RTStrPrintf(&pszOutput[off], 64, "lock ");
     306    if (pCpu->prefix & PREFIX_REP)
     307        off += RTStrPrintf(&pszOutput[off], 64, "rep(e) ");
     308    else if(pCpu->prefix & PREFIX_REPNE)
     309        off += RTStrPrintf(&pszOutput[off], 64, "repne ");
     310
     311    if (!strcmp("Invalid Opcode", pszFormat))
    330312    {
    331         RTStrPrintf(&pszOutput[strlen(pszOutput)], 64,  "lock ");
    332     }
    333     if(pCpu->prefix & PREFIX_REP)
    334     {
    335         RTStrPrintf(&pszOutput[strlen(pszOutput)], 64, "rep(e) ");
     313        if (pCpu->opsize >= 2)
     314            off += RTStrPrintf(&pszOutput[off], 64, "Invalid Opcode [%02X][%02X]", pCpu->abInstr[0], pCpu->abInstr[1]);
     315        else
     316            off += RTStrPrintf(&pszOutput[off], 64, "Invalid Opcode [%02X]", pCpu->abInstr[0]);
    336317    }
    337318    else
    338     if(pCpu->prefix & PREFIX_REPNE)
    339     {
    340         RTStrPrintf(&pszOutput[strlen(pszOutput)], 64, "repne ");
    341     }
    342 
    343     if(!strcmp("Invalid Opcode", lpszFormat))
    344     {
    345         RTStrPrintf(&pszOutput[strlen(pszOutput)], 64, "Invalid Opcode [%02X][%02X]", DISReadByte(pCpu, pu8Instruction), DISReadByte(pCpu, pu8Instruction+1) );
    346     }
    347     else
    348     while(*lpszFormat)
    349     {
    350         switch(*lpszFormat)
     319        while (*pszFormat)
    351320        {
    352         case '%':
    353             switch(*(lpszFormat+1))
     321            switch (*pszFormat)
    354322            {
    355             case 'J': //Relative jump offset
    356             {
    357                 int32_t disp;
    358 
    359                 AssertMsg(param == 1, ("Invalid branch parameter nr"));
    360                 if(pParam1->flags & USE_IMMEDIATE8_REL)
     323            case '%':
     324                switch (pszFormat[1])
    361325                {
    362                     disp = (int32_t)(char)pParam1->parval;
     326                case 'J': //Relative jump offset
     327                {
     328                    int32_t disp;
     329
     330                    AssertMsg(param == 1, ("Invalid branch parameter nr"));
     331                    if (pParam1->flags & USE_IMMEDIATE8_REL)
     332                        disp = (int32_t)(char)pParam1->parval;
     333                    else if (pParam1->flags & USE_IMMEDIATE16_REL)
     334                        disp = (int32_t)(uint16_t)pParam1->parval;
     335                    else if (pParam1->flags & USE_IMMEDIATE32_REL)
     336                        disp = (int32_t)pParam1->parval;
     337                    else if(pParam1->flags & USE_IMMEDIATE64_REL)
     338                        /** @todo: is this correct? */
     339                        disp = (int32_t)pParam1->parval;
     340                    else
     341                    {
     342                        AssertMsgFailed(("Oops!\n"));
     343                        return;
     344                    }
     345                    uint32_t addr = (uint32_t)(pCpu->opaddr + pCpu->opsize) + disp;
     346                    off += RTStrPrintf(&pszOutput[off], 64, "[%08X]", addr);
    363347                }
    364                 else
    365                 if(pParam1->flags & USE_IMMEDIATE16_REL)
    366                 {
    367                     disp = (int32_t)(uint16_t)pParam1->parval;
    368                 }
    369                 else
    370                 if(pParam1->flags & USE_IMMEDIATE32_REL)
    371                 {
    372                     disp = (int32_t)pParam1->parval;
    373                 }
    374                 else
    375                 if(pParam1->flags & USE_IMMEDIATE64_REL)
    376                 {
    377                     /* @todo: is this correct? */
    378                     disp = (int32_t)pParam1->parval;
    379                 }
    380                 else
    381                 {
     348
     349                    //no break;
     350
     351                case 'A': //direct address
     352                case 'C': //control register
     353                case 'D': //debug register
     354                case 'E': //ModRM specifies parameter
     355                case 'F': //Eflags register
     356                case 'G': //ModRM selects general register
     357                case 'I': //Immediate data
     358                case 'M': //ModRM may only refer to memory
     359                case 'O': //No ModRM byte
     360                case 'P': //ModRM byte selects MMX register
     361                case 'Q': //ModRM byte selects MMX register or memory address
     362                case 'R': //ModRM byte may only refer to a general register
     363                case 'S': //ModRM byte selects a segment register
     364                case 'T': //ModRM byte selects a test register
     365                case 'V': //ModRM byte selects an XMM/SSE register
     366                case 'W': //ModRM byte selects an XMM/SSE register or a memory address
     367                case 'X': //DS:SI
     368                case 'Y': //ES:DI
     369                    switch(param)
     370                    {
     371                    case 1:
     372                        off += RTStrPrintf(&pszOutput[off], 64, pParam1->szParam);
     373                        break;
     374                    case 2:
     375                        off += RTStrPrintf(&pszOutput[off], 64, pParam2->szParam);
     376                        break;
     377                    case 3:
     378                        off += RTStrPrintf(&pszOutput[off], 64, pParam3->szParam);
     379                        break;
     380                    }
     381                    break;
     382
     383                case 'e': //register based on operand size (e.g. %eAX)
     384                    if(pCpu->opmode == CPUMODE_32BIT)
     385                        off += RTStrPrintf(&pszOutput[off], 64, "E");
     386                    if(pCpu->opmode == CPUMODE_64BIT)
     387                        off += RTStrPrintf(&pszOutput[off], 64, "R");
     388
     389                    off += RTStrPrintf(&pszOutput[off], 64, "%c%c", pszFormat[2], pszFormat[3]);
     390                    break;
     391
     392                default:
    382393                    AssertMsgFailed(("Oops!\n"));
    383                     return;
    384                 }
    385                 uint32_t addr = (uint32_t)(pCpu->opaddr + pCpu->opsize) + disp;
    386                 RTStrPrintf(&pszOutput[strlen(pszOutput)], 64, "[%08X]", addr);
    387             }
    388 
    389                 //no break;
    390 
    391             case 'A': //direct address
    392             case 'C': //control register
    393             case 'D': //debug register
    394             case 'E': //ModRM specifies parameter
    395             case 'F': //Eflags register
    396             case 'G': //ModRM selects general register
    397             case 'I': //Immediate data
    398             case 'M': //ModRM may only refer to memory
    399             case 'O': //No ModRM byte
    400             case 'P': //ModRM byte selects MMX register
    401             case 'Q': //ModRM byte selects MMX register or memory address
    402             case 'R': //ModRM byte may only refer to a general register
    403             case 'S': //ModRM byte selects a segment register
    404             case 'T': //ModRM byte selects a test register
    405             case 'V': //ModRM byte selects an XMM/SSE register
    406             case 'W': //ModRM byte selects an XMM/SSE register or a memory address
    407             case 'X': //DS:SI
    408             case 'Y': //ES:DI
    409                 switch(param)
    410                 {
    411                 case 1:
    412                     RTStrPrintf(&pszOutput[strlen(pszOutput)], 64, pParam1->szParam);
    413                     break;
    414                 case 2:
    415                     RTStrPrintf(&pszOutput[strlen(pszOutput)], 64, pParam2->szParam);
    416                     break;
    417                 case 3:
    418                     RTStrPrintf(&pszOutput[strlen(pszOutput)], 64, pParam3->szParam);
    419394                    break;
    420395                }
     396
     397                //Go to the next parameter in the format string
     398                while (*pszFormat && *pszFormat != ',')
     399                    pszFormat++;
     400                if (*pszFormat == ',')
     401                    pszFormat--;
     402
    421403                break;
    422404
    423             case 'e': //register based on operand size (e.g. %eAX)
    424                 if(pCpu->opmode == CPUMODE_32BIT)
    425                     RTStrPrintf(&pszOutput[strlen(pszOutput)], 64, "E");
    426                 if(pCpu->opmode == CPUMODE_64BIT)
    427                     RTStrPrintf(&pszOutput[strlen(pszOutput)], 64, "R");
    428 
    429                 RTStrPrintf(&pszOutput[strlen(pszOutput)], 64, "%c%c", lpszFormat[2], lpszFormat[3]);
    430                 break;
     405            case ',':
     406                param++;
     407                //no break
    431408
    432409            default:
    433                 AssertMsgFailed(("Oops!\n"));
     410                off += RTStrPrintf(&pszOutput[off], 64, "%c", *pszFormat);
    434411                break;
    435412            }
    436413
    437             //Go to the next parameter in the format string
    438             while(*lpszFormat && *lpszFormat != ',') lpszFormat++;
    439             if(*lpszFormat == ',') lpszFormat--;
    440 
    441             break;
    442 
    443         case ',':
    444             param++;
    445             //no break
    446 
    447         default:
    448             RTStrPrintf(&pszOutput[strlen(pszOutput)], 64, "%c", *lpszFormat);
    449             break;
     414            if (*pszFormat)
     415                pszFormat++;
    450416        }
    451417
    452         if(*lpszFormat) lpszFormat++;
    453     }
    454     DbgBytesToString(pCpu, pu8Instruction, pCpu->opsize, pszOutput);
    455     RTStrPrintf(&pszOutput[strlen(pszOutput)], 64, "\n");
    456 }
    457 //*****************************************************************************
    458 //*****************************************************************************
     418    off += DbgBytesToString(pCpu, pszOutput, off);
     419    off += RTStrPrintf(&pszOutput[off], 64, "\n");
     420}
     421//*****************************************************************************
     422//*****************************************************************************
  • trunk/src/VBox/Disassembler/DisasmCore.cpp

    r41494 r41658  
     1/* $Id$ */
    12/** @file
    2  *
    3  * VBox disassembler:
    4  * Core components
     3 * VBox Disassembler - Core Components.
    54 */
    65
    76/*
    8  * Copyright (C) 2006-2007 Oracle Corporation
     7 * Copyright (C) 2006-2012 Oracle Corporation
    98 *
    109 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    4544*   Internal Functions                                                         *
    4645*******************************************************************************/
    47 static int disCoreOne(PDISCPUSTATE pCpu, RTUINTPTR InstructionAddr, unsigned *pcbInstruction);
     46static int disCoreParseInstr(PDISCPUSTATE pCpu, RTUINTPTR uInstrAddr, const OPCODE *paOneByteMap,
     47                             unsigned *pcbInstruction);
    4848#if !defined(DIS_CORE_ONLY) && defined(LOG_ENABLED)
    4949static void disasmAddString(char *psz, const char *pszString);
     
    160160};
    161161
    162 /**
    163  * Parses one instruction.
    164  * The result is found in pCpu.
    165  *
    166  * @returns Success indicator.
    167  * @param   pCpu            Pointer to cpu structure which has DISCPUSTATE::mode set correctly.
    168  * @param   InstructionAddr Pointer to the instruction to parse.
    169  * @param   pcbInstruction  Where to store the size of the instruction.
    170  *                          NULL is allowed.
    171  */
    172 DISDECL(int) DISCoreOne(PDISCPUSTATE pCpu, RTUINTPTR InstructionAddr, unsigned *pcbInstruction)
    173 {
    174     /*
    175      * Reset instruction settings
    176      */
    177     pCpu->prefix        = PREFIX_NONE;
    178     pCpu->enmPrefixSeg  = DIS_SELREG_DS;
    179     pCpu->lastprefix    = 0;
    180     pCpu->ModRM.u       = 0;
    181     pCpu->SIB.u         = 0;
    182     pCpu->param1.parval = 0;
    183     pCpu->param2.parval = 0;
    184     pCpu->param3.parval = 0;
    185     pCpu->param1.szParam[0] = '\0';
    186     pCpu->param2.szParam[0] = '\0';
    187     pCpu->param3.szParam[0] = '\0';
    188     pCpu->param1.flags  = 0;
    189     pCpu->param2.flags  = 0;
    190     pCpu->param3.flags  = 0;
    191     pCpu->param1.size   = 0;
    192     pCpu->param2.size   = 0;
    193     pCpu->param3.size   = 0;
    194     pCpu->pfnReadBytes  = 0;
    195     pCpu->uFilter       = OPTYPE_ALL;
    196     pCpu->pfnDisasmFnTable = pfnFullDisasm;
    197 
    198     return RT_SUCCESS(disCoreOne(pCpu, InstructionAddr, pcbInstruction));
    199 }
    200162
    201163/**
     
    204166 *
    205167 * @returns VBox status code.
    206  * @param   InstructionAddr Address of the instruction to decode. What this means
     168 * @param   uInstrAddr      Address of the instruction to decode. What this means
    207169 *                          is left to the pfnReadBytes function.
    208170 * @param   enmCpuMode      The CPU mode. CPUMODE_32BIT, CPUMODE_16BIT, or CPUMODE_64BIT.
     
    213175 *                          NULL is allowed.
    214176 */
    215 DISDECL(int) DISCoreOneEx(RTUINTPTR InstructionAddr, DISCPUMODE enmCpuMode, PFN_DIS_READBYTES pfnReadBytes, void *pvUser,
     177DISDECL(int) DISCoreOneEx(RTUINTPTR uInstrAddr, DISCPUMODE enmCpuMode, PFNDISREADBYTES pfnReadBytes, void *pvUser,
    216178                          PDISCPUSTATE pCpu, unsigned *pcbInstruction)
    217179{
     180    const OPCODE *paOneByteMap;
     181
    218182    /*
    219      * Reset instruction settings
     183     * Initialize the CPU state.
     184     * Note! The RT_BZERO make ASSUMPTIONS about the placement of apvUserData.
    220185     */
     186    RT_BZERO(pCpu, RT_OFFSETOF(DISCPUSTATE, apvUserData));
     187
     188    pCpu->mode              = enmCpuMode;
     189    if (enmCpuMode == CPUMODE_64BIT)
     190    {
     191        paOneByteMap        = g_aOneByteMapX64;
     192        pCpu->addrmode      = CPUMODE_64BIT;
     193        pCpu->opmode        = CPUMODE_32BIT;
     194    }
     195    else
     196    {
     197        paOneByteMap        = g_aOneByteMapX86;
     198        pCpu->addrmode      = enmCpuMode;
     199        pCpu->opmode        = enmCpuMode;
     200    }
    221201    pCpu->prefix            = PREFIX_NONE;
    222202    pCpu->enmPrefixSeg      = DIS_SELREG_DS;
    223     pCpu->lastprefix        = 0;
    224     pCpu->mode              = enmCpuMode;
    225     pCpu->ModRM.u           = 0;
    226     pCpu->SIB.u             = 0;
    227     pCpu->param1.parval     = 0;
    228     pCpu->param2.parval     = 0;
    229     pCpu->param3.parval     = 0;
    230     pCpu->param1.szParam[0] = '\0';
    231     pCpu->param2.szParam[0] = '\0';
    232     pCpu->param3.szParam[0] = '\0';
    233     pCpu->param1.flags      = 0;
    234     pCpu->param2.flags      = 0;
    235     pCpu->param3.flags      = 0;
    236     pCpu->param1.size       = 0;
    237     pCpu->param2.size       = 0;
    238     pCpu->param3.size       = 0;
    239     pCpu->pfnReadBytes      = pfnReadBytes;
     203    pCpu->uInstrAddr        = uInstrAddr;
     204    pCpu->pfnDisasmFnTable  = pfnFullDisasm;
     205    pCpu->uFilter           = OPTYPE_ALL;
     206    pCpu->rc                = VINF_SUCCESS;
     207    pCpu->pfnReadBytes      = pfnReadBytes ? pfnReadBytes : disReadBytesDefault;
    240208    pCpu->apvUserData[0]    = pvUser;
    241     pCpu->uFilter           = OPTYPE_ALL;
    242     pCpu->pfnDisasmFnTable  = pfnFullDisasm;
    243 
    244     return disCoreOne(pCpu, InstructionAddr, pcbInstruction);
     209
     210    return disCoreParseInstr(pCpu, uInstrAddr, paOneByteMap, pcbInstruction);
    245211}
    246212
     
    250216 * @returns VBox status code.
    251217 * @param   pCpu            Initialized cpu state.
    252  * @param   InstructionAddr Instruction address.
     218 * @param   paOneByteMap    The one byte opcode map to use.
     219 * @param   uInstrAddr      Instruction address.
    253220 * @param   pcbInstruction  Where to store the instruction size. Can be NULL.
    254221 */
    255 static int disCoreOne(PDISCPUSTATE pCpu, RTUINTPTR InstructionAddr, unsigned *pcbInstruction)
    256 {
    257     const OPCODE *paOneByteMap;
    258 
     222static int disCoreParseInstr(PDISCPUSTATE pCpu, RTUINTPTR uInstrAddr, const OPCODE *paOneByteMap, unsigned *pcbInstruction)
     223{
    259224    /*
    260225     * Parse byte by byte.
     
    262227    unsigned  iByte = 0;
    263228    unsigned  cbInc;
    264 
    265     if (pCpu->mode == CPUMODE_64BIT)
    266     {
    267         paOneByteMap     = g_aOneByteMapX64;
    268         pCpu->addrmode   = CPUMODE_64BIT;
    269         pCpu->opmode     = CPUMODE_32BIT;
    270     }
    271     else
    272     {
    273         paOneByteMap     = g_aOneByteMapX86;
    274         pCpu->addrmode   = pCpu->mode;
    275         pCpu->opmode     = pCpu->mode;
    276     }
    277 
    278 #ifdef IN_RING3
    279 # ifndef __L4ENV__  /* Unfortunately, we have no exception handling in l4env */
    280     try
    281 # else
    282     pCpu->pJumpBuffer = &jumpbuffer;
    283     if (setjmp(jumpbuffer) == 0)
    284 # endif
    285 #endif
    286     {
    287         while(1)
     229    for (;;)
     230    {
     231        uint8_t codebyte = DISReadByte(pCpu, uInstrAddr+iByte);
     232        uint8_t opcode   = paOneByteMap[codebyte].opcode;
     233
     234        /* Hardcoded assumption about OP_* values!! */
     235        if (opcode <= OP_LAST_PREFIX)
    288236        {
    289             uint8_t codebyte = DISReadByte(pCpu, InstructionAddr+iByte);
    290             uint8_t opcode   = paOneByteMap[codebyte].opcode;
    291 
    292             /* Hardcoded assumption about OP_* values!! */
    293             if (opcode <= OP_LAST_PREFIX)
     237            /* The REX prefix must precede the opcode byte(s). Any other placement is ignored. */
     238            if (opcode != OP_REX)
    294239            {
    295                 /* The REX prefix must precede the opcode byte(s). Any other placement is ignored. */
    296                 if (opcode != OP_REX)
     240                /** Last prefix byte (for SSE2 extension tables); don't include the REX prefix */
     241                pCpu->lastprefix = opcode;
     242                pCpu->prefix &= ~PREFIX_REX;
     243            }
     244
     245            switch (opcode)
     246            {
     247            case OP_INVALID:
     248                if (pcbInstruction)
     249                    *pcbInstruction = iByte + 1;
     250                return pCpu->rc = VERR_DIS_INVALID_OPCODE;
     251
     252            // segment override prefix byte
     253            case OP_SEG:
     254                pCpu->enmPrefixSeg = (DIS_SELREG)(paOneByteMap[codebyte].param1 - OP_PARM_REG_SEG_START);
     255                /* Segment prefixes for CS, DS, ES and SS are ignored in long mode. */
     256                if (   pCpu->mode != CPUMODE_64BIT
     257                    || pCpu->enmPrefixSeg >= DIS_SELREG_FS)
    297258                {
    298                     /** Last prefix byte (for SSE2 extension tables); don't include the REX prefix */
    299                     pCpu->lastprefix = opcode;
    300                     pCpu->prefix &= ~PREFIX_REX;
     259                    pCpu->prefix    |= PREFIX_SEG;
    301260                }
    302 
    303                 switch (opcode)
    304                 {
    305                 case OP_INVALID:
    306 #if 0
    307                     AssertMsgFailed(("Invalid opcode!!\n"));
    308 #endif
    309                     return VERR_DIS_INVALID_OPCODE;
    310 
    311                 // segment override prefix byte
    312                 case OP_SEG:
    313                     pCpu->enmPrefixSeg = (DIS_SELREG)(paOneByteMap[codebyte].param1 - OP_PARM_REG_SEG_START);
    314                     /* Segment prefixes for CS, DS, ES and SS are ignored in long mode. */
    315                     if (   pCpu->mode != CPUMODE_64BIT
    316                         || pCpu->enmPrefixSeg >= DIS_SELREG_FS)
    317                     {
    318                         pCpu->prefix    |= PREFIX_SEG;
    319                     }
    320                     iByte += sizeof(uint8_t);
    321                     continue;   //fetch the next byte
    322 
    323                 // lock prefix byte
    324                 case OP_LOCK:
    325                     pCpu->prefix |= PREFIX_LOCK;
    326                     iByte       += sizeof(uint8_t);
    327                     continue;   //fetch the next byte
    328 
    329                 // address size override prefix byte
    330                 case OP_ADDRSIZE:
    331                     pCpu->prefix |= PREFIX_ADDRSIZE;
    332                     if (pCpu->mode == CPUMODE_16BIT)
    333                         pCpu->addrmode = CPUMODE_32BIT;
    334                     else
    335                     if (pCpu->mode == CPUMODE_32BIT)
    336                         pCpu->addrmode = CPUMODE_16BIT;
    337                     else
    338                         pCpu->addrmode = CPUMODE_32BIT;     /* 64 bits */
    339 
    340                     iByte        += sizeof(uint8_t);
    341                     continue;   //fetch the next byte
    342 
    343                 // operand size override prefix byte
    344                 case OP_OPSIZE:
    345                     pCpu->prefix |= PREFIX_OPSIZE;
    346                     if (pCpu->mode == CPUMODE_16BIT)
    347                         pCpu->opmode = CPUMODE_32BIT;
    348                     else
    349                         pCpu->opmode = CPUMODE_16BIT;  /* for 32 and 64 bits mode (there is no 32 bits operand size override prefix) */
    350 
    351                     iByte        += sizeof(uint8_t);
    352                     continue;   //fetch the next byte
    353 
    354                 // rep and repne are not really prefixes, but we'll treat them as such
    355                 case OP_REPE:
    356                     pCpu->prefix |= PREFIX_REP;
    357                     iByte       += sizeof(uint8_t);
    358                     continue;   //fetch the next byte
    359 
    360                 case OP_REPNE:
    361                     pCpu->prefix |= PREFIX_REPNE;
    362                     iByte       += sizeof(uint8_t);
    363                     continue;   //fetch the next byte
    364 
    365                 case OP_REX:
    366                     Assert(pCpu->mode == CPUMODE_64BIT);
    367                     /* REX prefix byte */
    368                     pCpu->prefix    |= PREFIX_REX;
    369                     pCpu->prefix_rex = PREFIX_REX_OP_2_FLAGS(paOneByteMap[codebyte].param1);
    370                     iByte           += sizeof(uint8_t);
    371 
    372                     if (pCpu->prefix_rex & PREFIX_REX_FLAGS_W)
    373                         pCpu->opmode = CPUMODE_64BIT;  /* overrides size prefix byte */
    374                     continue;   //fetch the next byte
    375                 }
     261                iByte += sizeof(uint8_t);
     262                continue;   //fetch the next byte
     263
     264            // lock prefix byte
     265            case OP_LOCK:
     266                pCpu->prefix |= PREFIX_LOCK;
     267                iByte       += sizeof(uint8_t);
     268                continue;   //fetch the next byte
     269
     270            // address size override prefix byte
     271            case OP_ADDRSIZE:
     272                pCpu->prefix |= PREFIX_ADDRSIZE;
     273                if (pCpu->mode == CPUMODE_16BIT)
     274                    pCpu->addrmode = CPUMODE_32BIT;
     275                else
     276                if (pCpu->mode == CPUMODE_32BIT)
     277                    pCpu->addrmode = CPUMODE_16BIT;
     278                else
     279                    pCpu->addrmode = CPUMODE_32BIT;     /* 64 bits */
     280
     281                iByte        += sizeof(uint8_t);
     282                continue;   //fetch the next byte
     283
     284            // operand size override prefix byte
     285            case OP_OPSIZE:
     286                pCpu->prefix |= PREFIX_OPSIZE;
     287                if (pCpu->mode == CPUMODE_16BIT)
     288                    pCpu->opmode = CPUMODE_32BIT;
     289                else
     290                    pCpu->opmode = CPUMODE_16BIT;  /* for 32 and 64 bits mode (there is no 32 bits operand size override prefix) */
     291
     292                iByte        += sizeof(uint8_t);
     293                continue;   //fetch the next byte
     294
     295            // rep and repne are not really prefixes, but we'll treat them as such
     296            case OP_REPE:
     297                pCpu->prefix |= PREFIX_REP;
     298                iByte       += sizeof(uint8_t);
     299                continue;   //fetch the next byte
     300
     301            case OP_REPNE:
     302                pCpu->prefix |= PREFIX_REPNE;
     303                iByte       += sizeof(uint8_t);
     304                continue;   //fetch the next byte
     305
     306            case OP_REX:
     307                Assert(pCpu->mode == CPUMODE_64BIT);
     308                /* REX prefix byte */
     309                pCpu->prefix    |= PREFIX_REX;
     310                pCpu->prefix_rex = PREFIX_REX_OP_2_FLAGS(paOneByteMap[codebyte].param1);
     311                iByte           += sizeof(uint8_t);
     312
     313                if (pCpu->prefix_rex & PREFIX_REX_FLAGS_W)
     314                    pCpu->opmode = CPUMODE_64BIT;  /* overrides size prefix byte */
     315                continue;   //fetch the next byte
    376316            }
    377 
    378             unsigned uIdx = iByte;
    379             iByte += sizeof(uint8_t); //first opcode byte
    380 
    381             pCpu->opaddr = InstructionAddr;
    382             pCpu->opcode = codebyte;
    383 
    384             cbInc = ParseInstruction(InstructionAddr + iByte, &paOneByteMap[pCpu->opcode], pCpu);
    385             iByte += cbInc;
    386             break;
    387         }
    388     }
    389 #ifdef IN_RING3
    390 # ifndef __L4ENV__
    391     catch(...)
    392 # else
    393     else  /* setjmp has returned a non-zero value: an exception occurred */
    394 # endif
    395     {
    396         pCpu->opsize = 0;
    397         return VERR_DIS_GEN_FAILURE;
    398     }
    399 #endif
    400 
     317        }
     318
     319        unsigned uIdx = iByte;
     320        iByte += sizeof(uint8_t); //first opcode byte
     321
     322        pCpu->opaddr = uInstrAddr;
     323        pCpu->opcode = codebyte;
     324
     325        cbInc = ParseInstruction(uInstrAddr + iByte, &paOneByteMap[pCpu->opcode], pCpu);
     326        iByte += cbInc;
     327        break;
     328    }
     329
     330    AssertMsg(pCpu->opsize == iByte || RT_FAILURE_NP(pCpu->rc), ("%u %u\n", pCpu->opsize, iByte));
    401331    pCpu->opsize = iByte;
    402332    if (pcbInstruction)
     
    406336        disValidateLockSequence(pCpu);
    407337
    408     return VINF_SUCCESS;
     338    return pCpu->rc;
    409339}
    410340//*****************************************************************************
     
    619549        {
    620550            pParam->flags |= USE_DISPLACEMENT32;
    621             pParam->disp32 = pCpu->disp;
     551            pParam->disp32 = pCpu->i32SibDisp;
    622552            disasmAddChar(pParam->szParam, '+');
    623553            disasmPrintDisp32(pParam);
     
    626556        {   /* sign-extend to 64 bits */
    627557            pParam->flags |= USE_DISPLACEMENT64;
    628             pParam->disp64 = pCpu->disp;
     558            pParam->disp64 = pCpu->i32SibDisp;
    629559            disasmAddChar(pParam->szParam, '+');
    630560            disasmPrintDisp64(pParam);
     
    666596    {
    667597        /* Additional 32 bits displacement. No change in long mode. */
    668         pCpu->disp = DISReadDWord(pCpu, lpszCodeBlock);
     598        pCpu->i32SibDisp = DISReadDWord(pCpu, lpszCodeBlock);
    669599        size += sizeof(int32_t);
    670600    }
     
    807737                {
    808738                    pParam->flags |= USE_DISPLACEMENT32;
    809                     pParam->disp32 = pCpu->disp;
     739                    pParam->disp32 = pCpu->i32SibDisp;
    810740                    disasmPrintDisp32(pParam);
    811741                }
     
    813743                {
    814744                    pParam->flags |= USE_RIPDISPLACEMENT32;
    815                     pParam->disp32 = pCpu->disp;
     745                    pParam->disp32 = pCpu->i32SibDisp;
    816746                    disasmAddString(pParam->szParam, "RIP+");
    817747                    disasmPrintDisp32(pParam);
     
    836766                disasmModRMReg(pCpu, pOp, rm, pParam, 1);
    837767            }
    838             pParam->disp8 = pCpu->disp;
     768            pParam->disp8 = pCpu->i32SibDisp;
    839769            pParam->flags |= USE_DISPLACEMENT8;
    840770
     
    859789                disasmModRMReg(pCpu, pOp, rm, pParam, 1);
    860790            }
    861             pParam->disp32 = pCpu->disp;
     791            pParam->disp32 = pCpu->i32SibDisp;
    862792            pParam->flags |= USE_DISPLACEMENT32;
    863793
     
    884814            if (rm == 6)
    885815            {//16 bits displacement
    886                 pParam->disp16 = pCpu->disp;
     816                pParam->disp16 = pCpu->i32SibDisp;
    887817                pParam->flags |= USE_DISPLACEMENT16;
    888818                disasmPrintDisp16(pParam);
     
    900830            disasmAddChar(pParam->szParam, '[');
    901831            disasmModRMReg16(pCpu, pOp, rm, pParam);
    902             pParam->disp8 = pCpu->disp;
     832            pParam->disp8 = pCpu->i32SibDisp;
    903833            pParam->flags |= USE_BASE | USE_DISPLACEMENT8;
    904834
     
    916846            disasmAddChar(pParam->szParam, '[');
    917847            disasmModRMReg16(pCpu, pOp, rm, pParam);
    918             pParam->disp16 = pCpu->disp;
     848            pParam->disp16 = pCpu->i32SibDisp;
    919849            pParam->flags |= USE_BASE | USE_DISPLACEMENT16;
    920850
     
    968898        case 0: /* Effective address */
    969899            if (rm == 5) {  /* 32 bits displacement */
    970                 pCpu->disp = DISReadDWord(pCpu, lpszCodeBlock);
     900                pCpu->i32SibDisp = DISReadDWord(pCpu, lpszCodeBlock);
    971901                size += sizeof(int32_t);
    972902            }
     
    975905
    976906        case 1: /* Effective address + 8 bits displacement */
    977             pCpu->disp = (int8_t)DISReadByte(pCpu, lpszCodeBlock);
     907            pCpu->i32SibDisp = (int8_t)DISReadByte(pCpu, lpszCodeBlock);
    978908            size += sizeof(char);
    979909            break;
    980910
    981911        case 2: /* Effective address + 32 bits displacement */
    982             pCpu->disp = DISReadDWord(pCpu, lpszCodeBlock);
     912            pCpu->i32SibDisp = DISReadDWord(pCpu, lpszCodeBlock);
    983913            size += sizeof(int32_t);
    984914            break;
     
    995925        case 0: /* Effective address */
    996926            if (rm == 6) {
    997                 pCpu->disp = DISReadWord(pCpu, lpszCodeBlock);
     927                pCpu->i32SibDisp = DISReadWord(pCpu, lpszCodeBlock);
    998928                size += sizeof(uint16_t);
    999929            }
     
    1002932
    1003933        case 1: /* Effective address + 8 bits displacement */
    1004             pCpu->disp = (int8_t)DISReadByte(pCpu, lpszCodeBlock);
     934            pCpu->i32SibDisp = (int8_t)DISReadByte(pCpu, lpszCodeBlock);
    1005935            size += sizeof(char);
    1006936            break;
    1007937
    1008938        case 2: /* Effective address + 32 bits displacement */
    1009             pCpu->disp = (int16_t)DISReadWord(pCpu, lpszCodeBlock);
     939            pCpu->i32SibDisp = (int16_t)DISReadWord(pCpu, lpszCodeBlock);
    1010940            size += sizeof(uint16_t);
    1011941            break;
     
    24732403
    24742404    default:
    2475 #ifdef IN_RING3
    24762405        Log(("disasmModRMReg %x:%x failed!!\n", type, subtype));
    2477         DIS_THROW(ExceptionInvalidModRM);
    2478 #else
    2479         AssertMsgFailed(("Oops!\n"));
    2480 #endif
     2406        pCpu->rc = VERR_DIS_INVALID_MODRM;
    24812407        break;
    24822408    }
     
    25002426void disasmModRMSReg(PDISCPUSTATE pCpu, PCOPCODE pOp, unsigned idx, POP_PARAMETER pParam)
    25012427{
    2502     NOREF(pCpu); NOREF(pOp);
    2503 #if 0 //def DEBUG_Sander
    2504     AssertMsg(idx < RT_ELEMENTS(szModRMSegReg), ("idx=%d\n", idx));
    2505 #endif
    2506 #ifdef IN_RING3
     2428    NOREF(pOp);
    25072429    if (idx >= RT_ELEMENTS(szModRMSegReg))
    25082430    {
    25092431        Log(("disasmModRMSReg %d failed!!\n", idx));
    2510         DIS_THROW(ExceptionInvalidParameter);
    2511     }
    2512 #endif
    2513 
    2514     idx = RT_MIN(idx, RT_ELEMENTS(szModRMSegReg)-1);
     2432        pCpu->rc = VERR_DIS_INVALID_PARAMETER;
     2433        return;
     2434    }
     2435
    25152436    disasmAddString(pParam->szParam, szModRMSegReg[idx]);
    25162437    pParam->flags |= USE_REG_SEG;
     
    26102531        disasmAddStringF1(pParam->szParam, "%s:", szModRMSegReg[pCpu->enmPrefixSeg]);
    26112532}
    2612 //*****************************************************************************
    2613 /* Read functions for getting the opcode bytes */
    2614 //*****************************************************************************
    2615 uint8_t DISReadByte(PDISCPUSTATE pCpu, RTUINTPTR pAddress)
    2616 {
    2617     if (pCpu->pfnReadBytes)
    2618     {
    2619          uint8_t temp = 0;
    2620          int     rc;
    2621 
    2622          rc = pCpu->pfnReadBytes(pAddress, &temp, sizeof(temp), pCpu);
    2623          if (RT_FAILURE(rc))
    2624          {
    2625              Log(("DISReadByte failed!!\n"));
    2626              DIS_THROW(ExceptionMemRead);
    2627          }
    2628          return temp;
    2629     }
    2630 #ifdef IN_RING0
    2631     AssertMsgFailed(("DISReadByte with no read callback in ring 0!!\n"));
    2632     return 0;
    2633 #else
    2634     return *(uint8_t *)(uintptr_t)pAddress;
    2635 #endif
    2636 }
    2637 //*****************************************************************************
    2638 //*****************************************************************************
    2639 uint16_t DISReadWord(PDISCPUSTATE pCpu, RTUINTPTR pAddress)
    2640 {
    2641     if (pCpu->pfnReadBytes)
    2642     {
    2643          uint16_t temp = 0;
    2644          int     rc;
    2645 
    2646          rc = pCpu->pfnReadBytes(pAddress, (uint8_t*)&temp, sizeof(temp), pCpu);
    2647          if (RT_FAILURE(rc))
    2648          {
    2649              Log(("DISReadWord failed!!\n"));
    2650              DIS_THROW(ExceptionMemRead);
    2651          }
    2652          return temp;
    2653     }
     2533
     2534
     2535/**
     2536 * Slow path for storing instruction bytes.
     2537 *
     2538 * @param   pCpu                The disassembler state.
     2539 * @param   uAddress            The address.
     2540 * @param   pbSrc               The bytes.
     2541 * @param   cbSrc               The number of bytes.
     2542 */
     2543DECL_NO_INLINE(static, void)
     2544disStoreInstrBytesSlow(PDISCPUSTATE pCpu, RTUINTPTR uAddress, const uint8_t *pbSrc, size_t cbSrc)
     2545{
     2546    /*
     2547     * Figure out which case it is.
     2548     */
     2549    uint32_t  cbInstr = pCpu->opsize;
     2550    RTUINTPTR off     = uAddress - pCpu->uInstrAddr;
     2551    if (off < cbInstr)
     2552    {
     2553        if (off + cbSrc <= cbInstr)
     2554        {
     2555            AssertMsg(memcmp(&pCpu->abInstr[off], pbSrc, cbSrc) == 0,
     2556                      ("%RTptr LB %zx off=%RTptr (%.*Rhxs)", uAddress, cbSrc, off, cbInstr, pCpu->abInstr));
     2557            return; /* fully re-reading old stuff. */
     2558        }
     2559
     2560        /* Only partially re-reading stuff, skip ahead and add the rest. */
     2561        uint32_t cbAlreadyRead = cbInstr - (uint32_t)off;
     2562        Assert(memcmp(&pCpu->abInstr[off], pbSrc, cbAlreadyRead) == 0);
     2563        uAddress += cbAlreadyRead;
     2564        pbSrc    += cbAlreadyRead;
     2565        cbSrc    -= cbAlreadyRead;
     2566    }
     2567
     2568    if (off >= sizeof(cbInstr))
     2569    {
     2570        /* The instruction is too long! This shouldn't happen. */
     2571        AssertMsgFailed(("%RTptr LB %zx off=%RTptr (%.*Rhxs)", uAddress, cbSrc, off, cbInstr, pCpu->abInstr));
     2572        return;
     2573    }
     2574    else if (off > cbInstr)
     2575    {
     2576        /* Mind the gap - this shouldn't happen, but read the gap bytes if it does. */
     2577        AssertMsgFailed(("%RTptr LB %zx off=%RTptr (%.16Rhxs)", uAddress, cbSrc, off, cbInstr, pCpu->abInstr));
     2578        uint32_t cbGap = off - cbInstr;
     2579        int rc = pCpu->pfnReadBytes(pCpu, &pCpu->abInstr[cbInstr], uAddress - cbGap, cbGap);
     2580        if (RT_FAILURE(rc))
     2581        {
     2582            pCpu->rc = VERR_DIS_MEM_READ;
     2583            RT_BZERO(&pCpu->abInstr[cbInstr], cbGap);
     2584        }
     2585        pCpu->opsize = cbInstr = off;
     2586    }
     2587
     2588    /*
     2589     * Copy the bytes.
     2590     */
     2591    if (off + cbSrc <= sizeof(pCpu->abInstr))
     2592    {
     2593        memcpy(&pCpu->abInstr[cbInstr], pbSrc, cbSrc);
     2594        pCpu->opsize = cbInstr + cbSrc;
     2595    }
     2596    else
     2597    {
     2598        uint32_t cbToCopy = sizeof(pCpu->abInstr) - off;
     2599        memcpy(&pCpu->abInstr[cbInstr], pbSrc, cbToCopy);
     2600        pCpu->opsize = sizeof(pCpu->abInstr);
     2601        AssertMsgFailed(("%RTptr LB %zx off=%RTptr (%.*Rhxs)", uAddress, cbSrc, off, sizeof(pCpu->abInstr), pCpu->abInstr));
     2602    }
     2603}
     2604
     2605DECLCALLBACK(int) disReadBytesDefault(PDISCPUSTATE pCpu, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead)
     2606{
    26542607#ifdef IN_RING0
    26552608    AssertMsgFailed(("DISReadWord with no read callback in ring 0!!\n"));
    2656     return 0;
     2609    RT_BZERO(pbDst, cbToRead);
     2610    return VERR_DIS_NO_READ_CALLBACK;
    26572611#else
    2658     return *(uint16_t *)(uintptr_t)pAddress;
     2612    memcpy(pbDst, (void const *)(uintptr_t)uSrcAddr, cbToRead);
     2613    return VINF_SUCCESS;
    26592614#endif
    26602615}
    2661 //*****************************************************************************
    2662 //*****************************************************************************
    2663 uint32_t DISReadDWord(PDISCPUSTATE pCpu, RTUINTPTR pAddress)
    2664 {
    2665     if (pCpu->pfnReadBytes)
    2666     {
    2667          uint32_t temp = 0;
    2668          int     rc;
    2669 
    2670          rc = pCpu->pfnReadBytes(pAddress, (uint8_t*)&temp, sizeof(temp), pCpu);
    2671          if (RT_FAILURE(rc))
    2672          {
    2673              Log(("DISReadDWord failed!!\n"));
    2674              DIS_THROW(ExceptionMemRead);
    2675          }
    2676          return temp;
    2677     }
    2678 #ifdef IN_RING0
    2679     AssertMsgFailed(("DISReadDWord with no read callback in ring 0!!\n"));
    2680     return 0;
    2681 #else
    2682     return *(uint32_t *)(uintptr_t)pAddress;
    2683 #endif
    2684 }
    2685 //*****************************************************************************
    2686 //*****************************************************************************
    2687 uint64_t DISReadQWord(PDISCPUSTATE pCpu, RTUINTPTR pAddress)
    2688 {
    2689     if (pCpu->pfnReadBytes)
    2690     {
    2691          uint64_t temp = 0;
    2692          int     rc;
    2693 
    2694          rc = pCpu->pfnReadBytes(pAddress, (uint8_t*)&temp, sizeof(temp), pCpu);
    2695          if (RT_FAILURE(rc))
    2696          {
    2697              Log(("DISReadQWord %x failed!!\n", pAddress));
    2698              DIS_THROW(ExceptionMemRead);
    2699          }
    2700 
    2701          return temp;
    2702     }
    2703 #ifdef IN_RING0
    2704     AssertMsgFailed(("DISReadQWord with no read callback in ring 0!!\n"));
    2705     return 0;
    2706 #else
    2707     return *(uint64_t *)(uintptr_t)pAddress;
    2708 #endif
     2616
     2617//*****************************************************************************
     2618/* Read functions for getting the opcode bytes */
     2619//*****************************************************************************
     2620uint8_t DISReadByte(PDISCPUSTATE pCpu, RTUINTPTR uAddress)
     2621{
     2622    uint8_t bTemp = 0;
     2623    int rc = pCpu->pfnReadBytes(pCpu, &bTemp, uAddress, sizeof(bTemp));
     2624    if (RT_FAILURE(rc))
     2625    {
     2626        Log(("DISReadByte failed!!\n"));
     2627        pCpu->rc = VERR_DIS_MEM_READ;
     2628    }
     2629
     2630/** @todo change this into reading directly into abInstr and use it as a
     2631 *        cache. */
     2632    if (RT_LIKELY(   pCpu->uInstrAddr + pCpu->opsize == uAddress
     2633                  && pCpu->opsize + sizeof(bTemp) < sizeof(pCpu->abInstr)))
     2634        pCpu->abInstr[pCpu->opsize++] = bTemp;
     2635    else
     2636        disStoreInstrBytesSlow(pCpu, uAddress, &bTemp, sizeof(bTemp));
     2637
     2638    return bTemp;
     2639}
     2640//*****************************************************************************
     2641//*****************************************************************************
     2642uint16_t DISReadWord(PDISCPUSTATE pCpu, RTUINTPTR uAddress)
     2643{
     2644    RTUINT16U uTemp;
     2645    uTemp.u = 0;
     2646    int rc = pCpu->pfnReadBytes(pCpu, uTemp.au8, uAddress, sizeof(uTemp));
     2647    if (RT_FAILURE(rc))
     2648    {
     2649        Log(("DISReadWord failed!!\n"));
     2650        pCpu->rc = VERR_DIS_MEM_READ;
     2651    }
     2652
     2653    if (RT_LIKELY(   pCpu->uInstrAddr + pCpu->opsize == uAddress
     2654                  && pCpu->opsize + sizeof(uTemp) < sizeof(pCpu->abInstr)))
     2655    {
     2656        pCpu->abInstr[pCpu->opsize    ] = uTemp.au8[0];
     2657        pCpu->abInstr[pCpu->opsize + 1] = uTemp.au8[1];
     2658        pCpu->opsize += 2;
     2659    }
     2660    else
     2661        disStoreInstrBytesSlow(pCpu, uAddress, uTemp.au8, sizeof(uTemp));
     2662
     2663    return uTemp.u;
     2664}
     2665//*****************************************************************************
     2666//*****************************************************************************
     2667uint32_t DISReadDWord(PDISCPUSTATE pCpu, RTUINTPTR uAddress)
     2668{
     2669    RTUINT32U uTemp;
     2670    uTemp.u = 0;
     2671    int rc = pCpu->pfnReadBytes(pCpu, uTemp.au8, uAddress, sizeof(uTemp));
     2672    if (RT_FAILURE(rc))
     2673    {
     2674        Log(("DISReadDWord failed!!\n"));
     2675        pCpu->rc = VERR_DIS_MEM_READ;
     2676    }
     2677
     2678    if (RT_LIKELY(   pCpu->uInstrAddr + pCpu->opsize == uAddress
     2679                  && pCpu->opsize + sizeof(uTemp) < sizeof(pCpu->abInstr)))
     2680    {
     2681        pCpu->abInstr[pCpu->opsize    ] = uTemp.au8[0];
     2682        pCpu->abInstr[pCpu->opsize + 1] = uTemp.au8[1];
     2683        pCpu->abInstr[pCpu->opsize + 2] = uTemp.au8[2];
     2684        pCpu->abInstr[pCpu->opsize + 3] = uTemp.au8[3];
     2685        pCpu->opsize += 4;
     2686    }
     2687    else
     2688        disStoreInstrBytesSlow(pCpu, uAddress, uTemp.au8, sizeof(uTemp));
     2689
     2690    return uTemp.u;
     2691}
     2692//*****************************************************************************
     2693//*****************************************************************************
     2694uint64_t DISReadQWord(PDISCPUSTATE pCpu, RTUINTPTR uAddress)
     2695{
     2696    RTUINT64U uTemp;
     2697    uTemp.u = 0;
     2698    int rc = pCpu->pfnReadBytes(pCpu, uTemp.au8, uAddress, sizeof(uTemp));
     2699    if (RT_FAILURE(rc))
     2700    {
     2701        Log(("DISReadQWord %x failed!!\n", uAddress));
     2702        pCpu->rc = VERR_DIS_MEM_READ;
     2703    }
     2704
     2705    if (RT_LIKELY(   pCpu->uInstrAddr + pCpu->opsize == uAddress
     2706                  && pCpu->opsize + sizeof(uTemp) < sizeof(pCpu->abInstr)))
     2707    {
     2708        pCpu->abInstr[pCpu->opsize    ] = uTemp.au8[0];
     2709        pCpu->abInstr[pCpu->opsize + 1] = uTemp.au8[1];
     2710        pCpu->abInstr[pCpu->opsize + 2] = uTemp.au8[2];
     2711        pCpu->abInstr[pCpu->opsize + 3] = uTemp.au8[3];
     2712        pCpu->abInstr[pCpu->opsize + 4] = uTemp.au8[4];
     2713        pCpu->abInstr[pCpu->opsize + 5] = uTemp.au8[5];
     2714        pCpu->abInstr[pCpu->opsize + 6] = uTemp.au8[6];
     2715        pCpu->abInstr[pCpu->opsize + 7] = uTemp.au8[7];
     2716        pCpu->opsize += 4;
     2717    }
     2718    else
     2719        disStoreInstrBytesSlow(pCpu, uAddress, uTemp.au8, sizeof(uTemp));
     2720
     2721    return uTemp.u;
    27092722}
    27102723
  • trunk/src/VBox/Disassembler/DisasmFormatBytes.cpp

    r28800 r41658  
    55
    66/*
    7  * Copyright (C) 2008 Oracle Corporation
     7 * Copyright (C) 2008-2012 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3838size_t disFormatBytes(PCDISCPUSTATE pCpu, char *pszDst, size_t cchDst, uint32_t fFlags)
    3939{
    40     /*
    41      * Read the bytes first.
    42      */
    43     uint8_t     ab[16];
    44     uint32_t    cb = pCpu->opsize;
    45     Assert(cb <= 16);
    46     if (cb > 16)
    47         cb = 16;
     40    size_t      cchOutput = 0;
     41    uint32_t    cb        = pCpu->opsize;
     42    AssertStmt(cb <= 16, cb = 16);
    4843
    49     if (pCpu->pfnReadBytes)
    50     {
    51         int rc = pCpu->pfnReadBytes(pCpu->opaddr, &ab[0], cb, (void *)pCpu);
    52         if (RT_FAILURE(rc))
    53         {
    54             for (uint32_t i = 0; i < cb; i++)
    55             {
    56                 int rc2 = pCpu->pfnReadBytes(pCpu->opaddr + i, &ab[i], 1, (void *)pCpu);
    57                 if (RT_FAILURE(rc2))
    58                     ab[i] = 0xcc;
    59             }
    60         }
    61     }
    62     else
    63     {
    64         uint8_t const *pabSrc = (uint8_t const *)(uintptr_t)pCpu->opaddr;
    65         for (uint32_t i = 0; i < cb; i++)
    66             ab[i] = pabSrc[i];
    67     }
    68 
    69     /*
    70      * Now for the output.
    71      */
    72     size_t cchOutput = 0;
    7344#define PUT_C(ch) \
    7445            do { \
     
    9869    {
    9970        if (i != 0 && (fFlags & DIS_FMT_FLAGS_BYTES_SPACED))
    100             PUT_NUM(3, " %02x", ab[i]);
     71            PUT_NUM(3, " %02x", pCpu->abInstr[i]);
    10172        else
    102             PUT_NUM(2, "%02x", ab[i]);
     73            PUT_NUM(2, "%02x", pCpu->abInstr[i]);
    10374    }
    10475
  • trunk/src/VBox/Disassembler/DisasmFormatYasm.cpp

    r41505 r41658  
    689689                                PUT_SZ("word ");
    690690                            else if (   (pParam->flags & USE_DISPLACEMENT32)
    691                                      && (int8_t)pParam->disp32 == (int32_t)pParam->disp32)
     691                                     && (int16_t)pParam->disp32 == (int32_t)pParam->disp32) //??
    692692                                PUT_SZ("dword ");
    693693                            else if (   (pParam->flags & USE_DISPLACEMENT64)
    694                                      && (int8_t)pParam->disp64 == (int64_t)pParam->disp32)
     694                                     && (pCpu->SIB.Bits.Base != 5 || pCpu->ModRM.Bits.Mod != 0)
     695                                     && (int32_t)pParam->disp64 == (int64_t)pParam->disp64) //??
    695696                                PUT_SZ("qword ");
    696697                        }
     
    12311232    {
    12321233        uint32_t f;
    1233         switch (DISReadByte(pCpu, offOpcode + pCpu->opaddr))
     1234        switch (pCpu->abInstr[offOpcode])
    12341235        {
    12351236            case 0xf0:
  • trunk/src/VBox/Disassembler/DisasmInternal.h

    r40577 r41658  
    7070#define IDX_ParseImmAddrF           40
    7171#define IDX_ParseMax                (IDX_ParseImmAddrF+1)
    72 
    73 #if defined(IN_RING0) || defined(IN_RC)
    74 #define DIS_THROW(a)                /* Not available. */
    75 #elif  __L4ENV__
    76 #define DIS_THROW(a)                longjmp(*pCpu->pJumpBuffer, a)
    77 #else
    78 #define DIS_THROW(a)                throw(a)
    79 #endif
    8072
    8173
     
    161153
    162154/* Read functions */
     155DECLCALLBACK(int) disReadBytesDefault(PDISCPUSTATE pCpu, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead);
    163156uint8_t  DISReadByte(PDISCPUSTATE pCpu, RTUINTPTR pAddress);
    164157uint16_t DISReadWord(PDISCPUSTATE pCpu, RTUINTPTR pAddress);
  • trunk/src/VBox/Disassembler/DisasmTest.cpp

    r28800 r41658  
    4848            unsigned    cb;
    4949            DISCPUSTATE cpu;
    50             char         szOutput[256];
     50            char        szOutput[256];
    5151
    52             memset(&cpu, 0, sizeof(cpu));
    53             cpu.mode = CPUMODE_32BIT;
    54             if (RT_SUCCESS(DISInstr(&cpu, pInstr, 0, &cb, szOutput)))
     52            if (RT_SUCCESS(DISInstr(pInstr, CPUMODE_32BIT, &cpu, &cb, szOutput)))
    5553            {
    5654                printf("%s", szOutput);
     
    7371            unsigned    cb;
    7472            DISCPUSTATE cpu;
    75             char         szOutput[256];
     73            char        szOutput[256];
    7674
    77             memset(&cpu, 0, sizeof(cpu));
    78             cpu.mode = CPUMODE_64BIT;
    79             if (RT_SUCCESS(DISInstr(&cpu, pInstr, 0, &cb, szOutput)))
     75            if (RT_SUCCESS(DISInstr(pInstr, CPUMODE_64BIT, &cpu, &cb, szOutput)))
    8076                printf("%s", szOutput);
    8177            else
  • trunk/src/VBox/Disassembler/DisasmTestCore.cpp

    r28800 r41658  
    3939        unsigned    cb;
    4040        DISCPUSTATE cpu;
    41         cpu.mode = CPUMODE_32BIT;
    42         if (DISCoreOne(&cpu, (uintptr_t)&DISCoreOne, &cb))
     41        if (DISCoreOneEx((uintptr_t)&DISCoreOneEx, CPUMODE_32BIT, NULL /*pfnReadBytes*/, NULL /*pvUser*/, &cpu, &cb))
    4342            printf("ok %d\n", cpu.addrmode);
    4443        else
  • trunk/src/VBox/Disassembler/testcase/Makefile.kmk

    r41477 r41658  
    6060#       $(PATH_STAGE_BIN)/testcase/tstDisasm-2$(SUFF_EXEC)
    6161endif
     62VBOX_DISAS_TESTS_BINARIES_NOT_16BIT := \
     63        tstBinFnstsw-1.bin
     64VBOX_DISAS_TESTS_BINARIES_NOT_32BIT :=
     65VBOX_DISAS_TESTS_BINARIES_NOT_64BIT :=
    6266
    6367
     
    195199
    196200## @todo 64-bit is problematic because of bugs like POP RDI ending up as POP EDI (incorrect default opmode).
    197 #$(foreach bits, 32 16 64, $(foreach binary, $(VBOX_DISAS_TESTS_BINARIES), $(evalvalctx def_vbox_disas_binary)))
    198 $(foreach bits, 32 16, $(foreach binary, $(VBOX_DISAS_TESTS_BINARIES), $(evalvalctx def_vbox_disas_binary)))
     201#$(foreach bits, 64, $(foreach binary, $(VBOX_DISAS_TESTS_BINARIES), $(evalvalctx def_vbox_disas_binary)))
     202$(foreach bits, 32 16, $(foreach binary, $(filter-out $(VBOX_DISAS_TESTS_BINARIES_NOT_$(bits)BIT), $(VBOX_DISAS_TESTS_BINARIES)) \
     203        , $(evalvalctx def_vbox_disas_binary)))
    199204
    200205
  • trunk/src/VBox/Disassembler/testcase/tstDisasm-2.cpp

    r41501 r41658  
    171171 *       however the current doesn't do this and is just complicated...
    172172 */
    173 static DECLCALLBACK(int) MyDisasInstrRead(RTUINTPTR uSrcAddr, uint8_t *pbDst, uint32_t cbRead, void *pvDisCpu)
    174 {
    175     PMYDISSTATE pState = (PMYDISSTATE)pvDisCpu;
     173static DECLCALLBACK(int) MyDisasInstrRead(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead)
     174{
     175    PMYDISSTATE pState = (PMYDISSTATE)pDisState;
    176176    if (RT_LIKELY(   pState->uNextAddr == uSrcAddr
    177                   && pState->cbLeft >= cbRead))
     177                  && pState->cbLeft >= cbToRead))
    178178    {
    179179        /*
    180180         * Straight forward reading.
    181181         */
    182         if (cbRead == 1)
     182        if (cbToRead == 1)
    183183        {
    184184            pState->cbLeft--;
     
    188188        else
    189189        {
    190             memcpy(pbDst, pState->pbNext, cbRead);
    191             pState->pbNext += cbRead;
    192             pState->cbLeft -= cbRead;
    193             pState->uNextAddr += cbRead;
     190            memcpy(pbDst, pState->pbNext, cbToRead);
     191            pState->pbNext += cbToRead;
     192            pState->cbLeft -= cbToRead;
     193            pState->uNextAddr += cbToRead;
    194194        }
    195195    }
     
    211211                pState->cbLeft = 0;
    212212
    213                 memset(pbDst, 0xcc, cbRead);
     213                memset(pbDst, 0xcc, cbToRead);
    214214                pState->rc = VERR_EOF;
    215215                return VERR_EOF;
     
    227227
    228228            /* do the reading. */
    229             if (pState->cbLeft >= cbRead)
    230             {
    231                 memcpy(pbDst, pState->pbNext, cbRead);
    232                 pState->cbLeft -= cbRead;
    233                 pState->pbNext += cbRead;
    234                 pState->uNextAddr += cbRead;
     229            if (pState->cbLeft >= cbToRead)
     230            {
     231                memcpy(pbDst, pState->pbNext, cbToRead);
     232                pState->cbLeft -= cbToRead;
     233                pState->pbNext += cbToRead;
     234                pState->uNextAddr += cbToRead;
    235235            }
    236236            else
     
    240240                    memcpy(pbDst, pState->pbNext, pState->cbLeft);
    241241                    pbDst += pState->cbLeft;
    242                     cbRead -= (uint32_t)pState->cbLeft;
     242                    cbToRead -= (uint32_t)pState->cbLeft;
    243243                    pState->pbNext += pState->cbLeft;
    244244                    pState->uNextAddr += pState->cbLeft;
    245245                    pState->cbLeft = 0;
    246246                }
    247                 memset(pbDst, 0xcc, cbRead);
     247                memset(pbDst, 0xcc, cbToRead);
    248248                pState->rc = VERR_EOF;
    249249                return VERR_EOF;
     
    253253        {
    254254            RTStrmPrintf(g_pStdErr, "Reading before current instruction!\n");
    255             memset(pbDst, 0x90, cbRead);
     255            memset(pbDst, 0x90, cbToRead);
    256256            pState->rc = VERR_INTERNAL_ERROR;
    257257            return VERR_INTERNAL_ERROR;
     
    286286     */
    287287    MYDISSTATE State;
    288     State.Cpu.mode = enmCpuMode;
    289     State.Cpu.pfnReadBytes = MyDisasInstrRead;
    290288    State.uAddress = uAddress;
    291289    State.pbInstr = pbFile;
     
    331329        State.pbNext = State.pbInstr;
    332330
    333         int rc = DISInstr(&State.Cpu, State.uAddress, 0, &State.cbInstr, State.szLine);
     331
     332        int rc = DISInstrWithReader(State.uAddress, enmCpuMode, MyDisasInstrRead, &State,
     333                                    &State.Cpu, &State.cbInstr, State.szLine);
    334334        if (    RT_SUCCESS(rc)
    335335            ||  (   (   rc == VERR_DIS_INVALID_OPCODE
     
    345345            if (State.fUndefOp && State.enmUndefOp == kUndefOp_DefineByte)
    346346            {
     347                if (!State.cbInstr)
     348                {
     349                    State.Cpu.abInstr[0] = 0;
     350                    State.Cpu.pfnReadBytes(&State.Cpu, &State.Cpu.abInstr[0], State.uAddress, 1);
     351                    State.cbInstr = 1;
     352                }
    347353                RTPrintf("    db");
    348                 if (!State.cbInstr)
    349                     State.cbInstr = 1;
    350354                for (unsigned off = 0; off < State.cbInstr; off++)
    351                 {
    352                     uint8_t b;
    353                     State.Cpu.pfnReadBytes(State.uAddress + off, &b, 1, &State.Cpu);
    354                     RTPrintf(off ? ", %03xh" : " %03xh", b);
    355                 }
     355                    RTPrintf(off ? ", %03xh" : " %03xh", State.Cpu.abInstr[off]);
    356356                RTPrintf("    ; %s\n", State.szLine);
    357357            }
     
    376376                    RTPrintf("    db");
    377377                    for (unsigned off = 0; off < State.cbInstr; off++)
    378                     {
    379                         uint8_t b;
    380                         State.Cpu.pfnReadBytes(State.uAddress + off, &b, 1, &State.Cpu);
    381                         RTPrintf(off ? ", %03xh" : " %03xh", b);
    382                     }
     378                        RTPrintf(off ? ", %03xh" : " %03xh", State.Cpu.abInstr[off]);
    383379                    RTPrintf(" ; ");
    384380                }
  • trunk/src/VBox/Runtime/testcase/tstLdr-2.cpp

    r38636 r41658  
    4646        char        szOutput[256];
    4747        uint32_t    cbInstr;
    48         if (RT_FAILURE(DISInstr(pCpu, pvCodeBlock + i, off, &cbInstr, szOutput)))
     48        if (RT_FAILURE(DISInstrWithOff(pCpu, pvCodeBlock + i, off, &cbInstr, szOutput)))
    4949            return false;
    5050
  • trunk/src/VBox/Runtime/testcase/tstLdr-3.cpp

    r41078 r41658  
    144144
    145145
    146 static DECLCALLBACK(int) MyReadBytes(RTUINTPTR uSrc, uint8_t *pbDst, unsigned cb, void *pvUser)
    147 {
    148     PDISCPUSTATE pCpu = (PDISCPUSTATE)pvUser;
    149     memcpy(pbDst, (uint8_t const *)((uintptr_t)uSrc + (uintptr_t)pCpu->apvUserData[0]), cb);
     146/**
     147 * @callback_method_impl{FNDISREADBYTES}
     148 */
     149static DECLCALLBACK(int) MyReadBytes(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead)
     150{
     151    memcpy(pbDst, (uint8_t const *)((uintptr_t)uSrcAddr + (uintptr_t)pDisState->apvUserData[0]), cbToRead);
    150152    return VINF_SUCCESS;
    151153}
  • trunk/src/VBox/Runtime/testcase/tstLdrDisasmTest.cpp

    r39083 r41658  
    8080
    8181
    82 DECLCALLBACK(int) DisasmTest1ReadCode(RTUINTPTR SrcAddr, uint8_t *pbDst, uint32_t cb, void *pvUser)
     82/**
     83 * @callback_method_impl{FNDISREADBYTES}
     84 */
     85static DECLCALLBACK(int) DisasmTest1ReadCode(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead)
    8386{
    84     NOREF(pvUser);
    85     while (cb > 0)
     87    NOREF(pDisState);
     88    while (cbToRead > 0)
    8689    {
    87         *pbDst = g_ab32BitCode[SrcAddr];
     90        *pbDst = g_ab32BitCode[uSrcAddr];
     91
    8892        /* next */
    8993        pbDst++;
    90         SrcAddr++;
    91         cb--;
     94        uSrcAddr++;
     95        cbToRead--;
    9296    }
    9397    return 0;
  • trunk/src/VBox/Runtime/testcase/tstLdrObj.cpp

    r39083 r41658  
    9898    static unsigned cb;
    9999    DISCPUSTATE Cpu;
    100     memset(&Cpu, 0, sizeof(Cpu));
    101     Cpu.mode = CPUMODE_32BIT;
    102     DISCoreOne(&Cpu, (uintptr_t)SomeExportFunction3, &cb);
     100    DISCoreOneEx((uintptr_t)SomeExportFunction3, CPUMODE_32BIT, NULL /*pfnReadBytes*/, NULL /*pvUser*/, &Cpu, &cb);
    103101    return (void *)(uintptr_t)&SomeExportFunction1;
    104102}
  • trunk/src/VBox/Runtime/testcase/tstLdrObjR0.cpp

    r39083 r41658  
    9898    Cpu.mode = CPUMODE_32BIT;
    9999
    100     DISCoreOne(&Cpu, (uintptr_t)SomeExportFunction3, &cb);
     100    DISCoreOneEx((uintptr_t)SomeExportFunction3, CPUMODE_32BIT, NULL /*pfnReadBytes*/, NULL /*pvUser*/, &Cpu, &cb);
    101101    return (void *)(uintptr_t)&SomeExportFunction1;
    102102}
  • trunk/src/VBox/VMM/VMMAll/EMAll.cpp

    r41072 r41658  
    55
    66/*
    7  * Copyright (C) 2006-2007 Oracle Corporation
     7 * Copyright (C) 2006-2012 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    282282
    283283/**
    284  * Read callback for disassembly function; supports reading bytes that cross a page boundary
    285  *
    286  * @returns VBox status code.
    287  * @param   pSrc        GC source pointer
    288  * @param   pDest       HC destination pointer
    289  * @param   cb          Number of bytes to read
    290  * @param   dwUserdata  Callback specific user data (pDis)
    291  *
    292  */
    293 static DECLCALLBACK(int) emReadBytes(RTUINTPTR pSrc, uint8_t *pDest, unsigned cb, void *pvUserdata)
    294 {
    295     PDISCPUSTATE  pDis   = (PDISCPUSTATE)pvUserdata;
    296     PEMDISSTATE   pState = (PEMDISSTATE)pDis->apvUserData[0];
     284 * @callback_method_impl{FNDISREADBYTES}
     285 */
     286static DECLCALLBACK(int) emReadBytes(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead)
     287{
     288    PEMDISSTATE   pState = (PEMDISSTATE)pDisState->apvUserData[0];
    297289# ifndef IN_RING0
    298290    PVM           pVM    = pState->pVM;
     
    304296
    305297    if (    pState->GCPtr
    306         &&  pSrc + cb <= pState->GCPtr + sizeof(pState->aOpcode))
    307     {
    308         unsigned offset = pSrc - pState->GCPtr;
    309         Assert(pSrc >= pState->GCPtr);
    310 
    311         for (unsigned i = 0; i < cb; i++)
    312             pDest[i] = pState->aOpcode[offset + i];
     298        &&  uSrcAddr + cbToRead <= pState->GCPtr + sizeof(pState->aOpcode))
     299    {
     300        unsigned offset = uSrcAddr - pState->GCPtr;
     301        Assert(uSrcAddr >= pState->GCPtr);
     302
     303        for (unsigned i = 0; i < cbToRead; i++)
     304            pbDst[i] = pState->aOpcode[offset + i];
    313305        return VINF_SUCCESS;
    314306    }
    315307
    316     rc = PGMPhysSimpleReadGCPtr(pVCpu, pDest, pSrc, cb);
    317     AssertMsgRC(rc, ("PGMPhysSimpleReadGCPtr failed for pSrc=%RGv cb=%x rc=%d\n", pSrc, cb, rc));
     308    rc = PGMPhysSimpleReadGCPtr(pVCpu, pbDst, uSrcAddr, cbToRead);
     309    AssertMsgRC(rc, ("PGMPhysSimpleReadGCPtr failed for uSrcAddr=%RTptr cbToRead=%x rc=%d\n", uSrcAddr, cbToRead, rc));
    318310# elif defined(IN_RING3)
    319     if (!PATMIsPatchGCAddr(pVM, pSrc))
    320     {
    321         int rc = PGMPhysSimpleReadGCPtr(pVCpu, pDest, pSrc, cb);
     311    if (!PATMIsPatchGCAddr(pVM, uSrcAddr))
     312    {
     313        int rc = PGMPhysSimpleReadGCPtr(pVCpu, pbDst, uSrcAddr, cbToRead);
    322314        AssertRC(rc);
    323315    }
    324316    else
    325         memcpy(pDest, PATMR3GCPtrToHCPtr(pVM, pSrc), cb);
     317        memcpy(pbDst, PATMR3GCPtrToHCPtr(pVM, uSrcAddr), cbToRead);
    326318
    327319# elif defined(IN_RC)
    328     if (!PATMIsPatchGCAddr(pVM, pSrc))
    329     {
    330         int rc = MMGCRamRead(pVM, pDest, (void *)(uintptr_t)pSrc, cb);
     320    if (!PATMIsPatchGCAddr(pVM, uSrcAddr))
     321    {
     322        int rc = MMGCRamRead(pVM, pbDst, (void *)(uintptr_t)uSrcAddr, cbToRead);
    331323        if (rc == VERR_ACCESS_DENIED)
    332324        {
    333325            /* Recently flushed; access the data manually. */
    334             rc = PGMPhysSimpleReadGCPtr(pVCpu, pDest, pSrc, cb);
     326            rc = PGMPhysSimpleReadGCPtr(pVCpu, pbDst, uSrcAddr, cbToRead);
    335327            AssertRC(rc);
    336328        }
    337329    }
    338330    else /* the hypervisor region is always present. */
    339         memcpy(pDest, (RTRCPTR)(uintptr_t)pSrc, cb);
     331        memcpy(pbDst, (RTRCPTR)(uintptr_t)uSrcAddr, cbToRead);
    340332
    341333# endif /* IN_RING3 */
     
    343335}
    344336
    345 
    346337#ifndef IN_RC
     338
    347339DECLINLINE(int) emDisCoreOne(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pDis, RTGCUINTPTR InstrGC, uint32_t *pOpsize)
    348340{
     
    467459#endif
    468460
    469     rc = DISCoreOneEx(GCPtrInstr, SELMGetCpuModeFromSelector(pVCpu, pCtxCore->eflags, pCtxCore->cs, (PCPUMSELREGHID)&pCtxCore->csHid),
     461    rc = DISCoreOneEx(GCPtrInstr,
     462                      SELMGetCpuModeFromSelector(pVCpu, pCtxCore->eflags, pCtxCore->cs, (PCPUMSELREGHID)&pCtxCore->csHid),
    470463                      emReadBytes, &State,
    471464                      pDis, pcbInstr);
     
    659652    Assert(!CPUMIsGuestIn64BitCode(pVCpu, pRegFrame));
    660653    /** @todo Rainy day: Test what happens when VERR_EM_INTERPRETER is returned by
    661      *        this function.  Faire that it may guru on us, thus not converted to
     654     *        this function.  Fear that it may guru on us, thus not converted to
    662655     *        IEM. */
    663656
  • trunk/src/VBox/VMM/VMMR3/CPUM.cpp

    r41310 r41658  
    906906            pCPUM->aGuestCpuIdCentaur[i] = pCPUM->GuestCpuIdDef;
    907907
    908     /* 
     908    /*
    909909     * Hypervisor identification.
    910910     *
     
    35253525
    35263526/**
    3527  * Instruction reader.
    3528  *
    3529  * @returns VBox status code.
    3530  * @param   PtrSrc      Address to read from.
    3531  *                      In our case this is relative to the selector pointed to by the 2nd user argument of uDisCpu.
    3532  * @param   pu8Dst      Where to store the bytes.
    3533  * @param   cbRead      Number of bytes to read.
    3534  * @param   uDisCpu     Pointer to the disassembler cpu state.
    3535  *                      In this context it's always pointer to the Core of a DBGFDISASSTATE.
    3536  */
    3537 static DECLCALLBACK(int) cpumR3DisasInstrRead(RTUINTPTR PtrSrc, uint8_t *pu8Dst, unsigned cbRead, void *uDisCpu)
    3538 {
    3539     PDISCPUSTATE pCpu = (PDISCPUSTATE)uDisCpu;
    3540     PCPUMDISASSTATE pState = (PCPUMDISASSTATE)pCpu->apvUserData[0];
    3541     Assert(cbRead > 0);
     3527 * @callback_method_impl{FNDISREADBYTES}
     3528 */
     3529static DECLCALLBACK(int) cpumR3DisasInstrRead(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead)
     3530{
     3531    PCPUMDISASSTATE pState = (PCPUMDISASSTATE)pDisState->apvUserData[0];
     3532    Assert(cbToRead > 0);
    35423533    for (;;)
    35433534    {
    3544         RTGCUINTPTR GCPtr = PtrSrc + pState->GCPtrSegBase;
     3535        RTGCUINTPTR GCPtr = uSrcAddr + pState->GCPtrSegBase;
    35453536
    35463537        /* Need to update the page translation? */
     
    35753566
    35763567        /* check the segment limit */
    3577         if (!pState->f64Bits && PtrSrc > pState->cbSegLimit)
     3568        if (!pState->f64Bits && uSrcAddr > pState->cbSegLimit)
    35783569            return VERR_OUT_OF_SELECTOR_BOUNDS;
    35793570
     
    35863577                cb = cbSeg;
    35873578        }
    3588         if (cb > cbRead)
    3589             cb = cbRead;
     3579        if (cb > cbToRead)
     3580            cb = cbToRead;
    35903581
    35913582        /* read and advance */
    3592         memcpy(pu8Dst, (char *)pState->pvPageR3 + (GCPtr & PAGE_OFFSET_MASK), cb);
    3593         cbRead -= cb;
    3594         if (!cbRead)
     3583        memcpy(pbDst, (char *)pState->pvPageR3 + (GCPtr & PAGE_OFFSET_MASK), cb);
     3584        cbToRead -= cb;
     3585        if (!cbToRead)
    35953586            return VINF_SUCCESS;
    3596         pu8Dst += cb;
    3597         PtrSrc += cb;
     3587        pbDst    += cb;
     3588        uSrcAddr += cb;
    35983589    }
    35993590}
     
    36293620     * Get selector information.
    36303621     */
     3622    DISCPUMODE enmDisCpuMode;
    36313623    if (    (pCtx->cr0 & X86_CR0_PE)
    36323624        &&   pCtx->eflags.Bits.u1VM == 0)
     
    36383630            State.GCPtrSegEnd     = pCtx->csHid.u32Limit + 1 + (RTGCUINTPTR)pCtx->csHid.u64Base;
    36393631            State.cbSegLimit      = pCtx->csHid.u32Limit;
    3640             pCpu->mode            = (State.f64Bits)
     3632            enmDisCpuMode         = (State.f64Bits)
    36413633                                    ? CPUMODE_64BIT
    36423634                                    : pCtx->csHid.Attr.n.u1DefBig
     
    36673659            State.GCPtrSegEnd     = SelInfo.cbLimit + 1 + (RTGCUINTPTR)SelInfo.GCPtrBase;
    36683660            State.cbSegLimit      = SelInfo.cbLimit;
    3669             pCpu->mode            = SelInfo.u.Raw.Gen.u1DefBig ? CPUMODE_32BIT : CPUMODE_16BIT;
     3661            enmDisCpuMode         = SelInfo.u.Raw.Gen.u1DefBig ? CPUMODE_32BIT : CPUMODE_16BIT;
    36703662        }
    36713663    }
     
    36733665    {
    36743666        /* real or V86 mode */
    3675         pCpu->mode            = CPUMODE_16BIT;
     3667        enmDisCpuMode         = CPUMODE_16BIT;
    36763668        State.GCPtrSegBase    = pCtx->cs * 16;
    36773669        State.GCPtrSegEnd     = 0xFFFFFFFF;
     
    36823674     * Disassemble the instruction.
    36833675     */
    3684     pCpu->pfnReadBytes    = cpumR3DisasInstrRead;
    3685     pCpu->apvUserData[0]  = &State;
    3686 
    36873676    uint32_t cbInstr;
    36883677#ifndef LOG_ENABLED
    3689     rc = DISInstr(pCpu, GCPtrPC, 0, &cbInstr, NULL);
     3678    rc = DISInstrWithReader(GCPtrPC, enmDisCpuMode, cpumR3DisasInstrRead, &State, pCpu, &cbInstr, NULL);
    36903679    if (RT_SUCCESS(rc))
    36913680    {
    36923681#else
    36933682    char szOutput[160];
    3694     rc = DISInstr(pCpu, GCPtrPC, 0, &cbInstr, &szOutput[0]);
     3683    rc = DISInstrWithReader(GCPtrPC, enmDisCpuMode, cpumR3DisasInstrRead, &State, pCpu, &cbInstr, szOutput);
    36953684    if (RT_SUCCESS(rc))
    36963685    {
  • trunk/src/VBox/VMM/VMMR3/CSAM.cpp

    r40449 r41658  
    724724
    725725/**
    726  * Read callback for disassembly function; supports reading bytes that cross a page boundary
    727  *
    728  * @returns VBox status code.
    729  * @param   pSrc        GC source pointer
    730  * @param   pDest       HC destination pointer
    731  * @param   size        Number of bytes to read
    732  * @param   dwUserdata  Callback specific user data (pCpu)
    733  *
    734  */
    735 static DECLCALLBACK(int) CSAMR3ReadBytes(RTUINTPTR pSrc, uint8_t *pDest, unsigned size, void *pvUserdata)
    736 {
    737     DISCPUSTATE  *pCpu     = (DISCPUSTATE *)pvUserdata;
    738     PVM           pVM      = (PVM)pCpu->apvUserData[0];
    739     RTHCUINTPTR   pInstrHC = (RTHCUINTPTR)pCpu->apvUserData[1];
    740     RTGCUINTPTR32 pInstrGC = (uintptr_t)pCpu->apvUserData[2];
    741     int           orgsize  = size;
    742     Assert(pVM->cCpus == 1);
    743     PVMCPU        pVCpu = VMMGetCpu0(pVM);
    744 
    745     /* We are not interested in patched instructions, so read the original opcode bytes. */
    746     /** @note single instruction patches (int3) are checked in CSAMR3AnalyseCallback */
    747     for (int i=0;i<orgsize;i++)
    748     {
    749         int rc = PATMR3QueryOpcode(pVM, (RTRCPTR)pSrc, pDest);
    750         if (RT_SUCCESS(rc))
    751         {
    752             pSrc++;
    753             pDest++;
    754             size--;
    755         }
    756         else
     726 * @callback_method_impl{FNDISREADBYTES}
     727 */
     728static DECLCALLBACK(int) CSAMR3ReadBytes(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead)
     729{
     730    PVM           pVM      = (PVM)pDisState->apvUserData[0];
     731    RTHCUINTPTR   pInstrHC = (RTHCUINTPTR)pDisState->apvUserData[1];
     732    RTGCUINTPTR32 pInstrGC = pDisState->uInstrAddr;
     733    int           orgsize  = cbToRead;
     734    PVMCPU        pVCpu    = VMMGetCpu0(pVM);
     735
     736    /* We are not interested in patched instructions, so read the original opcode bytes.
     737       Note! single instruction patches (int3) are checked in CSAMR3AnalyseCallback */
     738    for (int i = 0; i < orgsize; i++)
     739    {
     740        int rc = PATMR3QueryOpcode(pVM, (RTRCPTR)uSrcAddr, pbDst);
     741        if (RT_FAILURE(rc))
    757742            break;
    758     }
    759     if (size == 0)
     743        uSrcAddr++;
     744        pbDst++;
     745        cbToRead--;
     746    }
     747    if (cbToRead == 0)
    760748        return VINF_SUCCESS;
    761749
    762     if (PAGE_ADDRESS(pInstrGC) != PAGE_ADDRESS(pSrc + size - 1) && !PATMIsPatchGCAddr(pVM, pSrc))
    763     {
    764         return PGMPhysSimpleReadGCPtr(pVCpu, pDest, pSrc, size);
    765     }
    766     else
    767     {
    768         Assert(pInstrHC);
    769 
    770         /* pInstrHC is the base address; adjust according to the GC pointer. */
    771         pInstrHC = pInstrHC + (pSrc - pInstrGC);
    772 
    773         memcpy(pDest, (void *)pInstrHC, size);
    774     }
     750    if (PAGE_ADDRESS(pInstrGC) != PAGE_ADDRESS(uSrcAddr + cbToRead - 1) && !PATMIsPatchGCAddr(pVM, uSrcAddr))
     751        return PGMPhysSimpleReadGCPtr(pVCpu, pbDst, uSrcAddr, cbToRead);
     752
     753    Assert(pInstrHC);
     754
     755    /* pInstrHC is the base address; adjust according to the GC pointer. */
     756    pInstrHC = pInstrHC + (uSrcAddr - pInstrGC);
     757
     758    memcpy(pbDst, (void *)pInstrHC, cbToRead);
    775759
    776760    return VINF_SUCCESS;
    777761}
    778762
    779 inline int CSAMR3DISInstr(PVM pVM, DISCPUSTATE *pCpu, RTRCPTR InstrGC, uint8_t *InstrHC, uint32_t *pOpsize, char *pszOutput)
    780 {
    781     (pCpu)->pfnReadBytes  = CSAMR3ReadBytes;
    782     (pCpu)->apvUserData[0] = pVM;
     763DECLINLINE(int) CSAMR3DISInstr(PVM pVM, RTRCPTR InstrGC, uint8_t *InstrHC, DISCPUMODE enmCpuMode,
     764                               PDISCPUSTATE pCpu, uint32_t *pcbInstr, char *pszOutput)
     765{
    783766    (pCpu)->apvUserData[1] = InstrHC;
    784767    (pCpu)->apvUserData[2] = (void *)(uintptr_t)InstrGC; Assert(sizeof(InstrGC) <= sizeof(pCpu->apvUserData[0]));
    785768#ifdef DEBUG
    786     return DISInstrEx(pCpu, InstrGC, 0, pOpsize, pszOutput, OPTYPE_ALL);
     769    return DISInstrEx(InstrGC, 0, enmCpuMode, CSAMR3ReadBytes, pVM, OPTYPE_ALL,
     770                      pCpu, pcbInstr, pszOutput);
    787771#else
    788772    /* We are interested in everything except harmless stuff */
    789     return DISInstrEx(pCpu, InstrGC, 0, pOpsize, pszOutput, ~(OPTYPE_INVALID | OPTYPE_HARMLESS | OPTYPE_RRM_MASK));
     773    return DISInstrEx(InstrGC, 0, enmCpuMode, CSAMR3ReadBytes, pVM, ~(OPTYPE_INVALID | OPTYPE_HARMLESS | OPTYPE_RRM_MASK),
     774                      pCpu, pcbInstr, pszOutput);
    790775#endif
    791776}
     
    883868                Assert(VALID_PTR(pCurInstrHC));
    884869
    885                 cpu.mode = (fCode32) ? CPUMODE_32BIT : CPUMODE_16BIT;
    886                 rc = CSAMR3DISInstr(pVM, &cpu, pCurInstrGC, pCurInstrHC, &opsize, NULL);
     870                rc = CSAMR3DISInstr(pVM, pCurInstrGC, pCurInstrHC, (fCode32) ? CPUMODE_32BIT : CPUMODE_16BIT,
     871                                    &cpu, &opsize, NULL);
    887872            }
    888873            AssertRC(rc);
     
    10541039             * - push ebp after the filler (can extend this later); aligned at at least a 4 byte boundary
    10551040             */
    1056             for (int j=0;j<16;j++)
     1041            for (int j = 0; j < 16; j++)
    10571042            {
    10581043                uint8_t *pCurInstrHC = (uint8_t *)CSAMGCVirtToHCVirt(pVM, pCacheRec, pCurInstrGC);
     
    10641049                Assert(VALID_PTR(pCurInstrHC));
    10651050
    1066                 cpu.mode = (fCode32) ? CPUMODE_32BIT : CPUMODE_16BIT;
    10671051                STAM_PROFILE_START(&pVM->csam.s.StatTimeDisasm, a);
    10681052#ifdef DEBUG
    1069                 rc2 = CSAMR3DISInstr(pVM, &cpu, pCurInstrGC, pCurInstrHC, &opsize, szOutput);
     1053                rc2 = CSAMR3DISInstr(pVM, pCurInstrGC, pCurInstrHC, (fCode32) ? CPUMODE_32BIT : CPUMODE_16BIT,
     1054                                     &cpu, &opsize, szOutput);
    10701055                if (RT_SUCCESS(rc2)) Log(("CSAM Call Analysis: %s", szOutput));
    10711056#else
    1072                 rc2 = CSAMR3DISInstr(pVM, &cpu, pCurInstrGC, pCurInstrHC, &opsize, NULL);
     1057                rc2 = CSAMR3DISInstr(pVM, pCurInstrGC, pCurInstrHC, (fCode32) ? CPUMODE_32BIT : CPUMODE_16BIT,
     1058                                     &cpu, &opsize, NULL);
    10731059#endif
    10741060                STAM_PROFILE_STOP(&pVM->csam.s.StatTimeDisasm, a);
     
    12761262            Assert(VALID_PTR(pCurInstrHC));
    12771263
    1278             cpu.mode = (fCode32) ? CPUMODE_32BIT : CPUMODE_16BIT;
    12791264            STAM_PROFILE_START(&pVM->csam.s.StatTimeDisasm, a);
    12801265#ifdef DEBUG
    1281             rc2 = CSAMR3DISInstr(pVM, &cpu, pCurInstrGC, pCurInstrHC, &opsize, szOutput);
     1266            rc2 = CSAMR3DISInstr(pVM, pCurInstrGC, pCurInstrHC, (fCode32) ? CPUMODE_32BIT : CPUMODE_16BIT,
     1267                                 &cpu, &opsize, szOutput);
    12821268            if (RT_SUCCESS(rc2)) Log(("CSAM Analysis: %s", szOutput));
    12831269#else
    1284             rc2 = CSAMR3DISInstr(pVM, &cpu, pCurInstrGC, pCurInstrHC, &opsize, NULL);
     1270            rc2 = CSAMR3DISInstr(pVM, &cpu, pCurInstrGC, pCurInstrHC, (fCode32) ? CPUMODE_32BIT : CPUMODE_16BIT,
     1271                                 &cpu, &opsize, NULL);
    12851272#endif
    12861273            STAM_PROFILE_STOP(&pVM->csam.s.StatTimeDisasm, a);
  • trunk/src/VBox/VMM/VMMR3/DBGFDisas.cpp

    r38838 r41658  
    8282*   Internal Functions                                                         *
    8383*******************************************************************************/
    84 static DECLCALLBACK(int) dbgfR3DisasInstrRead(RTUINTPTR pSrc, uint8_t *pDest, uint32_t size, void *pvUserdata);
     84static FNDISREADBYTES dbgfR3DisasInstrRead;
    8585
    8686
     
    199199
    200200/**
    201  * Instruction reader.
    202  *
    203  * @returns VBox status code. (Why this is a int32_t and not just an int is also beyond me.)
    204  * @param   PtrSrc      Address to read from.
    205  *                      In our case this is relative to the selector pointed to by the 2nd user argument of uDisCpu.
    206  * @param   pu8Dst      Where to store the bytes.
    207  * @param   cbRead      Number of bytes to read.
    208  * @param   uDisCpu     Pointer to the disassembler cpu state. (Why this is a VBOXHUINTPTR is beyond me...)
    209  *                      In this context it's always pointer to the Core of a DBGFDISASSTATE.
    210  */
    211 static DECLCALLBACK(int) dbgfR3DisasInstrRead(RTUINTPTR PtrSrc, uint8_t *pu8Dst, uint32_t cbRead, void *pvDisCpu)
    212 {
    213     PDBGFDISASSTATE pState = (PDBGFDISASSTATE)pvDisCpu;
    214     Assert(cbRead > 0);
     201 * @callback_method_impl{FNDISREADBYTES}
     202 *
     203 * @remarks @a uSrcAddr is relative to the base address indicated by
     204 *          DBGFDISASSTATE::GCPtrSegBase.
     205 */
     206static DECLCALLBACK(int) dbgfR3DisasInstrRead(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead)
     207{
     208    PDBGFDISASSTATE pState = (PDBGFDISASSTATE)pDisState;
     209    Assert(cbToRead > 0);
    215210    for (;;)
    216211    {
    217         RTGCUINTPTR GCPtr = PtrSrc + pState->GCPtrSegBase;
     212        RTGCUINTPTR GCPtr = uSrcAddr + pState->GCPtrSegBase;
    218213
    219214        /* Need to update the page translation? */
     
    250245
    251246        /* check the segment limit */
    252         if (!pState->f64Bits && PtrSrc > pState->cbSegLimit)
     247        if (!pState->f64Bits && uSrcAddr > pState->cbSegLimit)
    253248            return VERR_OUT_OF_SELECTOR_BOUNDS;
    254249
     
    261256                cb = cbSeg;
    262257        }
    263         if (cb > cbRead)
    264             cb = cbRead;
     258        if (cb > cbToRead)
     259            cb = cbToRead;
    265260
    266261        /* read and advance */
    267         memcpy(pu8Dst, (char *)pState->pvPageR3 + (GCPtr & PAGE_OFFSET_MASK), cb);
    268         cbRead -= cb;
    269         if (!cbRead)
     262        memcpy(pbDst, (char *)pState->pvPageR3 + (GCPtr & PAGE_OFFSET_MASK), cb);
     263        cbToRead -= cb;
     264        if (!cbToRead)
    270265            return VINF_SUCCESS;
    271         pu8Dst += cb;
    272         PtrSrc += cb;
     266        pbDst    += cb;
     267        uSrcAddr += cb;
    273268    }
    274269}
     
    507502        uint32_t cbBits = State.Cpu.opsize;
    508503        uint8_t *pau8Bits = (uint8_t *)alloca(cbBits);
    509         rc = dbgfR3DisasInstrRead(GCPtr, pau8Bits, cbBits, &State);
     504        rc = dbgfR3DisasInstrRead(&State.Cpu, pau8Bits, GCPtr, cbBits);
    510505        AssertRC(rc);
    511506        if (fFlags & DBGF_DISAS_FLAGS_NO_ADDRESS)
  • trunk/src/VBox/VMM/VMMR3/PATM.cpp

    r39417 r41658  
    517517}
    518518
    519 /**
    520  * Read callback for disassembly function; supports reading bytes that cross a page boundary
    521  *
    522  * @returns VBox status code.
    523  * @param   pSrc        GC source pointer
    524  * @param   pDest       HC destination pointer
    525  * @param   size        Number of bytes to read
    526  * @param   pvUserdata  Callback specific user data (pCpu)
    527  *
    528  */
    529 int patmReadBytes(RTUINTPTR pSrc, uint8_t *pDest, unsigned size, void *pvUserdata)
    530 {
    531     DISCPUSTATE  *pCpu     = (DISCPUSTATE *)pvUserdata;
    532     PATMDISASM   *pDisInfo = (PATMDISASM *)pCpu->apvUserData[0];
    533     int           orgsize  = size;
    534 
    535     Assert(size);
    536     if (size == 0)
     519DECLCALLBACK(int) patmReadBytes(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead)
     520{
     521    PATMDISASM   *pDisInfo = (PATMDISASM *)pDisState->apvUserData[0];
     522    int           orgsize  = cbToRead;
     523
     524    Assert(cbToRead);
     525    if (cbToRead == 0)
    537526        return VERR_INVALID_PARAMETER;
    538527
     
    544533    if (pDisInfo->fReadFlags & PATMREAD_ORGCODE)
    545534    {
    546         for (int i=0;i<orgsize;i++)
    547         {
    548             int rc = PATMR3QueryOpcode(pDisInfo->pVM, (RTRCPTR)pSrc, pDest);
    549             if (RT_SUCCESS(rc))
    550             {
    551                 pSrc++;
    552                 pDest++;
    553                 size--;
    554             }
    555             else break;
    556         }
    557         if (size == 0)
     535        for (int i = 0; i < orgsize; i++)
     536        {
     537            int rc = PATMR3QueryOpcode(pDisInfo->pVM, (RTRCPTR)uSrcAddr, pbDst);
     538            if (RT_FAILURE(rc))
     539                break;
     540            uSrcAddr++;
     541            pbDst++;
     542            cbToRead--;
     543        }
     544        if (cbToRead == 0)
    558545            return VINF_SUCCESS;
    559546#ifdef VBOX_STRICT
     
    561548            &&  !(pDisInfo->fReadFlags & PATMREAD_NOCHECK))
    562549        {
    563             Assert(PATMR3IsInsidePatchJump(pDisInfo->pVM, pSrc, NULL) == false);
    564             Assert(PATMR3IsInsidePatchJump(pDisInfo->pVM, pSrc+size-1, NULL) == false);
     550            Assert(PATMR3IsInsidePatchJump(pDisInfo->pVM, uSrcAddr, NULL) == false);
     551            Assert(PATMR3IsInsidePatchJump(pDisInfo->pVM, uSrcAddr+cbToRead-1, NULL) == false);
    565552        }
    566553#endif
     
    568555
    569556    if (    !pDisInfo->pInstrHC
    570         ||  (   PAGE_ADDRESS(pDisInfo->pInstrGC) != PAGE_ADDRESS(pSrc + size - 1)
    571              && !PATMIsPatchGCAddr(pDisInfo->pVM, pSrc)))
    572     {
    573         Assert(!PATMIsPatchGCAddr(pDisInfo->pVM, pSrc));
    574         return PGMPhysSimpleReadGCPtr(&pDisInfo->pVM->aCpus[0], pDest, pSrc, size);
    575     }
    576     else
    577     {
    578         Assert(pDisInfo->pInstrHC);
    579 
    580         uint8_t *pInstrHC = pDisInfo->pInstrHC;
    581 
    582         Assert(pInstrHC);
    583 
    584         /* pInstrHC is the base address; adjust according to the GC pointer. */
    585         pInstrHC = pInstrHC + (pSrc - pDisInfo->pInstrGC);
    586 
    587         memcpy(pDest, (void *)pInstrHC, size);
    588     }
     557        ||  (   PAGE_ADDRESS(pDisInfo->pInstrGC) != PAGE_ADDRESS(uSrcAddr + cbToRead - 1)
     558             && !PATMIsPatchGCAddr(pDisInfo->pVM, uSrcAddr)))
     559    {
     560        Assert(!PATMIsPatchGCAddr(pDisInfo->pVM, uSrcAddr));
     561        return PGMPhysSimpleReadGCPtr(&pDisInfo->pVM->aCpus[0], pbDst, uSrcAddr, cbToRead);
     562    }
     563
     564    Assert(pDisInfo->pInstrHC);
     565
     566    uint8_t *pInstrHC = pDisInfo->pInstrHC;
     567
     568    Assert(pInstrHC);
     569
     570    /* pInstrHC is the base address; adjust according to the GC pointer. */
     571    pInstrHC = pInstrHC + (uSrcAddr - pDisInfo->pInstrGC);
     572
     573    memcpy(pbDst, (void *)pInstrHC, cbToRead);
    589574
    590575    return VINF_SUCCESS;
     
    28372822    if (pPatch->flags & PATMFL_INT3_REPLACEMENT_BLOCK)
    28382823    {
    2839         /*uint8_t ASMInt3 = 0xCC; - unused */
     2824        /*uint8_t bASMInt3 = 0xCC; - unused */
    28402825
    28412826        Log(("PATMR3PatchBlock %RRv -> int 3 callable patch.\n", pPatch->pPrivInstrGC));
     
    37863771static int patmActivateInt3Patch(PVM pVM, PPATCHINFO pPatch)
    37873772{
    3788     uint8_t ASMInt3 = 0xCC;
     3773    uint8_t bASMInt3 = 0xCC;
    37893774    int     rc;
    37903775
     
    37933778
    37943779    /* Replace first opcode byte with 'int 3'. */
    3795     rc = PGMPhysSimpleDirtyWriteGCPtr(VMMGetCpu0(pVM), pPatch->pPrivInstrGC, &ASMInt3, sizeof(ASMInt3));
     3780    rc = PGMPhysSimpleDirtyWriteGCPtr(VMMGetCpu0(pVM), pPatch->pPrivInstrGC, &bASMInt3, sizeof(bASMInt3));
    37963781    AssertRC(rc);
    37973782
    3798     pPatch->cbPatchJump = sizeof(ASMInt3);
     3783    pPatch->cbPatchJump = sizeof(bASMInt3);
    37993784
    38003785    return rc;
     
    38233808
    38243809/**
    3825  * Replace an instruction with a breakpoint (0xCC), that is handled dynamically in the guest context.
     3810 * Replace an instruction with a breakpoint (0xCC), that is handled dynamically
     3811 * in the raw-mode context.
    38263812 *
    38273813 * @returns VBox status code.
     
    38353821 *
    38363822 */
    3837 VMMR3DECL(int) PATMR3PatchInstrInt3(PVM pVM, RTRCPTR pInstrGC, R3PTRTYPE(uint8_t *) pInstrHC, DISCPUSTATE *pCpu, PPATCHINFO pPatch)
    3838 {
    3839     uint8_t ASMInt3 = 0xCC;
     3823VMMR3DECL(int) PATMR3PatchInstrInt3(PVM pVM, RTRCPTR pInstrGC, R3PTRTYPE(uint8_t *) pInstrHC, DISCPUSTATE *pCpu,
     3824                                    PPATCHINFO pPatch)
     3825{
     3826    uint8_t bASMInt3 = 0xCC;
    38403827    int rc;
    38413828
     
    38553842    rc = PGMPhysSimpleReadGCPtr(VMMGetCpu0(pVM), pPatch->aPrivInstr, pPatch->pPrivInstrGC, pPatch->cbPrivInstr);
    38563843    AssertRC(rc);
    3857     pPatch->cbPatchJump = sizeof(ASMInt3);  /* bit of a misnomer in this case; size of replacement instruction. */
     3844    pPatch->cbPatchJump = sizeof(bASMInt3);  /* bit of a misnomer in this case; size of replacement instruction. */
    38583845
    38593846    pPatch->flags |= PATMFL_INT3_REPLACEMENT;
  • trunk/src/VBox/VMM/VMMR3/VMMSwitcher.cpp

    r39402 r41658  
    837837                uint32_t cbInstr = 0;
    838838                char szDisas[256];
    839                 if (RT_SUCCESS(DISInstr(&Cpu, (uintptr_t)pu8CodeR3 + offCode, uBase - (uintptr_t)pu8CodeR3, &cbInstr, szDisas)))
     839                if (RT_SUCCESS(DISInstrWithOff(&Cpu, (uintptr_t)pu8CodeR3 + offCode, uBase - (uintptr_t)pu8CodeR3,
     840                                               &cbInstr, szDisas)))
    840841                    RTLogPrintf("  %04x: %s", offCode, szDisas); //for whatever reason szDisas includes '\n'.
    841842                else
  • trunk/src/VBox/VMM/VMMRC/PATMRC.cpp

    r40453 r41658  
    11/* $Id$ */
    22/** @file
    3  * PATM - Dynamic Guest OS Patching Manager - Guest Context
     3 * PATM - Dynamic Guest OS Patching Manager - Raw-mode Context.
    44 */
    55
    66/*
    7  * Copyright (C) 2006-2007 Oracle Corporation
     7 * Copyright (C) 2006-2012 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2121*******************************************************************************/
    2222#define LOG_GROUP LOG_GROUP_PATM
     23#include <VBox/vmm/patm.h>
    2324#include <VBox/vmm/cpum.h>
    2425#include <VBox/vmm/stam.h>
    25 #include <VBox/vmm/patm.h>
    2626#include <VBox/vmm/pgm.h>
    2727#include <VBox/vmm/mm.h>
    28 #include <VBox/sup.h>
     28#include <VBox/vmm/em.h>
     29#ifdef VBOX_WITH_IEM
     30# include <VBox/vmm/iem.h>
     31#endif
     32#include <VBox/vmm/selm.h>
    2933#include <VBox/vmm/mm.h>
    30 #include <VBox/param.h>
    31 #include <iprt/avl.h>
    3234#include "PATMInternal.h"
    3335#include "PATMA.h"
     
    3638#include <VBox/dis.h>
    3739#include <VBox/disopcode.h>
    38 #include <VBox/vmm/em.h>
    3940#include <VBox/err.h>
    40 #include <VBox/vmm/selm.h>
    4141#include <VBox/log.h>
    4242#include <iprt/assert.h>
     
    441441 * Checks if the int 3 was caused by a patched instruction
    442442 *
    443  * @returns VBox status
     443 * @returns Strict VBox status, includes all statuses that
     444 *          EMInterpretInstructionDisasState and
     445 * @retval  VINF_SUCCESS
     446 * @retval  VINF_PATM_PATCH_INT3
     447 * @retval  VINF_EM_RAW_EMULATE_INSTR
    444448 *
    445449 * @param   pVM         The VM handle.
    446450 * @param   pCtxCore    The relevant core context.
    447451 */
    448 VMMDECL(int) PATMHandleInt3PatchTrap(PVM pVM, PCPUMCTXCORE pRegFrame)
     452VMMRCDECL(int) PATMRCHandleInt3PatchTrap(PVM pVM, PCPUMCTXCORE pRegFrame)
    449453{
    450454    PPATMPATCHREC pRec;
     
    456460    if (PATMIsPatchGCAddr(pVM, pRegFrame->eip))
    457461    {
    458         /* @note hardcoded assumption about it being a single byte int 3 instruction. */
     462        /* Note! Hardcoded assumption about it being a single byte int 3 instruction. */
    459463        pRegFrame->eip--;
    460464        return VINF_PATM_PATCH_INT3;
     
    512516                return VINF_EM_RAW_EMULATE_INSTR;
    513517            }
    514             rc = DISCoreOne(&cpu, (uintptr_t)&pRec->patch.aPrivInstr[0], &cbOp);
     518
     519#ifdef VBOX_WITH_IEM
     520            VBOXSTRICTRC rcStrict;
     521            rcStrict = IEMExecOneWithOpcodes(VMMGetCpu0(pVM), pRegFrame, pRec->patch.pPrivInstrGC,
     522                                             pRec->patch.aPrivInstr, pRec->patch.cbPrivInstr);
     523            rc = VBOXSTRICTRC_TODO(rcStrict);
     524#else
     525            rc = DISCoreOneEx((uintptr_t)&pRec->patch.aPrivInstr[0], cpu.mode, NULL /*pfnReadBytes*/, NULL /*pvUser*/,
     526                              &cpu, &cbOp);
    515527            if (RT_FAILURE(rc))
    516528            {
     
    523535            rc = EMInterpretInstructionDisasState(VMMGetCpu0(pVM), &cpu, pRegFrame, 0 /* not relevant here */,
    524536                                                  EMCODETYPE_SUPERVISOR);
    525             if (rc != VINF_SUCCESS)
     537#endif
     538            if (RT_FAILURE(rc))
    526539            {
    527540                Log(("EMInterpretInstructionCPU failed with %Rrc\n", rc));
     
    530543                return VINF_EM_RAW_EMULATE_INSTR;
    531544            }
    532             return VINF_SUCCESS;
     545            return rc;
    533546        }
    534547    }
  • trunk/src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp

    r40486 r41658  
    421421        &&  !pRegFrame->eflags.Bits.u1VM)
    422422    {
    423         rc = PATMHandleInt3PatchTrap(pVM, pRegFrame);
    424         if (rc == VINF_SUCCESS || rc == VINF_EM_RAW_EMULATE_INSTR || rc == VINF_PATM_PATCH_INT3 || rc == VINF_PATM_DUPLICATE_FUNCTION)
     423        rc = PATMRCHandleInt3PatchTrap(pVM, pRegFrame);
     424        if (   rc == VINF_SUCCESS
     425            || rc == VINF_EM_RAW_EMULATE_INSTR
     426            || rc == VINF_PATM_PATCH_INT3
     427            || rc == VINF_PATM_DUPLICATE_FUNCTION)
    425428        {
    426429            rc = trpmGCExitTrap(pVM, pVCpu, rc, pRegFrame);
     
    745748            {
    746749                /* Int 3 replacement patch? */
    747                 if (PATMHandleInt3PatchTrap(pVM, pRegFrame) == VINF_SUCCESS)
     750                if (PATMRCHandleInt3PatchTrap(pVM, pRegFrame) == VINF_SUCCESS)
    748751                {
    749752                    AssertFailed();
  • trunk/src/VBox/VMM/include/PATMInternal.h

    r36801 r41658  
    273273    /** Size of the patch jump in the guest code. */
    274274    uint32_t                    cbPatchJump;
    275     /* Only valid for PATMFL_JUMP_CONFLICT patches */
     275    /** Only valid for PATMFL_JUMP_CONFLICT patches */
    276276    RTRCPTR                     pPatchJumpDestGC;
    277277    /** Offset of the patch code from the beginning of the patch memory area. */
     
    675675
    676676
    677 /**
    678  * Read callback for disassembly function; supports reading bytes that cross a page boundary
    679  *
    680  * @returns VBox status code.
    681  * @param   pSrc        GC source pointer
    682  * @param   pDest       HC destination pointer
    683  * @param   size        Number of bytes to read
    684  * @param   pvUserdata  Callback specific user data (pCpu)
    685  *
    686  */
    687 int patmReadBytes(RTUINTPTR pSrc, uint8_t *pDest, unsigned size, void *pvUserdata);
     677FNDISREADBYTES patmReadBytes;
    688678
    689679
     
    706696} PATMDISASM, *PPATMDISASM;
    707697
    708 inline bool PATMR3DISInstr(PVM pVM, PPATCHINFO pPatch, DISCPUSTATE *pCpu, RTRCPTR InstrGC,
    709                            uint8_t *InstrHC, uint32_t *pOpsize, char *pszOutput,
    710                            uint32_t fReadFlags = PATMREAD_ORGCODE)
     698DECLINLINE(bool) PATMR3DISInstr(PVM pVM, PPATCHINFO pPatch, PDISCPUSTATE pCpu, RTRCPTR InstrGC,
     699                                uint8_t *InstrHC, uint32_t *pOpsize, char *pszOutput,
     700                                uint32_t fReadFlags = PATMREAD_ORGCODE)
    711701{
    712702    PATMDISASM disinfo;
     
    718708    (pCpu)->pfnReadBytes = patmReadBytes;
    719709    (pCpu)->apvUserData[0] = &disinfo;
    720     return RT_SUCCESS(DISInstr(pCpu, InstrGC, 0, pOpsize, pszOutput));
     710    return RT_SUCCESS(DISInstrWithReader(InstrGC, pCpu->mode, patmReadBytes, &disinfo, pCpu, pOpsize, pszOutput));
    721711}
    722712#endif /* !IN_RC */
  • trunk/src/VBox/VMM/testcase/tstCompiler.cpp

    r38636 r41658  
    204204
    205205    memset(&Cpu, 0, sizeof(Cpu));
    206     Cpu.mode = CPUMODE_32BIT;
    207206    do
    208207    {
    209208        char        sz[256];
    210209        uint32_t    cbInstr = 0;
    211         if (RT_SUCCESS(DISInstr(&Cpu, uCur, 0, &cbInstr, sz)))
     210        if (RT_SUCCESS(DISInstr(uCur, CPUMODE_32BIT, &Cpu, &cbInstr, sz)))
    212211        {
    213212            RTPrintf("tstBitFields: %s", sz);
  • trunk/src/recompiler/VBoxREMWrapper.cpp

    r40907 r41658  
    654654static const REMPARMDESC g_aArgsDISInstr[] =
    655655{
    656     { REMPARMDESC_FLAGS_INT,        sizeof(PVM),                NULL },
    657656    { REMPARMDESC_FLAGS_INT,        sizeof(RTUINTPTR),          NULL },
    658     { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t),           NULL },
     657    { REMPARMDESC_FLAGS_INT,        sizeof(DISCPUMODE),         NULL },
     658    { REMPARMDESC_FLAGS_INT,        sizeof(PDISCPUSTATE),       NULL },
    659659    { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t *),         NULL },
    660660    { REMPARMDESC_FLAGS_INT,        sizeof(char *),             NULL }
  • trunk/src/recompiler/VBoxRecompiler.c

    r41436 r41658  
    40714071        char            szOutput[256];
    40724072        DISCPUSTATE     Cpu;
    4073 
    4074         memset(&Cpu, 0, sizeof(Cpu));
    40754073#ifdef RT_ARCH_X86
    4076         Cpu.mode = CPUMODE_32BIT;
     4074        DISCPUMODE      enmCpuMode = CPUMODE_32BIT;
    40774075#else
    4078         Cpu.mode = CPUMODE_64BIT;
     4076        DISCPUMODE      enmCpuMode = CPUMODE_64BIT;
    40794077#endif
    40804078
     
    40834081        {
    40844082            uint32_t cbInstr;
    4085             if (RT_SUCCESS(DISInstr(&Cpu, (uintptr_t)pvCode + off, 0, &cbInstr, szOutput)))
     4083            int rc = DISInstr((uintptr_t)pvCode + off, enmCpuMode, &Cpu, &cbInstr, szOutput);
     4084            if (RT_SUCCESS(rc))
    40864085                RTLogPrintf("%s", szOutput);
    40874086            else
    40884087            {
    4089                 RTLogPrintf("disas error\n");
     4088                RTLogPrintf("disas error %Rrc\n", rc);
    40904089                cbInstr = 1;
    4091 #ifdef RT_ARCH_AMD64 /** @todo remove when DISInstr starts supporting 64-bit code. */
    4092                 break;
    4093 #endif
    40944090            }
    40954091            off += cbInstr;
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette