Alexandre Julliard : msvcrt: Added assembly routines to save/restore
registers for setjmp/longjmp
Alexandre Julliard
julliard at wine.codeweavers.com
Thu Jan 5 10:53:58 CST 2006
Module: wine
Branch: refs/heads/master
Commit: 545c4b7e7c002a04e289d57384b06a72a6738e05
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=545c4b7e7c002a04e289d57384b06a72a6738e05
Author: Alexandre Julliard <julliard at winehq.org>
Date: Thu Jan 5 14:36:37 2006 +0100
msvcrt: Added assembly routines to save/restore registers for setjmp/longjmp
to avoid the overhead of a full-blown register function.
Some tracing improvements.
---
dlls/msvcrt/except.c | 80 ++++++++++++++++++++++++++---------------------
dlls/msvcrt/msvcrt.spec | 8 ++---
2 files changed, 49 insertions(+), 39 deletions(-)
diff --git a/dlls/msvcrt/except.c b/dlls/msvcrt/except.c
index b17a04f..d0ea060 100644
--- a/dlls/msvcrt/except.c
+++ b/dlls/msvcrt/except.c
@@ -42,7 +42,7 @@
#include "msvcrt/float.h"
#include "wine/debug.h"
-WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
+WINE_DEFAULT_DEBUG_CHANNEL(seh);
/* VC++ extensions to Win32 SEH */
typedef struct _SCOPETABLE
@@ -261,6 +261,33 @@ int _abnormal_termination(void)
#define MSVCRT_JMP_MAGIC 0x56433230 /* ID value for new jump structure */
typedef void (*MSVCRT_unwind_function)(const void*);
+/* define an entrypoint for setjmp/setjmp3 that stores the registers in the jmp buf */
+/* and then jumps to the C backend function */
+#define DEFINE_SETJMP_ENTRYPOINT(name) \
+ __ASM_GLOBAL_FUNC( name, \
+ "movl 4(%esp),%ecx\n\t" /* jmp_buf */ \
+ "movl %ebp,0(%ecx)\n\t" /* jmp_buf.Ebp */ \
+ "movl %ebx,4(%ecx)\n\t" /* jmp_buf.Ebx */ \
+ "movl %edi,8(%ecx)\n\t" /* jmp_buf.Edi */ \
+ "movl %esi,12(%ecx)\n\t" /* jmp_buf.Esi */ \
+ "movl %esp,16(%ecx)\n\t" /* jmp_buf.Esp */ \
+ "movl 0(%esp),%eax\n\t" \
+ "movl %eax,20(%ecx)\n\t" /* jmp_buf.Eip */ \
+ "jmp " __ASM_NAME("__regs_") # name )
+
+/* restore the registers from the jmp buf upon longjmp */
+extern void DECLSPEC_NORETURN longjmp_set_regs( struct MSVCRT___JUMP_BUFFER *jmp, int retval );
+__ASM_GLOBAL_FUNC( longjmp_set_regs,
+ "movl 4(%esp),%ecx\n\t" /* jmp_buf */
+ "movl 8(%esp),%eax\n\t" /* retval */
+ "movl 0(%ecx),%ebp\n\t" /* jmp_buf.Ebp */
+ "movl 4(%ecx),%ebx\n\t" /* jmp_buf.Ebx */
+ "movl 8(%ecx),%edi\n\t" /* jmp_buf.Edi */
+ "movl 12(%ecx),%esi\n\t" /* jmp_buf.Esi */
+ "movl 16(%ecx),%esp\n\t" /* jmp_buf.Esp */
+ "addl $4,%esp\n\t" /* get rid of return address */
+ "jmp *20(%ecx)\n\t" /* jmp_buf.Eip */ );
+
/*
* The signatures of the setjmp/longjmp functions do not match that
* declared in the setjmp header so they don't follow the regular naming
@@ -270,38 +297,26 @@ typedef void (*MSVCRT_unwind_function)(c
/*******************************************************************
* _setjmp (MSVCRT.@)
*/
-DEFINE_REGS_ENTRYPOINT( MSVCRT__setjmp, 4, 0 );
-void WINAPI __regs_MSVCRT__setjmp(struct MSVCRT___JUMP_BUFFER *jmp, CONTEXT86* context)
+DEFINE_SETJMP_ENTRYPOINT(MSVCRT__setjmp);
+int __regs_MSVCRT__setjmp(struct MSVCRT___JUMP_BUFFER *jmp)
{
- 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()->Tib.ExceptionList;
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;
+
+ TRACE("buf=%p ebx=%08lx esi=%08lx edi=%08lx ebp=%08lx esp=%08lx eip=%08lx frame=%08lx\n",
+ jmp, jmp->Ebx, jmp->Esi, jmp->Edi, jmp->Ebp, jmp->Esp, jmp->Eip, jmp->Registration );
+ return 0;
}
/*******************************************************************
* _setjmp3 (MSVCRT.@)
*/
-DEFINE_REGS_ENTRYPOINT( MSVCRT__setjmp3, 8, 0 );
-void WINAPI __regs_MSVCRT__setjmp3(struct MSVCRT___JUMP_BUFFER *jmp, int nb_args, CONTEXT86* context)
+DEFINE_SETJMP_ENTRYPOINT( MSVCRT__setjmp3 );
+int __regs_MSVCRT__setjmp3(struct MSVCRT___JUMP_BUFFER *jmp, int nb_args)
{
- 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()->Tib.ExceptionList;
@@ -311,7 +326,7 @@ void WINAPI __regs_MSVCRT__setjmp3(struc
}
else
{
- void **args = ((void**)context->Esp)+2;
+ void **args = ((void**)jmp->Esp)+2;
if (nb_args > 0) jmp->UnwindFunc = (unsigned long)*args++;
if (nb_args > 1) jmp->TryLevel = (unsigned long)*args++;
@@ -322,19 +337,21 @@ void WINAPI __regs_MSVCRT__setjmp3(struc
memcpy( jmp->UnwindData, args, min( size, sizeof(jmp->UnwindData) ));
}
}
- TRACE("returning 0\n");
- context->Eax = 0;
+
+ TRACE("buf=%p ebx=%08lx esi=%08lx edi=%08lx ebp=%08lx esp=%08lx eip=%08lx frame=%08lx\n",
+ jmp, jmp->Ebx, jmp->Esi, jmp->Edi, jmp->Ebp, jmp->Esp, jmp->Eip, jmp->Registration );
+ return 0;
}
/*********************************************************************
* longjmp (MSVCRT.@)
*/
-DEFINE_REGS_ENTRYPOINT( MSVCRT_longjmp, 8, 0 );
-void WINAPI __regs_MSVCRT_longjmp(struct MSVCRT___JUMP_BUFFER *jmp, int retval, CONTEXT86* context)
+int MSVCRT_longjmp(struct MSVCRT___JUMP_BUFFER *jmp, int retval)
{
unsigned long cur_frame = 0;
- TRACE("(%p,%d)\n", jmp, retval);
+ TRACE("buf=%p ebx=%08lx esi=%08lx edi=%08lx ebp=%08lx esp=%08lx eip=%08lx frame=%08lx retval=%08x\n",
+ jmp, jmp->Ebx, jmp->Esi, jmp->Edi, jmp->Ebp, jmp->Esp, jmp->Eip, jmp->Registration, retval );
cur_frame=(unsigned long)NtCurrentTeb()->Tib.ExceptionList;
TRACE("cur_frame=%lx\n",cur_frame);
@@ -360,14 +377,7 @@ void WINAPI __regs_MSVCRT_longjmp(struct
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;
+ longjmp_set_regs( jmp, retval );
}
/*********************************************************************
diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec
index 8e4a994..69aa578 100644
--- a/dlls/msvcrt/msvcrt.spec
+++ b/dlls/msvcrt/msvcrt.spec
@@ -322,7 +322,7 @@
@ cdecl _lock(long)
@ cdecl _locking(long long long)
@ cdecl _logb( double )
-@ cdecl -i386 -register _longjmpex(ptr long) MSVCRT_longjmp
+@ cdecl -i386 _longjmpex(ptr long) MSVCRT_longjmp
@ cdecl _lrotl(long long)
@ cdecl _lrotr(long long)
@ cdecl _lsearch(ptr ptr long long ptr)
@@ -426,8 +426,8 @@
@ cdecl _set_error_mode(long)
@ cdecl _set_sbh_threshold(long)
@ cdecl _seterrormode(long)
-@ cdecl -i386 -register _setjmp(ptr) MSVCRT__setjmp
-@ cdecl -i386 -register _setjmp3(ptr long) MSVCRT__setjmp3
+@ cdecl -i386 -norelay _setjmp(ptr) MSVCRT__setjmp
+@ cdecl -i386 -norelay _setjmp3(ptr long) MSVCRT__setjmp3
@ stub _setmaxstdio #(long)
@ cdecl _setmbcp(long)
@ cdecl _setmode(long long)
@@ -659,7 +659,7 @@
@ cdecl localtime(ptr) MSVCRT_localtime
@ cdecl log(double)
@ cdecl log10(double)
-@ cdecl -i386 -register longjmp(ptr long) MSVCRT_longjmp
+@ cdecl -i386 longjmp(ptr long) MSVCRT_longjmp
@ cdecl malloc(long) MSVCRT_malloc
@ cdecl mblen(ptr long) MSVCRT_mblen
@ cdecl mbstowcs(ptr str long) ntdll.mbstowcs
More information about the wine-cvs
mailing list