winedos: fix 16bit stack pushing
Markus Amsler
markus.amsler at oribi.org
Sun Oct 17 18:50:50 CDT 2004
Pushing on stack from 16 bit mode was unsafe, because if esp was 0 it
pushed into the previous segment instead of wrap around in the same one.
This caused some crashes while invoking hooked interrupts.
Changlog:
* Push on stack in 16 bit mode with segment wrap around
-------------- next part --------------
Index: dlls/winedos/dosexe.h
===================================================================
RCS file: /home/wine/wine/dlls/winedos/dosexe.h,v
retrieving revision 1.34
diff -u -r1.34 dosexe.h
--- dlls/winedos/dosexe.h 15 Nov 2003 00:13:21 -0000 1.34
+++ dlls/winedos/dosexe.h 17 Oct 2004 23:46:16 -0000
@@ -136,6 +136,11 @@
LOWORD((context)->Ecx), LOWORD((context)->Edx), LOWORD((context)->Esi), \
LOWORD((context)->Edi), (WORD)(context)->SegDs, (WORD)(context)->SegEs )
+/* pushing on stack in 16 bit needs segment wrap around */
+#define PUSH_WORD16(context,val) \
+ *((WORD*)CTX_SEG_OFF_TO_LIN((context), \
+ (context)->SegSs, ADD_LOWORD( context->Esp, -2 ) )) = (val)
+
/* Macros for easier access to i386 context registers */
#define AX_reg(context) ((WORD)(context)->Eax)
Index: dlls/winedos/interrupts.c
===================================================================
RCS file: /home/wine/wine/dlls/winedos/interrupts.c,v
retrieving revision 1.24
diff -u -r1.24 interrupts.c
--- dlls/winedos/interrupts.c 25 Nov 2003 00:42:27 -0000 1.24
+++ dlls/winedos/interrupts.c 17 Oct 2004 23:46:25 -0000
@@ -392,8 +392,6 @@
}
else
{
- WORD *stack;
-
TRACE( "invoking hooked interrupt %02x at %04x:%04x\n",
intnum, SELECTOROF(addr), OFFSETOF(addr) );
@@ -401,11 +399,9 @@
DOSVM_PrepareIRQ( context, FALSE );
/* Push the flags and return address on the stack */
- stack = CTX_SEG_OFF_TO_LIN(context, context->SegSs, context->Esp);
- *(--stack) = LOWORD(context->EFlags);
- *(--stack) = context->SegCs;
- *(--stack) = LOWORD(context->Eip);
- ADD_LOWORD( context->Esp, -6 );
+ PUSH_WORD16( context, LOWORD(context->EFlags) );
+ PUSH_WORD16( context, context->SegCs );
+ PUSH_WORD16( context, LOWORD(context->Eip) );
/* Jump to the interrupt handler */
context->SegCs = HIWORD(addr);
@@ -506,7 +502,6 @@
else
{
/* the interrupt is hooked, simulate interrupt in DOS space */
- WORD* stack = PTR_REAL_TO_LIN( context->SegSs, context->Esp );
WORD flag = LOWORD( context->EFlags );
TRACE( "invoking hooked interrupt %02x at %04x:%04x\n",
@@ -518,10 +513,10 @@
else
flag &= ~IF_MASK;
- *(--stack) = flag;
- *(--stack) = context->SegCs;
- *(--stack) = LOWORD( context->Eip );
- context->Esp -= 6;
+ PUSH_WORD16( context, flag );
+ PUSH_WORD16( context, context->SegCs );
+ PUSH_WORD16( context, LOWORD( context->Eip ));
+
context->SegCs = SELECTOROF( handler );
context->Eip = OFFSETOF( handler );
Index: dlls/winedos/relay.c
===================================================================
RCS file: /home/wine/wine/dlls/winedos/relay.c,v
retrieving revision 1.6
diff -u -r1.6 relay.c
--- dlls/winedos/relay.c 14 Oct 2003 05:20:34 -0000 1.6
+++ dlls/winedos/relay.c 17 Oct 2004 23:46:26 -0000
@@ -168,7 +168,6 @@
*/
void DOSVM_BuildCallFrame( CONTEXT86 *context, DOSRELAY relay, LPVOID data )
{
- WORD *stack;
WORD code_sel = DOSVM_dpmi_segments->relay_code_sel;
/*
@@ -177,32 +176,26 @@
RELAY_MakeShortContext( context );
/*
- * Get stack pointer after RELAY_MakeShortContext.
- */
- stack = CTX_SEG_OFF_TO_LIN(context, context->SegSs, context->Esp);
-
- /*
* Build call frame.
*/
- *(--stack) = HIWORD(data); /* argument.hiword */
- *(--stack) = LOWORD(data); /* argument.loword */
- *(--stack) = context->SegCs; /* STACK16FRAME.cs */
- *(--stack) = LOWORD(context->Eip); /* STACK16FRAME.ip */
- *(--stack) = LOWORD(context->Ebp); /* STACK16FRAME.bp */
- *(--stack) = HIWORD(relay); /* STACK16FRAME.entry_point.hiword */
- *(--stack) = LOWORD(relay); /* STACK16FRAME.entry_point.loword */
- *(--stack) = 0; /* STACK16FRAME.entry_ip */
- *(--stack) = HIWORD(RELAY_RelayStub); /* STACK16FRAME.relay.hiword */
- *(--stack) = LOWORD(RELAY_RelayStub); /* STACK16FRAME.relay.loword */
- *(--stack) = 0; /* STACK16FRAME.module_cs.hiword */
- *(--stack) = code_sel; /* STACK16FRAME.module_cs.loword */
- *(--stack) = 0; /* STACK16FRAME.callfrom_ip.hiword */
- *(--stack) = 0; /* STACK16FRAME.callfrom_ip.loword */
+ PUSH_WORD16( context, HIWORD(data) ); /* argument.hiword */
+ PUSH_WORD16( context, LOWORD(data) ); /* argument.loword */
+ PUSH_WORD16( context, context->SegCs ); /* STACK16FRAME.cs */
+ PUSH_WORD16( context, LOWORD(context->Eip) ); /* STACK16FRAME.ip */
+ PUSH_WORD16( context, LOWORD(context->Ebp) ); /* STACK16FRAME.bp */
+ PUSH_WORD16( context, HIWORD(relay) ); /* STACK16FRAME.entry_point.hiword */
+ PUSH_WORD16( context, LOWORD(relay) ); /* STACK16FRAME.entry_point.loword */
+ PUSH_WORD16( context, 0 ); /* STACK16FRAME.entry_ip */
+ 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, 0 ); /* STACK16FRAME.callfrom_ip.hiword */
+ PUSH_WORD16( context, 0 ); /* STACK16FRAME.callfrom_ip.loword */
/*
- * Adjust stack and code pointers.
+ * Adjust code pointer.
*/
- ADD_LOWORD( context->Esp, -28 );
context->SegCs = wine_get_cs();
context->Eip = (DWORD)__wine_call_from_16_regs;
}
More information about the wine-patches
mailing list