Raise an exception for unimplemented 16-bit entry points too.

Added check for duplicate names in 16-bit spec files.
This commit is contained in:
Alexandre Julliard 2000-11-12 03:45:55 +00:00
parent 0ba2b569e2
commit 0a8114c152
8 changed files with 173 additions and 102 deletions

View File

@ -422,7 +422,7 @@ owner kernel32
#508 stub WOWFAILEDEXEC # conflict with 507 ! (something broken here ?) #508 stub WOWFAILEDEXEC # conflict with 507 ! (something broken here ?)
508 stub WOWCLOSECOMPORT 508 stub WOWCLOSECOMPORT
#509 stub WOWCLOSECOMPORT # conflict with 508 ! #509 stub WOWCLOSECOMPORT # conflict with 508 !
509 stub WOWKILLREMOTETASK #509 stub WOWKILLREMOTETASK
511 stub WOWKILLREMOTETASK 511 stub WOWKILLREMOTETASK
512 stub WOWQUERYDEBUG 512 stub WOWQUERYDEBUG
513 pascal LoadLibraryEx32W(ptr long long) LoadLibraryEx32W16 # Both NT/95 513 pascal LoadLibraryEx32W(ptr long long) LoadLibraryEx32W16 # Both NT/95
@ -482,12 +482,16 @@ owner kernel32
602 pascal16 GetDummyModuleHandleDS() GetDummyModuleHandleDS16 602 pascal16 GetDummyModuleHandleDS() GetDummyModuleHandleDS16
603 stub KERNEL_603 # OutputDebugString (?) 603 stub KERNEL_603 # OutputDebugString (?)
604 register CBClientGlueSL() CBClientGlueSL 604 register CBClientGlueSL() CBClientGlueSL
605 pascal AllocSLThunkletCallback(long long) AllocSLThunkletCallback16 # FIXME: 605 is duplicate of 562
606 pascal AllocLSThunkletCallback(segptr long) AllocLSThunkletCallback16 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 607 pascal AllocLSThunkletSysthunk(segptr long long) AllocLSThunkletSysthunk16
608 pascal AllocSLThunkletSysthunk(long segptr long) AllocSLThunkletSysthunk16 608 pascal AllocSLThunkletSysthunk(long segptr long) AllocSLThunkletSysthunk16
609 pascal FindLSThunkletCallback(segptr long) FindLSThunkletCallback # FIXME: 609 is duplicate of 563
610 pascal FindSLThunkletCallback(long long) FindSLThunkletCallback 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 611 pascal16 FreeThunklet(long long) FreeThunklet16
612 pascal16 IsSLThunklet(ptr) IsSLThunklet16 612 pascal16 IsSLThunklet(ptr) IsSLThunklet16
613 stub HugeMapLS 613 stub HugeMapLS

View File

@ -169,14 +169,16 @@ owner ole32
166 stub OPDELETE16 166 stub OPDELETE16
167 stub ?GETSIZEVALUE@CARRAYFVALUE@@RFCHXZ 167 stub ?GETSIZEVALUE@CARRAYFVALUE@@RFCHXZ
168 stub ?PROXY1632ADDREF@@ZAKPEVCPROXY1632@@@Z 168 stub ?PROXY1632ADDREF@@ZAKPEVCPROXY1632@@@Z
169 stub REMLOOKUPSHUNK # FIXME: 169 is a duplicate of 97
169 stub REMLOOKUPSHUNK_dup
170 stub ?ISEMPTY@CMAPKEYTOVALUE@@RFCHXZ 170 stub ?ISEMPTY@CMAPKEYTOVALUE@@RFCHXZ
171 stub ?FREE@CSTDMALLOC@@VEAXPEX@Z 171 stub ?FREE@CSTDMALLOC@@VEAXPEX@Z
172 stub CALLTHKMGRINITIALIZE 172 stub CALLTHKMGRINITIALIZE
173 stub ?REALLOC@CSTDMALLOC@@VEAPEXPEXK@Z 173 stub ?REALLOC@CSTDMALLOC@@VEAPEXPEXK@Z
174 stub ?SM16RHQI@@ZAPEXPEVCSM16RELEASEHANDLER@@AFUGUID@@PEPEX@Z 174 stub ?SM16RHQI@@ZAPEXPEVCSM16RELEASEHANDLER@@AFUGUID@@PEPEX@Z
175 stub ?PROXY1632METHOD10@@ZAKPEVCPROXY1632@@@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 177 stub ?PROXY1632METHOD20@@ZAKPEVCPROXY1632@@@Z
178 stub ?PROXY1632METHOD11@@ZAKPEVCPROXY1632@@@Z 178 stub ?PROXY1632METHOD11@@ZAKPEVCPROXY1632@@@Z
179 stub ?PROXY1632METHOD30@@ZAKPEVCPROXY1632@@@Z 179 stub ?PROXY1632METHOD30@@ZAKPEVCPROXY1632@@@Z

View File

@ -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 * RELAY_DebugCallTo16
* *

View File

@ -409,7 +409,6 @@ void TASK_ExitTask(void)
if (!nTaskCount || (nTaskCount == 1 && hFirstTask == initial_task)) if (!nTaskCount || (nTaskCount == 1 && hFirstTask == initial_task))
{ {
TRACE("this is the last task, exiting\n" ); TRACE("this is the last task, exiting\n" );
ERR("done\n");
ExitKernel16(); ExitKernel16();
} }

View File

@ -21,7 +21,8 @@ struct import
}; };
static char **undef_symbols; /* list of undefined symbols */ 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 struct import **dll_imports = NULL;
static int nb_imports = 0; /* number of imported dlls */ static int nb_imports = 0; /* number of imported dlls */
@ -223,7 +224,7 @@ int resolve_imports( FILE *outfile )
int i, j, off; int i, j, off;
char **p; 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(); add_extra_undef_symbols();

