From b6b180a16d6e8945421ec151ee174a59ea331fe5 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 25 Aug 2005 15:27:44 +0000 Subject: [PATCH] Moved the implementation of spec file stubs to the winecrt0 library. --- dlls/activeds/Makefile.in | 1 + dlls/d3dim/Makefile.in | 1 + dlls/d3drm/Makefile.in | 1 + dlls/msnet32/Makefile.in | 1 + dlls/msvcrt20/Makefile.in | 2 +- dlls/msvcrt40/Makefile.in | 2 +- dlls/ntdll/exception.c | 21 +++++++++++++++++++++ dlls/oleacc/Makefile.in | 1 + dlls/sti/Makefile.in | 1 + dlls/url/Makefile.in | 1 + dlls/winecrt0/Makefile.in | 3 ++- dlls/winecrt0/stub.c | 33 +++++++++++++++++++++++++++++++++ tools/winebuild/import.c | 27 ++++++++++++++++----------- tools/winebuild/spec32.c | 37 +++++++++---------------------------- 14 files changed, 90 insertions(+), 42 deletions(-) create mode 100644 dlls/winecrt0/stub.c diff --git a/dlls/activeds/Makefile.in b/dlls/activeds/Makefile.in index 824e2d9a67c..b319cab07ab 100644 --- a/dlls/activeds/Makefile.in +++ b/dlls/activeds/Makefile.in @@ -4,6 +4,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = activeds.dll IMPORTLIB = libactiveds.$(IMPLIBEXT) +IMPORTS = kernel32 C_SRCS = activeds_main.c diff --git a/dlls/d3dim/Makefile.in b/dlls/d3dim/Makefile.in index 21886c901ff..fa6752da3ed 100644 --- a/dlls/d3dim/Makefile.in +++ b/dlls/d3dim/Makefile.in @@ -4,6 +4,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = d3dim.dll IMPORTLIB = libd3dim.$(IMPLIBEXT) +IMPORTS = kernel32 C_SRCS = d3dim_main.c diff --git a/dlls/d3drm/Makefile.in b/dlls/d3drm/Makefile.in index 81adee3fc25..910f0515b08 100644 --- a/dlls/d3drm/Makefile.in +++ b/dlls/d3drm/Makefile.in @@ -4,6 +4,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = d3drm.dll IMPORTLIB = libd3drm.$(IMPLIBEXT) +IMPORTS = kernel32 C_SRCS = d3drm_main.c diff --git a/dlls/msnet32/Makefile.in b/dlls/msnet32/Makefile.in index 4e5fe3a2ad2..8023679ec5f 100644 --- a/dlls/msnet32/Makefile.in +++ b/dlls/msnet32/Makefile.in @@ -3,6 +3,7 @@ TOPOBJDIR = ../.. SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = msnet32.dll +IMPORTS = kernel32 C_SRCS = msnet_main.c diff --git a/dlls/msvcrt20/Makefile.in b/dlls/msvcrt20/Makefile.in index 47961c6f41f..0cda8754f0f 100644 --- a/dlls/msvcrt20/Makefile.in +++ b/dlls/msvcrt20/Makefile.in @@ -5,7 +5,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = msvcrt20.dll IMPORTLIB = libmsvcrt20.$(IMPLIBEXT) -IMPORTS = msvcrt +IMPORTS = msvcrt kernel32 EXTRALIBS = $(LIBUNICODE) C_SRCS = msvcrt20.c diff --git a/dlls/msvcrt40/Makefile.in b/dlls/msvcrt40/Makefile.in index 2efce54539f..2a70e62e91e 100644 --- a/dlls/msvcrt40/Makefile.in +++ b/dlls/msvcrt40/Makefile.in @@ -5,7 +5,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = msvcrt40.dll IMPORTLIB = libmsvcrt40.$(IMPLIBEXT) -IMPORTS = msvcrt +IMPORTS = msvcrt kernel32 C_SRCS = msvcrt40.c diff --git a/dlls/ntdll/exception.c b/dlls/ntdll/exception.c index b5d5de64204..b7564f33fe8 100644 --- a/dlls/ntdll/exception.c +++ b/dlls/ntdll/exception.c @@ -547,3 +547,24 @@ DWORD __wine_finally_handler( EXCEPTION_RECORD *record, EXCEPTION_REGISTRATION_R } return ExceptionContinueSearch; } + + +/************************************************************* + * __wine_spec_unimplemented_stub + * + * ntdll-specific implementation to avoid depending on kernel functions. + * Can be removed once ntdll.spec no longer contains stubs. + */ +void __wine_spec_unimplemented_stub( const char *module, const char *function ) +{ + EXCEPTION_RECORD record; + + record.ExceptionCode = EXCEPTION_WINE_STUB; + record.ExceptionFlags = EH_NONCONTINUABLE; + record.ExceptionRecord = NULL; + record.ExceptionAddress = __wine_spec_unimplemented_stub; + record.NumberParameters = 2; + record.ExceptionInformation[0] = (ULONG_PTR)module; + record.ExceptionInformation[1] = (ULONG_PTR)function; + RtlRaiseException( &record ); +} diff --git a/dlls/oleacc/Makefile.in b/dlls/oleacc/Makefile.in index 19d511e4f7d..9bc4847da56 100644 --- a/dlls/oleacc/Makefile.in +++ b/dlls/oleacc/Makefile.in @@ -4,6 +4,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = oleacc.dll IMPORTLIB = liboleacc.$(IMPLIBEXT) +IMPORTS = kernel32 C_SRCS = \ main.c diff --git a/dlls/sti/Makefile.in b/dlls/sti/Makefile.in index 56efe719df0..0378ac708ca 100644 --- a/dlls/sti/Makefile.in +++ b/dlls/sti/Makefile.in @@ -4,6 +4,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = sti.dll IMPORTLIB = libsti.$(IMPLIBEXT) +IMPORTS = kernel32 C_SRCS = sti_main.c diff --git a/dlls/url/Makefile.in b/dlls/url/Makefile.in index dabb32f3a98..b43aa86daf9 100644 --- a/dlls/url/Makefile.in +++ b/dlls/url/Makefile.in @@ -4,6 +4,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = url.dll IMPORTLIB = liburl.$(IMPLIBEXT) +IMPORTS = kernel32 C_SRCS = url_main.c diff --git a/dlls/winecrt0/Makefile.in b/dlls/winecrt0/Makefile.in index bf3026aa927..d9bc9873974 100644 --- a/dlls/winecrt0/Makefile.in +++ b/dlls/winecrt0/Makefile.in @@ -7,7 +7,8 @@ MODULE = libwinecrt0.a C_SRCS = \ dll_main.c \ exe_main.c \ - exe_wmain.c + exe_wmain.c \ + stub.c @MAKE_IMPLIB_RULES@ diff --git a/dlls/winecrt0/stub.c b/dlls/winecrt0/stub.c new file mode 100644 index 00000000000..fbb07049ed3 --- /dev/null +++ b/dlls/winecrt0/stub.c @@ -0,0 +1,33 @@ +/* + * Common handling of stub functions + * + * 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/exception.h" + +void __wine_spec_unimplemented_stub( const char *module, const char *function ) +{ + ULONG_PTR args[2]; + + args[0] = (ULONG_PTR)module; + args[1] = (ULONG_PTR)function; + RaiseException( EXCEPTION_WINE_STUB, EH_NONCONTINUABLE, 2, args ); +} diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c index b04be4b8a3e..218b4f9026b 100644 --- a/tools/winebuild/import.c +++ b/tools/winebuild/import.c @@ -479,21 +479,27 @@ static int add_extra_symbol( const char **extras, int *count, const char *name, return 1; } +/* check if the spec file exports any stubs */ +static int has_stubs( const DLLSPEC *spec ) +{ + int i; + for (i = 0; i < spec->nb_entry_points; i++) + { + ORDDEF *odp = &spec->entry_points[i]; + if (odp->type == TYPE_STUB) return 1; + } + 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 ) { const char *extras[10]; - int i, count = 0, nb_stubs = 0; - int kernel_imports = 0, ntdll_imports = 0; + int i, count = 0; + int kernel_imports = 0; sort_names( &undef_symbols ); - for (i = 0; i < spec->nb_entry_points; i++) - { - ORDDEF *odp = &spec->entry_points[i]; - if (odp->type == TYPE_STUB) nb_stubs++; - } - /* add symbols that will be contained in the spec file itself */ if (!(spec->characteristics & IMAGE_FILE_DLL)) { @@ -515,12 +521,9 @@ static void add_extra_undef_symbols( const DLLSPEC *spec ) kernel_imports += add_extra_symbol( extras, &count, "GetProcAddress", spec ); kernel_imports += add_extra_symbol( extras, &count, "DelayLoadFailureHook", spec ); } - if (nb_stubs) - ntdll_imports += add_extra_symbol( extras, &count, "RtlRaiseException", spec ); /* make sure we import the dlls that contain these functions */ if (kernel_imports) add_import_dll( "kernel32", NULL ); - if (ntdll_imports) add_import_dll( "ntdll", NULL ); if (count) { @@ -600,6 +603,8 @@ void read_undef_symbols( DLLSPEC *spec, char **argv ) 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" ); + strcpy( name_prefix, asm_name("") ); prefix_len = strlen( name_prefix ); diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c index 50746d411ae..668a9b5fb8e 100644 --- a/tools/winebuild/spec32.c +++ b/tools/winebuild/spec32.c @@ -322,29 +322,10 @@ static void output_stub_funcs( FILE *outfile, DLLSPEC *spec ) ORDDEF *odp = &spec->entry_points[i]; if (odp->type != TYPE_STUB) continue; fprintf( outfile, "#ifdef __GNUC__\n" ); - fprintf( outfile, "static void __wine_unimplemented( const char *func ) __attribute__((noreturn));\n" ); - fprintf( outfile, "#endif\n\n" ); - fprintf( outfile, "struct exc_record {\n" ); - fprintf( outfile, " unsigned int code, flags;\n" ); - fprintf( outfile, " void *rec, *addr;\n" ); - fprintf( outfile, " unsigned int params;\n" ); - fprintf( outfile, " const void *info[15];\n" ); - fprintf( outfile, "};\n\n" ); - fprintf( outfile, "extern void __stdcall RtlRaiseException( struct exc_record * );\n\n" ); - fprintf( outfile, "static void __wine_unimplemented( const char *func )\n{\n" ); - fprintf( outfile, " struct exc_record rec;\n" ); - fprintf( outfile, " rec.code = 0x%08x;\n", EXCEPTION_WINE_STUB ); - fprintf( outfile, " rec.flags = %d;\n", EH_NONCONTINUABLE ); - fprintf( outfile, " rec.rec = 0;\n" ); - fprintf( outfile, " rec.params = 2;\n" ); - fprintf( outfile, " rec.info[0] = \"%s\";\n", spec->file_name ); - fprintf( outfile, " rec.info[1] = func;\n" ); - fprintf( outfile, "#ifdef __GNUC__\n" ); - fprintf( outfile, " rec.addr = __builtin_return_address(1);\n" ); + fprintf( outfile, "extern void __wine_spec_unimplemented_stub( const char *module, const char *func ) __attribute__((noreturn));\n" ); fprintf( outfile, "#else\n" ); - fprintf( outfile, " rec.addr = 0;\n" ); - fprintf( outfile, "#endif\n" ); - fprintf( outfile, " for (;;) RtlRaiseException( &rec );\n}\n\n" ); + fprintf( outfile, "extern void __wine_spec_unimplemented_stub( const char *module, const char *func );\n" ); + fprintf( outfile, "#endif\n\n" ); break; } @@ -354,11 +335,11 @@ static void output_stub_funcs( FILE *outfile, DLLSPEC *spec ) if (odp->type != TYPE_STUB) continue; fprintf( outfile, "void %s(void) ", make_internal_name( odp, spec, "stub" ) ); if (odp->name) - fprintf( outfile, "{ __wine_unimplemented(\"%s\"); }\n", odp->name ); + fprintf( outfile, "{ __wine_spec_unimplemented_stub(__wine_spec_file_name, \"%s\"); }\n", odp->name ); else if (odp->export_name) - fprintf( outfile, "{ __wine_unimplemented(\"%s\"); }\n", odp->export_name ); + fprintf( outfile, "{ __wine_spec_unimplemented_stub(__wine_spec_file_name, \"%s\"); }\n", odp->export_name ); else - fprintf( outfile, "{ __wine_unimplemented(\"%d\"); }\n", odp->ordinal ); + fprintf( outfile, "{ __wine_spec_unimplemented_stub(__wine_spec_file_name, \"%d\"); }\n", odp->ordinal ); } } @@ -494,6 +475,7 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec ) else fprintf( outfile, "extern char _end[];\n" ); + 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) @@ -732,9 +714,8 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec ) "{\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, \"%s\" );\n" - "}\n\n", - spec->file_name ); + " __wine_dll_register( &nt_header, __wine_spec_file_name );\n" + "}\n\n" ); fprintf( outfile, "void __wine_spec_init_ctor(void)\n"