Common Source Code Project for Qt (a.k.a for FM-7).
Revision | 05b33b663e2c4e90f0d0dbe9d558fe67d7e0307a (tree) |
---|---|
Zeit | 2020-05-27 19:50:32 |
Autor | K.Ohta <whatisthis.sowhat@gmai...> |
Commiter | K.Ohta |
[VM][I386_NP21][DEBUGGER] Add call trace feature.
@@ -806,27 +806,21 @@ void* debugger_thread(void *lpx) | ||
806 | 806 | strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", timedat); |
807 | 807 | log_fio.Fprintf("**** Start of logging CALL TRACE %d steps for %s at %s.%06ld ****\n\n", steps, target->this_device_name, timestr, tv.tv_usec); |
808 | 808 | } |
809 | - int begin_step = (target_debugger->cpu_trace_ptr - steps) & (MAX_CPU_TRACE - 1); | |
810 | - int max_step = target_debugger->cpu_trace_ptr & (MAX_CPU_TRACE - 1); | |
809 | + int begin_step = (target_debugger->cpu_trace_call_ptr - steps) & (MAX_CPU_TRACE - 1); | |
810 | + int max_step = target_debugger->cpu_trace_call_ptr & (MAX_CPU_TRACE - 1); | |
811 | 811 | int steps_left = steps; |
812 | - if(!(target_debugger->cpu_trace_overwrap)) { | |
813 | - if(steps_left > max_step) { | |
814 | - begin_step = 0; | |
815 | - steps_left = max_step; | |
816 | - steps = max_step; | |
817 | - } | |
818 | - } | |
819 | 812 | for(int i = begin_step; i != max_step; i = ((i + 1) & (MAX_CPU_TRACE - 1)) ) { |
820 | 813 | int index = i; |
821 | 814 | |
822 | 815 | if(!(target_debugger->cpu_trace[index] & ~target->get_debug_prog_addr_mask())) { |
823 | 816 | int len = 0; |
824 | 817 | bool hit = target->debug_rewind_call_trace( |
825 | - target_debugger->cpu_trace[index] & target->get_debug_prog_addr_mask(), | |
818 | + target_debugger->cpu_trace_call[i] & target->get_debug_prog_addr_mask(), | |
826 | 819 | len, |
827 | 820 | buffer, |
828 | 821 | array_length(buffer), |
829 | - target_debugger->cpu_trace_userdata[index]); | |
822 | + target_debugger->cpu_trace_call_type[i] | |
823 | + ); | |
830 | 824 | if(hit) { |
831 | 825 | const _TCHAR *name = my_get_symbol(target, target_debugger->cpu_trace[index] & target->get_debug_prog_addr_mask()); |
832 | 826 | if(name != NULL) { |
@@ -1,6 +1,6 @@ | ||
1 | 1 | message("* vm/common_vm") |
2 | 2 | |
3 | -SET(THIS_LIB_VERSION 2.26.1) | |
3 | +SET(THIS_LIB_VERSION 2.26.2) | |
4 | 4 | |
5 | 5 | #include(cotire) |
6 | 6 | set(s_vm_common_vm_srcs |
@@ -21,8 +21,7 @@ | ||
21 | 21 | #define MAX_COMMAND_HISTORY 32 |
22 | 22 | //#define MAX_CPU_TRACE 0x01000000 /* 16Msteps */ |
23 | 23 | #define MAX_CPU_TRACE 0x00100000 /* 1Msteps */ |
24 | - | |
25 | - | |
24 | +#define TRACE_TYPE_CALL 0x00000000 | |
26 | 25 | typedef struct { |
27 | 26 | struct { |
28 | 27 | uint32_t addr, mask; |
@@ -100,10 +99,13 @@ public: | ||
100 | 99 | memset(cpu_trace_exp, 0x00, sizeof(cpu_trace_exp)); |
101 | 100 | memset(cpu_trace_exp_map, 0x00, sizeof(cpu_trace_exp_map)); |
102 | 101 | memset(cpu_trace_userdata, 0x00, sizeof(cpu_trace_userdata)); |
102 | + memset(cpu_trace_call_type, 0x00, sizeof(cpu_trace_call_type)); | |
103 | + memset(cpu_trace_call, 0x00, sizeof(cpu_trace_call)); | |
103 | 104 | exception_happened = false; |
104 | 105 | stop_on_exception = true; |
105 | 106 | prev_cpu_trace = 0xffffffff; |
106 | 107 | cpu_trace_ptr = 0; |
108 | + cpu_trace_call_ptr = 0; | |
107 | 109 | cpu_trace_overwrap = false; |
108 | 110 | set_device_name(_T("Debugger")); |
109 | 111 | } |
@@ -499,17 +501,39 @@ public: | ||
499 | 501 | } |
500 | 502 | first_symbol = last_symbol = NULL; |
501 | 503 | } |
502 | - void add_cpu_trace_exception(uint64_t exception_code) | |
504 | + void __FASTCALL add_cpu_trace_exception(uint64_t exception_code) | |
503 | 505 | { |
504 | 506 | cpu_trace_exp[(cpu_trace_ptr - 1) & (MAX_CPU_TRACE - 1)] = exception_code; |
505 | 507 | cpu_trace_exp_map[(cpu_trace_ptr - 1) & (MAX_CPU_TRACE - 1)] = true; |
506 | 508 | } |
507 | 509 | // Userdata should after executing instruction. |
508 | - void add_cpu_trace_userdata(uint32_t data, uint32_t mask) | |
510 | + void __FASTCALL add_cpu_trace_userdata(uint32_t data, uint32_t mask) | |
509 | 511 | { |
510 | 512 | cpu_trace_userdata[(cpu_trace_ptr - 1) & (MAX_CPU_TRACE - 1)] &= ~mask; |
511 | 513 | cpu_trace_userdata[(cpu_trace_ptr - 1) & (MAX_CPU_TRACE - 1)] |= (data & mask); |
512 | 514 | } |
515 | + void __FASTCALL add_cpu_trace_irq(uint32_t pc, uint32_t irq) | |
516 | + { | |
517 | + cpu_trace_call[cpu_trace_call_ptr] = pc; | |
518 | + cpu_trace_call_type[cpu_trace_call_ptr] = ((uint64_t)irq << 32); | |
519 | + cpu_trace_call_ptr++; | |
520 | + cpu_trace_call_ptr &= (MAX_CPU_TRACE - 1); | |
521 | + } | |
522 | + void __FASTCALL add_cpu_trace_call(uint32_t pc, uint32_t target) | |
523 | + { | |
524 | + cpu_trace_call[cpu_trace_call_ptr] = pc; | |
525 | + cpu_trace_call_type[cpu_trace_call_ptr] = (uint64_t)target; | |
526 | + cpu_trace_call_ptr++; | |
527 | + cpu_trace_call_ptr &= (MAX_CPU_TRACE - 1); | |
528 | + } | |
529 | + void __FASTCALL add_cpu_trace_return(uint32_t pc) | |
530 | + { | |
531 | + cpu_trace_call[cpu_trace_call_ptr] = pc; | |
532 | + cpu_trace_call_type[cpu_trace_call_ptr] = (uint64_t)0x80000000 << 32; | |
533 | + cpu_trace_call_ptr++; | |
534 | + cpu_trace_call_ptr &= (MAX_CPU_TRACE - 1); | |
535 | + } | |
536 | + | |
513 | 537 | void add_cpu_trace(uint32_t pc) |
514 | 538 | { |
515 | 539 | if(prev_cpu_trace != pc) { |
@@ -536,9 +560,12 @@ public: | ||
536 | 560 | uint32_t cpu_trace[MAX_CPU_TRACE], prev_cpu_trace; |
537 | 561 | uint64_t cpu_trace_exp[MAX_CPU_TRACE]; |
538 | 562 | uint32_t cpu_trace_userdata[MAX_CPU_TRACE]; // ToDo: Is need larger userdata? |
563 | + uint32_t cpu_trace_call[MAX_CPU_TRACE]; // ToDo: Is need larger userdata? | |
564 | + uint64_t cpu_trace_call_type[MAX_CPU_TRACE]; // ToDo: Is need larger userdata? | |
539 | 565 | |
540 | 566 | bool cpu_trace_exp_map[MAX_CPU_TRACE]; |
541 | 567 | int cpu_trace_ptr; |
568 | + int cpu_trace_call_ptr; | |
542 | 569 | bool cpu_trace_overwrap; |
543 | 570 | }; |
544 | 571 |
@@ -1234,7 +1234,7 @@ public: | ||
1234 | 1234 | { |
1235 | 1235 | return 0; |
1236 | 1236 | } |
1237 | - virtual bool debug_rewind_call_trace(uint32_t pc, int &size, _TCHAR* buffer, size_t buffer_len, uint32_t userdata = 0) | |
1237 | + virtual bool debug_rewind_call_trace(uint32_t pc, int &size, _TCHAR* buffer, size_t buffer_len, uint64_t userdata = 0) | |
1238 | 1238 | { |
1239 | 1239 | size = 0; |
1240 | 1240 | return false; |
@@ -315,9 +315,16 @@ int I386::run_one_opecode() | ||
315 | 315 | CPU_EXEC(); |
316 | 316 | if(nmi_pending) { |
317 | 317 | CPU_INTERRUPT(2, 0); |
318 | + if(device_debugger != NULL) { | |
319 | + device_debugger->add_cpu_trace_irq(get_pc(), 2); | |
320 | + } | |
318 | 321 | nmi_pending = false; |
319 | 322 | } else if(irq_pending && CPU_isEI) { |
320 | - CPU_INTERRUPT(device_pic->get_intr_ack(), 0); | |
323 | + uint32_t intr_level = device_pic->get_intr_ack(); | |
324 | + CPU_INTERRUPT(intr_level, 0); | |
325 | + if(device_debugger != NULL) { | |
326 | + device_debugger->add_cpu_trace_irq(get_pc(), intr_level); | |
327 | + } | |
321 | 328 | irq_pending = false; |
322 | 329 | device_pic->update_intr(); |
323 | 330 | } |
@@ -336,9 +343,16 @@ int I386::run_one_opecode() | ||
336 | 343 | CPU_EXEC(); |
337 | 344 | if(nmi_pending) { |
338 | 345 | CPU_INTERRUPT(2, 0); |
346 | + if(device_debugger != NULL) { | |
347 | + device_debugger->add_cpu_trace_irq(get_pc(), 2); | |
348 | + } | |
339 | 349 | nmi_pending = false; |
340 | 350 | } else if(irq_pending && CPU_isEI) { |
341 | - CPU_INTERRUPT(device_pic->get_intr_ack(), 0); | |
351 | + uint32_t intr_level = device_pic->get_intr_ack(); | |
352 | + CPU_INTERRUPT(intr_level, 0); | |
353 | + if(device_debugger != NULL) { | |
354 | + device_debugger->add_cpu_trace_irq(get_pc(), intr_level); | |
355 | + } | |
342 | 356 | irq_pending = false; |
343 | 357 | device_pic->update_intr(); |
344 | 358 | } |
@@ -717,37 +731,25 @@ bool I386::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) | ||
717 | 731 | return true; |
718 | 732 | } |
719 | 733 | |
720 | -bool I386::debug_rewind_call_trace(uint32_t pc, int &size, _TCHAR* buffer, size_t buffer_len, uint32_t userdata) | |
734 | +bool I386::debug_rewind_call_trace(uint32_t pc, int &size, _TCHAR* buffer, size_t buffer_len, uint64_t userdata) | |
721 | 735 | { |
722 | 736 | size = 0; |
723 | 737 | _TCHAR prefix[128] = {0}; |
724 | - if((userdata & 0x8000fff0) != 0) { // Maybe call/ret/jmp/intr | |
725 | - if(userdata & I386_TRACE_DATA_BIT_IRQ) { | |
726 | - strncpy(prefix, _T("*IRQ HAPPENED*"), 127); | |
727 | - } else if(userdata & I386_TRACE_DATA_BIT_EXCEPTION) { | |
728 | - strncpy(prefix, _T("*EXCEPTION HAPPENED*"), 127); | |
729 | - } else if(userdata & I386_TRACE_DATA_BIT_INT) { | |
730 | - strncpy(prefix, _T("*INTXX*"), 127); | |
731 | - } else if(userdata & I386_TRACE_DATA_BIT_RET) { | |
732 | - strncpy(prefix, _T("*RETURN*"), 127); | |
733 | - } else if(userdata & I386_TRACE_DATA_BIT_JMP) { | |
734 | - strncpy(prefix, _T("*JMP*"), 127); | |
735 | - } else if(userdata & I386_TRACE_DATA_BIT_CALL) { | |
736 | - strncpy(prefix, _T("*CALL*"), 127); | |
737 | - } else { | |
738 | - // Not meanful | |
739 | - return false; | |
740 | - } | |
741 | - _TCHAR dasmbuf[1024] = {0}; | |
742 | - size = debug_dasm_with_userdata(pc, dasmbuf, 1023, userdata); | |
743 | - if(size <= 0) { | |
744 | - strncpy(dasmbuf, 1023, _T("**UNDEFINED BEHAVIOR**")); | |
745 | - } | |
746 | - my_stprintf_s(buffer, buffer_len, _T("HIT %s @%08X %s\n"), | |
747 | - prefix, pc, dasmbuf); | |
748 | - return true; | |
738 | + if((userdata & ((uint64_t)0xffffffff << 32)) == ((uint64_t)0x80000000 << 32)) { | |
739 | + my_stprintf_s(prefix, 127, _T("*RETURN*")); | |
740 | + } else if((userdata & (uint64_t)0xffffffff00000000) != 0) { | |
741 | + my_stprintf_s(prefix, 127, _T("*IRQ %X HAPPENED*"), (uint32_t)(userdata >> 32)); | |
742 | + } else { | |
743 | + my_stprintf_s(prefix, 127, _T("*CALL TO %08X*"), (uint32_t)userdata); | |
744 | + } | |
745 | + _TCHAR dasmbuf[1024] = {0}; | |
746 | + size = debug_dasm_with_userdata(pc, dasmbuf, 1023, userdata); | |
747 | + if(size <= 0) { | |
748 | + strncpy(dasmbuf, 1023, _T("**UNDEFINED BEHAVIOR**")); | |
749 | 749 | } |
750 | - return false; | |
750 | + my_stprintf_s(buffer, buffer_len, _T("HIT %s @%08X %s\n"), | |
751 | + prefix, pc, dasmbuf); | |
752 | + return true; | |
751 | 753 | } |
752 | 754 | int I386::debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_len, uint32_t userdata) |
753 | 755 | { |
@@ -145,7 +145,7 @@ public: | ||
145 | 145 | virtual bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len); |
146 | 146 | virtual bool get_debug_regs_description(_TCHAR *buffer, size_t buffer_len); |
147 | 147 | int debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_len, uint32_t userdata = 0); |
148 | - virtual bool debug_rewind_call_trace(uint32_t pc, int &size, _TCHAR* buffer, size_t buffer_len, uint32_t userdata = 0); | |
148 | + virtual bool debug_rewind_call_trace(uint32_t pc, int &size, _TCHAR* buffer, size_t buffer_len, uint64_t userdata = 0); | |
149 | 149 | //#endif |
150 | 150 | bool process_state(FILEIO* state_fio, bool loading); |
151 | 151 |
@@ -559,7 +559,7 @@ int DEVICE::debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_ | ||
559 | 559 | { |
560 | 560 | return 0; |
561 | 561 | } |
562 | -bool DEVICE::debug_rewind_call_trace(uint32_t pc, int &size, _TCHAR* buffer, size_t buffer_len, uint32_t userdata = 0) | |
562 | +bool DEVICE::debug_rewind_call_trace(uint32_t pc, int &size, _TCHAR* buffer, size_t buffer_len, uint64_t userdata = 0) | |
563 | 563 | { |
564 | 564 | size = 0; |
565 | 565 | return false; |
@@ -761,7 +761,7 @@ public: | ||
761 | 761 | virtual bool get_debug_regs_description(_TCHAR *buffer, size_t buffer_len); |
762 | 762 | virtual int debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len); |
763 | 763 | virtual int debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_len, uint32_t userdata = 0); |
764 | - virtual bool debug_rewind_call_trace(uint32_t pc, int &size, _TCHAR* buffer, size_t buffer_len, uint32_t userdata = 0); | |
764 | + virtual bool debug_rewind_call_trace(uint32_t pc, int &size, _TCHAR* buffer, size_t buffer_len, uint64_t userdata = 0); | |
765 | 765 | /* |
766 | 766 | These functions are used for debugging non-cpu device |
767 | 767 | Insert debugger between standard read/write functions and these functions for checking breakpoints |
@@ -157,6 +157,8 @@ exec_1step(void) | ||
157 | 157 | } |
158 | 158 | ctx[ctx_index].opbytes = 0; |
159 | 159 | #endif |
160 | + UINT32 old_eip = CPU_PREV_EIP; | |
161 | + UINT32 old_addr = 0; | |
160 | 162 | |
161 | 163 | for (prefix = 0; prefix < MAX_PREFIX; prefix++) { |
162 | 164 | check_exception(is_debugging); |
@@ -181,31 +183,46 @@ exec_1step(void) | ||
181 | 183 | } else { |
182 | 184 | switch(op) { |
183 | 185 | case 0x9a: //CAll |
186 | + { | |
187 | + descriptor_t *sdp = &CPU_CS_DESC; | |
188 | + old_addr = sdp->u.seg.segbase + old_eip; | |
189 | + } | |
184 | 190 | op_size |= I386_TRACE_DATA_BIT_CALL; |
185 | 191 | break; |
186 | 192 | case 0xc2: // RET far |
187 | 193 | case 0xc3: |
194 | + { | |
195 | + descriptor_t *sdp = &CPU_CS_DESC; | |
196 | + old_addr = sdp->u.seg.segbase + old_eip; | |
197 | + } | |
188 | 198 | op_size |= I386_TRACE_DATA_BIT_RET; |
189 | 199 | break; |
190 | 200 | case 0xca: // RET far |
191 | 201 | case 0xcb: |
202 | + { | |
203 | + descriptor_t *sdp = &CPU_CS_DESC; | |
204 | + old_addr = sdp->u.seg.segbase + old_eip; | |
205 | + } | |
192 | 206 | op_size |= I386_TRACE_DATA_BIT_RET; |
193 | 207 | break; |
194 | - case 0xcc: // INTr | |
195 | - case 0xcd: | |
196 | - case 0xce: | |
197 | - op_size |= I386_TRACE_DATA_BIT_INT; | |
198 | - break; | |
199 | 208 | case 0xcf: |
209 | + { | |
210 | + descriptor_t *sdp = &CPU_CS_DESC; | |
211 | + old_addr = sdp->u.seg.segbase + old_eip; | |
212 | + } | |
200 | 213 | op_size |= I386_TRACE_DATA_BIT_IRET; |
201 | 214 | break; |
202 | 215 | case 0xe8: //CAll |
216 | + { | |
217 | + descriptor_t *sdp = &CPU_CS_DESC; | |
218 | + old_addr = sdp->u.seg.segbase + old_eip; | |
219 | + } | |
203 | 220 | op_size |= I386_TRACE_DATA_BIT_CALL; |
204 | 221 | break; |
205 | 222 | case 0xe9: //JMP |
206 | 223 | case 0xea: //JMP16 |
207 | 224 | case 0xeb: //JMP |
208 | - op_size |= I386_TRACE_DATA_BIT_CALL; | |
225 | + op_size |= I386_TRACE_DATA_BIT_JMP; | |
209 | 226 | break; |
210 | 227 | case 0xe3: |
211 | 228 | op_size |= I386_TRACE_DATA_BIT_JMP_COND; |
@@ -220,6 +237,26 @@ exec_1step(void) | ||
220 | 237 | /* prefix */ |
221 | 238 | if (insttable_info[op] & INST_PREFIX) { |
222 | 239 | (*insttable_1byte[0][op])(); |
240 | + switch(op) { | |
241 | + case 0x9a: //CAll | |
242 | + case 0xe8: //CAll | |
243 | + { | |
244 | + descriptor_t *sdp = &CPU_CS_DESC; | |
245 | + uint32_t new_addr = sdp->u.seg.segbase + CPU_EIP; | |
246 | + device_debugger->add_cpu_trace_call(old_addr, new_addr); | |
247 | + } | |
248 | + break; | |
249 | + case 0xc2: // RET far | |
250 | + case 0xc3: | |
251 | + case 0xca: // RET far | |
252 | + case 0xcb: | |
253 | + case 0xcf: // iRET | |
254 | + { | |
255 | + // ToDo: Collect intr num. | |
256 | + device_debugger->add_cpu_trace_return(old_addr); | |
257 | + } | |
258 | + break; | |
259 | + } | |
223 | 260 | continue; |
224 | 261 | } |
225 | 262 | break; |
@@ -245,6 +282,26 @@ exec_1step(void) | ||
245 | 282 | cpu_debug_rep_cont = 0; |
246 | 283 | #endif |
247 | 284 | (*insttable_1byte[CPU_INST_OP32][op])(); |
285 | + switch(op) { | |
286 | + case 0x9a: //CAll | |
287 | + case 0xe8: //CAll | |
288 | + { | |
289 | + descriptor_t *sdp = &CPU_CS_DESC; | |
290 | + uint32_t new_addr = sdp->u.seg.segbase + CPU_EIP; | |
291 | + device_debugger->add_cpu_trace_call(old_addr, new_addr); | |
292 | + } | |
293 | + break; | |
294 | + case 0xc2: // RET far | |
295 | + case 0xc3: | |
296 | + case 0xca: // RET far | |
297 | + case 0xcb: | |
298 | + case 0xcf: // iRET | |
299 | + { | |
300 | + // ToDo: Collect intr num. | |
301 | + device_debugger->add_cpu_trace_return(old_addr); | |
302 | + } | |
303 | + break; | |
304 | + } | |
248 | 305 | check_exception(is_debugging); |
249 | 306 | return; |
250 | 307 | } |
@@ -457,6 +514,37 @@ exec_allstep(void) | ||
457 | 514 | /* prefix */ |
458 | 515 | if (insttable_info[op] & INST_PREFIX) { |
459 | 516 | (*insttable_1byte[0][op])(); |
517 | + switch(op) { | |
518 | + case 0x9a: //CAll | |
519 | + case 0xe8: //CAll | |
520 | + { | |
521 | + descriptor_t *sdp = &CPU_CS_DESC; | |
522 | + uint32_t new_addr = sdp->u.seg.segbase + CPU_EIP; | |
523 | + device_debugger->add_cpu_trace_call(old_addr, new_addr); | |
524 | + } | |
525 | + break; | |
526 | + case 0xcc: // INTr | |
527 | + case 0xcd: | |
528 | + case 0xce: | |
529 | + case 0xf1: | |
530 | + { | |
531 | + // ToDo: Collect intr num. | |
532 | + descriptor_t *sdp = &CPU_CS_DESC; | |
533 | + uint32_t new_addr = sdp->u.seg.segbase + CPU_EIP; | |
534 | + device_debugger->add_cpu_trace_call(old_addr, new_addr); | |
535 | + } | |
536 | + break; | |
537 | + case 0xc2: // RET far | |
538 | + case 0xc3: | |
539 | + case 0xca: // RET far | |
540 | + case 0xcb: | |
541 | + case 0xcf: // iRET | |
542 | + { | |
543 | + // ToDo: Collect intr num. | |
544 | + device_debugger->add_cpu_trace_return(old_addr); | |
545 | + } | |
546 | + break; | |
547 | + } | |
460 | 548 | continue; |
461 | 549 | } |
462 | 550 | break; |
@@ -482,6 +570,37 @@ exec_allstep(void) | ||
482 | 570 | cpu_debug_rep_cont = 0; |
483 | 571 | #endif |
484 | 572 | (*insttable_1byte[CPU_INST_OP32][op])(); |
573 | + switch(op) { | |
574 | + case 0x9a: //CAll | |
575 | + case 0xe8: //CAll | |
576 | + { | |
577 | + descriptor_t *sdp = &CPU_CS_DESC; | |
578 | + uint32_t new_addr = sdp->u.seg.segbase + CPU_EIP; | |
579 | + device_debugger->add_cpu_trace_call(old_addr, new_addr); | |
580 | + } | |
581 | + break; | |
582 | + case 0xcc: // INTr | |
583 | + case 0xcd: | |
584 | + case 0xce: | |
585 | + case 0xf1: | |
586 | + { | |
587 | + // ToDo: Collect intr num. | |
588 | + descriptor_t *sdp = &CPU_CS_DESC; | |
589 | + uint32_t new_addr = sdp->u.seg.segbase + CPU_EIP; | |
590 | + device_debugger->add_cpu_trace_call(old_addr, new_addr); | |
591 | + } | |
592 | + break; | |
593 | + case 0xc2: // RET far | |
594 | + case 0xc3: | |
595 | + case 0xca: // RET far | |
596 | + case 0xcb: | |
597 | + case 0xcf: // iRET | |
598 | + { | |
599 | + // ToDo: Collect intr num. | |
600 | + device_debugger->add_cpu_trace_return(old_addr); | |
601 | + } | |
602 | + break; | |
603 | + } | |
485 | 604 | check_exception(is_debugging); |
486 | 605 | goto cpucontinue; //continue; |
487 | 606 | } |
@@ -420,8 +420,30 @@ Grp5_Ed(void) | ||
420 | 420 | { |
421 | 421 | UINT32 op; |
422 | 422 | |
423 | + UINT32 old_eip = CPU_PREV_EIP; | |
424 | + UINT32 old_addr = 0; | |
423 | 425 | GET_PCBYTE(op); |
426 | + UINT32 op_old = op; | |
427 | + switch((op >> 3) & 7) { | |
428 | + case 2: //CAll | |
429 | + case 3: //CAll | |
430 | + { | |
431 | + descriptor_t *sdp = &CPU_CS_DESC; | |
432 | + old_addr = sdp->u.seg.segbase + old_eip; | |
433 | + } | |
434 | + break; | |
435 | + } | |
424 | 436 | (*insttable_G5Ed[(op >> 3) & 7])(op); |
437 | + switch((op >> 3) & 7) { | |
438 | + case 2: //CAll | |
439 | + case 3: //CAll | |
440 | + { | |
441 | + descriptor_t *sdp = &CPU_CS_DESC; | |
442 | + uint32_t new_addr = sdp->u.seg.segbase + CPU_EIP; | |
443 | + device_debugger->add_cpu_trace_call(old_addr, new_addr); | |
444 | + } | |
445 | + break; | |
446 | + } | |
425 | 447 | } |
426 | 448 | |
427 | 449 |
@@ -1403,6 +1403,14 @@ void | ||
1403 | 1403 | INT1(void) |
1404 | 1404 | { |
1405 | 1405 | |
1406 | + uint32_t old_addr; | |
1407 | + { | |
1408 | + descriptor_t *sdp = &CPU_CS_DESC; | |
1409 | + old_addr = sdp->u.seg.segbase + CPU_PREV_EIP; | |
1410 | + } | |
1411 | + if(device_debugger != NULL) { | |
1412 | + device_debugger->add_cpu_trace_irq(old_addr, 1); | |
1413 | + } | |
1406 | 1414 | CPU_WORKCLOCK(33); |
1407 | 1415 | INTERRUPT(1, INTR_TYPE_SOFTINTR); |
1408 | 1416 | } |
@@ -1411,6 +1419,14 @@ INT1(void) | ||
1411 | 1419 | void |
1412 | 1420 | INT6(void) |
1413 | 1421 | { |
1422 | + uint32_t old_addr; | |
1423 | + { | |
1424 | + descriptor_t *sdp = &CPU_CS_DESC; | |
1425 | + old_addr = sdp->u.seg.segbase + CPU_PREV_EIP; | |
1426 | + } | |
1427 | + if(device_debugger != NULL) { | |
1428 | + device_debugger->add_cpu_trace_irq(old_addr, 6); | |
1429 | + } | |
1414 | 1430 | CPU_WORKCLOCK(33); |
1415 | 1431 | INTERRUPT(6, INTR_TYPE_SOFTINTR); |
1416 | 1432 | } |
@@ -1435,6 +1451,14 @@ INT3(void) | ||
1435 | 1451 | #endif |
1436 | 1452 | */ |
1437 | 1453 | CPU_WORKCLOCK(33); |
1454 | + uint32_t old_addr; | |
1455 | + { | |
1456 | + descriptor_t *sdp = &CPU_CS_DESC; | |
1457 | + old_addr = sdp->u.seg.segbase + CPU_PREV_EIP; | |
1458 | + } | |
1459 | + if(device_debugger != NULL) { | |
1460 | + device_debugger->add_cpu_trace_irq(old_addr, 3); | |
1461 | + } | |
1438 | 1462 | INTERRUPT(3, INTR_TYPE_SOFTINTR); |
1439 | 1463 | } |
1440 | 1464 |
@@ -1447,6 +1471,14 @@ INTO(void) | ||
1447 | 1471 | return; |
1448 | 1472 | } |
1449 | 1473 | CPU_WORKCLOCK(35); |
1474 | + uint32_t old_addr; | |
1475 | + { | |
1476 | + descriptor_t *sdp = &CPU_CS_DESC; | |
1477 | + old_addr = sdp->u.seg.segbase + CPU_PREV_EIP; | |
1478 | + } | |
1479 | + if(device_debugger != NULL) { | |
1480 | + device_debugger->add_cpu_trace_irq(old_addr, 4); | |
1481 | + } | |
1450 | 1482 | INTERRUPT(4, INTR_TYPE_SOFTINTR); |
1451 | 1483 | } |
1452 | 1484 |
@@ -1457,7 +1489,15 @@ INT_Ib(void) | ||
1457 | 1489 | |
1458 | 1490 | CPU_WORKCLOCK(37); |
1459 | 1491 | if (!CPU_STAT_PM || !CPU_STAT_VM86 || (CPU_STAT_IOPL == CPU_IOPL3)) { |
1492 | + uint32_t old_addr; | |
1493 | + { | |
1494 | + descriptor_t *sdp = &CPU_CS_DESC; | |
1495 | + old_addr = sdp->u.seg.segbase + CPU_PREV_EIP; | |
1496 | + } | |
1460 | 1497 | GET_PCBYTE(vect); |
1498 | + if(device_debugger != NULL) { | |
1499 | + device_debugger->add_cpu_trace_irq(old_addr, vect); | |
1500 | + } | |
1461 | 1501 | #if defined(ENABLE_TRAP) |
1462 | 1502 | softinttrap(CPU_CS, CPU_EIP - 2, vect); |
1463 | 1503 | #endif |