Commit 0628c7eb authored by Alexandre Julliard's avatar Alexandre Julliard

Moved more of the spec initialization code to the winecrt0 library,

and get rid of implicit kernel32 imports.
parent d672c65a
......@@ -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
......
/*
* 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__ */
/*
* 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 <stdarg.h>
#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;
}
/*
* 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 <stdarg.h>
#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 );
}
/*
* 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 <stdarg.h>
#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 );
}
......@@ -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;
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 (spec->characteristics & IMAGE_FILE_DLL) return "__wine_spec_dll_entry";
if (spec->subsystem == IMAGE_SUBSYSTEM_NATIVE) return "DriverEntry";
return "__wine_spec_exe_entry";
}
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++)
......
......@@ -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 */
......
......@@ -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");
}
}
......
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