diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h index b64c9a0a234..05adf31175b 100644 --- a/tools/winebuild/build.h +++ b/tools/winebuild/build.h @@ -85,7 +85,7 @@ typedef struct typedef struct { - unsigned int nb_args; + int nb_args; enum arg_type args[MAX_ARGUMENTS]; } ORD_FUNCTION; diff --git a/tools/winebuild/parser.c b/tools/winebuild/parser.c index 755084ee800..705601e9643 100644 --- a/tools/winebuild/parser.c +++ b/tools/winebuild/parser.c @@ -237,33 +237,17 @@ static int parse_spec_variable( ORDDEF *odp, DLLSPEC *spec ) /******************************************************************* - * parse_spec_export + * parse_spec_arguments * - * Parse an exported function definition in a .spec file. + * Parse the arguments of an entry point. */ -static int parse_spec_export( ORDDEF *odp, DLLSPEC *spec ) +static int parse_spec_arguments( ORDDEF *odp, DLLSPEC *spec, int optional ) { const char *token; unsigned int i, arg; int is_win32 = (spec->type == SPEC_WIN32) || (odp->flags & FLAG_EXPORT32); - if (!is_win32 && odp->type == TYPE_STDCALL) - { - error( "'stdcall' not supported for Win16\n" ); - return 0; - } - if (!is_win32 && odp->type == TYPE_THISCALL) - { - error( "'thiscall' not supported for Win16\n" ); - return 0; - } - if (is_win32 && odp->type == TYPE_PASCAL) - { - error( "'pascal' not supported for Win32\n" ); - return 0; - } - - if (!(token = GetToken(0))) return 0; + if (!(token = GetToken( optional ))) return optional; if (*token != '(') { error( "Expected '(' got '%s'\n", token ); @@ -303,13 +287,45 @@ static int parse_spec_export( ORDDEF *odp, DLLSPEC *spec ) } odp->u.func.nb_args = i; - if (odp->type == TYPE_VARARGS) - odp->flags |= FLAG_NORELAY; /* no relay debug possible for varags entry point */ if (odp->type == TYPE_THISCALL && (!i || odp->u.func.args[0] != ARG_PTR)) { error( "First argument of a thiscall function must be a pointer\n" ); return 0; } + return 1; +} + + +/******************************************************************* + * parse_spec_export + * + * Parse an exported function definition in a .spec file. + */ +static int parse_spec_export( ORDDEF *odp, DLLSPEC *spec ) +{ + const char *token; + int is_win32 = (spec->type == SPEC_WIN32) || (odp->flags & FLAG_EXPORT32); + + if (!is_win32 && odp->type == TYPE_STDCALL) + { + error( "'stdcall' not supported for Win16\n" ); + return 0; + } + if (!is_win32 && odp->type == TYPE_THISCALL) + { + error( "'thiscall' not supported for Win16\n" ); + return 0; + } + if (is_win32 && odp->type == TYPE_PASCAL) + { + error( "'pascal' not supported for Win32\n" ); + return 0; + } + + if (!parse_spec_arguments( odp, spec, 0 )) return 0; + + if (odp->type == TYPE_VARARGS) + odp->flags |= FLAG_NORELAY; /* no relay debug possible for varags entry point */ if (!(token = GetToken(1))) { @@ -383,14 +399,15 @@ static int parse_spec_equate( ORDDEF *odp, DLLSPEC *spec ) */ static int parse_spec_stub( ORDDEF *odp, DLLSPEC *spec ) { - odp->u.func.nb_args = 0; + odp->u.func.nb_args = -1; odp->link_name = xstrdup(""); /* don't bother generating stubs for Winelib */ if (odp->flags & FLAG_CPU_MASK) odp->flags &= FLAG_CPU(CPU_x86) | FLAG_CPU(CPU_x86_64); else odp->flags |= FLAG_CPU(CPU_x86) | FLAG_CPU(CPU_x86_64); - return 1; + + return parse_spec_arguments( odp, spec, 1 ); } @@ -808,7 +825,8 @@ void add_16bit_exports( DLLSPEC *spec32, DLLSPEC *spec16 ) odp->ordinal = -1; odp->link_name = xstrdup( odp16->link_name ); odp->u.func.nb_args = odp16->u.func.nb_args; - memcpy( odp->u.func.args, odp16->u.func.args, odp->u.func.nb_args * sizeof(odp->u.func.args[0]) ); + if (odp->u.func.nb_args > 0) memcpy( odp->u.func.args, odp16->u.func.args, + odp->u.func.nb_args * sizeof(odp->u.func.args[0]) ); } assign_names( spec32 ); diff --git a/tools/winebuild/spec16.c b/tools/winebuild/spec16.c index c5ca051216e..481ed132e0e 100644 --- a/tools/winebuild/spec16.c +++ b/tools/winebuild/spec16.c @@ -67,7 +67,7 @@ static inline int is_function( const ORDDEF *odp ) static const char *get_args_str( const ORDDEF *odp ) { static char buffer[MAX_ARGUMENTS*2+1]; - unsigned int i; + int i; buffer[0] = 0; for (i = 0; i < odp->u.func.nb_args; i++) @@ -275,7 +275,7 @@ static const char *get_relay_name( const ORDDEF *odp ) */ static int get_function_argsize( const ORDDEF *odp ) { - unsigned int i, argsize = 0; + int i, argsize = 0; for (i = 0; i < odp->u.func.nb_args; i++) { diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c index 6642661cdd6..8999b886fdf 100644 --- a/tools/winebuild/spec32.c +++ b/tools/winebuild/spec32.c @@ -61,7 +61,7 @@ static inline int needs_relay( const ORDDEF *odp ) return 1; } -static int is_float_arg( const ORDDEF *odp, unsigned int arg ) +static int is_float_arg( const ORDDEF *odp, int arg ) { if (arg >= odp->u.func.nb_args) return 0; return (odp->u.func.args[arg] == ARG_FLOAT || odp->u.func.args[arg] == ARG_DOUBLE); @@ -89,8 +89,8 @@ int has_relays( DLLSPEC *spec ) */ static void output_relay_debug( DLLSPEC *spec ) { - int i; - unsigned int j, pos, args, flags; + int i, j; + unsigned int pos, args, flags; /* first the table of entry point offsets */ diff --git a/tools/winebuild/utils.c b/tools/winebuild/utils.c index 931fc4960d4..acd6915eb77 100644 --- a/tools/winebuild/utils.c +++ b/tools/winebuild/utils.c @@ -892,7 +892,7 @@ unsigned int get_ptr_size(void) /* return the total size in bytes of the arguments on the stack */ unsigned int get_args_size( const ORDDEF *odp ) { - unsigned int i, size; + int i, size; for (i = size = 0; i < odp->u.func.nb_args; i++) { diff --git a/tools/winebuild/winebuild.man.in b/tools/winebuild/winebuild.man.in index 479bb1fd02d..59debd4afaf 100644 --- a/tools/winebuild/winebuild.man.in +++ b/tools/winebuild/winebuild.man.in @@ -245,7 +245,7 @@ syntax is the following: .RI [ flags ]\ exportname \ [ symbolname ] .br .IB ordinal\ stub -.RI [ flags ]\ exportname +.RI [ flags ]\ exportname \ [\ \fB( args... \fB)\fR\ ] .br .IB ordinal\ equate .RI [ flags ]\ exportname\ data @@ -453,7 +453,7 @@ is not specified, it is assumed to be identical to Syntax: .br .IB ordinal\ stub -.RI [ flags ]\ exportname +.RI [ flags ]\ exportname \ [\ \fB( args... \fB)\fR\ ] .PP This declaration defines a stub function. It makes the name and ordinal available for dynamic linking, but will terminate execution