Alexandre Julliard : winebuild: Support for adding 32-bit exports in 16-bit spec files.
Alexandre Julliard
julliard at winehq.org
Wed Dec 30 10:18:11 CST 2009
Module: wine
Branch: master
Commit: d097eef922d5c3e17fe67cce8011ebd2da955864
URL: http://source.winehq.org/git/wine.git/?a=commit;h=d097eef922d5c3e17fe67cce8011ebd2da955864
Author: Alexandre Julliard <julliard at 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" );
More information about the wine-cvs
mailing list