Alexandre Julliard : libwine: Added a wine_call_on_stack function.
Alexandre Julliard
julliard at winehq.org
Thu Mar 27 07:21:35 CDT 2008
Module: wine
Branch: master
Commit: c9f0bea910eb7d2a9ec9b395ef19c89e493e63cf
URL: http://source.winehq.org/git/wine.git/?a=commit;h=c9f0bea910eb7d2a9ec9b395ef19c89e493e63cf
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed Mar 26 15:38:00 2008 +0100
libwine: Added a wine_call_on_stack function.
---
include/wine/library.h | 1 +
libs/wine/port.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++
libs/wine/wine.def | 3 +-
libs/wine/wine.map | 1 +
4 files changed, 68 insertions(+), 1 deletions(-)
diff --git a/include/wine/library.h b/include/wine/library.h
index f00919e..2c3b7bb 100644
--- a/include/wine/library.h
+++ b/include/wine/library.h
@@ -66,6 +66,7 @@ extern void wine_init( int argc, char *argv[], char *error, int error_size );
/* portability */
extern void DECLSPEC_NORETURN wine_switch_to_stack( void (*func)(void *), void *arg, void *stack );
+extern int wine_call_on_stack( int (*func)(void *), void *arg, void *stack );
extern void wine_set_pe_load_area( void *base, size_t size );
extern void wine_free_pe_load_area(void);
diff --git a/libs/wine/port.c b/libs/wine/port.c
index 838c3ff..e2f7b0c 100644
--- a/libs/wine/port.c
+++ b/libs/wine/port.c
@@ -116,5 +116,69 @@ __ASM_GLOBAL_FUNC( wine_switch_to_stack,
"callq *%rax\n\t" /* call func */
"int $3")
#else
+void DECLSPEC_NORETURN wine_switch_to_stack( void (*func)(void *), void *arg, void *stack )
+{
+ wine_call_on_stack( (int (*)(void *))func, arg, stack );
+ abort();
+}
+#endif
+
+
+/***********************************************************************
+ * wine_call_on_stack
+ *
+ * Switch to the specified stack to call the function and return.
+ */
+int wine_call_on_stack( int (*func)(void *), void *arg, void *stack );
+#if defined(__i386__) && defined(__GNUC__)
+__ASM_GLOBAL_FUNC( wine_call_on_stack,
+ "pushl %ebp\n\t"
+ "pushl %esi\n\t"
+ "movl 12(%esp),%ecx\n\t" /* func */
+ "movl 16(%esp),%edx\n\t" /* arg */
+ "movl 20(%esp),%esi\n\t" /* stack */
+ "andl $~15,%esi\n\t"
+ "subl $12,%esi\n\t"
+ "xchgl %esi,%esp\n\t"
+ "pushl %edx\n\t"
+ "xorl %ebp,%ebp\n\t"
+ "call *%ecx\n\t"
+ "movl %esi,%esp\n\t"
+ "popl %esi\n\t"
+ "popl %ebp\n\t"
+ "ret" )
+#elif defined(__i386__) && defined(_MSC_VER)
+__declspec(naked) int wine_call_on_stack( int (*func)(void *), void *arg, void *stack )
+{
+ __asm push ebp;
+ __asm push esi;
+ __asm mov ecx, 12[esp];
+ __asm mov edx, 16[esp];
+ __asm mov esi, 20[esp];
+ __asm xchg esp, esi;
+ __asm push edx;
+ __asm xor ebp, ebp;
+ __asm call [ecx];
+ __asm mov esp, esi;
+ __asm pop esi;
+ __asm pop ebp
+ __asm ret;
+}
+#elif defined(__x86_64__) && defined(__GNUC__)
+__ASM_GLOBAL_FUNC( wine_call_on_stack,
+ "pushq %rbp\n\t"
+ "pushq %rbx\n\t"
+ "movq %rsp,%rbx\n\t"
+ "movq %rdi,%rax\n\t" /* func */
+ "movq %rsi,%rdi\n\t" /* arg */
+ "andq $~15,%rdx\n\t" /* stack */
+ "movq %rdx,%rsp\n\t"
+ "xorq %rbp,%rbp\n\t"
+ "callq *%rax\n\t" /* call func */
+ "movq %rbx,%rsp\n\t"
+ "popq %rbx\n\t"
+ "popq %rbp\n\t"
+ "ret")
+#else
#error You must implement wine_switch_to_stack for your platform
#endif
diff --git a/libs/wine/wine.def b/libs/wine/wine.def
index 462a619..6304113 100644
--- a/libs/wine/wine.def
+++ b/libs/wine/wine.def
@@ -50,6 +50,7 @@ EXPORTS
vsnprintfW
vsprintfW
wine_anon_mmap
+ wine_call_on_stack
wine_casemap_lower
wine_casemap_upper
wine_compare_string
@@ -65,7 +66,7 @@ EXPORTS
wine_dbgstr_an
wine_dbgstr_wn
wine_dlclose
- wine_dll_enum_load_path;
+ wine_dll_enum_load_path
wine_dll_get_owner
wine_dll_load
wine_dll_load_main_exe
diff --git a/libs/wine/wine.map b/libs/wine/wine.map
index 47e58ce..ef8d823 100644
--- a/libs/wine/wine.map
+++ b/libs/wine/wine.map
@@ -50,6 +50,7 @@ WINE_1.0
vsnprintfW;
vsprintfW;
wine_anon_mmap;
+ wine_call_on_stack;
wine_casemap_lower;
wine_casemap_upper;
wine_compare_string;
More information about the wine-cvs
mailing list