From 0a8114c152bea9840ab7980f5da124ed59a699de Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Sun, 12 Nov 2000 03:45:55 +0000 Subject: [PATCH] Raise an exception for unimplemented 16-bit entry points too. Added check for duplicate names in 16-bit spec files. --- dlls/kernel/kernel.spec | 14 +++-- dlls/ole32/compobj.spec | 6 ++- if1632/relay.c | 18 ------- loader/task.c | 1 - tools/winebuild/import.c | 5 +- tools/winebuild/parser.c | 41 ++++++++++++-- tools/winebuild/spec16.c | 78 ++++++++++++++++++++++----- tools/winebuild/spec32.c | 112 +++++++++++++++++++-------------------- 8 files changed, 173 insertions(+), 102 deletions(-) diff --git a/dlls/kernel/kernel.spec b/dlls/kernel/kernel.spec index 3f57447db4b..fad93d726bf 100644 --- a/dlls/kernel/kernel.spec +++ b/dlls/kernel/kernel.spec @@ -422,7 +422,7 @@ owner kernel32 #508 stub WOWFAILEDEXEC # conflict with 507 ! (something broken here ?) 508 stub WOWCLOSECOMPORT #509 stub WOWCLOSECOMPORT # conflict with 508 ! -509 stub WOWKILLREMOTETASK +#509 stub WOWKILLREMOTETASK 511 stub WOWKILLREMOTETASK 512 stub WOWQUERYDEBUG 513 pascal LoadLibraryEx32W(ptr long long) LoadLibraryEx32W16 # Both NT/95 @@ -482,12 +482,16 @@ owner kernel32 602 pascal16 GetDummyModuleHandleDS() GetDummyModuleHandleDS16 603 stub KERNEL_603 # OutputDebugString (?) 604 register CBClientGlueSL() CBClientGlueSL -605 pascal AllocSLThunkletCallback(long long) AllocSLThunkletCallback16 -606 pascal AllocLSThunkletCallback(segptr long) AllocLSThunkletCallback16 +# FIXME: 605 is duplicate of 562 +605 pascal AllocSLThunkletCallback_dup(long long) AllocSLThunkletCallback16 +# FIXME: 606 is duplicate of 561 +606 pascal AllocLSThunkletCallback_dup(segptr long) AllocLSThunkletCallback16 607 pascal AllocLSThunkletSysthunk(segptr long long) AllocLSThunkletSysthunk16 608 pascal AllocSLThunkletSysthunk(long segptr long) AllocSLThunkletSysthunk16 -609 pascal FindLSThunkletCallback(segptr long) FindLSThunkletCallback -610 pascal FindSLThunkletCallback(long long) FindSLThunkletCallback +# FIXME: 609 is duplicate of 563 +609 pascal FindLSThunkletCallback_dup(segptr long) FindLSThunkletCallback +# FIXME: 610 is duplicate of 562 +610 pascal FindSLThunkletCallback_dup(long long) FindSLThunkletCallback 611 pascal16 FreeThunklet(long long) FreeThunklet16 612 pascal16 IsSLThunklet(ptr) IsSLThunklet16 613 stub HugeMapLS diff --git a/dlls/ole32/compobj.spec b/dlls/ole32/compobj.spec index ef6e5fc3cfb..606f7a64e71 100644 --- a/dlls/ole32/compobj.spec +++ b/dlls/ole32/compobj.spec @@ -169,14 +169,16 @@ owner ole32 166 stub OPDELETE16 167 stub ?GETSIZEVALUE@CARRAYFVALUE@@RFCHXZ 168 stub ?PROXY1632ADDREF@@ZAKPEVCPROXY1632@@@Z -169 stub REMLOOKUPSHUNK +# FIXME: 169 is a duplicate of 97 +169 stub REMLOOKUPSHUNK_dup 170 stub ?ISEMPTY@CMAPKEYTOVALUE@@RFCHXZ 171 stub ?FREE@CSTDMALLOC@@VEAXPEX@Z 172 stub CALLTHKMGRINITIALIZE 173 stub ?REALLOC@CSTDMALLOC@@VEAPEXPEXK@Z 174 stub ?SM16RHQI@@ZAPEXPEVCSM16RELEASEHANDLER@@AFUGUID@@PEPEX@Z 175 stub ?PROXY1632METHOD10@@ZAKPEVCPROXY1632@@@Z -176 stub ___EXPORTEDSTUB +# FIXME: 176 is a duplicate of 154 +176 stub ___EXPORTEDSTUB_dup 177 stub ?PROXY1632METHOD20@@ZAKPEVCPROXY1632@@@Z 178 stub ?PROXY1632METHOD11@@ZAKPEVCPROXY1632@@@Z 179 stub ?PROXY1632METHOD30@@ZAKPEVCPROXY1632@@@Z diff --git a/if1632/relay.c b/if1632/relay.c index f4ecb65784f..2892091ef4b 100644 --- a/if1632/relay.c +++ b/if1632/relay.c @@ -262,24 +262,6 @@ void RELAY_DebugCallFrom16Ret( CONTEXT86 *context, int ret_val ) } -/*********************************************************************** - * RELAY_Unimplemented16 - * - * This function is called for unimplemented 16-bit entry points (declared - * as 'stub' in the spec file). - */ -void RELAY_Unimplemented16(void) -{ - WORD ordinal; - char name[80]; - STACK16FRAME *frame = CURRENT_STACK16; - BUILTIN_GetEntryPoint16( frame, name, &ordinal ); - MESSAGE("FATAL: No handler for Win16 routine %s (called from %04x:%04x)\n", - name, frame->cs, frame->ip ); - ExitProcess(1); -} - - /*********************************************************************** * RELAY_DebugCallTo16 * diff --git a/loader/task.c b/loader/task.c index e6bafa09ede..3924fad334b 100644 --- a/loader/task.c +++ b/loader/task.c @@ -409,7 +409,6 @@ void TASK_ExitTask(void) if (!nTaskCount || (nTaskCount == 1 && hFirstTask == initial_task)) { TRACE("this is the last task, exiting\n" ); - ERR("done\n"); ExitKernel16(); } diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c index 60d2045f85e..0f5ae4c2fe5 100644 --- a/tools/winebuild/import.c +++ b/tools/winebuild/import.c @@ -21,7 +21,8 @@ struct import }; static char **undef_symbols; /* list of undefined symbols */ -static int nb_undef_symbols, undef_size; +static int nb_undef_symbols = -1; +static int undef_size; static struct import **dll_imports = NULL; static int nb_imports = 0; /* number of imported dlls */ @@ -223,7 +224,7 @@ int resolve_imports( FILE *outfile ) int i, j, off; char **p; - if (!nb_undef_symbols) return 0; /* no symbol file specified */ + if (nb_undef_symbols == -1) return 0; /* no symbol file specified */ add_extra_undef_symbols(); diff --git a/tools/winebuild/parser.c b/tools/winebuild/parser.c index 19085a434ce..d4b6d4332e1 100644 --- a/tools/winebuild/parser.c +++ b/tools/winebuild/parser.c @@ -15,6 +15,7 @@ #include #include +#include "winbase.h" #include "build.h" int current_line = 0; @@ -45,9 +46,6 @@ static const char * const TypeNames[TYPE_NBTYPES] = "forward" /* TYPE_FORWARD */ }; -/* callback function used for stub functions */ -#define STUB_CALLBACK \ - ((SpecType == SPEC_WIN16) ? "RELAY_Unimplemented16": "RELAY_Unimplemented32") static int IsNumberString(char *s) { @@ -280,7 +278,7 @@ static void ParseEquate( ORDDEF *odp ) static void ParseStub( ORDDEF *odp ) { odp->u.func.arg_types[0] = '\0'; - strcpy( odp->u.func.link_name, STUB_CALLBACK ); + odp->u.func.link_name[0] = '\0'; } @@ -438,6 +436,40 @@ static void ParseOrdinal(int ordinal) } +static int name_compare( const void *name1, const void *name2 ) +{ + ORDDEF *odp1 = *(ORDDEF **)name1; + ORDDEF *odp2 = *(ORDDEF **)name2; + return strcmp( odp1->name, odp2->name ); +} + +/******************************************************************* + * sort_names + * + * Sort the name array and catch duplicates. + */ +static void sort_names(void) +{ + int i; + + if (!nb_names) return; + + /* sort the list of names */ + qsort( Names, nb_names, sizeof(Names[0]), name_compare ); + + /* check for duplicate names */ + for (i = 0; i < nb_names - 1; i++) + { + if (!strcmp( Names[i]->name, Names[i+1]->name )) + { + current_line = max( Names[i]->lineno, Names[i+1]->lineno ); + fatal_error( "'%s' redefined (previous definition at line %d)\n", + Names[i]->name, min( Names[i]->lineno, Names[i+1]->lineno ) ); + } + } +} + + /******************************************************************* * ParseTopLevel * @@ -543,5 +575,6 @@ SPEC_TYPE ParseTopLevel( FILE *file ) fatal_error( "'owner' not specified for Win16 dll\n" ); current_line = 0; /* no longer parsing the input file */ + sort_names(); return SpecType; } diff --git a/tools/winebuild/spec16.c b/tools/winebuild/spec16.c index da94cff5007..a113ecbc496 100644 --- a/tools/winebuild/spec16.c +++ b/tools/winebuild/spec16.c @@ -11,6 +11,7 @@ #include #include +#include "wine/exception.h" #include "builtin16.h" #include "module.h" #include "neexe.h" @@ -493,6 +494,58 @@ static int Spec16TypeCompare( const void *e1, const void *e2 ) } +/******************************************************************* + * output_stub_funcs + * + * Output the functions for stub entry points +*/ +static void output_stub_funcs( FILE *outfile ) +{ + int i; + char *p; + + for (i = 0; i <= Limit; i++) + { + ORDDEF *odp = Ordinals[i]; + if (!odp || 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" ); + fprintf( outfile, "static void __wine_unimplemented( const char *func )\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, " } rec;\n" ); + fprintf( outfile, " extern void RtlRaiseException( struct exc_record * );\n\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] = dllname;\n" ); + fprintf( outfile, " rec.info[1] = func;\n" ); + fprintf( outfile, "#ifdef __GNUC__\n" ); + fprintf( outfile, " rec.addr = __builtin_return_address(1);\n" ); + fprintf( outfile, "#else\n" ); + fprintf( outfile, " rec.addr = 0;\n" ); + fprintf( outfile, "#endif\n" ); + fprintf( outfile, " for (;;) RtlRaiseException( &rec );\n}\n\n" ); + break; + } + for (i = 0; i <= Limit; i++) + { + ORDDEF *odp = Ordinals[i]; + if (!odp || odp->type != TYPE_STUB) continue; + strcpy( odp->u.func.link_name, "__stub_" ); + strcat( odp->u.func.link_name, odp->name ); + for (p = odp->u.func.link_name; *p; p++) if (!isalnum(*p)) *p = '_'; + fprintf( outfile, "static void %s(void) { __wine_unimplemented(\"%s\"); }\n", + odp->u.func.link_name, odp->name ); + } +} + + /******************************************************************* * BuildSpec16File * @@ -519,6 +572,9 @@ void BuildSpec16File( FILE *outfile ) data_offset = 16; strupper( DLLName ); + fprintf( outfile, "static const char dllname[] = \"%s\";\n\n", DLLName ); + output_stub_funcs( outfile ); + /* Build sorted list of all argument types, without duplicates */ typelist = (ORDDEF **)calloc( Limit+1, sizeof(ORDDEF *) ); @@ -615,7 +671,6 @@ void BuildSpec16File( FILE *outfile ) case 's': /* s_word */ argsize += 2; break; - case 'l': /* long or segmented pointer */ case 'T': /* segmented pointer to null-terminated string */ case 'p': /* linear pointer */ @@ -679,24 +734,23 @@ void BuildSpec16File( FILE *outfile ) fprintf( outfile, " /* %s.%d */ ", DLLName, i ); fprintf( outfile, "{ 0x5566, 0x68, %s, 0xe866, %d /* %s_%s_%s */ },\n", - odp->u.func.link_name, - (type-typelist)*sizeof(CALLFROM16) - - (code_offset + sizeof(ENTRYPOINT16)), - (odp->type == TYPE_CDECL) ? "c" : "p", - (odp->type == TYPE_REGISTER) ? "regs" : - (odp->type == TYPE_INTERRUPT) ? "intr" : - (odp->type == TYPE_PASCAL_16) ? "word" : "long", - odp->u.func.arg_types ); - + odp->u.func.link_name, + (type-typelist)*sizeof(CALLFROM16) - + (code_offset + sizeof(ENTRYPOINT16)), + (odp->type == TYPE_CDECL) ? "c" : "p", + (odp->type == TYPE_REGISTER) ? "regs" : + (odp->type == TYPE_INTERRUPT) ? "intr" : + (odp->type == TYPE_PASCAL_16) ? "word" : "long", + odp->u.func.arg_types ); odp->offset = code_offset; code_offset += sizeof(ENTRYPOINT16); break; - + default: fprintf(stderr,"build: function type %d not available for Win16\n", odp->type); exit(1); - } + } } fprintf( outfile, " }\n};\n" ); diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c index 1629be61089..77ee24c4ab5 100644 --- a/tools/winebuild/spec32.c +++ b/tools/winebuild/spec32.c @@ -17,13 +17,6 @@ #include "build.h" -static int name_compare( const void *name1, const void *name2 ) -{ - ORDDEF *odp1 = *(ORDDEF **)name1; - ORDDEF *odp2 = *(ORDDEF **)name2; - return strcmp( odp1->name, odp2->name ); -} - static int string_compare( const void *ptr1, const void *ptr2 ) { const char * const *str1 = ptr1; @@ -42,20 +35,6 @@ static void AssignOrdinals(void) if ( !nb_names ) return; - /* sort the list of names */ - qsort( Names, nb_names, sizeof(Names[0]), name_compare ); - - /* check for duplicate names */ - for (i = 0; i < nb_names - 1; i++) - { - if (!strcmp( Names[i]->name, Names[i+1]->name )) - { - current_line = max( Names[i]->lineno, Names[i+1]->lineno ); - fatal_error( "'%s' redefined (previous definition at line %d)\n", - Names[i]->name, min( Names[i]->lineno, Names[i+1]->lineno ) ); - } - } - /* start assigning from Base, or from 1 if no ordinal defined yet */ if (Base == MAX_ORDINALS) Base = 1; for (i = 0, ordinal = Base; i < nb_names; i++) @@ -317,6 +296,58 @@ static void output_exports( FILE *outfile, int nr_exports, int fwd_size ) } +/******************************************************************* + * output_stub_funcs + * + * Output the functions for stub entry points +*/ +static void output_stub_funcs( FILE *outfile ) +{ + int i; + ORDDEF *odp; + + for (i = 0, odp = EntryPoints; i < nb_entry_points; i++, odp++) + { + 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" ); + fprintf( outfile, "static void __wine_unimplemented( const char *func )\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, " } rec;\n" ); + fprintf( outfile, " extern void RtlRaiseException( struct exc_record * );\n\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] = dllname;\n" ); + fprintf( outfile, " rec.info[1] = func;\n" ); + fprintf( outfile, "#ifdef __GNUC__\n" ); + fprintf( outfile, " rec.addr = __builtin_return_address(1);\n" ); + fprintf( outfile, "#else\n" ); + fprintf( outfile, " rec.addr = 0;\n" ); + fprintf( outfile, "#endif\n" ); + fprintf( outfile, " for (;;) RtlRaiseException( &rec );\n}\n\n" ); + break; + } + + for (i = 0, odp = EntryPoints; i < nb_entry_points; i++, odp++) + { + if (odp->type != TYPE_STUB) continue; + if (odp->name[0]) + fprintf( outfile, "static void __stub_%s(void) { __wine_unimplemented(\"%s\"); }\n", + odp->name, odp->name ); + else + fprintf( outfile, "static void __stub_%d(void) { __wine_unimplemented(\"%d\"); }\n", + odp->ordinal, odp->ordinal ); + } +} + + /******************************************************************* * BuildSpec32File * @@ -356,36 +387,9 @@ void BuildSpec32File( FILE *outfile, int output_main ) fprintf( outfile, "static const char dllname[] = \"%s\";\n\n", DLLName ); - /* Output the stub function if necessary */ + /* Output the stub functions */ - for (i = 0, odp = EntryPoints; i < nb_entry_points; i++, odp++) - { - 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" ); - fprintf( outfile, "static void __wine_unimplemented( const char *func )\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, " } rec;\n" ); - fprintf( outfile, " extern void RtlRaiseException( struct exc_record * );\n\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] = dllname;\n" ); - fprintf( outfile, " rec.info[1] = func;\n" ); - fprintf( outfile, "#ifdef __GNUC__\n" ); - fprintf( outfile, " rec.addr = __builtin_return_address(1);\n" ); - fprintf( outfile, "#else\n" ); - fprintf( outfile, " rec.addr = 0;\n" ); - fprintf( outfile, "#endif\n" ); - fprintf( outfile, " for (;;) RtlRaiseException( &rec );\n}\n\n" ); - break; - } + output_stub_funcs( outfile ); /* Output the DLL functions prototypes */ @@ -410,14 +414,6 @@ void BuildSpec32File( FILE *outfile, int output_main ) have_regs = TRUE; break; case TYPE_STUB: - if (odp->name[0]) - fprintf( outfile, - "static void __stub_%s() { __wine_unimplemented(\"%s\"); }\n", - odp->name, odp->name ); - else - fprintf( outfile, - "static void __stub_%d() { __wine_unimplemented(\"%d\"); }\n", - odp->ordinal, odp->ordinal ); break; default: fprintf(stderr,"build: function type %d not available for Win32\n",