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:
parent
ee2d3e73ce
commit
dc6a76d354
7 changed files with 32 additions and 16 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Add table
Reference in a new issue