Module: wine Branch: master Commit: d097eef922d5c3e17fe67cce8011ebd2da955864 URL: http://source.winehq.org/git/wine.git/?a=commit;h=d097eef922d5c3e17fe67cce80...
Author: Alexandre Julliard julliard@winehq.org Date: Mon Dec 28 22:42:58 2009 +0100
winebuild: Support for adding 32-bit exports in 16-bit spec files.
---
tools/winebuild/build.h | 1 + tools/winebuild/parser.c | 79 +++++++++++++++++++++++++++++----------------- tools/winebuild/spec16.c | 3 ++ 3 files changed, 54 insertions(+), 29 deletions(-)
diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h index e47278a..64ad5b1 100644 --- a/tools/winebuild/build.h +++ b/tools/winebuild/build.h @@ -146,6 +146,7 @@ extern enum target_platform target_platform;
#define FLAG_FORWARD 0x100 /* function is a forwarded name */ #define FLAG_EXT_LINK 0x200 /* function links to an external symbol */ +#define FLAG_EXPORT32 0x400 /* 32-bit export in 16-bit spec file */
#define FLAG_CPU(cpu) (0x01000 << (cpu)) #define FLAG_CPU_MASK (FLAG_CPU(CPU_LAST + 1) - FLAG_CPU(0)) diff --git a/tools/winebuild/parser.c b/tools/winebuild/parser.c index 57807ed..d08a190 100644 --- a/tools/winebuild/parser.c +++ b/tools/winebuild/parser.c @@ -228,25 +228,17 @@ static int parse_spec_export( ORDDEF *odp, DLLSPEC *spec ) { const char *token; unsigned int i; + int is_win32 = (spec->type == SPEC_WIN32) || (odp->flags & FLAG_EXPORT32);
- switch(spec->type) + if (!is_win32 && odp->type == TYPE_STDCALL) { - case SPEC_WIN16: - if (odp->type == TYPE_STDCALL) - { - error( "'stdcall' not supported for Win16\n" ); - return 0; - } - break; - case SPEC_WIN32: - if (odp->type == TYPE_PASCAL) - { - error( "'pascal' not supported for Win32\n" ); - return 0; - } - break; - default: - break; + error( "'stdcall' 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; @@ -288,7 +280,7 @@ static int parse_spec_export( ORDDEF *odp, DLLSPEC *spec ) return 0; }
- if (spec->type == SPEC_WIN32) + if (is_win32) { if (strcmp(token, "long") && strcmp(token, "ptr") && @@ -296,7 +288,7 @@ static int parse_spec_export( ORDDEF *odp, DLLSPEC *spec ) strcmp(token, "wstr") && strcmp(token, "double")) { - error( "Type '%s' not supported for Win32\n", token ); + error( "Type '%s' not supported for Win32 function\n", token ); return 0; } } @@ -325,7 +317,7 @@ static int parse_spec_export( ORDDEF *odp, DLLSPEC *spec ) odp->link_name = xstrdup( token ); if (strchr( odp->link_name, '.' )) { - if (spec->type == SPEC_WIN16) + if (!is_win32) { error( "Forwarded functions not supported for Win16\n" ); return 0; @@ -421,7 +413,7 @@ static int parse_spec_extern( ORDDEF *odp, DLLSPEC *spec ) * * Parse the optional flags for an entry point in a .spec file. */ -static const char *parse_spec_flags( ORDDEF *odp ) +static const char *parse_spec_flags( DLLSPEC *spec, ORDDEF *odp ) { unsigned int i; const char *token; @@ -436,7 +428,12 @@ static const char *parse_spec_flags( ORDDEF *odp ) while (cpu_name) { if (!strcmp( cpu_name, "win32" )) - odp->flags |= FLAG_CPU_WIN32; + { + if (spec->type == SPEC_WIN32) + odp->flags |= FLAG_CPU_WIN32; + else + odp->flags |= FLAG_EXPORT32; + } else if (!strcmp( cpu_name, "win64" )) odp->flags |= FLAG_CPU_WIN64; else @@ -499,7 +496,13 @@ static int parse_spec_ordinal( int ordinal, DLLSPEC *spec ) }
if (!(token = GetToken(0))) goto error; - if (*token == '-' && !(token = parse_spec_flags( odp ))) goto error; + if (*token == '-' && !(token = parse_spec_flags( spec, odp ))) goto error; + + if (ordinal == -1 && spec->type != SPEC_WIN32 && !(odp->flags & FLAG_EXPORT32)) + { + error( "'@' ordinals not supported for Win16\n" ); + goto error; + }
odp->name = xstrdup( token ); odp->lineno = current_line; @@ -650,7 +653,8 @@ static void assign_names( DLLSPEC *spec ) { const char *name1 = all_names[i]->name ? all_names[i]->name : all_names[i]->export_name; const char *name2 = all_names[i+1]->name ? all_names[i+1]->name : all_names[i+1]->export_name; - if (!strcmp( name1, name2 )) + if (!strcmp( name1, name2 ) && + !((all_names[i]->flags ^ all_names[i+1]->flags) & FLAG_EXPORT32)) { current_line = max( all_names[i]->lineno, all_names[i+1]->lineno ); error( "'%s' redefined\n%s:%d: First defined here\n", @@ -737,12 +741,14 @@ static void assign_ordinals( DLLSPEC *spec ) */ void add_16bit_exports( DLLSPEC *spec32, DLLSPEC *spec16 ) { + int i; ORDDEF *odp;
/* add an export for the NE module */
odp = add_entry_point( spec32 ); odp->type = TYPE_EXTERN; + odp->flags = FLAG_PRIVATE; odp->name = xstrdup( "__wine_spec_dos_header" ); odp->lineno = 0; odp->ordinal = 1; @@ -752,12 +758,32 @@ void add_16bit_exports( DLLSPEC *spec32, DLLSPEC *spec16 ) { odp = add_entry_point( spec32 ); odp->type = TYPE_EXTERN; + odp->flags = FLAG_PRIVATE; odp->name = xstrdup( "__wine_spec_main_module" ); odp->lineno = 0; odp->ordinal = 2; odp->link_name = xstrdup( ".L__wine_spec_main_module" ); }
+ /* add the explicit win32 exports */ + + for (i = 1; i <= spec16->limit; i++) + { + ORDDEF *odp16 = spec16->ordinals[i]; + + if (!odp16 || !odp16->name) continue; + if (!(odp16->flags & FLAG_EXPORT32)) continue; + + odp = add_entry_point( spec32 ); + odp->flags = odp16->flags & ~FLAG_EXPORT32; + odp->type = odp16->type; + odp->name = xstrdup( odp16->name ); + odp->lineno = odp16->lineno; + odp->ordinal = -1; + odp->link_name = xstrdup( odp16->link_name ); + strcpy( odp->u.func.arg_types, odp16->u.func.arg_types ); + } + assign_names( spec32 ); assign_ordinals( spec32 ); } @@ -783,11 +809,6 @@ int parse_spec_file( FILE *file, DLLSPEC *spec ) if (!(token = GetToken(1))) continue; if (strcmp(token, "@") == 0) { - if (spec->type != SPEC_WIN32) - { - error( "'@' ordinals not supported for Win16\n" ); - continue; - } if (!parse_spec_ordinal( -1, spec )) continue; } else if (IsNumberString(token)) diff --git a/tools/winebuild/spec16.c b/tools/winebuild/spec16.c index a0a962f..93c0822 100644 --- a/tools/winebuild/spec16.c +++ b/tools/winebuild/spec16.c @@ -57,6 +57,7 @@ static const char * const nop_sequence[4] =
static inline int is_function( const ORDDEF *odp ) { + if (odp->flags & FLAG_EXPORT32) return 0; return (odp->type == TYPE_CDECL || odp->type == TYPE_PASCAL || odp->type == TYPE_VARARGS || @@ -130,6 +131,7 @@ static void output_entry_table( DLLSPEC *spec ) int selector = 0; ORDDEF *odp = spec->ordinals[i]; if (!odp) continue; + if (odp->flags & FLAG_EXPORT32) continue;
switch (odp->type) { @@ -704,6 +706,7 @@ static void output_module16( DLLSPEC *spec ) { ORDDEF *odp = spec->ordinals[i]; if (!odp || !odp->name[0]) continue; + if (odp->flags & FLAG_EXPORT32) continue; output_resident_name( odp->name, i ); } output( "\t.byte 0\n" );