Msvcrt patch 2/2
François Gouget
fgouget at codeweavers.com
Thu Dec 20 01:48:48 CST 2001
And here is part two. This one deals with setjmp/setjmp3 and longjmp.
I also worked with Alexandre to convert it to use register functions
(hence the recent patches if anyone was wondering).
(note there's one new file: include/msvcrt/setjmp.h)
Changelog:
Jon Griffiths <jon_p_griffiths at yahoo.com>
François Gouget <fgouget at codeweavers.com>
Alexandre Julliard <julliard at codeweavers.com>
* include/msvcrt/setjmp.h,
dlls/msvcrt/except.c
Implement setjmp/setjmp3 and longjmp
--
François Gouget
fgouget at codeweavers.com
-------------- next part --------------
--- /dev/null Thu Dec 13 01:07:23 2001
+++ include/msvcrt/setjmp.h Wed Dec 19 23:18:16 2001
@@ -0,0 +1,58 @@
+/*
+ * Setjmp/Longjmp definitions
+ *
+ * Copyright 2001 Francois Gouget.
+ */
+#ifndef __WINE_SETJMP_H
+#define __WINE_SETJMP_H
+#define __WINE_USE_MSVCRT
+
+#ifdef USE_MSVCRT_PREFIX
+#define MSVCRT(x) MSVCRT_##x
+#else
+#define MSVCRT(x) x
+#endif
+
+
+#ifdef __i386__
+
+#define _JBLEN 16
+#define _JBTYPE int
+
+typedef struct __JUMP_BUFFER
+{
+ unsigned long Ebp;
+ unsigned long Ebx;
+ unsigned long Edi;
+ unsigned long Esi;
+ unsigned long Esp;
+ unsigned long Eip;
+ unsigned long Registration;
+ unsigned long TryLevel;
+ /* Start of new struct members */
+ unsigned long Cookie;
+ unsigned long UnwindFunc;
+ unsigned long UnwindData[6];
+} _JUMP_BUFFER;
+
+#endif /* __i386__ */
+
+typedef _JBTYPE MSVCRT(jmp_buf)[_JBLEN];
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int MSVCRT(_setjmp)( MSVCRT(jmp_buf));
+int MSVCRT(longjmp)( MSVCRT(jmp_buf),int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifndef USE_MSVCRT_PREFIX
+#define setjmp _setjmp
+#endif
+
+#endif /* __WINE_SETJMP_H */
Index: dlls/msvcrt/except.c
===================================================================
RCS file: /home/wine/wine/dlls/msvcrt/except.c,v
retrieving revision 1.7
diff -u -r1.7 except.c
--- dlls/msvcrt/except.c 2001/09/20 19:33:37 1.7
+++ dlls/msvcrt/except.c 2001/12/20 05:48:23
@@ -15,6 +15,9 @@
#include "thread.h"
#include "msvcrt.h"
+#include "msvcrt/setjmp.h"
+
+
DEFAULT_DEBUG_CHANNEL(msvcrt);
typedef void (*MSVCRT_sig_handler_func)(void);
@@ -227,32 +230,120 @@
return 0;
}
+/*
+ * setjmp/longjmp implementation
+ */
+
+#ifdef __i386__
+#define MSVCRT_JMP_MAGIC 0x56433230 /* ID value for new jump structure */
+typedef void (*MSVCRT_unwind_function)(const void*);
+
+/*
+ * The signatures of the setjmp/longjmp functions do not match that
+ * declared in the setjmp header so they don't follow the regular naming
+ * convention to avoid conflicts.
+ */
+
/*******************************************************************
* _setjmp (MSVCRT.@)
*/
-int MSVCRT__setjmp(LPDWORD* jmpbuf)
+void _MSVCRT__setjmp(_JUMP_BUFFER *jmp, CONTEXT86* context)
{
- FIXME(":(%p): stub\n",jmpbuf);
- return 0;
+ TRACE("(%p)\n",jmp);
+ jmp->Ebp = context->Ebp;
+ jmp->Ebx = context->Ebx;
+ jmp->Edi = context->Edi;
+ jmp->Esi = context->Esi;
+ jmp->Esp = context->Esp;
+ jmp->Eip = context->Eip;
+ jmp->Registration = (unsigned long)NtCurrentTeb()->except;
+ if (jmp->Registration == TRYLEVEL_END)
+ jmp->TryLevel = TRYLEVEL_END;
+ else
+ jmp->TryLevel = ((MSVCRT_EXCEPTION_FRAME*)jmp->Registration)->trylevel;
+ TRACE("returning 0\n");
+ context->Eax=0;
}
/*******************************************************************
* _setjmp3 (MSVCRT.@)
*/
-int __cdecl MSVCRT__setjmp3(LPDWORD *jmpbuf, int x)
+void _MSVCRT__setjmp3(_JUMP_BUFFER *jmp, int nb_args, CONTEXT86* context)
{
- FIXME(":(%p %x): stub\n",jmpbuf,x);
- return 0;
+ TRACE("(%p,%d)\n",jmp,nb_args);
+ jmp->Ebp = context->Ebp;
+ jmp->Ebx = context->Ebx;
+ jmp->Edi = context->Edi;
+ jmp->Esi = context->Esi;
+ jmp->Esp = context->Esp;
+ jmp->Eip = context->Eip;
+ jmp->Cookie = MSVCRT_JMP_MAGIC;
+ jmp->UnwindFunc = 0;
+ jmp->Registration = (unsigned long)NtCurrentTeb()->except;
+ if (jmp->Registration == TRYLEVEL_END)
+ {
+ jmp->TryLevel = TRYLEVEL_END;
+ }
+ else
+ {
+ void **args = ((void**)context->Esp)+2;
+
+ if (nb_args > 0) jmp->UnwindFunc = (unsigned long)*args++;
+ if (nb_args > 1) jmp->TryLevel = (unsigned long)*args++;
+ else jmp->TryLevel = ((MSVCRT_EXCEPTION_FRAME*)jmp->Registration)->trylevel;
+ if (nb_args > 2)
+ {
+ size_t size = (nb_args - 2) * sizeof(DWORD);
+ memcpy( jmp->UnwindData, args, min( size, sizeof(jmp->UnwindData) ));
+ }
+ }
+ TRACE("returning 0\n");
+ context->Eax = 0;
}
/*********************************************************************
* longjmp (MSVCRT.@)
*/
-void MSVCRT_longjmp(jmp_buf env, int val)
+void _MSVCRT_longjmp(_JUMP_BUFFER *jmp, int retval, CONTEXT86* context)
{
- FIXME("MSVCRT_longjmp semistub, expect crash\n");
- longjmp(env, val);
+ unsigned long cur_frame = 0;
+
+ TRACE("(%p,%d)\n", jmp, retval);
+
+ cur_frame=(unsigned long)NtCurrentTeb()->except;
+ TRACE("cur_frame=%lx\n",cur_frame);
+
+ if (cur_frame != jmp->Registration)
+ _global_unwind2((PEXCEPTION_FRAME)jmp->Registration);
+
+ if (jmp->Registration)
+ {
+ if (!IsBadReadPtr(&jmp->Cookie, sizeof(long)) &&
+ jmp->Cookie == MSVCRT_JMP_MAGIC && jmp->UnwindFunc)
+ {
+ MSVCRT_unwind_function unwind_func;
+
+ unwind_func=(MSVCRT_unwind_function)jmp->UnwindFunc;
+ unwind_func(jmp);
+ }
+ else
+ _local_unwind2((MSVCRT_EXCEPTION_FRAME*)jmp->Registration,
+ jmp->TryLevel);
+ }
+
+ if (!retval)
+ retval = 1;
+
+ TRACE("Jump to %lx returning %d\n",jmp->Eip,retval);
+ context->Ebp = jmp->Ebp;
+ context->Ebx = jmp->Ebx;
+ context->Edi = jmp->Edi;
+ context->Esi = jmp->Esi;
+ context->Esp = jmp->Esp;
+ context->Eip = jmp->Eip;
+ context->Eax = retval;
}
+#endif /* i386 */
/*********************************************************************
* signal (MSVCRT.@)
Index: dlls/msvcrt/msvcrt.spec
===================================================================
RCS file: /home/wine/wine/dlls/msvcrt/msvcrt.spec,v
retrieving revision 1.26
diff -u -r1.26 msvcrt.spec
--- dlls/msvcrt/msvcrt.spec 2001/12/05 22:11:35 1.26
+++ dlls/msvcrt/msvcrt.spec 2001/12/20 05:48:24
@@ -432,8 +432,8 @@
@ stub _set_error_mode #(long)
@ stub _set_sbh_threshold #(long)
@ stub _seterrormode #(long)
-@ cdecl _setjmp(ptr) MSVCRT__setjmp
-@ cdecl _setjmp3(ptr long) MSVCRT__setjmp3
+@ cdecl -register -noimport -i386 _setjmp(ptr) _MSVCRT__setjmp
+@ cdecl -register -noimport -i386 _setjmp3(ptr long) _MSVCRT__setjmp3
@ stub _setmaxstdio #(long)
@ cdecl _setmbcp(long) _setmbcp
@ cdecl _setmode(long long) _setmode
@@ -665,7 +665,7 @@
@ cdecl localtime(ptr) localtime
@ forward -noimport log ntdll.log
@ cdecl log10(double) log10
-@ cdecl longjmp(long long) MSVCRT_longjmp
+@ cdecl -register -noimport -i386 longjmp(ptr long) _MSVCRT_longjmp
@ cdecl malloc(long) MSVCRT_malloc
@ cdecl mblen(ptr long) MSVCRT_mblen
@ forward -noimport mbstowcs ntdll.mbstowcs
More information about the wine-patches
mailing list