|
|
| version 1.15, 2004/03/07 02:10:24 | version 1.27, 2012/01/08 11:32:16 |
|---|---|
| Line 1 | Line 1 |
| /* $Id$ */ | |
| /* | /* |
| * Copyright (c) 2002-2003 NONAKA Kimihiro | * Copyright (c) 2002-2003 NONAKA Kimihiro |
| * All rights reserved. | * All rights reserved. |
| Line 12 | Line 10 |
| * 2. Redistributions in binary form must reproduce the above copyright | * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the | * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. | * documentation and/or other materials provided with the distribution. |
| * 3. The name of the author may not be used to endorse or promote products | |
| * derived from this software without specific prior written permission. | |
| * | * |
| * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
| * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
| Line 34 | Line 30 |
| #include "inst_table.h" | #include "inst_table.h" |
| #if defined(ENABLE_TRAP) | |
| #include "steptrap.h" | |
| #endif | |
| sigjmp_buf exec_1step_jmpbuf; | sigjmp_buf exec_1step_jmpbuf; |
| Line 54 int ctx_index = 0; | Line 54 int ctx_index = 0; |
| int cpu_inst_trace = 0; | int cpu_inst_trace = 0; |
| #endif | #endif |
| #if defined(DEBUG) | |
| // #define IPTRACE (1 << 14) | int cpu_debug_rep_cont = 0; |
| CPU_REGS cpu_debug_rep_regs; | |
| #if defined(TRACE) && IPTRACE | |
| static UINT trpos = 0; | |
| static UINT32 trcs[IPTRACE]; | |
| static UINT32 treip[IPTRACE]; | |
| void iptrace_out(void) { | |
| FILEH fh; | |
| UINT s; | |
| UINT32 cs; | |
| UINT32 eip; | |
| char buf[32]; | |
| s = trpos; | |
| if (s > IPTRACE) { | |
| s -= IPTRACE; | |
| } | |
| else { | |
| s = 0; | |
| } | |
| fh = file_create_c("his.txt"); | |
| while(s < trpos) { | |
| cs = trcs[s & (IPTRACE - 1)]; | |
| eip = treip[s & (IPTRACE - 1)]; | |
| s++; | |
| SPRINTF(buf, "%.4x:%.8x\r\n", cs, eip); | |
| file_write(fh, buf, strlen(buf)); | |
| } | |
| file_close(fh); | |
| } | |
| #endif | #endif |
| Line 99 exec_1step(void) | Line 69 exec_1step(void) |
| CPU_PREV_EIP = CPU_EIP; | CPU_PREV_EIP = CPU_EIP; |
| CPU_STATSAVE.cpu_inst = CPU_STATSAVE.cpu_inst_default; | CPU_STATSAVE.cpu_inst = CPU_STATSAVE.cpu_inst_default; |
| #if defined(TRACE) && IPTRACE | #if defined(ENABLE_TRAP) |
| trcs[trpos & (IPTRACE - 1)] = CPU_CS; | steptrap(CPU_CS, CPU_EIP); |
| treip[trpos & (IPTRACE - 1)] = CPU_EIP; | |
| trpos++; | |
| #endif | #endif |
| #if defined(IA32_INSTRUCTION_TRACE) | #if defined(IA32_INSTRUCTION_TRACE) |
| Line 121 exec_1step(void) | Line 89 exec_1step(void) |
| buf[0] = '\0'; | buf[0] = '\0'; |
| for (i = 0; i < len; i++) { | for (i = 0; i < len; i++) { |
| snprintf(tmp, sizeof(tmp), "%02x ", d->opcode[i]); | snprintf(tmp, sizeof(tmp), "%02x ", d->opbyte[i]); |
| milstr_ncat(buf, tmp, sizeof(buf)); | milstr_ncat(buf, tmp, sizeof(buf)); |
| } | } |
| for (; i < 8; i++) { | for (; i < 8; i++) { |
| Line 131 exec_1step(void) | Line 99 exec_1step(void) |
| buf[0] = '\0'; | buf[0] = '\0'; |
| for (; i < d->nopbytes; i++) { | for (; i < d->nopbytes; i++) { |
| snprintf(tmp, sizeof(tmp), "%02x ", d->opcode[i]); | snprintf(tmp, sizeof(tmp), "%02x ", d->opbyte[i]); |
| milstr_ncat(buf, tmp, sizeof(buf)); | milstr_ncat(buf, tmp, sizeof(buf)); |
| if ((i % 8) == 7) { | if ((i % 8) == 7) { |
| VERBOSE((" : %s", buf)); | VERBOSE((" : %s", buf)); |
| Line 145 exec_1step(void) | Line 113 exec_1step(void) |
| } | } |
| ctx[ctx_index].opbytes = 0; | ctx[ctx_index].opbytes = 0; |
| #endif | #endif |
| #if defined(IA32_SUPPORT_DEBUG_REGISTER) | |
| if (CPU_STAT_BP && !(CPU_EFLAG & RF_FLAG)) { | |
| int i; | |
| for (i = 0; i < CPU_DEBUG_REG_INDEX_NUM; i++) { | |
| if ((CPU_STAT_BP & (1 << i)) | |
| && (CPU_DR7_GET_RW(i) == CPU_DR7_RW_CODE) | |
| && (CPU_DR(i) == CPU_EIP) | |
| && (CPU_DR7_GET_LEN(i) == 0)) { | |
| CPU_DR6 |= CPU_DR6_B(i); | |
| EXCEPTION(DB_EXCEPTION, 0); | |
| } | |
| } | |
| } | |
| #endif /* IA32_SUPPORT_DEBUG_REGISTER */ | |
| for (prefix = 0; prefix < MAX_PREFIX; prefix++) { | for (prefix = 0; prefix < MAX_PREFIX; prefix++) { |
| GET_PCBYTE(op); | GET_PCBYTE(op); |
| #if defined(IA32_INSTRUCTION_TRACE) | #if defined(IA32_INSTRUCTION_TRACE) |
| Line 175 exec_1step(void) | Line 159 exec_1step(void) |
| /* normal / rep, but not use */ | /* normal / rep, but not use */ |
| if (!(insttable_info[op] & INST_STRING) || !CPU_INST_REPUSE) { | if (!(insttable_info[op] & INST_STRING) || !CPU_INST_REPUSE) { |
| #if defined(DEBUG) | |
| cpu_debug_rep_cont = 0; | |
| #endif | |
| (*insttable_1byte[CPU_INST_OP32][op])(); | (*insttable_1byte[CPU_INST_OP32][op])(); |
| #if defined(IA32_SUPPORT_DEBUG_REGISTER) | |
| goto check_break_point; | |
| #else | |
| return; | return; |
| #endif | |
| } | } |
| /* rep */ | /* rep */ |
| CPU_WORKCLOCK(5); | CPU_WORKCLOCK(5); |
| #if defined(DEBUG) | |
| if (!cpu_debug_rep_cont) { | |
| cpu_debug_rep_cont = 1; | |
| cpu_debug_rep_regs = CPU_STATSAVE.cpu_regs; | |
| } | |
| #endif | |
| if (!CPU_INST_AS32) { | if (!CPU_INST_AS32) { |
| if (CPU_CX != 0) { | if (CPU_CX != 0) { |
| if (!(insttable_info[op] & REP_CHECKZF)) { | if (!(insttable_info[op] & REP_CHECKZF)) { |
| /* rep */ | /* rep */ |
| do { | for (;;) { |
| (*insttable_1byte[CPU_INST_OP32][op])(); | (*insttable_1byte[CPU_INST_OP32][op])(); |
| } while (--CPU_CX); | if (--CPU_CX == 0) { |
| #if defined(DEBUG) | |
| cpu_debug_rep_cont = 0; | |
| #endif | |
| break; | |
| } | |
| if (CPU_REMCLOCK <= 0) { | |
| CPU_EIP = CPU_PREV_EIP; | |
| break; | |
| } | |
| } | |
| } else if (CPU_INST_REPUSE != 0xf2) { | } else if (CPU_INST_REPUSE != 0xf2) { |
| /* repe */ | /* repe */ |
| do { | for (;;) { |
| (*insttable_1byte[CPU_INST_OP32][op])(); | (*insttable_1byte[CPU_INST_OP32][op])(); |
| } while (--CPU_CX && (CPU_FLAGL & Z_FLAG)); | if (--CPU_CX == 0 || CC_NZ) { |
| #if defined(DEBUG) | |
| cpu_debug_rep_cont = 0; | |
| #endif | |
| break; | |
| } | |
| if (CPU_REMCLOCK <= 0) { | |
| CPU_EIP = CPU_PREV_EIP; | |
| break; | |
| } | |
| } | |
| } else { | } else { |
| /* repne */ | /* repne */ |
| do { | for (;;) { |
| (*insttable_1byte[CPU_INST_OP32][op])(); | (*insttable_1byte[CPU_INST_OP32][op])(); |
| } while (--CPU_CX && !(CPU_FLAGL & Z_FLAG)); | if (--CPU_CX == 0 || CC_Z) { |
| #if defined(DEBUG) | |
| cpu_debug_rep_cont = 0; | |
| #endif | |
| break; | |
| } | |
| if (CPU_REMCLOCK <= 0) { | |
| CPU_EIP = CPU_PREV_EIP; | |
| break; | |
| } | |
| } | |
| } | } |
| } | } |
| } else { | } else { |
| if (CPU_ECX != 0) { | if (CPU_ECX != 0) { |
| if (!(insttable_info[op] & REP_CHECKZF)) { | if (!(insttable_info[op] & REP_CHECKZF)) { |
| /* rep */ | /* rep */ |
| do { | for (;;) { |
| (*insttable_1byte[CPU_INST_OP32][op])(); | (*insttable_1byte[CPU_INST_OP32][op])(); |
| } while (--CPU_ECX); | if (--CPU_ECX == 0) { |
| #if defined(DEBUG) | |
| cpu_debug_rep_cont = 0; | |
| #endif | |
| break; | |
| } | |
| if (CPU_REMCLOCK <= 0) { | |
| CPU_EIP = CPU_PREV_EIP; | |
| break; | |
| } | |
| } | |
| } else if (CPU_INST_REPUSE != 0xf2) { | } else if (CPU_INST_REPUSE != 0xf2) { |
| /* repe */ | /* repe */ |
| do { | for (;;) { |
| (*insttable_1byte[CPU_INST_OP32][op])(); | (*insttable_1byte[CPU_INST_OP32][op])(); |
| } while (--CPU_ECX && (CPU_FLAGL & Z_FLAG)); | if (--CPU_ECX == 0 || CC_NZ) { |
| #if defined(DEBUG) | |
| cpu_debug_rep_cont = 0; | |
| #endif | |
| break; | |
| } | |
| if (CPU_REMCLOCK <= 0) { | |
| CPU_EIP = CPU_PREV_EIP; | |
| break; | |
| } | |
| } | |
| } else { | } else { |
| /* repne */ | /* repne */ |
| do { | for (;;) { |
| (*insttable_1byte[CPU_INST_OP32][op])(); | (*insttable_1byte[CPU_INST_OP32][op])(); |
| } while (--CPU_ECX && !(CPU_FLAGL & Z_FLAG)); | if (--CPU_ECX == 0 || CC_Z) { |
| #if defined(DEBUG) | |
| cpu_debug_rep_cont = 0; | |
| #endif | |
| break; | |
| } | |
| if (CPU_REMCLOCK <= 0) { | |
| CPU_EIP = CPU_PREV_EIP; | |
| break; | |
| } | |
| } | |
| } | } |
| } | } |
| } | } |
| #if defined(IA32_SUPPORT_DEBUG_REGISTER) | |
| check_break_point: | |
| if (CPU_TRAP || (CPU_STAT_BP_EVENT & ~CPU_STAT_BP_EVENT_RF)) { | |
| UINT8 orig = CPU_STAT_BP_EVENT & ~CPU_STAT_BP_EVENT_RF; | |
| CPU_STAT_BP_EVENT &= CPU_STAT_BP_EVENT_RF; | |
| CPU_DR6 |= (orig & 0xf); | |
| if (orig & CPU_STAT_BP_EVENT_TASK) { | |
| CPU_DR6 |= CPU_DR6_BT; | |
| } | |
| if (CPU_TRAP) { | |
| CPU_DR6 |= CPU_DR6_BS; | |
| } | |
| INTERRUPT(DB_EXCEPTION, INTR_TYPE_EXCEPTION); | |
| } | |
| if (CPU_EFLAG & RF_FLAG) { | |
| if (CPU_STAT_BP_EVENT & CPU_STAT_BP_EVENT_RF) { | |
| /* after IRETD or task switch */ | |
| CPU_STAT_BP_EVENT &= ~CPU_STAT_BP_EVENT_RF; | |
| } else { | |
| CPU_EFLAG &= ~RF_FLAG; | |
| } | |
| } | |
| #endif /* IA32_SUPPORT_DEBUG_REGISTER */ | |
| } | } |