Clean invalid selectors on the pop %xs from the STACKFRAME itself
instead of using linked list hack.
This commit is contained in:
parent
6a4aa4917d
commit
735bec0f2f
|
@ -162,7 +162,6 @@ void SELECTOR_FreeBlock( WORD sel, WORD count )
|
||||||
{
|
{
|
||||||
WORD i, nextsel;
|
WORD i, nextsel;
|
||||||
ldt_entry entry;
|
ldt_entry entry;
|
||||||
STACK16FRAME *frame;
|
|
||||||
|
|
||||||
TRACE(selector, "(%04x,%d)\n", sel, count );
|
TRACE(selector, "(%04x,%d)\n", sel, count );
|
||||||
sel &= ~(__AHINCR - 1); /* clear bottom bits of selector */
|
sel &= ~(__AHINCR - 1); /* clear bottom bits of selector */
|
||||||
|
@ -190,16 +189,6 @@ void SELECTOR_FreeBlock( WORD sel, WORD count )
|
||||||
LDT_SetEntry( i, &entry );
|
LDT_SetEntry( i, &entry );
|
||||||
ldt_flags_copy[i] &= ~LDT_FLAGS_ALLOCATED;
|
ldt_flags_copy[i] &= ~LDT_FLAGS_ALLOCATED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear the saved 16-bit selector */
|
|
||||||
frame = CURRENT_STACK16;
|
|
||||||
while (frame && frame->frame32)
|
|
||||||
{
|
|
||||||
if ((frame->ds >= sel) && (frame->ds < nextsel)) frame->ds = 0;
|
|
||||||
if ((frame->es >= sel) && (frame->es < nextsel)) frame->es = 0;
|
|
||||||
if ((frame->fs >= sel) && (frame->fs < nextsel)) frame->fs = 0;
|
|
||||||
frame = PTR_SEG_TO_LIN( frame->frame32->frame16 );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "dosexe.h"
|
#include "dosexe.h"
|
||||||
#include "miscemu.h"
|
#include "miscemu.h"
|
||||||
#include "sig_context.h"
|
#include "sig_context.h"
|
||||||
|
#include "selectors.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,6 +34,9 @@
|
||||||
(IS_SELECTOR_SYSTEM(SS_sig(context)) ? (void *)ESP_sig(context) : \
|
(IS_SELECTOR_SYSTEM(SS_sig(context)) ? (void *)ESP_sig(context) : \
|
||||||
(PTR_SEG_OFF_TO_LIN(SS_sig(context),STACK_sig(context)))))
|
(PTR_SEG_OFF_TO_LIN(SS_sig(context),STACK_sig(context)))))
|
||||||
|
|
||||||
|
/* For invalid registers fixup */
|
||||||
|
extern DWORD CallFrom16_Start,CallFrom16_End;
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* INSTR_ReplaceSelector
|
* INSTR_ReplaceSelector
|
||||||
|
@ -386,9 +390,24 @@ BOOL32 INSTR_EmulateInstruction( SIGCONTEXT *context )
|
||||||
case 0x1f: /* pop ds */
|
case 0x1f: /* pop ds */
|
||||||
{
|
{
|
||||||
WORD seg = *(WORD *)STACK_PTR( context );
|
WORD seg = *(WORD *)STACK_PTR( context );
|
||||||
|
|
||||||
|
/* Sometimes invalid selectors are left on the stackframe
|
||||||
|
* pop them if needed.
|
||||||
|
*/
|
||||||
|
if ((EIP_sig(context)>=(DWORD)&CallFrom16_Start) &&
|
||||||
|
(EIP_sig(context)<(DWORD)&CallFrom16_End)
|
||||||
|
) {
|
||||||
|
switch(*instr) {
|
||||||
|
case 0x07: ES_sig(context) = 0; break;
|
||||||
|
case 0x17: SS_sig(context) = 0; break;
|
||||||
|
case 0x1f: DS_sig(context) = 0; break;
|
||||||
|
}
|
||||||
|
STACK_sig(context) += long_op ? 4 : 2;
|
||||||
|
EIP_sig(context) += prefixlen + 1;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
if ((seg = INSTR_ReplaceSelector( context, seg )) != 0)
|
if ((seg = INSTR_ReplaceSelector( context, seg )) != 0)
|
||||||
{
|
{ switch(*instr)
|
||||||
switch(*instr)
|
|
||||||
{
|
{
|
||||||
case 0x07: ES_sig(context) = seg; break;
|
case 0x07: ES_sig(context) = seg; break;
|
||||||
case 0x17: SS_sig(context) = seg; break;
|
case 0x17: SS_sig(context) = seg; break;
|
||||||
|
@ -426,6 +445,14 @@ BOOL32 INSTR_EmulateInstruction( SIGCONTEXT *context )
|
||||||
case 0xa1: /* pop fs */
|
case 0xa1: /* pop fs */
|
||||||
{
|
{
|
||||||
WORD seg = *(WORD *)STACK_PTR( context );
|
WORD seg = *(WORD *)STACK_PTR( context );
|
||||||
|
if ((EIP_sig(context)>=(DWORD)&CallFrom16_Start) &&
|
||||||
|
(EIP_sig(context)<(DWORD)&CallFrom16_End)
|
||||||
|
) {
|
||||||
|
FS_sig(context) = 0;
|
||||||
|
STACK_sig(context) += long_op ? 4 : 2;
|
||||||
|
EIP_sig(context) += prefixlen + 1;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
if ((seg = INSTR_ReplaceSelector( context, seg )) != 0)
|
if ((seg = INSTR_ReplaceSelector( context, seg )) != 0)
|
||||||
{
|
{
|
||||||
FS_sig(context) = seg;
|
FS_sig(context) = seg;
|
||||||
|
@ -441,6 +468,14 @@ BOOL32 INSTR_EmulateInstruction( SIGCONTEXT *context )
|
||||||
case 0xa9: /* pop gs */
|
case 0xa9: /* pop gs */
|
||||||
{
|
{
|
||||||
WORD seg = *(WORD *)STACK_PTR( context );
|
WORD seg = *(WORD *)STACK_PTR( context );
|
||||||
|
if ((EIP_sig(context)>=(DWORD)&CallFrom16_Start) &&
|
||||||
|
(EIP_sig(context)<(DWORD)&CallFrom16_End)
|
||||||
|
) {
|
||||||
|
GS_sig(context) = 0;
|
||||||
|
STACK_sig(context) += long_op ? 4 : 2;
|
||||||
|
EIP_sig(context) += prefixlen + 1;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
if ((seg = INSTR_ReplaceSelector( context, seg )) != 0)
|
if ((seg = INSTR_ReplaceSelector( context, seg )) != 0)
|
||||||
{
|
{
|
||||||
GS_sig(context) = seg;
|
GS_sig(context) = seg;
|
||||||
|
|
|
@ -2506,6 +2506,8 @@ static int BuildCallFrom16( FILE *outfile, char * outname, int argc, char *argv[
|
||||||
fprintf( outfile, "\t.align 4\n" );
|
fprintf( outfile, "\t.align 4\n" );
|
||||||
fprintf( outfile, "Code_Start:\n\n" );
|
fprintf( outfile, "Code_Start:\n\n" );
|
||||||
#endif
|
#endif
|
||||||
|
fprintf( outfile, PREFIX"CallFrom16_Start:\n" );
|
||||||
|
fprintf( outfile, "\t.globl "PREFIX"CallFrom16_Start\n" );
|
||||||
|
|
||||||
/* Build the callback functions */
|
/* Build the callback functions */
|
||||||
|
|
||||||
|
@ -2526,6 +2528,8 @@ static int BuildCallFrom16( FILE *outfile, char * outname, int argc, char *argv[
|
||||||
fprintf( outfile, STRING " \"%s\\0\"\n", argv[i] + 7 );
|
fprintf( outfile, STRING " \"%s\\0\"\n", argv[i] + 7 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fprintf( outfile, PREFIX"CallFrom16_End:\n" );
|
||||||
|
fprintf( outfile, "\t.globl "PREFIX"CallFrom16_End\n" );
|
||||||
|
|
||||||
#ifdef USE_STABS
|
#ifdef USE_STABS
|
||||||
fprintf( outfile, "\t.text\n");
|
fprintf( outfile, "\t.text\n");
|
||||||
|
|
Loading…
Reference in New Issue