From aa5a1162a3248ccd7ac72f43f3b1efc1c92f9ddd Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Sun, 29 Oct 2000 01:28:30 +0000 Subject: [PATCH] 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. --- if1632/builtin.c | 17 +++++++++++++++++ if1632/relay.c | 2 ++ include/builtin16.h | 4 ++-- tools/winebuild/build.h | 3 --- tools/winebuild/main.c | 21 --------------------- tools/winebuild/relay.c | 18 ++++++++++++++---- tools/winebuild/spec16.c | 13 ++++++++++--- 7 files changed, 45 insertions(+), 33 deletions(-) diff --git a/if1632/builtin.c b/if1632/builtin.c index 099df5f5966..4d53a32498f 100644 --- a/if1632/builtin.c +++ b/if1632/builtin.c @@ -17,6 +17,7 @@ #include "module.h" #include "miscemu.h" #include "stackframe.h" +#include "selectors.h" #include "task.h" #include "debugtools.h" #include "toolhelp.h" @@ -31,6 +32,21 @@ static const BUILTIN16_DESCRIPTOR *builtin_dlls[MAX_DLLS]; static int nb_dlls; +/* patch all the flat cs references of the code segment if necessary */ +inline static void patch_code_segment( void *code_segment ) +{ +#ifdef __i386__ + CALLFROM16 *call = code_segment; + if (call->flatcs == __get_cs()) return; /* nothing to patch */ + while (call->pushl == 0x68) + { + call->flatcs = __get_cs(); + call++; + } +#endif +} + + /*********************************************************************** * BUILTIN_DoLoadModule16 * @@ -62,6 +78,7 @@ static HMODULE16 BUILTIN_DoLoadModule16( const BUILTIN16_DESCRIPTOR *descr ) pSegTable->hSeg = GLOBAL_CreateBlock( GMEM_FIXED, descr->code_start, pSegTable->minsize, hModule, TRUE, TRUE, FALSE ); if (!pSegTable->hSeg) return 0; + patch_code_segment( descr->code_start ); pSegTable++; /* Allocate the data segment */ diff --git a/if1632/relay.c b/if1632/relay.c index e10754af9c5..f4ecb65784f 100644 --- a/if1632/relay.c +++ b/if1632/relay.c @@ -36,6 +36,7 @@ BOOL RELAY_Init(void) extern void CALL32_CBClient_Ret(); extern void CALL32_CBClientEx_Ret(); extern SEGPTR CallTo16_RetAddr; + extern DWORD CallTo16_DataSelector; extern SEGPTR CALL32_CBClient_RetAddr; extern SEGPTR CALL32_CBClientEx_RetAddr; @@ -46,6 +47,7 @@ BOOL RELAY_Init(void) /* Patch the return addresses for CallTo16 routines */ + CallTo16_DataSelector = __get_ds(); CallTo16_RetAddr = PTR_SEG_OFF_TO_SEGPTR( codesel, (char*)CallTo16_Ret - (char*)Call16_Ret_Start ); CALL32_CBClient_RetAddr = diff --git a/include/builtin16.h b/include/builtin16.h index f2f9baa9b17..e5626d294fc 100644 --- a/include/builtin16.h +++ b/include/builtin16.h @@ -55,8 +55,8 @@ typedef struct const char *name; /* DLL name */ void *module_start; /* 32-bit address of the module data */ int module_size; /* Size of the module data */ - const BYTE *code_start; /* 32-bit address of DLL code */ - const BYTE *data_start; /* 32-bit address of DLL data */ + void *code_start; /* 32-bit address of DLL code */ + void *data_start; /* 32-bit address of DLL data */ const char *owner; /* 32-bit dll that contains this dll */ const void *rsrc; /* resources data */ } BUILTIN16_DESCRIPTOR; diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h index c3e8094df6f..cd75f79b791 100644 --- a/tools/winebuild/build.h +++ b/tools/winebuild/build.h @@ -167,9 +167,6 @@ extern int DLLHeapSize; 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 9d8d84e1a18..19479d4af55 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 @@ char owner_name[80]; 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 @@ int main(int argc, char **argv) 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 018dc45d6f3..aa2c550cab5 100644 --- a/tools/winebuild/relay.c +++ b/tools/winebuild/relay.c @@ -120,8 +120,15 @@ static void BuildCallFrom16Core( FILE *outfile, int reg_func, int thunk, int sho 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 @@ static void BuildRet16Func( FILE *outfile ) /* 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 @@ static void BuildRet16Func( FILE *outfile ) 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 1f49bc8034a..da94cff5007 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 @@ void BuildSpec16File( FILE *outfile ) 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 @@ void BuildSpec16File( FILE *outfile ) 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" );