Moved the spec file init function and constructor to winecrt0.

This commit is contained in:
Alexandre Julliard 2005-09-02 14:43:03 +00:00
parent 4d7b593bd3
commit ce20722109
8 changed files with 69 additions and 32 deletions

View File

@ -12,6 +12,7 @@ C_SRCS = \
exe_main.c \ exe_main.c \
exe_wentry.c \ exe_wentry.c \
exe_wmain.c \ exe_wmain.c \
init.c \
stub.c stub.c
@MAKE_IMPLIB_RULES@ @MAKE_IMPLIB_RULES@

View File

@ -29,6 +29,13 @@ extern void _init(int argc, char **argv, char **envp );
extern void _fini(void); extern void _fini(void);
#endif #endif
extern int __wine_spec_init_state; enum init_state
{
NO_INIT_DONE, /* no initialization done yet */
DLL_REGISTERED, /* the dll has been registered */
CONSTRUCTORS_DONE /* the constructors have been run (implies dll registered too) */
};
extern enum init_state __wine_spec_init_state;
#endif /* __WINE_CRT0_PRIVATE_H__ */ #endif /* __WINE_CRT0_PRIVATE_H__ */

View File

@ -28,12 +28,13 @@ extern BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved );
BOOL WINAPI __wine_spec_dll_entry( HINSTANCE inst, DWORD reason, LPVOID reserved ) BOOL WINAPI __wine_spec_dll_entry( HINSTANCE inst, DWORD reason, LPVOID reserved )
{ {
BOOL ret; BOOL ret, needs_init = (__wine_spec_init_state != CONSTRUCTORS_DONE);
if (reason == DLL_PROCESS_ATTACH && __wine_spec_init_state == 1) if (reason == DLL_PROCESS_ATTACH && needs_init)
_init( __wine_main_argc, __wine_main_argv, __wine_main_environ ); _init( __wine_main_argc, __wine_main_argv, __wine_main_environ );
ret = DllMain( inst, reason, reserved ); ret = DllMain( inst, reason, reserved );
if (reason == DLL_PROCESS_DETACH && __wine_spec_init_state == 1)
_fini(); if (reason == DLL_PROCESS_DETACH && needs_init) _fini();
return ret; return ret;
} }

View File

@ -29,9 +29,11 @@ extern int main( int argc, char *argv[] );
DWORD WINAPI __wine_spec_exe_entry( PEB *peb ) DWORD WINAPI __wine_spec_exe_entry( PEB *peb )
{ {
BOOL needs_init = (__wine_spec_init_state != CONSTRUCTORS_DONE);
DWORD ret; DWORD ret;
if (__wine_spec_init_state == 1) _init( __wine_main_argc, __wine_main_argv, __wine_main_environ );
if (needs_init) _init( __wine_main_argc, __wine_main_argv, __wine_main_environ );
ret = main( __wine_main_argc, __wine_main_argv ); ret = main( __wine_main_argc, __wine_main_argv );
if (__wine_spec_init_state == 1) _fini(); if (needs_init) _fini();
ExitProcess( ret ); ExitProcess( ret );
} }

View File

@ -29,9 +29,11 @@ extern int wmain( int argc, WCHAR *argv[] );
DWORD WINAPI __wine_spec_exe_wentry( PEB *peb ) DWORD WINAPI __wine_spec_exe_wentry( PEB *peb )
{ {
BOOL needs_init = (__wine_spec_init_state != CONSTRUCTORS_DONE);
DWORD ret; DWORD ret;
if (__wine_spec_init_state == 1) _init( __wine_main_argc, __wine_main_argv, __wine_main_environ );
if (needs_init) _init( __wine_main_argc, __wine_main_argv, __wine_main_environ );
ret = wmain( __wine_main_argc, __wine_main_wargv ); ret = wmain( __wine_main_argc, __wine_main_wargv );
if (__wine_spec_init_state == 1) _fini(); if (needs_init) _fini();
ExitProcess( ret ); ExitProcess( ret );
} }

42
dlls/winecrt0/init.c Normal file
View File

@ -0,0 +1,42 @@
/*
* Initialization code for spec files
*
* Copyright 2005 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wine/library.h"
#include "crt0_private.h"
enum init_state __wine_spec_init_state = NO_INIT_DONE;
extern const IMAGE_NT_HEADERS __wine_spec_nt_header;
extern const char __wine_spec_file_name[];
void __wine_spec_init(void)
{
__wine_spec_init_state = DLL_REGISTERED;
__wine_dll_register( &__wine_spec_nt_header, __wine_spec_file_name );
}
void __wine_spec_init_ctor(void)
{
if (__wine_spec_init_state == NO_INIT_DONE) __wine_spec_init();
__wine_spec_init_state = CONSTRUCTORS_DONE;
}

View File

@ -53,6 +53,7 @@ extern int __wine_main_argc;
extern char **__wine_main_argv; extern char **__wine_main_argv;
extern WCHAR **__wine_main_wargv; extern WCHAR **__wine_main_wargv;
extern char **__wine_main_environ; extern char **__wine_main_environ;
extern void __wine_dll_register( const IMAGE_NT_HEADERS *header, const char *filename );
extern void wine_init( int argc, char *argv[], char *error, int error_size ); extern void wine_init( int argc, char *argv[], char *error, int error_size );
/* debugging */ /* debugging */

