Commit cceab986 authored by Alexandre Julliard's avatar Alexandre Julliard

Unregister 16-bit dlls on module unload.

parent da00742a
...@@ -998,6 +998,7 @@ init MAIN_KernelInit ...@@ -998,6 +998,7 @@ init MAIN_KernelInit
# 16-bit relays # 16-bit relays
@ cdecl __wine_register_dll_16(ptr) __wine_register_dll_16 @ cdecl __wine_register_dll_16(ptr) __wine_register_dll_16
@ cdecl __wine_unregister_dll_16(ptr) __wine_unregister_dll_16
@ varargs __wine_call_from_16_word() __wine_call_from_16_word @ varargs __wine_call_from_16_word() __wine_call_from_16_word
@ varargs __wine_call_from_16_long() __wine_call_from_16_long @ varargs __wine_call_from_16_long() __wine_call_from_16_long
@ varargs __wine_call_from_16_regs() __wine_call_from_16_regs @ varargs __wine_call_from_16_regs() __wine_call_from_16_regs
......
...@@ -51,7 +51,6 @@ typedef struct ...@@ -51,7 +51,6 @@ typedef struct
#define MAX_DLLS 50 #define MAX_DLLS 50
static const BUILTIN16_DESCRIPTOR *builtin_dlls[MAX_DLLS]; static const BUILTIN16_DESCRIPTOR *builtin_dlls[MAX_DLLS];
static int nb_dlls;
/* patch all the flat cs references of the code segment if necessary */ /* patch all the flat cs references of the code segment if necessary */
...@@ -134,20 +133,22 @@ static HMODULE16 BUILTIN_DoLoadModule16( const BUILTIN16_DESCRIPTOR *descr ) ...@@ -134,20 +133,22 @@ static HMODULE16 BUILTIN_DoLoadModule16( const BUILTIN16_DESCRIPTOR *descr )
static const BUILTIN16_DESCRIPTOR *find_dll_descr( const char *dllname ) static const BUILTIN16_DESCRIPTOR *find_dll_descr( const char *dllname )
{ {
int i; int i;
for (i = 0; i < nb_dlls; i++) for (i = 0; i < MAX_DLLS; i++)
{ {
const BUILTIN16_DESCRIPTOR *descr = builtin_dlls[i]; const BUILTIN16_DESCRIPTOR *descr = builtin_dlls[i];
NE_MODULE *pModule = (NE_MODULE *)descr->module_start; if (descr)
OFSTRUCT *pOfs = (OFSTRUCT *)((LPBYTE)pModule + pModule->fileinfo); {
BYTE *name_table = (BYTE *)pModule + pModule->name_table; NE_MODULE *pModule = (NE_MODULE *)descr->module_start;
OFSTRUCT *pOfs = (OFSTRUCT *)((LPBYTE)pModule + pModule->fileinfo);
/* check the dll file name */ BYTE *name_table = (BYTE *)pModule + pModule->name_table;
if (!FILE_strcasecmp( pOfs->szPathName, dllname ))
return descr; /* check the dll file name */
/* check the dll module name (without extension) */ if (!FILE_strcasecmp( pOfs->szPathName, dllname )) return descr;
if (!FILE_strncasecmp( dllname, name_table+1, *name_table ) && /* check the dll module name (without extension) */
!strcmp( dllname + *name_table, ".dll" )) if (!FILE_strncasecmp( dllname, name_table+1, *name_table ) &&
return descr; !strcmp( dllname + *name_table, ".dll" ))
return descr;
}
} }
return NULL; return NULL;
} }
...@@ -199,6 +200,31 @@ HMODULE16 BUILTIN_LoadModule( LPCSTR name ) ...@@ -199,6 +200,31 @@ HMODULE16 BUILTIN_LoadModule( LPCSTR name )
*/ */
void __wine_register_dll_16( const BUILTIN16_DESCRIPTOR *descr ) void __wine_register_dll_16( const BUILTIN16_DESCRIPTOR *descr )
{ {
assert( nb_dlls < MAX_DLLS ); int i;
builtin_dlls[nb_dlls++] = descr;
for (i = 0; i < MAX_DLLS; i++)
{
if (builtin_dlls[i]) continue;
builtin_dlls[i] = descr;
break;
}
assert( i < MAX_DLLS );
}
/***********************************************************************
* __wine_unregister_dll_16 (KERNEL32.@)
*
* Unregister a built-in DLL descriptor.
*/
void __wine_unregister_dll_16( const BUILTIN16_DESCRIPTOR *descr )
{
int i;
for (i = 0; i < MAX_DLLS; i++)
{
if (builtin_dlls[i] != descr) continue;
builtin_dlls[i] = NULL;
break;
}
} }
...@@ -157,6 +157,7 @@ extern int output_resources( FILE *outfile ); ...@@ -157,6 +157,7 @@ extern int output_resources( FILE *outfile );
extern void load_res16_file( const char *name ); extern void load_res16_file( const char *name );
extern int output_res16_data( FILE *outfile ); extern int output_res16_data( FILE *outfile );
extern int output_res16_directory( unsigned char *buffer ); extern int output_res16_directory( unsigned char *buffer );
extern void output_dll_init( FILE *outfile, const char *constructor, const char *destructor );
extern void parse_debug_channels( const char *srcdir, const char *filename ); extern void parse_debug_channels( const char *srcdir, const char *filename );
extern void BuildGlue( FILE *outfile, FILE *infile ); extern void BuildGlue( FILE *outfile, FILE *infile );
......
...@@ -623,6 +623,7 @@ void BuildSpec16File( FILE *outfile ) ...@@ -623,6 +623,7 @@ 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;
char constructor[100], destructor[100];
#ifdef __i386__ #ifdef __i386__
unsigned short code_selector = wine_get_cs(); unsigned short code_selector = wine_get_cs();
#endif #endif
...@@ -877,40 +878,22 @@ void BuildSpec16File( FILE *outfile ) ...@@ -877,40 +878,22 @@ void BuildSpec16File( FILE *outfile )
/* Output the DLL constructor */ /* Output the DLL constructor */
fprintf( outfile, "#ifndef __GNUC__\n" ); sprintf( constructor, "__wine_spec_%s_init", make_c_identifier(DLLName) );
fprintf( outfile, "static void __asm__dummy_dll_init(void) {\n" ); sprintf( destructor, "__wine_spec_%s_fini", make_c_identifier(DLLName) );
fprintf( outfile, "#endif /* defined(__GNUC__) */\n" ); output_dll_init( outfile, constructor, destructor );
#if defined(__i386__)
fprintf( outfile, "asm(\"\\t.section\t.init ,\\\"ax\\\"\\n\"\n" );
fprintf( outfile, " \"\\tcall " PREFIX "__wine_spec_%s_init\\n\"\n",
make_c_identifier(DLLName) );
fprintf( outfile, " \"\\t.previous\\n\");\n" );
#elif defined(__sparc__)
fprintf( outfile, "asm(\"\\t.section\t.init ,\\\"ax\\\"\\n\"\n" );
fprintf( outfile, " \"\\tcall " PREFIX "__wine_spec_%s_init\\n\"\n",
make_c_identifier(DLLName) );
fprintf( outfile, " \"\\tnop\\n\"\n" );
fprintf( outfile, " \"\\t.previous\\n\");\n" );
#elif defined(__PPC__)
fprintf( outfile, "asm(\"\\t.section\t.init ,\\\"ax\\\"\\n\"\n" );
fprintf( outfile, " \"\\tbl " PREFIX "__wine_spec_%s_init\\n\"\n",
make_c_identifier(DLLName) );
fprintf( outfile, " \"\\t.previous\\n\");\n" );
#else
#error You need to define the DLL constructor for your architecture
#endif
fprintf( outfile, "#ifndef __GNUC__\n" );
fprintf( outfile, "}\n" );
fprintf( outfile, "#endif /* defined(__GNUC__) */\n\n" );
fprintf( outfile, fprintf( outfile,
"void __wine_spec_%s_init(void)\n" "void %s(void)\n"
"{\n" "{\n"
" extern void __wine_register_dll_16( const struct dll_descriptor *descr );\n" " extern void __wine_register_dll_16( const struct dll_descriptor *descr );\n"
" __wine_register_dll_16( &descriptor );\n" " __wine_register_dll_16( &descriptor );\n"
"}\n", make_c_identifier(DLLName) ); "}\n", constructor );
fprintf( outfile,
"void %s(void)\n"
"{\n"
" extern void __wine_unregister_dll_16( const struct dll_descriptor *descr );\n"
" __wine_unregister_dll_16( &descriptor );\n"
"}\n", destructor );
} }
......
...@@ -426,6 +426,68 @@ static void output_register_funcs( FILE *outfile ) ...@@ -426,6 +426,68 @@ static void output_register_funcs( FILE *outfile )
/******************************************************************* /*******************************************************************
* output_dll_init
*
* Output code for calling a dll constructor and destructor.
*/
void output_dll_init( FILE *outfile, const char *constructor, const char *destructor )
{
fprintf( outfile, "#ifndef __GNUC__\n" );
fprintf( outfile, "static void __asm__dummy_dll_init(void) {\n" );
fprintf( outfile, "#endif\n" );
#if defined(__i386__)
if (constructor)
{
fprintf( outfile, "asm(\"\\t.section\t.init ,\\\"ax\\\"\\n\"\n" );
fprintf( outfile, " \"\\tcall " PREFIX "%s\\n\"\n", constructor );
fprintf( outfile, " \"\\t.previous\\n\");\n" );
}
if (destructor)
{
fprintf( outfile, "asm(\"\\t.section\t.fini ,\\\"ax\\\"\\n\"\n" );
fprintf( outfile, " \"\\tcall " PREFIX "%s\\n\"\n", destructor );
fprintf( outfile, " \"\\t.previous\\n\");\n" );
}
#elif defined(__sparc__)
if (constructor)
{
fprintf( outfile, "asm(\"\\t.section\t.init ,\\\"ax\\\"\\n\"\n" );
fprintf( outfile, " \"\\tcall " PREFIX "%s\\n\"\n", constructor );
fprintf( outfile, " \"\\tnop\\n\"\n" );
fprintf( outfile, " \"\\t.previous\\n\");\n" );
}
if (destructor)
{
fprintf( outfile, "asm(\"\\t.section\t.fini ,\\\"ax\\\"\\n\"\n" );
fprintf( outfile, " \"\\tcall " PREFIX "%s\\n\"\n", destructor );
fprintf( outfile, " \"\\tnop\\n\"\n" );
fprintf( outfile, " \"\\t.previous\\n\");\n" );
}
#elif defined(__PPC__)
if (constructor)
{
fprintf( outfile, "asm(\"\\t.section\t.init ,\\\"ax\\\"\\n\"\n" );
fprintf( outfile, " \"\\tbl " PREFIX "%s\\n\"\n", constructor );
fprintf( outfile, " \"\\t.previous\\n\");\n" );
}
if (destructor)
{
fprintf( outfile, "asm(\"\\t.section\t.fini ,\\\"ax\\\"\\n\"\n" );
fprintf( outfile, " \"\\tbl " PREFIX "%s\\n\"\n", destructor );
DLLName );
fprintf( outfile, " \"\\t.previous\\n\");\n" );
}
#else
#error You need to define the DLL constructor for your architecture
#endif
fprintf( outfile, "#ifndef __GNUC__\n" );
fprintf( outfile, "}\n" );
fprintf( outfile, "#endif\n" );
}
/*******************************************************************
* BuildSpec32File * BuildSpec32File
* *
* Build a Win32 C file from a spec file. * Build a Win32 C file from a spec file.
...@@ -436,6 +498,7 @@ void BuildSpec32File( FILE *outfile ) ...@@ -436,6 +498,7 @@ void BuildSpec32File( FILE *outfile )
int nr_exports, nr_imports, nr_resources; int nr_exports, nr_imports, nr_resources;
int characteristics, subsystem; int characteristics, subsystem;
DWORD page_size; DWORD page_size;
char constructor[100];
#ifdef HAVE_GETPAGESIZE #ifdef HAVE_GETPAGESIZE
page_size = getpagesize(); page_size = getpagesize();
...@@ -712,42 +775,17 @@ void BuildSpec32File( FILE *outfile ) ...@@ -712,42 +775,17 @@ void BuildSpec32File( FILE *outfile )
/* Output the DLL constructor */ /* Output the DLL constructor */
fprintf( outfile, "#ifndef __GNUC__\n" ); sprintf( constructor, "__wine_spec_%s_init", make_c_identifier(DLLName) );
fprintf( outfile, "static void __asm__dummy_dll_init(void) {\n" ); output_dll_init( outfile, constructor, NULL );
fprintf( outfile, "#endif /* defined(__GNUC__) */\n" );
#if defined(__i386__)
fprintf( outfile, "asm(\"\\t.section\t.init ,\\\"ax\\\"\\n\"\n" );
fprintf( outfile, " \"\\tcall " PREFIX "__wine_spec_%s_init\\n\"\n",
make_c_identifier(DLLName) );
fprintf( outfile, " \"\\t.previous\\n\");\n" );
#elif defined(__sparc__)
fprintf( outfile, "asm(\"\\t.section\t.init ,\\\"ax\\\"\\n\"\n" );
fprintf( outfile, " \"\\tcall " PREFIX "__wine_spec_%s_init\\n\"\n",
make_c_identifier(DLLName) );
fprintf( outfile, " \"\\tnop\\n\"\n" );
fprintf( outfile, " \"\\t.previous\\n\");\n" );
#elif defined(__PPC__)
fprintf( outfile, "asm(\"\\t.section\t.init ,\\\"ax\\\"\\n\"\n" );
fprintf( outfile, " \"\\tbl " PREFIX "__wine_spec_%s_init\\n\"\n",
make_c_identifier(DLLName) );
fprintf( outfile, " \"\\t.previous\\n\");\n" );
#else
#error You need to define the DLL constructor for your architecture
#endif
fprintf( outfile, "#ifndef __GNUC__\n" );
fprintf( outfile, "}\n" );
fprintf( outfile, "#endif /* defined(__GNUC__) */\n\n" );
fprintf( outfile, fprintf( outfile,
"void __wine_spec_%s_init(void)\n" "void %s(void)\n"
"{\n" "{\n"
" extern void __wine_dll_register( const struct image_nt_headers *, const char * );\n" " extern void __wine_dll_register( const struct image_nt_headers *, const char * );\n"
" extern void *__wine_dbg_register( char * const *, int );\n" " extern void *__wine_dbg_register( char * const *, int );\n"
" __wine_dll_register( &nt_header, \"%s\" );\n", " __wine_dll_register( &nt_header, \"%s\" );\n"
make_c_identifier(DLLName), DLLFileName ); "}\n",
fprintf( outfile, "}\n" ); constructor, DLLFileName );
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment