From 0628c7eba6f0931d05de918d8a31be7952ee5a81 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 29 Aug 2005 14:16:27 +0000 Subject: [PATCH] Moved more of the spec initialization code to the winecrt0 library, and get rid of implicit kernel32 imports. --- dlls/winecrt0/Makefile.in | 3 + dlls/winecrt0/crt0_private.h | 32 ++++++++++ dlls/winecrt0/dll_entry.c | 41 +++++++++++++ dlls/winecrt0/exe_entry.c | 39 +++++++++++++ dlls/winecrt0/exe_wentry.c | 39 +++++++++++++ tools/winebuild/import.c | 74 +++++------------------- tools/winebuild/spec32.c | 109 +---------------------------------- tools/winegcc/winegcc.c | 2 +- 8 files changed, 172 insertions(+), 167 deletions(-) create mode 100644 dlls/winecrt0/crt0_private.h create mode 100644 dlls/winecrt0/dll_entry.c create mode 100644 dlls/winecrt0/exe_entry.c create mode 100644 dlls/winecrt0/exe_wentry.c diff --git a/dlls/winecrt0/Makefile.in b/dlls/winecrt0/Makefile.in index 72cc5179e03..60a9b0cdf42 100644 --- a/dlls/winecrt0/Makefile.in +++ b/dlls/winecrt0/Makefile.in @@ -6,8 +6,11 @@ MODULE = libwinecrt0.a C_SRCS = \ delay_load.c \ + dll_entry.c \ dll_main.c \ + exe_entry.c \ exe_main.c \ + exe_wentry.c \ exe_wmain.c \ stub.c diff --git a/dlls/winecrt0/crt0_private.h b/dlls/winecrt0/crt0_private.h new file mode 100644 index 00000000000..d4dbea33895 --- /dev/null +++ b/dlls/winecrt0/crt0_private.h @@ -0,0 +1,32 @@ +/* + * crt0 library private definitions + * + * 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 + */ + +#ifndef __WINE_CRT0_PRIVATE_H__ +#define __WINE_CRT0_PRIVATE_H__ + +#ifdef __APPLE__ +static inline void _init(int argc, char **argv, char **envp ) { /* nothing */ } +static inline void _fini(void) { /* nothing */ } +#else +extern void _init(int argc, char **argv, char **envp ); +extern void _fini(void); +#endif + +#endif /* __WINE_CRT0_PRIVATE_H__ */ diff --git a/dlls/winecrt0/dll_entry.c b/dlls/winecrt0/dll_entry.c new file mode 100644 index 00000000000..e3be639d534 --- /dev/null +++ b/dlls/winecrt0/dll_entry.c @@ -0,0 +1,41 @@ +/* + * Default entry point for a dll + * + * 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 +#include "windef.h" +#include "winbase.h" +#include "wine/library.h" +#include "crt0_private.h" + +int __wine_spec_init_state; + +extern BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved ); + +BOOL WINAPI __wine_spec_dll_entry( HINSTANCE inst, DWORD reason, LPVOID reserved ) +{ + BOOL ret; + + if (reason == DLL_PROCESS_ATTACH && __wine_spec_init_state == 1) + _init( __wine_main_argc, __wine_main_argv, __wine_main_environ ); + ret = DllMain( inst, reason, reserved ); + if (reason == DLL_PROCESS_DETACH && __wine_spec_init_state == 1) + _fini(); + return ret; +} diff --git a/dlls/winecrt0/exe_entry.c b/dlls/winecrt0/exe_entry.c new file mode 100644 index 00000000000..df26bfa3a72 --- /dev/null +++ b/dlls/winecrt0/exe_entry.c @@ -0,0 +1,39 @@ +/* + * Default entry point for an exe + * + * 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 +#include "windef.h" +#include "winbase.h" +#include "winternl.h" +#include "wine/library.h" +#include "crt0_private.h" + +int __wine_spec_init_state; + +extern int main( int argc, char *argv[] ); + +DWORD WINAPI __wine_spec_exe_entry( PEB *peb ) +{ + DWORD ret; + if (__wine_spec_init_state == 1) _init( __wine_main_argc, __wine_main_argv, __wine_main_environ ); + ret = main( __wine_main_argc, __wine_main_argv ); + if (__wine_spec_init_state == 1) _fini(); + ExitProcess( ret ); +} diff --git a/dlls/winecrt0/exe_wentry.c b/dlls/winecrt0/exe_wentry.c new file mode 100644 index 00000000000..b79045a557b --- /dev/null +++ b/dlls/winecrt0/exe_wentry.c @@ -0,0 +1,39 @@ +/* + * Default entry point for a Unicode exe + * + * 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 +#include "windef.h" +#include "winbase.h" +#include "winternl.h" +#include "wine/library.h" +#include "crt0_private.h" + +int __wine_spec_init_state; + +extern int wmain( int argc, WCHAR *argv[] ); + +DWORD WINAPI __wine_spec_exe_wentry( PEB *peb ) +{ + DWORD ret; + if (__wine_spec_init_state == 1) _init( __wine_main_argc, __wine_main_argv, __wine_main_environ ); + ret = wmain( __wine_main_argc, __wine_main_wargv ); + if (__wine_spec_init_state == 1) _fini(); + ExitProcess( ret ); +} diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c index b4827121144..989e5bb0fff 100644 --- a/tools/winebuild/import.c +++ b/tools/winebuild/import.c @@ -454,31 +454,6 @@ static void add_import_func( struct import *imp, ORDDEF *func ) if (imp->delay) total_delayed++; } -/* add a symbol to the extra list, but only if needed */ -static int add_extra_symbol( const char **extras, int *count, const char *name, const DLLSPEC *spec ) -{ - int i; - - if (!find_name( name, &undef_symbols )) - { - /* check if the symbol is being exported by this dll */ - for (i = 0; i < spec->nb_entry_points; i++) - { - ORDDEF *odp = &spec->entry_points[i]; - if (odp->type == TYPE_STDCALL || - odp->type == TYPE_CDECL || - odp->type == TYPE_VARARGS || - odp->type == TYPE_EXTERN) - { - if (odp->name && !strcmp( odp->name, name )) return 0; - } - } - extras[*count] = name; - (*count)++; - } - return 1; -} - /* check if the spec file exports any stubs */ static int has_stubs( const DLLSPEC *spec ) { @@ -491,35 +466,21 @@ static int has_stubs( const DLLSPEC *spec ) return 0; } -/* add the extra undefined symbols that will be contained in the generated spec file itself */ -static void add_extra_undef_symbols( const DLLSPEC *spec ) +/* get the default entry point for a given spec file */ +static const char *get_default_entry_point( const DLLSPEC *spec ) { - const char *extras[10]; - int i, count = 0; - int kernel_imports = 0; + if (spec->characteristics & IMAGE_FILE_DLL) return "__wine_spec_dll_entry"; + if (spec->subsystem == IMAGE_SUBSYSTEM_NATIVE) return "DriverEntry"; + return "__wine_spec_exe_entry"; +} - sort_names( &undef_symbols ); - - /* add symbols that will be contained in the spec file itself */ - if (!(spec->characteristics & IMAGE_FILE_DLL)) - { - switch (spec->subsystem) - { - case IMAGE_SUBSYSTEM_WINDOWS_GUI: - case IMAGE_SUBSYSTEM_WINDOWS_CUI: - kernel_imports += add_extra_symbol( extras, &count, "ExitProcess", spec ); - break; - } - } - - /* make sure we import the dlls that contain these functions */ - if (kernel_imports) add_import_dll( "kernel32", NULL ); - - if (count) - { - for (i = 0; i < count; i++) add_name( &undef_symbols, extras[i] ); - sort_names( &undef_symbols ); - } +/* add the extra undefined symbols that will be contained in the generated spec file itself */ +static void add_extra_undef_symbols( DLLSPEC *spec ) +{ + if (!spec->init_func) spec->init_func = xstrdup( get_default_entry_point(spec) ); + add_extra_ld_symbol( spec->init_func ); + if (has_stubs( spec )) add_extra_ld_symbol( "__wine_spec_unimplemented_stub" ); + if (nb_delayed) add_extra_ld_symbol( "__wine_spec_delay_load" ); } /* check if a given imported dll is not needed, taking forwards into account */ @@ -588,13 +549,7 @@ void read_undef_symbols( DLLSPEC *spec, char **argv ) if (!argv[0]) return; - if (spec->init_func) add_extra_ld_symbol( spec->init_func ); - else if (spec->characteristics & IMAGE_FILE_DLL) add_extra_ld_symbol( "DllMain" ); - else if (spec->subsystem == IMAGE_SUBSYSTEM_NATIVE) add_extra_ld_symbol( "DriverEntry "); - else add_extra_ld_symbol( "main" ); - - if (has_stubs( spec )) add_extra_ld_symbol( "__wine_spec_unimplemented_stub" ); - if (nb_delayed) add_extra_ld_symbol( "__wine_spec_delay_load" ); + add_extra_undef_symbols( spec ); strcpy( name_prefix, asm_name("") ); prefix_len = strlen( name_prefix ); @@ -640,7 +595,6 @@ int resolve_imports( DLLSPEC *spec ) { unsigned int i, j, removed; - add_extra_undef_symbols( spec ); remove_ignored_symbols(); for (i = 0; i < nb_imports; i++) diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c index 966165ad12a..56f9883c5bb 100644 --- a/tools/winebuild/spec32.c +++ b/tools/winebuild/spec32.c @@ -443,7 +443,6 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec ) int exports_size = 0; int nr_exports, nr_imports, nr_delayed; unsigned int page_size = get_page_size(); - const char *init_func = spec->init_func; nr_exports = spec->base <= spec->limit ? spec->limit - spec->base + 1 : 0; resolve_imports( spec ); @@ -478,11 +477,6 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec ) fprintf( outfile, "static const char __wine_spec_file_name[] = \"%s\";\n", spec->file_name ); fprintf( outfile, "extern int __wine_spec_data_start[], __wine_spec_exports[];\n\n" ); - if (target_cpu == CPU_x86) - fprintf( outfile, "#define __stdcall __attribute__((__stdcall__))\n\n" ); - else - fprintf( outfile, "#define __stdcall\n\n" ); - output_stub_funcs( outfile, spec ); /* Output the DLL imports */ @@ -495,105 +489,8 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec ) /* Output the entry point function */ - fprintf( outfile, "static int __wine_spec_init_state;\n" ); - fprintf( outfile, "extern int __wine_main_argc;\n" ); - fprintf( outfile, "extern char **__wine_main_argv;\n" ); - fprintf( outfile, "extern char **__wine_main_environ;\n" ); - if (target_platform == PLATFORM_APPLE) - { - fprintf( outfile, "extern _dyld_func_lookup(char *, void *);" ); - fprintf( outfile, "static void __wine_spec_hidden_init(int argc, char** argv, char** envp)\n" ); - fprintf( outfile, "{\n" ); - fprintf( outfile, " void (*init)(void);\n" ); - fprintf( outfile, " _dyld_func_lookup(\"__dyld_make_delayed_module_initializer_calls\", (unsigned long *)&init);\n" ); - fprintf( outfile, " init();\n" ); - fprintf( outfile, "}\n" ); - fprintf( outfile, "static void __wine_spec_hidden_fini()\n" ); - fprintf( outfile, "{\n" ); - fprintf( outfile, " void (*fini)(void);\n" ); - fprintf( outfile, " _dyld_func_lookup(\"__dyld_mod_term_funcs\", (unsigned long *)&fini);\n" ); - fprintf( outfile, " fini();\n" ); - fprintf( outfile, "}\n" ); - fprintf( outfile, "#define _init __wine_spec_hidden_init\n" ); - fprintf( outfile, "#define _fini __wine_spec_hidden_fini\n" ); - } - else - { - fprintf( outfile, "extern void _init(int, char**, char**);\n" ); - fprintf( outfile, "extern void _fini();\n" ); - } - - if (spec->characteristics & IMAGE_FILE_DLL) - { - if (!init_func) init_func = "DllMain"; - fprintf( outfile, "extern int __stdcall %s( void*, unsigned int, void* );\n\n", init_func ); - fprintf( outfile, - "static int __stdcall __wine_dll_main( void *inst, unsigned int reason, void *reserved )\n" - "{\n" - " int ret;\n" - " if (reason == %d && __wine_spec_init_state == 1)\n" - " _init( __wine_main_argc, __wine_main_argv, __wine_main_environ );\n" - " ret = %s( inst, reason, reserved );\n" - " if (reason == %d && __wine_spec_init_state == 1)\n" - " _fini();\n" - " return ret;\n}\n", - DLL_PROCESS_ATTACH, init_func, DLL_PROCESS_DETACH ); - init_func = "__wine_dll_main"; - } - else switch(spec->subsystem) - { - case IMAGE_SUBSYSTEM_NATIVE: - if (!init_func) init_func = "DriverEntry"; - fprintf( outfile, "extern int __stdcall %s( void*, void* );\n\n", init_func ); - fprintf( outfile, - "static int __stdcall __wine_driver_entry( void *obj, void *path )\n" - "{\n" - " int ret;\n" - " if (__wine_spec_init_state == 1)\n" - " _init( __wine_main_argc, __wine_main_argv, __wine_main_environ );\n" - " ret = %s( obj, path );\n" - " if (__wine_spec_init_state == 1) _fini();\n" - " return ret;\n" - "}\n", - init_func ); - init_func = "__wine_driver_entry"; - break; - case IMAGE_SUBSYSTEM_WINDOWS_GUI: - case IMAGE_SUBSYSTEM_WINDOWS_CUI: - if (!init_func) init_func = "main"; - else if (!strcmp( init_func, "wmain" )) /* FIXME: temp hack for crt0 support */ - { - fprintf( outfile, "extern int wmain( int argc, unsigned short *argv[] );\n" ); - fprintf( outfile, "extern unsigned short **__wine_main_wargv;\n" ); - fprintf( outfile, - "\nextern void __stdcall ExitProcess(unsigned int);\n" - "static void __wine_exe_wmain(void)\n" - "{\n" - " int ret;\n" - " if (__wine_spec_init_state == 1)\n" - " _init( __wine_main_argc, __wine_main_argv, __wine_main_environ );\n" - " ret = wmain( __wine_main_argc, __wine_main_wargv );\n" - " if (__wine_spec_init_state == 1) _fini();\n" - " ExitProcess( ret );\n" - "}\n\n" ); - init_func = "__wine_exe_wmain"; - break; - } - fprintf( outfile, "extern int %s( int argc, char *argv[] );\n", init_func ); - fprintf( outfile, - "\nextern void __stdcall ExitProcess(unsigned int);\n" - "static void __wine_exe_main(void)\n" - "{\n" - " int ret;\n" - " if (__wine_spec_init_state == 1)\n" - " _init( __wine_main_argc, __wine_main_argv, __wine_main_environ );\n" - " ret = %s( __wine_main_argc, __wine_main_argv );\n" - " if (__wine_spec_init_state == 1) _fini();\n" - " ExitProcess( ret );\n" - "}\n\n", init_func ); - init_func = "__wine_exe_main"; - break; - } + fprintf( outfile, "int __wine_spec_init_state;\n" ); + fprintf( outfile, "extern void %s();\n\n", spec->init_func ); /* Output the NT header */ @@ -666,7 +563,7 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec ) fprintf( outfile, " { 0x%04x,\n", IMAGE_NT_OPTIONAL_HDR_MAGIC ); /* Magic */ fprintf( outfile, " 0, 0,\n" ); /* Major/MinorLinkerVersion */ fprintf( outfile, " 0, 0, 0,\n" ); /* SizeOfCode/Data */ - fprintf( outfile, " %s,\n", init_func ); /* AddressOfEntryPoint */ + fprintf( outfile, " %s,\n", spec->init_func ); /* AddressOfEntryPoint */ fprintf( outfile, " 0, __wine_spec_data_start,\n" ); /* BaseOfCode/Data */ fprintf( outfile, " __wine_spec_pe_header,\n" ); /* ImageBase */ fprintf( outfile, " %u,\n", page_size ); /* SectionAlignment */ diff --git a/tools/winegcc/winegcc.c b/tools/winegcc/winegcc.c index 30bcb337b70..502f8604064 100644 --- a/tools/winegcc/winegcc.c +++ b/tools/winegcc/winegcc.c @@ -563,7 +563,7 @@ static void build(struct options* opts) if (opts->unicode_app) { strarray_add(spec_args, "--entry"); - strarray_add(spec_args, "wmain"); + strarray_add(spec_args, "__wine_spec_exe_wentry"); } }