1 added + 13 modified, total 14 files
reactos/tools/winebuild
diff -N winehq2ros.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ winehq2ros.patch 23 Sep 2004 20:27:30 -0000 1.1
@@ -0,0 +1,86 @@
+Index: main.c
+===================================================================
+RCS file: /home/wine/wine/tools/winebuild/main.c,v
+retrieving revision 1.55
+diff -u -r1.55 main.c
+--- main.c 25 Mar 2004 00:40:52 -0000 1.55
++++ main.c 23 Sep 2004 20:38:14 -0000
+@@ -412,9 +412,7 @@
+ switch (spec->type)
+ {
+ case SPEC_WIN16:
+- if (argv[0])
+- fatal_error( "file argument '%s' not allowed in this mode\n", argv[0] );
+- BuildSpec16File( output_file, spec );
++ fatal_error( "Win16 specs are not supported in ReactOS version of winebuild\n" );
+ break;
+ case SPEC_WIN32:
+ read_undef_symbols( argv );
+@@ -439,12 +437,10 @@
+ BuildDebugFile( output_file, current_src_dir, argv );
+ break;
+ case MODE_RELAY16:
+- if (argv[0]) fatal_error( "file argument '%s' not allowed in this mode\n", argv[0] );
+- BuildRelays16( output_file );
++ fatal_error( "Win16 relays are not supported in ReactOS version of winebuild\n" );
+ break;
+ case MODE_RELAY32:
+- if (argv[0]) fatal_error( "file argument '%s' not allowed in this mode\n", argv[0] );
+- BuildRelays32( output_file );
++ fatal_error( "Win32 relays are not supported in ReactOS version of winebuild\n" );
+ break;
+ default:
+ usage(1);
+Index: spec32.c
+===================================================================
+RCS file: /home/wine/wine/tools/winebuild/spec32.c,v
+retrieving revision 1.83
+diff -u -r1.83 spec32.c
+--- spec32.c 15 Jul 2004 18:58:42 -0000 1.83
++++ spec32.c 23 Sep 2004 20:38:15 -0000
+@@ -30,9 +30,15 @@
+ #include <stdarg.h>
+ #include <string.h>
+
++#ifdef WIN32
+ #include "windef.h"
+ #include "winbase.h"
+-#include "wine/exception.h"
++#else
++#include "winglue.h"
++#endif
++#define EXCEPTION_WINE_STUB 0x80000100 /* stub entry point called */
++#define EH_NONCONTINUABLE 0x01
++
+ #include "build.h"
+
+
+@@ -886,7 +892,10 @@
+ fprintf( outfile, " @%d", odp->ordinal );
+ if (!odp->name) fprintf( outfile, " NONAME" );
+ if (is_data) fprintf( outfile, " DATA" );
++#if 0
++ /* MinGW binutils cannot handle this correctly */
+ if (odp->flags & FLAG_PRIVATE) fprintf( outfile, " PRIVATE" );
++#endif
+ fprintf( outfile, "\n" );
+ }
+ }
+Index: utils.c
+===================================================================
+RCS file: /home/wine/wine/tools/winebuild/utils.c,v
+retrieving revision 1.20
+diff -u -r1.20 utils.c
+--- utils.c 25 Mar 2004 00:40:52 -0000 1.20
++++ utils.c 23 Sep 2004 20:38:15 -0000
+@@ -21,6 +21,10 @@
+ #include "config.h"
+ #include "wine/port.h"
+
++#if !defined(WIN32)
++#undef strdup
++#endif
++
+ #include <ctype.h>
+ #include <stdarg.h>
+ #include <stdio.h>
reactos/tools/winebuild
diff -u -r1.4 -r1.5
--- Makefile 21 Feb 2004 09:20:34 -0000 1.4
+++ Makefile 23 Sep 2004 20:27:30 -0000 1.5
@@ -20,7 +20,7 @@
CLEAN_FILES = *.o $(TARGET)
-HOST_CFLAGS = -D__USE_W32API -D__REACTOS__ -I$(PATH_TO_TOP)/include -I$(PATH_TO_TOP)/include/wine -I$(W32API_PATH)/include
+HOST_CFLAGS = -D__USE_W32API -I$(PATH_TO_TOP)/include -I$(PATH_TO_TOP)/include/wine -I$(W32API_PATH)/include
%.o: %.c
$(HOST_CC) $(HOST_CFLAGS) -c $< -o $@
reactos/tools/winebuild
diff -u -r1.1 -r1.2
--- build.h 9 Dec 2003 18:44:25 -0000 1.1
+++ build.h 23 Sep 2004 20:27:30 -0000 1.2
@@ -50,15 +50,6 @@
SPEC_WIN32
} SPEC_TYPE;
-typedef enum
-{
- SPEC_MODE_DLL,
- SPEC_MODE_GUIEXE,
- SPEC_MODE_CUIEXE,
- SPEC_MODE_GUIEXE_UNICODE,
- SPEC_MODE_CUIEXE_UNICODE
-} SPEC_MODE;
-
typedef struct
{
int n_values;
@@ -67,7 +58,6 @@
typedef struct
{
- int n_args;
char arg_types[21];
} ORD_FUNCTION;
@@ -94,6 +84,31 @@
} u;
} ORDDEF;
+typedef struct
+{
+ char *file_name; /* file name of the dll */
+ char *dll_name; /* internal name of the dll */
+ char *owner_name; /* name of the 32-bit dll owning this one */
+ char *init_func; /* initialization routine */
+ SPEC_TYPE type; /* type of dll (Win16/Win32) */
+ int base; /* ordinal base */
+ int limit; /* ordinal limit */
+ int stack_size; /* exe stack size */
+ int heap_size; /* exe heap size */
+ int nb_entry_points; /* number of used entry points */
+ int alloc_entry_points; /* number of allocated entry points */
+ int nb_names; /* number of entry points with names */
+ int nb_resources; /* number of resources */
+ int characteristics; /* characteristics for the PE header */
+ int subsystem; /* subsystem id */
+ int subsystem_major; /* subsystem version major number */
+ int subsystem_minor; /* subsystem version minor number */
+ ORDDEF *entry_points; /* dll entry points */
+ ORDDEF **names; /* array of entry point names (points into entry_points) */
+ ORDDEF **ordinals; /* array of dll ordinals (points into entry_points) */
+ struct resource *resources; /* array of dll resources (format differs between Win16/Win32) */
+} DLLSPEC;
+
/* entry point flags */
#define FLAG_NORELAY 0x01 /* don't use relay debugging for this function */
#define FLAG_NONAME 0x02 /* don't import function by name */
@@ -101,10 +116,9 @@
#define FLAG_RET64 0x08 /* function returns a 64-bit value */
#define FLAG_I386 0x10 /* function is i386 only */
#define FLAG_REGISTER 0x20 /* use register calling convention */
-#define FLAG_INTERRUPT 0x40 /* function is an interrupt handler */
-#define FLAG_PRIVATE 0x80 /* function is private (cannot be imported) */
+#define FLAG_PRIVATE 0x40 /* function is private (cannot be imported) */
-#define FLAG_FORWARD 0x100 /* function is a forwarded name */
+#define FLAG_FORWARD 0x80 /* function is a forwarded name */
/* Offset of a structure field relative to the start of the struct */
#define STRUCTOFFSET(type,field) ((int)&((type *)0)->field)
@@ -147,60 +161,49 @@
extern void close_input_file( FILE *file );
extern void dump_bytes( FILE *outfile, const unsigned char *data, int len,
const char *label, int constant );
+extern int remove_stdcall_decoration( char *name );
+extern DLLSPEC *alloc_dll_spec(void);
+extern void free_dll_spec( DLLSPEC *spec );
extern const char *make_c_identifier( const char *str );
extern int get_alignment(int alignBoundary);
extern void add_import_dll( const char *name, int delay );
extern void add_ignore_symbol( const char *name );
extern void read_undef_symbols( char **argv );
-extern int resolve_imports( void );
-extern int output_imports( FILE *outfile );
-extern int load_res32_file( const char *name );
-extern int output_resources( FILE *outfile );
-extern void load_res16_file( const char *name );
-extern int output_res16_data( FILE *outfile );
-extern int output_res16_directory( unsigned char *buffer );
+extern int resolve_imports( DLLSPEC *spec );
+extern int output_imports( FILE *outfile, DLLSPEC *spec );
+extern int load_res32_file( const char *name, DLLSPEC *spec );
+extern void output_resources( FILE *outfile, DLLSPEC *spec );
+extern void load_res16_file( const char *name, DLLSPEC *spec );
+extern int output_res16_data( FILE *outfile, DLLSPEC *spec );
+extern int output_res16_directory( unsigned char *buffer, DLLSPEC *spec );
extern void output_dll_init( FILE *outfile, const char *constructor, const char *destructor );
-extern int parse_debug_channels( const char *srcdir, const char *filename );
extern void BuildRelays16( FILE *outfile );
extern void BuildRelays32( FILE *outfile );
-extern void BuildSpec16File( FILE *outfile );
-extern void BuildSpec32File( FILE *outfile );
-extern void BuildDef32File( FILE *outfile );
+extern void BuildSpec16File( FILE *outfile, DLLSPEC *spec );
+extern void BuildSpec32File( FILE *outfile, DLLSPEC *spec );
+extern void BuildDef32File( FILE *outfile, DLLSPEC *spec );
extern void BuildDebugFile( FILE *outfile, const char *srcdir, char **argv );
-extern int ParseTopLevel( FILE *file );
+
+extern int parse_spec_file( FILE *file, DLLSPEC *spec );
+extern int parse_def_file( FILE *file, DLLSPEC *spec );
+extern int parse_debug_channels( const char *srcdir, const char *filename );
/* global variables */
extern int current_line;
-extern int nb_entry_points;
-extern int nb_names;
-extern int Base;
-extern int Limit;
-extern int DLLHeapSize;
extern int UsePIC;
extern int debugging;
-extern int stack_size;
extern int nb_debug_channels;
extern int nb_lib_paths;
extern int nb_errors;
extern int display_warnings;
extern int kill_at;
-extern char *owner_name;
-extern char *dll_name;
-extern char *dll_file_name;
-extern const char *init_func;
extern char *input_file_name;
extern const char *output_file_name;
extern char **debug_channels;
extern char **lib_path;
-extern ORDDEF *EntryPoints[MAX_ORDINALS];
-extern ORDDEF *Ordinals[MAX_ORDINALS];
-extern ORDDEF *Names[MAX_ORDINALS];
-extern SPEC_MODE SpecMode;
-extern SPEC_TYPE SpecType;
-
#endif /* __WINE_BUILD_H */
reactos/tools/winebuild
diff -u -r1.3 -r1.4
--- import.c 5 Jan 2004 19:49:59 -0000 1.3
+++ import.c 23 Sep 2004 20:27:30 -0000 1.4
@@ -1,8 +1,8 @@
/*
* DLL imports support
*
- * Copyright 2000 Alexandre Julliard
- * 2000 Eric Pouech
+ * Copyright 2000, 2004 Alexandre Julliard
+ * Copyright 2000 Eric Pouech
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -26,32 +26,22 @@
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
+#include <stdarg.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
-#if defined(WIN32)
-#include <windows.h>
-#else
-#include <limits.h>
-#endif
-
+#include "windef.h"
+#include "winbase.h"
#include "build.h"
-struct func
-{
- char *name; /* function name */
- int ordinal; /* function ordinal */
- int ord_only; /* non-zero if function is imported by ordinal */
-};
-
struct import
{
- char *dll; /* dll name */
+ DLLSPEC *spec; /* description of the imported dll */
int delay; /* delay or not dll loading ? */
- struct func *exports; /* functions exported from this dll */
+ ORDDEF **exports; /* functions exported from this dll */
int nb_exports; /* number of exported functions */
- struct func *imports; /* functions we want to import from this dll */
+ ORDDEF **imports; /* functions we want to import from this dll */
int nb_imports; /* number of imported functions */
};
@@ -143,13 +133,16 @@
/* compare function names; helper for resolve_imports */
static int name_cmp( const void *name, const void *entry )
{
- return strcmp( *(char **)name, *(char **)entry );
+ return strcmp( *(const char* const *)name, *(const char* const *)entry );
}
/* compare function names; helper for resolve_imports */
static int func_cmp( const void *func1, const void *func2 )
{
- return strcmp( ((struct func *)func1)->name, ((struct func *)func2)->name );
+ const ORDDEF *odp1 = *(const ORDDEF * const *)func1;
+ const ORDDEF *odp2 = *(const ORDDEF * const *)func2;
+ return strcmp( odp1->name ? odp1->name : odp1->export_name,
+ odp2->name ? odp2->name : odp2->export_name );
}
/* locate a symbol in a (sorted) list */
@@ -165,14 +158,15 @@
}
/* locate an export in a (sorted) export list */
-inline static struct func *find_export( const char *name, struct func *table, int size )
+inline static ORDDEF *find_export( const char *name, ORDDEF **table, int size )
{
- struct func func, *res = NULL;
+ ORDDEF func, *odp, **res = NULL;
func.name = (char *)name;
func.ordinal = -1;
- if (table) res = bsearch( &func, table, size, sizeof(*table), func_cmp );
- return res;
+ odp = &func;
+ if (table) res = bsearch( &odp, table, size, sizeof(*table), func_cmp );
+ return res ? *res : NULL;
}
/* sort a symbol table */
@@ -182,16 +176,19 @@
qsort( table, size, sizeof(*table), name_cmp );
}
+inline static void output_function_size( FILE *outfile, const char *name )
+{
+#ifdef HAVE_ASM_DOT_SIZE
+ fprintf( outfile, " \"\\t.size " __ASM_NAME("%s") ", . - " __ASM_NAME("%s") "\\n\"\n", name, name);
+#endif
+}
+
/* free an import structure */
static void free_imports( struct import *imp )
{
- int i;
-
- for (i = 0; i < imp->nb_exports; i++) free( imp->exports[i].name );
- for (i = 0; i < imp->nb_imports; i++) free( imp->imports[i].name );
free( imp->exports );
free( imp->imports );
- free( imp->dll );
+ free_dll_spec( imp->spec );
free( imp );
}
@@ -208,7 +205,7 @@
for (i = 0; i < nb_imports; i++)
{
- if (!strcmp( dll_imports[i]->dll, name )) return 1;
+ if (!strcmp( dll_imports[i]->spec->file_name, name )) return 1;
}
return 0;
}
@@ -242,157 +239,44 @@
{
if ((fullname = try_library_path( lib_path[i], name ))) return fullname;
}
- if (!(fullname = try_library_path( ".", name )))
- fatal_error( "could not open .def file for %s\n", name );
- return fullname;
-}
-
-/* skip whitespace until the next token */
-static char *skip_whitespace( char *p )
-{
- while (*p && isspace(*p)) p++;
- if (!*p || *p == ';') p = NULL;
- return p;
-}
-
-/* skip to the start of the next token, null terminating the current one */
-static char *next_token( char *p )
-{
- while (*p && !isspace(*p)) p++;
- if (*p) *p++ = 0;
- return skip_whitespace( p );
-}
-
-/* remove the @nn suffix from stdcall names */
-static char *remove_stdcall_decoration( char *buffer )
-{
- char *p = buffer + strlen(buffer) - 1;
- while (p > buffer && isdigit(*p)) p--;
- if (p > buffer && *p == '@') *p = 0;
- return buffer;
+ fatal_error( "could not open .def file for %s\n", name );
+ return NULL;
}
/* read in the list of exported symbols of an import library */
static int read_import_lib( const char *name, struct import *imp )
{
FILE *f;
- char buffer[1024];
char *fullname;
- int size;
+ int i, ret;
+ DLLSPEC *spec = imp->spec;
imp->exports = NULL;
- imp->nb_exports = size = 0;
+ imp->nb_exports = 0;
fullname = open_library( name );
f = open_input_file( NULL, fullname );
free( fullname );
- while (fgets( buffer, sizeof(buffer), f ))
- {
- char *name, *flags;
- int ordinal = 0, ord_only = 0;
-
- char *p = buffer + strlen(buffer) - 1;
- if (p < buffer) goto next;
- if (*p == '\n') *p-- = 0;
-
- p = buffer;
- if (!(p = skip_whitespace(p))) goto next;
- name = p;
- p = next_token( name );
-
- if (!strcmp( name, "LIBRARY" ))
- {
- if (!p)
- {
- error( "Expected name after LIBRARY\n" );
- goto next;
- }
- name = p;
- p = next_token( name );
- if (p)
- {
- error( "Garbage after LIBRARY statement\n" );
- goto next;
- }
- if (is_already_imported( name ))
- {
- close_input_file( f );
- return 0; /* ignore this dll */
- }
- free( imp->dll );
- imp->dll = xstrdup( name );
- goto next;
- }
- if (!strcmp( name, "EXPORTS" )) goto next;
+ ret = parse_def_file( f, spec );
+ close_input_file( f );
+ if (!ret) return 0;
+ if (is_already_imported( spec->file_name )) return 0;
- /* check for ordinal */
- if (!p)
- {
- error( "Expected ordinal after function name\n" );
- goto next;
- }
- if (*p != '@' || !isdigit(p[1]))
- {
- error( "Expected ordinal after function name '%s'\n", name );
- goto next;
- }
- ordinal = strtol( p+1, &p, 10 );
- if (ordinal >= MAX_ORDINALS)
- {
- error( "Invalid ordinal number %d\n", ordinal );
- goto next;
- }
+ imp->exports = xmalloc( spec->nb_entry_points * sizeof(*imp->exports) );
- /* check for optional flags */
- while (p && (p = skip_whitespace(p)))
- {
- flags = p;
- p = next_token( flags );
- if (!strcmp( flags, "NONAME" ))
- {
- ord_only = 1;
- if (!ordinal)
- {
- error( "Invalid ordinal number %d\n", ordinal );
- goto next;
- }
- }
- else if (!strcmp( flags, "CONSTANT" ) || !strcmp( flags, "DATA" ))
- {
- /* we don't support importing non-function entry points */
- goto next;
- }
- else if (!strcmp( flags, "PRIVATE" ))
- {
- /* function must not be imported */
- goto next;
- }
- else
- {
- error( "Garbage after ordinal declaration\n" );
- goto next;
- }
- }
+ for (i = 0; i < spec->nb_entry_points; i++)
+ {
+ ORDDEF *odp = &spec->entry_points[i];
- if (imp->nb_exports == size)
- {
- size += 128;
- imp->exports = xrealloc( imp->exports, size * sizeof(*imp->exports) );
- }
- if ((p = strchr( name, '=' ))) *p = 0;
- remove_stdcall_decoration( name );
- imp->exports[imp->nb_exports].name = xstrdup( name );
- imp->exports[imp->nb_exports].ordinal = ordinal;
- imp->exports[imp->nb_exports].ord_only = ord_only;
- imp->nb_exports++;
- next:
- current_line++;
+ if (odp->type != TYPE_STDCALL && odp->type != TYPE_CDECL) continue;
+ if (odp->flags & FLAG_PRIVATE) continue;
+ imp->exports[imp->nb_exports++] = odp;
}
- close_input_file( f );
+ imp->exports = xrealloc( imp->exports, imp->nb_exports * sizeof(*imp->exports) );
if (imp->nb_exports)
qsort( imp->exports, imp->nb_exports, sizeof(*imp->exports), func_cmp );
- return !nb_errors;
+ return 1;
}
/* add a dll to the list of imports */
@@ -413,11 +297,11 @@
}
imp = xmalloc( sizeof(*imp) );
- imp->dll = fullname;
- imp->delay = delay;
- imp->imports = NULL;
- imp->nb_imports = 0;
-
+ imp->spec = alloc_dll_spec();
+ imp->spec->file_name = fullname;
+ imp->delay = delay;
+ imp->imports = NULL;
+ imp->nb_imports = 0;
if (delay) nb_delayed++;
if (read_import_lib( name, imp ))
@@ -495,13 +379,10 @@
}
/* add a function to the list of imports from a given dll */
-static void add_import_func( struct import *imp, const struct func *func )
+static void add_import_func( struct import *imp, ORDDEF *func )
{
imp->imports = xrealloc( imp->imports, (imp->nb_imports+1) * sizeof(*imp->imports) );
- imp->imports[imp->nb_imports].name = xstrdup( func->name );
- imp->imports[imp->nb_imports].ordinal = func->ordinal;
- imp->imports[imp->nb_imports].ord_only = func->ord_only;
- imp->nb_imports++;
+ imp->imports[imp->nb_imports++] = func;
total_imports++;
if (imp->delay) total_delayed++;
}
@@ -531,16 +412,16 @@
}
/* add a symbol to the extra list, but only if needed */
-static int add_extra_symbol( const char **extras, int *count, const char *name )
+static int add_extra_symbol( const char **extras, int *count, const char *name, const DLLSPEC *spec )
{
int i;
if (!find_symbol( name, undef_symbols, nb_undef_symbols ))
{
/* check if the symbol is being exported by this dll */
- for (i = 0; i < nb_entry_points; i++)
+ for (i = 0; i < spec->nb_entry_points; i++)
{
- ORDDEF *odp = EntryPoints[i];
+ ORDDEF *odp = &spec->entry_points[i];
if (odp->type == TYPE_STDCALL ||
odp->type == TYPE_CDECL ||
odp->type == TYPE_VARARGS ||
@@ -556,7 +437,7 @@
}
/* add the extra undefined symbols that will be contained in the generated spec file itself */
-static void add_extra_undef_symbols(void)
+static void add_extra_undef_symbols( const DLLSPEC *spec )
{
const char *extras[10];
int i, count = 0, nb_stubs = 0, nb_regs = 0;
@@ -564,44 +445,36 @@
sort_symbols( undef_symbols, nb_undef_symbols );
- for (i = 0; i < nb_entry_points; i++)
+ for (i = 0; i < spec->nb_entry_points; i++)
{
- ORDDEF *odp = EntryPoints[i];
+ ORDDEF *odp = &spec->entry_points[i];
if (odp->type == TYPE_STUB) nb_stubs++;
if (odp->flags & FLAG_REGISTER) nb_regs++;
}
/* add symbols that will be contained in the spec file itself */
- switch (SpecMode)
+ if (!(spec->characteristics & IMAGE_FILE_DLL))
{
- case SPEC_MODE_DLL:
- break;
- case SPEC_MODE_GUIEXE:
- kernel_imports += add_extra_symbol( extras, &count, "GetCommandLineA" );
- kernel_imports += add_extra_symbol( extras, &count, "GetStartupInfoA" );
- kernel_imports += add_extra_symbol( extras, &count, "GetModuleHandleA" );
- /* fall through */
- case SPEC_MODE_CUIEXE:
- kernel_imports += add_extra_symbol( extras, &count, "ExitProcess" );
- break;
- case SPEC_MODE_GUIEXE_UNICODE:
- kernel_imports += add_extra_symbol( extras, &count, "GetCommandLineA" );
- kernel_imports += add_extra_symbol( extras, &count, "GetStartupInfoA" );
- kernel_imports += add_extra_symbol( extras, &count, "GetModuleHandleA" );
- /* fall through */
- case SPEC_MODE_CUIEXE_UNICODE:
- kernel_imports += add_extra_symbol( extras, &count, "ExitProcess" );
- break;
+ switch (spec->subsystem)
+ {
+ case IMAGE_SUBSYSTEM_WINDOWS_GUI:
+ case IMAGE_SUBSYSTEM_WINDOWS_CUI:
+ kernel_imports += add_extra_symbol( extras, &count, "GetCommandLineA", spec );
+ kernel_imports += add_extra_symbol( extras, &count, "GetStartupInfoA", spec );
+ kernel_imports += add_extra_symbol( extras, &count, "GetModuleHandleA", spec );
+ kernel_imports += add_extra_symbol( extras, &count, "ExitProcess", spec );
+ break;
+ }
}
if (nb_delayed)
{
- kernel_imports += add_extra_symbol( extras, &count, "LoadLibraryA" );
- kernel_imports += add_extra_symbol( extras, &count, "GetProcAddress" );
+ kernel_imports += add_extra_symbol( extras, &count, "LoadLibraryA", spec );
+ kernel_imports += add_extra_symbol( extras, &count, "GetProcAddress", spec );
}
if (nb_regs)
- ntdll_imports += add_extra_symbol( extras, &count, "__wine_call_from_32_regs" );
+ ntdll_imports += add_extra_symbol( extras, &count, "__wine_call_from_32_regs", spec );
if (nb_delayed || nb_stubs)
- ntdll_imports += add_extra_symbol( extras, &count, "RtlRaiseException" );
+ ntdll_imports += add_extra_symbol( extras, &count, "RtlRaiseException", spec );
/* make sure we import the dlls that contain these functions */
if (kernel_imports) add_import_dll( "kernel32", 0 );
@@ -615,18 +488,19 @@
}
/* check if a given imported dll is not needed, taking forwards into account */
-static int check_unused( const struct import* imp )
+static int check_unused( const struct import* imp, const DLLSPEC *spec )
{
int i;
- size_t len = strlen(imp->dll);
- const char *p = strchr( imp->dll, '.' );
- if (p && !strcasecmp( p, ".dll" )) len = p - imp->dll;
+ const char *file_name = imp->spec->file_name;
+ size_t len = strlen( file_name );
+ const char *p = strchr( file_name, '.' );
+ if (p && !strcasecmp( p, ".dll" )) len = p - file_name;
- for (i = Base; i <= Limit; i++)
+ for (i = spec->base; i <= spec->limit; i++)
{
- ORDDEF *odp = Ordinals[i];
+ ORDDEF *odp = spec->ordinals[i];
if (!odp || !(odp->flags & FLAG_FORWARD)) continue;
- if (!strncasecmp( odp->link_name, imp->dll, len ) &&
+ if (!strncasecmp( odp->link_name, file_name, len ) &&
odp->link_name[len] == '.')
return 0; /* found a forward, it is used */
}
@@ -638,35 +512,26 @@
static const char *ldcombine_files( char **argv )
{
int i, len = 0;
- char *cmd;
+ char *cmd, *ldcmd;
int fd, err;
-#if defined(WIN32)
- char tmppath[MAX_PATH];
- char tmpfile[MAX_PATH];
-#endif
-#if defined(WIN32)
- if (GetTempPathA(MAX_PATH, tmppath) == 0) return NULL;
- if (GetTempFileNameA(tmppath, "WNB", 0, tmpfile) == 0) fatal_error( "could not generate a temp file\n" );
- ld_tmp_file = xstrdup( tmpfile );
- if ((fd = open( ld_tmp_file, O_RDONLY )) == -1)
-#else
- if (output_file_name && output_file_name[0])
+ if (output_file_name && output_file_name[0])
{
- ld_tmp_file = xmalloc( PATH_MAX );
+ ld_tmp_file = xmalloc( strlen(output_file_name) + 10 );
strcpy( ld_tmp_file, output_file_name );
strcat( ld_tmp_file, ".XXXXXX.o" );
}
- else ld_tmp_file = xstrdup( "/tmp/winebuild.tmp.XXXXXX.o" );
- if ((fd = mkstemps( ld_tmp_file, 2 ) == -1)) fatal_error( "could not generate a temp file\n" );
-#endif
+ else ld_tmp_file = xstrdup( "/tmp/winebuild.tmp.XXXXXX.o" );
+ if ((fd = mkstemps( ld_tmp_file, 2 ) == -1)) fatal_error( "could not generate a temp file\n" );
close( fd );
atexit( remove_ld_tmp_file );
+ ldcmd = getenv("LD");
+ if (!ldcmd) ldcmd = "ld";
for (i = 0; argv[i]; i++) len += strlen(argv[i]) + 1;
- cmd = xmalloc( len + strlen(ld_tmp_file) + 10 );
- sprintf( cmd, "ld -r -o %s", ld_tmp_file );
+ cmd = xmalloc( len + strlen(ld_tmp_file) + 8 + strlen(ldcmd) );
+ sprintf( cmd, "%s -r -o %s", ldcmd, ld_tmp_file );
for (i = 0; argv[i]; i++) sprintf( cmd + strlen(cmd), " %s", argv[i] );
err = system( cmd );
if (err) fatal_error( "ld -r failed with status %d\n", err );
@@ -677,6 +542,8 @@
/* read in the list of undefined symbols */
void read_undef_symbols( char **argv )
{
+ static const char name_prefix[] = __ASM_NAME("");
+ static const int prefix_len = sizeof(name_prefix) - 1;
FILE *f;
char buffer[1024];
int err;
@@ -702,6 +569,7 @@
p = buffer;
while (*p == ' ') p++;
if (p[0] == 'U' && p[1] == ' ' && p[2]) p += 2;
+ if (prefix_len && !strncmp( p, name_prefix, prefix_len )) p += prefix_len;
add_undef_symbol( p );
}
if ((err = pclose( f ))) warning( "nm -u %s error %d\n", name, err );
@@ -725,13 +593,13 @@
}
/* resolve the imports for a Win32 module */
-int resolve_imports( void )
+int resolve_imports( DLLSPEC *spec )
{
int i, j;
if (nb_undef_symbols == -1) return 0; /* no symbol file specified */
- add_extra_undef_symbols();
+ add_extra_undef_symbols( spec );
remove_ignored_symbols();
for (i = 0; i < nb_imports; i++)
@@ -740,19 +608,19 @@
for (j = 0; j < nb_undef_symbols; j++)
{
- struct func *func = find_export( undef_symbols[j], imp->exports, imp->nb_exports );
- if (func)
+ ORDDEF *odp = find_export( undef_symbols[j], imp->exports, imp->nb_exports );
+ if (odp)
{
- add_import_func( imp, func );
+ add_import_func( imp, odp );
free( undef_symbols[j] );
undef_symbols[j] = NULL;
}
}
/* remove all the holes in the undef symbols list */
- if (!remove_symbol_holes() && check_unused( imp ))
+ if (!remove_symbol_holes() && check_unused( imp, spec ))
{
/* the dll is not used, get rid of it */
- warning( "%s imported but no symbols used\n", imp->dll );
+ warning( "%s imported but no symbols used\n", imp->spec->file_name );
remove_import_dll( i );
i--;
}
@@ -765,6 +633,7 @@
{
int i, j, pos;
int nb_imm = nb_imports - nb_delayed;
+ static const char import_thunks[] = "__wine_spec_import_thunks";
if (!nb_imm) goto done;
@@ -788,7 +657,7 @@
{
if (dll_imports[i]->delay) continue;
fprintf( outfile, " { 0, 0, 0, \"%s\", &imports.data[%d] },\n",
- dll_imports[i]->dll, j );
+ dll_imports[i]->spec->file_name, j );
j += dll_imports[i]->nb_imports + 1;
}
@@ -800,18 +669,18 @@
for (i = 0; i < nb_imports; i++)
{
if (dll_imports[i]->delay) continue;
- fprintf( outfile, " /* %s */\n", dll_imports[i]->dll );
+ fprintf( outfile, " /* %s */\n", dll_imports[i]->spec->file_name );
for (j = 0; j < dll_imports[i]->nb_imports; j++)
{
- struct func *import = &dll_imports[i]->imports[j];
- if (!import->ord_only)
+ ORDDEF *odp = dll_imports[i]->imports[j];
+ if (!(odp->flags & FLAG_NONAME))
{
- unsigned short ord = import->ordinal;
+ unsigned short ord = odp->ordinal;
fprintf( outfile, " \"\\%03o\\%03o%s\",\n",
- *(unsigned char *)&ord, *((unsigned char *)&ord + 1), import->name );
+ *(unsigned char *)&ord, *((unsigned char *)&ord + 1), odp->name );
}
else
- fprintf( outfile, " (char *)%d,\n", import->ordinal );
+ fprintf( outfile, " (char *)%d,\n", odp->ordinal );
}
fprintf( outfile, " 0,\n" );
}
@@ -822,18 +691,21 @@
fprintf( outfile, "#ifndef __GNUC__\nstatic void __asm__dummy_import(void) {\n#endif\n\n" );
pos = 20 * (nb_imm + 1); /* offset of imports.data from start of imports */
fprintf( outfile, "asm(\".data\\n\\t.align %d\\n\"\n", get_alignment(8) );
+ fprintf( outfile, " \"" __ASM_NAME("%s") ":\\n\"\n", import_thunks);
+
for (i = 0; i < nb_imports; i++)
{
if (dll_imports[i]->delay) continue;
for (j = 0; j < dll_imports[i]->nb_imports; j++, pos += 4)
{
- struct func *import = &dll_imports[i]->imports[j];
- fprintf( outfile, " \"\\t" __ASM_FUNC("%s") "\\n\"\n", import->name );
- fprintf( outfile, " \"\\t.globl " __ASM_NAME("%s") "\\n\"\n", import->name );
- fprintf( outfile, " \"" __ASM_NAME("%s") ":\\n\\t", import->name);
+ ORDDEF *odp = dll_imports[i]->imports[j];
+ const char *name = odp->name ? odp->name : odp->export_name;
+ fprintf( outfile, " \"\\t" __ASM_FUNC("%s") "\\n\"\n", name );
+ fprintf( outfile, " \"\\t.globl " __ASM_NAME("%s") "\\n\"\n", name );
+ fprintf( outfile, " \"" __ASM_NAME("%s") ":\\n\\t", name);
#if defined(__i386__)
- if (strstr( import->name, "__wine_call_from_16" ))
+ if (strstr( name, "__wine_call_from_16" ))
fprintf( outfile, ".byte 0x2e\\n\\tjmp *(imports+%d)\\n\\tnop\\n", pos );
else
fprintf( outfile, "jmp *(imports+%d)\\n\\tmovl %%esi,%%esi\\n", pos );
@@ -880,19 +752,23 @@
#error You need to define import thunks for your architecture!
#endif
fprintf( outfile, "\"\n" );
+ output_function_size( outfile, name );
}
pos += 4;
}
- fprintf( outfile, "\".text\");\n#ifndef __GNUC__\n}\n#endif\n\n" );
+ output_function_size( outfile, import_thunks );
+ fprintf( outfile, " \".text\");\n#ifndef __GNUC__\n}\n#endif\n\n" );
done:
return nb_imm;
}
/* output the delayed import table of a Win32 module */
-static int output_delayed_imports( FILE *outfile )
+static int output_delayed_imports( FILE *outfile, const DLLSPEC *spec )
{
int i, idx, j, pos;
+ static const char delayed_import_loaders[] = "__wine_spec_delayed_import_loaders";
+ static const char delayed_import_thunks[] = "__wine_spec_delayed_import_thunks";
if (!nb_delayed) goto done;
@@ -902,8 +778,9 @@
fprintf( outfile, "static void *__wine_delay_imp_%d_hmod;\n", i);
for (j = 0; j < dll_imports[i]->nb_imports; j++)
{
- fprintf( outfile, "void __wine_delay_imp_%d_%s();\n",
- i, dll_imports[i]->imports[j].name );
+ ORDDEF *odp = dll_imports[i]->imports[j];
+ const char *name = odp->name ? odp->name : odp->export_name;
+ fprintf( outfile, "void __wine_delay_imp_%d_%s();\n", i, name );
}
}
fprintf( outfile, "\n" );
@@ -926,31 +803,33 @@
{
if (!dll_imports[i]->delay) continue;
fprintf( outfile, " { 0, \"%s\", &__wine_delay_imp_%d_hmod, &delay_imports.IAT[%d], &delay_imports.INT[%d], 0, 0, 0 },\n",
- dll_imports[i]->dll, i, j, j );
+ dll_imports[i]->spec->file_name, i, j, j );
j += dll_imports[i]->nb_imports;
}
fprintf( outfile, " },\n {\n" );
for (i = 0; i < nb_imports; i++)
{
if (!dll_imports[i]->delay) continue;
- fprintf( outfile, " /* %s */\n", dll_imports[i]->dll );
+ fprintf( outfile, " /* %s */\n", dll_imports[i]->spec->file_name );
for (j = 0; j < dll_imports[i]->nb_imports; j++)
{
- fprintf( outfile, " &__wine_delay_imp_%d_%s,\n", i, dll_imports[i]->imports[j].name);
+ ORDDEF *odp = dll_imports[i]->imports[j];
+ const char *name = odp->name ? odp->name : odp->export_name;
+ fprintf( outfile, " &__wine_delay_imp_%d_%s,\n", i, name );
}
}
fprintf( outfile, " },\n {\n" );
for (i = 0; i < nb_imports; i++)
{
if (!dll_imports[i]->delay) continue;
- fprintf( outfile, " /* %s */\n", dll_imports[i]->dll );
+ fprintf( outfile, " /* %s */\n", dll_imports[i]->spec->file_name );
for (j = 0; j < dll_imports[i]->nb_imports; j++)
{
- struct func *import = &dll_imports[i]->imports[j];
- if (import->ord_only)
- fprintf( outfile, " (char *)%d,\n", import->ordinal );
+ ORDDEF *odp = dll_imports[i]->imports[j];
+ if (!odp->name)
+ fprintf( outfile, " (char *)%d,\n", odp->ordinal );
else
- fprintf( outfile, " \"%s\",\n", import->name );
+ fprintf( outfile, " \"%s\",\n", odp->name );
}
}
fprintf( outfile, " }\n};\n\n" );
@@ -958,9 +837,9 @@
/* check if there's some stub defined. if so, exception struct
* is already defined, so don't emit it twice
*/
- for (i = 0; i < nb_entry_points; i++) if (EntryPoints[i]->type == TYPE_STUB) break;
+ for (i = 0; i < spec->nb_entry_points; i++) if (spec->entry_points[i].type == TYPE_STUB) break;
- if (i == nb_entry_points) {
+ if (i == spec->nb_entry_points) {
fprintf( outfile, "struct exc_record {\n" );
fprintf( outfile, " unsigned int code, flags;\n" );
fprintf( outfile, " void *rec, *addr;\n" );
@@ -993,7 +872,7 @@
fprintf( outfile, " rec.rec = 0;\n" );
fprintf( outfile, " rec.params = 2;\n" );
fprintf( outfile, " rec.info[0] = imd->szName;\n" );
- fprintf( outfile, " rec.info[1] = *pINT + 2;\n" );
+ fprintf( outfile, " rec.info[1] = *pINT;\n" );
fprintf( outfile, "#ifdef __GNUC__\n" );
fprintf( outfile, " rec.addr = __builtin_return_address(1);\n" );
fprintf( outfile, "#else\n" );
@@ -1008,6 +887,7 @@
fprintf( outfile, "#endif\n" );
fprintf( outfile, "asm(\".align %d\\n\"\n", get_alignment(8) );
+ fprintf( outfile, " \"" __ASM_NAME("%s") ":\\n\"\n", delayed_import_loaders);
fprintf( outfile, " \"\\t" __ASM_FUNC("__wine_delay_load_asm") "\\n\"\n" );
fprintf( outfile, " \"" __ASM_NAME("__wine_delay_load_asm") ":\\n\"\n" );
#if defined(__i386__)
@@ -1020,25 +900,31 @@
fprintf( outfile, " \"\\tmov %%g1, %%o0\\n\"\n" );
fprintf( outfile, " \"\\tjmp %%o0\\n\\trestore\\n\"\n" );
#elif defined(__powerpc__)
+# if defined(__APPLE__)
+/* On darwin an extra 56 bytes must be allowed for the linkage area+param area */
+# define extra_stack_storage 56
+# else
+# define extra_stack_storage 0
+# endif
/* Save all callee saved registers into a stackframe. */
- fprintf( outfile, " \"\\tstwu %s, -48(%s)\\n\"\n", ppc_reg[1], ppc_reg[1]);
- fprintf( outfile, " \"\\tstw %s, 4(%s)\\n\"\n", ppc_reg[3], ppc_reg[1]);
- fprintf( outfile, " \"\\tstw %s, 8(%s)\\n\"\n", ppc_reg[4], ppc_reg[1]);
- fprintf( outfile, " \"\\tstw %s, 12(%s)\\n\"\n", ppc_reg[5], ppc_reg[1]);
- fprintf( outfile, " \"\\tstw %s, 16(%s)\\n\"\n", ppc_reg[6], ppc_reg[1]);
- fprintf( outfile, " \"\\tstw %s, 20(%s)\\n\"\n", ppc_reg[7], ppc_reg[1]);
- fprintf( outfile, " \"\\tstw %s, 24(%s)\\n\"\n", ppc_reg[8], ppc_reg[1]);
- fprintf( outfile, " \"\\tstw %s, 28(%s)\\n\"\n", ppc_reg[9], ppc_reg[1]);
- fprintf( outfile, " \"\\tstw %s, 32(%s)\\n\"\n", ppc_reg[10], ppc_reg[1]);
- fprintf( outfile, " \"\\tstw %s, 36(%s)\\n\"\n", ppc_reg[11], ppc_reg[1]);
- fprintf( outfile, " \"\\tstw %s, 40(%s)\\n\"\n", ppc_reg[12], ppc_reg[1]);
+ fprintf( outfile, " \"\\tstwu %s, -%d(%s)\\n\"\n",ppc_reg[1], 48+extra_stack_storage, ppc_reg[1]);
+ fprintf( outfile, " \"\\tstw %s, %d(%s)\\n\"\n", ppc_reg[3], 4+extra_stack_storage, ppc_reg[1]);
+ fprintf( outfile, " \"\\tstw %s, %d(%s)\\n\"\n", ppc_reg[4], 8+extra_stack_storage, ppc_reg[1]);
+ fprintf( outfile, " \"\\tstw %s, %d(%s)\\n\"\n", ppc_reg[5], 12+extra_stack_storage, ppc_reg[1]);
+ fprintf( outfile, " \"\\tstw %s, %d(%s)\\n\"\n", ppc_reg[6], 16+extra_stack_storage, ppc_reg[1]);
+ fprintf( outfile, " \"\\tstw %s, %d(%s)\\n\"\n", ppc_reg[7], 20+extra_stack_storage, ppc_reg[1]);
+ fprintf( outfile, " \"\\tstw %s, %d(%s)\\n\"\n", ppc_reg[8], 24+extra_stack_storage, ppc_reg[1]);
+ fprintf( outfile, " \"\\tstw %s, %d(%s)\\n\"\n", ppc_reg[9], 28+extra_stack_storage, ppc_reg[1]);
+ fprintf( outfile, " \"\\tstw %s, %d(%s)\\n\"\n", ppc_reg[10],32+extra_stack_storage, ppc_reg[1]);
+ fprintf( outfile, " \"\\tstw %s, %d(%s)\\n\"\n", ppc_reg[11],36+extra_stack_storage, ppc_reg[1]);
+ fprintf( outfile, " \"\\tstw %s, %d(%s)\\n\"\n", ppc_reg[12],40+extra_stack_storage, ppc_reg[1]);
/* r0 -> r3 (arg1) */
fprintf( outfile, " \"\\tmr %s, %s\\n\"\n", ppc_reg[3], ppc_reg[0]);
/* save return address */
fprintf( outfile, " \"\\tmflr %s\\n\"\n", ppc_reg[0]);
- fprintf( outfile, " \"\\tstw %s, 44(%s)\\n\"\n", ppc_reg[0], ppc_reg[1]);
+ fprintf( outfile, " \"\\tstw %s, %d(%s)\\n\"\n", ppc_reg[0], 44+extra_stack_storage, ppc_reg[1]);
/* Call the __wine_delay_load function, arg1 is arg1. */
fprintf( outfile, " \"\\tbl " __ASM_NAME("__wine_delay_load") "\\n\"\n");
@@ -1047,27 +933,28 @@
fprintf( outfile, " \"\\tmtctr %s\\n\"\n", ppc_reg[3]);
/* restore all saved registers and drop stackframe. */
- fprintf( outfile, " \"\\tlwz %s, 4(%s)\\n\"\n", ppc_reg[3], ppc_reg[1]);
- fprintf( outfile, " \"\\tlwz %s, 8(%s)\\n\"\n", ppc_reg[4], ppc_reg[1]);
- fprintf( outfile, " \"\\tlwz %s, 12(%s)\\n\"\n", ppc_reg[5], ppc_reg[1]);
- fprintf( outfile, " \"\\tlwz %s, 16(%s)\\n\"\n", ppc_reg[6], ppc_reg[1]);
- fprintf( outfile, " \"\\tlwz %s, 20(%s)\\n\"\n", ppc_reg[7], ppc_reg[1]);
- fprintf( outfile, " \"\\tlwz %s, 24(%s)\\n\"\n", ppc_reg[8], ppc_reg[1]);
- fprintf( outfile, " \"\\tlwz %s, 28(%s)\\n\"\n", ppc_reg[9], ppc_reg[1]);
- fprintf( outfile, " \"\\tlwz %s, 32(%s)\\n\"\n", ppc_reg[10], ppc_reg[1]);
- fprintf( outfile, " \"\\tlwz %s, 36(%s)\\n\"\n", ppc_reg[11], ppc_reg[1]);
- fprintf( outfile, " \"\\tlwz %s, 40(%s)\\n\"\n", ppc_reg[12], ppc_reg[1]);
+ fprintf( outfile, " \"\\tlwz %s, %d(%s)\\n\"\n", ppc_reg[3], 4+extra_stack_storage, ppc_reg[1]);
+ fprintf( outfile, " \"\\tlwz %s, %d(%s)\\n\"\n", ppc_reg[4], 8+extra_stack_storage, ppc_reg[1]);
+ fprintf( outfile, " \"\\tlwz %s, %d(%s)\\n\"\n", ppc_reg[5], 12+extra_stack_storage, ppc_reg[1]);
+ fprintf( outfile, " \"\\tlwz %s, %d(%s)\\n\"\n", ppc_reg[6], 16+extra_stack_storage, ppc_reg[1]);
+ fprintf( outfile, " \"\\tlwz %s, %d(%s)\\n\"\n", ppc_reg[7], 20+extra_stack_storage, ppc_reg[1]);
+ fprintf( outfile, " \"\\tlwz %s, %d(%s)\\n\"\n", ppc_reg[8], 24+extra_stack_storage, ppc_reg[1]);
+ fprintf( outfile, " \"\\tlwz %s, %d(%s)\\n\"\n", ppc_reg[9], 28+extra_stack_storage, ppc_reg[1]);
+ fprintf( outfile, " \"\\tlwz %s, %d(%s)\\n\"\n", ppc_reg[10],32+extra_stack_storage, ppc_reg[1]);
+ fprintf( outfile, " \"\\tlwz %s, %d(%s)\\n\"\n", ppc_reg[11],36+extra_stack_storage, ppc_reg[1]);
+ fprintf( outfile, " \"\\tlwz %s, %d(%s)\\n\"\n", ppc_reg[12],40+extra_stack_storage, ppc_reg[1]);
/* Load return value from call into return register */
- fprintf( outfile, " \"\\tlwz %s, 44(%s)\\n\"\n", ppc_reg[0], ppc_reg[1]);
+ fprintf( outfile, " \"\\tlwz %s, %d(%s)\\n\"\n", ppc_reg[0], 44+extra_stack_storage, ppc_reg[1]);
fprintf( outfile, " \"\\tmtlr %s\\n\"\n", ppc_reg[0]);
- fprintf( outfile, " \"\\taddi %s, %s, 48\\n\"\n", ppc_reg[1], ppc_reg[1]);
+ fprintf( outfile, " \"\\taddi %s, %s, %d\\n\"\n", ppc_reg[1], ppc_reg[1], 48+extra_stack_storage);
/* branch to ctr register. */
- fprintf( outfile, "\"bctr\\n\"\n");
+ fprintf( outfile, " \"bctr\\n\"\n");
#else
#error You need to defined delayed import thunks for your architecture!
#endif
+ output_function_size( outfile, "__wine_delay_load_asm" );
for (i = idx = 0; i < nb_imports; i++)
{
@@ -1075,7 +962,10 @@
for (j = 0; j < dll_imports[i]->nb_imports; j++)
{
char buffer[128];
- sprintf( buffer, "__wine_delay_imp_%d_%s", i, dll_imports[i]->imports[j].name );
+ ORDDEF *odp = dll_imports[i]->imports[j];
+ const char *name = odp->name ? odp->name : odp->export_name;
+
+ sprintf( buffer, "__wine_delay_imp_%d_%s", i, name );
fprintf( outfile, " \"\\t" __ASM_FUNC("%s") "\\n\"\n", buffer );
fprintf( outfile, " \"" __ASM_NAME("%s") ":\\n\"\n", buffer );
#if defined(__i386__)
@@ -1085,31 +975,52 @@
fprintf( outfile, " \"\\tset %d, %%g1\\n\"\n", (idx << 16) | j );
fprintf( outfile, " \"\\tb,a __wine_delay_load_asm\\n\"\n" );
#elif defined(__powerpc__)
- /* g0 is a function scratch register or so I understand. */
- /* First load the upper half-word, and then the lower part */
- fprintf( outfile, " \"\\tlis %s, %d\\n\"\n", ppc_reg[0], idx);
- fprintf( outfile, " \"\\tli %s, %d\\n\"\n", ppc_reg[0], j);
+#ifdef __APPLE__
+ /* On Darwin we can use r0 and r2 */
+ /* Upper part in r2 */
+ fprintf( outfile, " \"\\tlis %s, %d\\n\"\n", ppc_reg[2], idx);
+ /* Lower part + r2 -> r0, Note we can't use r0 directly */
+ fprintf( outfile, " \"\\taddi %s, %s, %d\\n\"\n", ppc_reg[0], ppc_reg[2], j);
+ fprintf( outfile, " \"\\tb " __ASM_NAME("__wine_delay_load_asm") "\\n\"\n");
+#else /* __APPLE__ */
+ /* On linux we can't use r2 since r2 is not a scratch register (hold the TOC) */
+ /* Save r13 on the stack */
+ fprintf( outfile, " \"\\taddi %s, %s, -0x4\\n\"\n", ppc_reg[1], ppc_reg[1]);
+ fprintf( outfile, " \"\\tstw %s, 0(%s)\\n\"\n", ppc_reg[13], ppc_reg[1]);
+ /* Upper part in r13 */
+ fprintf( outfile, " \"\\tlis %s, %d\\n\"\n", ppc_reg[13], idx);
+ /* Lower part + r13 -> r0, Note we can't use r0 directly */
+ fprintf( outfile, " \"\\taddi %s, %s, %d\\n\"\n", ppc_reg[0], ppc_reg[13], j);
+ /* Restore r13 */
+ fprintf( outfile, " \"\\tstw %s, 0(%s)\\n\"\n", ppc_reg[13], ppc_reg[1]);
+ fprintf( outfile, " \"\\taddic %s, %s, 0x4\\n\"\n", ppc_reg[1], ppc_reg[1]);
fprintf( outfile, " \"\\tb " __ASM_NAME("__wine_delay_load_asm") "\\n\"\n");
+#endif /* __APPLE__ */
#else
#error You need to defined delayed import thunks for your architecture!
#endif
+ output_function_size( outfile, name );
}
idx++;
}
+ output_function_size( outfile, delayed_import_loaders );
fprintf( outfile, "\n \".data\\n\\t.align %d\\n\"\n", get_alignment(8) );
+ fprintf( outfile, " \"" __ASM_NAME("%s") ":\\n\"\n", delayed_import_thunks);
pos = nb_delayed * 32;
for (i = 0; i < nb_imports; i++)
{
if (!dll_imports[i]->delay) continue;
for (j = 0; j < dll_imports[i]->nb_imports; j++, pos += 4)
{
- struct func *import = &dll_imports[i]->imports[j];
- fprintf( outfile, " \"\\t" __ASM_FUNC("%s") "\\n\"\n", import->name );
- fprintf( outfile, " \"\\t.globl " __ASM_NAME("%s") "\\n\"\n", import->name );
- fprintf( outfile, " \"" __ASM_NAME("%s") ":\\n\\t\"", import->name);
+ ORDDEF *odp = dll_imports[i]->imports[j];
+ const char *name = odp->name ? odp->name : odp->export_name;
+
+ fprintf( outfile, " \"\\t" __ASM_FUNC("%s") "\\n\"\n", name );
+ fprintf( outfile, " \"\\t.globl " __ASM_NAME("%s") "\\n\"\n", name );
+ fprintf( outfile, " \"" __ASM_NAME("%s") ":\\n\\t\"", name );
#if defined(__i386__)
- if (strstr( import->name, "__wine_call_from_16" ))
+ if (strstr( name, "__wine_call_from_16" ))
fprintf( outfile, "\".byte 0x2e\\n\\tjmp *(delay_imports+%d)\\n\\tnop\\n\"", pos );
else
fprintf( outfile, "\"jmp *(delay_imports+%d)\\n\\tmovl %%esi,%%esi\\n\"", pos );
@@ -1139,8 +1050,9 @@
fprintf( outfile, "\t\"\\tstw %s, 0(%s)\\n\"\n", ppc_reg[8], ppc_reg[1]);
fprintf( outfile, "\t\"\\taddi %s, %s, -0x4\\n\"\n", ppc_reg[1], ppc_reg[1]);
fprintf( outfile, "\t\"\\tstw %s, 0(%s)\\n\"\n", ppc_reg[7], ppc_reg[1]);
- fprintf( outfile, "\t\"\\tlis %s, " ppc_high(__ASM_NAME("imports") "+ %d") "\\n\"\n", ppc_reg[9], pos);
- fprintf( outfile, "\t\"\\tla %s, " ppc_low (__ASM_NAME("imports") "+ %d") "(%s)\\n\"\n", ppc_reg[8], pos, ppc_reg[9]);
+
+ fprintf( outfile, "\t\"\\tlis %s, " ppc_high(__ASM_NAME("delay_imports") "+ %d") "\\n\"\n", ppc_reg[9], pos);
+ fprintf( outfile, "\t\"\\tla %s, " ppc_low (__ASM_NAME("delay_imports") "+ %d") "(%s)\\n\"\n", ppc_reg[8], pos, ppc_reg[9]);
fprintf( outfile, "\t\"\\tlwz %s, 0(%s)\\n\"\n", ppc_reg[7], ppc_reg[8]);
fprintf( outfile, "\t\"\\tmtctr %s\\n\"\n", ppc_reg[7]);
@@ -1155,8 +1067,10 @@
#error You need to define delayed import thunks for your architecture!
#endif
fprintf( outfile, "\n" );
+ output_function_size( outfile, name );
}
}
+ output_function_size( outfile, delayed_import_thunks );
fprintf( outfile, "\".text\");\n" );
fprintf( outfile, "#ifndef __GNUC__\n" );
fprintf( outfile, "}\n" );
@@ -1170,8 +1084,8 @@
/* output the import and delayed import tables of a Win32 module
* returns number of DLLs exported in 'immediate' mode
*/
-int output_imports( FILE *outfile )
+int output_imports( FILE *outfile, DLLSPEC *spec )
{
- output_delayed_imports( outfile );
+ output_delayed_imports( outfile, spec );
return output_immediate_imports( outfile );
}
reactos/tools/winebuild
diff -u -r1.3 -r1.4
--- main.c 5 Jan 2004 19:49:59 -0000 1.3
+++ main.c 23 Sep 2004 20:27:30 -0000 1.4
@@ -29,27 +29,17 @@
#include <stdio.h>
#include <errno.h>
#include <string.h>
+#include <stdarg.h>
#include <ctype.h>
#ifdef HAVE_GETOPT_H
# include <getopt.h>
#endif
+#include "windef.h"
+#include "winbase.h"
#include "build.h"
-ORDDEF *EntryPoints[MAX_ORDINALS];
-ORDDEF *Ordinals[MAX_ORDINALS];
-ORDDEF *Names[MAX_ORDINALS];
-
-SPEC_MODE SpecMode = SPEC_MODE_DLL;
-SPEC_TYPE SpecType = SPEC_WIN32;
-
-int Base = MAX_ORDINALS;
-int Limit = 0;
-int DLLHeapSize = 0;
int UsePIC = 0;
-int stack_size = 0;
-int nb_entry_points = 0;
-int nb_names = 0;
int nb_debug_channels = 0;
int nb_lib_paths = 0;
int nb_errors = 0;
@@ -63,27 +53,23 @@
int debugging = 0;
#endif
-char *owner_name = NULL;
-char *dll_name = NULL;
-char *dll_file_name = NULL;
-const char *init_func = NULL;
char **debug_channels = NULL;
char **lib_path = NULL;
char *input_file_name = NULL;
const char *output_file_name = NULL;
-static FILE *input_file;
static FILE *output_file;
static const char *current_src_dir;
static int nb_res_files;
static char **res_files;
+static char *spec_file_name;
/* execution mode */
enum exec_mode_values
{
MODE_NONE,
- MODE_SPEC,
+ MODE_DLL,
MODE_EXE,
MODE_DEF,
MODE_DEBUG,
@@ -94,18 +80,43 @@
static enum exec_mode_values exec_mode = MODE_NONE;
/* set the dll file name from the input file name */
-static void set_dll_file_name( const char *name )
+static void set_dll_file_name( const char *name, DLLSPEC *spec )
{
char *p;
- if (dll_file_name) return;
+ if (spec->file_name) return;
if ((p = strrchr( name, '\\' ))) name = p + 1;
if ((p = strrchr( name, '/' ))) name = p + 1;
- dll_file_name = xmalloc( strlen(name) + 5 );
- strcpy( dll_file_name, name );
- if ((p = strrchr( dll_file_name, '.' )) && !strcmp( p, ".spec" )) *p = 0;
- if (!strchr( dll_file_name, '.' )) strcat( dll_file_name, ".dll" );
+ spec->file_name = xmalloc( strlen(name) + 5 );
+ strcpy( spec->file_name, name );
+ if ((p = strrchr( spec->file_name, '.' )))
+ {
+ if (!strcmp( p, ".spec" ) || !strcmp( p, ".def" )) *p = 0;
+ }
+ if (!strchr( spec->file_name, '.' )) strcat( spec->file_name, ".dll" );
+}
+
+/* set the dll subsystem */
+static void set_subsystem( const char *subsystem, DLLSPEC *spec )
+{
+ char *major, *minor, *str = xstrdup( subsystem );
+
+ if ((major = strchr( str, ':' ))) *major++ = 0;
+ if (!strcmp( str, "native" )) spec->subsystem = IMAGE_SUBSYSTEM_NATIVE;
+ else if (!strcmp( str, "windows" )) spec->subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
+ else if (!strcmp( str, "console" )) spec->subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI;
+ else fatal_error( "Invalid subsystem name '%s'\n", subsystem );
+ if (major)
+ {
+ if ((minor = strchr( major, '.' )))
+ {
+ *minor++ = 0;
+ spec->subsystem_minor = atoi( minor );
+ }
+ spec->subsystem_major = atoi( major );
+ }
+ free( str );
}
/* cleanup on program exit */
@@ -135,15 +146,15 @@
" -K FLAGS Compiler flags (only -KPIC is supported)\n"
" -l --library=LIB Import the specified library\n"
" -L --library-path=DIR Look for imports libraries in DIR\n"
-" -m --exe-mode=MODE Set the executable mode (cui|gui|cuiw|guiw)\n"
" -M --main-module=MODULE Set the name of the main module for a Win16 dll\n"
" -N --dll-name=DLLNAME Set the DLL name (default: from input file name)\n"
" -o --output=NAME Set the output file name (default: stdout)\n"
" -r --res=RSRC.RES Load resources from RSRC.RES\n"
+" --subsystem=SUBSYS Set the subsystem (one of native, windows, console)\n"
" --version Print the version and exit\n"
" -w --warnings Turn on warnings\n"
"\nMode options:\n"
-" --spec=FILE.SPEC Build a .c file from a spec file\n"
+" --dll=FILE Build a .c file from a .spec or .def file\n"
" --def=FILE.SPEC Build a .def file from a spec file\n"
" --exe=NAME Build a .c file for the named executable\n"
" --debug [FILES] Build a .c file with the debug channels declarations\n"
@@ -153,12 +164,13 @@
enum long_options_values
{
- LONG_OPT_SPEC = 1,
+ LONG_OPT_DLL = 1,
LONG_OPT_DEF,
LONG_OPT_EXE,
LONG_OPT_DEBUG,
LONG_OPT_RELAY16,
LONG_OPT_RELAY32,
+ LONG_OPT_SUBSYSTEM,
LONG_OPT_VERSION
};
@@ -166,12 +178,13 @@
static const struct option long_options[] =
{
- { "spec", 1, 0, LONG_OPT_SPEC },
+ { "dll", 1, 0, LONG_OPT_DLL },
{ "def", 1, 0, LONG_OPT_DEF },
{ "exe", 1, 0, LONG_OPT_EXE },
{ "debug", 0, 0, LONG_OPT_DEBUG },
{ "relay16", 0, 0, LONG_OPT_RELAY16 },
{ "relay32", 0, 0, LONG_OPT_RELAY32 },
+ { "subsystem",1, 0, LONG_OPT_SUBSYSTEM },
{ "version", 0, 0, LONG_OPT_VERSION },
/* aliases for short options */
{ "source-dir", 1, 0, 'C' },
@@ -184,7 +197,6 @@
{ "kill-at", 0, 0, 'k' },
{ "library", 1, 0, 'l' },
{ "library-path", 1, 0, 'L' },
- { "exe-mode", 1, 0, 'm' },
{ "main-module", 1, 0, 'M' },
{ "dll-name", 1, 0, 'N' },
{ "output", 1, 0, 'o' },
@@ -206,7 +218,7 @@
}
/* parse options from the argv array and remove all the recognized ones */
-static char **parse_options( int argc, char **argv )
+static char **parse_options( int argc, char **argv, DLLSPEC *spec )
{
char *p;
int optc;
@@ -222,14 +234,14 @@
/* ignored */
break;
case 'F':
- dll_file_name = xstrdup( optarg );
+ spec->file_name = xstrdup( optarg );
break;
case 'H':
if (!isdigit(optarg[0]))
fatal_error( "Expected number argument with -H option instead of '%s'\n", optarg );
- DLLHeapSize = atoi(optarg);
- if (DLLHeapSize > 65535)
- fatal_error( "Invalid heap size %d, maximum is 65535\n", DLLHeapSize );
+ spec->heap_size = atoi(optarg);
+ if (spec->heap_size > 65535)
+ fatal_error( "Invalid heap size %d, maximum is 65535\n", spec->heap_size );
break;
case 'I':
/* ignored */
@@ -242,18 +254,18 @@
lib_path[nb_lib_paths++] = xstrdup( optarg );
break;
case 'M':
- owner_name = xstrdup( optarg );
- SpecType = SPEC_WIN16;
+ spec->owner_name = xstrdup( optarg );
+ spec->type = SPEC_WIN16;
break;
case 'N':
- dll_name = xstrdup( optarg );
+ spec->dll_name = xstrdup( optarg );
break;
case 'd':
add_import_dll( optarg, 1 );
break;
case 'e':
- init_func = xstrdup( optarg );
- if ((p = strchr( init_func, '@' ))) *p = 0; /* kill stdcall decoration */
+ spec->init_func = xstrdup( optarg );
+ if ((p = strchr( spec->init_func, '@' ))) *p = 0; /* kill stdcall decoration */
break;
case 'f':
if (!strcmp( optarg, "PIC") || !strcmp( optarg, "pic")) UsePIC = 1;
@@ -280,13 +292,6 @@
case 'l':
add_import_dll( optarg, 0 );
break;
- case 'm':
- if (!strcmp( optarg, "gui" )) SpecMode = SPEC_MODE_GUIEXE;
- else if (!strcmp( optarg, "cui" )) SpecMode = SPEC_MODE_CUIEXE;
- else if (!strcmp( optarg, "guiw" )) SpecMode = SPEC_MODE_GUIEXE_UNICODE;
- else if (!strcmp( optarg, "cuiw" )) SpecMode = SPEC_MODE_CUIEXE_UNICODE;
- else usage(1);
- break;
case 'o':
if (unlink( optarg ) == -1 && errno != ENOENT)
fatal_error( "Unable to create output file '%s'\n", optarg );
@@ -302,24 +307,24 @@
case 'w':
display_warnings = 1;
break;
- case LONG_OPT_SPEC:
- set_exec_mode( MODE_SPEC );
- input_file = open_input_file( NULL, optarg );
- set_dll_file_name( optarg );
+ case LONG_OPT_DLL:
+ set_exec_mode( MODE_DLL );
+ spec_file_name = xstrdup( optarg );
+ set_dll_file_name( optarg, spec );
break;
case LONG_OPT_DEF:
set_exec_mode( MODE_DEF );
- input_file = open_input_file( NULL, optarg );
- set_dll_file_name( optarg );
+ spec_file_name = xstrdup( optarg );
+ set_dll_file_name( optarg, spec );
break;
case LONG_OPT_EXE:
set_exec_mode( MODE_EXE );
if ((p = strrchr( optarg, '/' ))) p++;
else p = optarg;
- dll_file_name = xmalloc( strlen(p) + 5 );
- strcpy( dll_file_name, p );
- if (!strchr( dll_file_name, '.' )) strcat( dll_file_name, ".exe" );
- if (SpecMode == SPEC_MODE_DLL) SpecMode = SPEC_MODE_GUIEXE;
+ spec->file_name = xmalloc( strlen(p) + 5 );
+ strcpy( spec->file_name, p );
+ if (!strchr( spec->file_name, '.' )) strcat( spec->file_name, ".exe" );
+ if (!spec->subsystem) spec->subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
break;
case LONG_OPT_DEBUG:
set_exec_mode( MODE_DEBUG );
@@ -330,6 +335,9 @@
case LONG_OPT_RELAY32:
set_exec_mode( MODE_RELAY32 );
break;
+ case LONG_OPT_SUBSYSTEM:
+ set_subsystem( optarg, spec );
+ break;
case LONG_OPT_VERSION:
printf( "winebuild version " PACKAGE_VERSION "\n" );
exit(0);
@@ -343,28 +351,28 @@
/* load all specified resource files */
-static void load_resources( char *argv[] )
+static void load_resources( char *argv[], DLLSPEC *spec )
{
int i;
char **ptr, **last;
- switch (SpecType)
+ switch (spec->type)
{
case SPEC_WIN16:
- for (i = 0; i < nb_res_files; i++) load_res16_file( res_files[i] );
+ for (i = 0; i < nb_res_files; i++) load_res16_file( res_files[i], spec );
break;
case SPEC_WIN32:
for (i = 0; i < nb_res_files; i++)
{
- if (!load_res32_file( res_files[i] ))
+ if (!load_res32_file( res_files[i], spec ))
fatal_error( "%s is not a valid Win32 resource file\n", res_files[i] );
}
/* load any resource file found in the remaining arguments */
for (ptr = last = argv; *ptr; ptr++)
{
- if (!load_res32_file( *ptr ))
+ if (!load_res32_file( *ptr, spec ))
*last++ = *ptr; /* not a resource file, keep it in the list */
}
*last = NULL;
@@ -372,67 +380,67 @@
}
}
+static int parse_input_file( DLLSPEC *spec )
+{
+ FILE *input_file = open_input_file( NULL, spec_file_name );
+ char *extension = strrchr( spec_file_name, '.' );
+
+ if (extension && !strcmp( extension, ".def" ))
+ return parse_def_file( input_file, spec );
+ else
+ return parse_spec_file( input_file, spec );
+ close_input_file( input_file );
+}
+
+
/*******************************************************************
* main
*/
int main(int argc, char **argv)
{
+ DLLSPEC *spec = alloc_dll_spec();
+
output_file = stdout;
- argv = parse_options( argc, argv );
+ argv = parse_options( argc, argv, spec );
switch(exec_mode)
{
- case MODE_SPEC:
- load_resources( argv );
- if (!ParseTopLevel( input_file )) break;
- switch (SpecType)
+ case MODE_DLL:
+ spec->characteristics |= IMAGE_FILE_DLL;
+ load_resources( argv, spec );
+ if (!parse_input_file( spec )) break;
+ switch (spec->type)
{
case SPEC_WIN16:
-#if defined(__REACTOS__)
fatal_error( "Win16 specs are not supported in ReactOS version of winebuild\n" );
-#else
- if (argv[0])
- fatal_error( "file argument '%s' not allowed in this mode\n", argv[0] );
- BuildSpec16File( output_file );
-#endif
break;
case SPEC_WIN32:
read_undef_symbols( argv );
- BuildSpec32File( output_file );
+ BuildSpec32File( output_file, spec );
break;
default: assert(0);
}
break;
case MODE_EXE:
- if (SpecType == SPEC_WIN16) fatal_error( "Cannot build 16-bit exe files\n" );
- load_resources( argv );
+ if (spec->type == SPEC_WIN16) fatal_error( "Cannot build 16-bit exe files\n" );
+ load_resources( argv, spec );
read_undef_symbols( argv );
- BuildSpec32File( output_file );
+ BuildSpec32File( output_file, spec );
break;
case MODE_DEF:
if (argv[0]) fatal_error( "file argument '%s' not allowed in this mode\n", argv[0] );
- if (SpecType == SPEC_WIN16) fatal_error( "Cannot yet build .def file for 16-bit dlls\n" );
- if (!ParseTopLevel( input_file )) break;
- BuildDef32File( output_file );
+ if (spec->type == SPEC_WIN16) fatal_error( "Cannot yet build .def file for 16-bit dlls\n" );
+ if (!parse_input_file( spec )) break;
+ BuildDef32File( output_file, spec );
break;
case MODE_DEBUG:
BuildDebugFile( output_file, current_src_dir, argv );
break;
case MODE_RELAY16:
-#if defined(__REACTOS__)
fatal_error( "Win16 relays are not supported in ReactOS version of winebuild\n" );
-#else
- if (argv[0]) fatal_error( "file argument '%s' not allowed in this mode\n", argv[0] );
- BuildRelays16( output_file );
-#endif
break;
case MODE_RELAY32:
-#if defined(__REACTOS__)
fatal_error( "Win32 relays are not supported in ReactOS version of winebuild\n" );
-#else
- if (argv[0]) fatal_error( "file argument '%s' not allowed in this mode\n", argv[0] );
- BuildRelays32( output_file );
-#endif
break;
default:
usage(1);
reactos/tools/winebuild
diff -u -r1.2 -r1.3
--- parser.c 4 Jan 2004 15:50:41 -0000 1.2
+++ parser.c 23 Sep 2004 20:27:30 -0000 1.3
@@ -3,7 +3,7 @@
*
* Copyright 1993 Robert J. Amstadt
* Copyright 1995 Martin von Loewis
- * Copyright 1995, 1996, 1997 Alexandre Julliard
+ * Copyright 1995, 1996, 1997, 2004 Alexandre Julliard
* Copyright 1997 Eric Youngdale
* Copyright 1999 Ulrich Weigand
*
@@ -32,12 +32,8 @@
#include <stdlib.h>
#include <string.h>
-#ifdef WIN32
#include "windef.h"
#include "winbase.h"
-#else
-#include "winglue.h"
-#endif
#include "build.h"
int current_line = 0;
@@ -47,6 +43,9 @@
static char *ParseNext = ParseBuffer;
static FILE *input_file;
+static const char *separator_chars;
+static const char *comment_chars;
+
static const char * const TypeNames[TYPE_NBTYPES] =
{
"variable", /* TYPE_VARIABLE */
@@ -67,7 +66,6 @@
"ret64", /* FLAG_RET64 */
"i386", /* FLAG_I386 */
"register", /* FLAG_REGISTER */
- "interrupt", /* FLAG_INTERRUPT */
"private", /* FLAG_PRIVATE */
NULL
};
@@ -80,7 +78,12 @@
inline static int is_token_separator( char ch )
{
- return (ch == '(' || ch == ')' || ch == '-');
+ return strchr( separator_chars, ch ) != NULL;
+}
+
+inline static int is_token_comment( char ch )
+{
+ return strchr( comment_chars, ch ) != NULL;
}
/* get the next line from the input file, or return 0 if at eof */
@@ -113,7 +116,7 @@
else break;
}
- if ((*p == '\0') || (*p == '#'))
+ if ((*p == '\0') || is_token_comment(*p))
{
if (!allow_eol) error( "Declaration not terminated properly\n" );
return NULL;
@@ -138,12 +141,23 @@
}
+static ORDDEF *add_entry_point( DLLSPEC *spec )
+{
+ if (spec->nb_entry_points == spec->alloc_entry_points)
+ {
+ spec->alloc_entry_points += 128;
+ spec->entry_points = xrealloc( spec->entry_points,
+ spec->alloc_entry_points * sizeof(*spec->entry_points) );
+ }
+ return &spec->entry_points[spec->nb_entry_points++];
+}
+
/*******************************************************************
- * ParseVariable
+ * parse_spec_variable
*
- * Parse a variable definition.
+ * Parse a variable definition in a .spec file.
*/
-static int ParseVariable( ORDDEF *odp )
+static int parse_spec_variable( ORDDEF *odp, DLLSPEC *spec )
{
char *endptr;
int *value_array;
@@ -151,7 +165,7 @@
int value_array_size;
const char *token;
- if (SpecType == SPEC_WIN32)
+ if (spec->type == SPEC_WIN32)
{
error( "'variable' not supported in Win32, use 'extern' instead\n" );
return 0;
@@ -201,16 +215,16 @@
/*******************************************************************
- * ParseExportFunction
+ * parse_spec_export
*
- * Parse a function definition.
+ * Parse an exported function definition in a .spec file.
*/
-static int ParseExportFunction( ORDDEF *odp )
+static int parse_spec_export( ORDDEF *odp, DLLSPEC *spec )
{
const char *token;
unsigned int i;
- switch(SpecType)
+ switch(spec->type)
{
case SPEC_WIN16:
if (odp->type == TYPE_STDCALL)
@@ -225,11 +239,6 @@
error( "'pascal' not supported for Win32\n" );
return 0;
}
- if (odp->flags & FLAG_INTERRUPT)
- {
- error( "'interrupt' not supported for Win32\n" );
- return 0;
- }
break;
default:
break;
@@ -273,7 +282,7 @@
return 0;
}
- if (SpecType == SPEC_WIN32)
+ if (spec->type == SPEC_WIN32)
{
if (strcmp(token, "long") &&
strcmp(token, "ptr") &&
@@ -310,7 +319,7 @@
odp->link_name = xstrdup( token );
if (strchr( odp->link_name, '.' ))
{
- if (SpecType == SPEC_WIN16)
+ if (spec->type == SPEC_WIN16)
{
error( "Forwarded functions not supported for Win16\n" );
return 0;
@@ -323,17 +332,17 @@
/*******************************************************************
- * ParseEquate
+ * parse_spec_equate
*
- * Parse an 'equate' definition.
+ * Parse an 'equate' definition in a .spec file.
*/
-static int ParseEquate( ORDDEF *odp )
+static int parse_spec_equate( ORDDEF *odp, DLLSPEC *spec )
{
char *endptr;
int value;
const char *token;
- if (SpecType == SPEC_WIN32)
+ if (spec->type == SPEC_WIN32)
{
error( "'equate' not supported for Win32\n" );
return 0;
@@ -351,11 +360,11 @@
/*******************************************************************
- * ParseStub
+ * parse_spec_stub
*
- * Parse a 'stub' definition.
+ * Parse a 'stub' definition in a .spec file
*/
-static int ParseStub( ORDDEF *odp )
+static int parse_spec_stub( ORDDEF *odp, DLLSPEC *spec )
{
odp->u.func.arg_types[0] = '\0';
odp->link_name = xstrdup("");
@@ -364,15 +373,15 @@
/*******************************************************************
- * ParseExtern
+ * parse_spec_extern
*
- * Parse an 'extern' definition.
+ * Parse an 'extern' definition in a .spec file.
*/
-static int ParseExtern( ORDDEF *odp )
+static int parse_spec_extern( ORDDEF *odp, DLLSPEC *spec )
{
const char *token;
- if (SpecType == SPEC_WIN16)
+ if (spec->type == SPEC_WIN16)
{
error( "'extern' not supported for Win16, use 'variable' instead\n" );
return 0;
@@ -396,11 +405,11 @@
/*******************************************************************
- * ParseFlags
+ * parse_spec_flags
*
- * Parse the optional flags for an entry point
+ * Parse the optional flags for an entry point in a .spec file.
*/
-static const char *ParseFlags( ORDDEF *odp )
+static const char *parse_spec_flags( ORDDEF *odp )
{
unsigned int i;
const char *token;
@@ -422,32 +431,18 @@
return token;
}
-/*******************************************************************
- * fix_export_name
- *
- * Fix an exported function name by removing a possible @xx suffix
- */
-static void fix_export_name( char *name )
-{
- char *p, *end = strrchr( name, '@' );
- if (!end || !end[1] || end == name) return;
- /* make sure all the rest is digits */
- for (p = end + 1; *p; p++) if (!isdigit(*p)) return;
- *end = 0;
-}
/*******************************************************************
- * ParseOrdinal
+ * parse_spec_ordinal
*
- * Parse an ordinal definition.
+ * Parse an ordinal definition in a .spec file.
*/
-static int ParseOrdinal(int ordinal)
+static int parse_spec_ordinal( int ordinal, DLLSPEC *spec )
{
const char *token;
- ORDDEF *odp = xmalloc( sizeof(*odp) );
+ ORDDEF *odp = add_entry_point( spec );
memset( odp, 0, sizeof(*odp) );
- EntryPoints[nb_entry_points++] = odp;
if (!(token = GetToken(0))) goto error;
@@ -462,32 +457,31 @@
}
if (!(token = GetToken(0))) goto error;
- if (*token == '-' && !(token = ParseFlags( odp ))) goto error;
+ if (*token == '-' && !(token = parse_spec_flags( odp ))) goto error;
odp->name = xstrdup( token );
- fix_export_name( odp->name );
odp->lineno = current_line;
odp->ordinal = ordinal;
switch(odp->type)
{
case TYPE_VARIABLE:
- if (!ParseVariable( odp )) goto error;
+ if (!parse_spec_variable( odp, spec )) goto error;
break;
case TYPE_PASCAL:
case TYPE_STDCALL:
case TYPE_VARARGS:
case TYPE_CDECL:
- if (!ParseExportFunction( odp )) goto error;
+ if (!parse_spec_export( odp, spec )) goto error;
break;
case TYPE_ABS:
- if (!ParseEquate( odp )) goto error;
+ if (!parse_spec_equate( odp, spec )) goto error;
break;
case TYPE_STUB:
- if (!ParseStub( odp )) goto error;
+ if (!parse_spec_stub( odp, spec )) goto error;
break;
case TYPE_EXTERN:
- if (!ParseExtern( odp )) goto error;
+ if (!parse_spec_extern( odp, spec )) goto error;
break;
default:
assert( 0 );
@@ -497,8 +491,7 @@
if (odp->flags & FLAG_I386)
{
/* ignore this entry point on non-Intel archs */
- EntryPoints[--nb_entry_points] = NULL;
- free( odp );
+ spec->nb_entry_points--;
return 1;
}
#endif
@@ -515,15 +508,20 @@
error( "Ordinal number %d too large\n", ordinal );
goto error;
}
- if (ordinal > Limit) Limit = ordinal;
- if (ordinal < Base) Base = ordinal;
+ if (ordinal > spec->limit) spec->limit = ordinal;
+ if (ordinal < spec->base) spec->base = ordinal;
odp->ordinal = ordinal;
- if (Ordinals[ordinal])
+ }
+
+ if (odp->type == TYPE_STDCALL && !(odp->flags & FLAG_PRIVATE))
+ {
+ if (!strcmp( odp->name, "DllRegisterServer" ) ||
+ !strcmp( odp->name, "DllUnregisterServer" ) ||
+ !strcmp( odp->name, "DllGetClassObject" ) ||
+ !strcmp( odp->name, "DllCanUnloadNow" ))
{
- error( "Duplicate ordinal %d\n", ordinal );
- goto error;
+ warning( "Function %s should be marked private\n", odp->name );
}
- Ordinals[ordinal] = odp;
}
if (!strcmp( odp->name, "@" ) || odp->flags & FLAG_NONAME)
@@ -533,7 +531,7 @@
error( "Nameless function needs an explicit ordinal number\n" );
goto error;
}
- if (SpecType != SPEC_WIN32)
+ if (spec->type != SPEC_WIN32)
{
error( "Nameless functions not supported for Win16\n" );
goto error;
@@ -542,79 +540,135 @@
else odp->export_name = odp->name;
odp->name = NULL;
}
- else Names[nb_names++] = odp;
return 1;
error:
- EntryPoints[--nb_entry_points] = NULL;
+ spec->nb_entry_points--;
free( odp->name );
- free( odp );
return 0;
}
static int name_compare( const void *name1, const void *name2 )
{
- ORDDEF *odp1 = *(ORDDEF **)name1;
- ORDDEF *odp2 = *(ORDDEF **)name2;
+ const ORDDEF *odp1 = *(const ORDDEF * const *)name1;
+ const ORDDEF *odp2 = *(const ORDDEF * const *)name2;
return strcmp( odp1->name, odp2->name );
}
/*******************************************************************
- * sort_names
+ * assign_names
*
- * Sort the name array and catch duplicates.
+ * Build the name array and catch duplicates.
*/
-static void sort_names(void)
+static void assign_names( DLLSPEC *spec )
{
- int i;
+ int i, j;
- if (!nb_names) return;
+ spec->nb_names = 0;
+ for (i = 0; i < spec->nb_entry_points; i++)
+ if (spec->entry_points[i].name) spec->nb_names++;
+ if (!spec->nb_names) return;
+
+ spec->names = xmalloc( spec->nb_names * sizeof(spec->names[0]) );
+ for (i = j = 0; i < spec->nb_entry_points; i++)
+ if (spec->entry_points[i].name) spec->names[j++] = &spec->entry_points[i];
/* sort the list of names */
- qsort( Names, nb_names, sizeof(Names[0]), name_compare );
+ qsort( spec->names, spec->nb_names, sizeof(spec->names[0]), name_compare );
/* check for duplicate names */
- for (i = 0; i < nb_names - 1; i++)
+ for (i = 0; i < spec->nb_names - 1; i++)
{
- if (!strcmp( Names[i]->name, Names[i+1]->name ))
+ if (!strcmp( spec->names[i]->name, spec->names[i+1]->name ))
{
- current_line = max( Names[i]->lineno, Names[i+1]->lineno );
+ current_line = max( spec->names[i]->lineno, spec->names[i+1]->lineno );
error( "'%s' redefined\n%s:%d: First defined here\n",
- Names[i]->name, input_file_name,
- min( Names[i]->lineno, Names[i+1]->lineno ) );
+ spec->names[i]->name, input_file_name,
+ min( spec->names[i]->lineno, spec->names[i+1]->lineno ) );
+ }
+ }
+}
+
+/*******************************************************************
+ * assign_ordinals
+ *
+ * Build the ordinal array.
+ */
+static void assign_ordinals( DLLSPEC *spec )
+{
+ int i, count, ordinal;
+
+ /* start assigning from base, or from 1 if no ordinal defined yet */
+ if (spec->base == MAX_ORDINALS) spec->base = 1;
+ if (spec->limit < spec->base) spec->limit = spec->base;
+
+ count = max( spec->limit + 1, spec->base + spec->nb_entry_points );
+ spec->ordinals = xmalloc( count * sizeof(spec->ordinals[0]) );
+ memset( spec->ordinals, 0, count * sizeof(spec->ordinals[0]) );
+
+ /* fill in all explicitly specified ordinals */
+ for (i = 0; i < spec->nb_entry_points; i++)
+ {
+ ordinal = spec->entry_points[i].ordinal;
+ if (ordinal == -1) continue;
+ if (spec->ordinals[ordinal])
+ {
+ current_line = max( spec->entry_points[i].lineno, spec->ordinals[ordinal]->lineno );
+ error( "ordinal %d redefined\n%s:%d: First defined here\n",
+ ordinal, input_file_name,
+ min( spec->entry_points[i].lineno, spec->ordinals[ordinal]->lineno ) );
}
+ else spec->ordinals[ordinal] = &spec->entry_points[i];
}
+
+ /* now assign ordinals to the rest */
+ for (i = 0, ordinal = spec->base; i < spec->nb_names; i++)
+ {
+ if (spec->names[i]->ordinal != -1) continue; /* already has an ordinal */
+ while (spec->ordinals[ordinal]) ordinal++;
+ if (ordinal >= MAX_ORDINALS)
+ {
+ current_line = spec->names[i]->lineno;
+ fatal_error( "Too many functions defined (max %d)\n", MAX_ORDINALS );
+ }
+ spec->names[i]->ordinal = ordinal;
+ spec->ordinals[ordinal] = spec->names[i];
+ }
+ if (ordinal > spec->limit) spec->limit = ordinal;
}
/*******************************************************************
- * ParseTopLevel
+ * parse_spec_file
*
- * Parse a spec file.
+ * Parse a .spec file.
*/
-int ParseTopLevel( FILE *file )
+int parse_spec_file( FILE *file, DLLSPEC *spec )
{
const char *token;
input_file = file;
current_line = 0;
+ comment_chars = "#;";
+ separator_chars = "()-";
+
while (get_next_line())
{
if (!(token = GetToken(1))) continue;
if (strcmp(token, "@") == 0)
{
- if (SpecType != SPEC_WIN32)
+ if (spec->type != SPEC_WIN32)
{
error( "'@' ordinals not supported for Win16\n" );
continue;
}
- if (!ParseOrdinal( -1 )) continue;
+ if (!parse_spec_ordinal( -1, spec )) continue;
}
else if (IsNumberString(token))
{
- if (!ParseOrdinal( atoi(token) )) continue;
+ if (!parse_spec_ordinal( atoi(token), spec )) continue;
}
else
{
@@ -625,7 +679,245 @@
}
current_line = 0; /* no longer parsing the input file */
- sort_names();
+ assign_names( spec );
+ assign_ordinals( spec );
+ return !nb_errors;
+}
+
+
+/*******************************************************************
+ * parse_def_library
+ *
+ * Parse a LIBRARY declaration in a .def file.
+ */
+static int parse_def_library( DLLSPEC *spec )
+{
+ const char *token = GetToken(1);
+
+ if (!token) return 1;
+ if (strcmp( token, "BASE" ))
+ {
+ free( spec->file_name );
+ spec->file_name = xstrdup( token );
+ if (!(token = GetToken(1))) return 1;
+ }
+ if (strcmp( token, "BASE" ))
+ {
+ error( "Expected library name or BASE= declaration, got '%s'\n", token );
+ return 0;
+ }
+ if (!(token = GetToken(0))) return 0;
+ if (strcmp( token, "=" ))
+ {
+ error( "Expected '=' after BASE, got '%s'\n", token );
+ return 0;
+ }
+ if (!(token = GetToken(0))) return 0;
+ /* FIXME: do something with base address */
+
+ return 1;
+}
+
+
+/*******************************************************************
+ * parse_def_stack_heap_size
+ *
+ * Parse a STACKSIZE or HEAPSIZE declaration in a .def file.
+ */
+static int parse_def_stack_heap_size( int is_stack, DLLSPEC *spec )
+{
+ const char *token = GetToken(0);
+ char *end;
+ unsigned long size;
+
+ if (!token) return 0;
+ size = strtoul( token, &end, 0 );
+ if (*end)
+ {
+ error( "Invalid number '%s'\n", token );
+ return 0;
+ }
+ if (is_stack) spec->stack_size = size / 1024;
+ else spec->heap_size = size / 1024;
+ if (!(token = GetToken(1))) return 1;
+ if (strcmp( token, "," ))
+ {
+ error( "Expected ',' after size, got '%s'\n", token );
+ return 0;
+ }
+ if (!(token = GetToken(0))) return 0;
+ /* FIXME: do something with reserve size */
+ return 1;
+}
+
+
+/*******************************************************************
+ * parse_def_export
+ *
+ * Parse an export declaration in a .def file.
+ */
+static int parse_def_export( char *name, DLLSPEC *spec )
+{
+ int i, args;
+ const char *token = GetToken(1);
+
+ ORDDEF *odp = add_entry_point( spec );
+ memset( odp, 0, sizeof(*odp) );
+
+ odp->lineno = current_line;
+ odp->ordinal = -1;
+ odp->name = name;
+ args = remove_stdcall_decoration( odp->name );
+ if (args == -1) odp->type = TYPE_CDECL;
+ else
+ {
+ odp->type = TYPE_STDCALL;
+ args /= sizeof(int);
+ if (args >= sizeof(odp->u.func.arg_types))
+ {
+ error( "Too many arguments in stdcall function '%s'\n", odp->name );
+ return 0;
+ }
+ for (i = 0; i < args; i++) odp->u.func.arg_types[i] = 'l';
+ }
+
+ /* check for optional internal name */
+
+ if (token && !strcmp( token, "=" ))
+ {
+ if (!(token = GetToken(0))) goto error;
+ odp->link_name = xstrdup( token );
+ remove_stdcall_decoration( odp->link_name );
+ token = GetToken(1);
+ }
+
+ /* check for optional ordinal */
+
+ if (token && token[0] == '@')
+ {
+ int ordinal;
+
+ if (!IsNumberString( token+1 ))
+ {
+ error( "Expected number after '@', got '%s'\n", token+1 );
+ goto error;
+ }
+ ordinal = atoi( token+1 );
+ if (!ordinal)
+ {
+ error( "Ordinal 0 is not valid\n" );
+ goto error;
+ }
+ if (ordinal >= MAX_ORDINALS)
+ {
+ error( "Ordinal number %d too large\n", ordinal );
+ goto error;
+ }
+ if (ordinal > spec->limit) spec->limit = ordinal;
+ if (ordinal < spec->base) spec->base = ordinal;
+ odp->ordinal = ordinal;
+ token = GetToken(1);
+ }
+
+ /* check for other optional keywords */
+
+ if (token && !strcmp( token, "NONAME" ))
+ {
+ if (odp->ordinal == -1)
+ {
+ error( "NONAME requires an ordinal\n" );
+ goto error;
+ }
+ odp->export_name = odp->name;
+ odp->name = NULL;
+ odp->flags |= FLAG_NONAME;
+ token = GetToken(1);
+ }
+ if (token && !strcmp( token, "PRIVATE" ))
+ {
+ odp->flags |= FLAG_PRIVATE;
+ token = GetToken(1);
+ }
+ if (token && !strcmp( token, "DATA" ))
+ {
+ odp->type = TYPE_EXTERN;
+ token = GetToken(1);
+ }
+ if (token)
+ {
+ error( "Garbage text '%s' found at end of export declaration\n", token );
+ goto error;
+ }
+ return 1;
+
+error:
+ spec->nb_entry_points--;
+ free( odp->name );
+ return 0;
+}
+
+
+/*******************************************************************
+ * parse_def_file
+ *
+ * Parse a .def file.
+ */
+int parse_def_file( FILE *file, DLLSPEC *spec )
+{
+ const char *token;
+ int in_exports = 0;
+
+ input_file = file;
+ current_line = 0;
+
+ comment_chars = ";";
+ separator_chars = ",=";
+
+ while (get_next_line())
+ {
+ if (!(token = GetToken(1))) continue;
+
+ if (!strcmp( token, "LIBRARY" ) || !strcmp( token, "NAME" ))
+ {
+ if (!parse_def_library( spec )) continue;
+ goto end_of_line;
+ }
+ else if (!strcmp( token, "STACKSIZE" ))
+ {
+ if (!parse_def_stack_heap_size( 1, spec )) continue;
+ goto end_of_line;
+ }
+ else if (!strcmp( token, "HEAPSIZE" ))
+ {
+ if (!parse_def_stack_heap_size( 0, spec )) continue;
+ goto end_of_line;
+ }
+ else if (!strcmp( token, "EXPORTS" ))
+ {
+ in_exports = 1;
+ if (!(token = GetToken(1))) continue;
+ }
+ else if (!strcmp( token, "IMPORTS" ))
+ {
+ in_exports = 0;
+ if (!(token = GetToken(1))) continue;
+ }
+ else if (!strcmp( token, "SECTIONS" ))
+ {
+ in_exports = 0;
+ if (!(token = GetToken(1))) continue;
+ }
+
+ if (!in_exports) continue; /* ignore this line */
+ if (!parse_def_export( xstrdup(token), spec )) continue;
+
+ end_of_line:
+ if ((token = GetToken(1))) error( "Syntax error near '%s'\n", token );
+ }
+
+ current_line = 0; /* no longer parsing the input file */
+ assign_names( spec );
+ assign_ordinals( spec );
return !nb_errors;
}
reactos/tools/winebuild
diff -u -r1.1 -r1.2
--- relay.c 9 Dec 2003 18:44:25 -0000 1.1
+++ relay.c 23 Sep 2004 20:27:30 -0000 1.2
@@ -32,25 +32,22 @@
#include "build.h"
-#if defined(__GNUC__) && !defined(__svr4__)
-static const int use_stabs = 1;
-#else
-static const int use_stabs = 0;
-#endif
-
#ifdef __i386__
static void function_header( FILE *outfile, const char *name )
{
fprintf( outfile, "\n\t.align %d\n", get_alignment(4) );
- if (use_stabs)
- fprintf( outfile, "\t.stabs \"%s:F1\",36,0,0," __ASM_NAME("%s") "\n", name, name);
fprintf( outfile, "\t" __ASM_FUNC("%s") "\n", name );
fprintf( outfile, "\t.globl " __ASM_NAME("%s") "\n", name );
fprintf( outfile, __ASM_NAME("%s") ":\n", name );
}
+static void function_footer( FILE *outfile, const char *name )
+{
+ fprintf( outfile, ".size " __ASM_NAME("%s") ", . - " __ASM_NAME("%s") "\n", name, name );
+}
+
/*******************************************************************
* BuildCallFrom16Core
*
@@ -444,6 +441,10 @@
/* Return to return stub which will return to caller */
fprintf( outfile, "\tlret $12\n" );
}
+ if (thunk) function_footer( outfile, "__wine_call_from_16_thunk" );
+ else if (reg_func) function_footer( outfile, "__wine_call_from_16_regs" );
+ else if (short_ret) function_footer( outfile, "__wine_call_from_16_word" );
+ else function_footer( outfile, "__wine_call_from_16_long" );
}
@@ -605,6 +606,9 @@
/* Jump to the called routine */
fprintf( outfile, "\t.byte 0x66\n" );
fprintf( outfile, "\tlret\n" );
+
+ /* Function footer */
+ function_footer( outfile, name );
}
@@ -648,6 +652,9 @@
fprintf( outfile, "\tlret\n" );
+ /* Function footer */
+ function_footer( outfile, "CallTo16_Ret" );
+
/* Declare the return address and data selector variables */
fprintf( outfile, "\n\t.align %d\n", get_alignment(4) );
@@ -756,9 +763,6 @@
/* Function header */
fprintf( outfile, "\n\t.align %d\n", get_alignment(4) );
- if (use_stabs)
- fprintf( outfile, ".stabs \"CALL32_%s:F1\",36,0,0," __ASM_NAME("CALL32_%s") "\n",
- name, name );
fprintf( outfile, "\t.globl " __ASM_NAME("CALL32_%s") "\n", name );
fprintf( outfile, __ASM_NAME("CALL32_%s") ":\n", name );
@@ -882,6 +886,7 @@
fprintf( outfile, "\tpopl %%edi\n" );
fprintf( outfile, "\tpopl %%ebp\n" );
fprintf( outfile, "\tret\n" );
+ fprintf( outfile, ".size " __ASM_NAME("CALL32_%s") ", . - " __ASM_NAME("CALL32_%s") "\n", name, name );
}
static void BuildCallTo32CBClientRet( FILE *outfile, BOOL isEx )
@@ -907,6 +912,8 @@
}
fprintf( outfile, "\tlret\n" );
+ fprintf( outfile, ".size " __ASM_NAME("CALL32_%s_Ret") ", . - " __ASM_NAME("CALL32_%s_Ret") "\n", name, name );
+
/* Declare the return address variable */
fprintf( outfile, "\n\t.globl " __ASM_NAME("CALL32_%s_RetAddr") "\n", name );
@@ -1036,10 +1043,65 @@
fprintf( outfile, "\tpopl %%ds\n" );
fprintf( outfile, "\tiret\n" );
+ function_footer( outfile, "__wine_call_from_32_regs" );
function_header( outfile, "__wine_call_from_32_restore_regs" );
fprintf( outfile, "\tleal 4(%%esp),%%ecx\n" );
fprintf( outfile, "\tjmp 2b\n" );
+ function_footer( outfile, "__wine_call_from_32_restore_regs" );
+}
+
+
+/*******************************************************************
+ * BuildPendingEventCheck
+ *
+ * Build a function that checks whether there are any
+ * pending DPMI events.
+ *
+ * Stack layout:
+ *
+ * (sp+12) long eflags
+ * (sp+6) long cs
+ * (sp+2) long ip
+ * (sp) word fs
+ *
+ * On entry to function, fs register points to a valid TEB.
+ * On exit from function, stack will be popped.
+ */
+static void BuildPendingEventCheck( FILE *outfile )
+{
+ /* Function header */
+
+ function_header( outfile, "DPMI_PendingEventCheck" );
+
+ /* Check for pending events. */
+
+ fprintf( outfile, "\t.byte 0x64\n\ttestl $0xffffffff,(%d)\n",
+ STRUCTOFFSET(TEB,vm86_pending) );
+ fprintf( outfile, "\tje " __ASM_NAME("DPMI_PendingEventCheck_Cleanup") "\n" );
+
+ fprintf( outfile, "\t.byte 0x64\n\ttestl $0xffffffff,(%d)\n",
+ STRUCTOFFSET(TEB,dpmi_vif) );
+
+ fprintf( outfile, "\tje " __ASM_NAME("DPMI_PendingEventCheck_Cleanup") "\n" );
+
+ /* Process pending events. */
+
+ fprintf( outfile, "\tsti\n" );
+
+ /* Start cleanup. Restore fs register. */
+
+ fprintf( outfile, ".globl " __ASM_NAME("DPMI_PendingEventCheck_Cleanup") "\n" );
+ fprintf( outfile, __ASM_NAME("DPMI_PendingEventCheck_Cleanup") ":\n" );
+ fprintf( outfile, "\tpopw %%fs\n" );
+
+ /* Return from function. */
+
+ fprintf( outfile, ".globl " __ASM_NAME("DPMI_PendingEventCheck_Return") "\n" );
+ fprintf( outfile, __ASM_NAME("DPMI_PendingEventCheck_Return") ":\n" );
+ fprintf( outfile, "\tiret\n" );
+
+ function_footer( outfile, "DPMI_PendingEventCheck" );
}
@@ -1050,26 +1112,12 @@
*/
void BuildRelays16( FILE *outfile )
{
- char buffer[1024];
-
/* File header */
fprintf( outfile, "/* File generated automatically. Do not edit! */\n\n" );
fprintf( outfile, "\t.text\n" );
- if (output_file_name && use_stabs)
- {
- getcwd(buffer, sizeof(buffer));
- fprintf( outfile, "\t.file\t\"%s\"\n", output_file_name );
-
- /*
- * The stabs help the internal debugger as they are an indication that it
- * is sensible to step into a thunk/trampoline.
- */
- fprintf( outfile, ".stabs \"%s/\",100,0,0,Code_Start\n", buffer);
- fprintf( outfile, ".stabs \"%s\",100,0,0,Code_Start\n", output_file_name );
- fprintf( outfile, "Code_Start:\n\n" );
- }
+ fprintf( outfile, __ASM_NAME("__wine_spec_thunk_text_16") ":\n\n" );
fprintf( outfile, __ASM_NAME("Call16_Start") ":\n" );
fprintf( outfile, "\t.globl " __ASM_NAME("Call16_Start") "\n" );
@@ -1101,24 +1149,11 @@
fprintf( outfile, __ASM_NAME("Call16_End") ":\n" );
fprintf( outfile, "\t.globl " __ASM_NAME("Call16_End") "\n" );
-
- if (use_stabs)
- {
- fprintf( outfile, "\t.stabs \"\",100,0,0,.Letext\n");
- fprintf( outfile, ".Letext:\n");
-
- /* Some versions of gdb need to have the filename data for
- each section, so output it again for the data section. */
- if (output_file_name)
- {
- fprintf( outfile, ".stabs \"%s/\",100,0,0,Data_Start\n", buffer);
- fprintf( outfile, ".stabs \"%s\",100,0,0,Data_Start\n", output_file_name );
- fprintf( outfile, "Data_Start:\n\n" );
- }
- }
+ fprintf( outfile, "\t.size " __ASM_NAME("__wine_spec_thunk_text_16") ",. - " __ASM_NAME("__wine_spec_thunk_text_16") "\n" );
/* The whole Call16_Ret segment must lie within the .data section */
fprintf( outfile, "\n\t.data\n" );
+ fprintf( outfile, __ASM_NAME("__wine_spec_thunk_data_16") ":\n\n" );
fprintf( outfile, "\t.globl " __ASM_NAME("Call16_Ret_Start") "\n" );
fprintf( outfile, __ASM_NAME("Call16_Ret_Start") ":\n" );
@@ -1131,9 +1166,13 @@
/* CBClientThunkSLEx return stub */
BuildCallTo32CBClientRet( outfile, TRUE );
+ /* Pending DPMI events check stub */
+ BuildPendingEventCheck( outfile );
+
/* End of Call16_Ret segment */
fprintf( outfile, "\n\t.globl " __ASM_NAME("Call16_Ret_End") "\n" );
fprintf( outfile, __ASM_NAME("Call16_Ret_End") ":\n" );
+ fprintf( outfile, "\t.size " __ASM_NAME("__wine_spec_thunk_data_16") ",. - " __ASM_NAME("__wine_spec_thunk_data_16") "\n" );
}
/*******************************************************************
@@ -1147,30 +1186,12 @@
fprintf( outfile, "/* File generated automatically. Do not edit! */\n\n" );
fprintf( outfile, "\t.text\n" );
-
- if (output_file_name && use_stabs)
- {
- char buffer[1024];
- getcwd(buffer, sizeof(buffer));
- fprintf( outfile, "\t.file\t\"%s\"\n", output_file_name );
-
- /*
- * The stabs help the internal debugger as they are an indication that it
- * is sensible to step into a thunk/trampoline.
- */
- fprintf( outfile, ".stabs \"%s/\",100,0,0,Code_Start\n", buffer);
- fprintf( outfile, ".stabs \"%s\",100,0,0,Code_Start\n", output_file_name );
- fprintf( outfile, "Code_Start:\n\n" );
- }
+ fprintf( outfile, __ASM_NAME("__wine_spec_thunk_text_32") ":\n\n" );
/* 32-bit register entry point */
BuildCallFrom32Regs( outfile );
- if (use_stabs)
- {
- fprintf( outfile, "\t.stabs \"\",100,0,0,.Letext\n");
- fprintf( outfile, ".Letext:\n");
- }
+ fprintf( outfile, "\t.size " __ASM_NAME("__wine_spec_thunk_text_32") ",. - " __ASM_NAME("__wine_spec_thunk_text_32") "\n" );
}
#else /* __i386__ */
reactos/tools/winebuild
diff -u -r1.2 -r1.3
--- res16.c 4 Jan 2004 15:50:41 -0000 1.2
+++ res16.c 23 Sep 2004 20:27:30 -0000 1.3
@@ -37,12 +37,8 @@
#include <sys/mman.h>
#endif
-#ifdef WIN32
#include "windef.h"
#include "winbase.h"
-#else
-#include "winglue.h"
-#endif
#include "build.h"
#define ALIGNMENT 2 /* alignment for resource data */
@@ -73,28 +69,29 @@
unsigned int nb_names; /* total number of names */
};
-static struct resource *resources;
-static int nb_resources;
-
-static struct res_type *res_types;
-static int nb_types; /* total number of types */
+/* top level of the resource tree */
+struct res_tree
+{
+ struct res_type *types; /* types array */
+ unsigned int nb_types; /* total number of types */
+};
static const unsigned char *file_pos; /* current position in resource file */
static const unsigned char *file_end; /* end of resource file */
static const char *file_name; /* current resource file name */
-inline static struct resource *add_resource(void)
+inline static struct resource *add_resource( DLLSPEC *spec )
{
- resources = xrealloc( resources, (nb_resources + 1) * sizeof(*resources) );
- return &resources[nb_resources++];
+ spec->resources = xrealloc( spec->resources, (spec->nb_resources + 1) * sizeof(*spec->resources) );
+ return &spec->resources[spec->nb_resources++];
}
-static struct res_type *add_type( const struct resource *res )
+static struct res_type *add_type( struct res_tree *tree, const struct resource *res )
{
struct res_type *type;
- res_types = xrealloc( res_types, (nb_types + 1) * sizeof(*res_types) );
- type = &res_types[nb_types++];
+ tree->types = xrealloc( tree->types, (tree->nb_types + 1) * sizeof(*tree->types) );
+ type = &tree->types[tree->nb_types++];
type->type = &res->type;
type->res = res;
type->nb_names = 0;
@@ -155,9 +152,9 @@
}
/* load the next resource from the current file */
-static void load_next_resource(void)
+static void load_next_resource( DLLSPEC *spec )
{
- struct resource *res = add_resource();
+ struct resource *res = add_resource( spec );
get_string( &res->type );
get_string( &res->name );
@@ -169,7 +166,7 @@
}
/* load a Win16 .res file */
-void load_res16_file( const char *name )
+void load_res16_file( const char *name, DLLSPEC *spec )
{
int fd;
void *base;
@@ -190,7 +187,7 @@
file_name = name;
file_pos = base;
file_end = file_pos + st.st_size;
- while (file_pos < file_end) load_next_resource();
+ while (file_pos < file_end) load_next_resource( spec );
}
/* compare two strings/ids */
@@ -218,19 +215,32 @@
}
/* build the 2-level (type,name) resource tree */
-static void build_resource_tree(void)
+static struct res_tree *build_resource_tree( DLLSPEC *spec )
{
int i;
+ struct res_tree *tree;
struct res_type *type = NULL;
- qsort( resources, nb_resources, sizeof(*resources), cmp_res );
+ qsort( spec->resources, spec->nb_resources, sizeof(*spec->resources), cmp_res );
- for (i = 0; i < nb_resources; i++)
+ tree = xmalloc( sizeof(*tree) );
+ tree->types = NULL;
+ tree->nb_types = 0;
+
+ for (i = 0; i < spec->nb_resources; i++)
{
- if (!i || cmp_string( &resources[i].type, &resources[i-1].type )) /* new type */
- type = add_type( &resources[i] );
+ if (!i || cmp_string( &spec->resources[i].type, &spec->resources[i-1].type )) /* new type */
+ type = add_type( tree, &spec->resources[i] );
type->nb_names++;
}
+ return tree;
+}
+
+/* free the resource tree */
+static void free_resource_tree( struct res_tree *tree )
+{
+ free( tree->types );
+ free( tree );
}
inline static void put_byte( unsigned char **buffer, unsigned char val )
@@ -258,19 +268,19 @@
}
/* output the resource data */
-int output_res16_data( FILE *outfile )
+int output_res16_data( FILE *outfile, DLLSPEC *spec )
{
const struct resource *res;
unsigned char *buffer, *p;
int i, total;
- if (!nb_resources) return 0;
+ if (!spec->nb_resources) return 0;
- for (i = total = 0, res = resources; i < nb_resources; i++, res++)
+ for (i = total = 0, res = spec->resources; i < spec->nb_resources; i++, res++)
total += (res->data_size + ALIGN_MASK) & ~ALIGN_MASK;
buffer = p = xmalloc( total );
- for (i = 0, res = resources; i < nb_resources; i++, res++)
+ for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++)
{
memcpy( p, res->data, res->data_size );
p += res->data_size;
@@ -282,25 +292,26 @@
}
/* output the resource definitions */
-int output_res16_directory( unsigned char *buffer )
+int output_res16_directory( unsigned char *buffer, DLLSPEC *spec )
{
int i, offset, res_offset = 0;
unsigned int j;
+ struct res_tree *tree;
const struct res_type *type;
const struct resource *res;
unsigned char *start = buffer;
- build_resource_tree();
+ tree = build_resource_tree( spec );
offset = 4; /* alignment + terminator */
- offset += nb_types * 8; /* typeinfo structures */
- offset += nb_resources * 12; /* nameinfo structures */
+ offset += tree->nb_types * 8; /* typeinfo structures */
+ offset += spec->nb_resources * 12; /* nameinfo structures */
put_word( &buffer, ALIGNMENT );
/* type and name structures */
- for (i = 0, type = res_types; i < nb_types; i++, type++)
+ for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
{
if (type->type->str)
{
@@ -335,7 +346,7 @@
/* name strings */
- for (i = 0, type = res_types; i < nb_types; i++, type++)
+ for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
{
if (type->type->str) output_string( &buffer, type->type->str );
for (j = 0, res = type->res; j < type->nb_names; j++, res++)
@@ -346,5 +357,6 @@
put_byte( &buffer, 0 ); /* names terminator */
if ((buffer - start) & 1) put_byte( &buffer, 0 ); /* align on word boundary */
+ free_resource_tree( tree );
return buffer - start;
}
reactos/tools/winebuild
diff -u -r1.2 -r1.3
--- res32.c 4 Jan 2004 15:50:41 -0000 1.2
+++ res32.c 23 Sep 2004 20:27:30 -0000 1.3
@@ -37,12 +37,8 @@
#include <sys/mman.h>
#endif
-#ifdef WIN32
#include "windef.h"
#include "winbase.h"
-#else
-#include "winglue.h"
-#endif
#include "build.h"
/* Unicode string or integer id */
@@ -68,6 +64,7 @@
const struct string_id *name; /* name */
const struct resource *res; /* resource */
int nb_languages; /* number of languages */
+ unsigned int name_offset; /* offset of name in resource dir */
};
/* type level of the resource tree */
@@ -77,24 +74,28 @@
struct res_name *names; /* names array */
unsigned int nb_names; /* total number of names */
unsigned int nb_id_names; /* number of names that have a numeric id */
+ unsigned int name_offset; /* offset of type name in resource dir */
};
-static struct resource *resources;
-static int nb_resources;
-
-static struct res_type *res_types;
-static int nb_types; /* total number of types */
-static int nb_id_types; /* number of types that have a numeric id */
+/* top level of the resource tree */
+struct res_tree
+{
+ struct res_type *types; /* types array */
+ unsigned int nb_types; /* total number of types */
+};
static const unsigned char *file_pos; /* current position in resource file */
static const unsigned char *file_end; /* end of resource file */
static const char *file_name; /* current resource file name */
+/* size of a resource directory with n entries */
+#define RESDIR_SIZE(n) ((4 + 2 * (n)) * sizeof(int))
-inline static struct resource *add_resource(void)
+
+inline static struct resource *add_resource( DLLSPEC *spec )
{
- resources = xrealloc( resources, (nb_resources + 1) * sizeof(*resources) );
- return &resources[nb_resources++];
+ spec->resources = xrealloc( spec->resources, (spec->nb_resources + 1) * sizeof(spec->resources[0]) );
+ return &spec->resources[spec->nb_resources++];
}
static inline unsigned int strlenW( const WCHAR *str )
@@ -122,23 +123,22 @@
return name;
}
-static struct res_type *add_type( const struct resource *res )
+static struct res_type *add_type( struct res_tree *tree, const struct resource *res )
{
struct res_type *type;
- res_types = xrealloc( res_types, (nb_types + 1) * sizeof(*res_types) );
- type = &res_types[nb_types++];
+ tree->types = xrealloc( tree->types, (tree->nb_types + 1) * sizeof(*tree->types) );
+ type = &tree->types[tree->nb_types++];
type->type = &res->type;
type->names = NULL;
type->nb_names = 0;
type->nb_id_names = 0;
- if (!type->type->str) nb_id_types++;
return type;
}
/* get the next word from the current resource file */
static WORD get_word(void)
{
- WORD ret = *(WORD *)file_pos;
+ WORD ret = *(const WORD *)file_pos;
file_pos += sizeof(WORD);
if (file_pos > file_end) fatal_error( "%s is a truncated file\n", file_name );
return ret;
@@ -147,7 +147,7 @@
/* get the next dword from the current resource file */
static DWORD get_dword(void)
{
- DWORD ret = *(DWORD *)file_pos;
+ DWORD ret = *(const DWORD *)file_pos;
file_pos += sizeof(DWORD);
if (file_pos > file_end) fatal_error( "%s is a truncated file\n", file_name );
return ret;
@@ -156,7 +156,7 @@
/* get a string from the current resource file */
static void get_string( struct string_id *str )
{
- if (*(WCHAR *)file_pos == 0xffff)
+ if (*(const WCHAR *)file_pos == 0xffff)
{
get_word(); /* skip the 0xffff */
str->str = NULL;
@@ -164,7 +164,7 @@
}
else
{
- WCHAR *p = xmalloc( (strlenW((WCHAR*)file_pos) + 1) * sizeof(WCHAR) );
+ WCHAR *p = xmalloc( (strlenW((const WCHAR*)file_pos) + 1) * sizeof(WCHAR) );
str->str = p;
str->id = 0;
while ((*p++ = get_word()));
@@ -188,10 +188,10 @@
}
/* load the next resource from the current file */
-static void load_next_resource(void)
+static void load_next_resource( DLLSPEC *spec )
{
DWORD hdr_size;
- struct resource *res = add_resource();
+ struct resource *res = add_resource( spec );
res->data_size = (get_dword() + 3) & ~3;
hdr_size = get_dword();
@@ -207,12 +207,12 @@
get_dword(); /* skip version */
get_dword(); /* skip characteristics */
- file_pos = (char *)res->data + res->data_size;
+ file_pos = (const char *)res->data + res->data_size;
if (file_pos > file_end) fatal_error( "%s is a truncated file\n", file_name );
}
/* load a Win32 .res file */
-int load_res32_file( const char *name )
+int load_res32_file( const char *name, DLLSPEC *spec )
{
int fd, ret;
void *base;
@@ -235,7 +235,7 @@
file_end = file_pos + st.st_size;
if ((ret = check_header()))
{
- while (file_pos < file_end) load_next_resource();
+ while (file_pos < file_end) load_next_resource( spec );
}
close( fd );
return ret;
@@ -267,27 +267,43 @@
}
/* build the 3-level (type,name,language) resource tree */
-static void build_resource_tree(void)
+static struct res_tree *build_resource_tree( DLLSPEC *spec )
{
int i;
+ struct res_tree *tree;
struct res_type *type = NULL;
struct res_name *name = NULL;
- qsort( resources, nb_resources, sizeof(*resources), cmp_res );
+ qsort( spec->resources, spec->nb_resources, sizeof(*spec->resources), cmp_res );
+
+ tree = xmalloc( sizeof(*tree) );
+ tree->types = NULL;
+ tree->nb_types = 0;
- for (i = 0; i < nb_resources; i++)
+ for (i = 0; i < spec->nb_resources; i++)
{
- if (!i || cmp_string( &resources[i].type, &resources[i-1].type )) /* new type */
+ if (!i || cmp_string( &spec->resources[i].type, &spec->resources[i-1].type )) /* new type */
{
- type = add_type( &resources[i] );
- name = add_name( type, &resources[i] );
+ type = add_type( tree, &spec->resources[i] );
+ name = add_name( type, &spec->resources[i] );
}
- else if (cmp_string( &resources[i].name, &resources[i-1].name )) /* new name */
+ else if (cmp_string( &spec->resources[i].name, &spec->resources[i-1].name )) /* new name */
{
- name = add_name( type, &resources[i] );
+ name = add_name( type, &spec->resources[i] );
}
else name->nb_languages++;
}
+ return tree;
+}
+
+/* free the resource tree */
+static void free_resource_tree( struct res_tree *tree )
+{
+ int i;
+
+ for (i = 0; i < tree->nb_types; i++) free( tree->types[i].names );
+ free( tree->types );
+ free( tree );
}
/* output a Unicode string */
@@ -302,21 +318,22 @@
}
/* output the resource definitions */
-int output_resources( FILE *outfile )
+void output_resources( FILE *outfile, DLLSPEC *spec )
{
- int i, j, k;
- unsigned int n;
- const struct res_type *type;
- const struct res_name *name;
+ int i, j, k, nb_id_types;
+ unsigned int n, offset, data_offset;
+ struct res_tree *tree;
+ struct res_type *type;
+ struct res_name *name;
const struct resource *res;
- if (!nb_resources) return 0;
+ if (!spec->nb_resources) return;
- build_resource_tree();
+ tree = build_resource_tree( spec );
/* resource data */
- for (i = 0, res = resources; i < nb_resources; i++, res++)
+ for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++)
{
const unsigned int *p = res->data;
int size = res->data_size / 4;
@@ -348,69 +365,86 @@
/* resource directory definition */
- fprintf( outfile, "#define OFFSETOF(field) ((char*)&((struct res_struct *)0)->field - (char*)((struct res_struct *) 0))\n" );
fprintf( outfile, "static struct res_struct{\n" );
fprintf( outfile, " struct res_dir type_dir;\n" );
- fprintf( outfile, " struct res_dir_entry type_entries[%d];\n", nb_types );
+ fprintf( outfile, " struct res_dir_entry type_entries[%d];\n", tree->nb_types );
+ offset = RESDIR_SIZE( tree->nb_types );
- for (i = 0, type = res_types; i < nb_types; i++, type++)
+ for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
{
+ offset += RESDIR_SIZE( type->nb_names );
fprintf( outfile, " struct res_dir name_%d_dir;\n", i );
fprintf( outfile, " struct res_dir_entry name_%d_entries[%d];\n", i, type->nb_names );
for (n = 0, name = type->names; n < type->nb_names; n++, name++)
{
+ offset += RESDIR_SIZE( name->nb_languages );
fprintf( outfile, " struct res_dir lang_%d_%d_dir;\n", i, n );
fprintf( outfile, " struct res_dir_entry lang_%d_%d_entries[%d];\n",
i, n, name->nb_languages );
}
}
- fprintf( outfile, " struct res_data_entry data_entries[%d];\n", nb_resources );
+ fprintf( outfile, " struct res_data_entry data_entries[%d];\n", spec->nb_resources );
+ offset += spec->nb_resources * 4 * sizeof(int);
- for (i = 0, type = res_types; i < nb_types; i++, type++)
+ for (i = nb_id_types = 0, type = tree->types; i < tree->nb_types; i++, type++)
{
if (type->type->str)
+ {
+ type->name_offset = offset | 0x80000000;
+ offset += (strlenW(type->type->str)+1) * sizeof(unsigned short);
fprintf( outfile, " unsigned short type_%d_name[%d];\n",
i, strlenW(type->type->str)+1 );
+ }
+ else
+ {
+ type->name_offset = type->type->id;
+ nb_id_types++;
+ }
+
for (n = 0, name = type->names; n < type->nb_names; n++, name++)
{
if (name->name->str)
+ {
+ name->name_offset = offset | 0x80000000;
+ offset += (strlenW(name->name->str)+1) * sizeof(unsigned short);
fprintf( outfile, " unsigned short name_%d_%d_name[%d];\n",
i, n, strlenW(name->name->str)+1 );
+ }
+ else name->name_offset = name->name->id;
}
}
/* resource directory contents */
fprintf( outfile, "} resources = {\n" );
- fprintf( outfile, " { 0, 0, 0, 0, %d, %d },\n", nb_types - nb_id_types, nb_id_types );
+ fprintf( outfile, " { 0, 0, 0, 0, %d, %d },\n", tree->nb_types - nb_id_types, nb_id_types );
/* dump the type directory */
+ offset = RESDIR_SIZE( tree->nb_types );
fprintf( outfile, " {\n" );
- for (i = 0, type = res_types; i < nb_types; i++, type++)
+ for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
{
- if (!type->type->str)
- fprintf( outfile, " { 0x%04x, OFFSETOF(name_%d_dir) | 0x80000000 },\n",
- type->type->id, i );
- else
- fprintf( outfile, " { OFFSETOF(type_%d_name) | 0x80000000, OFFSETOF(name_%d_dir) | 0x80000000 },\n",
- i, i );
+ fprintf( outfile, " { 0x%08x, 0x%08x },\n", type->name_offset, offset | 0x80000000 );
+ offset += RESDIR_SIZE( type->nb_names );
+ for (n = 0, name = type->names; n < type->nb_names; n++, name++)
+ offset += RESDIR_SIZE( name->nb_languages );
}
fprintf( outfile, " },\n" );
+ data_offset = offset;
+ offset = RESDIR_SIZE( tree->nb_types );
+
/* dump the names and languages directories */
- for (i = 0, type = res_types; i < nb_types; i++, type++)
+ for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
{
fprintf( outfile, " { 0, 0, 0, 0, %d, %d }, /* name_%d_dir */\n {\n",
type->nb_names - type->nb_id_names, type->nb_id_names, i );
+ offset += RESDIR_SIZE( type->nb_names );
for (n = 0, name = type->names; n < type->nb_names; n++, name++)
{
- if (!name->name->str)
- fprintf( outfile, " { 0x%04x, OFFSETOF(lang_%d_%d_dir) | 0x80000000 },\n",
- name->name->id, i, n );
- else
- fprintf( outfile, " { OFFSETOF(name_%d_%d_name) | 0x80000000, OFFSETOF(lang_%d_%d_dir) | 0x80000000 },\n",
- i, n, i, n );
+ fprintf( outfile, " { 0x%08x, 0x%08x },\n", name->name_offset, offset | 0x80000000 );
+ offset += RESDIR_SIZE( name->nb_languages );
}
fprintf( outfile, " },\n" );
@@ -420,8 +454,8 @@
name->nb_languages, i, n );
for (k = 0, res = name->res; k < name->nb_languages; k++, res++)
{
- fprintf( outfile, " { 0x%04x, OFFSETOF(data_entries[%d]) },\n",
- res->lang, res - resources );
+ fprintf( outfile, " { 0x%04x, 0x%08x },\n",
+ res->lang, data_offset + (res - spec->resources) * 4 * sizeof(int) );
}
fprintf( outfile, " },\n" );
}
@@ -429,13 +463,14 @@
/* dump the resource data entries */
fprintf( outfile, " {\n" );
- for (i = 0, res = resources; i < nb_resources; i++, res++)
+ for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++)
{
- fprintf( outfile, " { res_%d, sizeof(res_%d), 0, 0 },\n", i, i );
+ fprintf( outfile, " { res_%d, sizeof(res_%d), 0, 0 }, /* %08x */\n", i, i,
+ data_offset + i * 4 * sizeof(int) );
}
/* dump the name strings */
- for (i = 0, type = res_types; i < nb_types; i++, type++)
+ for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
{
if (type->type->str)
{
@@ -451,6 +486,6 @@
}
}
}
- fprintf( outfile, " }\n};\n#undef OFFSETOF\n\n" );
- return nb_resources;
+ fprintf( outfile, " }\n};\n\n" );
+ free_resource_tree( tree );
}
reactos/tools/winebuild
diff -u -r1.1 -r1.2
--- spec16.c 9 Dec 2003 18:44:25 -0000 1.1
+++ spec16.c 23 Sep 2004 20:27:30 -0000 1.2
@@ -111,7 +111,7 @@
* as a byte stream into the assembly code.
*/
static int BuildModule16( FILE *outfile, int max_code_offset,
- int max_data_offset )
+ int max_data_offset, DLLSPEC *spec )
{
int i;
char *buffer;
@@ -142,7 +142,7 @@
pModule->next = 0;
pModule->flags = NE_FFLAGS_SINGLEDATA | NE_FFLAGS_BUILTIN | NE_FFLAGS_LIBMODULE;
pModule->dgroup = 2;
- pModule->heap_size = DLLHeapSize;
+ pModule->heap_size = spec->heap_size;
pModule->stack_size = 0;
pModule->ip = 0;
pModule->cs = 0;
@@ -172,8 +172,8 @@
pModule->fileinfo = (int)pFileInfo - (int)pModule;
memset( pFileInfo, 0, sizeof(*pFileInfo) - sizeof(pFileInfo->szPathName) );
pFileInfo->cBytes = sizeof(*pFileInfo) - sizeof(pFileInfo->szPathName)
- + strlen(dll_file_name);
- strcpy( pFileInfo->szPathName, dll_file_name );
+ + strlen(spec->file_name);
+ strcpy( pFileInfo->szPathName, spec->file_name );
pstr = (char *)pFileInfo + pFileInfo->cBytes + 1;
/* Segment table */
@@ -201,7 +201,7 @@
pstr = (char *)pSegment;
pstr = (char *)(((long)pstr + 3) & ~3);
pModule->res_table = (int)pstr - (int)pModule;
- pstr += output_res16_directory( pstr );
+ pstr += output_res16_directory( pstr, spec );
/* Imported names table */
@@ -215,16 +215,16 @@
pstr = (char *)(((long)pstr + 3) & ~3);
pModule->name_table = (int)pstr - (int)pModule;
/* First entry is module name */
- *pstr = strlen( dll_name );
- strcpy( pstr + 1, dll_name );
+ *pstr = strlen( spec->dll_name );
+ strcpy( pstr + 1, spec->dll_name );
strupper( pstr + 1 );
pstr += *pstr + 1;
*pstr++ = 0;
*pstr++ = 0;
/* Store all ordinals */
- for (i = 1; i <= Limit; i++)
+ for (i = 1; i <= spec->limit; i++)
{
- ORDDEF *odp = Ordinals[i];
+ ORDDEF *odp = spec->ordinals[i];
WORD ord = i;
if (!odp || !odp->name[0]) continue;
*pstr = strlen( odp->name );
@@ -240,10 +240,10 @@
pstr = (char *)(((long)pstr + 3) & ~3);
pModule->entry_table = (int)pstr - (int)pModule;
- for (i = 1; i <= Limit; i++)
+ for (i = 1; i <= spec->limit; i++)
{
int selector = 0;
- ORDDEF *odp = Ordinals[i];
+ ORDDEF *odp = spec->ordinals[i];
if (!odp) continue;
switch (odp->type)
@@ -317,8 +317,6 @@
* extern LONG WINAPI PREFIX_CallFrom16_C_long_xxx( FARPROC func, LPBYTE args );
* extern void WINAPI PREFIX_CallFrom16_C_regs_xxx( FARPROC func, LPBYTE args,
* CONTEXT86 *context );
- * extern void WINAPI PREFIX_CallFrom16_C_intr_xxx( FARPROC func, LPBYTE args,
- * CONTEXT86 *context );
*
* where 'C' is the calling convention ('p' for pascal or 'c' for cdecl),
* and each 'x' is an argument ('w'=word, 's'=signed word, 'l'=long,
@@ -333,10 +331,6 @@
* For register functions, the arguments (if present) are converted just
* the same as for normal functions, but in addition the CONTEXT86 pointer
* filled with the current register values is passed to the 32-bit routine.
- * (An 'intr' interrupt handler routine is treated exactly like a register
- * routine, except that upon return, the flags word pushed onto the stack
- * by the interrupt is removed by the 16-bit call stub.)
- *
*/
static void BuildCallFrom16Func( FILE *outfile, const char *profile, const char *prefix )
{
@@ -360,7 +354,6 @@
if (!strncmp( "word_", profile + 2, 5 )) short_ret = 1;
else if (!strncmp( "regs_", profile + 2, 5 )) reg_func = 1;
- else if (!strncmp( "intr_", profile + 2, 5 )) reg_func = 2;
else if (strncmp( "long_", profile + 2, 5 ))
{
fprintf( stderr, "Invalid function name '%s', ignored\n", profile );
@@ -467,7 +460,6 @@
(odp->type == TYPE_PASCAL) ? "p" :
(odp->type == TYPE_VARARGS) ? "v" : "c",
(odp->flags & FLAG_REGISTER) ? "regs" :
- (odp->flags & FLAG_INTERRUPT) ? "intr" :
(odp->flags & FLAG_RET16) ? "word" : "long",
odp->u.func.arg_types );
return buffer;
@@ -479,8 +471,8 @@
*/
static int Spec16TypeCompare( const void *e1, const void *e2 )
{
- const ORDDEF *odp1 = *(const ORDDEF **)e1;
- const ORDDEF *odp2 = *(const ORDDEF **)e2;
+ const ORDDEF *odp1 = *(const ORDDEF * const *)e1;
+ const ORDDEF *odp2 = *(const ORDDEF * const *)e2;
int retval;
int type1 = odp1->type;
int type2 = odp2->type;
@@ -490,8 +482,8 @@
if ((retval = type1 - type2) != 0) return retval;
- type1 = odp1->flags & (FLAG_RET16|FLAG_REGISTER|FLAG_INTERRUPT);
- type2 = odp2->flags & (FLAG_RET16|FLAG_REGISTER|FLAG_INTERRUPT);
+ type1 = odp1->flags & (FLAG_RET16|FLAG_REGISTER);
+ type2 = odp2->flags & (FLAG_RET16|FLAG_REGISTER);
if ((retval = type1 - type2) != 0) return retval;
@@ -504,14 +496,14 @@
*
* Output the functions for stub entry points
*/
-static void output_stub_funcs( FILE *outfile )
+static void output_stub_funcs( FILE *outfile, const DLLSPEC *spec )
{
int i;
char *p;
- for (i = 0; i <= Limit; i++)
+ for (i = 0; i <= spec->limit; i++)
{
- ORDDEF *odp = Ordinals[i];
+ ORDDEF *odp = spec->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" );
@@ -528,7 +520,7 @@
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] = \"%s\";\n", dll_file_name );
+ fprintf( outfile, " rec.info[0] = \"%s\";\n", spec->file_name );
fprintf( outfile, " rec.info[1] = func;\n" );
fprintf( outfile, "#ifdef __GNUC__\n" );
fprintf( outfile, " rec.addr = __builtin_return_address(1);\n" );
@@ -538,9 +530,9 @@
fprintf( outfile, " for (;;) RtlRaiseException( &rec );\n}\n\n" );
break;
}
- for (i = 0; i <= Limit; i++)
+ for (i = 0; i <= spec->limit; i++)
{
- ORDDEF *odp = Ordinals[i];
+ ORDDEF *odp = spec->ordinals[i];
if (!odp || odp->type != TYPE_STUB) continue;
odp->link_name = xrealloc( odp->link_name, strlen(odp->name) + 13 );
strcpy( odp->link_name, "__wine_stub_" );
@@ -557,7 +549,7 @@
*
* Build a Win16 assembly file from a spec file.
*/
-void BuildSpec16File( FILE *outfile )
+void BuildSpec16File( FILE *outfile, DLLSPEC *spec )
{
ORDDEF **type, **typelist;
int i, nFuncs, nTypes;
@@ -580,22 +572,22 @@
memset( data, 0, 16 );
data_offset = 16;
- if (!dll_name) /* set default name from file name */
+ if (!spec->dll_name) /* set default name from file name */
{
char *p;
- dll_name = xstrdup( dll_file_name );
- if ((p = strrchr( dll_name, '.' ))) *p = 0;
+ spec->dll_name = xstrdup( spec->file_name );
+ if ((p = strrchr( spec->dll_name, '.' ))) *p = 0;
}
- output_stub_funcs( outfile );
+ output_stub_funcs( outfile, spec );
/* Build sorted list of all argument types, without duplicates */
- typelist = (ORDDEF **)calloc( Limit+1, sizeof(ORDDEF *) );
+ typelist = (ORDDEF **)calloc( spec->limit+1, sizeof(ORDDEF *) );
- for (i = nFuncs = 0; i <= Limit; i++)
+ for (i = nFuncs = 0; i <= spec->limit; i++)
{
- ORDDEF *odp = Ordinals[i];
+ ORDDEF *odp = spec->ordinals[i];
if (!odp) continue;
switch (odp->type)
{
@@ -627,15 +619,15 @@
char profile[101];
strcpy( profile, get_function_name( typelist[i] ));
- BuildCallFrom16Func( outfile, profile, dll_file_name );
+ BuildCallFrom16Func( outfile, profile, spec->file_name );
}
#endif
/* Output the DLL functions prototypes */
- for (i = 0; i <= Limit; i++)
+ for (i = 0; i <= spec->limit; i++)
{
- ORDDEF *odp = Ordinals[i];
+ ORDDEF *odp = spec->ordinals[i];
if (!odp) continue;
switch(odp->type)
{
@@ -701,8 +693,6 @@
break;
}
- if (typelist[i]->flags & FLAG_INTERRUPT) argsize += 2;
-
/* build the arg types bit fields */
arg_types[0] = arg_types[1] = 0;
for (j = 0; typelist[i]->u.func.arg_types[j]; j++)
@@ -719,13 +709,13 @@
}
arg_types[j / 10] |= type << (3 * (j % 10));
}
- if (typelist[i]->flags & (FLAG_REGISTER|FLAG_INTERRUPT)) arg_types[0] |= ARG_REGISTER;
+ if (typelist[i]->flags & FLAG_REGISTER) arg_types[0] |= ARG_REGISTER;
if (typelist[i]->flags & FLAG_RET16) arg_types[0] |= ARG_RET16;
#ifdef __i386__
fprintf( outfile, " { 0x68, __wine_%s_CallFrom16_%s, 0x9a, __wine_call_from_16_%s,\n",
- make_c_identifier(dll_file_name), profile,
- (typelist[i]->flags & (FLAG_REGISTER|FLAG_INTERRUPT)) ? "regs":
+ make_c_identifier(spec->file_name), profile,
+ (typelist[i]->flags & FLAG_REGISTER) ? "regs":
(typelist[i]->flags & FLAG_RET16) ? "word" : "long" );
if (argsize)
fprintf( outfile, " 0x%04x, 0xca66, %d, { 0x%08x, 0x%08x } },\n",
@@ -745,9 +735,9 @@
}
fprintf( outfile, " },\n {\n" );
- for (i = 0; i <= Limit; i++)
+ for (i = 0; i <= spec->limit; i++)
{
- ORDDEF *odp = Ordinals[i];
+ ORDDEF *odp = spec->ordinals[i];
if (!odp) continue;
switch (odp->type)
{
@@ -767,7 +757,7 @@
type = bsearch( &odp, typelist, nTypes, sizeof(ORDDEF *), Spec16TypeCompare );
assert( type );
- fprintf( outfile, " /* %s.%d */ ", dll_name, i );
+ fprintf( outfile, " /* %s.%d */ ", spec->dll_name, i );
#ifdef __i386__
fprintf( outfile, "{ 0x5566, 0x68, %s, 0xe866, %d /* %s */ },\n",
#else
@@ -797,8 +787,8 @@
/* Build the module */
- module_size = BuildModule16( outfile, code_offset, data_offset );
- res_size = output_res16_data( outfile );
+ module_size = BuildModule16( outfile, code_offset, data_offset, spec );
+ res_size = output_res16_data( outfile, spec );
/* Output the DLL descriptor */
@@ -816,14 +806,14 @@
fprintf( outfile, " sizeof(Module),\n" );
fprintf( outfile, " &code_segment,\n" );
fprintf( outfile, " Data_Segment,\n" );
- fprintf( outfile, " \"%s\",\n", owner_name );
+ fprintf( outfile, " \"%s\",\n", spec->owner_name );
fprintf( outfile, " %s\n", res_size ? "resource_data" : "0" );
fprintf( outfile, "};\n" );
/* Output the DLL constructor */
- sprintf( constructor, "__wine_spec_%s_init", make_c_identifier(dll_file_name) );
- sprintf( destructor, "__wine_spec_%s_fini", make_c_identifier(dll_file_name) );
+ sprintf( constructor, "__wine_spec_%s_init", make_c_identifier(spec->file_name) );
+ sprintf( destructor, "__wine_spec_%s_fini", make_c_identifier(spec->file_name) );
output_dll_init( outfile, constructor, destructor );
fprintf( outfile,
reactos/tools/winebuild
diff -u -r1.5 -r1.6
--- spec32.c 18 Jan 2004 13:42:57 -0000 1.5
+++ spec32.c 23 Sep 2004 20:27:30 -0000 1.6
@@ -61,48 +61,42 @@
*
* Generate an internal name for an entry point. Used for stubs etc.
*/
-static const char *make_internal_name( const ORDDEF *odp, const char *prefix )
+static const char *make_internal_name( const ORDDEF *odp, DLLSPEC *spec, const char *prefix )
{
static char buffer[256];
if (odp->name || odp->export_name)
{
char *p;
- sprintf( buffer, "__wine_%s_%s_%s", prefix, dll_file_name,
+ sprintf( buffer, "__wine_%s_%s_%s", prefix, spec->file_name,
odp->name ? odp->name : odp->export_name );
/* make sure name is a legal C identifier */
for (p = buffer; *p; p++) if (!isalnum(*p) && *p != '_') break;
if (!*p) return buffer;
}
- sprintf( buffer, "__wine_%s_%s_%d", prefix, make_c_identifier(dll_file_name), odp->ordinal );
+ sprintf( buffer, "__wine_%s_%s_%d", prefix, make_c_identifier(spec->file_name), odp->ordinal );
return buffer;
}
/*******************************************************************
- * AssignOrdinals
+ * declare_weak_function
*
- * Assign ordinals to all entry points.
+ * Output a prototype for a weak function.
*/
-static void AssignOrdinals(void)
+static void declare_weak_function( FILE *outfile, const char *ret_type, const char *name, const char *params)
{
- int i, ordinal;
-
- if ( !nb_names ) return;
-
- /* 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++)
- {
- if (Names[i]->ordinal != -1) continue; /* already has an ordinal */
- while (Ordinals[ordinal]) ordinal++;
- if (ordinal >= MAX_ORDINALS)
- {
- current_line = Names[i]->lineno;
- fatal_error( "Too many functions defined (max %d)\n", MAX_ORDINALS );
- }
- Names[i]->ordinal = ordinal;
- Ordinals[ordinal] = Names[i];
- }
- if (ordinal > Limit) Limit = ordinal;
+ fprintf( outfile, "#ifdef __GNUC__\n" );
+ fprintf( outfile, "# ifdef __APPLE__\n" );
+ fprintf( outfile, "extern %s %s(%s) __attribute__((weak_import));\n", ret_type, name, params );
+ fprintf( outfile, "static %s (*__wine_spec_weak_%s)(%s) = %s;\n", ret_type, name, params, name );
+ fprintf( outfile, "#define %s __wine_spec_weak_%s\n", name, name );
+ fprintf( outfile, "# else\n" );
+ fprintf( outfile, "extern %s %s(%s) __attribute__((weak));\n", ret_type, name, params );
+ fprintf( outfile, "# endif\n" );
+ fprintf( outfile, "#else\n" );
+ fprintf( outfile, "extern %s %s(%s);\n", ret_type, name, params );
+ fprintf( outfile, "static void __asm__dummy_%s(void)", name );
+ fprintf( outfile, " { asm(\".weak " __ASM_NAME("%s") "\"); }\n", name );
+ fprintf( outfile, "#endif\n\n" );
}
@@ -140,7 +134,7 @@
*
* Output the export table for a Win32 module.
*/
-static int output_exports( FILE *outfile, int nr_exports )
+static int output_exports( FILE *outfile, int nr_exports, DLLSPEC *spec )
{
int i, fwd_size = 0, total_size = 0;
@@ -156,11 +150,11 @@
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* TimeDateStamp */
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* MajorVersion/MinorVersion */
fprintf( outfile, " \"\\t.long __wine_spec_exp_names\\n\"\n" ); /* Name */
- fprintf( outfile, " \"\\t.long %d\\n\"\n", Base ); /* Base */
- fprintf( outfile, " \"\\t.long %d\\n\"\n", nr_exports ); /* NumberOfFunctions */
- fprintf( outfile, " \"\\t.long %d\\n\"\n", nb_names ); /* NumberOfNames */
+ fprintf( outfile, " \"\\t.long %d\\n\"\n", spec->base ); /* Base */
+ fprintf( outfile, " \"\\t.long %d\\n\"\n", nr_exports ); /* NumberOfFunctions */
+ fprintf( outfile, " \"\\t.long %d\\n\"\n", spec->nb_names ); /* NumberOfNames */
fprintf( outfile, " \"\\t.long __wine_spec_exports_funcs\\n\"\n" ); /* AddressOfFunctions */
- if (nb_names)
+ if (spec->nb_names)
{
fprintf( outfile, " \"\\t.long __wine_spec_exp_name_ptrs\\n\"\n" ); /* AddressOfNames */
fprintf( outfile, " \"\\t.long __wine_spec_exp_ordinals\\n\"\n" ); /* AddressOfNameOrdinals */
@@ -175,9 +169,9 @@
/* output the function pointers */
fprintf( outfile, " \"__wine_spec_exports_funcs:\\n\"\n" );
- for (i = Base; i <= Limit; i++)
+ for (i = spec->base; i <= spec->limit; i++)
{
- ORDDEF *odp = Ordinals[i];
+ ORDDEF *odp = spec->ordinals[i];
if (!odp) fprintf( outfile, " \"\\t.long 0\\n\"\n" );
else switch(odp->type)
{
@@ -188,7 +182,8 @@
if (!(odp->flags & FLAG_FORWARD))
{
fprintf( outfile, " \"\\t.long " __ASM_NAME("%s") "\\n\"\n",
- (odp->flags & FLAG_REGISTER) ? make_internal_name(odp,"regs") : odp->link_name );
+ (odp->flags & FLAG_REGISTER) ? make_internal_name( odp, spec, "regs" )
+ : odp->link_name );
}
else
{
@@ -197,49 +192,51 @@
}
break;
case TYPE_STUB:
- fprintf( outfile, " \"\\t.long " __ASM_NAME("%s") "\\n\"\n", make_internal_name( odp, "stub" ) );
+ fprintf( outfile, " \"\\t.long " __ASM_NAME("%s") "\\n\"\n",
+ make_internal_name( odp, spec, "stub" ) );
break;
default:
assert(0);
}
}
- total_size += (Limit - Base + 1) * sizeof(int);
+ total_size += (spec->limit - spec->base + 1) * sizeof(int);
- if (nb_names)
+ if (spec->nb_names)
{
/* output the function name pointers */
- int namepos = strlen(dll_file_name) + 1;
+ int namepos = strlen(spec->file_name) + 1;
fprintf( outfile, " \"__wine_spec_exp_name_ptrs:\\n\"\n" );
- for (i = 0; i < nb_names; i++)
+ for (i = 0; i < spec->nb_names; i++)
{
fprintf( outfile, " \"\\t.long __wine_spec_exp_names+%d\\n\"\n", namepos );
- namepos += strlen(Names[i]->name) + 1;
+ namepos += strlen(spec->names[i]->name) + 1;
}
- total_size += nb_names * sizeof(int);
+ total_size += spec->nb_names * sizeof(int);
}
/* output the function names */
fprintf( outfile, " \"\\t.text\\n\"\n" );
fprintf( outfile, " \"__wine_spec_exp_names:\\n\"\n" );
- fprintf( outfile, " \"\\t" __ASM_STRING " \\\"%s\\\"\\n\"\n", dll_file_name );
- for (i = 0; i < nb_names; i++)
- fprintf( outfile, " \"\\t" __ASM_STRING " \\\"%s\\\"\\n\"\n", Names[i]->name );
+ fprintf( outfile, " \"\\t" __ASM_STRING " \\\"%s\\\"\\n\"\n", spec->file_name );
+ for (i = 0; i < spec->nb_names; i++)
+ fprintf( outfile, " \"\\t" __ASM_STRING " \\\"%s\\\"\\n\"\n", spec->names[i]->name );
fprintf( outfile, " \"\\t.data\\n\"\n" );
- if (nb_names)
+ if (spec->nb_names)
{
/* output the function ordinals */
fprintf( outfile, " \"__wine_spec_exp_ordinals:\\n\"\n" );
- for (i = 0; i < nb_names; i++)
+ for (i = 0; i < spec->nb_names; i++)
{
- fprintf( outfile, " \"\\t" __ASM_SHORT " %d\\n\"\n", Names[i]->ordinal - Base );
+ fprintf( outfile, " \"\\t" __ASM_SHORT " %d\\n\"\n",
+ spec->names[i]->ordinal - spec->base );
}
- total_size += nb_names * sizeof(short);
- if (nb_names % 2)
+ total_size += spec->nb_names * sizeof(short);
+ if (spec->nb_names % 2)
{
fprintf( outfile, " \"\\t" __ASM_SHORT " 0\\n\"\n" );
total_size += sizeof(short);
@@ -251,9 +248,9 @@
if (fwd_size)
{
fprintf( outfile, " \"__wine_spec_forwards:\\n\"\n" );
- for (i = Base; i <= Limit; i++)
+ for (i = spec->base; i <= spec->limit; i++)
{
- ORDDEF *odp = Ordinals[i];
+ ORDDEF *odp = spec->ordinals[i];
if (odp && (odp->flags & FLAG_FORWARD))
fprintf( outfile, " \"\\t" __ASM_STRING " \\\"%s\\\"\\n\"\n", odp->link_name );
}
@@ -265,9 +262,9 @@
if (debugging)
{
- for (i = Base; i <= Limit; i++)
+ for (i = spec->base; i <= spec->limit; i++)
{
- ORDDEF *odp = Ordinals[i];
+ ORDDEF *odp = spec->ordinals[i];
unsigned int j, args, mask = 0;
const char *name;
@@ -287,7 +284,7 @@
name = odp->link_name;
args = strlen(odp->u.func.arg_types) * sizeof(int);
- if (odp->flags & FLAG_REGISTER) name = make_internal_name( odp, "regs" );
+ if (odp->flags & FLAG_REGISTER) name = make_internal_name( odp, spec, "regs" );
switch(odp->type)
{
@@ -325,13 +322,13 @@
*
* Output the functions for stub entry points
*/
-static void output_stub_funcs( FILE *outfile )
+static void output_stub_funcs( FILE *outfile, DLLSPEC *spec )
{
int i;
- for (i = 0; i < nb_entry_points; i++)
+ for (i = 0; i < spec->nb_entry_points; i++)
{
- ORDDEF *odp = EntryPoints[i];
+ ORDDEF *odp = &spec->entry_points[i];
if (odp->type != TYPE_STUB) continue;
fprintf( outfile, "#ifdef __GNUC__\n" );
fprintf( outfile, "static void __wine_unimplemented( const char *func ) __attribute__((noreturn));\n" );
@@ -349,7 +346,7 @@
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] = \"%s\";\n", dll_file_name );
+ fprintf( outfile, " rec.info[0] = \"%s\";\n", spec->file_name );
fprintf( outfile, " rec.info[1] = func;\n" );
fprintf( outfile, "#ifdef __GNUC__\n" );
fprintf( outfile, " rec.addr = __builtin_return_address(1);\n" );
@@ -360,11 +357,11 @@
break;
}
- for (i = 0; i < nb_entry_points; i++)
+ for (i = 0; i < spec->nb_entry_points; i++)
{
- ORDDEF *odp = EntryPoints[i];
+ const ORDDEF *odp = &spec->entry_points[i];
if (odp->type != TYPE_STUB) continue;
- fprintf( outfile, "void %s(void) ", make_internal_name( odp, "stub" ) );
+ fprintf( outfile, "void %s(void) ", make_internal_name( odp, spec, "stub" ) );
if (odp->name)
fprintf( outfile, "{ __wine_unimplemented(\"%s\"); }\n", odp->name );
else if (odp->export_name)
@@ -380,18 +377,18 @@
*
* Output the functions for register entry points
*/
-static void output_register_funcs( FILE *outfile )
+static void output_register_funcs( FILE *outfile, DLLSPEC *spec )
{
const char *name;
int i;
- for (i = 0; i < nb_entry_points; i++)
+ for (i = 0; i < spec->nb_entry_points; i++)
{
- ORDDEF *odp = EntryPoints[i];
+ const ORDDEF *odp = &spec->entry_points[i];
if (odp->type != TYPE_STDCALL && odp->type != TYPE_CDECL) continue;
if (!(odp->flags & FLAG_REGISTER)) continue;
if (odp->flags & FLAG_FORWARD) continue;
- name = make_internal_name( odp, "regs" );
+ name = make_internal_name( odp, spec, "regs" );
fprintf( outfile,
"asm(\".align %d\\n\\t\"\n"
" \"" __ASM_FUNC("%s") "\\n\\t\"\n"
@@ -491,13 +488,12 @@
*
* Build a Win32 C file from a spec file.
*/
-void BuildSpec32File( FILE *outfile )
+void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
{
int exports_size = 0;
- int nr_exports, nr_imports, nr_resources;
- int characteristics, subsystem;
+ int nr_exports, nr_imports;
DWORD page_size;
- char constructor[100];
+ const char *init_func = spec->init_func;
#ifdef HAVE_GETPAGESIZE
page_size = getpagesize();
@@ -513,10 +509,8 @@
# error Cannot get the page size on this platform
#endif
- AssignOrdinals();
- nr_exports = Base <= Limit ? Limit - Base + 1 : 0;
-
- resolve_imports();
+ nr_exports = spec->base <= spec->limit ? spec->limit - spec->base + 1 : 0;
+ resolve_imports( spec );
output_standard_file_header( outfile );
/* Reserve some space for the PE header */
@@ -535,7 +529,12 @@
fprintf( outfile, "}\n" );
fprintf( outfile, "#endif\n" );
+#ifdef __APPLE__
+ fprintf( outfile, "static char _end[4];\n" );
+#else
fprintf( outfile, "extern char _end[];\n" );
+#endif
+
fprintf( outfile, "extern int __wine_spec_data_start[], __wine_spec_exports[];\n\n" );
#ifdef __i386__
@@ -548,7 +547,7 @@
{
/* Output the stub functions */
- output_stub_funcs( outfile );
+ output_stub_funcs( outfile, spec );
fprintf( outfile, "#ifndef __GNUC__\n" );
fprintf( outfile, "static void __asm__dummy(void) {\n" );
@@ -556,11 +555,11 @@
/* Output code for all register functions */
- output_register_funcs( outfile );
+ output_register_funcs( outfile, spec );
/* Output the exports and relay entry points */
- exports_size = output_exports( outfile, nr_exports );
+ exports_size = output_exports( outfile, nr_exports, spec );
fprintf( outfile, "#ifndef __GNUC__\n" );
fprintf( outfile, "}\n" );
@@ -569,86 +568,97 @@
/* Output the DLL imports */
- nr_imports = output_imports( outfile );
+ nr_imports = output_imports( outfile, spec );
/* Output the resources */
- nr_resources = output_resources( outfile );
+ output_resources( outfile, spec );
- /* Output LibMain function */
+ /* Output the entry point function */
+
+ fprintf( outfile, "static int __wine_spec_init_state;\n" );
+ fprintf( outfile, "extern int __wine_main_argc;\n" );
+ fprintf( outfile, "extern char **__wine_main_argv;\n" );
+ fprintf( outfile, "extern char **__wine_main_environ;\n" );
+ fprintf( outfile, "extern unsigned short **__wine_main_wargv;\n" );
+#ifdef __APPLE__
+ fprintf( outfile, "extern _dyld_func_lookup(char *, void *);" );
+ fprintf( outfile, "static void __wine_spec_hidden_init(int argc, char** argv, char** envp)\n" );
+ fprintf( outfile, "{\n" );
+ fprintf( outfile, " void (*init)(void);\n" );
+ fprintf( outfile, " _dyld_func_lookup(\"__dyld_make_delayed_module_initializer_calls\", (unsigned long *)&init);\n" );
+ fprintf( outfile, " init();\n" );
+ fprintf( outfile, "}\n" );
+ fprintf( outfile, "static void __wine_spec_hidden_fini()\n" );
+ fprintf( outfile, "{\n" );
+ fprintf( outfile, " void (*fini)(void);\n" );
+ fprintf( outfile, " _dyld_func_lookup(\"__dyld_mod_term_funcs\", (unsigned long *)&fini);\n" );
+ fprintf( outfile, " fini();\n" );
+ fprintf( outfile, "}\n" );
+ fprintf( outfile, "#define _init __wine_spec_hidden_init\n" );
+ fprintf( outfile, "#define _fini __wine_spec_hidden_fini\n" );
+#else
+ fprintf( outfile, "extern void _init(int, char**, char**);\n" );
+ fprintf( outfile, "extern void _fini();\n" );
+#endif
- characteristics = subsystem = 0;
- switch(SpecMode)
+ if (spec->characteristics & IMAGE_FILE_DLL)
{
- case SPEC_MODE_DLL:
- if (init_func) fprintf( outfile, "extern void %s();\n", init_func );
+ if (init_func)
+ fprintf( outfile, "extern int __stdcall %s( void*, unsigned int, void* );\n\n", init_func );
else
{
- fprintf( outfile, "#ifdef __GNUC__\n" );
- fprintf( outfile, "# ifdef __APPLE__\n" );
- fprintf( outfile, "extern void DllMain() __attribute__((weak_import));\n" );
- fprintf( outfile, "# else\n" );
- fprintf( outfile, "extern void DllMain() __attribute__((weak));\n" );
- fprintf( outfile, "# endif\n" );
- fprintf( outfile, "#else\n" );
- fprintf( outfile, "extern void DllMain();\n" );
- fprintf( outfile, "static void __asm__dummy_dllmain(void)" );
- fprintf( outfile, " { asm(\".weak " __ASM_NAME("DllMain") "\"); }\n" );
- fprintf( outfile, "#endif\n" );
+ declare_weak_function( outfile, "int __stdcall", "DllMain", "void*, unsigned int, void*" );
+ init_func = "DllMain";
}
- characteristics = IMAGE_FILE_DLL;
- break;
- case SPEC_MODE_GUIEXE:
- if (!init_func) init_func = "WinMain";
fprintf( outfile,
- "\ntypedef struct {\n"
- " unsigned int cb;\n"
- " char *lpReserved, *lpDesktop, *lpTitle;\n"
- " unsigned int dwX, dwY, dwXSize, dwYSize;\n"
- " unsigned int dwXCountChars, dwYCountChars, dwFillAttribute, dwFlags;\n"
- " unsigned short wShowWindow, cbReserved2;\n"
- " char *lpReserved2;\n"
- " void *hStdInput, *hStdOutput, *hStdError;\n"
- "} STARTUPINFOA;\n"
- "int _ARGC;\n"
- "char **_ARGV;\n"
- "extern int __stdcall %s(void *,void *,char *,int);\n"
- "extern char * __stdcall GetCommandLineA(void);\n"
- "extern void * __stdcall GetModuleHandleA(char *);\n"
- "extern void __stdcall GetStartupInfoA(STARTUPINFOA *);\n"
- "extern void __stdcall ExitProcess(unsigned int);\n"
- "static void __wine_exe_main(void)\n"
+ "static int __stdcall __wine_dll_main( void *inst, unsigned int reason, void *reserved )\n"
"{\n"
- " extern int __wine_main_argc;\n"
- " extern char **__wine_main_argv;\n"
- " STARTUPINFOA info;\n"
- " char *cmdline = GetCommandLineA();\n"
- " int bcount=0, in_quotes=0;\n"
- " while (*cmdline) {\n"
- " if ((*cmdline=='\\t' || *cmdline==' ') && !in_quotes) break;\n"
- " else if (*cmdline=='\\\\') bcount++;\n"
- " else if (*cmdline=='\\\"') {\n"
- " if ((bcount & 1)==0) in_quotes=!in_quotes;\n"
- " bcount=0;\n"
- " }\n"
- " else bcount=0;\n"
- " cmdline++;\n"
- " }\n"
- " while (*cmdline=='\\t' || *cmdline==' ') cmdline++;\n"
- " GetStartupInfoA( &info );\n"
- " if (!(info.dwFlags & 1)) info.wShowWindow = 1;\n"
- " _ARGC = __wine_main_argc;\n"
- " _ARGV = __wine_main_argv;\n"
- " ExitProcess( %s( GetModuleHandleA(0), 0, cmdline, info.wShowWindow ) );\n"
- "}\n\n", init_func, init_func );
- init_func = "__wine_exe_main";
- subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
+ " int ret;\n"
+ " if (reason == %d && __wine_spec_init_state == 1)\n"
+ " _init( __wine_main_argc, __wine_main_argv, __wine_main_environ );\n"
+ " ret = %s ? %s( inst, reason, reserved ) : 1;\n"
+ " if (reason == %d && __wine_spec_init_state == 1) _fini();\n"
+ " return ret;\n"
+ "}\n",
+ DLL_PROCESS_ATTACH, init_func, init_func, DLL_PROCESS_DETACH );
+ init_func = "__wine_dll_main";
+ }
+ else switch(spec->subsystem)
+ {
+ case IMAGE_SUBSYSTEM_NATIVE:
+ if (init_func)
+ fprintf( outfile, "extern int __stdcall %s( void*, void* );\n\n", init_func );
+ else
+ {
+ declare_weak_function( outfile, "int __stdcall", "DriverEntry", "void*, void*");
+ init_func = "DriverEntry";
+ }
+ fprintf( outfile,
+ "static int __stdcall __wine_driver_entry( void *obj, void *path )\n"
+ "{\n"
+ " int ret;\n"
+ " if (__wine_spec_init_state == 1)\n"
+ " _init( __wine_main_argc, __wine_main_argv, __wine_main_environ );\n"
+ " ret = %s ? %s( obj, path ) : 0;\n"
+ " if (__wine_spec_init_state == 1) _fini();\n"
+ " return ret;\n"
+ "}\n",
+ init_func, init_func );
+ init_func = "__wine_driver_entry";
break;
- case SPEC_MODE_GUIEXE_UNICODE:
- if (!init_func) init_func = "WinMain";
+ case IMAGE_SUBSYSTEM_WINDOWS_GUI:
+ case IMAGE_SUBSYSTEM_WINDOWS_CUI:
+ if (init_func)
+ fprintf( outfile, "extern int %s( int argc, char *argv[] );\n", init_func );
+ else
+ {
+ declare_weak_function( outfile, "int", "main", "int argc, char *argv[]" );
+ declare_weak_function( outfile, "int", "wmain", "int argc, unsigned short *argv[]" );
+ declare_weak_function( outfile, "int __stdcall", "WinMain", "void *,void *,char *,int" );
+ }
fprintf( outfile,
- "\ntypedef unsigned short WCHAR;\n"
- "typedef struct {\n"
+ "\ntypedef struct {\n"
" unsigned int cb;\n"
" char *lpReserved, *lpDesktop, *lpTitle;\n"
" unsigned int dwX, dwY, dwXSize, dwYSize;\n"
@@ -657,76 +667,46 @@
" char *lpReserved2;\n"
" void *hStdInput, *hStdOutput, *hStdError;\n"
"} STARTUPINFOA;\n"
- "int _ARGC;\n"
- "WCHAR **_ARGV;\n"
- "extern int __stdcall %s(void *,void *,char *,int);\n"
"extern char * __stdcall GetCommandLineA(void);\n"
"extern void * __stdcall GetModuleHandleA(char *);\n"
"extern void __stdcall GetStartupInfoA(STARTUPINFOA *);\n"
"extern void __stdcall ExitProcess(unsigned int);\n"
"static void __wine_exe_main(void)\n"
"{\n"
- " extern int __wine_main_argc;\n"
- " extern WCHAR **__wine_main_wargv;\n"
- " STARTUPINFOA info;\n"
- " char *cmdline = GetCommandLineA();\n"
- " int bcount=0, in_quotes=0;\n"
- " while (*cmdline) {\n"
- " if ((*cmdline=='\\t' || *cmdline==' ') && !in_quotes) break;\n"
- " else if (*cmdline=='\\\\') bcount++;\n"
- " else if (*cmdline=='\\\"') {\n"
- " if ((bcount & 1)==0) in_quotes=!in_quotes;\n"
- " bcount=0;\n"
- " }\n"
- " else bcount=0;\n"
- " cmdline++;\n"
- " }\n"
- " while (*cmdline=='\\t' || *cmdline==' ') cmdline++;\n"
- " GetStartupInfoA( &info );\n"
- " if (!(info.dwFlags & 1)) info.wShowWindow = 1;\n"
- " _ARGC = __wine_main_argc;\n"
- " _ARGV = __wine_main_wargv;\n"
- " ExitProcess( %s( GetModuleHandleA(0), 0, cmdline, info.wShowWindow ) );\n"
- "}\n\n", init_func, init_func );
- init_func = "__wine_exe_main";
- subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
- break;
- case SPEC_MODE_CUIEXE:
- if (!init_func) init_func = "main";
- fprintf( outfile,
- "\nint _ARGC;\n"
- "char **_ARGV;\n"
- "extern void __stdcall ExitProcess(int);\n"
- "static void __wine_exe_main(void)\n"
- "{\n"
- " extern int %s( int argc, char *argv[] );\n"
- " extern int __wine_main_argc;\n"
- " extern char **__wine_main_argv;\n"
- " _ARGC = __wine_main_argc;\n"
- " _ARGV = __wine_main_argv;\n"
- " ExitProcess( %s( _ARGC, _ARGV ) );\n"
- "}\n\n", init_func, init_func );
- init_func = "__wine_exe_main";
- subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI;
- break;
- case SPEC_MODE_CUIEXE_UNICODE:
- if (!init_func) init_func = "wmain";
+ " int ret;\n"
+ " if (__wine_spec_init_state == 1)\n"
+ " _init( __wine_main_argc, __wine_main_argv, __wine_main_environ );\n" );
+ if (init_func)
+ fprintf( outfile,
+ " ret = %s( __wine_main_argc, __wine_main_argv );\n", init_func );
+ else
+ fprintf( outfile,
+ " if (WinMain) {\n"
+ " STARTUPINFOA info;\n"
+ " char *cmdline = GetCommandLineA();\n"
+ " int bcount=0, in_quotes=0;\n"
+ " while (*cmdline) {\n"
+ " if ((*cmdline=='\\t' || *cmdline==' ') && !in_quotes) break;\n"
+ " else if (*cmdline=='\\\\') bcount++;\n"
+ " else if (*cmdline=='\\\"') {\n"
+ " if ((bcount & 1)==0) in_quotes=!in_quotes;\n"
+ " bcount=0;\n"
+ " }\n"
+ " else bcount=0;\n"
+ " cmdline++;\n"
+ " }\n"
+ " while (*cmdline=='\\t' || *cmdline==' ') cmdline++;\n"
+ " GetStartupInfoA( &info );\n"
+ " if (!(info.dwFlags & 1)) info.wShowWindow = 1;\n"
+ " ret = WinMain( GetModuleHandleA(0), 0, cmdline, info.wShowWindow );\n"
+ " }\n"
+ " else if (wmain) ret = wmain( __wine_main_argc, __wine_main_wargv );\n"
+ " else ret = main( __wine_main_argc, __wine_main_argv );\n" );
fprintf( outfile,
- "\ntypedef unsigned short WCHAR;\n"
- "int _ARGC;\n"
- "WCHAR **_ARGV;\n"
- "extern void __stdcall ExitProcess(int);\n"
- "static void __wine_exe_main(void)\n"
- "{\n"
- " extern int %s( int argc, WCHAR *argv[] );\n"
- " extern int __wine_main_argc;\n"
- " extern WCHAR **__wine_main_wargv;\n"
- " _ARGC = __wine_main_argc;\n"
- " _ARGV = __wine_main_wargv;\n"
- " ExitProcess( %s( _ARGC, _ARGV ) );\n"
- "}\n\n", init_func, init_func );
+ " if (__wine_spec_init_state == 1) _fini();\n"
+ " ExitProcess( ret );\n"
+ "}\n\n" );
init_func = "__wine_exe_main";
- subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI;
break;
}
@@ -788,29 +768,30 @@
#endif
fprintf( outfile, " 0, 0, 0, 0,\n" );
fprintf( outfile, " sizeof(nt_header.OptionalHeader),\n" ); /* SizeOfOptionalHeader */
- fprintf( outfile, " 0x%04x },\n", characteristics ); /* Characteristics */
+ fprintf( outfile, " 0x%04x },\n", spec->characteristics ); /* Characteristics */
fprintf( outfile, " { 0x%04x,\n", IMAGE_NT_OPTIONAL_HDR_MAGIC ); /* Magic */
fprintf( outfile, " 0, 0,\n" ); /* Major/MinorLinkerVersion */
fprintf( outfile, " 0, 0, 0,\n" ); /* SizeOfCode/Data */
- fprintf( outfile, " %s,\n", init_func ? init_func : "DllMain" ); /* AddressOfEntryPoint */
+ fprintf( outfile, " %s,\n", init_func ); /* AddressOfEntryPoint */
fprintf( outfile, " 0, __wine_spec_data_start,\n" ); /* BaseOfCode/Data */
fprintf( outfile, " __wine_spec_pe_header,\n" ); /* ImageBase */
fprintf( outfile, " %ld,\n", page_size ); /* SectionAlignment */
fprintf( outfile, " %ld,\n", page_size ); /* FileAlignment */
fprintf( outfile, " 1, 0,\n" ); /* Major/MinorOperatingSystemVersion */
fprintf( outfile, " 0, 0,\n" ); /* Major/MinorImageVersion */
- fprintf( outfile, " 4, 0,\n" ); /* Major/MinorSubsystemVersion */
+ fprintf( outfile, " %d,\n", spec->subsystem_major ); /* MajorSubsystemVersion */
+ fprintf( outfile, " %d,\n", spec->subsystem_minor ); /* MinorSubsystemVersion */
fprintf( outfile, " 0,\n" ); /* Win32VersionValue */
fprintf( outfile, " _end,\n" ); /* SizeOfImage */
fprintf( outfile, " %ld,\n", page_size ); /* SizeOfHeaders */
fprintf( outfile, " 0,\n" ); /* CheckSum */
- fprintf( outfile, " 0x%04x,\n", subsystem ); /* Subsystem */
+ fprintf( outfile, " 0x%04x,\n", spec->subsystem );/* Subsystem */
fprintf( outfile, " 0,\n" ); /* DllCharacteristics */
fprintf( outfile, " %d, %ld,\n", /* SizeOfStackReserve/Commit */
- (stack_size ? stack_size : 1024) * 1024, page_size );
+ (spec->stack_size ? spec->stack_size : 1024) * 1024, page_size );
fprintf( outfile, " %d, %ld,\n", /* SizeOfHeapReserve/Commit */
- (DLLHeapSize ? DLLHeapSize : 1024) * 1024, page_size );
+ (spec->heap_size ? spec->heap_size : 1024) * 1024, page_size );
fprintf( outfile, " 0,\n" ); /* LoaderFlags */
fprintf( outfile, " %d,\n", IMAGE_NUMBEROF_DIRECTORY_ENTRIES ); /* NumberOfRvaAndSizes */
fprintf( outfile, " {\n" );
@@ -819,22 +800,29 @@
fprintf( outfile, " { %s, %s },\n", /* IMAGE_DIRECTORY_ENTRY_IMPORT */
nr_imports ? "&imports" : "0", nr_imports ? "sizeof(imports)" : "0" );
fprintf( outfile, " { %s, %s },\n", /* IMAGE_DIRECTORY_ENTRY_RESOURCE */
- nr_resources ? "&resources" : "0", nr_resources ? "sizeof(resources)" : "0" );
+ spec->nb_resources ? "&resources" : "0",
+ spec->nb_resources ? "sizeof(resources)" : "0" );
fprintf( outfile, " }\n }\n};\n\n" );
/* Output the DLL constructor */
- sprintf( constructor, "__wine_spec_%s_init", make_c_identifier(dll_file_name) );
- output_dll_init( outfile, constructor, NULL );
-
fprintf( outfile,
- "void %s(void)\n"
+ "void __wine_spec_init(void)\n"
"{\n"
" extern void __wine_dll_register( const struct image_nt_headers *, const char * );\n"
- " extern void *__wine_dbg_register( char * const *, int );\n"
+ " __wine_spec_init_state = 1;\n"
" __wine_dll_register( &nt_header, \"%s\" );\n"
- "}\n",
- constructor, dll_file_name );
+ "}\n\n",
+ spec->file_name );
+
+ output_dll_init( outfile, "__wine_spec_init_ctor", NULL );
+ fprintf( outfile,
+ "void __wine_spec_init_ctor(void)\n"
+ "{\n"
+ " if (__wine_spec_init_state) return;\n"
+ " __wine_spec_init();\n"
+ " __wine_spec_init_state = 2;\n"
+ "}\n" );
}
@@ -843,25 +831,23 @@
*
* Build a Win32 def file from a spec file.
*/
-void BuildDef32File(FILE *outfile)
+void BuildDef32File( FILE *outfile, DLLSPEC *spec )
{
const char *name;
int i;
- AssignOrdinals();
-
fprintf(outfile, "; File generated automatically from %s; do not edit!\n\n",
input_file_name );
- fprintf(outfile, "LIBRARY %s\n\n", dll_file_name);
+ fprintf(outfile, "LIBRARY %s\n\n", spec->file_name);
fprintf(outfile, "EXPORTS\n");
/* Output the exports and relay entry points */
- for(i = 0; i < nb_entry_points; i++)
+ for(i = 0; i < spec->nb_entry_points; i++)
{
- ORDDEF *odp = EntryPoints[i];
+ const ORDDEF *odp = &spec->entry_points[i];
int is_data = 0;
if (!odp) continue;
@@ -906,7 +892,7 @@
fprintf( outfile, " @%d", odp->ordinal );
if (!odp->name) fprintf( outfile, " NONAME" );
if (is_data) fprintf( outfile, " DATA" );
-#if !defined(__REACTOS__)
+#if 0
/* MinGW binutils cannot handle this correctly */
if (odp->flags & FLAG_PRIVATE) fprintf( outfile, " PRIVATE" );
#endif
@@ -951,8 +937,8 @@
fprintf( outfile,
"#ifdef __GNUC__\n"
- "static void __wine_dbg_%s_init(void) __attribute__((constructor));\n"
- "static void __wine_dbg_%s_fini(void) __attribute__((destructor));\n"
+ "void __wine_dbg_%s_init(void) __attribute__((constructor));\n"
+ "void __wine_dbg_%s_fini(void) __attribute__((destructor));\n"
"#else\n"
"static void __asm__dummy_dll_init(void) {\n",
prefix, prefix );
@@ -972,29 +958,34 @@
fprintf( outfile, " \"\\tnop\\n\"\n" );
fprintf( outfile, " \"\\t.section\t\\\".text\\\"\\n\");\n" );
#elif defined(__powerpc__)
+# ifdef __APPLE__
+ fprintf( outfile, "asm(\"\\t.mod_init_func\\n\"\n" );
+ fprintf( outfile, " \"\\t.align 2\\n\"\n" );
+ fprintf( outfile, " \"\\t.long " __ASM_NAME("__wine_dbg_%s_init") "\\n\"\n", prefix );
+ fprintf( outfile, " \"\\t.text\\n\");\n" );
+ fprintf( outfile, "asm(\"\\t.mod_term_func\\n\"\n" );
+ fprintf( outfile, " \"\\t.align 2\\n\"\n" );
+ fprintf( outfile, " \"\\t.long " __ASM_NAME("__wine_dbg_%s_fini") "\\n\"\n", prefix );
+ fprintf( outfile, " \"\\t.text\\n\");\n" );
+# else
fprintf( outfile, "asm(\"\\t.section\\t\\\".init\\\" ,\\\"ax\\\"\\n\"\n" );
fprintf( outfile, " \"\\tbl " __ASM_NAME("__wine_dbg_%s_init") "\\n\"\n", prefix );
fprintf( outfile, " \"\\t.section\\t\\\".fini\\\" ,\\\"ax\\\"\\n\"\n" );
fprintf( outfile, " \"\\tbl " __ASM_NAME("__wine_dbg_%s_fini") "\\n\"\n", prefix );
fprintf( outfile, " \"\\t.text\\n\");\n" );
+# endif
#else
#error You need to define the DLL constructor for your architecture
#endif
- fprintf( outfile, "}\n#endif /* defined(__GNUC__) */\n" );
+ fprintf( outfile, "}\n#endif /* defined(__GNUC__) */\n\n" );
fprintf( outfile,
- "\n#ifdef __GNUC__\n"
- "static\n"
- "#endif\n"
"void __wine_dbg_%s_init(void)\n"
"{\n"
" extern void *__wine_dbg_register( char * const *, int );\n"
- " debug_registration = __wine_dbg_register( debug_channels, %d );\n"
- "}\n", prefix, nr_debug );
+ " if (!debug_registration) debug_registration = __wine_dbg_register( debug_channels, %d );\n"
+ "}\n\n", prefix, nr_debug );
fprintf( outfile,
- "\n#ifdef __GNUC__\n"
- "static\n"
- "#endif\n"
"void __wine_dbg_%s_fini(void)\n"
"{\n"
" extern void __wine_dbg_unregister( void* );\n"
reactos/tools/winebuild
diff -u -r1.2 -r1.3
--- utils.c 5 Jan 2004 19:49:59 -0000 1.2
+++ utils.c 23 Sep 2004 20:27:30 -0000 1.3
@@ -86,6 +86,7 @@
fprintf( stderr, "%d:", current_line );
fputc( ' ', stderr );
}
+ else fprintf( stderr, "winebuild: " );
vfprintf( stderr, msg, valist );
va_end( valist );
exit(1);
@@ -214,6 +215,86 @@
/*******************************************************************
+ * remove_stdcall_decoration
+ *
+ * Remove a possible @xx suffix from a function name.
+ * Return the numerical value of the suffix, or -1 if none.
+ */
+int remove_stdcall_decoration( char *name )
+{
+ char *p, *end = strrchr( name, '@' );
+ if (!end || !end[1] || end == name) return -1;
+ /* make sure all the rest is digits */
+ for (p = end + 1; *p; p++) if (!isdigit(*p)) return -1;
+ *end = 0;
+ return atoi( end + 1 );
+}
+
+
+/*******************************************************************
+ * alloc_dll_spec
+ *
+ * Create a new dll spec file descriptor
+ */
+DLLSPEC *alloc_dll_spec(void)
+{
+ DLLSPEC *spec;
+
+ spec = xmalloc( sizeof(*spec) );
+ spec->file_name = NULL;
+ spec->dll_name = NULL;
+ spec->owner_name = NULL;
+ spec->init_func = NULL;
+ spec->type = SPEC_WIN32;
+ spec->base = MAX_ORDINALS;
+ spec->limit = 0;
+ spec->stack_size = 0;
+ spec->heap_size = 0;
+ spec->nb_entry_points = 0;
+ spec->alloc_entry_points = 0;
+ spec->nb_names = 0;
+ spec->nb_resources = 0;
+ spec->characteristics = 0;
+ spec->subsystem = 0;
+ spec->subsystem_major = 4;
+ spec->subsystem_minor = 0;
+ spec->entry_points = NULL;
+ spec->names = NULL;
+ spec->ordinals = NULL;
+ spec->resources = NULL;
+ return spec;
+}
+
+
+/*******************************************************************
+ * free_dll_spec
+ *
+ * Free dll spec file descriptor
+ */
+void free_dll_spec( DLLSPEC *spec )
+{
+ int i;
+
+ for (i = 0; i < spec->nb_entry_points; i++)
+ {
+ ORDDEF *odp = &spec->entry_points[i];
+ free( odp->name );
+ free( odp->export_name );
+ free( odp->link_name );
+ }
+ free( spec->file_name );
+ free( spec->dll_name );
+ free( spec->owner_name );
+ free( spec->init_func );
+ free( spec->entry_points );
+ free( spec->names );
+ free( spec->ordinals );
+ free( spec->resources );
+ free( spec );
+}
+
+
+/*******************************************************************
* make_c_identifier
*
* Map a string to a valid C identifier.
reactos/tools/winebuild
diff -u -r1.1 -r1.2
--- winebuild.man.in 9 Dec 2003 18:44:25 -0000 1.1
+++ winebuild.man.in 23 Sep 2004 20:27:30 -0000 1.2
@@ -19,10 +19,11 @@
You have to specify exactly one of the following options, depending on
what you want winebuild to generate.
.TP
-.BI \--spec=\ file.spec
-Build a C file from a spec file (see \fBSPEC FILE SYNTAX\fR for
-details). The resulting C file must be compiled and linked to the
-other object files to build a working Wine dll.
+.BI \--dll= filename
+Build a C file from a .spec file (see \fBSPEC FILE SYNTAX\fR for
+details), or from a standard Windows .def file. The resulting C file
+must be compiled and linked to the other object files to build a
+working Wine dll.
.br
In that mode, the
.I input files
@@ -32,16 +33,16 @@
to get the list of all undefined symbols that need to be imported from
other dlls.
.TP
-.BI \--exe=\ name
+.BI \--exe= name
Build a C file for the named executable. This is basically the same as
-the --spec mode except that it doesn't require a .spec file as input,
+the --dll mode except that it doesn't require a .spec file as input,
since an executable doesn't export functions. The resulting C file
must be compiled and linked to the other object files to build a
working Wine executable, and all the other object files must be listed
as
.I input files.
.TP
-.BI \--def=\ file.spec
+.BI \--def= file.spec
Build a .def file from a spec file. This is used when building dlls
with a PE (Win32) compiler.
.TP
@@ -75,11 +76,12 @@
is
.B DllMain
for dlls, and
-.B main
-or
.B WinMain
-for CUI or GUI executables respectively. This is only valid for Win32
-modules.
+for executables (if
+.B WinMain
+is not defined, the standard C
+.B main
+is used instead). This is only valid for Win32 modules.
.TP
.BI \-f\ flags
Ignored for compatibility with the C compiler.
@@ -130,29 +132,7 @@
.BI \-M,\ --main-module= module
Specify that we are building a 16-bit dll, that will ultimately be
linked together with the 32-bit dll specified in \fImodule\fR. Only
-meaningful in \fB--spec\fR mode.
-.TP
-.BI \-m,\ --exe-mode= mode
-Set the executable mode, which can be one of the following:
-.br
-.B cui
-for a command line ASCII executable,
-.br
-.B gui
-for a graphical ASCII executable,
-.br
-.B cuiw
-for a command line Unicode executable,
-.br
-.B guiw
-for a graphical Unicode executable.
-.br
-A command line executable entry point is a normal C \fBmain\fR
-function. A graphical executable has a \fBWinMain\fR entry point
-instead. The ASCII/Unicode distinction applies to the strings that are
-passed to the entry point.
-.br
-This option is only meaningful in \fB--exe\fR mode.
+meaningful in \fB--dll\fR mode.
.TP
.BI \-N,\ --dll-name= dllname
Set the internal name of the module. It is only used in Win16
@@ -176,6 +156,26 @@
.B \-r
option will also work for Win32 files).
.TP
+.BI --subsystem= subsystem[:major[.minor]]
+Set the subsystem of the executable, which can be one of the following:
+.br
+.B console
+for a command line executable,
+.br
+.B windows
+for a graphical executable,
+.br
+.B native
+for a native-mode dll.
+.br
+The entry point of a command line executable is a normal C \fBmain\fR
+function. A \fBwmain\fR function can be used instead if you need the
+argument array to use Unicode strings. A graphical executable has a
+\fBWinMain\fR entry point.
+.br
+Optionally a major and minor subsystem version can also be specified;
+the default subsystem version is 4.0.
+.TP
.B \--version
Display the program version and exit.
.TP
@@ -237,9 +237,6 @@
.B -register
The function uses CPU register to pass arguments.
.TP
-.B -interrupt
-The function is an interrupt handler routine.
-.TP
.B -private
The function cannot be imported from other dlls, it can only be
accessed through GetProcAddress.
reactos/tools/winebuild
diff -u -r1.1 -r1.2
--- winglue.h 4 Jan 2004 15:50:41 -0000 1.1
+++ winglue.h 23 Sep 2004 20:27:30 -0000 1.2
@@ -9,7 +9,11 @@
#define LOBYTE(w) ((BYTE)(w))
#define HIBYTE(w) ((BYTE)(((WORD)(w)>>8)&0xFF))
+#define DLL_PROCESS_ATTACH 1
+#define DLL_PROCESS_DETACH 0
+
#define IMAGE_FILE_DLL 8192
+#define IMAGE_SUBSYSTEM_NATIVE 1
#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2
#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
CVSspam 0.2.8