Commit 545c4b7e authored by Alexandre Julliard's avatar Alexandre Julliard

msvcrt: Added assembly routines to save/restore registers for setjmp/longjmp

to avoid the overhead of a full-blown register function. Some tracing improvements.
parent abb170fa
......@@ -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)(const void*);
/*******************************************************************
* _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(struct MSVCRT___JUMP_BUFFER *jmp, int nb_args
}
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(struct MSVCRT___JUMP_BUFFER *jmp, int nb_args
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 MSVCRT___JUMP_BUFFER *jmp, int retval,
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 );
}
/*********************************************************************
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment