1
0
Fork 0

Store whether generated code is 16 or 32 bit, so this information can be used when checking for self modifying code. Some code is identical except for being 32 or 16 bit. Fixes some hard to reproduce problems (with small codeblocks). Thanks jmarsh!

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4206
This commit is contained in:
Peter Veenstra 2019-04-19 12:16:14 +00:00
parent ee2d3e73ce
commit dc6a76d354
7 changed files with 32 additions and 16 deletions

View file

@ -362,7 +362,7 @@ run_block:
{
Bitu temp_ip=SegPhys(cs)+reg_eip;
CodePageHandler * temp_handler=(CodePageHandler *)get_tlb_readhandler(temp_ip);
if (temp_handler->flags & PFLAG_HASCODE) {
if (temp_handler->flags & (cpu.code.big ? PFLAG_HASCODE32:PFLAG_HASCODE16)) {
block=temp_handler->FindCacheBlock(temp_ip & 4095);
if (!block) goto restart_core;
cache.block.running->LinkTo(ret==BR_Link2,block);

View file

@ -73,7 +73,7 @@ public:
void SetupAt(Bitu _phys_page,PageHandler * _old_pagehandler) {
phys_page=_phys_page;
old_pagehandler=_old_pagehandler;
flags=old_pagehandler->flags|PFLAG_HASCODE;
flags=old_pagehandler->flags|(cpu.code.big ? PFLAG_HASCODE32:PFLAG_HASCODE16);
flags&=~PFLAG_WRITEABLE;
active_blocks=0;
active_count=16;

View file

@ -53,19 +53,26 @@ static struct DynDecode {
static bool MakeCodePage(Bitu lin_addr,CodePageHandler * &cph) {
Bit8u rdval;
const Bitu cflag = cpu.code.big ? PFLAG_HASCODE32:PFLAG_HASCODE16;
//Ensure page contains memory:
if (GCC_UNLIKELY(mem_readb_checked(lin_addr,&rdval))) return true;
PageHandler * handler=get_tlb_readhandler(lin_addr);
if (handler->flags & PFLAG_HASCODE) {
cph=( CodePageHandler *)handler;
return false;
if (handler->flags & cflag) return false;
cph->ClearRelease();
cph=0;
handler=get_tlb_readhandler(lin_addr);
}
if (handler->flags & PFLAG_NOCODE) {
if (PAGING_ForcePageInit(lin_addr)) {
handler=get_tlb_readhandler(lin_addr);
if (handler->flags & PFLAG_HASCODE) {
cph=( CodePageHandler *)handler;
return false;
if (handler->flags & cflag) return false;
cph->ClearRelease();
cph=0;
handler=get_tlb_readhandler(lin_addr);
}
}
if (handler->flags & PFLAG_NOCODE) {

View file

@ -159,16 +159,14 @@ CacheBlockDynRec * LinkBlocks(BlockReturn ret) {
// the last instruction was a control flow modifying instruction
Bitu temp_ip=SegPhys(cs)+reg_eip;
CodePageHandlerDynRec * temp_handler=(CodePageHandlerDynRec *)get_tlb_readhandler(temp_ip);
if (temp_handler->flags & PFLAG_HASCODE) {
if (temp_handler->flags & (cpu.code.big ? PFLAG_HASCODE32:PFLAG_HASCODE16)) {
// see if the target is an already translated block
block=temp_handler->FindCacheBlock(temp_ip & 4095);
if (!block) return NULL;
// found it, link the current block to
cache.block.running->LinkTo(ret==BR_Link2,block);
return block;
if (block) { // found it, link the current block to
cache.block.running->LinkTo(ret==BR_Link2,block);
}
}
return NULL;
return block;
}
/*

View file

@ -96,7 +96,7 @@ public:
old_pagehandler=_old_pagehandler;
// adjust flags
flags=old_pagehandler->flags|PFLAG_HASCODE;
flags=old_pagehandler->flags|(cpu.code.big ? PFLAG_HASCODE32:PFLAG_HASCODE16);
flags&=~PFLAG_WRITEABLE;
active_blocks=0;

View file

@ -130,21 +130,30 @@ static struct DynDecode {
static bool MakeCodePage(Bitu lin_addr,CodePageHandlerDynRec * &cph) {
Bit8u rdval;
const Bitu cflag = cpu.code.big ? PFLAG_HASCODE32:PFLAG_HASCODE16;
//Ensure page contains memory:
if (GCC_UNLIKELY(mem_readb_checked(lin_addr,&rdval))) return true;
PageHandler * handler=get_tlb_readhandler(lin_addr);
if (handler->flags & PFLAG_HASCODE) {
// this is a codepage handler, and the one that we're looking for
// this is a codepage handler, make sure it matches current code size
cph=(CodePageHandlerDynRec *)handler;
return false;
if (handler->flags & cflag) return false;
// wrong code size/stale dynamic code, drop it
cph->ClearRelease();
cph=0;
// handler was changed, refresh
handler=get_tlb_readhandler(lin_addr);
}
if (handler->flags & PFLAG_NOCODE) {
if (PAGING_ForcePageInit(lin_addr)) {
handler=get_tlb_readhandler(lin_addr);
if (handler->flags & PFLAG_HASCODE) {
cph=(CodePageHandlerDynRec *)handler;
return false;
if (handler->flags & cflag) return false;
cph->ClearRelease();
cph=0;
handler=get_tlb_readhandler(lin_addr);
}
}
if (handler->flags & PFLAG_NOCODE) {