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