Phil Krylov <phil@newstar.rinet.ru>
- Fixed winebuild operation in Darwin.
Steve Zellers <zellers@mac.com>
- Fixed leftover import table name in output_import_thunk.
Alexandre Julliard <julliard@winehq.org>
- Replace configure macros by explicit platform checks (probably not
  correct on all platforms yet).
- Moved most of the implementation of CALL32_CBClient(Ex) to the C
  code.
- Don't use the full 32 bits of %esp when called from 16-bit code.
- Added a --target option to allow cross-compilation.
- Improve a bit the assembly generated for import thunks.
- Don't depend on ELF features for PIC code.
- A couple of optimizations.
- Intercept functions for 16-bit relay debugging by patching the
  CALLFROM16 table instead of having the wine_call_from_16 functions
  call out the relay functions explicitly.
- Added vararg argument type so that the relay code can distinguish from
  a normal cdecl function.
- Don't rely on the relay thunk preserving the stack pointer.
- Moved all 16-bit relay code to the text section.
- Changed a few symbol names for better consistency.
- Get rid of the global debugging flag.
Mike McCormack <mike@codeweavers.com>
- gcc 4.0 -Wpointer-sign fixes.
Marcus Meissner <marcus@jet.franken.de>
- Fixed signedness warnings.
Modified: trunk/reactos/tools/winebuild/build.h
Modified: trunk/reactos/tools/winebuild/import.c
Modified: trunk/reactos/tools/winebuild/main.c
Modified: trunk/reactos/tools/winebuild/relay.c
Modified: trunk/reactos/tools/winebuild/spec16.c
Modified: trunk/reactos/tools/winebuild/spec32.c
Modified: trunk/reactos/tools/winebuild/utils.c
Modified: trunk/reactos/tools/winebuild/winebuild.man.in

Modified: trunk/reactos/tools/winebuild/build.h
--- trunk/reactos/tools/winebuild/build.h	2005-08-10 21:09:05 UTC (rev 17270)
+++ trunk/reactos/tools/winebuild/build.h	2005-08-10 22:15:12 UTC (rev 17271)
@@ -184,6 +184,8 @@
 extern const char *asm_name( const char *func );
 extern const char *func_declaration( const char *func );
 extern const char *func_size( const char *func );
+extern const char *get_asm_string_keyword(void);
+extern const char *get_asm_short_keyword(void);
 
 extern void add_import_dll( const char *name, const char *filename );
 extern void add_delayed_import( const char *name );
@@ -220,7 +222,6 @@
 
 extern int current_line;
 extern int UsePIC;
-extern int debugging;
 extern int nb_debug_channels;
 extern int nb_lib_paths;
 extern int nb_errors;

Modified: trunk/reactos/tools/winebuild/import.c
--- trunk/reactos/tools/winebuild/import.c	2005-08-10 21:09:05 UTC (rev 17270)
+++ trunk/reactos/tools/winebuild/import.c	2005-08-10 22:15:12 UTC (rev 17271)
@@ -586,6 +586,7 @@
     close( fd );
     atexit( remove_ld_tmp_file );
 
+    if (!ld_command) ld_command = xstrdup("ld");
     for (i = 0; argv[i]; i++) len += strlen(argv[i]) + 1;
     cmd = xmalloc( len + strlen(ld_tmp_file) + 8 + strlen(ld_command)  );
     sprintf( cmd, "%s -r -o %s", ld_command, ld_tmp_file );
@@ -616,6 +617,7 @@
     if (argv[1]) name = ldcombine_files( argv );
     else name = argv[0];
 
+    if (!nm_command) nm_command = xstrdup("nm");
     cmd = xmalloc( strlen(nm_command) + strlen(name) + 5 );
     sprintf( cmd, "%s -u %s", nm_command, name );
     if (!(f = popen( cmd, "r" )))
