Mercurial > repos > blastem
diff m68k_core_x86.c @ 1329:85a90964b557
Fix interaction between 68K debugger and instruction retranslation due to self modifying code or bank switching
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Mon, 24 Apr 2017 20:49:31 -0700 |
parents | 5b90d7669eee |
children | 87bbc4bec958 |
line wrap: on
line diff
--- a/m68k_core_x86.c Sun Apr 23 00:54:33 2017 -0700 +++ b/m68k_core_x86.c Mon Apr 24 20:49:31 2017 -0700 @@ -2484,51 +2484,27 @@ } } -void insert_breakpoint(m68k_context * context, uint32_t address, m68k_debug_handler bp_handler) +void m68k_breakpoint_patch(m68k_context *context, uint32_t address, m68k_debug_handler bp_handler, code_ptr native_addr) { - static code_ptr bp_stub = NULL; m68k_options * opts = context->options; code_info native; - native.cur = get_native_address_trans(context, address); + native.cur = native_addr ? native_addr : get_native_address(context->options, address); + + if (!native.cur) { + return; + } + + if (*native.cur != opts->prologue_start) { + //instruction has already been patched, probably for retranslation + return; + } native.last = native.cur + 128; native.stack_off = 0; code_ptr start_native = native.cur; mov_ir(&native, address, opts->gen.scratch1, SZ_D); - if (!bp_stub) { - code_info *code = &opts->gen.code; - check_code_prologue(code); - bp_stub = code->cur; - call(&native, bp_stub); - - uint32_t tmp_stack_off = code->stack_off; - //Calculate length of prologue - check_cycles_int(&opts->gen, address); - int check_int_size = code->cur-bp_stub; - code->cur = bp_stub; - code->stack_off = tmp_stack_off; - - //Save context and call breakpoint handler - call(code, opts->gen.save_context); - push_r(code, opts->gen.scratch1); - call_args_abi(code, (code_ptr)bp_handler, 2, opts->gen.context_reg, opts->gen.scratch1); - mov_rr(code, RAX, opts->gen.context_reg, SZ_PTR); - //Restore context - call(code, opts->gen.load_context); - pop_r(code, opts->gen.scratch1); - //do prologue stuff - cmp_rr(code, opts->gen.cycles, opts->gen.limit, SZ_D); - code_ptr jmp_off = code->cur + 1; - jcc(code, CC_NC, code->cur + 7); - call(code, opts->gen.handle_cycle_limit_int); - *jmp_off = code->cur - (jmp_off+1); - //jump back to body of translated instruction - pop_r(code, opts->gen.scratch1); - add_ir(code, check_int_size - (native.cur-start_native), opts->gen.scratch1, SZ_PTR); - jmp_r(code, opts->gen.scratch1); - code->stack_off = tmp_stack_off; - } else { - call(&native, bp_stub); - } + + + call(&native, opts->bp_stub); } void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chunks, uint32_t clock_divider) @@ -3129,4 +3105,42 @@ mov_rr(code, RAX, opts->gen.scratch1, SZ_PTR); call(code, opts->gen.load_context); jmp_r(code, opts->gen.scratch1); + + + check_code_prologue(code); + opts->bp_stub = code->cur; + + tmp_stack_off = code->stack_off; + //Calculate length of prologue + check_cycles_int(&opts->gen, 0x1234); + int check_int_size = code->cur-opts->bp_stub; + code->cur = opts->bp_stub; + code->stack_off = tmp_stack_off; + opts->prologue_start = *opts->bp_stub; + //Calculate length of patch + mov_ir(code, 0x1234, opts->gen.scratch1, SZ_D); + call(code, opts->bp_stub); + int patch_size = code->cur - opts->bp_stub; + code->cur = opts->bp_stub; + code->stack_off = tmp_stack_off; + + //Save context and call breakpoint handler + call(code, opts->gen.save_context); + push_r(code, opts->gen.scratch1); + call_args_abi(code, (code_ptr)m68k_bp_dispatcher, 2, opts->gen.context_reg, opts->gen.scratch1); + mov_rr(code, RAX, opts->gen.context_reg, SZ_PTR); + //Restore context + call(code, opts->gen.load_context); + pop_r(code, opts->gen.scratch1); + //do prologue stuff + cmp_rr(code, opts->gen.cycles, opts->gen.limit, SZ_D); + code_ptr jmp_off = code->cur + 1; + jcc(code, CC_NC, code->cur + 7); + call(code, opts->gen.handle_cycle_limit_int); + *jmp_off = code->cur - (jmp_off+1); + //jump back to body of translated instruction + pop_r(code, opts->gen.scratch1); + add_ir(code, check_int_size - patch_size, opts->gen.scratch1, SZ_PTR); + jmp_r(code, opts->gen.scratch1); + code->stack_off = tmp_stack_off; }