VirtualBox

Ignore:
Timestamp:
Feb 22, 2011 3:04:28 PM (14 years ago)
Author:
vboxsync
Message:

VMM/REM: Made .remstep work to some degree (might skip interrupts/traps).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/recompiler/VBoxRecompiler.c

    r35994 r36054  
    10641064
    10651065/**
     1066 * Used by REMR3Run to handle the case where CPU_EMULATE_SINGLE_STEP is set.
     1067 *
     1068 * @returns VBox status code.
     1069 *
     1070 * @param   pVM                 The VM handle.
     1071 * @param   pVCpu               The Virtual CPU handle.
     1072 */
     1073static int remR3RunLoggingStep(PVM pVM, PVMCPU pVCpu)
     1074{
     1075    int rc;
     1076    Assert(!pVM->rem.s.Env.singlestep_enabled);
     1077    Assert(pVM->rem.s.fInREM);
     1078/* #define REM_USE_QEMU_SINGLE_STEP_FOR_LOGGING - slow (tb flushing?) */
     1079#ifdef REM_USE_QEMU_SINGLE_STEP_FOR_LOGGING
     1080    cpu_single_step(&pVM->rem.s.Env, 1);
     1081#endif
     1082
     1083    /*
     1084     * Now we set the execute single instruction flag and enter the cpu_exec loop.
     1085     */
     1086    for (;;)
     1087    {
     1088        char szBuf[256];
     1089
     1090        /*
     1091         * Log the current registers state and instruction.
     1092         */
     1093        remR3StateUpdate(pVM, pVCpu);
     1094        DBGFR3Info(pVM, "cpumguest", NULL, NULL);
     1095        szBuf[0] = '\0';
     1096        rc = DBGFR3DisasInstrEx(pVM,
     1097                                pVCpu->idCpu,
     1098                                0, /* Sel */
     1099                                0, /* GCPtr */
     1100                                DBGF_DISAS_FLAGS_CURRENT_GUEST
     1101                                | DBGF_DISAS_FLAGS_DEFAULT_MODE
     1102                                | DBGF_DISAS_FLAGS_HID_SEL_REGS_VALID,
     1103                                szBuf,
     1104                                sizeof(szBuf),
     1105                                NULL);
     1106        if (RT_FAILURE(rc))
     1107            RTStrPrintf(szBuf, sizeof(szBuf), "DBGFR3DisasInstrEx failed with rc=%Rrc\n", rc);
     1108        RTLogPrintf("CPU%d: %s\n", pVCpu->idCpu, szBuf);
     1109
     1110        /*
     1111         * Execute the instruction.
     1112         */
     1113        TMNotifyStartOfExecution(pVCpu);
     1114
     1115        if (   pVM->rem.s.Env.exception_index < 0
     1116            || pVM->rem.s.Env.exception_index > 256)
     1117            pVM->rem.s.Env.exception_index = -1; /** @todo We need to do similar stuff elsewhere, I think. */
     1118
     1119#ifdef REM_USE_QEMU_SINGLE_STEP_FOR_LOGGING
     1120        pVM->rem.s.Env.interrupt_request = 0;
     1121#else
     1122        pVM->rem.s.Env.interrupt_request = CPU_INTERRUPT_SINGLE_INSTR;
     1123#endif
     1124        if (VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC))
     1125            pVM->rem.s.Env.interrupt_request |= CPU_INTERRUPT_HARD;
     1126        RTLogPrintf("remR3RunLoggingStep: interrupt_request=%#x halted=%d exception_index=%#x\n", rc,
     1127                    pVM->rem.s.Env.interrupt_request,
     1128                    pVM->rem.s.Env.halted,
     1129                    pVM->rem.s.Env.exception_index
     1130                    );
     1131
     1132        rc = cpu_exec(&pVM->rem.s.Env);
     1133
     1134        RTLogPrintf("remR3RunLoggingStep: cpu_exec -> %#x interrupt_request=%#x halted=%d exception_index=%#x\n", rc,
     1135                    pVM->rem.s.Env.interrupt_request,
     1136                    pVM->rem.s.Env.halted,
     1137                    pVM->rem.s.Env.exception_index
     1138                    );
     1139
     1140        TMNotifyEndOfExecution(pVCpu);
     1141
     1142        switch (rc)
     1143        {
     1144#ifndef REM_USE_QEMU_SINGLE_STEP_FOR_LOGGING
     1145            /*
     1146             * The normal exit.
     1147             */
     1148            case EXCP_SINGLE_INSTR:
     1149                if (   !VM_FF_ISPENDING(pVM, VM_FF_ALL_REM_MASK)
     1150                    && !VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_ALL_REM_MASK))
     1151                    continue;
     1152                RTLogPrintf("remR3RunLoggingStep: rc=VINF_SUCCESS w/ FFs (%#x/%#x)\n",
     1153                            pVM->fGlobalForcedActions, pVCpu->fLocalForcedActions);
     1154                rc = VINF_SUCCESS;
     1155                break;
     1156
     1157#else
     1158            /*
     1159             * The normal exit, check for breakpoints at PC just to be sure.
     1160             */
     1161#endif
     1162            case EXCP_DEBUG:
     1163                rc = VINF_EM_DBG_STEPPED;
     1164                if (pVM->rem.s.Env.nb_breakpoints > 0)
     1165                {
     1166                    RTGCPTR     GCPtrPC = pVM->rem.s.Env.eip + pVM->rem.s.Env.segs[R_CS].base;
     1167                    int         iBP;
     1168                    for (iBP = 0; iBP < pVM->rem.s.Env.nb_breakpoints; iBP++)
     1169                        if (pVM->rem.s.Env.breakpoints[iBP] == GCPtrPC)
     1170                        {
     1171                            rc = VINF_EM_DBG_BREAKPOINT;
     1172                            RTLogPrintf("remR3RunLoggingStep: cpu_exec -> EXCP_DEBUG rc=%Rrc iBP=%d GCPtrPC=%RGv\n", rc, iBP, GCPtrPC);
     1173                            break;
     1174                        }
     1175                }
     1176#ifdef REM_USE_QEMU_SINGLE_STEP_FOR_LOGGING
     1177                if (rc == VINF_EM_DBG_STEPPED)
     1178                {
     1179                    if (   !VM_FF_ISPENDING(pVM, VM_FF_ALL_REM_MASK)
     1180                        && !VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_ALL_REM_MASK))
     1181                        continue;
     1182
     1183                    RTLogPrintf("remR3RunLoggingStep: rc=VINF_SUCCESS w/ FFs (%#x/%#x)\n",
     1184                                pVM->fGlobalForcedActions, pVCpu->fLocalForcedActions);
     1185                    rc = VINF_SUCCESS;
     1186                }
     1187#endif
     1188                break;
     1189
     1190            /*
     1191             * If we take a trap or start servicing a pending interrupt, we might end up here.
     1192             * (Timer thread or some other thread wishing EMT's attention.)
     1193             */
     1194            case EXCP_INTERRUPT:
     1195                RTLogPrintf("remR3RunLoggingStep: cpu_exec -> EXCP_INTERRUPT rc=VINF_SUCCESS\n");
     1196                rc = VINF_SUCCESS;
     1197                break;
     1198
     1199            /*
     1200             * hlt instruction.
     1201             */
     1202            case EXCP_HLT:
     1203                RTLogPrintf("remR3RunLoggingStep: cpu_exec -> EXCP_HLT rc=VINF_EM_HALT\n");
     1204                rc = VINF_EM_HALT;
     1205                break;
     1206
     1207            /*
     1208             * The VM has halted.
     1209             */
     1210            case EXCP_HALTED:
     1211                RTLogPrintf("remR3RunLoggingStep: cpu_exec -> EXCP_HALTED rc=VINF_EM_HALT\n");
     1212                rc = VINF_EM_HALT;
     1213                break;
     1214
     1215            /*
     1216             * Switch to RAW-mode.
     1217             */
     1218            case EXCP_EXECUTE_RAW:
     1219                RTLogPrintf("remR3RunLoggingStep: cpu_exec -> EXCP_EXECUTE_RAW rc=VINF_EM_RESCHEDULE_RAW\n");
     1220                rc = VINF_EM_RESCHEDULE_RAW;
     1221                break;
     1222
     1223            /*
     1224             * Switch to hardware accelerated RAW-mode.
     1225             */
     1226            case EXCP_EXECUTE_HWACC:
     1227                RTLogPrintf("remR3RunLoggingStep: cpu_exec -> EXCP_EXECUTE_HWACC rc=VINF_EM_RESCHEDULE_HWACC\n");
     1228                rc = VINF_EM_RESCHEDULE_HWACC;
     1229                break;
     1230
     1231            /*
     1232             * An EM RC was raised (VMR3Reset/Suspend/PowerOff/some-fatal-error).
     1233             */
     1234            case EXCP_RC:
     1235                RTLogPrintf("remR3RunLoggingStep: cpu_exec -> EXCP_RC rc=%Rrc\n", pVM->rem.s.rc);
     1236                rc = pVM->rem.s.rc;
     1237                pVM->rem.s.rc = VERR_INTERNAL_ERROR;
     1238                break;
     1239
     1240            /*
     1241             * Figure out the rest when they arrive....
     1242             */
     1243            default:
     1244                AssertMsgFailed(("rc=%d\n", rc));
     1245                RTLogPrintf("remR3RunLoggingStep: cpu_exec -> %d rc=VINF_EM_RESCHEDULE\n", rc);
     1246                rc = VINF_EM_RESCHEDULE;
     1247                break;
     1248        }
     1249        break;
     1250    }
     1251
     1252#ifdef REM_USE_QEMU_SINGLE_STEP_FOR_LOGGING
     1253    cpu_single_step(&pVM->rem.s.Env, 0);
     1254#else
     1255    pVM->rem.s.Env.interrupt_request &= ~(CPU_INTERRUPT_SINGLE_INSTR | CPU_INTERRUPT_SINGLE_INSTR_IN_FLIGHT);
     1256#endif
     1257    return rc;
     1258}
     1259
     1260
     1261/**
    10661262 * Runs code in recompiled mode.
    10671263 *
     
    10791275{
    10801276    int rc;
     1277
     1278    if (RT_UNLIKELY(pVM->rem.s.Env.state & CPU_EMULATE_SINGLE_STEP))
     1279        return remR3RunLoggingStep(pVM, pVCpu);
     1280
     1281    Assert(pVM->rem.s.fInREM);
    10811282    Log2(("REMR3Run: (cs:eip=%04x:%RGv)\n", pVM->rem.s.Env.segs[R_CS].selector, (RTGCPTR)pVM->rem.s.Env.eip));
    1082     Assert(pVM->rem.s.fInREM);
    10831283
    10841284    TMNotifyStartOfExecution(pVCpu);
     
    11951395 * Check if the cpu state is suitable for Raw execution.
    11961396 *
    1197  * @returns boolean
     1397 * @returns true if RAW/HWACC mode is ok, false if we should stay in REM.
     1398 *
    11981399 * @param   env         The CPU env struct.
    11991400 * @param   eip         The EIP to check this for (might differ from env->eip).
     
    12121413    /* Update counter. */
    12131414    env->pVM->rem.s.cCanExecuteRaw++;
     1415
     1416    /* Never when single stepping+logging guest code. */
     1417    if (env->state & CPU_EMULATE_SINGLE_STEP)
     1418        return false;
    12141419
    12151420    if (HWACCMIsEnabled(env->pVM))
     
    37393944     * Log registers if requested.
    37403945     */
    3741     if (!fLog2)
     3946    if (fLog2)
    37423947        DBGFR3InfoLog(pVM, "cpumguest", pszPrefix);
    37433948
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