--- winegcc.c.orig	2011-02-03 22:57:05.000000000 +0100
+++ winegcc.c	2011-02-04 02:43:57.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
@@ -98,44 +99,56 @@
 
 #include "utils.h"
 
-static const char* app_loader_template =
-    "#!/bin/sh\n"
-    "\n"
-    "appname=\"%s\"\n"
-    "# determine the application directory\n"
-    "appdir=''\n"
-    "case \"$0\" in\n"
-    "  */*)\n"
-    "    # $0 contains a path, use it\n"
-    "    appdir=`dirname \"$0\"`\n"
-    "    ;;\n"
-    "  *)\n"
-    "    # no directory in $0, search in PATH\n"
-    "    saved_ifs=$IFS\n"
-    "    IFS=:\n"
-    "    for d in $PATH\n"
-    "    do\n"
-    "      IFS=$saved_ifs\n"
-    "      if [ -x \"$d/$appname\" ]; then appdir=\"$d\"; break; fi\n"
-    "    done\n"
-    "    ;;\n"
-    "esac\n"
-    "\n"
-    "# figure out the full app path\n"
-    "if [ -n \"$appdir\" ]; then\n"
-    "    apppath=\"$appdir/$appname\"\n"
-    "    WINEDLLPATH=\"$appdir:$WINEDLLPATH\"\n"
-    "    export WINEDLLPATH\n"
-    "else\n"
-    "    apppath=\"$appname\"\n"
-    "fi\n"
-    "\n"
-    "# determine the WINELOADER\n"
-    "if [ ! -x \"$WINELOADER\" ]; then WINELOADER=\"wine\"; fi\n"
-    "\n"
-    "# and try to start the app\n"
-    "exec \"$WINELOADER\" \"$apppath\" \"$@\"\n"
-;
+/* Assembler code that implement section _start for wine executables - shared libraries */
+/* It call sys_execve - start wine with all arguments */
+static const char * start_asm_code = "\n\
+.text\n\
+\n\
+.global _start\n\
+\n\
+_start:\n\
+\n\
+	pushl	%%ebp\n\
+	movl	%%esp, %%ebp\n\
+\n\
+	pushl	$0\n\
+\n\
+	movl	$4, %%eax\n\
+	movl	4(%%ebp), %%ebx\n\
+	mul	%%ebx\n\
+	add	$4, %%ebp\n\
+	movl	%%ebp, %%ebx\n\
+	add	%%eax, %%ebp\n\
+	movl	%%ebx, %%eax\n\
+\n\
+loop:\n\
+	pushl	0(%%ebp)\n\
+	subl	$4, %%ebp\n\
+	cmp	%%ebp, %%eax\n\
+	jne	loop\n\
+\n\
+	movl	%%esp, %%ebx\n\
+	andl	$-16, %%esp\n\
+	subl	$32, %%esp\n\
+	movl	$0x752F, 18(%%esp)\n\
+	movl	$0x622F7273, 20(%%esp)\n\
+	movl	$0x772F6E69, 24(%%esp)\n\
+	movl	$0x00656E69, 28(%%esp)\n\
+	leal	18(%%esp), %%eax\n\
+	movl	%%ebx, %%esp\n\
+\n\
+	pushl	%%eax\n\
+\n\
+	movl	$0, %%edx\n\
+	movl	%%esp, %%ecx\n\
+	movl	%%eax, %%ebx\n\
+	movl	$11, %%eax\n\
+	int	$0x80\n\
+\n\
+	movl	$1, %%ebx\n\
+	movl	$1, %%eax\n\
+	int	$0x80\n\
+";
 
 static int keep_generated = 0;
 static strarray* tmp_files;
@@ -641,10 +654,11 @@ static void build(struct options* opts)
 {
     strarray *lib_dirs, *files;
     strarray *spec_args, *link_args;
+    strarray * start_args;
+    const char *start_name, *start_obj_name;
     char *output_file;
     const char *spec_o_name;
     const char *output_name, *spec_file, *lang;
-    int generate_app_loader = 1;
     int fake_module = 0;
     unsigned int j;
 
@@ -658,24 +672,10 @@ 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;
-    }
-
-    /* generate app loader only for .exe */
-    if (opts->shared || strendswith(output_file, ".so"))
-	generate_app_loader = 0;
+    output_file = strdup( opts->output_name ? opts->output_name : "a.exe" );
 
     if (strendswith(output_file, ".fake")) fake_module = 1;
 
-    /* normalize the filename a bit: strip .so, ensure it has proper ext */
-    if (strendswith(output_file, ".so")) 
-	output_file[strlen(output_file) - 3] = 0;
     if ((output_name = strrchr(output_file, '/'))) output_name++;
     else output_name = output_file;
     if (!strchr(output_name, '.'))
@@ -958,7 +958,7 @@ static void build(struct options* opts)
     strarray_addall(link_args, strarray_fromstring(LDDLLFLAGS, " "));
 
     strarray_add(link_args, "-o");
-    strarray_add(link_args, strmake("%s.so", output_file));
+    strarray_add(link_args, output_file);
 
     for ( j = 0 ; j < opts->linker_args->size ; j++ ) 
         strarray_add(link_args, opts->linker_args->base[j]);
@@ -1007,6 +1007,21 @@ static void build(struct options* opts)
 	}
     }
 
+    start_name = get_temp_file(output_name, "-start.s");
+    start_obj_name = get_temp_file(output_name, "-start.o");
+
+    create_file(start_name, 0644, start_asm_code);
+
+    start_args = strarray_alloc();
+    strarray_add(start_args, "as");
+    strarray_add(start_args, start_name);
+    strarray_add(start_args, "-o");
+    strarray_add(start_args, start_obj_name);
+    spawn(opts->prefix, start_args, 0);
+    strarray_free(start_args);
+
+    strarray_add(link_args, start_obj_name);
+
     if (!opts->nostdlib) 
     {
 	strarray_add(link_args, "-lm");
@@ -1026,15 +1041,12 @@ static void build(struct options* opts)
             strarray_add(prelink_args, prelink);
             strarray_add(prelink_args, "--reloc-only");
             strarray_add(prelink_args, opts->image_base);
-            strarray_add(prelink_args, strmake("%s.so", output_file));
+            strarray_add(prelink_args, output_file);
+
             spawn(opts->prefix, prelink_args, 1);
             strarray_free(prelink_args);
         }
     }
-
-    /* create the loader script */
-    if (generate_app_loader)
-        create_file(output_file, 0755, app_loader_template, strmake("%s.so", output_name));
 }
 
 
