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.
This commit is contained in:
parent
44f84b55f3
commit
aa5a1162a3
|
@ -17,6 +17,7 @@
|
||||||
#include "module.h"
|
#include "module.h"
|
||||||
#include "miscemu.h"
|
#include "miscemu.h"
|
||||||
#include "stackframe.h"
|
#include "stackframe.h"
|
||||||
|
#include "selectors.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include "debugtools.h"
|
#include "debugtools.h"
|
||||||
#include "toolhelp.h"
|
#include "toolhelp.h"
|
||||||
|
@ -31,6 +32,21 @@ static const BUILTIN16_DESCRIPTOR *builtin_dlls[MAX_DLLS];
|
||||||
static int nb_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
|
* BUILTIN_DoLoadModule16
|
||||||
*
|
*
|
||||||
|
@ -62,6 +78,7 @@ static HMODULE16 BUILTIN_DoLoadModule16( const BUILTIN16_DESCRIPTOR *descr )
|
||||||
pSegTable->hSeg = GLOBAL_CreateBlock( GMEM_FIXED, descr->code_start,
|
pSegTable->hSeg = GLOBAL_CreateBlock( GMEM_FIXED, descr->code_start,
|
||||||
pSegTable->minsize, hModule, TRUE, TRUE, FALSE );
|
pSegTable->minsize, hModule, TRUE, TRUE, FALSE );
|
||||||
if (!pSegTable->hSeg) return 0;
|
if (!pSegTable->hSeg) return 0;
|
||||||
|
patch_code_segment( descr->code_start );
|
||||||
pSegTable++;
|
pSegTable++;
|
||||||
|
|
||||||
/* Allocate the data segment */
|
/* Allocate the data segment */
|
||||||
|
|
|
@ -36,6 +36,7 @@ BOOL RELAY_Init(void)
|
||||||
extern void CALL32_CBClient_Ret();
|
extern void CALL32_CBClient_Ret();
|
||||||
extern void CALL32_CBClientEx_Ret();
|
extern void CALL32_CBClientEx_Ret();
|
||||||
extern SEGPTR CallTo16_RetAddr;
|
extern SEGPTR CallTo16_RetAddr;
|
||||||
|
extern DWORD CallTo16_DataSelector;
|
||||||
extern SEGPTR CALL32_CBClient_RetAddr;
|
extern SEGPTR CALL32_CBClient_RetAddr;
|
||||||
extern SEGPTR CALL32_CBClientEx_RetAddr;
|
extern SEGPTR CALL32_CBClientEx_RetAddr;
|
||||||
|
|
||||||
|
@ -46,6 +47,7 @@ BOOL RELAY_Init(void)
|
||||||
|
|
||||||
/* Patch the return addresses for CallTo16 routines */
|
/* Patch the return addresses for CallTo16 routines */
|
||||||
|
|
||||||
|
CallTo16_DataSelector = __get_ds();
|
||||||
CallTo16_RetAddr =
|
CallTo16_RetAddr =
|
||||||
PTR_SEG_OFF_TO_SEGPTR( codesel, (char*)CallTo16_Ret - (char*)Call16_Ret_Start );
|
PTR_SEG_OFF_TO_SEGPTR( codesel, (char*)CallTo16_Ret - (char*)Call16_Ret_Start );
|
||||||
CALL32_CBClient_RetAddr =
|
CALL32_CBClient_RetAddr =
|
||||||
|
|
|
@ -55,8 +55,8 @@ typedef struct
|
||||||
const char *name; /* DLL name */
|
const char *name; /* DLL name */
|
||||||
void *module_start; /* 32-bit address of the module data */
|
void *module_start; /* 32-bit address of the module data */
|
||||||
int module_size; /* Size of the module data */
|
int module_size; /* Size of the module data */
|
||||||
const BYTE *code_start; /* 32-bit address of DLL code */
|
void *code_start; /* 32-bit address of DLL code */
|
||||||
const BYTE *data_start; /* 32-bit address of DLL data */
|
void *data_start; /* 32-bit address of DLL data */
|
||||||
const char *owner; /* 32-bit dll that contains this dll */
|
const char *owner; /* 32-bit dll that contains this dll */
|
||||||
const void *rsrc; /* resources data */
|
const void *rsrc; /* resources data */
|
||||||
} BUILTIN16_DESCRIPTOR;
|
} BUILTIN16_DESCRIPTOR;
|
||||||
|
|
|
@ -167,9 +167,6 @@ extern int DLLHeapSize;
|
||||||
extern int UsePIC;
|
extern int UsePIC;
|
||||||
extern int debugging;
|
extern int debugging;
|
||||||
|
|
||||||
extern unsigned short code_selector;
|
|
||||||
extern unsigned short data_selector;
|
|
||||||
|
|
||||||
extern char DLLName[80];
|
extern char DLLName[80];
|
||||||
extern char DLLFileName[80];
|
extern char DLLFileName[80];
|
||||||
extern char DLLInitFunc[80];
|
extern char DLLInitFunc[80];
|
||||||
|
|
|
@ -17,17 +17,6 @@
|
||||||
#include "winnt.h"
|
#include "winnt.h"
|
||||||
#include "build.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 EntryPoints[MAX_ORDINALS];
|
||||||
ORDDEF *Ordinals[MAX_ORDINALS];
|
ORDDEF *Ordinals[MAX_ORDINALS];
|
||||||
ORDDEF *Names[MAX_ORDINALS];
|
ORDDEF *Names[MAX_ORDINALS];
|
||||||
|
@ -49,9 +38,6 @@ char owner_name[80];
|
||||||
const char *input_file_name;
|
const char *input_file_name;
|
||||||
const char *output_file_name;
|
const char *output_file_name;
|
||||||
|
|
||||||
unsigned short code_selector;
|
|
||||||
unsigned short data_selector;
|
|
||||||
|
|
||||||
static FILE *input_file;
|
static FILE *input_file;
|
||||||
static FILE *output_file;
|
static FILE *output_file;
|
||||||
|
|
||||||
|
@ -189,13 +175,6 @@ int main(int argc, char **argv)
|
||||||
output_file = stdout;
|
output_file = stdout;
|
||||||
parse_options( argv );
|
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)
|
switch(exec_mode)
|
||||||
{
|
{
|
||||||
case MODE_SPEC:
|
case MODE_SPEC:
|
||||||
|
|
|
@ -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 );
|
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 */
|
/* Load 32-bit segment registers */
|
||||||
fprintf( outfile, "\tmovw $0x%04x, %%dx\n", data_selector );
|
|
||||||
#ifdef __svr4__
|
#ifdef __svr4__
|
||||||
fprintf( outfile, "\tdata16\n");
|
fprintf( outfile, "\tdata16\n");
|
||||||
#endif
|
#endif
|
||||||
|
@ -690,7 +697,7 @@ static void BuildRet16Func( FILE *outfile )
|
||||||
|
|
||||||
/* Restore 32-bit segment registers */
|
/* 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__
|
#ifdef __svr4__
|
||||||
fprintf( outfile, "\tdata16\n");
|
fprintf( outfile, "\tdata16\n");
|
||||||
#endif
|
#endif
|
||||||
|
@ -715,9 +722,12 @@ static void BuildRet16Func( FILE *outfile )
|
||||||
|
|
||||||
fprintf( outfile, "\tlret\n" );
|
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" );
|
fprintf( outfile, PREFIX "CallTo16_RetAddr:\t.long 0\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,13 @@
|
||||||
|
|
||||||
#include "build.h"
|
#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
|
* StoreVariableCode
|
||||||
|
@ -497,12 +504,12 @@ void BuildSpec16File( FILE *outfile )
|
||||||
int i, nFuncs, nTypes;
|
int i, nFuncs, nTypes;
|
||||||
int code_offset, data_offset, module_size, res_size;
|
int code_offset, data_offset, module_size, res_size;
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
|
unsigned short code_selector = __get_cs();
|
||||||
|
|
||||||
/* File header */
|
/* File header */
|
||||||
|
|
||||||
fprintf( outfile, "/* File generated automatically from %s; do not edit! */\n\n",
|
fprintf( outfile, "/* File generated automatically from %s; do not edit! */\n\n",
|
||||||
input_file_name );
|
input_file_name );
|
||||||
fprintf( outfile, "#define __FLATCS__ 0x%04x\n", code_selector );
|
|
||||||
fprintf( outfile, "#include \"builtin16.h\"\n\n" );
|
fprintf( outfile, "#include \"builtin16.h\"\n\n" );
|
||||||
|
|
||||||
fprintf( outfile, "extern void RELAY_Unimplemented16(void);\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, " \"%s\",\n", DLLName );
|
||||||
fprintf( outfile, " Module,\n" );
|
fprintf( outfile, " Module,\n" );
|
||||||
fprintf( outfile, " sizeof(Module),\n" );
|
fprintf( outfile, " sizeof(Module),\n" );
|
||||||
fprintf( outfile, " (BYTE *)&Code_Segment,\n" );
|
fprintf( outfile, " &Code_Segment,\n" );
|
||||||
fprintf( outfile, " (BYTE *)Data_Segment,\n" );
|
fprintf( outfile, " Data_Segment,\n" );
|
||||||
fprintf( outfile, " \"%s\",\n", owner_name );
|
fprintf( outfile, " \"%s\",\n", owner_name );
|
||||||
fprintf( outfile, " %s\n", res_size ? "resource_data" : "0" );
|
fprintf( outfile, " %s\n", res_size ? "resource_data" : "0" );
|
||||||
fprintf( outfile, "};\n" );
|
fprintf( outfile, "};\n" );
|
||||||
|
|
Loading…
Reference in New Issue