--- winegcc.c.orig	2011-02-03 22:57:05.000000000 +0100
+++ winegcc.c	2011-02-06 00:04:59.000000000 +0100
@@ -4,6 +4,7 @@
  * Copyright 2000 Manuel Novoa III
  * Copyright 2000 Francois Gouget
  * Copyright 2002 Dimitrie O. Paun
+ * Copyright 2011 Pali Rohár
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -137,6 +138,37 @@ static const char* app_loader_template =
     "exec \"$WINELOADER\" \"$apppath\" \"$@\"\n"
 ;
 
+#if defined (__i386__) || defined (__x86_64__)
+/* x86 assembler code that implement section _start for wine executables - shared ELF binary libraries */
+/* Data on stack: %esp ==> int argc, char * argv1, char * argv2, ... , 0, char * env1, char * env2, ..., 0 */
+/* It overwrite argc on stack with pointer to wine path string and calculate position of env1 */
+/* Then call sys_execve with wine path string, args from stack and envp from calculating position */
+static const char* start_asm_code =
+".text\n"
+".global _start\n"
+"_start:\n"
+"	movl	0(%%esp), %%edx\n"
+"	subl	$16, %%esp\n"
+"	movl	$0x7273752F, 0(%%esp)\n"
+"	movl	$0x6E69622F, 4(%%esp)\n"
+"	movl	$0x6E69772F, 8(%%esp)\n"
+"	movl	$0x00000065, 12(%%esp)\n"
+"	movl	%%esp, %%ebx\n"
+"	addl	$16, %%esp\n"
+"	movl	%%ebx, 0(%%esp)\n"
+"	movl	%%esp, %%ecx\n"
+"	addl	$2, %%edx\n"
+"	sall	$2, %%edx\n"
+"	addl	%%esp, %%edx\n"
+"	movl	$11, %%eax\n"
+"	int	$0x80\n"
+"	movl	$255, %%ebx\n"
+"	subl	%%eax, %%ebx\n"
+"	movl	$1, %%eax\n"
+"	int	$0x80\n"
+;
+#endif
+
 static int keep_generated = 0;
 static strarray* tmp_files;
 #ifdef HAVE_SIGSET_T
@@ -642,6 +674,7 @@ static void build(struct options* opts)
     strarray *lib_dirs, *files;
     strarray *spec_args, *link_args;
     char *output_file;
+    const char *start_name;
     const char *spec_o_name;
     const char *output_name, *spec_file, *lang;
     int generate_app_loader = 1;
@@ -658,24 +691,22 @@ static void build(struct options* opts)
      *    -xlll:  lll is the language (c, c++, etc.)
      */
 
-    output_file = strdup( opts->output_name ? opts->output_name : "a.out" );
-
-    /* 'winegcc -o app xxx.exe.so' only creates the load script */
-    if (opts->files->size == 1 && strendswith(opts->files->base[0], ".exe.so"))
-    {
-	create_file(output_file, 0755, app_loader_template, opts->files->base[0]);
-	return;
-    }
+    output_file = strdup( opts->output_name ? opts->output_name : "a.exe" );
 
     /* generate app loader only for .exe */
     if (opts->shared || strendswith(output_file, ".so"))
-	generate_app_loader = 0;
+        generate_app_loader = 0;
 
     if (strendswith(output_file, ".fake")) fake_module = 1;
 
+#if defined (__i386__) || defined (__x86_64__)
+    generate_app_loader = 0;
+#else
     /* normalize the filename a bit: strip .so, ensure it has proper ext */
     if (strendswith(output_file, ".so")) 
-	output_file[strlen(output_file) - 3] = 0;
+        output_file[strlen(output_file) - 3] = 0;
+#endif
+
     if ((output_name = strrchr(output_file, '/'))) output_name++;
     else output_name = output_file;
     if (!strchr(output_name, '.'))
@@ -958,7 +989,11 @@ static void build(struct options* opts)
     strarray_addall(link_args, strarray_fromstring(LDDLLFLAGS, " "));
 
     strarray_add(link_args, "-o");
+#if defined (__i386__) || defined (__x86_64__)
+    strarray_add(link_args, output_file);
+#else
     strarray_add(link_args, strmake("%s.so", output_file));
+#endif
 
     for ( j = 0 ; j < opts->linker_args->size ; j++ ) 
         strarray_add(link_args, opts->linker_args->base[j]);
@@ -1007,6 +1042,12 @@ static void build(struct options* opts)
 	}
     }
 
+#if defined (__i386__) || defined (__x86_64__)
+    start_name = get_temp_file(output_name, "-start.s");
+    create_file(start_name, 0644, start_asm_code);
+    strarray_add(link_args, start_name);
+#endif
+
     if (!opts->nostdlib) 
     {
 	strarray_add(link_args, "-lm");
@@ -1026,15 +1067,21 @@ static void build(struct options* opts)
             strarray_add(prelink_args, prelink);
             strarray_add(prelink_args, "--reloc-only");
             strarray_add(prelink_args, opts->image_base);
+#if defined (__i386__) || defined (__x86_64__)
+            strarray_add(prelink_args, output_file);
+#else
             strarray_add(prelink_args, strmake("%s.so", output_file));
+#endif
             spawn(opts->prefix, prelink_args, 1);
             strarray_free(prelink_args);
         }
     }
 
+#if ! defined (__i386__) && ! defined (__x86_64__)
     /* create the loader script */
     if (generate_app_loader)
         create_file(output_file, 0755, app_loader_template, strmake("%s.so", output_name));
+#endif
 }
 
 
