[PATCH 1/3] krnl386: Call DOSVM_IntProcRelay() via the application stack.

Zebediah Figura zfigura at codeweavers.com
Tue Sep 28 20:39:03 CDT 2021


Instead of using a dedicated stack.

The dedicated stack was introduced by 9d7ff6c85b0827b7f54989050b4c34f1f459e94d,
in order to support potentially nested DPMI interrupts. DPMI support was removed
by ed6bdb3c51cd4b8c94f9839806321703e7aa9765; hence there is no longer a reason
to account for nested interrupts.

Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
 dlls/krnl386.exe16/dosexe.h     |   2 -
 dlls/krnl386.exe16/dosmem.c     |   8 --
 dlls/krnl386.exe16/interrupts.c |   9 +--
 dlls/krnl386.exe16/relay.c      | 132 +-------------------------------
 4 files changed, 3 insertions(+), 148 deletions(-)

diff --git a/dlls/krnl386.exe16/dosexe.h b/dlls/krnl386.exe16/dosexe.h
index c4c8def5dce..42b8e0f4437 100644
--- a/dlls/krnl386.exe16/dosexe.h
+++ b/dlls/krnl386.exe16/dosexe.h
@@ -41,7 +41,6 @@ typedef void (WINAPI *INTPROC)(CONTEXT*);
 extern WORD DOSVM_psp DECLSPEC_HIDDEN;     /* psp of current DOS task */
 extern WORD int16_sel DECLSPEC_HIDDEN;
 extern WORD relay_code_sel DECLSPEC_HIDDEN;
-extern WORD relay_data_sel DECLSPEC_HIDDEN;
 
 #define ADD_LOWORD(dw,val)  ((dw) = ((dw) & 0xffff0000) | LOWORD((DWORD)(dw)+(val)))
 
@@ -247,7 +246,6 @@ extern DWORD DOSVM_inport( int port, int size ) DECLSPEC_HIDDEN;
 extern void DOSVM_outport( int port, int size, DWORD value ) DECLSPEC_HIDDEN;
 
 /* relay.c */
-void DOSVM_RelayHandler( CONTEXT * ) DECLSPEC_HIDDEN;
 void DOSVM_BuildCallFrame( CONTEXT *, DOSRELAY, LPVOID ) DECLSPEC_HIDDEN;
 
 #endif /* __WINE_DOSEXE_H */
diff --git a/dlls/krnl386.exe16/dosmem.c b/dlls/krnl386.exe16/dosmem.c
index 36b02aec484..2d55eb050de 100644
--- a/dlls/krnl386.exe16/dosmem.c
+++ b/dlls/krnl386.exe16/dosmem.c
@@ -45,7 +45,6 @@ WORD DOSMEM_BiosSysSeg;   /* BIOS ROM segment at 0xf000:0 */
 WORD DOSVM_psp = 0;
 WORD int16_sel = 0;
 WORD relay_code_sel = 0;
-WORD relay_data_sel = 0;
 
 /* DOS memory highest address (including HMA) */
 #define DOSMEM_SIZE             0x110000
@@ -306,7 +305,6 @@ static void DOSMEM_InitSegments(void)
     static const char relay[]=
     {
         0xca, 0x04, 0x00, /* 16-bit far return and pop 4 bytes (relay void* arg) */
-        0xcd, 0x31,       /* int 31 */
     };
 
     /*
@@ -330,17 +328,11 @@ static void DOSMEM_InitSegments(void)
 
     /*
      * PM / offset 0: Stub where __wine_call_from_16_regs returns.
-     * PM / offset 3: Stub which swaps back to 32-bit application code/stack.
      */
     relay_code_sel = GLOBAL_Alloc( GMEM_FIXED, sizeof(relay), 0, LDT_FLAGS_CODE );
     ptr = GlobalLock16( relay_code_sel );
     memcpy( ptr, relay, sizeof(relay) );
     GlobalUnlock16( relay_code_sel );
