Patch flat cs of 16-bit entry points if current %cs is different from
compiled value, and retrieve flat ds from a global variable. This
should avoid problems with win4lin kernels.

diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h
index c3e8094..cd75f79 100644
--- a/tools/winebuild/build.h
+++ b/tools/winebuild/build.h
@@ -167,9 +167,6 @@
 extern int UsePIC;
 extern int debugging;
 
-extern unsigned short code_selector;
-extern unsigned short data_selector;
-
 extern char DLLName[80];
 extern char DLLFileName[80];
 extern char DLLInitFunc[80];
diff --git a/tools/winebuild/main.c b/tools/winebuild/main.c
index 9d8d84e..19479d4 100644
--- a/tools/winebuild/main.c
+++ b/tools/winebuild/main.c
@@ -17,17 +17,6 @@
 #include "winnt.h"
 #include "build.h"
 
-#ifdef __i386__
-extern WORD __get_cs(void);
-extern WORD __get_ds(void);
-__ASM_GLOBAL_FUNC( __get_cs, "movw %cs,%ax\n\tret" );
-__ASM_GLOBAL_FUNC( __get_ds, "movw %ds,%ax\n\tret" );
-#else
-static inline WORD __get_cs(void) { return 0; }
-static inline WORD __get_ds(void) { return 0; }
-#endif
-
-
 ORDDEF EntryPoints[MAX_ORDINALS];
 ORDDEF *Ordinals[MAX_ORDINALS];
 ORDDEF *Names[MAX_ORDINALS];
@@ -49,9 +38,6 @@
 const char *input_file_name;
 const char *output_file_name;
 
-unsigned short code_selector;
-unsigned short data_selector;
-
 static FILE *input_file;
 static FILE *output_file;
 
@@ -189,13 +175,6 @@
     output_file = stdout;
     parse_options( argv );
 
-    /* Retrieve the selector values; this assumes that we are building
-     * the asm files on the platform that will also run them. Probably
-     * a safe assumption to make.
-     */
-    code_selector = __get_cs();
-    data_selector = __get_ds();
-
     switch(exec_mode)
     {
     case MODE_SPEC:
diff --git a/tools/winebuild/relay.c b/tools/winebuild/relay.c
index 018dc45..aa2c550 100644
--- a/tools/winebuild/relay.c
+++ b/tools/winebuild/relay.c
@@ -120,8 +120,15 @@
         fprintf( outfile, "\taddl $_GLOBAL_OFFSET_TABLE_+[.-.LCallFrom16%s.getgot1], %%ecx\n", name );
     }
 
+    if (UsePIC)
+    {
+        fprintf( outfile, "\t.byte 0x2e\n\tmovl " PREFIX "CallTo16_DataSelector@GOT(%%ecx), %%edx\n" );
+        fprintf( outfile, "\t.byte 0x2e\n\tmovl (%%edx), %%edx\n" );
+    }
+    else
+        fprintf( outfile, "\t.byte 0x2e\n\tmovl " PREFIX "CallTo16_DataSelector,%%edx\n" );
+
     /* Load 32-bit segment registers */
-    fprintf( outfile, "\tmovw $0x%04x, %%dx\n", data_selector );
 #ifdef __svr4__
     fprintf( outfile, "\tdata16\n");
 #endif
@@ -690,7 +697,7 @@
 
     /* Restore 32-bit segment registers */
 
-    fprintf( outfile, "\tmovw $0x%04x,%%di\n", data_selector );
+    fprintf( outfile, "\t.byte 0x2e\n\tmovl " PREFIX "CallTo16_DataSelector-" PREFIX "Call16_Ret_Start,%%edi\n" );
 #ifdef __svr4__
     fprintf( outfile, "\tdata16\n");
 #endif
@@ -715,9 +722,12 @@
 
     fprintf( outfile, "\tlret\n" );
 
-    /* Declare the return address variable */
+    /* Declare the return address and data selector variables */
 
-    fprintf( outfile, "\n\t.globl " PREFIX "CallTo16_RetAddr\n" );
+    fprintf( outfile, "\n\t.align 4\n" );
+    fprintf( outfile, "\t.globl " PREFIX "CallTo16_DataSelector\n" );
+    fprintf( outfile, PREFIX "CallTo16_DataSelector:\t.long 0\n" );
+    fprintf( outfile, "\t.globl " PREFIX "CallTo16_RetAddr\n" );
     fprintf( outfile, PREFIX "CallTo16_RetAddr:\t.long 0\n" );
 }
 
diff --git a/tools/winebuild/spec16.c b/tools/winebuild/spec16.c
index 1f49bc8..da94cff 100644
--- a/tools/winebuild/spec16.c
+++ b/tools/winebuild/spec16.c
@@ -18,6 +18,13 @@
 
 #include "build.h"
 
+#ifdef __i386__
+extern unsigned short __get_cs(void);
+__ASM_GLOBAL_FUNC( __get_cs, "movw %cs,%ax\n\tret" );
+#else
+static inline unsigned short __get_cs(void) { return 0; }
+#endif /* __i386__ */
+
 
 /*******************************************************************
  *         StoreVariableCode
@@ -497,12 +504,12 @@
     int i, nFuncs, nTypes;
     int code_offset, data_offset, module_size, res_size;
     unsigned char *data;
+    unsigned short code_selector = __get_cs();
 
     /* File header */
 
     fprintf( outfile, "/* File generated automatically from %s; do not edit! */\n\n",
              input_file_name );
-    fprintf( outfile, "#define __FLATCS__ 0x%04x\n", code_selector );
     fprintf( outfile, "#include \"builtin16.h\"\n\n" );
 
     fprintf( outfile, "extern void RELAY_Unimplemented16(void);\n\n" );
@@ -709,8 +716,8 @@
     fprintf( outfile, "    \"%s\",\n", DLLName );
     fprintf( outfile, "    Module,\n" );
     fprintf( outfile, "    sizeof(Module),\n" );
-    fprintf( outfile, "    (BYTE *)&Code_Segment,\n" );
-    fprintf( outfile, "    (BYTE *)Data_Segment,\n" );
+    fprintf( outfile, "    &Code_Segment,\n" );
+    fprintf( outfile, "    Data_Segment,\n" );
     fprintf( outfile, "    \"%s\",\n", owner_name );
     fprintf( outfile, "    %s\n", res_size ? "resource_data" : "0" );
     fprintf( outfile, "};\n" );