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

@ -48,9 +48,11 @@ class PageDirectory;
#define PFLAG_READABLE 0x1
#define PFLAG_WRITEABLE 0x2
#define PFLAG_HASROM 0x4
#define PFLAG_HASCODE 0x8 //Page contains dynamic code
#define PFLAG_HASCODE32 0x8 //Page contains 32-bit dynamic code
#define PFLAG_NOCODE 0x10 //No dynamic code can be generated here
#define PFLAG_INIT 0x20 //No dynamic code can be generated here
#define PFLAG_HASCODE16 0x40 //Page contains 16-bit dynamic code
#define PFLAG_HASCODE (PFLAG_HASCODE32|PFLAG_HASCODE16)
#define LINK_START ((1024+64)/4) //Start right after the HMA

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) {