VirtualBox

Changeset 36801 in vbox


Ignore:
Timestamp:
Apr 21, 2011 6:14:13 PM (14 years ago)
Author:
vboxsync
Message:

PATM: Indentation and comments of the structures. Fix remaining RTAvl*Insert return values

Location:
trunk/src/VBox/VMM
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/PATM.cpp

    r36669 r36801  
    13071307    bool       fIllegalInstr = false;
    13081308
    1309     //Preliminary heuristics:
    1310     //- no call instructions without a fixed displacement between cli and sti/popf
    1311     //- no jumps in the instructions following cli (4+ bytes; enough for the replacement jump (5 bytes))
    1312     //- no nested pushf/cli
    1313     //- sti/popf should be the (eventual) target of all branches
    1314     //- no near or far returns; no int xx, no into
    1315     //
    1316     // Note: Later on we can impose less stricter guidelines if the need arises
     1309    /*
     1310     *  Preliminary heuristics:
     1311     *- no call instructions without a fixed displacement between cli and sti/popf
     1312     *- no jumps in the instructions following cli (4+ bytes; enough for the replacement jump (5 bytes))
     1313     *- no nested pushf/cli
     1314     *- sti/popf should be the (eventual) target of all branches
     1315     *- no near or far returns; no int xx, no into
     1316     *
     1317     * Note: Later on we can impose less stricter guidelines if the need arises
     1318     */
    13171319
    13181320    /* Bail out if the patch gets too big. */
     
    13441346        if (pPatch->opcode == OP_CLI && pCpu->pCurInstr->opcode == OP_JMP)
    13451347        {
    1346             if (pCurInstrGC > pPatch->pPrivInstrGC && pCurInstrGC + pCpu->opsize < pPatch->pPrivInstrGC + SIZEOF_NEARJUMP32) /* hardcoded patch jump size; cbPatchJump is still zero */
     1348            if (   pCurInstrGC > pPatch->pPrivInstrGC
     1349                && pCurInstrGC + pCpu->opsize < pPatch->pPrivInstrGC + SIZEOF_NEARJUMP32) /* hardcoded patch jump size; cbPatchJump is still zero */
    13471350            {
    13481351                Log(("Dangerous unconditional jump ends in our generated patch jump!! (%x vs %x)\n", pCurInstrGC, pPatch->pPrivInstrGC));
     
    13621365        }
    13631366
    1364         // no far returns
     1367        /* no far returns */
    13651368        if (pCpu->pCurInstr->opcode == OP_RETF)
    13661369        {
     
    13691372            patmAddIllegalInstrRecord(pVM, pPatch, pCurInstrGC);
    13701373        }
    1371         else
    1372         // no int xx or into either
    1373         if (pCpu->pCurInstr->opcode == OP_INT3 || pCpu->pCurInstr->opcode == OP_INT || pCpu->pCurInstr->opcode == OP_INTO)
    1374         {
     1374        else if (   pCpu->pCurInstr->opcode == OP_INT3
     1375                 || pCpu->pCurInstr->opcode == OP_INT
     1376                 || pCpu->pCurInstr->opcode == OP_INTO)
     1377        {
     1378            /* No int xx or into either. */
    13751379            fIllegalInstr = true;
    13761380            patmAddIllegalInstrRecord(pVM, pPatch, pCurInstrGC);
     
    13921396    case OP_SYSENTER:
    13931397    case OP_ILLUD2:
    1394         //This appears to be some kind of kernel panic in Linux 2.4; no point to analyse more
     1398        /* This appears to be some kind of kernel panic in Linux 2.4; no point to analyse more. */
    13951399        Log(("Illegal opcode (0xf 0xb) -> return here\n"));
    13961400        return VINF_SUCCESS;
     
    14161420                pPatch->flags |= PATMFL_CHECK_SIZE;
    14171421            }
    1418             break;  //sti doesn't mark the end of a pushf block; only popf does
    1419         }
    1420         //else no break
     1422            break;  /* sti doesn't mark the end of a pushf block; only popf does. */
     1423        }
     1424        /* else: fall through. */
    14211425    case OP_RETN: /* exit point for function replacement */
    14221426        return VINF_SUCCESS;
     
    14391443    }
    14401444
    1441     // If single instruction patch, we've copied enough instructions *and* the current instruction is not a relative jump
     1445    /* If single instruction patch, we've copied enough instructions *and* the current instruction is not a relative jump. */
    14421446    if ((pPatch->flags & PATMFL_CHECK_SIZE) && pPatch->cbPatchBlockSize > SIZEOF_NEARJUMP32 && !(pCpu->pCurInstr->optype & OPTYPE_RELATIVE_CONTROLFLOW))
    14431447    {
    1444         // The end marker for this kind of patch is any instruction at a location outside our patch jump
     1448        /* The end marker for this kind of patch is any instruction at a location outside our patch jump. */
    14451449        Log(("End of block at %RRv size %d\n", pCurInstrGC, pCpu->opsize));
    14461450        return VINF_SUCCESS;
     
    26672671    uint32_t orgOffsetPatchMem = ~0;
    26682672    RTRCPTR pInstrStart;
     2673    bool fInserted;
    26692674#ifdef LOG_ENABLED
    26702675    uint32_t opsize;
     
    27872792    LogFlow(("Insert %RRv patch offset %RRv\n", pPatchRec->patch.pPrivInstrGC, pPatch->pPatchBlockOffset));
    27882793    pPatchRec->CoreOffset.Key = pPatch->pPatchBlockOffset;
    2789     rc = RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTreeByPatchAddr, &pPatchRec->CoreOffset);
    2790     AssertMsg(rc, ("RTAvlULInsert failed for %x\n", pPatchRec->CoreOffset.Key));
    2791     if (!rc)
     2794    fInserted = RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTreeByPatchAddr, &pPatchRec->CoreOffset);
     2795    AssertMsg(fInserted, ("RTAvlULInsert failed for %x\n", pPatchRec->CoreOffset.Key));
     2796    if (!fInserted)
    27922797    {
    27932798        rc = VERR_PATCHING_REFUSED;
     
    29342939           )
    29352940        {
     2941            bool fInserted;
    29362942            PPATMPATCHREC pJmpPatch = (PPATMPATCHREC)RTAvloU32Get(&pVM->patm.s.PatchLookupTreeHC->PatchTree, pJmpInstrGC);
    29372943            if (pJmpPatch == 0)
     
    30023008            LogFlow(("Insert %RRv patch offset %RRv\n", pPatchRec->patch.pPrivInstrGC, pPatch->pPatchBlockOffset));
    30033009            pPatchRec->CoreOffset.Key = pPatch->pPatchBlockOffset;
    3004             rc = RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTreeByPatchAddr, &pPatchRec->CoreOffset);
    3005             AssertMsg(rc, ("RTAvlULInsert failed for %x\n", pPatchRec->CoreOffset.Key));
     3010            fInserted = RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTreeByPatchAddr, &pPatchRec->CoreOffset);
     3011            AssertMsg(fInserted, ("RTAvlULInsert failed for %x\n", pPatchRec->CoreOffset.Key));
    30063012
    30073013            pPatch->uState = PATCH_ENABLED;
     
    30333039    int rc = VERR_PATCHING_REFUSED;
    30343040    uint32_t orgOffsetPatchMem = ~0;
     3041    bool fInserted;
    30353042#ifdef LOG_ENABLED
    30363043    bool disret;
     
    30863093    LogFlow(("Insert %RRv patch offset %RRv\n", pPatchRec->patch.pPrivInstrGC, pPatch->pPatchBlockOffset));
    30873094    pPatchRec->CoreOffset.Key = pPatch->pPatchBlockOffset;
    3088     rc = RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTreeByPatchAddr, &pPatchRec->CoreOffset);
    3089     AssertMsg(rc, ("RTAvlULInsert failed for %x\n", pPatchRec->CoreOffset.Key));
     3095    fInserted = RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTreeByPatchAddr, &pPatchRec->CoreOffset);
     3096    AssertMsg(fInserted, ("RTAvlULInsert failed for %x\n", pPatchRec->CoreOffset.Key));
    30903097
    30913098    pPatch->uState = PATCH_ENABLED;
     
    31443151    DISCPUSTATE cpu;
    31453152    uint32_t orgOffsetPatchMem = ~0;
     3153    bool fInserted;
    31463154
    31473155    Log(("patmDuplicateFunction %RRv\n", pInstrGC));
     
    32033211    LogFlow(("Insert %RRv patch offset %RRv\n", pPatchRec->patch.pPrivInstrGC, pPatch->pPatchBlockOffset));
    32043212    pPatchRec->CoreOffset.Key = pPatch->pPatchBlockOffset;
    3205     rc = RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTreeByPatchAddr, &pPatchRec->CoreOffset);
    3206     AssertMsg(rc, ("RTAvloU32Insert failed for %x\n", pPatchRec->CoreOffset.Key));
    3207     if (!rc)
     3213    fInserted = RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTreeByPatchAddr, &pPatchRec->CoreOffset);
     3214    AssertMsg(fInserted, ("RTAvloU32Insert failed for %x\n", pPatchRec->CoreOffset.Key));
     3215    if (!fInserted)
    32083216    {
    32093217        rc = VERR_PATCHING_REFUSED;
     
    41874195
    41884196    /* Initialize cache record for guest address translations. */
     4197    bool fInserted;
    41894198    PATMP2GLOOKUPREC cacheRec;
    41904199    RT_ZERO(cacheRec);
     
    42034212    pPatchRec->patch.uState = PATCH_REFUSED;   /* default value */
    42044213    /* Insert patch record into the lookup tree. */
    4205     rc = RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTree, &pPatchRec->Core);
    4206     Assert(rc);
     4214    fInserted = RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTree, &pPatchRec->Core);
     4215    Assert(fInserted);
    42074216
    42084217    pPatchRec->patch.pPrivInstrGC = pInstrGC;
     
    45444553    else
    45454554    {
     4555        bool fInserted;
     4556
    45464557        rc = MMHyperAlloc(pVM, sizeof(PATMPATCHPAGE), 0, MM_TAG_PATM_PATCH, (void **)&pPatchPage);
    45474558        if (RT_FAILURE(rc))
     
    45634574        pPatchPage->aPatch[0] = pPatch;
    45644575
    4565         rc = RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTreeByPage, &pPatchPage->Core);
    4566         Assert(rc);
     4576        fInserted = RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTreeByPage, &pPatchPage->Core);
     4577        Assert(fInserted);
    45674578        pVM->patm.s.cPageRecords++;
    45684579
     
    56145625
    56155626        /* Put the new patch back into the tree, because removing the old one kicked this one out. (hack alert) */
    5616         RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTree, &pNewPatchRec->Core);
     5627        bool fInserted = RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTree, &pNewPatchRec->Core);
     5628        Assert(fInserted);
    56175629
    56185630        LogRel(("PATM: patmR3RefreshPatch: succeeded to refresh patch at %RRv \n", pInstrGC));
     
    56655677
    56665678        /* Put the old patch back into the tree (or else it won't be saved) (hack alert) */
    5667         RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTree, &pPatchRec->Core);
     5679        bool fInserted = RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTree, &pPatchRec->Core);
     5680        Assert(fInserted);
    56685681
    56695682        /* Enable again in case the dirty instruction is near the end and there are safe code paths. */
  • trunk/src/VBox/VMM/include/PATMInternal.h

    r36669 r36801  
    7777#define MAX_INSTR_SIZE                     16
    7878
    79 //Patch states
     79/* Patch states */
    8080#define PATCH_REFUSED                     1
    8181#define PATCH_DISABLED                    2
     
    140140{
    141141    /** The key is a HC virtual address. */
    142     AVLPVNODECORE   Core;
    143 
    144     uint32_t        uType;
    145     R3PTRTYPE(uint8_t *) pRelocPos;
    146     RTRCPTR       pSource;
    147     RTRCPTR       pDest;
     142    AVLPVNODECORE               Core;
     143
     144    uint32_t                    uType;
     145    R3PTRTYPE(uint8_t *)        pRelocPos;
     146    RTRCPTR                     pSource;
     147    RTRCPTR                     pDest;
    148148} RELOCREC, *PRELOCREC;
    149149
     
    154154typedef struct
    155155{
    156     R3PTRTYPE(uint8_t *) pPageLocStartHC;
    157     RCPTRTYPE(uint8_t *) pGuestLoc;
    158     R3PTRTYPE(void *)    pPatch;
    159     PGMPAGEMAPLOCK       Lock;
     156    R3PTRTYPE(uint8_t *)        pPageLocStartHC;
     157    RCPTRTYPE(uint8_t *)        pGuestLoc;
     158    R3PTRTYPE(void *)           pPatch;
     159    PGMPAGEMAPLOCK              Lock;
    160160} PATMP2GLOOKUPREC, *PPATMP2GLOOKUPREC;
    161161
     
    163163typedef struct
    164164{
    165     R3PTRTYPE(uint8_t *) pPatchLocStartHC;
    166     R3PTRTYPE(uint8_t *) pPatchLocEndHC;
    167     RCPTRTYPE(uint8_t *) pGuestLoc;
    168     uint32_t             opsize;
     165    R3PTRTYPE(uint8_t *)        pPatchLocStartHC;
     166    R3PTRTYPE(uint8_t *)        pPatchLocEndHC;
     167    RCPTRTYPE(uint8_t *)        pGuestLoc;
     168    uint32_t                    opsize;
    169169} PATMP2GLOOKUPREC_OBSOLETE;
    170170
     
    172172{
    173173    /** The key is a pointer to a JUMPREC structure. */
    174     AVLPVNODECORE   Core;
    175 
    176     R3PTRTYPE(uint8_t *) pJumpHC;
    177     RCPTRTYPE(uint8_t *) pTargetGC;
    178     uint32_t            offDispl;
    179     uint32_t            opcode;
     174    AVLPVNODECORE               Core;
     175
     176    R3PTRTYPE(uint8_t *)        pJumpHC;
     177    RCPTRTYPE(uint8_t *)        pTargetGC;
     178    uint32_t                    offDispl;
     179    uint32_t                    opcode;
    180180} JUMPREC, *PJUMPREC;
    181181
     
    185185typedef enum
    186186{
    187     PATM_LOOKUP_PATCH2GUEST,    /* patch to guest */
    188     PATM_LOOKUP_BOTHDIR         /* guest to patch + patch to guest */
     187    /** patch to guest */
     188    PATM_LOOKUP_PATCH2GUEST,
     189    /** guest to patch + patch to guest */
     190    PATM_LOOKUP_BOTHDIR
    189191} PATM_LOOKUP_TYPE;
    190192
    191193/**
    192  * Patch to guest address lookup record
     194 * Patch to guest address lookup record.
    193195 */
    194196typedef struct RECPATCHTOGUEST
    195197{
    196198    /** The key is an offset inside the patch memory block. */
    197     AVLU32NODECORE   Core;
    198 
    199     RTRCPTR          pOrgInstrGC;
    200     PATM_LOOKUP_TYPE enmType;
    201     bool             fDirty;
    202     bool             fJumpTarget;
    203     uint8_t          u8DirtyOpcode;  /* original opcode before writing 0xCC there to mark it dirty */
     199    AVLU32NODECORE              Core;
     200    /** GC address of the guest instruction this record is for. */
     201    RTRCPTR                     pOrgInstrGC;
     202    /** Patch to guest lookup type. */
     203    PATM_LOOKUP_TYPE            enmType;
     204    /** Flag whether the original instruction was changed by the guest. */
     205    bool                        fDirty;
     206    /** Flag whether this guest instruction is a jump target from
     207     * a trampoline patch. */
     208    bool                        fJumpTarget;
     209    /** Original opcode before writing 0xCC there to mark it dirty. */
     210    uint8_t                     u8DirtyOpcode;
    204211} RECPATCHTOGUEST, *PRECPATCHTOGUEST;
    205212
     
    210217{
    211218    /** The key is a GC virtual address. */
    212     AVLU32NODECORE      Core;
    213 
     219    AVLU32NODECORE              Core;
    214220    /** Patch offset (relative to PATM::pPatchMemGC / PATM::pPatchMemHC). */
    215     uint32_t            PatchOffset;
     221    uint32_t                    PatchOffset;
    216222} RECGUESTTOPATCH, *PRECGUESTTOPATCH;
    217223
     
    234240
    235241    /** Last original guest instruction pointer; used for disassembly log. */
    236     RTRCPTR                   pLastDisasmInstrGC;
     242    RTRCPTR                     pLastDisasmInstrGC;
    237243
    238244    /** Keeping track of multiple ret instructions. */
    239     RTRCPTR                 pPatchRetInstrGC;
     245    RTRCPTR                     pPatchRetInstrGC;
    240246    uint32_t                    uPatchRetParam1;
    241247} PATCHINFOTEMP, *PPATCHINFOTEMP;
     
    244250typedef struct TRAMPREC *PTRAMPREC;
    245251
     252/**
     253 * Patch information.
     254 */
    246255typedef struct _PATCHINFO
    247256{
    248     uint32_t        uState;
    249     uint32_t        uOldState;
    250     DISCPUMODE      uOpMode;
    251 
    252     /* GC pointer of privileged instruction */
    253     RCPTRTYPE(uint8_t *)  pPrivInstrGC;
    254     R3PTRTYPE(uint8_t *)  unusedHC;                             /* todo Can't remove due to structure size dependencies in saved states. */
    255     uint8_t               aPrivInstr[MAX_INSTR_SIZE];
    256     uint32_t              cbPrivInstr;
    257     uint32_t              opcode;      //opcode for priv instr (OP_*)
    258     uint32_t              cbPatchJump; //patch jump size
    259 
     257    /** Current patch state (enabled, disabled, etc.). */
     258    uint32_t                    uState;
     259    /** Previous patch state. Used when enabling a disabled patch. */
     260    uint32_t                    uOldState;
     261    /** CPU mode (16bit or 32bit). */
     262    DISCPUMODE                  uOpMode;
     263    /** GC pointer of privileged instruction */
     264    RCPTRTYPE(uint8_t *)        pPrivInstrGC;
     265    /** @todo: Can't remove due to structure size dependencies in saved states. */
     266    R3PTRTYPE(uint8_t *)        unusedHC;
     267    /** Original privileged guest instructions overwritten by the jump patch. */
     268    uint8_t                     aPrivInstr[MAX_INSTR_SIZE];
     269    /** Number of valid bytes in the instruction buffer. */
     270    uint32_t                    cbPrivInstr;
     271    /** Opcode for priv instr (OP_*). */
     272    uint32_t                    opcode;
     273    /** Size of the patch jump in the guest code. */
     274    uint32_t                    cbPatchJump;
    260275    /* Only valid for PATMFL_JUMP_CONFLICT patches */
    261     RTRCPTR               pPatchJumpDestGC;
    262 
    263     RTGCUINTPTR32         pPatchBlockOffset;
    264     uint32_t              cbPatchBlockSize;
    265     uint32_t              uCurPatchOffset;
     276    RTRCPTR                     pPatchJumpDestGC;
     277    /** Offset of the patch code from the beginning of the patch memory area. */
     278    RTGCUINTPTR32               pPatchBlockOffset;
     279    /** Size of the patch code in bytes. */
     280    uint32_t                    cbPatchBlockSize;
     281    /** Current offset of the patch starting from pPatchBlockOffset.
     282     * Used during patch creation. */
     283    uint32_t                    uCurPatchOffset;
    266284#if HC_ARCH_BITS == 64
    267     uint32_t              Alignment0;         /**< Align flags correctly. */
     285    uint32_t                    Alignment0;         /**< Align flags correctly. */
    268286#endif
    269 
    270     uint64_t              flags;
    271 
     287    /** PATM flags (see PATMFL_*). */
     288    uint64_t                    flags;
    272289    /**
    273290     * Lowest and highest patched GC instruction address. To optimize searches.
    274291     */
    275     RTRCPTR               pInstrGCLowest;
    276     RTRCPTR               pInstrGCHighest;
    277 
     292    RTRCPTR                     pInstrGCLowest;
     293    RTRCPTR                     pInstrGCHighest;
    278294    /* Tree of fixup records for the patch. */
    279     R3PTRTYPE(PAVLPVNODECORE) FixupTree;
    280     uint32_t                  nrFixups;
    281 
     295    R3PTRTYPE(PAVLPVNODECORE)   FixupTree;
     296    uint32_t                    nrFixups;
    282297    /* Tree of jumps inside the generated patch code. */
    283     uint32_t                  nrJumpRecs;
    284     R3PTRTYPE(PAVLPVNODECORE) JumpTree;
    285 
     298    uint32_t                    nrJumpRecs;
     299    R3PTRTYPE(PAVLPVNODECORE)   JumpTree;
    286300    /**
    287301     * Lookup trees for determining the corresponding guest address of an
    288302     * instruction in the patch block.
    289303     */
    290     R3PTRTYPE(PAVLU32NODECORE) Patch2GuestAddrTree;
    291     R3PTRTYPE(PAVLU32NODECORE) Guest2PatchAddrTree;
    292     uint32_t                  nrPatch2GuestRecs;
     304    R3PTRTYPE(PAVLU32NODECORE)  Patch2GuestAddrTree;
     305    R3PTRTYPE(PAVLU32NODECORE)  Guest2PatchAddrTree;
     306    uint32_t                    nrPatch2GuestRecs;
    293307#if HC_ARCH_BITS == 64
    294     uint32_t        Alignment1;
     308    uint32_t                    Alignment1;
    295309#endif
    296 
    297     /* Unused, but can't remove due to structure size dependencies in the saved state. */
    298     PATMP2GLOOKUPREC_OBSOLETE    unused;
    299 
    300     /* Temporary information during patch creation. Don't waste hypervisor memory for this. */
    301     R3PTRTYPE(PPATCHINFOTEMP) pTempInfo;
    302 
    303     /* List of trampoline patches referencing this patch.
     310    /** Unused, but can't remove due to structure size dependencies in the saved state. */
     311    PATMP2GLOOKUPREC_OBSOLETE   unused;
     312    /** Temporary information during patch creation. Don't waste hypervisor memory for this. */
     313    R3PTRTYPE(PPATCHINFOTEMP)   pTempInfo;
     314    /** List of trampoline patches referencing this patch.
    304315     * Used when refreshing the patch. (Only for function duplicates) */
    305     R3PTRTYPE(PTRAMPREC)      pTrampolinePatchesHead;
    306 
    307     /* Count the number of writes to the corresponding guest code. */
    308     uint32_t        cCodeWrites;
    309 
    310     /* Count the number of invalid writes to pages monitored for the patch. */
    311     //some statistics to determine if we should keep this patch activated
    312     uint32_t        cTraps;
    313 
    314     uint32_t        cInvalidWrites;
    315 
    316     // Index into the uPatchRun and uPatchTrap arrays (0..MAX_PATCHES-1)
    317     uint32_t        uPatchIdx;
    318 
    319     /* First opcode byte, that's overwritten when a patch is marked dirty. */
    320     uint8_t         bDirtyOpcode;
    321     uint8_t         Alignment2[HC_ARCH_BITS == 64 ? 7 : 3];      /**< Align the structure size on a 8-byte boundary. */
     316    R3PTRTYPE(PTRAMPREC)        pTrampolinePatchesHead;
     317    /** Count the number of writes to the corresponding guest code. */
     318    uint32_t                    cCodeWrites;
     319    /** Some statistics to determine if we should keep this patch activated. */
     320    uint32_t                    cTraps;
     321    /** Count the number of invalid writes to pages monitored for the patch. */
     322    uint32_t                    cInvalidWrites;
     323    /** Index into the uPatchRun and uPatchTrap arrays (0..MAX_PATCHES-1) */
     324    uint32_t                    uPatchIdx;
     325    /** First opcode byte, that's overwritten when a patch is marked dirty. */
     326    uint8_t                     bDirtyOpcode;
     327    /** Align the structure size on a 8-byte boundary. */
     328    uint8_t                     Alignment2[HC_ARCH_BITS == 64 ? 7 : 3];
    322329} PATCHINFO, *PPATCHINFO;
    323330
     
    331338{
    332339    /** The key is a GC virtual address. */
    333     AVLOU32NODECORE  Core;
     340    AVLOU32NODECORE             Core;
    334341    /** The key is a patch offset. */
    335     AVLOU32NODECORE  CoreOffset;
    336 
    337     PATCHINFO  patch;
     342    AVLOU32NODECORE             CoreOffset;
     343    /** The patch information. */
     344    PATCHINFO                   patch;
    338345} PATMPATCHREC, *PPATMPATCHREC;
    339346
     
    344351{
    345352    /** Pointer to the next trampoline patch. */
    346     struct TRAMPREC    *pNext;
     353    struct TRAMPREC            *pNext;
    347354    /** Pointer to the trampoline patch record. */
    348     PPATMPATCHREC       pPatchTrampoline;
     355    PPATMPATCHREC               pPatchTrampoline;
    349356} TRAMPREC;
    350357
     
    358365{
    359366    /** The key is a GC virtual address. */
    360     AVLOU32NODECORE  Core;
     367    AVLOU32NODECORE             Core;
    361368    /** Region to monitor. */
    362     RTRCPTR          pLowestAddrGC;
    363     RTRCPTR          pHighestAddrGC;
     369    RTRCPTR                     pLowestAddrGC;
     370    RTRCPTR                     pHighestAddrGC;
    364371    /** Number of patches for this page. */
    365     uint32_t           cCount;
     372    uint32_t                    cCount;
    366373    /** Maximum nr of pointers in the array. */
    367     uint32_t           cMaxPatches;
     374    uint32_t                    cMaxPatches;
    368375    /** Array of patch pointers for this page. */
    369     R3PTRTYPE(PPATCHINFO *) aPatch;
     376    R3PTRTYPE(PPATCHINFO *)     aPatch;
    370377} PATMPATCHPAGE, *PPATMPATCHPAGE;
    371378
     
    373380#define PATM_PATCHREC_FROM_PATCHINFO(a)   (PPATMPATCHREC)((uintptr_t)a - RT_OFFSETOF(PATMPATCHREC, patch))
    374381
     382/**
     383 * AVL trees used by PATM.
     384 */
    375385typedef struct PATMTREES
    376386{
     
    378388     * AVL tree with all patches (active or disabled) sorted by guest instruction address
    379389     */
    380     AVLOU32TREE           PatchTree;
     390    AVLOU32TREE                 PatchTree;
    381391
    382392    /**
    383393     * AVL tree with all patches sorted by patch address (offset actually)
    384394     */
    385     AVLOU32TREE           PatchTreeByPatchAddr;
     395    AVLOU32TREE                 PatchTreeByPatchAddr;
    386396
    387397    /**
    388398     * AVL tree with all pages which were (partly) patched
    389399     */
    390     AVLOU32TREE           PatchTreeByPage;
    391 
    392     uint32_t                align[1];
     400    AVLOU32TREE                 PatchTreeByPage;
     401
     402    uint32_t                    align[1];
    393403} PATMTREES, *PPATMTREES;
    394404
     
    401411    /** Offset to the VM structure.
    402412     * See PATM2VM(). */
    403     RTINT                   offVM;
    404 
    405     RCPTRTYPE(uint8_t *)    pPatchMemGC;
    406     R3PTRTYPE(uint8_t *)    pPatchMemHC;
    407     uint32_t                cbPatchMem;
    408     uint32_t                offPatchMem;
    409     bool                    fOutOfMemory;
    410 
    411     int32_t                 deltaReloc;
    412 
    413     /* GC PATM state pointers */
    414     R3PTRTYPE(PPATMGCSTATE) pGCStateHC;
    415     RCPTRTYPE(PPATMGCSTATE) pGCStateGC;
    416 
     413    RTINT                       offVM;
     414    /** Pointer to the patch memory area (GC) */
     415    RCPTRTYPE(uint8_t *)        pPatchMemGC;
     416    /** Pointer to the patch memory area (HC) */
     417    R3PTRTYPE(uint8_t *)        pPatchMemHC;
     418    /** Size of the patch memory area in bytes. */
     419    uint32_t                    cbPatchMem;
     420    /** Relative offset to the next free byte starting from the start of the region. */
     421    uint32_t                    offPatchMem;
     422    /** Flag whether PATM ran out of patch memory. */
     423    bool                        fOutOfMemory;
     424    /** Delta to the new relocated HMA area.
     425     * Used only during PATMR3Relocate(). */
     426    int32_t                     deltaReloc;
     427    /* GC PATM state pointer - HC pointer. */
     428    R3PTRTYPE(PPATMGCSTATE)     pGCStateHC;
     429    /* GC PATM state pointer - GC pointer. */
     430    RCPTRTYPE(PPATMGCSTATE)     pGCStateGC;
    417431    /** PATM stack page for call instruction execution. (2 parts: one for our private stack and one to store the original return address */
    418     RCPTRTYPE(RTRCPTR *)    pGCStackGC;
    419     R3PTRTYPE(RTRCPTR *)    pGCStackHC;
    420 
     432    RCPTRTYPE(RTRCPTR *)        pGCStackGC;
     433    /** HC pointer of the PATM stack page. */
     434    R3PTRTYPE(RTRCPTR *)        pGCStackHC;
    421435    /** GC pointer to CPUMCTX structure. */
    422     RCPTRTYPE(PCPUMCTX)     pCPUMCtxGC;
    423 
    424     /* GC statistics pointers */
    425     RCPTRTYPE(PSTAMRATIOU32) pStatsGC;
    426     R3PTRTYPE(PSTAMRATIOU32) pStatsHC;
    427 
     436    RCPTRTYPE(PCPUMCTX)         pCPUMCtxGC;
     437    /** GC statistics pointer. */
     438    RCPTRTYPE(PSTAMRATIOU32)    pStatsGC;
     439    /** HC statistics pointer. */
     440    R3PTRTYPE(PSTAMRATIOU32)    pStatsHC;
    428441    /* Current free index value (uPatchRun/uPatchTrap arrays). */
    429     uint32_t                uCurrentPatchIdx;
    430 
     442    uint32_t                    uCurrentPatchIdx;
    431443    /* Temporary counter for patch installation call depth. (in order not to go on forever) */
    432     uint32_t                ulCallDepth;
    433 
     444    uint32_t                    ulCallDepth;
    434445    /** Number of page lookup records. */
    435     uint32_t                cPageRecords;
    436 
    437     /**
    438      * Lowest and highest patched GC instruction addresses. To optimize searches.
    439      */
    440     RTRCPTR                 pPatchedInstrGCLowest;
    441     RTRCPTR                 pPatchedInstrGCHighest;
    442 
     446    uint32_t                    cPageRecords;
     447    /** Lowest and highest patched GC instruction addresses. To optimize searches. */
     448    RTRCPTR                     pPatchedInstrGCLowest;
     449    RTRCPTR                     pPatchedInstrGCHighest;
    443450    /** Pointer to the patch tree for instructions replaced by 'int 3'. */
    444     RCPTRTYPE(PPATMTREES)   PatchLookupTreeGC;
    445     R3PTRTYPE(PPATMTREES)   PatchLookupTreeHC;
    446 
     451    RCPTRTYPE(PPATMTREES)       PatchLookupTreeGC;
     452    R3PTRTYPE(PPATMTREES)       PatchLookupTreeHC;
    447453    /** Global PATM lookup and call function (used by call patches). */
    448     RTRCPTR                 pfnHelperCallGC;
     454    RTRCPTR                     pfnHelperCallGC;
    449455    /** Global PATM return function (used by ret patches). */
    450     RTRCPTR                 pfnHelperRetGC;
     456    RTRCPTR                     pfnHelperRetGC;
    451457    /** Global PATM jump function (used by indirect jmp patches). */
    452     RTRCPTR                 pfnHelperJumpGC;
     458    RTRCPTR                     pfnHelperJumpGC;
    453459    /** Global PATM return function (used by iret patches). */
    454     RTRCPTR                 pfnHelperIretGC;
    455 
     460    RTRCPTR                     pfnHelperIretGC;
    456461    /** Fake patch record for global functions. */
    457     R3PTRTYPE(PPATMPATCHREC) pGlobalPatchRec;
    458 
     462    R3PTRTYPE(PPATMPATCHREC)    pGlobalPatchRec;
    459463    /** Pointer to original sysenter handler */
    460     RTRCPTR                 pfnSysEnterGC;
     464    RTRCPTR                     pfnSysEnterGC;
    461465    /** Pointer to sysenter handler trampoline */
    462     RTRCPTR                 pfnSysEnterPatchGC;
     466    RTRCPTR                     pfnSysEnterPatchGC;
    463467    /** Sysenter patch index (for stats only) */
    464     uint32_t                uSysEnterPatchIdx;
    465 
    466     // GC address of fault in monitored page (set by PATMGCMonitorPage, used by PATMR3HandleMonitoredPage)
    467     RTRCPTR                 pvFaultMonitor;
    468 
    469     /* Temporary information for pending MMIO patch. Set in GC or R0 context. */
     468    uint32_t                    uSysEnterPatchIdx;
     469    /** GC address of fault in monitored page (set by PATMGCMonitorPage, used by PATMR3HandleMonitoredPage)- */
     470    RTRCPTR                     pvFaultMonitor;
     471    /** Temporary information for pending MMIO patch. Set in GC or R0 context. */
    470472    struct
    471473    {
    472         RTGCPHYS            GCPhys;
    473         RTRCPTR             pCachedData;
    474         RTRCPTR             Alignment0; /**< Align the structure size on a 8-byte boundary. */
     474        RTGCPHYS                GCPhys;
     475        RTRCPTR                 pCachedData;
     476        RTRCPTR                 Alignment0; /**< Align the structure size on a 8-byte boundary. */
    475477    } mmio;
    476 
    477     /* Temporary storage during load/save state */
     478    /** Temporary storage during load/save state */
    478479    struct
    479480    {
    480         R3PTRTYPE(PSSMHANDLE) pSSM;
    481         uint32_t            cPatches;
     481        R3PTRTYPE(PSSMHANDLE)   pSSM;
     482        uint32_t                cPatches;
    482483#if HC_ARCH_BITS == 64
    483         uint32_t            Alignment0; /**< Align the structure size on a 8-byte boundary. */
     484        uint32_t                Alignment0; /**< Align the structure size on a 8-byte boundary. */
    484485#endif
    485486    } savedstate;
    486487
    487     STAMCOUNTER             StatNrOpcodeRead;
    488     STAMCOUNTER             StatDisabled;
    489     STAMCOUNTER             StatUnusable;
    490     STAMCOUNTER             StatEnabled;
    491     STAMCOUNTER             StatInstalled;
    492     STAMCOUNTER             StatInstalledFunctionPatches;
    493     STAMCOUNTER             StatInstalledTrampoline;
    494     STAMCOUNTER             StatInstalledJump;
    495     STAMCOUNTER             StatInt3Callable;
    496     STAMCOUNTER             StatInt3BlockRun;
    497     STAMCOUNTER             StatOverwritten;
    498     STAMCOUNTER             StatFixedConflicts;
    499     STAMCOUNTER             StatFlushed;
    500     STAMCOUNTER             StatPageBoundaryCrossed;
    501     STAMCOUNTER             StatMonitored;
    502     STAMPROFILEADV          StatHandleTrap;
    503     STAMCOUNTER             StatSwitchBack;
    504     STAMCOUNTER             StatSwitchBackFail;
    505     STAMCOUNTER             StatPATMMemoryUsed;
    506     STAMCOUNTER             StatDuplicateREQSuccess;
    507     STAMCOUNTER             StatDuplicateREQFailed;
    508     STAMCOUNTER             StatDuplicateUseExisting;
    509     STAMCOUNTER             StatFunctionFound;
    510     STAMCOUNTER             StatFunctionNotFound;
    511     STAMPROFILEADV          StatPatchWrite;
    512     STAMPROFILEADV          StatPatchWriteDetect;
    513     STAMCOUNTER             StatDirty;
    514     STAMCOUNTER             StatPushTrap;
    515     STAMCOUNTER             StatPatchWriteInterpreted;
    516     STAMCOUNTER             StatPatchWriteInterpretedFailed;
    517 
    518     STAMCOUNTER             StatSysEnter;
    519     STAMCOUNTER             StatSysExit;
    520     STAMCOUNTER             StatEmulIret;
    521     STAMCOUNTER             StatEmulIretFailed;
    522 
    523     STAMCOUNTER             StatInstrDirty;
    524     STAMCOUNTER             StatInstrDirtyGood;
    525     STAMCOUNTER             StatInstrDirtyBad;
    526 
    527     STAMCOUNTER             StatPatchPageInserted;
    528     STAMCOUNTER             StatPatchPageRemoved;
    529 
    530     STAMCOUNTER             StatPatchRefreshSuccess;
    531     STAMCOUNTER             StatPatchRefreshFailed;
    532 
    533     STAMCOUNTER             StatGenRet;
    534     STAMCOUNTER             StatGenRetReused;
    535     STAMCOUNTER             StatGenJump;
    536     STAMCOUNTER             StatGenCall;
    537     STAMCOUNTER             StatGenPopf;
    538 
    539     STAMCOUNTER             StatCheckPendingIRQ;
    540 
    541     STAMCOUNTER             StatFunctionLookupReplace;
    542     STAMCOUNTER             StatFunctionLookupInsert;
    543     uint32_t                StatU32FunctionMaxSlotsUsed;
    544     uint32_t                Alignment0; /**< Align the structure size on a 8-byte boundary. */
     488    STAMCOUNTER                 StatNrOpcodeRead;
     489    STAMCOUNTER                 StatDisabled;
     490    STAMCOUNTER                 StatUnusable;
     491    STAMCOUNTER                 StatEnabled;
     492    STAMCOUNTER                 StatInstalled;
     493    STAMCOUNTER                 StatInstalledFunctionPatches;
     494    STAMCOUNTER                 StatInstalledTrampoline;
     495    STAMCOUNTER                 StatInstalledJump;
     496    STAMCOUNTER                 StatInt3Callable;
     497    STAMCOUNTER                 StatInt3BlockRun;
     498    STAMCOUNTER                 StatOverwritten;
     499    STAMCOUNTER                 StatFixedConflicts;
     500    STAMCOUNTER                 StatFlushed;
     501    STAMCOUNTER                 StatPageBoundaryCrossed;
     502    STAMCOUNTER                 StatMonitored;
     503    STAMPROFILEADV              StatHandleTrap;
     504    STAMCOUNTER                 StatSwitchBack;
     505    STAMCOUNTER                 StatSwitchBackFail;
     506    STAMCOUNTER                 StatPATMMemoryUsed;
     507    STAMCOUNTER                 StatDuplicateREQSuccess;
     508    STAMCOUNTER                 StatDuplicateREQFailed;
     509    STAMCOUNTER                 StatDuplicateUseExisting;
     510    STAMCOUNTER                 StatFunctionFound;
     511    STAMCOUNTER                 StatFunctionNotFound;
     512    STAMPROFILEADV              StatPatchWrite;
     513    STAMPROFILEADV              StatPatchWriteDetect;
     514    STAMCOUNTER                 StatDirty;
     515    STAMCOUNTER                 StatPushTrap;
     516    STAMCOUNTER                 StatPatchWriteInterpreted;
     517    STAMCOUNTER                 StatPatchWriteInterpretedFailed;
     518
     519    STAMCOUNTER                 StatSysEnter;
     520    STAMCOUNTER                 StatSysExit;
     521    STAMCOUNTER                 StatEmulIret;
     522    STAMCOUNTER                 StatEmulIretFailed;
     523
     524    STAMCOUNTER                 StatInstrDirty;
     525    STAMCOUNTER                 StatInstrDirtyGood;
     526    STAMCOUNTER                 StatInstrDirtyBad;
     527
     528    STAMCOUNTER                 StatPatchPageInserted;
     529    STAMCOUNTER                 StatPatchPageRemoved;
     530
     531    STAMCOUNTER                 StatPatchRefreshSuccess;
     532    STAMCOUNTER                 StatPatchRefreshFailed;
     533
     534    STAMCOUNTER                 StatGenRet;
     535    STAMCOUNTER                 StatGenRetReused;
     536    STAMCOUNTER                 StatGenJump;
     537    STAMCOUNTER                 StatGenCall;
     538    STAMCOUNTER                 StatGenPopf;
     539
     540    STAMCOUNTER                 StatCheckPendingIRQ;
     541
     542    STAMCOUNTER                 StatFunctionLookupReplace;
     543    STAMCOUNTER                 StatFunctionLookupInsert;
     544    uint32_t                    StatU32FunctionMaxSlotsUsed;
     545    uint32_t                    Alignment0; /**< Align the structure size on a 8-byte boundary. */
    545546} PATM, *PPATM;
    546547
     
    698699typedef struct
    699700{
    700     PVM           pVM;
    701     PPATCHINFO    pPatchInfo;
     701    PVM                  pVM;
     702    PPATCHINFO           pPatchInfo;
    702703    R3PTRTYPE(uint8_t *) pInstrHC;
    703     RTRCPTR       pInstrGC;
    704     uint32_t      fReadFlags;
     704    RTRCPTR              pInstrGC;
     705    uint32_t             fReadFlags;
    705706} PATMDISASM, *PPATMDISASM;
    706707
Note: See TracChangeset for help on using the changeset viewer.

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