Sync to Wine-0_9_3:
authorGé van Geldorp <ge@gse.nl>
Mon, 12 Dec 2005 22:24:42 +0000 (22:24 +0000)
committerGé van Geldorp <ge@gse.nl>
Mon, 12 Dec 2005 22:24:42 +0000 (22:24 +0000)
Francois Gouget <fgouget@free.fr>
- Assorted spelling fixes.
Alexandre Julliard <julliard@winehq.org>
- Enforce 16-byte stack alignment when returning from 16-bit code and
  when calling a register function.
- Preserve 16-byte stack alignment in 16-bit relays.
- Preserve 16-byte stack alignment in the various assembly
  functions. Needed for MacOSX.

svn path=/trunk/; revision=20128

reactos/tools/winebuild/relay.c
reactos/tools/winebuild/spec16.c
reactos/tools/winebuild/utils.c

index 29ccd9b..e53a839 100644 (file)
@@ -269,7 +269,16 @@ static void BuildCallFrom16Core( FILE *outfile, int reg_func, int thunk )
 #endif
 
         /* Push address of CONTEXT86 structure -- popped by the relay routine */
-        fprintf( outfile, "\tpushl %%esp\n" );
+        fprintf( outfile, "\tmovl %%esp,%%eax\n" );
+        fprintf( outfile, "\tandl $~15,%%esp\n" );
+        fprintf( outfile, "\tsubl $4,%%esp\n" );
+        fprintf( outfile, "\tpushl %%eax\n" );
+    }
+    else
+    {
+        fprintf( outfile, "\tsubl $8,%%esp\n" );
+        fprintf( outfile, "\tandl $~15,%%esp\n" );
+        fprintf( outfile, "\taddl $8,%%esp\n" );
     }
 
     /* Call relay routine (which will call the API entry point) */
@@ -725,7 +734,8 @@ static void BuildCallTo32CBClient( FILE *outfile, BOOL isEx )
  * (ebp+0)   saved ebp
  * (ebp-128) buffer area to allow stack frame manipulation
  * (ebp-332) CONTEXT86 struct
- * (ebp-336) CONTEXT86 *argument
+ * (ebp-336) padding for stack alignment
+ * (ebp-336-n) CONTEXT86 *argument
  *  ....     other arguments copied from (ebp+12)
  *
  * The entry point routine is called with a CONTEXT* extra argument,
@@ -746,7 +756,7 @@ static void BuildCallFrom32Regs( FILE *outfile )
 
     fprintf( outfile, "\tpushl %%ebp\n" );
     fprintf( outfile, "\tmovl %%esp,%%ebp\n ");
-    fprintf( outfile, "\tleal -%d(%%esp), %%esp\n", STACK_SPACE );
+    fprintf( outfile, "\tleal -%d(%%esp), %%esp\n", STACK_SPACE + 4 /* for context arg */);
 
     /* Build the context structure */
 
@@ -787,17 +797,18 @@ static void BuildCallFrom32Regs( FILE *outfile )
     /* Transfer the arguments */
 
     fprintf( outfile, "\tmovl 4(%%ebp),%%ebx\n" );   /* get relay code addr */
-    fprintf( outfile, "\tpushl %%esp\n" );           /* push ptr to context struct */
     fprintf( outfile, "\tmovzbl 4(%%ebx),%%ecx\n" ); /* fetch number of args to copy */
-    fprintf( outfile, "\tjecxz 1f\n" );
     fprintf( outfile, "\tsubl %%ecx,%%esp\n" );
+    fprintf( outfile, "\tandl $~15,%%esp\n" );
     fprintf( outfile, "\tleal 16(%%ebp),%%esi\n" );  /* get %esp at time of call */
     fprintf( outfile, "\tmovl %%esp,%%edi\n" );
     fprintf( outfile, "\tshrl $2,%%ecx\n" );
+    fprintf( outfile, "\tjz 1f\n" );
     fprintf( outfile, "\tcld\n" );
     fprintf( outfile, "\trep\n\tmovsl\n" );  /* copy args */
