From: Gé van Geldorp Date: Mon, 12 Dec 2005 22:24:42 +0000 (+0000) Subject: Sync to Wine-0_9_3: X-Git-Tag: backups/expat-rbuild@40467~967 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=d6570df79698b954c1085fc638707e6b3cb08cb7 Sync to Wine-0_9_3: Francois Gouget - Assorted spelling fixes. Alexandre Julliard - 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 --- diff --git a/reactos/tools/winebuild/relay.c b/reactos/tools/winebuild/relay.c index 29ccd9b8faa..e53a8392b7d 100644 --- a/reactos/tools/winebuild/relay.c +++ b/reactos/tools/winebuild/relay.c @@ -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 ); diff --git a/reactos/tools/winebuild/spec16.c b/reactos/tools/winebuild/spec16.c index c3bb98b8b7f..4c89f8bc519 100644 --- a/reactos/tools/winebuild/spec16.c +++ b/reactos/tools/winebuild/spec16.c @@ -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 ); diff --git a/reactos/tools/winebuild/utils.c b/reactos/tools/winebuild/utils.c index dd887414cf8..fbbfa455b41 100644 --- a/reactos/tools/winebuild/utils.c +++ b/reactos/tools/winebuild/utils.c @@ -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. *