-
-    /*
-     * Space for 16-bit stack used by relay code.
-     */
-    relay_data_sel = GlobalAlloc16( GMEM_FIXED | GMEM_ZEROINIT, DOSVM_RELAY_DATA_SIZE );
 }
 
 /******************************************************************
diff --git a/dlls/krnl386.exe16/interrupts.c b/dlls/krnl386.exe16/interrupts.c
index e2a129e4a20..d397d20072d 100644
--- a/dlls/krnl386.exe16/interrupts.c
+++ b/dlls/krnl386.exe16/interrupts.c
@@ -250,14 +250,7 @@ BOOL DOSVM_EmulateInterruptPM( CONTEXT *context, BYTE intnum )
 
     DOSMEM_InitDosMemory();
 
-    if (context->SegCs == relay_code_sel)
-    {
-        /*
-         * This must not be called using DOSVM_BuildCallFrame.
-         */
-        DOSVM_RelayHandler( context );
-    }
-    else if (context->SegCs == int16_sel)
+    if (context->SegCs == int16_sel)
     {
         /* Restore original flags stored into the stack by the caller. */
         WORD *stack = CTX_SEG_OFF_TO_LIN(context, 
diff --git a/dlls/krnl386.exe16/relay.c b/dlls/krnl386.exe16/relay.c
index 3559bb460a7..116198e5ddb 100644
--- a/dlls/krnl386.exe16/relay.c
+++ b/dlls/krnl386.exe16/relay.c
@@ -34,26 +34,6 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(relay);
 
-/*
- * Magic DWORD used to check stack integrity.
- */
-#define RELAY_MAGIC 0xabcdef00
-
-/*
- * Memory block for temporary 16-bit stacks used with relay calls.
- */
-typedef struct {
-    DWORD inuse;          /* non-zero if stack block is in use */
-    DWORD eip;            /* saved ip */
-    DWORD seg_cs;         /* saved cs */
-    DWORD esp;            /* saved sp */
-    DWORD seg_ss;         /* saved ss */
-    DWORD stack_bottom;   /* guard dword */
-    BYTE  stack[256-7*4]; /* 16-bit stack */
-    DWORD stack_top;      /* guard dword */
-} RELAY_Stack16;
-
-
 static const char **debug_relay_excludelist;
 static const char **debug_relay_includelist;
 static const char **debug_snoop_excludelist;
@@ -572,58 +552,6 @@ int relay_call_from_16( void *entry_point, unsigned char *args16, CONTEXT *conte
     return ret_val;
 }
 
-/**********************************************************************
- *          RELAY_GetPointer
- *
- * Get pointer to stack block when given esp pointing to 16-bit stack
- * inside relay data segment.
- */
-static RELAY_Stack16 *RELAY_GetPointer( DWORD offset )
-{
-    offset = offset / sizeof(RELAY_Stack16) * sizeof(RELAY_Stack16);
-    return MapSL(MAKESEGPTR(relay_data_sel, offset));
-}
-
-
-/**********************************************************************
- *          RELAY_MakeShortContext
- *
- * Allocate separate 16-bit stack, make stack pointer point to this
- * stack and make code pointer point to stub that restores everything.
- * So, after this routine, SS and CS are guaranteed to be 16-bit.
- *
- * Note: This might be called from signal handler, so the stack
- *       allocation algorithm must be signal safe.
- */
-static void RELAY_MakeShortContext( CONTEXT *context )
-{
-    DWORD offset = offsetof(RELAY_Stack16, stack_top);
-    RELAY_Stack16 *stack = RELAY_GetPointer( 0 );
-
-    while (stack->inuse && offset < DOSVM_RELAY_DATA_SIZE) {
-        stack++;
-        offset += sizeof(RELAY_Stack16);
-    }
-
-    if (offset >= DOSVM_RELAY_DATA_SIZE)
-        ERR( "Too many nested interrupts!\n" );
-
-    stack->inuse = 1;
-    stack->eip = context->Eip;
-    stack->seg_cs = context->SegCs;
-    stack->esp = context->Esp;
-    stack->seg_ss = context->SegSs;
-
-    stack->stack_bottom = RELAY_MAGIC;
-    stack->stack_top = RELAY_MAGIC;
-
-    context->SegSs = relay_data_sel;
-    context->Esp = offset;
-    context->SegCs = relay_code_sel;
-    context->Eip = 3;
-}
-
-
 /**********************************************************************
  *          RELAY_RelayStub
  *
@@ -632,58 +560,9 @@ static void RELAY_MakeShortContext( CONTEXT *context )
  */
 static void __stdcall RELAY_RelayStub( DOSRELAY proc, unsigned char *args, CONTEXT *context )
 {
-    if (proc)
-    {
-        RELAY_Stack16 *stack = RELAY_GetPointer( context->Esp );
-
-        DWORD old_seg_cs = context->SegCs;
-        DWORD old_eip    = context->Eip;
-        DWORD old_seg_ss = context->SegSs;
-        DWORD old_esp    = context->Esp;
-
-        context->SegCs = stack->seg_cs;
-        context->Eip   = stack->eip;
-        context->SegSs = stack->seg_ss;
-        context->Esp   = stack->esp;
-
-        proc( context, *(LPVOID *)args );
-
-        stack->seg_cs = context->SegCs;
-        stack->eip    = context->Eip;
-        stack->seg_ss = context->SegSs;
-        stack->esp    = context->Esp;
-
-        context->SegCs = old_seg_cs;
-        context->Eip   = old_eip;
-        context->SegSs = old_seg_ss;
-        context->Esp   = old_esp;
-    }
+    proc( context, *(LPVOID *)args );
 }
 
-
-/**********************************************************************
- *          DOSVM_RelayHandler
- *
- * Restore saved code and stack pointers and release stack block.
- */
-void DOSVM_RelayHandler( CONTEXT *context )
-{
-    RELAY_Stack16 *stack = RELAY_GetPointer( context->Esp );
-
-    context->SegSs = stack->seg_ss;
-    context->Esp = stack->esp;
-    context->SegCs = stack->seg_cs;
-    context->Eip = stack->eip;
-
-    if (!stack->inuse ||
-        stack->stack_bottom != RELAY_MAGIC ||
-        stack->stack_top != RELAY_MAGIC)
-        ERR( "Stack corrupted!\n" );
-
-    stack->inuse = 0;
-}
-
-
 /**********************************************************************
  *          DOSVM_BuildCallFrame
  *
@@ -692,13 +571,6 @@ void DOSVM_RelayHandler( CONTEXT *context )
  */
 void DOSVM_BuildCallFrame( CONTEXT *context, DOSRELAY relay, LPVOID data )
 {
-    WORD  code_sel = relay_code_sel;
-
-    /*
-     * Allocate separate stack for relay call.
-     */
-    RELAY_MakeShortContext( context );
-
     /*
      * Build call frame.
      */
@@ -713,7 +585,7 @@ void DOSVM_BuildCallFrame( CONTEXT *context, DOSRELAY relay, LPVOID data )
     PUSH_WORD16( context, HIWORD(RELAY_RelayStub) ); /* STACK16FRAME.relay.hiword */
     PUSH_WORD16( context, LOWORD(RELAY_RelayStub) ); /* STACK16FRAME.relay.loword */
     PUSH_WORD16( context, 0 );                       /* STACK16FRAME.module_cs.hiword */
-    PUSH_WORD16( context, code_sel );                /* STACK16FRAME.module_cs.loword */
+    PUSH_WORD16( context, relay_code_sel );          /* STACK16FRAME.module_cs.loword */
     PUSH_WORD16( context, 0 );                       /* STACK16FRAME.callfrom_ip.hiword */
     PUSH_WORD16( context, 0 );                       /* STACK16FRAME.callfrom_ip.loword */
 
-- 
2.33.0




More information about the wine-devel mailing list