Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/msvcrt/except_i386.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/dlls/msvcrt/except_i386.c b/dlls/msvcrt/except_i386.c index ee12fb6..2c845b2 100644 --- a/dlls/msvcrt/except_i386.c +++ b/dlls/msvcrt/except_i386.c @@ -172,12 +172,14 @@ __ASM_GLOBAL_FUNC( call_copy_ctor, "ret" );
/* continue execution to the specified address after exception is caught */ -static inline void DECLSPEC_NORETURN continue_after_catch( cxx_exception_frame* frame, void *addr ) -{ - __asm__ __volatile__("movl -4(%0),%%esp; leal 12(%0),%%ebp; jmp *%1" - : : "r" (frame), "a" (addr) ); - for (;;) ; /* unreached */ -} +extern void DECLSPEC_NORETURN continue_after_catch( cxx_exception_frame* frame, void *addr ); + +__ASM_GLOBAL_FUNC( continue_after_catch, + "movl 4(%esp), %edx\n\t" + "movl 8(%esp), %eax\n\t" + "movl -4(%edx), %esp\n\t" + "leal 12(%edx), %ebp\n\t" + "jmp *%eax" );
static inline void call_finally_block( void *code_block, void *base_ptr ) {
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/msvcrt/except_i386.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/dlls/msvcrt/except_i386.c b/dlls/msvcrt/except_i386.c index 2c845b2..508e2ee 100644 --- a/dlls/msvcrt/except_i386.c +++ b/dlls/msvcrt/except_i386.c @@ -181,11 +181,11 @@ __ASM_GLOBAL_FUNC( continue_after_catch, "leal 12(%edx), %ebp\n\t" "jmp *%eax" );
-static inline void call_finally_block( void *code_block, void *base_ptr ) -{ - __asm__ __volatile__ ("movl %1,%%ebp; call *%%eax" - : : "a" (code_block), "g" (base_ptr)); -} +extern void DECLSPEC_NORETURN call_finally_block( void *code_block, void *base_ptr ); + +__ASM_GLOBAL_FUNC( call_finally_block, + "movl 8(%esp), %ebp\n\t" + "jmp *4(%esp)" );
static inline int call_filter( int (*func)(PEXCEPTION_POINTERS), void *arg, void *ebp ) { @@ -938,7 +938,6 @@ int CDECL _except_handler3(PEXCEPTION_RECORD rec, frame->trylevel = pScopeTable[trylevel].previousTryLevel; TRACE("__finally block %p\n",pScopeTable[trylevel].lpfnHandler); call_finally_block(pScopeTable[trylevel].lpfnHandler, &frame->_ebp); - ERR("Returned from __finally block - expect crash!\n"); } } trylevel = pScopeTable[trylevel].previousTryLevel; @@ -1012,7 +1011,6 @@ int CDECL _except_handler4_common( ULONG *cookie, void (*check_cookie)(void), frame->trylevel = scope_table->entries[trylevel].previousTryLevel; TRACE("__finally block %p\n",scope_table->entries[trylevel].lpfnHandler); call_finally_block(scope_table->entries[trylevel].lpfnHandler, &frame->_ebp); - ERR("Returned from __finally block - expect crash!\n"); } } trylevel = scope_table->entries[trylevel].previousTryLevel;
Signed-off-by: Piotr Caban piotr@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/msvcrt/except_i386.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/dlls/msvcrt/except_i386.c b/dlls/msvcrt/except_i386.c index 508e2ee..29540cd 100644 --- a/dlls/msvcrt/except_i386.c +++ b/dlls/msvcrt/except_i386.c @@ -187,15 +187,16 @@ __ASM_GLOBAL_FUNC( call_finally_block, "movl 8(%esp), %ebp\n\t" "jmp *4(%esp)" );
-static inline int call_filter( int (*func)(PEXCEPTION_POINTERS), void *arg, void *ebp ) -{ - int ret; - __asm__ __volatile__ ("pushl %%ebp; pushl %3; movl %2,%%ebp; call *%%eax; popl %%ebp; popl %%ebp" - : "=a" (ret) - : "0" (func), "r" (ebp), "r" (arg) - : "ecx", "edx", "memory" ); - return ret; -} +extern int call_filter( int (*func)(PEXCEPTION_POINTERS), void *arg, void *ebp ); + +__ASM_GLOBAL_FUNC( call_filter, + "pushl %ebp\n\t" + "pushl 12(%esp)\n\t" + "movl 20(%esp), %ebp\n\t" + "call *12(%esp)\n\t" + "popl %ebp\n\t" + "popl %ebp\n\t" + "ret" );
static inline int call_unwind_func( int (*func)(void), void *ebp ) {
Signed-off-by: Piotr Caban piotr@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/msvcrt/except_i386.c | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-)
diff --git a/dlls/msvcrt/except_i386.c b/dlls/msvcrt/except_i386.c index 29540cd..42212c9 100644 --- a/dlls/msvcrt/except_i386.c +++ b/dlls/msvcrt/except_i386.c @@ -198,24 +198,20 @@ __ASM_GLOBAL_FUNC( call_filter, "popl %ebp\n\t" "ret" );
-static inline int call_unwind_func( int (*func)(void), void *ebp ) -{ - int ret; - __asm__ __volatile__ ("pushl %%ebp\n\t" - "pushl %%ebx\n\t" - "pushl %%esi\n\t" - "pushl %%edi\n\t" - "movl %2,%%ebp\n\t" - "call *%0\n\t" - "popl %%edi\n\t" - "popl %%esi\n\t" - "popl %%ebx\n\t" - "popl %%ebp" - : "=a" (ret) - : "0" (func), "r" (ebp) - : "ecx", "edx", "memory" ); - return ret; -} +extern int call_unwind_func( int (*func)(void), void *ebp ); + +__ASM_GLOBAL_FUNC( call_unwind_func, + "pushl %ebp\n\t" + "pushl %ebx\n\t" + "pushl %esi\n\t" + "pushl %edi\n\t" + "movl 24(%esp), %ebp\n\t" + "call *20(%esp)\n\t" + "popl %edi\n\t" + "popl %esi\n\t" + "popl %ebx\n\t" + "popl %ebp\n\t" + "ret" );
static inline void dump_type( const cxx_type_info *type ) {
Hi Zeb,
On 06/05/18 00:23, Zebediah Figura wrote:
+extern int call_unwind_func( int (*func)(void), void *ebp );
+__ASM_GLOBAL_FUNC( call_unwind_func,
"pushl %ebp\n\t"
"pushl %ebx\n\t"
"pushl %esi\n\t"
"pushl %edi\n\t"
"movl 24(%esp), %ebp\n\t"
"call *20(%esp)\n\t"
"popl %edi\n\t"
"popl %esi\n\t"
"popl %ebx\n\t"
"popl %ebp\n\t"
"ret" );
How about renaming the function to call_handler and returning void* from it? It looks strange that in all places where return value is used we need to cast it to pointer.
Thanks, Piotr
On 06/11/2018 11:48 AM, Piotr Caban wrote:
Hi Zeb,
On 06/05/18 00:23, Zebediah Figura wrote:
+extern int call_unwind_func( int (*func)(void), void *ebp );
+__ASM_GLOBAL_FUNC( call_unwind_func, + "pushl %ebp\n\t" + "pushl %ebx\n\t" + "pushl %esi\n\t" + "pushl %edi\n\t" + "movl 24(%esp), %ebp\n\t" + "call *20(%esp)\n\t" + "popl %edi\n\t" + "popl %esi\n\t" + "popl %ebx\n\t" + "popl %ebp\n\t" + "ret" );
How about renaming the function to call_handler and returning void* from it? It looks strange that in all places where return value is used we need to cast it to pointer.
Thanks, Piotr
Thanks; I'll send an updated patch.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/msvcrt/except_i386.c | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-)
diff --git a/dlls/msvcrt/except_i386.c b/dlls/msvcrt/except_i386.c index 42212c9..301c169 100644 --- a/dlls/msvcrt/except_i386.c +++ b/dlls/msvcrt/except_i386.c @@ -59,7 +59,7 @@ typedef struct __catchblock_info UINT flags; /* flags (see below) */ const type_info *type_info; /* C++ type caught by this block */ int offset; /* stack offset to copy exception object to */ - void (*handler)(void);/* catch block handler code */ + int (*handler)(void);/* catch block handler code */ } catchblock_info; #define TYPE_FLAG_CONST 1 #define TYPE_FLAG_VOLATILE 2 @@ -79,7 +79,7 @@ typedef struct __tryblock_info typedef struct __unwind_info { int prev; /* prev trylevel unwind handler, to run after this one */ - void (*handler)(void);/* unwind handler */ + int (*handler)(void);/* unwind handler */ } unwind_info;
/* descriptor of all try blocks of a given function */ @@ -137,22 +137,6 @@ DWORD CDECL cxx_frame_handler( PEXCEPTION_RECORD rec, cxx_exception_frame* frame const cxx_function_descr *descr, EXCEPTION_REGISTRATION_RECORD* nested_frame, int nested_trylevel ) DECLSPEC_HIDDEN;
-/* call a function with a given ebp */ -static inline void *call_ebp_func( void *func, void *ebp ) -{ - void *ret; - int dummy; - __asm__ __volatile__ ("pushl %%ebx\n\t" - "pushl %%ebp\n\t" - "movl %4,%%ebp\n\t" - "call *%%eax\n\t" - "popl %%ebp\n\t" - "popl %%ebx" - : "=a" (ret), "=S" (dummy), "=D" (dummy) - : "0" (func), "1" (ebp) : "ecx", "edx", "memory" ); - return ret; -} - /* call a copy constructor */ extern void call_copy_ctor( void *func, void *this, void *src, int has_vbase );
@@ -326,7 +310,7 @@ static void copy_exception( void *object, cxx_exception_frame *frame, /* unwind the local function up to a given trylevel */ static void cxx_local_unwind( cxx_exception_frame* frame, const cxx_function_descr *descr, int last_level) { - void (*handler)(void); + int (*handler)(void); int trylevel = frame->trylevel;
while (trylevel != last_level) @@ -341,7 +325,7 @@ static void cxx_local_unwind( cxx_exception_frame* frame, const cxx_function_des { TRACE( "calling unwind handler %p trylevel %d last %d ebp %p\n", handler, trylevel, last_level, &frame->ebp ); - call_ebp_func( handler, &frame->ebp ); + call_unwind_func( handler, &frame->ebp ); } trylevel = descr->unwind_table[trylevel].prev; } @@ -478,7 +462,7 @@ static inline void call_catch_block( PEXCEPTION_RECORD rec, CONTEXT *context, nested_frame.trylevel = nested_trylevel + 1;
__wine_push_frame( &nested_frame.frame ); - addr = call_ebp_func( catchblock->handler, &frame->ebp ); + addr = (void *)call_unwind_func( catchblock->handler, &frame->ebp ); __wine_pop_frame( &nested_frame.frame );
((DWORD*)frame)[-1] = save_esp;