forked from Mirrors/wine-wine
If supported by the linker, prevent the ELF loader from calling the
dll constructors at load time and call them from the dll entry point instead.oldstable
parent
925a2f936e
commit
3604824262
|
@ -13649,6 +13649,72 @@ echo "${ECHO_T}$ac_cv_c_dll_zdefs" >&6
|
|||
LDDLL="$LDDLL,-z,defs"
|
||||
fi
|
||||
|
||||
echo "$as_me:$LINENO: checking whether the linker accepts -init and -fini" >&5
|
||||
echo $ECHO_N "checking whether the linker accepts -init and -fini... $ECHO_C" >&6
|
||||
if test "${ac_cv_c_dll_init_fini+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
ac_wine_try_cflags_saved=$CFLAGS
|
||||
CFLAGS="$CFLAGS -fPIC -shared -Wl,-Bsymbolic,-init,__wine_spec_init,-fini,__wine_spec_fini"
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext conftest$ac_exeext
|
||||
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
|
||||
(eval $ac_link) 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; } &&
|
||||
{ ac_try='test -s conftest$ac_exeext'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; }; then
|
||||
ac_cv_c_dll_init_fini="yes"
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
ac_cv_c_dll_init_fini="no"
|
||||
fi
|
||||
rm -f conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
CFLAGS=$ac_wine_try_cflags_saved
|
||||
fi
|
||||
echo "$as_me:$LINENO: result: $ac_cv_c_dll_init_fini" >&5
|
||||
echo "${ECHO_T}$ac_cv_c_dll_init_fini" >&6
|
||||
if test "$ac_cv_c_dll_init_fini" = "yes"
|
||||
then
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define HAVE_LINKER_INIT_FINI 1
|
||||
_ACEOF
|
||||
|
||||
LDDLL="$LDDLL,-init,__wine_spec_init,-fini,__wine_spec_fini"
|
||||
fi
|
||||
|
||||
echo "$as_me:$LINENO: checking whether the linker accepts --export-dynamic" >&5
|
||||
echo $ECHO_N "checking whether the linker accepts --export-dynamic... $ECHO_C" >&6
|
||||
if test "${ac_cv_c_export_dynamic+set}" = set; then
|
||||
|
|
|
@ -880,6 +880,15 @@ case $host_os in
|
|||
LDDLL="$LDDLL,-z,defs"
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([whether the linker accepts -init and -fini], ac_cv_c_dll_init_fini,
|
||||
[WINE_TRY_CFLAGS([-fPIC -shared -Wl,-Bsymbolic,-init,__wine_spec_init,-fini,__wine_spec_fini],
|
||||
ac_cv_c_dll_init_fini="yes",ac_cv_c_dll_init_fini="no")])
|
||||
if test "$ac_cv_c_dll_init_fini" = "yes"
|
||||
then
|
||||
AC_DEFINE(HAVE_LINKER_INIT_FINI,1,[Define if the linker supports renaming the init and fini functions])
|
||||
LDDLL="$LDDLL,-init,__wine_spec_init,-fini,__wine_spec_fini"
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([whether the linker accepts --export-dynamic], ac_cv_c_export_dynamic,
|
||||
[WINE_TRY_CFLAGS([-fPIC -Wl,--export-dynamic],
|
||||
ac_cv_c_export_dynamic="yes",ac_cv_c_export_dynamic="no")])
|
||||
|
|
|
@ -618,9 +618,12 @@ static BOOL process_init( char *argv[], char **environ )
|
|||
RTL_USER_PROCESS_PARAMETERS *params;
|
||||
PEB *peb = NtCurrentTeb()->Peb;
|
||||
HANDLE hstdin, hstdout, hstderr;
|
||||
extern void __wine_dbg_kernel32_init(void);
|
||||
|
||||
PTHREAD_Init();
|
||||
|
||||
__wine_dbg_kernel32_init(); /* hack: register debug channels early */
|
||||
|
||||
setbuf(stdout,NULL);
|
||||
setbuf(stderr,NULL);
|
||||
setlocale(LC_CTYPE,"");
|
||||
|
|
|
@ -1956,8 +1956,10 @@ void __wine_process_init( int argc, char *argv[] )
|
|||
NTSTATUS status;
|
||||
ANSI_STRING func_name;
|
||||
void (* DECLSPEC_NORETURN init_func)();
|
||||
extern void __wine_dbg_ntdll_init(void);
|
||||
|
||||
thread_init();
|
||||
__wine_dbg_ntdll_init(); /* hack: register debug channels early */
|
||||
|
||||
/* setup the load callback and create ntdll modref */
|
||||
wine_dll_set_callback( load_builtin_callback );
|
||||
|
|
|
@ -461,6 +461,11 @@
|
|||
*/
|
||||
#undef HAVE_LIBXXSHM
|
||||
|
||||
/*
|
||||
Define if the linker supports renaming the init
|
||||
and fini functions */
|
||||
#undef HAVE_LINKER_INIT_FINI
|
||||
|
||||
/*
|
||||
Define to 1 if you have the <link.h>
|
||||
header file. */
|
||||
|
|
|
@ -491,7 +491,6 @@ void BuildSpec32File( FILE *outfile )
|
|||
int nr_exports, nr_imports, nr_resources;
|
||||
int characteristics, subsystem;
|
||||
DWORD page_size;
|
||||
char constructor[100];
|
||||
|
||||
#ifdef HAVE_GETPAGESIZE
|
||||
page_size = getpagesize();
|
||||
|
@ -569,30 +568,53 @@ void BuildSpec32File( FILE *outfile )
|
|||
|
||||
nr_resources = output_resources( outfile );
|
||||
|
||||
/* Output LibMain function */
|
||||
/* Output the entry point function */
|
||||
|
||||
fprintf( outfile, "extern int __wine_main_argc;\n" );
|
||||
fprintf( outfile, "extern char **__wine_main_argv;\n" );
|
||||
fprintf( outfile, "extern char **__wine_main_environ;\n" );
|
||||
fprintf( outfile, "extern unsigned short **__wine_main_wargv;\n" );
|
||||
fprintf( outfile, "extern void _init(int, char**, char**);\n" );
|
||||
fprintf( outfile, "extern void _fini();\n" );
|
||||
|
||||
characteristics = subsystem = 0;
|
||||
switch(SpecMode)
|
||||
{
|
||||
case SPEC_MODE_DLL:
|
||||
if (init_func) fprintf( outfile, "extern void %s();\n", init_func );
|
||||
if (init_func)
|
||||
fprintf( outfile, "extern int __stdcall %s( void*, unsigned int, void* );\n\n", init_func );
|
||||
else
|
||||
{
|
||||
fprintf( outfile, "#ifdef __GNUC__\n" );
|
||||
fprintf( outfile, "# ifdef __APPLE__\n" );
|
||||
fprintf( outfile, "extern void DllMain() __attribute__((weak_import));\n" );
|
||||
fprintf( outfile, "extern int __stdcall DllMain( void*, unsigned int, void* ) __attribute__((weak_import));\n" );
|
||||
fprintf( outfile, "# else\n" );
|
||||
fprintf( outfile, "extern void DllMain() __attribute__((weak));\n" );
|
||||
fprintf( outfile, "extern int __stdcall DllMain( void*, unsigned int, void* ) __attribute__((weak));\n" );
|
||||
fprintf( outfile, "# endif\n" );
|
||||
fprintf( outfile, "#else\n" );
|
||||
fprintf( outfile, "extern void DllMain();\n" );
|
||||
fprintf( outfile, "extern int __stdcall DllMain( void*, unsigned int, void* );\n" );
|
||||
fprintf( outfile, "static void __asm__dummy_dllmain(void)" );
|
||||
fprintf( outfile, " { asm(\".weak " __ASM_NAME("DllMain") "\"); }\n" );
|
||||
fprintf( outfile, "#endif\n" );
|
||||
fprintf( outfile, "#endif\n\n" );
|
||||
init_func = "DllMain";
|
||||
}
|
||||
#ifdef HAVE_LINKER_INIT_FINI
|
||||
fprintf( outfile,
|
||||
"static int __stdcall __wine_dll_main( void *inst, unsigned int reason, void *reserved )\n"
|
||||
"{\n"
|
||||
" int ret;\n"
|
||||
" if (reason == %d) _init( __wine_main_argc, __wine_main_argv, __wine_main_environ );\n"
|
||||
" ret = %s ? %s( inst, reason, reserved ) : 1;\n"
|
||||
" if (reason == %d) _fini();\n"
|
||||
" return ret;\n"
|
||||
"}\n",
|
||||
DLL_PROCESS_ATTACH, init_func, init_func, DLL_PROCESS_DETACH );
|
||||
init_func = "__wine_dll_main";
|
||||
#endif
|
||||
characteristics = IMAGE_FILE_DLL;
|
||||
break;
|
||||
case SPEC_MODE_GUIEXE:
|
||||
case SPEC_MODE_GUIEXE_UNICODE:
|
||||
if (!init_func) init_func = "WinMain";
|
||||
fprintf( outfile,
|
||||
"\ntypedef struct {\n"
|
||||
|
@ -604,8 +626,6 @@ void BuildSpec32File( FILE *outfile )
|
|||
" char *lpReserved2;\n"
|
||||
" void *hStdInput, *hStdOutput, *hStdError;\n"
|
||||
"} STARTUPINFOA;\n"
|
||||
"int _ARGC;\n"
|
||||
"char **_ARGV;\n"
|
||||
"extern int __stdcall %s(void *,void *,char *,int);\n"
|
||||
"extern char * __stdcall GetCommandLineA(void);\n"
|
||||
"extern void * __stdcall GetModuleHandleA(char *);\n"
|
||||
|
@ -613,11 +633,9 @@ void BuildSpec32File( FILE *outfile )
|
|||
"extern void __stdcall ExitProcess(unsigned int);\n"
|
||||
"static void __wine_exe_main(void)\n"
|
||||
"{\n"
|
||||
" extern int __wine_main_argc;\n"
|
||||
" extern char **__wine_main_argv;\n"
|
||||
" STARTUPINFOA info;\n"
|
||||
" char *cmdline = GetCommandLineA();\n"
|
||||
" int bcount=0, in_quotes=0;\n"
|
||||
" int ret, bcount=0, in_quotes=0;\n"
|
||||
" while (*cmdline) {\n"
|
||||
" if ((*cmdline=='\\t' || *cmdline==' ') && !in_quotes) break;\n"
|
||||
" else if (*cmdline=='\\\\') bcount++;\n"
|
||||
|
@ -631,56 +649,14 @@ void BuildSpec32File( FILE *outfile )
|
|||
" while (*cmdline=='\\t' || *cmdline==' ') cmdline++;\n"
|
||||
" GetStartupInfoA( &info );\n"
|
||||
" if (!(info.dwFlags & 1)) info.wShowWindow = 1;\n"
|
||||
" _ARGC = __wine_main_argc;\n"
|
||||
" _ARGV = __wine_main_argv;\n"
|
||||
" ExitProcess( %s( GetModuleHandleA(0), 0, cmdline, info.wShowWindow ) );\n"
|
||||
"}\n\n", init_func, init_func );
|
||||
init_func = "__wine_exe_main";
|
||||
subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
|
||||
break;
|
||||
case SPEC_MODE_GUIEXE_UNICODE:
|
||||
if (!init_func) init_func = "WinMain";
|
||||
fprintf( outfile,
|
||||
"\ntypedef unsigned short WCHAR;\n"
|
||||
"typedef struct {\n"
|
||||
" unsigned int cb;\n"
|
||||
" char *lpReserved, *lpDesktop, *lpTitle;\n"
|
||||
" unsigned int dwX, dwY, dwXSize, dwYSize;\n"
|
||||
" unsigned int dwXCountChars, dwYCountChars, dwFillAttribute, dwFlags;\n"
|
||||
" unsigned short wShowWindow, cbReserved2;\n"
|
||||
" char *lpReserved2;\n"
|
||||
" void *hStdInput, *hStdOutput, *hStdError;\n"
|
||||
"} STARTUPINFOA;\n"
|
||||
"int _ARGC;\n"
|
||||
"WCHAR **_ARGV;\n"
|
||||
"extern int __stdcall %s(void *,void *,char *,int);\n"
|
||||
"extern char * __stdcall GetCommandLineA(void);\n"
|
||||
"extern void * __stdcall GetModuleHandleA(char *);\n"
|
||||
"extern void __stdcall GetStartupInfoA(STARTUPINFOA *);\n"
|
||||
"extern void __stdcall ExitProcess(unsigned int);\n"
|
||||
"static void __wine_exe_main(void)\n"
|
||||
"{\n"
|
||||
" extern int __wine_main_argc;\n"
|
||||
" extern WCHAR **__wine_main_wargv;\n"
|
||||
" STARTUPINFOA info;\n"
|
||||
" char *cmdline = GetCommandLineA();\n"
|
||||
" int bcount=0, in_quotes=0;\n"
|
||||
" while (*cmdline) {\n"
|
||||
" if ((*cmdline=='\\t' || *cmdline==' ') && !in_quotes) break;\n"
|
||||
" else if (*cmdline=='\\\\') bcount++;\n"
|
||||
" else if (*cmdline=='\\\"') {\n"
|
||||
" if ((bcount & 1)==0) in_quotes=!in_quotes;\n"
|
||||
" bcount=0;\n"
|
||||
" }\n"
|
||||
" else bcount=0;\n"
|
||||
" cmdline++;\n"
|
||||
" }\n"
|
||||
" while (*cmdline=='\\t' || *cmdline==' ') cmdline++;\n"
|
||||
" GetStartupInfoA( &info );\n"
|
||||
" if (!(info.dwFlags & 1)) info.wShowWindow = 1;\n"
|
||||
" _ARGC = __wine_main_argc;\n"
|
||||
" _ARGV = __wine_main_wargv;\n"
|
||||
" ExitProcess( %s( GetModuleHandleA(0), 0, cmdline, info.wShowWindow ) );\n"
|
||||
#ifdef HAVE_LINKER_INIT_FINI
|
||||
" _init( __wine_main_argc, __wine_main_argv, __wine_main_environ );\n"
|
||||
" ret = %s( GetModuleHandleA(0), 0, cmdline, info.wShowWindow );\n"
|
||||
" _fini();\n"
|
||||
#else
|
||||
" ret = %s( GetModuleHandleA(0), 0, cmdline, info.wShowWindow );\n"
|
||||
#endif
|
||||
" ExitProcess( ret );\n"
|
||||
"}\n\n", init_func, init_func );
|
||||
init_func = "__wine_exe_main";
|
||||
subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
|
||||
|
@ -688,17 +664,19 @@ void BuildSpec32File( FILE *outfile )
|
|||
case SPEC_MODE_CUIEXE:
|
||||
if (!init_func) init_func = "main";
|
||||
fprintf( outfile,
|
||||
"\nint _ARGC;\n"
|
||||
"char **_ARGV;\n"
|
||||
"extern void __stdcall ExitProcess(int);\n"
|
||||
"\nextern void __stdcall ExitProcess(int);\n"
|
||||
"static void __wine_exe_main(void)\n"
|
||||
"{\n"
|
||||
" int ret;\n"
|
||||
" extern int %s( int argc, char *argv[] );\n"
|
||||
" extern int __wine_main_argc;\n"
|
||||
" extern char **__wine_main_argv;\n"
|
||||
" _ARGC = __wine_main_argc;\n"
|
||||
" _ARGV = __wine_main_argv;\n"
|
||||
" ExitProcess( %s( _ARGC, _ARGV ) );\n"
|
||||
#ifdef HAVE_LINKER_INIT_FINI
|
||||
" _init( __wine_main_argc, __wine_main_argv, __wine_main_environ );\n"
|
||||
" ret = %s( __wine_main_argc, __wine_main_argv );\n"
|
||||
" _fini();\n"
|
||||
#else
|
||||
" ret = %s( __wine_main_argc, __wine_main_argv );\n"
|
||||
#endif
|
||||
" ExitProcess( ret );\n"
|
||||
"}\n\n", init_func, init_func );
|
||||
init_func = "__wine_exe_main";
|
||||
subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI;
|
||||
|
@ -706,18 +684,19 @@ void BuildSpec32File( FILE *outfile )
|
|||
case SPEC_MODE_CUIEXE_UNICODE:
|
||||
if (!init_func) init_func = "wmain";
|
||||
fprintf( outfile,
|
||||
"\ntypedef unsigned short WCHAR;\n"
|
||||
"int _ARGC;\n"
|
||||
"WCHAR **_ARGV;\n"
|
||||
"extern void __stdcall ExitProcess(int);\n"
|
||||
"\nextern void __stdcall ExitProcess(int);\n"
|
||||
"static void __wine_exe_main(void)\n"
|
||||
"{\n"
|
||||
" extern int %s( int argc, WCHAR *argv[] );\n"
|
||||
" extern int __wine_main_argc;\n"
|
||||
" extern WCHAR **__wine_main_wargv;\n"
|
||||
" _ARGC = __wine_main_argc;\n"
|
||||
" _ARGV = __wine_main_wargv;\n"
|
||||
" ExitProcess( %s( _ARGC, _ARGV ) );\n"
|
||||
" int ret;\n"
|
||||
" extern int %s( int argc, unsigned short *argv[] );\n"
|
||||
#ifdef HAVE_LINKER_INIT_FINI
|
||||
" _init( __wine_main_argc, __wine_main_argv, __wine_main_environ );\n"
|
||||
" ret = %s( __wine_main_argc, __wine_main_wargv );\n"
|
||||
" _fini();\n"
|
||||
#else
|
||||
" ret = %s( __wine_main_argc, __wine_main_wargv );\n"
|
||||
#endif
|
||||
" ExitProcess( ret );\n"
|
||||
"}\n\n", init_func, init_func );
|
||||
init_func = "__wine_exe_main";
|
||||
subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI;
|
||||
|
@ -787,7 +766,7 @@ void BuildSpec32File( FILE *outfile )
|
|||
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 ? init_func : "DllMain" ); /* AddressOfEntryPoint */
|
||||
fprintf( outfile, " %s,\n", init_func ); /* AddressOfEntryPoint */
|
||||
fprintf( outfile, " 0, __wine_spec_data_start,\n" ); /* BaseOfCode/Data */
|
||||
fprintf( outfile, " __wine_spec_pe_header,\n" ); /* ImageBase */
|
||||
fprintf( outfile, " %ld,\n", page_size ); /* SectionAlignment */
|
||||
|
@ -818,17 +797,16 @@ void BuildSpec32File( FILE *outfile )
|
|||
|
||||
/* Output the DLL constructor */
|
||||
|
||||
sprintf( constructor, "__wine_spec_%s_init", make_c_identifier(dll_file_name) );
|
||||
output_dll_init( outfile, constructor, NULL );
|
||||
|
||||
#ifndef HAVE_LINKER_INIT_FINI
|
||||
output_dll_init( outfile, "__wine_spec_init", NULL );
|
||||
#endif
|
||||
fprintf( outfile,
|
||||
"void %s(void)\n"
|
||||
"void __wine_spec_init(void)\n"
|
||||
"{\n"
|
||||
" extern void __wine_dll_register( const struct image_nt_headers *, const char * );\n"
|
||||
" extern void *__wine_dbg_register( char * const *, int );\n"
|
||||
" __wine_dll_register( &nt_header, \"%s\" );\n"
|
||||
"}\n",
|
||||
constructor, dll_file_name );
|
||||
dll_file_name );
|
||||
}
|
||||
|
||||
|
||||
|
@ -942,8 +920,8 @@ void BuildDebugFile( FILE *outfile, const char *srcdir, char **argv )
|
|||
|
||||
fprintf( outfile,
|
||||
"#ifdef __GNUC__\n"
|
||||
"static void __wine_dbg_%s_init(void) __attribute__((constructor));\n"
|
||||
"static void __wine_dbg_%s_fini(void) __attribute__((destructor));\n"
|
||||
"void __wine_dbg_%s_init(void) __attribute__((constructor));\n"
|
||||
"void __wine_dbg_%s_fini(void) __attribute__((destructor));\n"
|
||||
"#else\n"
|
||||
"static void __asm__dummy_dll_init(void) {\n",
|
||||
prefix, prefix );
|
||||
|
@ -971,21 +949,15 @@ void BuildDebugFile( FILE *outfile, const char *srcdir, char **argv )
|
|||
#else
|
||||
#error You need to define the DLL constructor for your architecture
|
||||
#endif
|
||||
fprintf( outfile, "}\n#endif /* defined(__GNUC__) */\n" );
|
||||
fprintf( outfile, "}\n#endif /* defined(__GNUC__) */\n\n" );
|
||||
|
||||
fprintf( outfile,
|
||||
"\n#ifdef __GNUC__\n"
|
||||
"static\n"
|
||||
"#endif\n"
|
||||
"void __wine_dbg_%s_init(void)\n"
|
||||
"{\n"
|
||||
" extern void *__wine_dbg_register( char * const *, int );\n"
|
||||
" debug_registration = __wine_dbg_register( debug_channels, %d );\n"
|
||||
"}\n", prefix, nr_debug );
|
||||
" if (!debug_registration) debug_registration = __wine_dbg_register( debug_channels, %d );\n"
|
||||
"}\n\n", prefix, nr_debug );
|
||||
fprintf( outfile,
|
||||
"\n#ifdef __GNUC__\n"
|
||||
"static\n"
|
||||
"#endif\n"
|
||||
"void __wine_dbg_%s_fini(void)\n"
|
||||
"{\n"
|
||||
" extern void __wine_dbg_unregister( void* );\n"
|
||||
|
|
Loading…
Reference in New Issue