Clean invalid selectors on the pop %xs from the STACKFRAME itself

instead of using linked list hack.
This commit is contained in:
Marcus Meissner 1998-11-15 11:34:10 +00:00 committed by Alexandre Julliard
parent 6a4aa4917d
commit 735bec0f2f
3 changed files with 41 additions and 13 deletions

View File

@ -162,7 +162,6 @@ void SELECTOR_FreeBlock( WORD sel, WORD count )
{
WORD i, nextsel;
ldt_entry entry;
STACK16FRAME *frame;
TRACE(selector, "(%04x,%d)\n", sel, count );
sel &= ~(__AHINCR - 1); /* clear bottom bits of selector */
@ -190,16 +189,6 @@ void SELECTOR_FreeBlock( WORD sel, WORD count )
LDT_SetEntry( i, &entry );
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 );
}
}

View File

@ -11,6 +11,7 @@
#include "dosexe.h"
#include "miscemu.h"
#include "sig_context.h"
#include "selectors.h"
#include "debug.h"
@ -33,6 +34,9 @@
(IS_SELECTOR_SYSTEM(SS_sig(context)) ? (void *)ESP_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
@ -386,9 +390,24 @@ BOOL32 INSTR_EmulateInstruction( SIGCONTEXT *context )
case 0x1f: /* pop ds */
{
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)
{
switch(*instr)
{ switch(*instr)
{
case 0x07: ES_sig(context) = seg; break;
case 0x17: SS_sig(context) = seg; break;
@ -426,6 +445,14 @@ BOOL32 INSTR_EmulateInstruction( SIGCONTEXT *context )
case 0xa1: /* pop fs */
{
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)
{
FS_sig(context) = seg;
@ -441,6 +468,14 @@ BOOL32 INSTR_EmulateInstruction( SIGCONTEXT *context )
case 0xa9: /* pop gs */
{
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)
{
GS_sig(context) = seg;

View File

@ -2506,6 +2506,8 @@ static int BuildCallFrom16( FILE *outfile, char * outname, int argc, char *argv[
fprintf( outfile, "\t.align 4\n" );
fprintf( outfile, "Code_Start:\n\n" );
#endif
fprintf( outfile, PREFIX"CallFrom16_Start:\n" );
fprintf( outfile, "\t.globl "PREFIX"CallFrom16_Start\n" );
/* 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, PREFIX"CallFrom16_End:\n" );
fprintf( outfile, "\t.globl "PREFIX"CallFrom16_End\n" );
#ifdef USE_STABS
fprintf( outfile, "\t.text\n");