View File

@ -15,6 +15,7 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include "winbase.h"
#include "build.h" #include "build.h"
int current_line = 0; int current_line = 0;
@ -45,9 +46,6 @@ static const char * const TypeNames[TYPE_NBTYPES] =
"forward" /* TYPE_FORWARD */ "forward" /* TYPE_FORWARD */
}; };
/* callback function used for stub functions */
#define STUB_CALLBACK \
((SpecType == SPEC_WIN16) ? "RELAY_Unimplemented16": "RELAY_Unimplemented32")
static int IsNumberString(char *s) static int IsNumberString(char *s)
{ {
@ -280,7 +278,7 @@ static void ParseEquate( ORDDEF *odp )
static void ParseStub( ORDDEF *odp ) static void ParseStub( ORDDEF *odp )
{ {
odp->u.func.arg_types[0] = '\0'; 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 * ParseTopLevel
* *
@ -543,5 +575,6 @@ SPEC_TYPE ParseTopLevel( FILE *file )
fatal_error( "'owner' not specified for Win16 dll\n" ); fatal_error( "'owner' not specified for Win16 dll\n" );
current_line = 0; /* no longer parsing the input file */ current_line = 0; /* no longer parsing the input file */
sort_names();
return SpecType; return SpecType;
} }

View File

@ -11,6 +11,7 @@
#include <assert.h> #include <assert.h>
#include <ctype.h> #include <ctype.h>
#include "wine/exception.h"
#include "builtin16.h" #include "builtin16.h"
#include "module.h" #include "module.h"
#include "neexe.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 * BuildSpec16File
* *
@ -519,6 +572,9 @@ void BuildSpec16File( FILE *outfile )
data_offset = 16; data_offset = 16;
strupper( DLLName ); 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 */ /* Build sorted list of all argument types, without duplicates */
typelist = (ORDDEF **)calloc( Limit+1, sizeof(ORDDEF *) ); typelist = (ORDDEF **)calloc( Limit+1, sizeof(ORDDEF *) );
@ -615,7 +671,6 @@ void BuildSpec16File( FILE *outfile )
case 's': /* s_word */ case 's': /* s_word */
argsize += 2; argsize += 2;
break; break;
case 'l': /* long or segmented pointer */ case 'l': /* long or segmented pointer */
case 'T': /* segmented pointer to null-terminated string */ case 'T': /* segmented pointer to null-terminated string */
case 'p': /* linear pointer */ case 'p': /* linear pointer */
@ -679,24 +734,23 @@ void BuildSpec16File( FILE *outfile )
fprintf( outfile, " /* %s.%d */ ", DLLName, i ); fprintf( outfile, " /* %s.%d */ ", DLLName, i );
fprintf( outfile, "{ 0x5566, 0x68, %s, 0xe866, %d /* %s_%s_%s */ },\n", fprintf( outfile, "{ 0x5566, 0x68, %s, 0xe866, %d /* %s_%s_%s */ },\n",
odp->u.func.link_name, odp->u.func.link_name,
(type-typelist)*sizeof(CALLFROM16) - (type-typelist)*sizeof(CALLFROM16) -
(code_offset + sizeof(ENTRYPOINT16)), (code_offset + sizeof(ENTRYPOINT16)),
(odp->type == TYPE_CDECL) ? "c" : "p", (odp->type == TYPE_CDECL) ? "c" : "p",
(odp->type == TYPE_REGISTER) ? "regs" : (odp->type == TYPE_REGISTER) ? "regs" :
(odp->type == TYPE_INTERRUPT) ? "intr" : (odp->type == TYPE_INTERRUPT) ? "intr" :
(odp->type == TYPE_PASCAL_16) ? "word" : "long", (odp->type == TYPE_PASCAL_16) ? "word" : "long",
odp->u.func.arg_types ); odp->u.func.arg_types );
odp->offset = code_offset; odp->offset = code_offset;
code_offset += sizeof(ENTRYPOINT16); code_offset += sizeof(ENTRYPOINT16);
break; break;
default: default:
fprintf(stderr,"build: function type %d not available for Win16\n", fprintf(stderr,"build: function type %d not available for Win16\n",
odp->type); odp->type);
exit(1); exit(1);
} }
} }
fprintf( outfile, " }\n};\n" ); fprintf( outfile, " }\n};\n" );

View File

@ -17,13 +17,6 @@
#include "build.h" #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 ) static int string_compare( const void *ptr1, const void *ptr2 )
{ {
const char * const *str1 = ptr1; const char * const *str1 = ptr1;
@ -42,20 +35,6 @@ static void AssignOrdinals(void)
if ( !nb_names ) return; 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 */ /* start assigning from Base, or from 1 if no ordinal defined yet */
if (Base == MAX_ORDINALS) Base = 1; if (Base == MAX_ORDINALS) Base = 1;
for (i = 0, ordinal = Base; i < nb_names; i++) 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 * BuildSpec32File
* *
@ -356,36 +387,9 @@ void BuildSpec32File( FILE *outfile, int output_main )
fprintf( outfile, "static const char dllname[] = \"%s\";\n\n", DLLName ); 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++) output_stub_funcs( outfile );
{
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 the DLL functions prototypes */ /* Output the DLL functions prototypes */
@ -410,14 +414,6 @@ void BuildSpec32File( FILE *outfile, int output_main )
have_regs = TRUE; have_regs = TRUE;
break; break;
case TYPE_STUB: 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; break;
default: default:
fprintf(stderr,"build: function type %d not available for Win32\n", fprintf(stderr,"build: function type %d not available for Win32\n",