@@ -692,7 +694,7 @@
 /* output a single import thunk */
 static void output_import_thunk( FILE *outfile, const char *name, const char *table, int pos )
 {
-    fprintf( outfile, "    \"\\t.align %d\\n\"\n", get_alignment(8) );
+    fprintf( outfile, "    \"\\t.align %d\\n\"\n", get_alignment(4) );
     fprintf( outfile, "    \"\\t%s\\n\"\n", func_declaration(name) );
     fprintf( outfile, "    \"\\t.globl %s\\n\"\n", asm_name(name) );
     fprintf( outfile, "    \"%s:\\n\"\n", asm_name(name) );
@@ -703,38 +705,50 @@
         if (!UsePIC)
         {
             if (strstr( name, "__wine_call_from_16" )) fprintf( outfile, "    \"\\t.byte 0x2e\\n\"\n" );
-            fprintf( outfile, "    \"\\tjmp *(imports+%d)\\n\"\n", pos );
+            fprintf( outfile, "    \"\\tjmp *(%s+%d)\\n\"\n", asm_name(table), pos );
         }
         else
         {
-            if (!strcmp( name, "__wine_call_from_32_regs" ) ||
-                !strcmp( name, "__wine_call_from_16_regs" ))
+            if (!strcmp( name, "__wine_call_from_32_regs" ))
             {
                 /* special case: need to preserve all registers */
                 fprintf( outfile, "    \"\\tpushl %%eax\\n\"\n" );
-                fprintf( outfile, "    \"\\tpushfl\\n\"\n" );
                 fprintf( outfile, "    \"\\tcall .L__wine_spec_%s\\n\"\n", name );
                 fprintf( outfile, "    \".L__wine_spec_%s:\\n\"\n", name );
                 fprintf( outfile, "    \"\\tpopl %%eax\\n\"\n" );
-                fprintf( outfile, "    \"\\taddl $%d+%s-.L__wine_spec_%s,%%eax\\n\"\n",
-                         pos, asm_name(table), name );
                 if (!strcmp( name, "__wine_call_from_16_regs" ))
                     fprintf( outfile, "    \"\\t.byte 0x2e\\n\"\n" );
-                fprintf( outfile, "    \"\\tmovl 0(%%eax),%%eax\\n\"\n" );
-                fprintf( outfile, "    \"\\txchgl 4(%%esp),%%eax\\n\"\n" );
-                fprintf( outfile, "    \"\\tpopfl\\n\"\n" );
+                fprintf( outfile, "    \"\\tmovl %s+%d-.L__wine_spec_%s(%%eax),%%eax\\n\"\n",
+                         asm_name(table), pos, name );
+                fprintf( outfile, "    \"\\txchgl %%eax,(%%esp)\\n\"\n" );
                 fprintf( outfile, "    \"\\tret\\n\"\n" );
             }
+            else if (!strcmp( name, "__wine_call_from_16_regs" ))
+            {
+                /* special case: need to preserve all registers */
+                fprintf( outfile, "    \"\\tpushl %%eax\\n\"\n" );
+                fprintf( outfile, "    \"\\tpushl %%ecx\\n\"\n" );
+                fprintf( outfile, "    \"\\tcall .L__wine_spec_%s\\n\"\n", name );
+                fprintf( outfile, "    \".L__wine_spec_%s:\\n\"\n", name );
+                fprintf( outfile, "    \"\\tpopl %%eax\\n\"\n" );
+                fprintf( outfile, "    \"\\t.byte 0x2e\\n\"\n" );
+                fprintf( outfile, "    \"\\tmovl %s+%d-.L__wine_spec_%s(%%eax),%%eax\\n\"\n",
+                         asm_name(table), pos, name );
+                fprintf( outfile, "    \"\\tmovzwl %%sp, %%ecx\\n\"\n" );
+                fprintf( outfile, "    \"\\t.byte 0x36\\n\"\n" );
+                fprintf( outfile, "    \"\\txchgl %%eax,4(%%ecx)\\n\"\n" );
+                fprintf( outfile, "    \"\\tpopl %%ecx\\n\"\n" );
+                fprintf( outfile, "    \"\\tret\\n\"\n" );
+            }
             else
             {
                 fprintf( outfile, "    \"\\tcall .L__wine_spec_%s\\n\"\n", name );
                 fprintf( outfile, "    \".L__wine_spec_%s:\\n\"\n", name );
                 fprintf( outfile, "    \"\\tpopl %%eax\\n\"\n" );
-                fprintf( outfile, "    \"\\taddl $%d+%s-.L__wine_spec_%s,%%eax\\n\"\n",
-                         pos, asm_name(table), name );
                 if (strstr( name, "__wine_call_from_16" ))
                     fprintf( outfile, "    \"\\t.byte 0x2e\\n\"\n" );
-                fprintf( outfile, "    \"\\tjmp *0(%%eax)\\n\"\n" );
+                fprintf( outfile, "    \"\\tjmp *%s+%d-.L__wine_spec_%s(%%eax)\\n\"\n",
+                         asm_name(table), pos, name );
             }
         }
         break;

Modified: trunk/reactos/tools/winebuild/main.c
--- trunk/reactos/tools/winebuild/main.c	2005-08-10 21:09:05 UTC (rev 17270)
+++ trunk/reactos/tools/winebuild/main.c	2005-08-10 22:15:12 UTC (rev 17271)
@@ -44,7 +44,6 @@
 int nb_errors = 0;
 int display_warnings = 0;
 int kill_at = 0;
-int debugging = 0;
 
 #if defined(__i386__) || defined(__x86_64__)
 enum target_cpu target_cpu = CPU_x86;
@@ -75,8 +74,8 @@
 char *spec_file_name = NULL;
 const char *output_file_name = NULL;
 
-char *ld_command = "ld";
-char *nm_command = "nm";
+char *ld_command = NULL;
+char *nm_command = NULL;
 
 static FILE *output_file;
 static const char *current_src_dir;
@@ -98,6 +97,35 @@
 
 static enum exec_mode_values exec_mode = MODE_NONE;
 
+static const struct
+{
+    const char *name;
+    enum target_cpu cpu;
+} cpu_names[] =
+{
+    { "i386",    CPU_x86 },
+    { "i486",    CPU_x86 },
+    { "i586",    CPU_x86 },
+    { "i686",    CPU_x86 },
+    { "i786",    CPU_x86 },
+    { "sparc",   CPU_SPARC },
+    { "alpha",   CPU_ALPHA },
+    { "powerpc", CPU_POWERPC }
+};
+
+static const struct
+{
+    const char *name;
+    enum target_platform platform;
+} platform_names[] =
+{
+    { "macos",   PLATFORM_APPLE },
+    { "darwin",  PLATFORM_APPLE },
+    { "sunos",   PLATFORM_SVR4 },
+    { "windows", PLATFORM_WINDOWS },
+    { "winnt",   PLATFORM_WINDOWS }
+};
+
 /* set the dll file name from the input file name */
 static void set_dll_file_name( const char *name, DLLSPEC *spec )
 {
@@ -137,6 +165,56 @@
     free( str );
 }
 
+/* set the target CPU and platform */
+static void set_target( const char *target )
+{
+    unsigned int i;
+    char *p, *platform, *spec = xstrdup( target );
+
+    /* target specification is in the form CPU-MANUFACTURER-OS or CPU-MANUFACTURER-KERNEL-OS */
+
+    /* get the CPU part */
+
+    if (!(p = strchr( spec, '-' ))) fatal_error( "Invalid target specification '%s'\n", target );
+    *p++ = 0;
+    for (i = 0; i < sizeof(cpu_names)/sizeof(cpu_names[0]); i++)
+    {
+        if (!strcmp( cpu_names[i].name, spec )) break;
+    }
+    if (i < sizeof(cpu_names)/sizeof(cpu_names[0])) target_cpu = cpu_names[i].cpu;
+    else fatal_error( "Unrecognized CPU '%s'\n", spec );
+
+    platform = p;
+    if ((p = strrchr( p, '-' ))) platform = p + 1;
+
+    /* get the OS part */
+
+    target_platform = PLATFORM_UNSPECIFIED;  /* default value */
+    for (i = 0; i < sizeof(platform_names)/sizeof(platform_names[0]); i++)
+    {
+        if (!strncmp( platform_names[i].name, platform, strlen(platform_names[i].name) ))
+        {
+            target_platform = platform_names[i].platform;
+            break;
+        }
+    }
+
+    free( spec );
+
+    if (!ld_command)
+    {
+        ld_command = xmalloc( strlen(target) + sizeof("-ld") );
+        strcpy( ld_command, target );
+        strcat( ld_command, "-ld" );
+    }
+    if (!nm_command)
+    {
+        nm_command = xmalloc( strlen(target) + sizeof("-nm") );
+        strcpy( nm_command, target );
+        strcat( nm_command, "-nm" );
+    }
+}
+
 /* cleanup on program exit */
 static void cleanup(void)
 {
@@ -177,6 +255,7 @@
 "    -o --output=NAME        Set the output file name (default: stdout)\n"
 "    -r --res=RSRC.RES       Load resources from RSRC.RES\n"
 "       --subsystem=SUBSYS   Set the subsystem (one of native, windows, console)\n"
+"       --target=TARGET      Specify target CPU and platform for cross-compiling\n"
 "       --version            Print the version and exit\n"
 "    -w --warnings           Turn on warnings\n"
 "\nMode options:\n"
@@ -201,6 +280,7 @@
     LONG_OPT_RELAY32,
     LONG_OPT_SUBSYSTEM,
     LONG_OPT_VERSION,
+    LONG_OPT_TARGET,
     LONG_OPT_PEDLL
 };
 
@@ -217,6 +297,7 @@
     { "relay16",  0, 0, LONG_OPT_RELAY16 },
     { "relay32",  0, 0, LONG_OPT_RELAY32 },
     { "subsystem",1, 0, LONG_OPT_SUBSYSTEM },
+    { "target",   1, 0, LONG_OPT_TARGET },
     { "version",  0, 0, LONG_OPT_VERSION },
     { "pedll",    1, 0, LONG_OPT_PEDLL },
     /* aliases for short options */
@@ -373,6 +454,9 @@
         case LONG_OPT_SUBSYSTEM:
             set_subsystem( optarg, spec );
             break;
+        case LONG_OPT_TARGET:
+            set_target( optarg );
+            break;
         case LONG_OPT_VERSION:
             printf( "winebuild version " PACKAGE_VERSION "\n" );
             exit(0);
@@ -470,9 +554,6 @@
     output_file = stdout;
     argv = parse_options( argc, argv, spec );
 
-    /* we only support relay debugging on i386 */
-    debugging = (target_cpu == CPU_x86);
-
     switch(exec_mode)
     {
     case MODE_DLL:

Modified: trunk/reactos/tools/winebuild/relay.c
--- trunk/reactos/tools/winebuild/relay.c	2005-08-10 21:09:05 UTC (rev 17270)
+++ trunk/reactos/tools/winebuild/relay.c	2005-08-10 22:15:12 UTC (rev 17271)
@@ -138,22 +138,16 @@
     fprintf( outfile, "\tpushl %%edx\n" );
 
     /* Save original EFlags register */
-    fprintf( outfile, "\tpushfl\n" );
+    if (reg_func) fprintf( outfile, "\tpushfl\n" );
 
     if ( UsePIC )
     {
-        /* Get Global Offset Table into %ecx */
-        fprintf( outfile, "\tcall .L__wine_call_from_16_%s.getgot1\n", name );
-        fprintf( outfile, ".L__wine_call_from_16_%s.getgot1:\n", name );
+        fprintf( outfile, "\tcall .Lcall_from_16_%s.getpc\n", name );
+        fprintf( outfile, ".Lcall_from_16_%s.getpc:\n", name );
         fprintf( outfile, "\tpopl %%ecx\n" );
-        fprintf( outfile, "\taddl $_GLOBAL_OFFSET_TABLE_+[.-.L__wine_call_from_16_%s.getgot1], %%ecx\n", name );
+        fprintf( outfile, "\t.byte 0x2e\n\tmovl %s-.Lcall_from_16_%s.getpc(%%ecx),%%edx\n",
+                 asm_name("CallTo16_DataSelector"), name );
     }
-
-    if (UsePIC)
-    {
-        fprintf( outfile, "\t.byte 0x2e\n\tmovl %s(%%ecx), %%edx\n", asm_name("CallTo16_DataSelector@GOT") );
-        fprintf( outfile, "\t.byte 0x2e\n\tmovl (%%edx), %%edx\n" );
-    }
     else
         fprintf( outfile, "\t.byte 0x2e\n\tmovl %s,%%edx\n", asm_name("CallTo16_DataSelector") );
 
@@ -162,31 +156,29 @@
     fprintf( outfile, "%s\tmovw %%dx, %%es\n", data16_prefix() );
 
     if ( UsePIC )
-    {
-        fprintf( outfile, "\tmovl %s(%%ecx), %%edx\n", asm_name("CallTo16_TebSelector@GOT") );
-        fprintf( outfile, "\tmovw (%%edx), %%fs\n" );
-    }
+        fprintf( outfile, "\tmovw %s-.Lcall_from_16_%s.getpc(%%ecx), %%fs\n",
+                 asm_name("CallTo16_TebSelector"), name );
     else
         fprintf( outfile, "\tmovw %s, %%fs\n", asm_name("CallTo16_TebSelector") );
 
     fprintf( outfile, "\t.byte 0x64\n\tmov (%d),%%gs\n", STRUCTOFFSET(TEB,gs_sel) );
 
-    /* Get address of wine_ldt_copy array into %ecx */
-    if ( UsePIC )
-        fprintf( outfile, "\tmovl %s(%%ecx), %%ecx\n", asm_name("wine_ldt_copy@GOT") );
-    else
-        fprintf( outfile, "\tmovl $%s, %%ecx\n", asm_name("wine_ldt_copy") );
-
     /* Translate STACK16FRAME base to flat offset in %edx */
     fprintf( outfile, "\tmovw %%ss, %%dx\n" );
     fprintf( outfile, "\tandl $0xfff8, %%edx\n" );
     fprintf( outfile, "\tshrl $1, %%edx\n" );
-    fprintf( outfile, "\tmovl (%%ecx,%%edx), %%edx\n" );
+    if (UsePIC)
+    {
+        fprintf( outfile, "\taddl wine_ldt_copy_ptr-.Lcall_from_16_%s.getpc(%%ecx),%%edx\n", name );
+        fprintf( outfile, "\tmovl (%%edx), %%edx\n" );
+    }
+    else
+        fprintf( outfile, "\tmovl %s(%%edx), %%edx\n", asm_name("wine_ldt_copy") );
     fprintf( outfile, "\tmovzwl %%sp, %%ebp\n" );
-    fprintf( outfile, "\tleal (%%ebp,%%edx), %%edx\n" );
+    fprintf( outfile, "\tleal %d(%%ebp,%%edx), %%edx\n", reg_func ? 0 : -4 );
 
     /* Get saved flags into %ecx */
-    fprintf( outfile, "\tpopl %%ecx\n" );
+    if (reg_func) fprintf( outfile, "\tpopl %%ecx\n" );
 
     /* Get the 32-bit stack pointer from the TEB and complete STACK16FRAME */
     fprintf( outfile, "\t.byte 0x64\n\tmovl (%d), %%ebp\n", STACKOFFSET );
@@ -292,83 +284,16 @@
         fprintf( outfile, "\tpushl %%esp\n" );
     }
 
-
-    /* Print debug info before call */
-    if ( debugging )
-    {
-        if ( UsePIC )
-        {
-            fprintf( outfile, "\tpushl %%ebx\n" );
-
-            /* Get Global Offset Table into %ebx (for PLT call) */
-            fprintf( outfile, "\tcall .L__wine_call_from_16_%s.getgot2\n", name );
-            fprintf( outfile, ".L__wine_call_from_16_%s.getgot2:\n", name );
-            fprintf( outfile, "\tpopl %%ebx\n" );
-            fprintf( outfile, "\taddl $_GLOBAL_OFFSET_TABLE_+[.-.L__wine_call_from_16_%s.getgot2], %%ebx\n", name );
-        }
-
-        fprintf( outfile, "\tpushl %%edx\n" );
-        if ( reg_func )
-            fprintf( outfile, "\tleal -%d(%%ebp), %%eax\n\tpushl %%eax\n",
-                              sizeof(CONTEXT) + STRUCTOFFSET(STACK32FRAME, ebp) );
-        else
-            fprintf( outfile, "\tpushl $0\n" );
-
-        if ( UsePIC )
-            fprintf( outfile, "\tcall %s\n ", asm_name("RELAY_DebugCallFrom16@PLT"));
-        else
-            fprintf( outfile, "\tcall %s\n ", asm_name("RELAY_DebugCallFrom16"));
-
-        fprintf( outfile, "\tpopl %%edx\n" );
-        fprintf( outfile, "\tpopl %%edx\n" );
-
-        if ( UsePIC )
-            fprintf( outfile, "\tpopl %%ebx\n" );
-    }
-
     /* Call relay routine (which will call the API entry point) */
     fprintf( outfile, "\tleal %d(%%edx), %%eax\n", sizeof(STACK16FRAME) );
     fprintf( outfile, "\tpushl %%eax\n" );
     fprintf( outfile, "\tpushl %d(%%edx)\n", STACK16OFFSET(entry_point) );
     fprintf( outfile, "\tcall *%d(%%edx)\n", STACK16OFFSET(relay) );
 
-    /* Print debug info after call */
-    if ( debugging )
-    {
-        if ( UsePIC )
-        {
-            fprintf( outfile, "\tpushl %%ebx\n" );
-
-            /* Get Global Offset Table into %ebx (for PLT call) */
-            fprintf( outfile, "\tcall .L__wine_call_from_16_%s.getgot3\n", name );
-            fprintf( outfile, ".L__wine_call_from_16_%s.getgot3:\n", name );
-            fprintf( outfile, "\tpopl %%ebx\n" );
-            fprintf( outfile, "\taddl $_GLOBAL_OFFSET_TABLE_+[.-.L__wine_call_from_16_%s.getgot3], %%ebx\n", name );
-        }
-
-        fprintf( outfile, "\tpushl %%eax\n" );
-        if ( reg_func )
-            fprintf( outfile, "\tleal -%d(%%ebp), %%eax\n\tpushl %%eax\n",
-                              sizeof(CONTEXT) + STRUCTOFFSET(STACK32FRAME, ebp) );
-        else
-            fprintf( outfile, "\tpushl $0\n" );
-
-        if ( UsePIC )
-            fprintf( outfile, "\tcall %s\n ", asm_name("RELAY_DebugCallFrom16Ret@PLT"));
-        else
-            fprintf( outfile, "\tcall %s\n ", asm_name("RELAY_DebugCallFrom16Ret"));
-
-        fprintf( outfile, "\tpopl %%eax\n" );
-        fprintf( outfile, "\tpopl %%eax\n" );
-
-        if ( UsePIC )
-            fprintf( outfile, "\tpopl %%ebx\n" );
-    }
-
-
     if ( reg_func )
     {
-        fprintf( outfile, "\tmovl %%esp, %%ebx\n" );
+        fprintf( outfile, "\tleal -%d(%%ebp), %%ebx\n",
+                 sizeof(CONTEXT) + STRUCTOFFSET(STACK32FRAME, ebp) );
 
         /* Switch stack back */
         fprintf( outfile, "\t.byte 0x64\n\tmovw (%d), %%ss\n", STACKOFFSET+2 );
@@ -610,7 +535,7 @@
  */
 static void BuildRet16Func( FILE *outfile )
 {
-    function_header( outfile, "CallTo16_Ret" );
+    function_header( outfile, "__wine_call_to_16_ret" );
 
     /* Save %esp into %esi */
     fprintf( outfile, "\tmovl %%esp,%%esi\n" );
@@ -618,12 +543,12 @@
     /* Restore 32-bit segment registers */
 
     fprintf( outfile, "\t.byte 0x2e\n\tmovl %s", asm_name("CallTo16_DataSelector") );
-    fprintf( outfile, "-%s,%%edi\n", asm_name("Call16_Ret_Start") );
+    fprintf( outfile, "-%s,%%edi\n", asm_name("__wine_call16_start") );
     fprintf( outfile, "%s\tmovw %%di,%%ds\n", data16_prefix() );
     fprintf( outfile, "%s\tmovw %%di,%%es\n", data16_prefix() );
 
     fprintf( outfile, "\t.byte 0x2e\n\tmov %s", asm_name("CallTo16_TebSelector") );
-    fprintf( outfile, "-%s,%%fs\n", asm_name("Call16_Ret_Start") );
+    fprintf( outfile, "-%s,%%fs\n", asm_name("__wine_call16_start") );
 
     fprintf( outfile, "\t.byte 0x64\n\tmov (%d),%%gs\n", STRUCTOFFSET(TEB,gs_sel) );
 
@@ -635,17 +560,7 @@
     /* Return to caller */
 
     fprintf( outfile, "\tlret\n" );
-
-    /* Function footer */
-    function_footer( outfile, "CallTo16_Ret" );
-
-    /* Declare the return address and data selector variables */
-
-    fprintf( outfile, "\n\t.align %d\n", get_alignment(4) );
-    fprintf( outfile, "\t.globl %s\n", asm_name("CallTo16_DataSelector") );
-    fprintf( outfile, "%s:\t.long 0\n", asm_name("CallTo16_DataSelector") );
-    fprintf( outfile, "\t.globl %s\n", asm_name("CallTo16_TebSelector") );
-    fprintf( outfile, "%s:\t.long 0\n", asm_name("CallTo16_TebSelector") );
+    function_footer( outfile, "__wine_call_to_16_ret" );
 }
 
 
@@ -741,15 +656,8 @@
  */
 static void BuildCallTo32CBClient( FILE *outfile, BOOL isEx )
 {
-    const char *name = isEx? "CALL32_CBClientEx" : "CALL32_CBClient";
-    int size = isEx? 24 : 12;
+    function_header( outfile, isEx ? "CALL32_CBClientEx" : "CALL32_CBClient" );
 
-    /* Function header */
-
-    fprintf( outfile, "\n\t.align %d\n", get_alignment(4) );
-    fprintf( outfile, "\t.globl %s\n", asm_name(name) );
-    fprintf( outfile, "%s:\n", asm_name(name) );
-
     /* Entry code */
 
     fprintf( outfile, "\tpushl %%ebp\n" );
@@ -758,106 +666,21 @@
     fprintf( outfile, "\tpushl %%esi\n" );
     fprintf( outfile, "\tpushl %%ebx\n" );
 
-    if (UsePIC)
-    {
-        /* Get Global Offset Table into %edx */
-        fprintf( outfile, "\tcall .L__wine_%s.getgot1\n", name );
-        fprintf( outfile, ".L__wine_%s.getgot1:\n", name );
-        fprintf( outfile, "\tpopl %%edx\n" );
-        fprintf( outfile, "\taddl $_GLOBAL_OFFSET_TABLE_+[.-.L__wine_%s.getgot1], %%edx\n", name );
-    }
+    /* Get pointer to temporary area and save the 32-bit stack pointer */
 
-    /* Get the 16-bit stack */
+    fprintf( outfile, "\tmovl 16(%%ebp), %%ebx\n" );
+    fprintf( outfile, "\tleal -8(%%esp), %%eax\n" );
 
-    fprintf( outfile, "\t.byte 0x64\n\tmovl (%d),%%ebx\n", STACKOFFSET);
-
-    /* Convert it to a flat address */
-
-    fprintf( outfile, "\tshldl $16,%%ebx,%%eax\n" );
-    fprintf( outfile, "\tandl $0xfff8,%%eax\n" );
-    fprintf( outfile, "\tshrl $1,%%eax\n" );
-    if (!UsePIC)
-        fprintf( outfile, "\tmovl %s(%%eax),%%esi\n", asm_name("wine_ldt_copy") );
-    else
-    {
-        fprintf( outfile, "\tmovl %s(%%edx), %%esi\n", asm_name("wine_ldt_copy@GOT") );
-        fprintf( outfile, "\tmovl (%%esi,%%eax), %%esi\n" );
-    }
-    fprintf( outfile, "\tmovw %%bx,%%ax\n" );
-    fprintf( outfile, "\taddl %%eax,%%esi\n" );
-
-    /* Allocate temporary area (simulate STACK16_PUSH) */
-
-    fprintf( outfile, "\tpushf\n" );
-    fprintf( outfile, "\tcld\n" );
-    fprintf( outfile, "\tleal -%d(%%esi), %%edi\n", size );
-    fprintf( outfile, "\tmovl $%d, %%ecx\n", sizeof(STACK16FRAME) );
-    fprintf( outfile, "\trep\n\tmovsb\n" );
-    fprintf( outfile, "\tpopf\n" );
-
-    fprintf( outfile, "\t.byte 0x64\n\tsubw $%d,(%d)\n", size, STACKOFFSET );
-
-    fprintf( outfile, "\tpushl %%edi\n" );  /* remember address */
-
-    /* Set up temporary area */
-
     if ( !isEx )
-    {
-        fprintf( outfile, "\tleal 4(%%edi), %%edi\n" );
-
-        fprintf( outfile, "\tleal -8(%%esp), %%eax\n" );
-        fprintf( outfile, "\tmovl %%eax, -8(%%edi)\n" );    /* 32-bit sp */
-
-        fprintf( outfile, "\tmovw %%ss, %%ax\n" );
-        fprintf( outfile, "\tandl $0x0000ffff, %%eax\n" );
-        fprintf( outfile, "\tmovl %%eax, -4(%%edi)\n" );    /* 32-bit ss */
-
-        fprintf( outfile, "\taddl $%d, %%ebx\n", sizeof(STACK16FRAME)-size+4 + 4 );
-        fprintf( outfile, "\tmovl %%ebx, 0(%%edi)\n" );    /* 16-bit ss:sp */
-
-        if (!UsePIC)
-            fprintf( outfile, "\tmovl %s_RetAddr, %%eax\n", asm_name(name) );
-        else
-        {
-            fprintf( outfile, "\tmovl %s_RetAddr@GOT(%%edx), %%eax\n", asm_name(name) );
-            fprintf( outfile, "\tmovl (%%eax), %%eax\n" );
-        }
-        fprintf( outfile, "\tmovl %%eax, 4(%%edi)\n" );   /* overwrite return address */
-    }
+        fprintf( outfile, "\tmovl %%eax, -8(%%ebx)\n" );
     else
-    {
-        fprintf( outfile, "\taddl $%d, %%ebx\n", sizeof(STACK16FRAME)-size+4 );
-        fprintf( outfile, "\tmovl %%ebx, 0(%%edi)\n" );
+        fprintf( outfile, "\tmovl %%eax, 12(%%ebx)\n" );
 
-        fprintf( outfile, "\tmovw %%ds, %%ax\n" );
-        fprintf( outfile, "\tmovw %%ax, 4(%%edi)\n" );
-
-        fprintf( outfile, "\taddl $20, %%ebx\n" );
-        fprintf( outfile, "\tmovw %%bx, 10(%%edi)\n" );
-
-        fprintf( outfile, "\tleal -8(%%esp), %%eax\n" );
-        fprintf( outfile, "\tmovl %%eax, 12(%%edi)\n" );
-
-        fprintf( outfile, "\tmovw %%ss, %%ax\n" );
-        fprintf( outfile, "\tandl $0x0000ffff, %%eax\n" );
-        fprintf( outfile, "\tmovl %%eax, 16(%%edi)\n" );
-
-        if (!UsePIC)
-            fprintf( outfile, "\tmovl %s_RetAddr, %%eax\n", asm_name(name) );
-        else
-        {
-            fprintf( outfile, "\tmovl %s_RetAddr@GOT(%%edx), %%eax\n", asm_name(name) );
-            fprintf( outfile, "\tmovl (%%eax), %%eax\n" );
-        }
-        fprintf( outfile, "\tmovl %%eax, 20(%%edi)\n" );
-    }
-
     /* Set up registers and call CBClient relay stub (simulating a far call) */
 
-    fprintf( outfile, "\tmovl 16(%%ebp), %%esi\n" );
+    fprintf( outfile, "\tmovl 20(%%ebp), %%esi\n" );
     fprintf( outfile, "\tmovl (%%esi), %%esi\n" );
 
-    fprintf( outfile, "\tmovl %%edi, %%ebx\n" );
     fprintf( outfile, "\tmovl 8(%%ebp), %%eax\n" );
     fprintf( outfile, "\tmovl 12(%%ebp), %%ebp\n" );
 
@@ -869,24 +692,10 @@
     fprintf( outfile, "\tmovl 32(%%esp), %%edi\n" );
     fprintf( outfile, "\tmovl %%esi, (%%edi)\n" );
 
-    /* Cleanup temporary area (simulate STACK16_POP) */
-
-    fprintf( outfile, "\tpop %%esi\n" );
-
-    fprintf( outfile, "\tpushf\n" );
-    fprintf( outfile, "\tstd\n" );
-    fprintf( outfile, "\tdec %%esi\n" );
-    fprintf( outfile, "\tleal %d(%%esi), %%edi\n", size );
-    fprintf( outfile, "\tmovl $%d, %%ecx\n", sizeof(STACK16FRAME) );
-    fprintf( outfile, "\trep\n\tmovsb\n" );
-    fprintf( outfile, "\tpopf\n" );
-
-    fprintf( outfile, "\t.byte 0x64\n\taddw $%d,(%d)\n", size, STACKOFFSET );
-
     /* Return argument size to caller */
     if ( isEx )
     {
-        fprintf( outfile, "\tmovl 32(%%esp), %%ebx\n" );
+        fprintf( outfile, "\tmovl 36(%%esp), %%ebx\n" );
         fprintf( outfile, "\tmovl %%ebp, (%%ebx)\n" );
     }
 
@@ -897,18 +706,11 @@
     fprintf( outfile, "\tpopl %%edi\n" );
     fprintf( outfile, "\tpopl %%ebp\n" );
     fprintf( outfile, "\tret\n" );
-    function_footer( outfile, name );
-}
+    function_footer( outfile, isEx ? "CALL32_CBClientEx" : "CALL32_CBClient" );
 
-static void BuildCallTo32CBClientRet( FILE *outfile, BOOL isEx )
-{
-    const char *name = isEx? "CALL32_CBClientEx_Ret" : "CALL32_CBClient_Ret";
-
     /* '16-bit' return stub */
 
-    fprintf( outfile, "\n\t.globl %s\n", asm_name(name) );
-    fprintf( outfile, "%s:\n", asm_name(name) );
-
+    function_header( outfile, isEx ? "CALL32_CBClientEx_Ret" : "CALL32_CBClient_Ret" );
     if ( !isEx )
     {
         fprintf( outfile, "\tmovzwl %%sp, %%ebx\n" );
@@ -922,12 +724,7 @@
         fprintf( outfile, "\tlssl %%ss:-12(%%ebx), %%esp\n" );
     }
     fprintf( outfile, "\tlret\n" );
-    function_footer( outfile, name );
-
-    /* Declare the return address variable */
-
-    fprintf( outfile, "\n\t.globl %sAddr\n", asm_name(name) );
-    fprintf( outfile, "%sAddr:\t.long 0\n", asm_name(name) );
+    function_footer( outfile, isEx ? "CALL32_CBClientEx_Ret" : "CALL32_CBClient_Ret" );
 }
 
 
@@ -1102,13 +899,13 @@
 
     /* Start cleanup. Restore fs register. */
 
-    fprintf( outfile, ".globl %s\n", asm_name("DPMI_PendingEventCheck_Cleanup") );
+    fprintf( outfile, "\t.globl %s\n", asm_name("DPMI_PendingEventCheck_Cleanup") );
     fprintf( outfile, "%s:\n", asm_name("DPMI_PendingEventCheck_Cleanup") );
     fprintf( outfile, "\tpopw %%fs\n" );
 
     /* Return from function. */
 
-    fprintf( outfile, ".globl %s\n", asm_name("DPMI_PendingEventCheck_Return") );
+    fprintf( outfile, "\t.globl %s\n", asm_name("DPMI_PendingEventCheck_Return") );
     fprintf( outfile, "%s:\n", asm_name("DPMI_PendingEventCheck_Return") );
     fprintf( outfile, "\tiret\n" );
 
@@ -1136,9 +933,8 @@
 
     fprintf( outfile, "%s:\n\n", asm_name("__wine_spec_thunk_text_16") );
 
-    fprintf( outfile, "\t.globl %s\n", asm_name("Call16_Start") );
-    fprintf( outfile, "%s:\n", asm_name("Call16_Start") );
-    fprintf( outfile, "\t.byte 0\n\n" );
+    fprintf( outfile, "\t.globl %s\n", asm_name("__wine_call16_start") );
+    fprintf( outfile, "%s:\n", asm_name("__wine_call16_start") );
 
     /* Standard CallFrom16 routine (WORD return) */
     BuildCallFrom16Core( outfile, FALSE, FALSE, TRUE );
@@ -1158,38 +954,29 @@
     /* Register CallTo16 routine */
     BuildCallTo16Core( outfile, 1 );
 
+    /* Standard CallTo16 return stub */
+    BuildRet16Func( outfile );
+
     /* CBClientThunkSL routine */
     BuildCallTo32CBClient( outfile, FALSE );
 
     /* CBClientThunkSLEx routine */
     BuildCallTo32CBClient( outfile, TRUE  );
 
-    fprintf( outfile, "\t.globl %s\n", asm_name("Call16_End") );
-    fprintf( outfile, "%s:\n", asm_name("Call16_End") );
-    function_footer( outfile, "__wine_spec_thunk_text_16" );
-
-    /* The whole Call16_Ret segment must lie within the .data section */
-    fprintf( outfile, "\n\t.data\n" );
-    fprintf( outfile, "%s:\n\n", asm_name("__wine_spec_thunk_data_16") );
-    fprintf( outfile, "\t.globl %s\n", asm_name("Call16_Ret_Start") );
-    fprintf( outfile, "%s:\n", asm_name("Call16_Ret_Start") );
-
-    /* Standard CallTo16 return stub */
-    BuildRet16Func( outfile );
-
-    /* CBClientThunkSL return stub */
-    BuildCallTo32CBClientRet( outfile, FALSE );
-
-    /* CBClientThunkSLEx return stub */
-    BuildCallTo32CBClientRet( outfile, TRUE  );
-
     /* Pending DPMI events check stub */
     BuildPendingEventCheck( outfile );
 
-    /* End of Call16_Ret segment */
-    fprintf( outfile, "\n\t.globl %s\n", asm_name("Call16_Ret_End") );
-    fprintf( outfile, "%s:\n", asm_name("Call16_Ret_End") );
-    function_footer( outfile, "__wine_spec_thunk_data_16" );
+    fprintf( outfile, "\t.globl %s\n", asm_name("__wine_call16_end") );
+    fprintf( outfile, "%s:\n", asm_name("__wine_call16_end") );
+    function_footer( outfile, "__wine_spec_thunk_text_16" );
+
+    /* Declare the return address and data selector variables */
+    fprintf( outfile, "\n\t.data\n\t.align %d\n", get_alignment(4) );
+    fprintf( outfile, "\t.globl %s\n", asm_name("CallTo16_DataSelector") );
+    fprintf( outfile, "%s:\t.long 0\n", asm_name("CallTo16_DataSelector") );
+    fprintf( outfile, "\t.globl %s\n", asm_name("CallTo16_TebSelector") );
+    fprintf( outfile, "%s:\t.long 0\n", asm_name("CallTo16_TebSelector") );
+    if (UsePIC) fprintf( outfile, "wine_ldt_copy_ptr:\t.long %s\n", asm_name("wine_ldt_copy") );
 }
 
 /*******************************************************************

Modified: trunk/reactos/tools/winebuild/spec16.c
--- trunk/reactos/tools/winebuild/spec16.c	2005-08-10 21:09:05 UTC (rev 17270)
+++ trunk/reactos/tools/winebuild/spec16.c	2005-08-10 22:15:12 UTC (rev 17271)
@@ -253,7 +253,7 @@
         fprintf( outfile, "void" );
     fprintf( outfile, " );\n" );
 
-    fprintf( outfile, "static %s __stdcall __wine_%s_CallFrom16_%s( proc_%s_t proc, unsigned char *args%s )\n",
+    fprintf( outfile, "static %s __wine_%s_CallFrom16_%s( proc_%s_t proc, unsigned char *args%s )\n",
              ret_type, make_c_identifier(prefix), profile, profile,
              reg_func? ", void *context" : "" );
 
@@ -397,7 +397,7 @@
     ORDDEF **type, **typelist;
     int i, nFuncs, nTypes;
     unsigned char *resdir_buffer, *resdata_buffer, *et_buffer, *data_buffer;
-    unsigned char string[256];
+    char string[256];
     unsigned int ne_offset, segtable_offset, impnames_offset;
     unsigned int entrypoint_size, callfrom_size;
     unsigned int code_size, code_offset;
@@ -780,6 +780,7 @@
             }
             arg_types[j / 10] |= type << (3 * (j % 10));
         }
+        if (typelist[i]->type == TYPE_VARARGS) arg_types[j / 10] |= ARG_VARARG << (3 * (j % 10));
         if (typelist[i]->flags & FLAG_REGISTER) arg_types[0] |= ARG_REGISTER;
         if (typelist[i]->flags & FLAG_RET16) arg_types[0] |= ARG_RET16;
 

Modified: trunk/reactos/tools/winebuild/spec32.c
--- trunk/reactos/tools/winebuild/spec32.c	2005-08-10 21:09:05 UTC (rev 17270)
+++ trunk/reactos/tools/winebuild/spec32.c	2005-08-10 22:15:12 UTC (rev 17271)
@@ -267,12 +267,12 @@
         fprintf( outfile, "    \"__wine_spec_exp_ordinals:\\n\"\n" );
         for (i = 0; i < spec->nb_names; i++)
         {
-            fprintf( outfile, "    \"\\t" __ASM_SHORT " %d\\n\"\n",
-                     spec->names[i]->ordinal - spec->base );
+            fprintf( outfile, "    \"\\t%s %d\\n\"\n",
+                     get_asm_short_keyword(), spec->names[i]->ordinal - spec->base );
         }
         if (spec->nb_names % 2)
         {
-            fprintf( outfile, "    \"\\t" __ASM_SHORT " 0\\n\"\n" );
+            fprintf( outfile, "    \"\\t%s 0\\n\"\n", get_asm_short_keyword() );
         }
     }
 
@@ -285,14 +285,15 @@
         {
             ORDDEF *odp = spec->ordinals[i];
             if (odp && (odp->flags & FLAG_FORWARD))
-                fprintf( outfile, "    \"\\t" __ASM_STRING " \\\"%s\\\"\\n\"\n", odp->link_name );
+                fprintf( outfile, "    \"\\t%s \\\"%s\\\"\\n\"\n", get_asm_string_keyword(), odp->link_name );
         }
         fprintf( outfile, "    \"\\t.align %d\\n\"\n", get_alignment(4) );
     }
 
     /* output relays */
 
-    if (debugging)
+    /* we only support relay debugging on i386 */
+    if (target_cpu == CPU_x86)
     {
         for (i = spec->base; i <= spec->limit; i++)
         {
@@ -325,7 +326,7 @@
             case TYPE_CDECL:
                 fprintf( outfile, "    \"\\tjmp %s\\n\"\n", asm_name(odp->link_name) );
                 fprintf( outfile, "    \"\\tret\\n\"\n" );
-                fprintf( outfile, "    \"\\t" __ASM_SHORT " %d\\n\"\n", args );
+                fprintf( outfile, "    \"\\t%s %d\\n\"\n", get_asm_short_keyword(), args );
                 fprintf( outfile, "    \"\\t.long %s,0x%08x\\n\"\n", asm_name(odp->link_name), mask );
                 break;
             default:

Modified: trunk/reactos/tools/winebuild/utils.c
--- trunk/reactos/tools/winebuild/utils.c	2005-08-10 21:09:05 UTC (rev 17270)
+++ trunk/reactos/tools/winebuild/utils.c	2005-08-10 22:15:12 UTC (rev 17271)
@@ -387,26 +387,74 @@
 const char *asm_name( const char *sym )
 {
     static char buffer[256];
-    sprintf( buffer, __ASM_NAME("%s"), sym );
-    return buffer;
+
+    switch (target_platform)
+    {
+    case PLATFORM_APPLE:
+    case PLATFORM_WINDOWS:
+        buffer[0] = '_';
+        strcpy( buffer + 1, sym );
+        return buffer;
+    default:
+        return sym;
+    }
 }
 
 /* return an assembly function declaration for a C function name */
 const char *func_declaration( const char *func )
 {
     static char buffer[256];
-    sprintf( buffer, __ASM_FUNC("%s"), func );
+
+    switch (target_platform)
+    {
+    case PLATFORM_APPLE:
+        return "";
+    case PLATFORM_WINDOWS:
+        sprintf( buffer, ".def _%s; .scl 2; .type 32; .endef", func );
+        break;
+    case PLATFORM_SVR4:
+        sprintf( buffer, ".type %s,2", func );
+        break;
+    default:
+        sprintf( buffer, ".type %s,@function", func );
+        break;
+    }
     return buffer;
 }
 
 /* return a size declaration for an assembly function */
 const char *func_size( const char *func )
 {
-#ifdef HAVE_ASM_DOT_SIZE
     static char buffer[256];
-    sprintf( buffer, ".size " __ASM_NAME("%s") ", .-" __ASM_NAME("%s"), func, func );
-    return buffer;
-#else
-    return "";
-#endif
+
+    switch (target_platform)
+    {
+    case PLATFORM_APPLE:
+    case PLATFORM_WINDOWS:
+        return "";
+    default:
+        sprintf( buffer, ".size %s, .-%s", func, func );
+        return buffer;
+    }
 }
+
+const char *get_asm_string_keyword(void)
+{
+    switch (target_platform)
+    {
+    case PLATFORM_APPLE:
+    case PLATFORM_SVR4:
+        return ".asciz";
+    default:
+        return ".string";
+    }
+}
+
+const char *get_asm_short_keyword(void)
+{
+    switch (target_platform)
+    {
+    case PLATFORM_SVR4: return ".half";
+    default:            return ".short";
+    }
+}

Modified: trunk/reactos/tools/winebuild/winebuild.man.in
--- trunk/reactos/tools/winebuild/winebuild.man.in	2005-08-10 21:09:05 UTC (rev 17270)
+++ trunk/reactos/tools/winebuild/winebuild.man.in	2005-08-10 22:15:12 UTC (rev 17271)
@@ -191,6 +191,11 @@
 Optionally a major and minor subsystem version can also be specified;
 the default subsystem version is 4.0.
 .TP
+.BI --target= cpu-manufacturer[-kernel]-os
+Specify the target CPU and platform on which the generated code will
+be built. The target specification is in the standard autoconf format
+as returned by config.sub.
+.TP
 .B \--version
 Display the program version and exit.
 .TP