View File

@ -474,7 +474,7 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
else else
fprintf( outfile, "extern char _end[];\n" ); fprintf( outfile, "extern char _end[];\n" );
fprintf( outfile, "static const char __wine_spec_file_name[] = \"%s\";\n", spec->file_name ); fprintf( outfile, "const char __wine_spec_file_name[] = \"%s\";\n", spec->file_name );
fprintf( outfile, "extern int __wine_spec_data_start[], __wine_spec_exports[];\n\n" ); fprintf( outfile, "extern int __wine_spec_data_start[], __wine_spec_exports[];\n\n" );
output_stub_funcs( outfile, spec ); output_stub_funcs( outfile, spec );
@ -489,13 +489,12 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
/* Output the entry point function */ /* Output the entry point function */
fprintf( outfile, "int __wine_spec_init_state = 0;\n" );
fprintf( outfile, "extern void %s();\n\n", spec->init_func ); fprintf( outfile, "extern void %s();\n\n", spec->init_func );
/* Output the NT header */ /* Output the NT header */
/* this is the IMAGE_NT_HEADERS structure, but we cannot include winnt.h here */ /* this is the IMAGE_NT_HEADERS structure, but we cannot include winnt.h here */
fprintf( outfile, "static const struct image_nt_headers\n{\n" ); fprintf( outfile, "const struct image_nt_headers\n{\n" );
fprintf( outfile, " int Signature;\n" ); fprintf( outfile, " int Signature;\n" );
fprintf( outfile, " struct file_header {\n" ); fprintf( outfile, " struct file_header {\n" );
fprintf( outfile, " short Machine;\n" ); fprintf( outfile, " short Machine;\n" );
@ -539,7 +538,7 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
fprintf( outfile, " struct { const void *VirtualAddress; int Size; } DataDirectory[%d];\n", fprintf( outfile, " struct { const void *VirtualAddress; int Size; } DataDirectory[%d];\n",
IMAGE_NUMBEROF_DIRECTORY_ENTRIES ); IMAGE_NUMBEROF_DIRECTORY_ENTRIES );
fprintf( outfile, " } OptionalHeader;\n" ); fprintf( outfile, " } OptionalHeader;\n" );
fprintf( outfile, "} nt_header = {\n" ); fprintf( outfile, "} __wine_spec_nt_header = {\n" );
fprintf( outfile, " 0x%04x,\n", IMAGE_NT_SIGNATURE ); /* Signature */ fprintf( outfile, " 0x%04x,\n", IMAGE_NT_SIGNATURE ); /* Signature */
switch(target_cpu) switch(target_cpu)
{ {
@ -557,7 +556,7 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
break; break;
} }
fprintf( outfile, " 0, 0, 0, 0,\n" ); fprintf( outfile, " 0, 0, 0, 0,\n" );
fprintf( outfile, " sizeof(nt_header.OptionalHeader),\n" ); /* SizeOfOptionalHeader */ fprintf( outfile, " sizeof(__wine_spec_nt_header.OptionalHeader),\n" ); /* SizeOfOptionalHeader */
fprintf( outfile, " 0x%04x },\n", spec->characteristics ); /* Characteristics */ fprintf( outfile, " 0x%04x },\n", spec->characteristics ); /* Characteristics */
fprintf( outfile, " { 0x%04x,\n", IMAGE_NT_OPTIONAL_HDR_MAGIC ); /* Magic */ fprintf( outfile, " { 0x%04x,\n", IMAGE_NT_OPTIONAL_HDR_MAGIC ); /* Magic */
@ -594,24 +593,6 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
spec->nb_resources ? "sizeof(__wine_spec_resources)" : "0" ); spec->nb_resources ? "sizeof(__wine_spec_resources)" : "0" );
fprintf( outfile, " }\n }\n};\n\n" ); fprintf( outfile, " }\n }\n};\n\n" );
/* Output the DLL constructor */
fprintf( outfile,
"void __wine_spec_init(void)\n"
"{\n"
" extern void __wine_dll_register( const struct image_nt_headers *, const char * );\n"
" __wine_spec_init_state = 1;\n"
" __wine_dll_register( &nt_header, __wine_spec_file_name );\n"
"}\n\n" );
fprintf( outfile,
"void __wine_spec_init_ctor(void)\n"
"{\n"
" if (__wine_spec_init_state) return;\n"
" __wine_spec_init();\n"
" __wine_spec_init_state = 2;\n"
"}\n" );
fprintf( outfile, "#ifndef __GNUC__\n" ); fprintf( outfile, "#ifndef __GNUC__\n" );
fprintf( outfile, "static void __asm__dummy(void) {\n" ); fprintf( outfile, "static void __asm__dummy(void) {\n" );
fprintf( outfile, "#endif\n" ); fprintf( outfile, "#endif\n" );