Commit 0a8114c1 authored by Alexandre Julliard's avatar Alexandre Julliard

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

Added check for duplicate names in 16-bit spec files.
parent 0ba2b569
......@@ -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
......
......@@ -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
......
......@@ -263,24 +263,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
*
* 'target' contains either the function to call (normal CallTo16)
......
......@@ -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();
}
......
......@@ -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();
......
......@@ -15,6 +15,7 @@
#include <string.h>
#include <unistd.h>
#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;
}
......@@ -11,6 +11,7 @@
#include <assert.h>
#include <ctype.h>
#include "wine/exception.h"
#include "builtin16.h"
#include "module.h"
#include "neexe.h"
......@@ -494,6 +495,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
*
* Build a Win16 assembly file from a spec file.
......@@ -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" );
......
......@@ -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++)
......@@ -318,6 +297,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
*
* Build a Win32 C file from a spec file.
......@@ -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",
......
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