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:
parent
0ba2b569e2
commit
0a8114c152
|
@ -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
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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"
|
||||
|
@ -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" );
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in New Issue