-
-    fprintf( outfile, "1:\tmovzbl 5(%%ebx),%%eax\n" ); /* fetch number of args to remove */
+    fprintf( outfile, "1:\tleal %d(%%ebp),%%eax\n", -STACK_SPACE );  /* get addr of context struct */
+    fprintf( outfile, "\tmovl %%eax,(%%edi)\n" );    /* and pass it as extra arg */
+    fprintf( outfile, "\tmovzbl 5(%%ebx),%%eax\n" ); /* fetch number of args to remove */
     fprintf( outfile, "\tleal 16(%%ebp,%%eax),%%eax\n" );
     fprintf( outfile, "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(Esp) - STACK_SPACE );
 
index c3bb98b..4c89f8b 100644 (file)
@@ -285,7 +285,7 @@ static int get_function_argsize( const ORDDEF *odp )
 static void output_call16_function( FILE *outfile, ORDDEF *odp )
 {
     char name[256];
-    int i, pos;
+    int i, pos, stack_words;
     const char *args = odp->u.func.arg_types;
     int argsize = get_function_argsize( odp );
     int needs_ldt = strchr( args, 'p' ) || strchr( args, 't' );
@@ -297,19 +297,25 @@ static void output_call16_function( FILE *outfile, ORDDEF *odp )
     fprintf( outfile, "%s:\n", name );
     fprintf( outfile, "\tpushl %%ebp\n" );
     fprintf( outfile, "\tmovl %%esp,%%ebp\n" );
+    stack_words = 2;
     if (needs_ldt)
     {
         fprintf( outfile, "\tpushl %%esi\n" );
+        stack_words++;
         if (UsePIC)
         {
-            fprintf( outfile, "\tcall 1f\n" );
-            fprintf( outfile, "1:\tpopl %%eax\n" );
-            fprintf( outfile, "\tmovl wine_ldt_copy_ptr-1b(%%eax),%%esi\n" );
+            fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") );
+            fprintf( outfile, "1:\tmovl wine_ldt_copy_ptr-1b(%%eax),%%esi\n" );
         }
         else
             fprintf( outfile, "\tmovl $%s,%%esi\n", asm_name("wine_ldt_copy") );
     }
 
+    /* preserve 16-byte stack alignment */
+    stack_words += strlen(args);
+    if ((odp->flags & FLAG_REGISTER) || (odp->type == TYPE_VARARGS)) stack_words++;
+    if (stack_words % 4) fprintf( outfile, "\tsubl $%d,%%esp\n", 16 - 4 * (stack_words % 4) );
+
     if (args[0] || odp->type == TYPE_VARARGS)
         fprintf( outfile, "\tmovl 12(%%ebp),%%ecx\n" );  /* args */
 
@@ -455,6 +461,7 @@ static void output_init_code( FILE *outfile, const DLLSPEC *spec, const char *he
     fprintf( outfile, "\t.align 4\n" );
     fprintf( outfile, "\t%s\n", func_declaration(name) );
     fprintf( outfile, "%s:\n", name );
+    fprintf( outfile, "subl $4,%%esp\n" );
     if (UsePIC)
     {
         fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") );
@@ -469,7 +476,7 @@ static void output_init_code( FILE *outfile, const DLLSPEC *spec, const char *he
         fprintf( outfile, "\tpushl $%s\n", header_name );
     }
     fprintf( outfile, "\tcall %s\n", asm_name("__wine_dll_register_16") );
-    fprintf( outfile, "\taddl $8,%%esp\n" );
+    fprintf( outfile, "\taddl $12,%%esp\n" );
     fprintf( outfile, "\tret\n" );
     output_function_size( outfile, name );
 
@@ -478,6 +485,7 @@ static void output_init_code( FILE *outfile, const DLLSPEC *spec, const char *he
     fprintf( outfile, "\t.align 4\n" );
     fprintf( outfile, "\t%s\n", func_declaration(name) );
     fprintf( outfile, "%s:\n", name );
+    fprintf( outfile, "subl $8,%%esp\n" );
     if (UsePIC)
     {
         fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") );
@@ -489,7 +497,7 @@ static void output_init_code( FILE *outfile, const DLLSPEC *spec, const char *he
         fprintf( outfile, "\tpushl $%s\n", header_name );
     }
     fprintf( outfile, "\tcall %s\n", asm_name("__wine_dll_unregister_16") );
-    fprintf( outfile, "\taddl $4,%%esp\n" );
+    fprintf( outfile, "\taddl $12,%%esp\n" );
     fprintf( outfile, "\tret\n" );
     output_function_size( outfile, name );
 
index dd88741..fbbfa45 100644 (file)
@@ -420,7 +420,7 @@ const char *get_stub_name( const ORDDEF *odp, const DLLSPEC *spec )
  *
  * The reason gas is written this way is that it's trying to mimick
  * native assemblers for the various architectures it runs on.  gas
- * provides other directives that work consistantly across
+ * provides other directives that work consistently across
  * architectures, but of course we want to work on all arches with or
  * without gas.  Hence this function.
  *