From f47287f59c678e2efcd8bc936b522bd6dd27406c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 20 Jan 2006 21:27:03 +0000 Subject: [PATCH] dynamic core: prevent double memory access on smc, handle 16bit-underflow of stack (fixes Privateer) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2432 --- src/cpu/core_dyn_x86/cache.h | 27 +++++++++++++++------------ src/cpu/core_dyn_x86/decoder.h | 7 ++++--- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index 5f507a5b..4777c2ee 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -117,41 +117,44 @@ public: } bool writeb_checked(PhysPt addr,Bitu val) { addr&=4095; - host_writeb(hostmem+addr,val); if (!*(Bit8u*)&write_map[addr]) { - if (active_blocks) return false; - active_count--; - if (!active_count) Release(); + if (!active_blocks) { + active_count--; + if (!active_count) Release(); + } } else if (InvalidateRange(addr,addr)) { cpu.exception.which=SMC_CURRENT_BLOCK; return true; } + host_writeb(hostmem+addr,val); return false; } bool writew_checked(PhysPt addr,Bitu val) { addr&=4095; - host_writew(hostmem+addr,val); if (!*(Bit16u*)&write_map[addr]) { - if (active_blocks) return false; - active_count--; - if (!active_count) Release(); + if (!active_blocks) { + active_count--; + if (!active_count) Release(); + } } else if (InvalidateRange(addr,addr+1)) { cpu.exception.which=SMC_CURRENT_BLOCK; return true; } + host_writew(hostmem+addr,val); return false; } bool writed_checked(PhysPt addr,Bitu val) { addr&=4095; - host_writed(hostmem+addr,val); if (!*(Bit32u*)&write_map[addr]) { - if (active_blocks) return false; - active_count--; - if (!active_count) Release(); + if (!active_blocks) { + active_count--; + if (!active_count) Release(); + } } else if (InvalidateRange(addr,addr+3)) { cpu.exception.which=SMC_CURRENT_BLOCK; return true; } + host_writed(hostmem+addr,val); return false; } void AddCacheBlock(CacheBlock * block) { diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 30f6bdd2..274df299 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -272,8 +272,8 @@ static void dyn_push(DynReg * dynreg) { } else { gen_dop_word_imm(DOP_SUB,true,DREG(ESP),2); } + gen_dop_word(DOP_AND,true,DREG(ESP),DREG(SMASK)); gen_dop_word(DOP_MOV,true,DREG(STACK),DREG(ESP)); - gen_dop_word(DOP_AND,true,DREG(STACK),DREG(SMASK)); gen_dop_word(DOP_ADD,true,DREG(STACK),DREG(SS)); if (decode.big_op) { gen_call_function((void *)&mem_writed,"%Drd%Dd",DREG(STACK),dynreg); @@ -299,6 +299,7 @@ static void dyn_pop(DynReg * dynreg) { } else { gen_dop_word_imm(DOP_ADD,true,DREG(ESP),2); } + gen_dop_word(DOP_AND,true,DREG(ESP),DREG(SMASK)); } } @@ -904,8 +905,8 @@ static void dyn_load_seg_off_ea(SegNames seg) { dyn_fill_ea(); gen_lea(DREG(TMPW),DREG(EA),0,0,decode.big_op ? 4:2); dyn_read_word(DREG(TMPW),DREG(TMPW),false); - dyn_load_seg(seg,DREG(TMPW));gen_releasereg(DREG(TMPW)); dyn_read_word_release(DREG(EA),&DynRegs[decode.modrm.reg],decode.big_op); + dyn_load_seg(seg,DREG(TMPW));gen_releasereg(DREG(TMPW)); } else { IllegalOption("dyn_load_seg_off_ea"); } @@ -1701,8 +1702,8 @@ restart_prefix: gen_protectflags(); dyn_flags_gen_to_host(); gen_lea(DREG(EA),DREG(EA),0,0,decode.big_op ? 4: 2); - dyn_set_eip_last_end(DREG(TMPB)); dyn_read_word(DREG(EA),DREG(EA),false); + dyn_set_eip_last_end(DREG(TMPB)); dyn_save_critical_regs(); gen_call_function( decode.modrm.reg == 3 ? (void*)&CPU_CALL : (void*)&CPU_JMP,