From 26c115dc6ab9404e4e968af892c9c188ce13dcac Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Mon, 17 Dec 2007 20:17:36 +0000 Subject: [PATCH] Sync winebuild (keeping ReactOS-specific changes). 3 days ago Michael Stefaniuc winebuild: Remove duplicate declaration of variable ... 6 days ago Alexandre Julliard winebuild: Don't set the IMAGE_FILE_DLL flag on native ... 10 days ago Alexandre Julliard winebuild: Also optimize out imports that are only ... 10 days ago Alexandre Julliard winebuild: Improved checks for missing forward entry ... 10 days ago Alexandre Julliard winebuild: Print a warning when failing to import a ... 2007-11-07 Alexandre Julliard winebuild: Add a few nops to stub entry points to make ... 2007-10-26 Alexandre Julliard winebuild: Add a -ordinal flag for entry points that ... 2007-09-10 Dmitry Timoshkov winebuild: Add IMAGE_FILE_32BIT_MACHINE flag for a ... 2007-07-19 Alexandre Julliard ntdll: Move private data to make room in the TEB for ... 2007-05-29 Dmitry Timoshkov winebuild: Mark builtin DLLs as IMAGE_FILE_LARGE_ADDRES ... 2007-05-24 Alexandre Julliard winebuild: Set the IMAGE_FILE_EXECUTABLE_IMAGE flag ... 2007-05-21 Dmitry Timoshkov winebuild: Fix compilation warnings in 64-bit mode. 2007-04-25 Rob Shearman winebuild: Refer to strings used in generated stubs ... 2007-04-09 Dmitry Timoshkov winebuild: Check if a given forward does exist in one ... 2007-03-17 Andrew Talbot winebuild: Replace inline static with static inline. 2007-03-05 Joris Huizer winebuild: sign-compare fixes. 2006-12-27 Alexandre Julliard make_makefiles: Generate the top-level .gitignore file. 2006-12-07 Alexandre Julliard winebuild: Added --nxcompat option, and mark all module ... 2006-12-04 Alexandre Julliard winebuild: Check for illegal characters in entry point ... 2006-10-12 Andrew Talbot winebuild: Cast-qual warning fix. 2006-09-14 Alexandre Julliard makefiles: Generate the dependencies line to avoid ... 2006-08-23 Andrew Talbot winebuild: Cast-qual warnings fix. 2006-08-11 Alexandre Julliard winebuild: Added output() function to properly deal ... 2006-08-07 Alexandre Julliard makefiles: Use make dependencies to create installation ... 2006-07-11 Ge van Geldorp winebuild: Save registers which might contain parameter ... 2006-07-11 Ge van Geldorp winebuild: Reserve enough space for null function pointer. 2006-07-10 Alexandre Julliard Take advantage of the recursive nature of .gitignore ... 2006-06-19 Alexandre Julliard winebuild: Get rid of the data16 prefix, it shouldn't ... 2006-06-13 Alexandre Julliard winebuild: Fix a few printf format warnings by casting ... 2006-05-23 Jonathan Ernst Update the address of the Free Software Foundation. 2006-04-18 Alexandre Julliard winebuild: Disable linking to external symbols by default. 2006-04-18 Alexandre Julliard winebuild: Fixed index in module table for delayed ... 2006-04-05 Alexandre Julliard winebuild: Remove a no longer necessary movzwl instruction. 2006-02-16 Robert Shearman winebuild: Correction for manpage. 2006-02-14 Mike Frysinger Add support for 'make install DESTDIR'. 2006-01-24 Alexandre Julliard winebuild: Get rid of the default ignored symbols list. 2006-01-23 Alexandre Julliard winebuild: Always import atof, the MS version is different. 2006-01-21 Marcus Meissner winebuild: Output a .note.GNU-stack section to allow ... 2006-01-20 Alexandre Julliard winebuild: Moved offset definitions to relay.c since ... 2006-01-20 Alexandre Julliard ntdll: Move the %gs register to the ntdll_thread_regs ... svn path=/trunk/; revision=31292 --- reactos/media/doc/README.WINE | 4 +- reactos/tools/winebuild/Makefile.in | 13 +- reactos/tools/winebuild/build.h | 68 +- reactos/tools/winebuild/import.c | 723 ++++++++++---------- reactos/tools/winebuild/main.c | 76 ++- reactos/tools/winebuild/parser.c | 42 +- reactos/tools/winebuild/relay.c | 810 ++++++++++++----------- reactos/tools/winebuild/res16.c | 67 +- reactos/tools/winebuild/res32.c | 70 +- reactos/tools/winebuild/spec16.c | 423 ++++++------ reactos/tools/winebuild/spec32.c | 415 ++++++------ reactos/tools/winebuild/utils.c | 68 +- reactos/tools/winebuild/winebuild.man.in | 27 +- reactos/tools/winebuild/winglue.h | 126 +--- 14 files changed, 1455 insertions(+), 1477 deletions(-) diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index c6f2757d2be..f4461b17437 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -24,8 +24,8 @@ The following build tools are shared with Wine. reactos/tools/unicode # Synced to Wine-0_9_5 reactos/tools/wpp # Synced to Wine-0_9_5 reactos/tools/bin2res # Resource to binary converter -reactos/tools/winebuild # Synced to Wine-0_9_5 -reactos/tools/wmc # Synced to Wine-0_9_5 +reactos/tools/winebuild # Synced to Wine-20071217 +reactos/tools/wmc # Synced to Wine-20071201 reactos/tools/wrc # Synced to Wine-0_9_5 reactos/tools/widl # Synced to Wine-20060729 diff --git a/reactos/tools/winebuild/Makefile.in b/reactos/tools/winebuild/Makefile.in index 62d7f6bd794..77f36917113 100644 --- a/reactos/tools/winebuild/Makefile.in +++ b/reactos/tools/winebuild/Makefile.in @@ -19,6 +19,8 @@ C_SRCS = \ spec32.c \ utils.c +INSTALLDIRS = $(DESTDIR)$(bindir) $(DESTDIR)$(mandir)/man$(prog_manext) + all: $(PROGRAMS) $(MANPAGES) @MAKE_RULES@ @@ -26,12 +28,11 @@ all: $(PROGRAMS) $(MANPAGES) winebuild$(EXEEXT): $(OBJS) $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBPORT) $(LDFLAGS) -install:: $(PROGRAMS) $(MANPAGES) - $(MKINSTALLDIRS) $(bindir) $(mandir)/man$(prog_manext) - $(INSTALL_PROGRAM) winebuild$(EXEEXT) $(bindir)/winebuild$(EXEEXT) - $(INSTALL_DATA) winebuild.man $(mandir)/man$(prog_manext)/winebuild.$(prog_manext) +install:: $(PROGRAMS) $(MANPAGES) $(INSTALLDIRS) + $(INSTALL_PROGRAM) winebuild$(EXEEXT) $(DESTDIR)$(bindir)/winebuild$(EXEEXT) + $(INSTALL_DATA) winebuild.man $(DESTDIR)$(mandir)/man$(prog_manext)/winebuild.$(prog_manext) uninstall:: - $(RM) $(bindir)/winebuild$(EXEEXT) $(mandir)/man$(prog_manext)/winebuild.$(prog_manext) + $(RM) $(DESTDIR)$(bindir)/winebuild$(EXEEXT) $(DESTDIR)$(mandir)/man$(prog_manext)/winebuild.$(prog_manext) -### Dependencies: +@DEPENDENCIES@ # everything below this line is overwritten by make depend diff --git a/reactos/tools/winebuild/build.h b/reactos/tools/winebuild/build.h index c5c646bf2a0..af5c2caed69 100644 --- a/reactos/tools/winebuild/build.h +++ b/reactos/tools/winebuild/build.h @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __WINE_BUILD_H @@ -31,6 +31,8 @@ #include #include +#include "winglue.h" + typedef enum { TYPE_VARIABLE, /* variable */ @@ -85,6 +87,7 @@ typedef struct typedef struct { + char *src_name; /* file name of the source spec file */ char *file_name; /* file name of the dll */ char *dll_name; /* internal name of the dll */ char *init_func; /* initialization routine */ @@ -98,6 +101,7 @@ typedef struct int nb_names; /* number of entry points with names */ unsigned int nb_resources; /* number of resources */ int characteristics; /* characteristics for the PE header */ + int dll_characteristics;/* DLL characteristics for the PE header */ int subsystem; /* subsystem id */ int subsystem_major; /* subsystem version major number */ int subsystem_minor; /* subsystem version minor number */ @@ -114,7 +118,7 @@ enum target_cpu enum target_platform { - PLATFORM_UNSPECIFIED, PLATFORM_APPLE, PLATFORM_SVR4, PLATFORM_WINDOWS + PLATFORM_UNSPECIFIED, PLATFORM_APPLE, PLATFORM_WINDOWS }; extern enum target_cpu target_cpu; @@ -122,31 +126,16 @@ extern enum target_platform target_platform; /* 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 */ +#define FLAG_NONAME 0x02 /* don't export function by name */ #define FLAG_RET16 0x04 /* function returns a 16-bit value */ #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_PRIVATE 0x40 /* function is private (cannot be imported) */ +#define FLAG_ORDINAL 0x80 /* function should be imported by ordinal */ -#define FLAG_FORWARD 0x80 /* function is a forwarded name */ -#define FLAG_EXT_LINK 0x100 /* function links to an external symbol */ - - /* Offset of a structure field relative to the start of the struct */ -#define STRUCTOFFSET(type,field) ((int)&((type *)0)->field) - - /* Offset of register relative to the start of the CONTEXT struct */ -#define CONTEXTOFFSET(reg) STRUCTOFFSET(CONTEXT86,reg) - - /* Offset of register relative to the start of the STACK16FRAME struct */ -#define STACK16OFFSET(reg) STRUCTOFFSET(STACK16FRAME,reg) - - /* Offset of register relative to the start of the STACK32FRAME struct */ -#define STACK32OFFSET(reg) STRUCTOFFSET(STACK32FRAME,reg) - - /* Offset of the stack pointer relative to %fs:(0) */ -#define STACKOFFSET (STRUCTOFFSET(TEB,WOW32Reserved)) - +#define FLAG_FORWARD 0x100 /* function is a forwarded name */ +#define FLAG_EXT_LINK 0x200 /* function links to an external symbol */ #define MAX_ORDINALS 65535 @@ -169,11 +158,13 @@ extern void error( const char *msg, ... ) __attribute__ ((__format__ (__printf__, 1, 2))); extern void warning( const char *msg, ... ) __attribute__ ((__format__ (__printf__, 1, 2))); +extern int output( const char *format, ... ) + __attribute__ ((__format__ (__printf__, 1, 2))); extern char *get_temp_file_name( const char *prefix, const char *suffix ); -extern void output_standard_file_header( FILE *outfile ); +extern void output_standard_file_header(void); extern FILE *open_input_file( const char *srcdir, const char *name ); extern void close_input_file( FILE *file ); -extern void dump_bytes( FILE *outfile, const void *buffer, unsigned int size ); +extern void dump_bytes( const void *buffer, unsigned int size ); extern int remove_stdcall_decoration( char *name ); extern void assemble_file( const char *src_file, const char *obj_file ); extern DLLSPEC *alloc_dll_spec(void); @@ -191,7 +182,8 @@ extern const char *get_asm_string_keyword(void); extern const char *get_asm_short_keyword(void); extern const char *get_asm_rodata_section(void); extern const char *get_asm_string_section(void); -extern void output_function_size( FILE *outfile, const char *name ); +extern void output_function_size( const char *name ); +extern void output_gnu_stack_note(void); extern void add_import_dll( const char *name, const char *filename ); extern void add_delayed_import( const char *name ); @@ -201,27 +193,25 @@ extern void read_undef_symbols( DLLSPEC *spec, char **argv ); extern int resolve_imports( DLLSPEC *spec ); extern int has_imports(void); extern int has_relays( DLLSPEC *spec ); -extern void output_get_pc_thunk( FILE *outfile ); -extern void output_stubs( FILE *outfile, DLLSPEC *spec ); -extern void output_imports( FILE *outfile, DLLSPEC *spec ); +extern void output_get_pc_thunk(void); +extern void output_stubs( DLLSPEC *spec ); +extern void output_imports( DLLSPEC *spec ); extern int load_res32_file( const char *name, DLLSPEC *spec ); -extern void output_resources( FILE *outfile, DLLSPEC *spec ); +extern void output_resources( DLLSPEC *spec ); extern void load_res16_file( const char *name, DLLSPEC *spec ); -extern void output_res16_data( FILE *outfile, DLLSPEC *spec ); -extern void output_res16_directory( FILE *outfile, DLLSPEC *spec, const char *header_name ); +extern void output_res16_data( DLLSPEC *spec ); +extern void output_res16_directory( DLLSPEC *spec, const char *header_name ); -extern void BuildRelays16( FILE *outfile ); -extern void BuildRelays32( 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 BuildPedllFile( FILE *outfile, DLLSPEC *spec ); +extern void BuildRelays16(void); +extern void BuildRelays32(void); +extern void BuildSpec16File( DLLSPEC *spec ); +extern void BuildSpec32File( DLLSPEC *spec ); +extern void BuildDef32File( DLLSPEC *spec ); +extern void BuildPedllFile( DLLSPEC *spec ); extern int parse_spec_file( FILE *file, DLLSPEC *spec ); extern int parse_def_file( FILE *file, DLLSPEC *spec ); -extern int mkstemps(char *template, int suffix_len); - /* global variables */ extern int current_line; @@ -232,9 +222,11 @@ extern int display_warnings; extern int kill_at; extern int verbose; extern int save_temps; +extern int link_ext_symbols; extern char *input_file_name; extern char *spec_file_name; +extern FILE *output_file; extern const char *output_file_name; extern char **lib_path; diff --git a/reactos/tools/winebuild/import.c b/reactos/tools/winebuild/import.c index a51eb30cbce..5b62512a53b 100644 --- a/reactos/tools/winebuild/import.c +++ b/reactos/tools/winebuild/import.c @@ -16,10 +16,11 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include "config.h" +#include "wine/port.h" #include #include @@ -34,15 +35,10 @@ # include #endif -#include "winglue.h" +#include "windef.h" +#include "winbase.h" #include "build.h" -#ifndef EXCEPTION_NONCONTINUABLE -#define EXCEPTION_NONCONTINUABLE 1 -#endif - -#define EXCEPTION_WINE_STUB 0x80000100 /* stub entry point called */ - struct import { DLLSPEC *spec; /* description of the imported dll */ @@ -74,57 +70,6 @@ static int nb_delayed = 0; /* number of delayed dlls */ static int total_imports = 0; /* total number of imported functions */ static int total_delayed = 0; /* total number of imported functions in delayed DLLs */ -/* list of symbols that are ignored by default */ -static const char * const default_ignored_symbols[] = -{ - "abs", - "acos", - "asin", - "atan", - "atan2", - "atof", - "atoi", - "atol", - "bsearch", - "ceil", - "cos", - "cosh", - "exp", - "fabs", - "floor", - "fmod", - "frexp", - "labs", - "log", - "log10", - "memchr", - "memcmp", - "memcpy", - "memmove", - "memset", - "modf", - "pow", - "qsort", - "sin", - "sinh", - "sqrt", - "strcat", - "strchr", - "strcmp", - "strcpy", - "strcspn", - "strlen", - "strncat", - "strncmp", - "strncpy", - "strpbrk", - "strrchr", - "strspn", - "strstr", - "tan", - "tanh" -}; - static inline const char *ppc_reg( int reg ) { @@ -152,7 +97,7 @@ static int func_cmp( const void *func1, const void *func2 ) } /* add a name to a name table */ -inline static void add_name( struct name_table *table, const char *name ) +static inline void add_name( struct name_table *table, const char *name ) { if (table->count == table->size) { @@ -164,7 +109,7 @@ inline static void add_name( struct name_table *table, const char *name ) } /* remove a name from a name table */ -inline static void remove_name( struct name_table *table, unsigned int idx ) +static inline void remove_name( struct name_table *table, unsigned int idx ) { assert( idx < table->count ); free( table->names[idx] ); @@ -174,7 +119,7 @@ inline static void remove_name( struct name_table *table, unsigned int idx ) } /* make a name table empty */ -inline static void empty_name_table( struct name_table *table ) +static inline void empty_name_table( struct name_table *table ) { unsigned int i; @@ -183,7 +128,7 @@ inline static void empty_name_table( struct name_table *table ) } /* locate a name in a (sorted) list */ -inline static const char *find_name( const char *name, const struct name_table *table ) +static inline const char *find_name( const char *name, const struct name_table *table ) { char **res = NULL; @@ -192,20 +137,21 @@ inline static const char *find_name( const char *name, const struct name_table * } /* sort a name table */ -inline static void sort_names( struct name_table *table ) +static inline void sort_names( struct name_table *table ) { if (table->count) qsort( table->names, table->count, sizeof(*table->names), name_cmp ); } /* locate an export in a (sorted) export list */ -inline static ORDDEF *find_export( const char *name, ORDDEF **table, int size ) +static inline ORDDEF *find_export( const char *name, ORDDEF **table, int size ) { ORDDEF func, *odp, **res = NULL; - func.name = (char *)name; + func.name = xstrdup(name); func.ordinal = -1; odp = &func; if (table) res = bsearch( &odp, table, size, sizeof(*table), func_cmp ); + free( func.name ); return res ? *res : NULL; } @@ -222,7 +168,7 @@ static void free_imports( struct import *imp ) /* check whether a given dll is imported in delayed mode */ static int is_delayed_import( const char *name ) { - int i; + unsigned int i; for (i = 0; i < delayed_imports.count; i++) { @@ -308,19 +254,13 @@ static int read_import_lib( struct import *imp ) nb_delayed++; } - imp->exports = xmalloc( spec->nb_entry_points * sizeof(*imp->exports) ); - - for (i = 0; i < spec->nb_entry_points; i++) + if (spec->nb_entry_points) { - ORDDEF *odp = &spec->entry_points[i]; - - if (odp->type != TYPE_STDCALL && odp->type != TYPE_CDECL) continue; - if (odp->flags & FLAG_PRIVATE) continue; - imp->exports[imp->nb_exports++] = odp; - } - imp->exports = xrealloc( imp->exports, imp->nb_exports * sizeof(*imp->exports) ); - if (imp->nb_exports) + imp->exports = xmalloc( spec->nb_entry_points * sizeof(*imp->exports) ); + for (i = 0; i < spec->nb_entry_points; i++) + imp->exports[imp->nb_exports++] = &spec->entry_points[i]; qsort( imp->exports, imp->nb_exports, sizeof(*imp->exports), func_cmp ); + } return 1; } @@ -402,23 +342,12 @@ static void remove_import_dll( int index ) free_imports( imp ); } -/* initialize the list of ignored symbols */ -static void init_ignored_symbols(void) -{ - unsigned int i; - - for (i = 0; i < sizeof(default_ignored_symbols)/sizeof(default_ignored_symbols[0]); i++) - add_name( &ignore_symbols, default_ignored_symbols[i] ); -} - /* add a symbol to the ignored symbol list */ /* if the name starts with '-' the symbol is removed instead */ void add_ignore_symbol( const char *name ) { unsigned int i; - if (!ignore_symbols.size) init_ignored_symbols(); /* first time around, fill list with defaults */ - if (name[0] == '-') /* remove it */ { if (!name[1]) empty_name_table( &ignore_symbols ); /* remove everything */ @@ -494,6 +423,42 @@ static int check_unused( const struct import* imp, const DLLSPEC *spec ) return 1; } +/* check if a given forward does exist in one of the imported dlls */ +static void check_undefined_forwards( DLLSPEC *spec ) +{ + char *link_name, *api_name, *dll_name, *p; + int i, j; + + for (i = 0; i < spec->nb_entry_points; i++) + { + ORDDEF *odp = &spec->entry_points[i]; + + if (!(odp->flags & FLAG_FORWARD)) continue; + + link_name = xstrdup( odp->link_name ); + p = strrchr( link_name, '.' ); + *p = 0; + api_name = p + 1; + dll_name = get_dll_name( link_name, NULL ); + + for (j = 0; j < nb_imports; j++) + { + struct import *imp = dll_imports[j]; + + if (strcasecmp( imp->spec->file_name, dll_name )) continue; + if (!find_export( api_name, imp->exports, imp->nb_exports )) + warning( "%s:%d: forward '%s' not found in %s\n", + spec->src_name, odp->lineno, odp->link_name, imp->spec->file_name ); + break; + } + if (j == nb_imports) + warning( "%s:%d: forward '%s' not found in the imported dll list\n", + spec->src_name, odp->lineno, odp->link_name ); + free( link_name ); + free( dll_name ); + } +} + /* flag the dll exports that link to an undefined symbol */ static void check_undefined_exports( DLLSPEC *spec ) { @@ -506,8 +471,25 @@ static void check_undefined_exports( DLLSPEC *spec ) if (odp->flags & FLAG_FORWARD) continue; if (find_name( odp->link_name, &undef_symbols )) { - odp->flags |= FLAG_EXT_LINK; - add_name( &ext_link_imports, odp->link_name ); + switch(odp->type) + { + case TYPE_PASCAL: + case TYPE_STDCALL: + case TYPE_CDECL: + case TYPE_VARARGS: + if (link_ext_symbols) + { + odp->flags |= FLAG_EXT_LINK; + add_name( &ext_link_imports, odp->link_name ); + } + else error( "%s:%d: function '%s' not defined\n", + spec->src_name, odp->lineno, odp->link_name ); + break; + default: + error( "%s:%d: external symbol '%s' is not a function\n", + spec->src_name, odp->lineno, odp->link_name ); + break; + } } } } @@ -516,7 +498,8 @@ static void check_undefined_exports( DLLSPEC *spec ) static char *create_undef_symbols_file( DLLSPEC *spec ) { char *as_file, *obj_file; - unsigned int i; + int i; + unsigned int j; FILE *f; as_file = get_temp_file_name( output_file_name, ".s" ); @@ -530,8 +513,8 @@ static char *create_undef_symbols_file( DLLSPEC *spec ) if (odp->flags & FLAG_FORWARD) continue; fprintf( f, "\t%s %s\n", get_asm_ptr_keyword(), asm_name(odp->link_name) ); } - for (i = 0; i < extra_ld_symbols.count; i++) - fprintf( f, "\t%s %s\n", get_asm_ptr_keyword(), asm_name(extra_ld_symbols.names[i]) ); + for (j = 0; j < extra_ld_symbols.count; j++) + fprintf( f, "\t%s %s\n", get_asm_ptr_keyword(), asm_name(extra_ld_symbols.names[j]) ); fclose( f ); obj_file = get_temp_file_name( output_file_name, ".o" ); @@ -605,11 +588,12 @@ void read_undef_symbols( DLLSPEC *spec, char **argv ) /* resolve the imports for a Win32 module */ int resolve_imports( DLLSPEC *spec ) { - unsigned int i, j, removed; + int i; + unsigned int j, removed; ORDDEF *odp; - if (!ignore_symbols.size) init_ignored_symbols(); sort_names( &ignore_symbols ); + check_undefined_forwards( spec ); for (i = 0; i < nb_imports; i++) { @@ -621,15 +605,23 @@ int resolve_imports( DLLSPEC *spec ) odp = find_export( undef_symbols.names[j], imp->exports, imp->nb_exports ); if (odp) { - add_import_func( imp, odp ); - remove_name( &undef_symbols, j-- ); - removed++; + if (odp->flags & FLAG_PRIVATE) continue; + if (odp->type != TYPE_STDCALL && odp->type != TYPE_CDECL) + warning( "winebuild: Data export '%s' cannot be imported from %s\n", + odp->link_name, imp->spec->file_name ); + else + { + add_import_func( imp, odp ); + remove_name( &undef_symbols, j-- ); + removed++; + } } } - if (!removed && check_unused( imp, spec )) + if (!removed) { /* the dll is not used, get rid of it */ - warning( "%s imported but no symbols used\n", imp->spec->file_name ); + if (check_unused( imp, spec )) + warning( "winebuild: %s imported but no symbols used\n", imp->spec->file_name ); remove_import_dll( i ); i--; } @@ -642,99 +634,99 @@ int resolve_imports( DLLSPEC *spec ) } /* output the get_pc thunk if needed */ -void output_get_pc_thunk( FILE *outfile ) +void output_get_pc_thunk(void) { if (target_cpu != CPU_x86) return; if (!UsePIC) return; - fprintf( outfile, "\n\t.text\n" ); - fprintf( outfile, "\t.align %d\n", get_alignment(4) ); - fprintf( outfile, "\t%s\n", func_declaration("__wine_spec_get_pc_thunk_eax") ); - fprintf( outfile, "%s:\n", asm_name("__wine_spec_get_pc_thunk_eax") ); - fprintf( outfile, "\tpopl %%eax\n" ); - fprintf( outfile, "\tpushl %%eax\n" ); - fprintf( outfile, "\tret\n" ); - output_function_size( outfile, "__wine_spec_get_pc_thunk_eax" ); + output( "\n\t.text\n" ); + output( "\t.align %d\n", get_alignment(4) ); + output( "\t%s\n", func_declaration("__wine_spec_get_pc_thunk_eax") ); + output( "%s:\n", asm_name("__wine_spec_get_pc_thunk_eax") ); + output( "\tpopl %%eax\n" ); + output( "\tpushl %%eax\n" ); + output( "\tret\n" ); + output_function_size( "__wine_spec_get_pc_thunk_eax" ); } /* output a single import thunk */ -static void output_import_thunk( FILE *outfile, const char *name, const char *table, int pos ) +static void output_import_thunk( const char *name, const char *table, int pos ) { - fprintf( outfile, "\n\t.align %d\n", get_alignment(4) ); - fprintf( outfile, "\t%s\n", func_declaration(name) ); - fprintf( outfile, "%s\n", asm_globl(name) ); + output( "\n\t.align %d\n", get_alignment(4) ); + output( "\t%s\n", func_declaration(name) ); + output( "%s\n", asm_globl(name) ); switch(target_cpu) { case CPU_x86: if (!UsePIC) { - fprintf( outfile, "\tjmp *(%s+%d)\n", table, pos ); + output( "\tjmp *(%s+%d)\n", table, pos ); } else { - fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") ); - fprintf( outfile, "1:\tjmp *%s+%d-1b(%%eax)\n", table, pos ); + output( "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") ); + output( "1:\tjmp *%s+%d-1b(%%eax)\n", table, pos ); } break; case CPU_x86_64: - fprintf( outfile, "\tjmpq *%s+%d(%%rip)\n", table, pos ); + output( "\tjmpq *%s+%d(%%rip)\n", table, pos ); break; case CPU_SPARC: if ( !UsePIC ) { - fprintf( outfile, "\tsethi %%hi(%s+%d), %%g1\n", table, pos ); - fprintf( outfile, "\tld [%%g1+%%lo(%s+%d)], %%g1\n", table, pos ); - fprintf( outfile, "\tjmp %%g1\n" ); - fprintf( outfile, "\tnop\n" ); + output( "\tsethi %%hi(%s+%d), %%g1\n", table, pos ); + output( "\tld [%%g1+%%lo(%s+%d)], %%g1\n", table, pos ); + output( "\tjmp %%g1\n" ); + output( "\tnop\n" ); } else { /* Hmpf. Stupid sparc assembler always interprets global variable names as GOT offsets, so we have to do it the long way ... */ - fprintf( outfile, "\tsave %%sp, -96, %%sp\n" ); - fprintf( outfile, "0:\tcall 1f\n" ); - fprintf( outfile, "\tnop\n" ); - fprintf( outfile, "1:\tsethi %%hi(%s+%d-0b), %%g1\n", table, pos ); - fprintf( outfile, "\tor %%g1, %%lo(%s+%d-0b), %%g1\n", table, pos ); - fprintf( outfile, "\tld [%%g1+%%o7], %%g1\n" ); - fprintf( outfile, "\tjmp %%g1\n" ); - fprintf( outfile, "\trestore\n" ); + output( "\tsave %%sp, -96, %%sp\n" ); + output( "0:\tcall 1f\n" ); + output( "\tnop\n" ); + output( "1:\tsethi %%hi(%s+%d-0b), %%g1\n", table, pos ); + output( "\tor %%g1, %%lo(%s+%d-0b), %%g1\n", table, pos ); + output( "\tld [%%g1+%%o7], %%g1\n" ); + output( "\tjmp %%g1\n" ); + output( "\trestore\n" ); } break; case CPU_ALPHA: - fprintf( outfile, "\tlda $0,%s\n", table ); - fprintf( outfile, "\tlda $0,%d($0)\n", pos ); - fprintf( outfile, "\tjmp $31,($0)\n" ); + output( "\tlda $0,%s\n", table ); + output( "\tlda $0,%d($0)\n", pos ); + output( "\tjmp $31,($0)\n" ); break; case CPU_POWERPC: - fprintf( outfile, "\taddi %s, %s, -0x4\n", ppc_reg(1), ppc_reg(1) ); - fprintf( outfile, "\tstw %s, 0(%s)\n", ppc_reg(9), ppc_reg(1) ); - fprintf( outfile, "\taddi %s, %s, -0x4\n", ppc_reg(1), ppc_reg(1) ); - fprintf( outfile, "\tstw %s, 0(%s)\n", ppc_reg(8), ppc_reg(1) ); - fprintf( outfile, "\taddi %s, %s, -0x4\n", ppc_reg(1), ppc_reg(1) ); - fprintf( outfile, "\tstw %s, 0(%s)\n", ppc_reg(7), ppc_reg(1) ); + output( "\taddi %s, %s, -0x4\n", ppc_reg(1), ppc_reg(1) ); + output( "\tstw %s, 0(%s)\n", ppc_reg(9), ppc_reg(1) ); + output( "\taddi %s, %s, -0x4\n", ppc_reg(1), ppc_reg(1) ); + output( "\tstw %s, 0(%s)\n", ppc_reg(8), ppc_reg(1) ); + output( "\taddi %s, %s, -0x4\n", ppc_reg(1), ppc_reg(1) ); + output( "\tstw %s, 0(%s)\n", ppc_reg(7), ppc_reg(1) ); if (target_platform == PLATFORM_APPLE) { - fprintf( outfile, "\tlis %s, ha16(%s+%d)\n", ppc_reg(9), table, pos ); - fprintf( outfile, "\tla %s, lo16(%s+%d)(%s)\n", ppc_reg(8), table, pos, ppc_reg(9) ); + output( "\tlis %s, ha16(%s+%d)\n", ppc_reg(9), table, pos ); + output( "\tla %s, lo16(%s+%d)(%s)\n", ppc_reg(8), table, pos, ppc_reg(9) ); } else { - fprintf( outfile, "\tlis %s, (%s+%d)@h\n", ppc_reg(9), table, pos ); - fprintf( outfile, "\tla %s, (%s+%d)@l(%s)\n", ppc_reg(8), table, pos, ppc_reg(9) ); + output( "\tlis %s, (%s+%d)@h\n", ppc_reg(9), table, pos ); + output( "\tla %s, (%s+%d)@l(%s)\n", ppc_reg(8), table, pos, ppc_reg(9) ); } - fprintf( outfile, "\tlwz %s, 0(%s)\n", ppc_reg(7), ppc_reg(8) ); - fprintf( outfile, "\tmtctr %s\n", ppc_reg(7) ); - fprintf( outfile, "\tlwz %s, 0(%s)\n", ppc_reg(7), ppc_reg(1) ); - fprintf( outfile, "\taddi %s, %s, 0x4\n", ppc_reg(1), ppc_reg(1) ); - fprintf( outfile, "\tlwz %s, 0(%s)\n", ppc_reg(8), ppc_reg(1) ); - fprintf( outfile, "\taddi %s, %s, 0x4\n", ppc_reg(1), ppc_reg(1) ); - fprintf( outfile, "\tlwz %s, 0(%s)\n", ppc_reg(9), ppc_reg(1) ); - fprintf( outfile, "\taddi %s, %s, 0x4\n", ppc_reg(1), ppc_reg(1) ); - fprintf( outfile, "\tbctr\n" ); + output( "\tlwz %s, 0(%s)\n", ppc_reg(7), ppc_reg(8) ); + output( "\tmtctr %s\n", ppc_reg(7) ); + output( "\tlwz %s, 0(%s)\n", ppc_reg(7), ppc_reg(1) ); + output( "\taddi %s, %s, 0x4\n", ppc_reg(1), ppc_reg(1) ); + output( "\tlwz %s, 0(%s)\n", ppc_reg(8), ppc_reg(1) ); + output( "\taddi %s, %s, 0x4\n", ppc_reg(1), ppc_reg(1) ); + output( "\tlwz %s, 0(%s)\n", ppc_reg(9), ppc_reg(1) ); + output( "\taddi %s, %s, 0x4\n", ppc_reg(1), ppc_reg(1) ); + output( "\tbctr\n" ); break; } - output_function_size( outfile, name ); + output_function_size( name ); } /* check if we need an import directory */ @@ -744,7 +736,7 @@ int has_imports(void) } /* output the import table of a Win32 module */ -static void output_immediate_imports( FILE *outfile ) +static void output_immediate_imports(void) { int i, j; const char *dll_name; @@ -753,10 +745,10 @@ static void output_immediate_imports( FILE *outfile ) /* main import header */ - fprintf( outfile, "\n/* import table */\n" ); - fprintf( outfile, "\n\t.data\n" ); - fprintf( outfile, "\t.align %d\n", get_alignment(4) ); - fprintf( outfile, ".L__wine_spec_imports:\n" ); + output( "\n/* import table */\n" ); + output( "\n\t.data\n" ); + output( "\t.align %d\n", get_alignment(4) ); + output( ".L__wine_spec_imports:\n" ); /* list of dlls */ @@ -764,23 +756,23 @@ static void output_immediate_imports( FILE *outfile ) { if (dll_imports[i]->delay) continue; dll_name = make_c_identifier( dll_imports[i]->spec->file_name ); - fprintf( outfile, "\t.long 0\n" ); /* OriginalFirstThunk */ - fprintf( outfile, "\t.long 0\n" ); /* TimeDateStamp */ - fprintf( outfile, "\t.long 0\n" ); /* ForwarderChain */ - fprintf( outfile, "\t.long .L__wine_spec_import_name_%s-.L__wine_spec_rva_base\n", /* Name */ + output( "\t.long 0\n" ); /* OriginalFirstThunk */ + output( "\t.long 0\n" ); /* TimeDateStamp */ + output( "\t.long 0\n" ); /* ForwarderChain */ + output( "\t.long .L__wine_spec_import_name_%s-.L__wine_spec_rva_base\n", /* Name */ dll_name ); - fprintf( outfile, "\t.long .L__wine_spec_import_data_ptrs+%d-.L__wine_spec_rva_base\n", /* FirstThunk */ + output( "\t.long .L__wine_spec_import_data_ptrs+%d-.L__wine_spec_rva_base\n", /* FirstThunk */ j * get_ptr_size() ); j += dll_imports[i]->nb_imports + 1; } - fprintf( outfile, "\t.long 0\n" ); /* OriginalFirstThunk */ - fprintf( outfile, "\t.long 0\n" ); /* TimeDateStamp */ - fprintf( outfile, "\t.long 0\n" ); /* ForwarderChain */ - fprintf( outfile, "\t.long 0\n" ); /* Name */ - fprintf( outfile, "\t.long 0\n" ); /* FirstThunk */ + output( "\t.long 0\n" ); /* OriginalFirstThunk */ + output( "\t.long 0\n" ); /* TimeDateStamp */ + output( "\t.long 0\n" ); /* ForwarderChain */ + output( "\t.long 0\n" ); /* Name */ + output( "\t.long 0\n" ); /* FirstThunk */ - fprintf( outfile, "\n\t.align %d\n", get_alignment(get_ptr_size()) ); - fprintf( outfile, ".L__wine_spec_import_data_ptrs:\n" ); + output( "\n\t.align %d\n", get_alignment(get_ptr_size()) ); + output( ".L__wine_spec_import_data_ptrs:\n" ); for (i = 0; i < nb_imports; i++) { if (dll_imports[i]->delay) continue; @@ -789,19 +781,19 @@ static void output_immediate_imports( FILE *outfile ) { ORDDEF *odp = dll_imports[i]->imports[j]; if (!(odp->flags & FLAG_NONAME)) - fprintf( outfile, "\t%s .L__wine_spec_import_data_%s_%s-.L__wine_spec_rva_base\n", + output( "\t%s .L__wine_spec_import_data_%s_%s-.L__wine_spec_rva_base\n", get_asm_ptr_keyword(), dll_name, odp->name ); else { if (get_ptr_size() == 8) - fprintf( outfile, "\t.quad 0x800000000000%04x\n", odp->ordinal ); + output( "\t.quad 0x800000000000%04x\n", odp->ordinal ); else - fprintf( outfile, "\t.long 0x8000%04x\n", odp->ordinal ); + output( "\t.long 0x8000%04x\n", odp->ordinal ); } } - fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() ); + output( "\t%s 0\n", get_asm_ptr_keyword() ); } - fprintf( outfile, ".L__wine_spec_imports_end:\n" ); + output( ".L__wine_spec_imports_end:\n" ); for (i = 0; i < nb_imports; i++) { @@ -812,10 +804,10 @@ static void output_immediate_imports( FILE *outfile ) ORDDEF *odp = dll_imports[i]->imports[j]; if (!(odp->flags & FLAG_NONAME)) { - fprintf( outfile, "\t.align %d\n", get_alignment(2) ); - fprintf( outfile, ".L__wine_spec_import_data_%s_%s:\n", dll_name, odp->name ); - fprintf( outfile, "\t%s %d\n", get_asm_short_keyword(), odp->ordinal ); - fprintf( outfile, "\t%s \"%s\"\n", get_asm_string_keyword(), odp->name ); + output( "\t.align %d\n", get_alignment(2) ); + output( ".L__wine_spec_import_data_%s_%s:\n", dll_name, odp->name ); + output( "\t%s %d\n", get_asm_short_keyword(), odp->ordinal ); + output( "\t%s \"%s\"\n", get_asm_string_keyword(), odp->name ); } } } @@ -824,13 +816,13 @@ static void output_immediate_imports( FILE *outfile ) { if (dll_imports[i]->delay) continue; dll_name = make_c_identifier( dll_imports[i]->spec->file_name ); - fprintf( outfile, ".L__wine_spec_import_name_%s:\n\t%s \"%s\"\n", + output( ".L__wine_spec_import_name_%s:\n\t%s \"%s\"\n", dll_name, get_asm_string_keyword(), dll_imports[i]->spec->file_name ); } } /* output the import thunks of a Win32 module */ -static void output_immediate_import_thunks( FILE *outfile ) +static void output_immediate_import_thunks(void) { int i, j, pos; int nb_imm = nb_imports - nb_delayed; @@ -838,10 +830,10 @@ static void output_immediate_import_thunks( FILE *outfile ) if (!nb_imm) return; - fprintf( outfile, "\n/* immediate import thunks */\n\n" ); - fprintf( outfile, "\t.text\n" ); - fprintf( outfile, "\t.align %d\n", get_alignment(8) ); - fprintf( outfile, "%s:\n", asm_name(import_thunks)); + output( "\n/* immediate import thunks */\n\n" ); + output( "\t.text\n" ); + output( "\t.align %d\n", get_alignment(8) ); + output( "%s:\n", asm_name(import_thunks)); for (i = pos = 0; i < nb_imports; i++) { @@ -849,55 +841,56 @@ static void output_immediate_import_thunks( FILE *outfile ) for (j = 0; j < dll_imports[i]->nb_imports; j++, pos += get_ptr_size()) { ORDDEF *odp = dll_imports[i]->imports[j]; - output_import_thunk( outfile, odp->name ? odp->name : odp->export_name, + output_import_thunk( odp->name ? odp->name : odp->export_name, ".L__wine_spec_import_data_ptrs", pos ); } pos += get_ptr_size(); } - output_function_size( outfile, import_thunks ); + output_function_size( import_thunks ); } /* output the delayed import table of a Win32 module */ -static void output_delayed_imports( FILE *outfile, const DLLSPEC *spec ) +static void output_delayed_imports( const DLLSPEC *spec ) { - int i, j; + int i, j, mod; if (!nb_delayed) return; - fprintf( outfile, "\n/* delayed imports */\n\n" ); - fprintf( outfile, "\t.data\n" ); - fprintf( outfile, "\t.align %d\n", get_alignment(get_ptr_size()) ); - fprintf( outfile, "%s\n", asm_globl("__wine_spec_delay_imports") ); + output( "\n/* delayed imports */\n\n" ); + output( "\t.data\n" ); + output( "\t.align %d\n", get_alignment(get_ptr_size()) ); + output( "%s\n", asm_globl("__wine_spec_delay_imports") ); /* list of dlls */ - for (i = j = 0; i < nb_imports; i++) + for (i = j = mod = 0; i < nb_imports; i++) { if (!dll_imports[i]->delay) continue; - fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() ); /* grAttrs */ - fprintf( outfile, "\t%s .L__wine_delay_name_%d\n", /* szName */ + output( "\t%s 0\n", get_asm_ptr_keyword() ); /* grAttrs */ + output( "\t%s .L__wine_delay_name_%d\n", /* szName */ get_asm_ptr_keyword(), i ); - fprintf( outfile, "\t%s .L__wine_delay_modules+%d\n", /* phmod */ - get_asm_ptr_keyword(), i * get_ptr_size() ); - fprintf( outfile, "\t%s .L__wine_delay_IAT+%d\n", /* pIAT */ + output( "\t%s .L__wine_delay_modules+%d\n", /* phmod */ + get_asm_ptr_keyword(), mod * get_ptr_size() ); + output( "\t%s .L__wine_delay_IAT+%d\n", /* pIAT */ get_asm_ptr_keyword(), j * get_ptr_size() ); - fprintf( outfile, "\t%s .L__wine_delay_INT+%d\n", /* pINT */ + output( "\t%s .L__wine_delay_INT+%d\n", /* pINT */ get_asm_ptr_keyword(), j * get_ptr_size() ); - fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() ); /* pBoundIAT */ - fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() ); /* pUnloadIAT */ - fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() ); /* dwTimeStamp */ + output( "\t%s 0\n", get_asm_ptr_keyword() ); /* pBoundIAT */ + output( "\t%s 0\n", get_asm_ptr_keyword() ); /* pUnloadIAT */ + output( "\t%s 0\n", get_asm_ptr_keyword() ); /* dwTimeStamp */ j += dll_imports[i]->nb_imports; + mod++; } - fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() ); /* grAttrs */ - fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() ); /* szName */ - fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() ); /* phmod */ - fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() ); /* pIAT */ - fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() ); /* pINT */ - fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() ); /* pBoundIAT */ - fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() ); /* pUnloadIAT */ - fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() ); /* dwTimeStamp */ + output( "\t%s 0\n", get_asm_ptr_keyword() ); /* grAttrs */ + output( "\t%s 0\n", get_asm_ptr_keyword() ); /* szName */ + output( "\t%s 0\n", get_asm_ptr_keyword() ); /* phmod */ + output( "\t%s 0\n", get_asm_ptr_keyword() ); /* pIAT */ + output( "\t%s 0\n", get_asm_ptr_keyword() ); /* pINT */ + output( "\t%s 0\n", get_asm_ptr_keyword() ); /* pBoundIAT */ + output( "\t%s 0\n", get_asm_ptr_keyword() ); /* pUnloadIAT */ + output( "\t%s 0\n", get_asm_ptr_keyword() ); /* dwTimeStamp */ - fprintf( outfile, "\n.L__wine_delay_IAT:\n" ); + output( "\n.L__wine_delay_IAT:\n" ); for (i = 0; i < nb_imports; i++) { if (!dll_imports[i]->delay) continue; @@ -905,12 +898,12 @@ static void output_delayed_imports( FILE *outfile, const DLLSPEC *spec ) { ORDDEF *odp = dll_imports[i]->imports[j]; const char *name = odp->name ? odp->name : odp->export_name; - fprintf( outfile, "\t%s .L__wine_delay_imp_%d_%s\n", + output( "\t%s .L__wine_delay_imp_%d_%s\n", get_asm_ptr_keyword(), i, name ); } } - fprintf( outfile, "\n.L__wine_delay_INT:\n" ); + output( "\n.L__wine_delay_INT:\n" ); for (i = 0; i < nb_imports; i++) { if (!dll_imports[i]->delay) continue; @@ -918,24 +911,24 @@ static void output_delayed_imports( FILE *outfile, const DLLSPEC *spec ) { ORDDEF *odp = dll_imports[i]->imports[j]; if (!odp->name) - fprintf( outfile, "\t%s %d\n", get_asm_ptr_keyword(), odp->ordinal ); + output( "\t%s %d\n", get_asm_ptr_keyword(), odp->ordinal ); else - fprintf( outfile, "\t%s .L__wine_delay_data_%d_%s\n", + output( "\t%s .L__wine_delay_data_%d_%s\n", get_asm_ptr_keyword(), i, odp->name ); } } - fprintf( outfile, "\n.L__wine_delay_modules:\n" ); + output( "\n.L__wine_delay_modules:\n" ); for (i = 0; i < nb_imports; i++) { - if (dll_imports[i]->delay) fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() ); + if (dll_imports[i]->delay) output( "\t%s 0\n", get_asm_ptr_keyword() ); } for (i = 0; i < nb_imports; i++) { if (!dll_imports[i]->delay) continue; - fprintf( outfile, ".L__wine_delay_name_%d:\n", i ); - fprintf( outfile, "\t%s \"%s\"\n", + output( ".L__wine_delay_name_%d:\n", i ); + output( "\t%s \"%s\"\n", get_asm_string_keyword(), dll_imports[i]->spec->file_name ); } @@ -946,15 +939,15 @@ static void output_delayed_imports( FILE *outfile, const DLLSPEC *spec ) { ORDDEF *odp = dll_imports[i]->imports[j]; if (!odp->name) continue; - fprintf( outfile, ".L__wine_delay_data_%d_%s:\n", i, odp->name ); - fprintf( outfile, "\t%s \"%s\"\n", get_asm_string_keyword(), odp->name ); + output( ".L__wine_delay_data_%d_%s:\n", i, odp->name ); + output( "\t%s \"%s\"\n", get_asm_string_keyword(), odp->name ); } } - output_function_size( outfile, "__wine_spec_delay_imports" ); + output_function_size( "__wine_spec_delay_imports" ); } /* output the delayed import thunks of a Win32 module */ -static void output_delayed_import_thunks( FILE *outfile, const DLLSPEC *spec ) +static void output_delayed_import_thunks( const DLLSPEC *spec ) { int i, idx, j, pos, extra_stack_storage = 0; static const char delayed_import_loaders[] = "__wine_spec_delayed_import_loaders"; @@ -962,95 +955,105 @@ static void output_delayed_import_thunks( FILE *outfile, const DLLSPEC *spec ) if (!nb_delayed) return; - fprintf( outfile, "\n/* delayed import thunks */\n\n" ); - fprintf( outfile, "\t.text\n" ); - fprintf( outfile, "\t.align %d\n", get_alignment(8) ); - fprintf( outfile, "%s:\n", asm_name(delayed_import_loaders)); - fprintf( outfile, "\t%s\n", func_declaration("__wine_delay_load_asm") ); - fprintf( outfile, "%s:\n", asm_name("__wine_delay_load_asm") ); + output( "\n/* delayed import thunks */\n\n" ); + output( "\t.text\n" ); + output( "\t.align %d\n", get_alignment(8) ); + output( "%s:\n", asm_name(delayed_import_loaders)); + output( "\t%s\n", func_declaration("__wine_delay_load_asm") ); + output( "%s:\n", asm_name("__wine_delay_load_asm") ); switch(target_cpu) { case CPU_x86: - fprintf( outfile, "\tpushl %%ecx\n" ); - fprintf( outfile, "\tpushl %%edx\n" ); - fprintf( outfile, "\tpushl %%eax\n" ); - fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_delay_load") ); - fprintf( outfile, "\tpopl %%edx\n" ); - fprintf( outfile, "\tpopl %%ecx\n" ); - fprintf( outfile, "\tjmp *%%eax\n" ); + output( "\tpushl %%ecx\n" ); + output( "\tpushl %%edx\n" ); + output( "\tpushl %%eax\n" ); + output( "\tcall %s\n", asm_name("__wine_spec_delay_load") ); + output( "\tpopl %%edx\n" ); + output( "\tpopl %%ecx\n" ); + output( "\tjmp *%%eax\n" ); break; case CPU_x86_64: - fprintf( outfile, "\tpushq %%rdi\n" ); - fprintf( outfile, "\tsubq $8,%%rsp\n" ); - fprintf( outfile, "\tmovq %%r11,%%rdi\n" ); - fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_delay_load") ); - fprintf( outfile, "\taddq $8,%%rsp\n" ); - fprintf( outfile, "\tpopq %%rdi\n" ); - fprintf( outfile, "\tjmp *%%rax\n" ); + output( "\tpushq %%rdi\n" ); + output( "\tpushq %%rsi\n" ); + output( "\tpushq %%rdx\n" ); + output( "\tpushq %%rcx\n" ); + output( "\tpushq %%r8\n" ); + output( "\tpushq %%r9\n" ); + output( "\tsubq $8,%%rsp\n" ); + output( "\tmovq %%r11,%%rdi\n" ); + output( "\tcall %s\n", asm_name("__wine_spec_delay_load") ); + output( "\taddq $8,%%rsp\n" ); + output( "\tpopq %%r9\n" ); + output( "\tpopq %%r8\n" ); + output( "\tpopq %%rcx\n" ); + output( "\tpopq %%rdx\n" ); + output( "\tpopq %%rsi\n" ); + output( "\tpopq %%rdi\n" ); + output( "\tjmp *%%rax\n" ); break; case CPU_SPARC: - fprintf( outfile, "\tsave %%sp, -96, %%sp\n" ); - fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_delay_load") ); - fprintf( outfile, "\tmov %%g1, %%o0\n" ); - fprintf( outfile, "\tjmp %%o0\n" ); - fprintf( outfile, "\trestore\n" ); + output( "\tsave %%sp, -96, %%sp\n" ); + output( "\tcall %s\n", asm_name("__wine_spec_delay_load") ); + output( "\tmov %%g1, %%o0\n" ); + output( "\tjmp %%o0\n" ); + output( "\trestore\n" ); break; case CPU_ALPHA: - fprintf( outfile, "\tjsr $26,%s\n", asm_name("__wine_spec_delay_load") ); - fprintf( outfile, "\tjmp $31,($0)\n" ); + output( "\tjsr $26,%s\n", asm_name("__wine_spec_delay_load") ); + output( "\tjmp $31,($0)\n" ); break; case CPU_POWERPC: if (target_platform == PLATFORM_APPLE) extra_stack_storage = 56; /* Save all callee saved registers into a stackframe. */ - fprintf( outfile, "\tstwu %s, -%d(%s)\n",ppc_reg(1), 48+extra_stack_storage, ppc_reg(1)); - fprintf( outfile, "\tstw %s, %d(%s)\n", ppc_reg(3), 4+extra_stack_storage, ppc_reg(1)); - fprintf( outfile, "\tstw %s, %d(%s)\n", ppc_reg(4), 8+extra_stack_storage, ppc_reg(1)); - fprintf( outfile, "\tstw %s, %d(%s)\n", ppc_reg(5), 12+extra_stack_storage, ppc_reg(1)); - fprintf( outfile, "\tstw %s, %d(%s)\n", ppc_reg(6), 16+extra_stack_storage, ppc_reg(1)); - fprintf( outfile, "\tstw %s, %d(%s)\n", ppc_reg(7), 20+extra_stack_storage, ppc_reg(1)); - fprintf( outfile, "\tstw %s, %d(%s)\n", ppc_reg(8), 24+extra_stack_storage, ppc_reg(1)); - fprintf( outfile, "\tstw %s, %d(%s)\n", ppc_reg(9), 28+extra_stack_storage, ppc_reg(1)); - fprintf( outfile, "\tstw %s, %d(%s)\n", ppc_reg(10),32+extra_stack_storage, ppc_reg(1)); - fprintf( outfile, "\tstw %s, %d(%s)\n", ppc_reg(11),36+extra_stack_storage, ppc_reg(1)); - fprintf( outfile, "\tstw %s, %d(%s)\n", ppc_reg(12),40+extra_stack_storage, ppc_reg(1)); + output( "\tstwu %s, -%d(%s)\n",ppc_reg(1), 48+extra_stack_storage, ppc_reg(1)); + output( "\tstw %s, %d(%s)\n", ppc_reg(3), 4+extra_stack_storage, ppc_reg(1)); + output( "\tstw %s, %d(%s)\n", ppc_reg(4), 8+extra_stack_storage, ppc_reg(1)); + output( "\tstw %s, %d(%s)\n", ppc_reg(5), 12+extra_stack_storage, ppc_reg(1)); + output( "\tstw %s, %d(%s)\n", ppc_reg(6), 16+extra_stack_storage, ppc_reg(1)); + output( "\tstw %s, %d(%s)\n", ppc_reg(7), 20+extra_stack_storage, ppc_reg(1)); + output( "\tstw %s, %d(%s)\n", ppc_reg(8), 24+extra_stack_storage, ppc_reg(1)); + output( "\tstw %s, %d(%s)\n", ppc_reg(9), 28+extra_stack_storage, ppc_reg(1)); + output( "\tstw %s, %d(%s)\n", ppc_reg(10),32+extra_stack_storage, ppc_reg(1)); + output( "\tstw %s, %d(%s)\n", ppc_reg(11),36+extra_stack_storage, ppc_reg(1)); + output( "\tstw %s, %d(%s)\n", ppc_reg(12),40+extra_stack_storage, ppc_reg(1)); /* r0 -> r3 (arg1) */ - fprintf( outfile, "\tmr %s, %s\n", ppc_reg(3), ppc_reg(0)); + output( "\tmr %s, %s\n", ppc_reg(3), ppc_reg(0)); /* save return address */ - fprintf( outfile, "\tmflr %s\n", ppc_reg(0)); - fprintf( outfile, "\tstw %s, %d(%s)\n", ppc_reg(0), 44+extra_stack_storage, ppc_reg(1)); + output( "\tmflr %s\n", ppc_reg(0)); + output( "\tstw %s, %d(%s)\n", ppc_reg(0), 44+extra_stack_storage, ppc_reg(1)); /* Call the __wine_delay_load function, arg1 is arg1. */ - fprintf( outfile, "\tbl %s\n", asm_name("__wine_spec_delay_load") ); + output( "\tbl %s\n", asm_name("__wine_spec_delay_load") ); /* Load return value from call into ctr register */ - fprintf( outfile, "\tmtctr %s\n", ppc_reg(3)); + output( "\tmtctr %s\n", ppc_reg(3)); /* restore all saved registers and drop stackframe. */ - fprintf( outfile, "\tlwz %s, %d(%s)\n", ppc_reg(3), 4+extra_stack_storage, ppc_reg(1)); - fprintf( outfile, "\tlwz %s, %d(%s)\n", ppc_reg(4), 8+extra_stack_storage, ppc_reg(1)); - fprintf( outfile, "\tlwz %s, %d(%s)\n", ppc_reg(5), 12+extra_stack_storage, ppc_reg(1)); - fprintf( outfile, "\tlwz %s, %d(%s)\n", ppc_reg(6), 16+extra_stack_storage, ppc_reg(1)); - fprintf( outfile, "\tlwz %s, %d(%s)\n", ppc_reg(7), 20+extra_stack_storage, ppc_reg(1)); - fprintf( outfile, "\tlwz %s, %d(%s)\n", ppc_reg(8), 24+extra_stack_storage, ppc_reg(1)); - fprintf( outfile, "\tlwz %s, %d(%s)\n", ppc_reg(9), 28+extra_stack_storage, ppc_reg(1)); - fprintf( outfile, "\tlwz %s, %d(%s)\n", ppc_reg(10),32+extra_stack_storage, ppc_reg(1)); - fprintf( outfile, "\tlwz %s, %d(%s)\n", ppc_reg(11),36+extra_stack_storage, ppc_reg(1)); - fprintf( outfile, "\tlwz %s, %d(%s)\n", ppc_reg(12),40+extra_stack_storage, ppc_reg(1)); + output( "\tlwz %s, %d(%s)\n", ppc_reg(3), 4+extra_stack_storage, ppc_reg(1)); + output( "\tlwz %s, %d(%s)\n", ppc_reg(4), 8+extra_stack_storage, ppc_reg(1)); + output( "\tlwz %s, %d(%s)\n", ppc_reg(5), 12+extra_stack_storage, ppc_reg(1)); + output( "\tlwz %s, %d(%s)\n", ppc_reg(6), 16+extra_stack_storage, ppc_reg(1)); + output( "\tlwz %s, %d(%s)\n", ppc_reg(7), 20+extra_stack_storage, ppc_reg(1)); + output( "\tlwz %s, %d(%s)\n", ppc_reg(8), 24+extra_stack_storage, ppc_reg(1)); + output( "\tlwz %s, %d(%s)\n", ppc_reg(9), 28+extra_stack_storage, ppc_reg(1)); + output( "\tlwz %s, %d(%s)\n", ppc_reg(10),32+extra_stack_storage, ppc_reg(1)); + output( "\tlwz %s, %d(%s)\n", ppc_reg(11),36+extra_stack_storage, ppc_reg(1)); + output( "\tlwz %s, %d(%s)\n", ppc_reg(12),40+extra_stack_storage, ppc_reg(1)); /* Load return value from call into return register */ - fprintf( outfile, "\tlwz %s, %d(%s)\n", ppc_reg(0), 44+extra_stack_storage, ppc_reg(1)); - fprintf( outfile, "\tmtlr %s\n", ppc_reg(0)); - fprintf( outfile, "\taddi %s, %s, %d\n", ppc_reg(1), ppc_reg(1), 48+extra_stack_storage); + output( "\tlwz %s, %d(%s)\n", ppc_reg(0), 44+extra_stack_storage, ppc_reg(1)); + output( "\tmtlr %s\n", ppc_reg(0)); + output( "\taddi %s, %s, %d\n", ppc_reg(1), ppc_reg(1), 48+extra_stack_storage); /* branch to ctr register. */ - fprintf( outfile, "\tbctr\n"); + output( "\tbctr\n"); break; } - output_function_size( outfile, "__wine_delay_load_asm" ); - fprintf( outfile, "\n" ); + output_function_size( "__wine_delay_load_asm" ); + output( "\n" ); for (i = idx = 0; i < nb_imports; i++) { @@ -1060,25 +1063,25 @@ static void output_delayed_import_thunks( FILE *outfile, const DLLSPEC *spec ) ORDDEF *odp = dll_imports[i]->imports[j]; const char *name = odp->name ? odp->name : odp->export_name; - fprintf( outfile, ".L__wine_delay_imp_%d_%s:\n", i, name ); + output( ".L__wine_delay_imp_%d_%s:\n", i, name ); switch(target_cpu) { case CPU_x86: - fprintf( outfile, "\tmovl $%d, %%eax\n", (idx << 16) | j ); - fprintf( outfile, "\tjmp %s\n", asm_name("__wine_delay_load_asm") ); + output( "\tmovl $%d, %%eax\n", (idx << 16) | j ); + output( "\tjmp %s\n", asm_name("__wine_delay_load_asm") ); break; case CPU_x86_64: - fprintf( outfile, "\tmovq $%d,%%r11\n", (idx << 16) | j ); - fprintf( outfile, "\tjmp %s\n", asm_name("__wine_delay_load_asm") ); + output( "\tmovq $%d,%%r11\n", (idx << 16) | j ); + output( "\tjmp %s\n", asm_name("__wine_delay_load_asm") ); break; case CPU_SPARC: - fprintf( outfile, "\tset %d, %%g1\n", (idx << 16) | j ); - fprintf( outfile, "\tb,a %s\n", asm_name("__wine_delay_load_asm") ); + output( "\tset %d, %%g1\n", (idx << 16) | j ); + output( "\tb,a %s\n", asm_name("__wine_delay_load_asm") ); break; case CPU_ALPHA: - fprintf( outfile, "\tlda $0,%d($31)\n", j); - fprintf( outfile, "\tldah $0,%d($0)\n", idx); - fprintf( outfile, "\tjmp $31,%s\n", asm_name("__wine_delay_load_asm") ); + output( "\tlda $0,%d($31)\n", j); + output( "\tldah $0,%d($0)\n", idx); + output( "\tjmp $31,%s\n", asm_name("__wine_delay_load_asm") ); break; case CPU_POWERPC: switch(target_platform) @@ -1086,24 +1089,24 @@ static void output_delayed_import_thunks( FILE *outfile, const DLLSPEC *spec ) case PLATFORM_APPLE: /* On Darwin we can use r0 and r2 */ /* Upper part in r2 */ - fprintf( outfile, "\tlis %s, %d\n", ppc_reg(2), idx); + output( "\tlis %s, %d\n", ppc_reg(2), idx); /* Lower part + r2 -> r0, Note we can't use r0 directly */ - fprintf( outfile, "\taddi %s, %s, %d\n", ppc_reg(0), ppc_reg(2), j); - fprintf( outfile, "\tb %s\n", asm_name("__wine_delay_load_asm") ); + output( "\taddi %s, %s, %d\n", ppc_reg(0), ppc_reg(2), j); + output( "\tb %s\n", asm_name("__wine_delay_load_asm") ); break; default: /* 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", ppc_reg(1), ppc_reg(1)); - fprintf( outfile, "\tstw %s, 0(%s)\n", ppc_reg(13), ppc_reg(1)); + output( "\taddi %s, %s, -0x4\n", ppc_reg(1), ppc_reg(1)); + output( "\tstw %s, 0(%s)\n", ppc_reg(13), ppc_reg(1)); /* Upper part in r13 */ - fprintf( outfile, "\tlis %s, %d\n", ppc_reg(13), idx); + output( "\tlis %s, %d\n", ppc_reg(13), idx); /* Lower part + r13 -> r0, Note we can't use r0 directly */ - fprintf( outfile, "\taddi %s, %s, %d\n", ppc_reg(0), ppc_reg(13), j); + output( "\taddi %s, %s, %d\n", ppc_reg(0), ppc_reg(13), j); /* Restore r13 */ - fprintf( outfile, "\tstw %s, 0(%s)\n", ppc_reg(13), ppc_reg(1)); - fprintf( outfile, "\taddic %s, %s, 0x4\n", ppc_reg(1), ppc_reg(1)); - fprintf( outfile, "\tb %s\n", asm_name("__wine_delay_load_asm") ); + output( "\tstw %s, 0(%s)\n", ppc_reg(13), ppc_reg(1)); + output( "\taddic %s, %s, 0x4\n", ppc_reg(1), ppc_reg(1)); + output( "\tb %s\n", asm_name("__wine_delay_load_asm") ); break; } break; @@ -1111,25 +1114,25 @@ static void output_delayed_import_thunks( FILE *outfile, const DLLSPEC *spec ) } idx++; } - output_function_size( outfile, delayed_import_loaders ); + output_function_size( delayed_import_loaders ); - fprintf( outfile, "\n\t.align %d\n", get_alignment(get_ptr_size()) ); - fprintf( outfile, "%s:\n", asm_name(delayed_import_thunks)); + output( "\n\t.align %d\n", get_alignment(get_ptr_size()) ); + output( "%s:\n", asm_name(delayed_import_thunks)); for (i = pos = 0; i < nb_imports; i++) { if (!dll_imports[i]->delay) continue; for (j = 0; j < dll_imports[i]->nb_imports; j++, pos += get_ptr_size()) { ORDDEF *odp = dll_imports[i]->imports[j]; - output_import_thunk( outfile, odp->name ? odp->name : odp->export_name, + output_import_thunk( odp->name ? odp->name : odp->export_name, ".L__wine_delay_IAT", pos ); } } - output_function_size( outfile, delayed_import_thunks ); + output_function_size( delayed_import_thunks ); } /* output import stubs for exported entry points that link to external symbols */ -static void output_external_link_imports( FILE *outfile, DLLSPEC *spec ) +static void output_external_link_imports( DLLSPEC *spec ) { unsigned int i, pos; @@ -1144,25 +1147,25 @@ static void output_external_link_imports( FILE *outfile, DLLSPEC *spec ) remove_name( &ext_link_imports, i-- ); } - fprintf( outfile, "\n/* external link thunks */\n\n" ); - fprintf( outfile, "\t.data\n" ); - fprintf( outfile, "\t.align %d\n", get_alignment(get_ptr_size()) ); - fprintf( outfile, ".L__wine_spec_external_links:\n" ); + output( "\n/* external link thunks */\n\n" ); + output( "\t.data\n" ); + output( "\t.align %d\n", get_alignment(get_ptr_size()) ); + output( ".L__wine_spec_external_links:\n" ); for (i = 0; i < ext_link_imports.count; i++) - fprintf( outfile, "\t%s %s\n", get_asm_ptr_keyword(), asm_name(ext_link_imports.names[i]) ); + output( "\t%s %s\n", get_asm_ptr_keyword(), asm_name(ext_link_imports.names[i]) ); - fprintf( outfile, "\n\t.text\n" ); - fprintf( outfile, "\t.align %d\n", get_alignment(get_ptr_size()) ); - fprintf( outfile, "%s:\n", asm_name("__wine_spec_external_link_thunks") ); + output( "\n\t.text\n" ); + output( "\t.align %d\n", get_alignment(get_ptr_size()) ); + output( "%s:\n", asm_name("__wine_spec_external_link_thunks") ); for (i = pos = 0; i < ext_link_imports.count; i++) { char buffer[256]; sprintf( buffer, "__wine_spec_ext_link_%s", ext_link_imports.names[i] ); - output_import_thunk( outfile, buffer, ".L__wine_spec_external_links", pos ); + output_import_thunk( buffer, ".L__wine_spec_external_links", pos ); pos += get_ptr_size(); } - output_function_size( outfile, "__wine_spec_external_link_thunks" ); + output_function_size( "__wine_spec_external_link_thunks" ); } /******************************************************************* @@ -1170,81 +1173,95 @@ static void output_external_link_imports( FILE *outfile, DLLSPEC *spec ) * * Output the functions for stub entry points */ -void output_stubs( FILE *outfile, DLLSPEC *spec ) +void output_stubs( DLLSPEC *spec ) { const char *name, *exp_name; - int i, pos; + int i, count; if (!has_stubs( spec )) return; - fprintf( outfile, "\n/* stub functions */\n\n" ); - fprintf( outfile, "\t.text\n" ); + output( "\n/* stub functions */\n\n" ); + output( "\t.text\n" ); - for (i = pos = 0; i < spec->nb_entry_points; i++) + for (i = count = 0; i < spec->nb_entry_points; i++) { ORDDEF *odp = &spec->entry_points[i]; if (odp->type != TYPE_STUB) continue; name = get_stub_name( odp, spec ); exp_name = odp->name ? odp->name : odp->export_name; - fprintf( outfile, "\t.align %d\n", get_alignment(4) ); - fprintf( outfile, "\t%s\n", func_declaration(name) ); - fprintf( outfile, "%s:\n", asm_name(name) ); - fprintf( outfile, "\tsubl $4,%%esp\n" ); + output( "\t.align %d\n", get_alignment(4) ); + output( "\t%s\n", func_declaration(name) ); + output( "%s:\n", asm_name(name) ); + /* flesh out the stub a bit to make safedisc happy */ + output(" \tnop\n" ); + output(" \tnop\n" ); + output(" \tnop\n" ); + output(" \tnop\n" ); + output(" \tnop\n" ); + output(" \tnop\n" ); + output(" \tnop\n" ); + output(" \tnop\n" ); + output(" \tnop\n" ); + + output( "\tsubl $4,%%esp\n" ); if (UsePIC) { - fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") ); - fprintf( outfile, "1:" ); + output( "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") ); + output( "1:" ); if (exp_name) { - fprintf( outfile, "\tleal .L__wine_stub_strings+%d-1b(%%eax),%%ecx\n", pos ); - fprintf( outfile, "\tpushl %%ecx\n" ); - pos += strlen(exp_name) + 1; + output( "\tleal .L%s_string-1b(%%eax),%%ecx\n", name ); + output( "\tpushl %%ecx\n" ); + count++; } else - fprintf( outfile, "\tpushl $%d\n", odp->ordinal ); - fprintf( outfile, "\tleal .L__wine_spec_file_name-1b(%%eax),%%ecx\n" ); - fprintf( outfile, "\tpushl %%ecx\n" ); + output( "\tpushl $%d\n", odp->ordinal ); + output( "\tleal .L__wine_spec_file_name-1b(%%eax),%%ecx\n" ); + output( "\tpushl %%ecx\n" ); } else { if (exp_name) { - fprintf( outfile, "\tpushl $.L__wine_stub_strings+%d\n", pos ); - pos += strlen(exp_name) + 1; + output( "\tpushl $.L%s_string\n", name ); + count++; } else - fprintf( outfile, "\tpushl $%d\n", odp->ordinal ); - fprintf( outfile, "\tpushl $.L__wine_spec_file_name\n" ); + output( "\tpushl $%d\n", odp->ordinal ); + output( "\tpushl $.L__wine_spec_file_name\n" ); } - fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_unimplemented_stub") ); - output_function_size( outfile, name ); + output( "\tcall %s\n", asm_name("__wine_spec_unimplemented_stub") ); + output_function_size( name ); } - if (pos) + if (count) { - fprintf( outfile, "\t%s\n", get_asm_string_section() ); - fprintf( outfile, ".L__wine_stub_strings:\n" ); + output( "\t%s\n", get_asm_string_section() ); for (i = 0; i < spec->nb_entry_points; i++) { ORDDEF *odp = &spec->entry_points[i]; if (odp->type != TYPE_STUB) continue; exp_name = odp->name ? odp->name : odp->export_name; if (exp_name) - fprintf( outfile, "\t%s \"%s\"\n", get_asm_string_keyword(), exp_name ); + { + name = get_stub_name( odp, spec ); + output( ".L%s_string:\n", name ); + output( "\t%s \"%s\"\n", get_asm_string_keyword(), exp_name ); + } } } } /* output the import and delayed import tables of a Win32 module */ -void output_imports( FILE *outfile, DLLSPEC *spec ) +void output_imports( DLLSPEC *spec ) { - output_immediate_imports( outfile ); - output_delayed_imports( outfile, spec ); - output_immediate_import_thunks( outfile ); - output_delayed_import_thunks( outfile, spec ); - output_external_link_imports( outfile, spec ); + output_immediate_imports(); + output_delayed_imports( spec ); + output_immediate_import_thunks(); + output_delayed_import_thunks( spec ); + output_external_link_imports( spec ); if (nb_imports || ext_link_imports.count || has_stubs(spec) || has_relays(spec)) - output_get_pc_thunk( outfile ); + output_get_pc_thunk(); } diff --git a/reactos/tools/winebuild/main.c b/reactos/tools/winebuild/main.c index e9750412ba4..88a3a7dd664 100644 --- a/reactos/tools/winebuild/main.c +++ b/reactos/tools/winebuild/main.c @@ -19,16 +19,14 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include "config.h" +#include "wine/port.h" #include #include -#ifdef WIN32 -#include /* unlink() */ -#endif//WIN32 #include #include #include @@ -38,7 +36,8 @@ # include #endif -#include "winglue.h" +#include "windef.h" +#include "winbase.h" #include "build.h" int UsePIC = 0; @@ -48,8 +47,9 @@ int display_warnings = 0; int kill_at = 0; int verbose = 0; int save_temps = 0; +int link_ext_symbols = 0; -#if defined(__i386__) || defined(__x86_64__) +#ifdef __i386__ enum target_cpu target_cpu = CPU_x86; #elif defined(__x86_64__) enum target_cpu target_cpu = CPU_x86_64; @@ -65,8 +65,6 @@ enum target_cpu target_cpu = CPU_POWERPC; #ifdef __APPLE__ enum target_platform target_platform = PLATFORM_APPLE; -#elif defined(__svr4__) -enum target_platform target_platform = PLATFORM_SVR4; #elif defined(_WINDOWS) enum target_platform target_platform = PLATFORM_WINDOWS; #else @@ -77,6 +75,7 @@ char **lib_path = NULL; char *input_file_name = NULL; char *spec_file_name = NULL; +FILE *output_file = NULL; const char *output_file_name = NULL; static const char *output_file_source_name; @@ -84,7 +83,6 @@ char *as_command = NULL; char *ld_command = NULL; char *nm_command = NULL; -static FILE *output_file; static int nb_res_files; static char **res_files; @@ -127,7 +125,6 @@ static const struct { { "macos", PLATFORM_APPLE }, { "darwin", PLATFORM_APPLE }, - { "sunos", PLATFORM_SVR4 }, { "windows", PLATFORM_WINDOWS }, { "winnt", PLATFORM_WINDOWS } }; @@ -248,8 +245,9 @@ static const char usage_str[] = " --as-cmd=AS Command to use for assembling (default: as)\n" " -d, --delay-lib=LIB Import the specified library in delayed mode\n" " -D SYM Ignored for C flags compatibility\n" -" -E, --export=FILE Export the symbols defined in the .spec or .def file\n" " -e, --entry=FUNC Set the DLL entry point function (default: DllMain)\n" +" -E, --export=FILE Export the symbols defined in the .spec or .def file\n" +" --external-symbols Allow linking to external symbols\n" " -f FLAGS Compiler flags (only -fPIC is supported)\n" " -F, --filename=DLLFILE Set the DLL filename (default: from input file name)\n" " -h, --help Display this help message\n" @@ -263,6 +261,7 @@ static const char usage_str[] = " -L, --library-path=DIR Look for imports libraries in DIR\n" " -M, --main-module=MODULE Set the name of the main module for a Win16 dll\n" " --nm-cmd=NM Command to use to get undefined symbols (default: nm)\n" +" --nxcompat=y|n Set the NX compatibility flag (default: yes)\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" @@ -278,7 +277,7 @@ static const char usage_str[] = " --def Build a .def file from a .spec file\n" " --exe Build a .c file for an executable\n" " --relay16 Build the 16-bit relay assembly routines\n" -" --relay32 Build the 32-bit relay assembly routines\n" +" --relay32 Build the 32-bit relay assembly routines\n\n" " --pedll Build a .c file for PE dll\n\n" "The mode options are mutually exclusive; you must specify one and only one.\n\n"; @@ -288,14 +287,16 @@ enum long_options_values LONG_OPT_DEF, LONG_OPT_EXE, LONG_OPT_ASCMD, + LONG_OPT_EXTERNAL_SYMS, LONG_OPT_LDCMD, LONG_OPT_NMCMD, + LONG_OPT_NXCOMPAT, LONG_OPT_RELAY16, LONG_OPT_RELAY32, LONG_OPT_SAVE_TEMPS, LONG_OPT_SUBSYSTEM, - LONG_OPT_VERSION, LONG_OPT_TARGET, + LONG_OPT_VERSION, LONG_OPT_PEDLL }; @@ -303,19 +304,21 @@ static const char short_options[] = "C:D:E:F:H:I:K:L:M:N:d:e:f:hi:kl:m:o:r:u:vw" static const struct option long_options[] = { - { "dll", 0, 0, LONG_OPT_DLL }, - { "def", 0, 0, LONG_OPT_DEF }, - { "exe", 0, 0, LONG_OPT_EXE }, - { "as-cmd", 1, 0, LONG_OPT_ASCMD }, - { "ld-cmd", 1, 0, LONG_OPT_LDCMD }, - { "nm-cmd", 1, 0, LONG_OPT_NMCMD }, - { "relay16", 0, 0, LONG_OPT_RELAY16 }, - { "relay32", 0, 0, LONG_OPT_RELAY32 }, - { "save-temps",0, 0, LONG_OPT_SAVE_TEMPS }, - { "subsystem",1, 0, LONG_OPT_SUBSYSTEM }, - { "target", 1, 0, LONG_OPT_TARGET }, - { "version", 0, 0, LONG_OPT_VERSION }, - { "pedll", 1, 0, LONG_OPT_PEDLL }, + { "dll", 0, 0, LONG_OPT_DLL }, + { "def", 0, 0, LONG_OPT_DEF }, + { "exe", 0, 0, LONG_OPT_EXE }, + { "as-cmd", 1, 0, LONG_OPT_ASCMD }, + { "external-symbols", 0, 0, LONG_OPT_EXTERNAL_SYMS }, + { "ld-cmd", 1, 0, LONG_OPT_LDCMD }, + { "nm-cmd", 1, 0, LONG_OPT_NMCMD }, + { "nxcompat", 1, 0, LONG_OPT_NXCOMPAT }, + { "relay16", 0, 0, LONG_OPT_RELAY16 }, + { "relay32", 0, 0, LONG_OPT_RELAY32 }, + { "save-temps", 0, 0, LONG_OPT_SAVE_TEMPS }, + { "subsystem", 1, 0, LONG_OPT_SUBSYSTEM }, + { "target", 1, 0, LONG_OPT_TARGET }, + { "version", 0, 0, LONG_OPT_VERSION }, + { "pedll", 1, 0, LONG_OPT_PEDLL }, /* aliases for short options */ { "delay-lib", 1, 0, 'd' }, { "export", 1, 0, 'E' }, @@ -471,12 +474,19 @@ static char **parse_options( int argc, char **argv, DLLSPEC *spec ) case LONG_OPT_ASCMD: as_command = xstrdup( optarg ); break; + case LONG_OPT_EXTERNAL_SYMS: + link_ext_symbols = 1; + break; case LONG_OPT_LDCMD: ld_command = xstrdup( optarg ); break; case LONG_OPT_NMCMD: nm_command = xstrdup( optarg ); break; + case LONG_OPT_NXCOMPAT: + if (optarg[0] == 'n' || optarg[0] == 'N') + spec->dll_characteristics &= ~IMAGE_DLLCHARACTERISTICS_NX_COMPAT; + break; case LONG_OPT_RELAY16: set_exec_mode( MODE_RELAY16 ); break; @@ -564,6 +574,7 @@ static int parse_input_file( DLLSPEC *spec ) char *extension = strrchr( spec_file_name, '.' ); int result; + spec->src_name = xstrdup( input_file_name ); if (extension && !strcmp( extension, ".def" )) result = parse_def_file( input_file, spec ); else @@ -592,7 +603,8 @@ int main(int argc, char **argv) switch(exec_mode) { case MODE_DLL: - spec->characteristics |= IMAGE_FILE_DLL; + if (spec->subsystem != IMAGE_SUBSYSTEM_NATIVE) + spec->characteristics |= IMAGE_FILE_DLL; load_resources( argv, spec ); load_import_libs( argv ); if (!spec_file_name) fatal_error( "missing .spec file\n" ); @@ -604,7 +616,7 @@ int main(int argc, char **argv) break; case SPEC_WIN32: read_undef_symbols( spec, argv ); - BuildSpec32File( output_file, spec ); + BuildSpec32File( spec ); break; default: assert(0); } @@ -616,14 +628,14 @@ int main(int argc, char **argv) load_import_libs( argv ); if (spec_file_name && !parse_input_file( spec )) break; read_undef_symbols( spec, argv ); - BuildSpec32File( output_file, spec ); + BuildSpec32File( spec ); break; case MODE_DEF: if (argv[0]) fatal_error( "file argument '%s' not allowed in this mode\n", argv[0] ); if (spec->type == SPEC_WIN16) fatal_error( "Cannot yet build .def file for 16-bit dlls\n" ); if (!spec_file_name) fatal_error( "missing .spec file\n" ); if (!parse_input_file( spec )) break; - BuildDef32File( output_file, spec ); + BuildDef32File( spec ); break; case MODE_RELAY16: fatal_error( "Win16 relays are not supported in ReactOS version of winebuild\n" ); @@ -634,7 +646,7 @@ int main(int argc, char **argv) case MODE_PEDLL: if (argv[0]) fatal_error( "file argument '%s' not allowed in this mode\n", argv[0] ); if (!parse_input_file( spec )) break; - BuildPedllFile( output_file, spec ); + BuildPedllFile( spec ); break; default: usage(1); @@ -643,7 +655,7 @@ int main(int argc, char **argv) if (nb_errors) exit(1); if (output_file_name) { - fclose( output_file ); + if (fclose( output_file ) < 0) fatal_perror( "fclose" ); if (output_file_source_name) assemble_file( output_file_source_name, output_file_name ); output_file_name = NULL; } diff --git a/reactos/tools/winebuild/parser.c b/reactos/tools/winebuild/parser.c index 1ea33766523..bcbf9510be9 100644 --- a/reactos/tools/winebuild/parser.c +++ b/reactos/tools/winebuild/parser.c @@ -19,10 +19,11 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include "config.h" +#include "wine/port.h" #include #include @@ -31,7 +32,8 @@ #include #include -#include "winglue.h" +#include "windef.h" +#include "winbase.h" #include "build.h" int current_line = 0; @@ -44,6 +46,9 @@ static FILE *input_file; static const char *separator_chars; static const char *comment_chars; +/* valid characters in ordinal names */ +static const char valid_ordname_chars[] = "/$:-_@?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + static const char * const TypeNames[TYPE_NBTYPES] = { "variable", /* TYPE_VARIABLE */ @@ -65,6 +70,7 @@ static const char * const FlagNames[] = "i386", /* FLAG_I386 */ "register", /* FLAG_REGISTER */ "private", /* FLAG_PRIVATE */ + "ordinal", /* FLAG_ORDINAL */ NULL }; @@ -74,12 +80,12 @@ static int IsNumberString(const char *s) return 1; } -inline static int is_token_separator( char ch ) +static inline int is_token_separator( char ch ) { return strchr( separator_chars, ch ) != NULL; } -inline static int is_token_comment( char ch ) +static inline int is_token_comment( char ch ) { return strchr( comment_chars, ch ) != NULL; } @@ -445,6 +451,7 @@ static const char *parse_spec_flags( ORDDEF *odp ) static int parse_spec_ordinal( int ordinal, DLLSPEC *spec ) { const char *token; + size_t len; ORDDEF *odp = add_entry_point( spec ); memset( odp, 0, sizeof(*odp) ); @@ -468,6 +475,13 @@ static int parse_spec_ordinal( int ordinal, DLLSPEC *spec ) odp->lineno = current_line; odp->ordinal = ordinal; + len = strspn( odp->name, valid_ordname_chars ); + if (len < strlen( odp->name )) + { + error( "Character '%c' is not allowed in exported name '%s'\n", odp->name[len], odp->name ); + goto error; + } + switch(odp->type) { case TYPE_VARIABLE: @@ -532,11 +546,14 @@ static int parse_spec_ordinal( int ordinal, DLLSPEC *spec ) } } - if (!strcmp( odp->name, "@" ) || odp->flags & FLAG_NONAME) + if (!strcmp( odp->name, "@" ) || odp->flags & (FLAG_NONAME | FLAG_ORDINAL)) { if (ordinal == -1) { - error( "Nameless function needs an explicit ordinal number\n" ); + if (!strcmp( odp->name, "@" )) + error( "Nameless function needs an explicit ordinal number\n" ); + else + error( "Function imported by ordinal needs an explicit ordinal number\n" ); goto error; } if (spec->type != SPEC_WIN32) @@ -544,9 +561,16 @@ static int parse_spec_ordinal( int ordinal, DLLSPEC *spec ) error( "Nameless functions not supported for Win16\n" ); goto error; } - if (!strcmp( odp->name, "@" )) free( odp->name ); - else odp->export_name = odp->name; - odp->name = NULL; + if (!strcmp( odp->name, "@" )) + { + free( odp->name ); + odp->name = NULL; + } + else if (!(odp->flags & FLAG_ORDINAL)) /* -ordinal only affects the import library */ + { + odp->export_name = odp->name; + odp->name = NULL; + } } return 1; diff --git a/reactos/tools/winebuild/relay.c b/reactos/tools/winebuild/relay.c index dd3b9c07c20..0ddcc55f51e 100644 --- a/reactos/tools/winebuild/relay.c +++ b/reactos/tools/winebuild/relay.c @@ -19,10 +19,11 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include "config.h" +#include "wine/port.h" #include @@ -31,19 +32,32 @@ #include "build.h" -static void function_header( FILE *outfile, const char *name ) +/* offset of a structure field relative to the start of the struct */ +#define STRUCTOFFSET(type,field) ((int)FIELD_OFFSET(type,field)) + +/* offset of register relative to the start of the CONTEXT struct */ +#define CONTEXTOFFSET(reg) STRUCTOFFSET(CONTEXT86,reg) + +/* offset of register relative to the start of the STACK16FRAME struct */ +#define STACK16OFFSET(reg) STRUCTOFFSET(STACK16FRAME,reg) + +/* offset of register relative to the start of the STACK32FRAME struct */ +#define STACK32OFFSET(reg) STRUCTOFFSET(STACK32FRAME,reg) + +/* offset of the stack pointer relative to %fs:(0) */ +#define STACKOFFSET 0xc0 /* STRUCTOFFSET(TEB,WOW32Reserved) */ + +/* fix this if the ntdll_thread_regs structure is changed */ +#define GS_OFFSET 0x1d8 /* STRUCTOFFSET(TEB,SystemReserved2) + STRUCTOFFSET(ntdll_thread_data,gs) */ + +static void function_header( const char *name ) { - fprintf( outfile, "\n\t.align %d\n", get_alignment(4) ); - fprintf( outfile, "\t%s\n", func_declaration(name) ); - fprintf( outfile, "%s\n", asm_globl(name) ); + output( "\n\t.align %d\n", get_alignment(4) ); + output( "\t%s\n", func_declaration(name) ); + output( "%s\n", asm_globl(name) ); } -static inline const char *data16_prefix(void) -{ - return (target_platform == PLATFORM_SVR4) ? "\tdata16\n" : ""; -} - /******************************************************************* * BuildCallFrom16Core * @@ -111,74 +125,73 @@ static inline const char *data16_prefix(void) * (sp-20) long saved edx * (sp-24) long saved previous stack */ -static void BuildCallFrom16Core( FILE *outfile, int reg_func, int thunk ) +static void BuildCallFrom16Core( int reg_func, int thunk ) { /* Function header */ - if (thunk) function_header( outfile, "__wine_call_from_16_thunk" ); - else if (reg_func) function_header( outfile, "__wine_call_from_16_regs" ); - else function_header( outfile, "__wine_call_from_16" ); + if (thunk) function_header( "__wine_call_from_16_thunk" ); + else if (reg_func) function_header( "__wine_call_from_16_regs" ); + else function_header( "__wine_call_from_16" ); /* Create STACK16FRAME (except STACK32FRAME link) */ - fprintf( outfile, "\tpushw %%gs\n" ); - fprintf( outfile, "\tpushw %%fs\n" ); - fprintf( outfile, "\tpushw %%es\n" ); - fprintf( outfile, "\tpushw %%ds\n" ); - fprintf( outfile, "\tpushl %%ebp\n" ); - fprintf( outfile, "\tpushl %%ecx\n" ); - fprintf( outfile, "\tpushl %%edx\n" ); + output( "\tpushw %%gs\n" ); + output( "\tpushw %%fs\n" ); + output( "\tpushw %%es\n" ); + output( "\tpushw %%ds\n" ); + output( "\tpushl %%ebp\n" ); + output( "\tpushl %%ecx\n" ); + output( "\tpushl %%edx\n" ); /* Save original EFlags register */ - if (reg_func) fprintf( outfile, "\tpushfl\n" ); + if (reg_func) output( "\tpushfl\n" ); if ( UsePIC ) { - fprintf( outfile, "\tcall 1f\n" ); - fprintf( outfile, "1:\tpopl %%ecx\n" ); - fprintf( outfile, "\t.byte 0x2e\n\tmovl %s-1b(%%ecx),%%edx\n", - asm_name("CallTo16_DataSelector") ); + output( "\tcall 1f\n" ); + output( "1:\tpopl %%ecx\n" ); + output( "\t.byte 0x2e\n\tmovl %s-1b(%%ecx),%%edx\n", asm_name("CallTo16_DataSelector") ); } else - fprintf( outfile, "\t.byte 0x2e\n\tmovl %s,%%edx\n", asm_name("CallTo16_DataSelector") ); + output( "\t.byte 0x2e\n\tmovl %s,%%edx\n", asm_name("CallTo16_DataSelector") ); /* Load 32-bit segment registers */ - fprintf( outfile, "%s\tmovw %%dx, %%ds\n", data16_prefix() ); - fprintf( outfile, "%s\tmovw %%dx, %%es\n", data16_prefix() ); + output( "\tmovw %%dx, %%ds\n" ); + output( "\tmovw %%dx, %%es\n" ); if ( UsePIC ) - fprintf( outfile, "\tmovw %s-1b(%%ecx), %%fs\n", asm_name("CallTo16_TebSelector") ); + output( "\tmovw %s-1b(%%ecx), %%fs\n", asm_name("CallTo16_TebSelector") ); else - fprintf( outfile, "\tmovw %s, %%fs\n", asm_name("CallTo16_TebSelector") ); + output( "\tmovw %s, %%fs\n", asm_name("CallTo16_TebSelector") ); - fprintf( outfile, "\t.byte 0x64\n\tmov (%d),%%gs\n", STRUCTOFFSET(TEB,gs_sel) ); + output( "\t.byte 0x64\n\tmov (%d),%%gs\n", GS_OFFSET ); /* Translate STACK16FRAME base to flat offset in %edx */ - fprintf( outfile, "\tmovw %%ss, %%dx\n" ); - fprintf( outfile, "\tandl $0xfff8, %%edx\n" ); - fprintf( outfile, "\tshrl $1, %%edx\n" ); + output( "\tmovw %%ss, %%dx\n" ); + output( "\tandl $0xfff8, %%edx\n" ); + output( "\tshrl $1, %%edx\n" ); if (UsePIC) { - fprintf( outfile, "\taddl wine_ldt_copy_ptr-1b(%%ecx),%%edx\n" ); - fprintf( outfile, "\tmovl (%%edx), %%edx\n" ); + output( "\taddl wine_ldt_copy_ptr-1b(%%ecx),%%edx\n" ); + output( "\tmovl (%%edx), %%edx\n" ); } else - fprintf( outfile, "\tmovl %s(%%edx), %%edx\n", asm_name("wine_ldt_copy") ); - fprintf( outfile, "\tmovzwl %%sp, %%ebp\n" ); - fprintf( outfile, "\tleal %d(%%ebp,%%edx), %%edx\n", reg_func ? 0 : -4 ); + output( "\tmovl %s(%%edx), %%edx\n", asm_name("wine_ldt_copy") ); + output( "\tmovzwl %%sp, %%ebp\n" ); + output( "\tleal %d(%%ebp,%%edx), %%edx\n", reg_func ? 0 : -4 ); /* Get saved flags into %ecx */ - if (reg_func) fprintf( outfile, "\tpopl %%ecx\n" ); + if (reg_func) output( "\tpopl %%ecx\n" ); /* Get the 32-bit stack pointer from the TEB and complete STACK16FRAME */ - fprintf( outfile, "\t.byte 0x64\n\tmovl (%d), %%ebp\n", STACKOFFSET ); - fprintf( outfile, "\tpushl %%ebp\n" ); + output( "\t.byte 0x64\n\tmovl (%d), %%ebp\n", STACKOFFSET ); + output( "\tpushl %%ebp\n" ); /* Switch stacks */ - fprintf( outfile, "%s\t.byte 0x64\n\tmovw %%ss, (%d)\n", data16_prefix(), STACKOFFSET + 2 ); - fprintf( outfile, "\t.byte 0x64\n\tmovw %%sp, (%d)\n", STACKOFFSET ); - fprintf( outfile, "\tpushl %%ds\n" ); - fprintf( outfile, "\tpopl %%ss\n" ); - fprintf( outfile, "\tmovl %%ebp, %%esp\n" ); - fprintf( outfile, "\taddl $%d, %%ebp\n", STRUCTOFFSET(STACK32FRAME, ebp) ); + output( "\t.byte 0x64\n\tmovw %%ss, (%d)\n", STACKOFFSET + 2 ); + output( "\t.byte 0x64\n\tmovw %%sp, (%d)\n", STACKOFFSET ); + output( "\tpushl %%ds\n" ); + output( "\tpopl %%ss\n" ); + output( "\tmovl %%ebp, %%esp\n" ); + output( "\taddl $%d, %%ebp\n", STACK32OFFSET(ebp) ); /* At this point: @@ -195,32 +208,32 @@ static void BuildCallFrom16Core( FILE *outfile, int reg_func, int thunk ) if ( thunk ) { /* Set up registers as expected and call thunk */ - fprintf( outfile, "\tleal %d(%%edx), %%ebx\n", sizeof(STACK16FRAME)-22 ); - fprintf( outfile, "\tleal -4(%%esp), %%ebp\n" ); + output( "\tleal %d(%%edx), %%ebx\n", (int)sizeof(STACK16FRAME)-22 ); + output( "\tleal -4(%%esp), %%ebp\n" ); - fprintf( outfile, "\tcall *%d(%%edx)\n", STACK16OFFSET(entry_point) ); + output( "\tcall *%d(%%edx)\n", STACK16OFFSET(entry_point) ); /* Switch stack back */ - fprintf( outfile, "\t.byte 0x64\n\tmovw (%d), %%ss\n", STACKOFFSET+2 ); - fprintf( outfile, "\t.byte 0x64\n\tmovzwl (%d), %%esp\n", STACKOFFSET ); - fprintf( outfile, "\t.byte 0x64\n\tpopl (%d)\n", STACKOFFSET ); + output( "\t.byte 0x64\n\tmovw (%d), %%ss\n", STACKOFFSET+2 ); + output( "\t.byte 0x64\n\tmovzwl (%d), %%esp\n", STACKOFFSET ); + output( "\t.byte 0x64\n\tpopl (%d)\n", STACKOFFSET ); /* Restore registers and return directly to caller */ - fprintf( outfile, "\taddl $8, %%esp\n" ); - fprintf( outfile, "\tpopl %%ebp\n" ); - fprintf( outfile, "\tpopw %%ds\n" ); - fprintf( outfile, "\tpopw %%es\n" ); - fprintf( outfile, "\tpopw %%fs\n" ); - fprintf( outfile, "\tpopw %%gs\n" ); - fprintf( outfile, "\taddl $20, %%esp\n" ); + output( "\taddl $8, %%esp\n" ); + output( "\tpopl %%ebp\n" ); + output( "\tpopw %%ds\n" ); + output( "\tpopw %%es\n" ); + output( "\tpopw %%fs\n" ); + output( "\tpopw %%gs\n" ); + output( "\taddl $20, %%esp\n" ); - fprintf( outfile, "\txorb %%ch, %%ch\n" ); - fprintf( outfile, "\tpopl %%ebx\n" ); - fprintf( outfile, "\taddw %%cx, %%sp\n" ); - fprintf( outfile, "\tpush %%ebx\n" ); + output( "\txorb %%ch, %%ch\n" ); + output( "\tpopl %%ebx\n" ); + output( "\taddw %%cx, %%sp\n" ); + output( "\tpush %%ebx\n" ); - fprintf( outfile, "\t.byte 0x66\n" ); - fprintf( outfile, "\tlret\n" ); + output( "\t.byte 0x66\n" ); + output( "\tlret\n" ); return; } @@ -229,132 +242,131 @@ static void BuildCallFrom16Core( FILE *outfile, int reg_func, int thunk ) /* Build register CONTEXT */ if ( reg_func ) { - fprintf( outfile, "\tsubl $%d, %%esp\n", sizeof(CONTEXT86) ); + output( "\tsubl $%d, %%esp\n", (int)sizeof(CONTEXT86) ); - fprintf( outfile, "\tmovl %%ecx, %d(%%esp)\n", CONTEXTOFFSET(EFlags) ); + output( "\tmovl %%ecx, %d(%%esp)\n", CONTEXTOFFSET(EFlags) ); - fprintf( outfile, "\tmovl %%eax, %d(%%esp)\n", CONTEXTOFFSET(Eax) ); - fprintf( outfile, "\tmovl %%ebx, %d(%%esp)\n", CONTEXTOFFSET(Ebx) ); - fprintf( outfile, "\tmovl %%esi, %d(%%esp)\n", CONTEXTOFFSET(Esi) ); - fprintf( outfile, "\tmovl %%edi, %d(%%esp)\n", CONTEXTOFFSET(Edi) ); + output( "\tmovl %%eax, %d(%%esp)\n", CONTEXTOFFSET(Eax) ); + output( "\tmovl %%ebx, %d(%%esp)\n", CONTEXTOFFSET(Ebx) ); + output( "\tmovl %%esi, %d(%%esp)\n", CONTEXTOFFSET(Esi) ); + output( "\tmovl %%edi, %d(%%esp)\n", CONTEXTOFFSET(Edi) ); - fprintf( outfile, "\tmovl %d(%%edx), %%eax\n", STACK16OFFSET(ebp) ); - fprintf( outfile, "\tmovl %%eax, %d(%%esp)\n", CONTEXTOFFSET(Ebp) ); - fprintf( outfile, "\tmovl %d(%%edx), %%eax\n", STACK16OFFSET(ecx) ); - fprintf( outfile, "\tmovl %%eax, %d(%%esp)\n", CONTEXTOFFSET(Ecx) ); - fprintf( outfile, "\tmovl %d(%%edx), %%eax\n", STACK16OFFSET(edx) ); - fprintf( outfile, "\tmovl %%eax, %d(%%esp)\n", CONTEXTOFFSET(Edx) ); + output( "\tmovl %d(%%edx), %%eax\n", STACK16OFFSET(ebp) ); + output( "\tmovl %%eax, %d(%%esp)\n", CONTEXTOFFSET(Ebp) ); + output( "\tmovl %d(%%edx), %%eax\n", STACK16OFFSET(ecx) ); + output( "\tmovl %%eax, %d(%%esp)\n", CONTEXTOFFSET(Ecx) ); + output( "\tmovl %d(%%edx), %%eax\n", STACK16OFFSET(edx) ); + output( "\tmovl %%eax, %d(%%esp)\n", CONTEXTOFFSET(Edx) ); - fprintf( outfile, "\tmovzwl %d(%%edx), %%eax\n", STACK16OFFSET(ds) ); - fprintf( outfile, "\tmovl %%eax, %d(%%esp)\n", CONTEXTOFFSET(SegDs) ); - fprintf( outfile, "\tmovzwl %d(%%edx), %%eax\n", STACK16OFFSET(es) ); - fprintf( outfile, "\tmovl %%eax, %d(%%esp)\n", CONTEXTOFFSET(SegEs) ); - fprintf( outfile, "\tmovzwl %d(%%edx), %%eax\n", STACK16OFFSET(fs) ); - fprintf( outfile, "\tmovl %%eax, %d(%%esp)\n", CONTEXTOFFSET(SegFs) ); - fprintf( outfile, "\tmovzwl %d(%%edx), %%eax\n", STACK16OFFSET(gs) ); - fprintf( outfile, "\tmovl %%eax, %d(%%esp)\n", CONTEXTOFFSET(SegGs) ); + output( "\tmovzwl %d(%%edx), %%eax\n", STACK16OFFSET(ds) ); + output( "\tmovl %%eax, %d(%%esp)\n", CONTEXTOFFSET(SegDs) ); + output( "\tmovzwl %d(%%edx), %%eax\n", STACK16OFFSET(es) ); + output( "\tmovl %%eax, %d(%%esp)\n", CONTEXTOFFSET(SegEs) ); + output( "\tmovzwl %d(%%edx), %%eax\n", STACK16OFFSET(fs) ); + output( "\tmovl %%eax, %d(%%esp)\n", CONTEXTOFFSET(SegFs) ); + output( "\tmovzwl %d(%%edx), %%eax\n", STACK16OFFSET(gs) ); + output( "\tmovl %%eax, %d(%%esp)\n", CONTEXTOFFSET(SegGs) ); - fprintf( outfile, "\tmovzwl %d(%%edx), %%eax\n", STACK16OFFSET(cs) ); - fprintf( outfile, "\tmovl %%eax, %d(%%esp)\n", CONTEXTOFFSET(SegCs) ); - fprintf( outfile, "\tmovzwl %d(%%edx), %%eax\n", STACK16OFFSET(ip) ); - fprintf( outfile, "\tmovl %%eax, %d(%%esp)\n", CONTEXTOFFSET(Eip) ); + output( "\tmovzwl %d(%%edx), %%eax\n", STACK16OFFSET(cs) ); + output( "\tmovl %%eax, %d(%%esp)\n", CONTEXTOFFSET(SegCs) ); + output( "\tmovzwl %d(%%edx), %%eax\n", STACK16OFFSET(ip) ); + output( "\tmovl %%eax, %d(%%esp)\n", CONTEXTOFFSET(Eip) ); - fprintf( outfile, "\t.byte 0x64\n\tmovzwl (%d), %%eax\n", STACKOFFSET+2 ); - fprintf( outfile, "\tmovl %%eax, %d(%%esp)\n", CONTEXTOFFSET(SegSs) ); - fprintf( outfile, "\t.byte 0x64\n\tmovzwl (%d), %%eax\n", STACKOFFSET ); - fprintf( outfile, "\taddl $%d, %%eax\n", STACK16OFFSET(ip) ); - fprintf( outfile, "\tmovl %%eax, %d(%%esp)\n", CONTEXTOFFSET(Esp) ); + output( "\t.byte 0x64\n\tmovzwl (%d), %%eax\n", STACKOFFSET+2 ); + output( "\tmovl %%eax, %d(%%esp)\n", CONTEXTOFFSET(SegSs) ); + output( "\t.byte 0x64\n\tmovzwl (%d), %%eax\n", STACKOFFSET ); + output( "\taddl $%d, %%eax\n", STACK16OFFSET(ip) ); + output( "\tmovl %%eax, %d(%%esp)\n", CONTEXTOFFSET(Esp) ); #if 0 - fprintf( outfile, "\tfsave %d(%%esp)\n", CONTEXTOFFSET(FloatSave) ); + output( "\tfsave %d(%%esp)\n", CONTEXTOFFSET(FloatSave) ); #endif /* Push address of CONTEXT86 structure -- popped by the relay routine */ - fprintf( outfile, "\tmovl %%esp,%%eax\n" ); - fprintf( outfile, "\tandl $~15,%%esp\n" ); - fprintf( outfile, "\tsubl $4,%%esp\n" ); - fprintf( outfile, "\tpushl %%eax\n" ); + output( "\tmovl %%esp,%%eax\n" ); + output( "\tandl $~15,%%esp\n" ); + output( "\tsubl $4,%%esp\n" ); + output( "\tpushl %%eax\n" ); } else { - fprintf( outfile, "\tsubl $8,%%esp\n" ); - fprintf( outfile, "\tandl $~15,%%esp\n" ); - fprintf( outfile, "\taddl $8,%%esp\n" ); + output( "\tsubl $8,%%esp\n" ); + output( "\tandl $~15,%%esp\n" ); + output( "\taddl $8,%%esp\n" ); } /* Call relay routine (which will call the API entry point) */ - fprintf( outfile, "\tleal %d(%%edx), %%eax\n", sizeof(STACK16FRAME) ); - fprintf( outfile, "\tpushl %%eax\n" ); - fprintf( outfile, "\tpushl %d(%%edx)\n", STACK16OFFSET(entry_point) ); - fprintf( outfile, "\tcall *%d(%%edx)\n", STACK16OFFSET(relay) ); + output( "\tleal %d(%%edx), %%eax\n", (int)sizeof(STACK16FRAME) ); + output( "\tpushl %%eax\n" ); + output( "\tpushl %d(%%edx)\n", STACK16OFFSET(entry_point) ); + output( "\tcall *%d(%%edx)\n", STACK16OFFSET(relay) ); if ( reg_func ) { - fprintf( outfile, "\tleal -%d(%%ebp), %%ebx\n", - sizeof(CONTEXT) + STRUCTOFFSET(STACK32FRAME, ebp) ); + output( "\tleal -%d(%%ebp), %%ebx\n", (int)sizeof(CONTEXT) + STACK32OFFSET(ebp) ); /* Switch stack back */ - fprintf( outfile, "\t.byte 0x64\n\tmovw (%d), %%ss\n", STACKOFFSET+2 ); - fprintf( outfile, "\t.byte 0x64\n\tmovzwl (%d), %%esp\n", STACKOFFSET ); - fprintf( outfile, "\t.byte 0x64\n\tpopl (%d)\n", STACKOFFSET ); + output( "\t.byte 0x64\n\tmovw (%d), %%ss\n", STACKOFFSET+2 ); + output( "\t.byte 0x64\n\tmovzwl (%d), %%esp\n", STACKOFFSET ); + output( "\t.byte 0x64\n\tpopl (%d)\n", STACKOFFSET ); /* Get return address to CallFrom16 stub */ - fprintf( outfile, "\taddw $%d, %%sp\n", STACK16OFFSET(callfrom_ip)-4 ); - fprintf( outfile, "\tpopl %%eax\n" ); - fprintf( outfile, "\tpopl %%edx\n" ); + output( "\taddw $%d, %%sp\n", STACK16OFFSET(callfrom_ip)-4 ); + output( "\tpopl %%eax\n" ); + output( "\tpopl %%edx\n" ); /* Restore all registers from CONTEXT */ - fprintf( outfile, "\tmovw %d(%%ebx), %%ss\n", CONTEXTOFFSET(SegSs) ); - fprintf( outfile, "\tmovl %d(%%ebx), %%esp\n", CONTEXTOFFSET(Esp) ); - fprintf( outfile, "\taddl $4, %%esp\n" ); /* room for final return address */ + output( "\tmovw %d(%%ebx), %%ss\n", CONTEXTOFFSET(SegSs) ); + output( "\tmovl %d(%%ebx), %%esp\n", CONTEXTOFFSET(Esp) ); + output( "\taddl $4, %%esp\n" ); /* room for final return address */ - fprintf( outfile, "\tpushw %d(%%ebx)\n", CONTEXTOFFSET(SegCs) ); - fprintf( outfile, "\tpushw %d(%%ebx)\n", CONTEXTOFFSET(Eip) ); - fprintf( outfile, "\tpushl %%edx\n" ); - fprintf( outfile, "\tpushl %%eax\n" ); - fprintf( outfile, "\tpushl %d(%%ebx)\n", CONTEXTOFFSET(EFlags) ); - fprintf( outfile, "\tpushl %d(%%ebx)\n", CONTEXTOFFSET(SegDs) ); + output( "\tpushw %d(%%ebx)\n", CONTEXTOFFSET(SegCs) ); + output( "\tpushw %d(%%ebx)\n", CONTEXTOFFSET(Eip) ); + output( "\tpushl %%edx\n" ); + output( "\tpushl %%eax\n" ); + output( "\tpushl %d(%%ebx)\n", CONTEXTOFFSET(EFlags) ); + output( "\tpushl %d(%%ebx)\n", CONTEXTOFFSET(SegDs) ); - fprintf( outfile, "\tpushl %d(%%ebx)\n", CONTEXTOFFSET(SegEs) ); - fprintf( outfile, "\tpopl %%es\n" ); - fprintf( outfile, "\tpushl %d(%%ebx)\n", CONTEXTOFFSET(SegFs) ); - fprintf( outfile, "\tpopl %%fs\n" ); - fprintf( outfile, "\tpushl %d(%%ebx)\n", CONTEXTOFFSET(SegGs) ); - fprintf( outfile, "\tpopl %%gs\n" ); + output( "\tpushl %d(%%ebx)\n", CONTEXTOFFSET(SegEs) ); + output( "\tpopl %%es\n" ); + output( "\tpushl %d(%%ebx)\n", CONTEXTOFFSET(SegFs) ); + output( "\tpopl %%fs\n" ); + output( "\tpushl %d(%%ebx)\n", CONTEXTOFFSET(SegGs) ); + output( "\tpopl %%gs\n" ); - fprintf( outfile, "\tmovl %d(%%ebx), %%ebp\n", CONTEXTOFFSET(Ebp) ); - fprintf( outfile, "\tmovl %d(%%ebx), %%esi\n", CONTEXTOFFSET(Esi) ); - fprintf( outfile, "\tmovl %d(%%ebx), %%edi\n", CONTEXTOFFSET(Edi) ); - fprintf( outfile, "\tmovl %d(%%ebx), %%eax\n", CONTEXTOFFSET(Eax) ); - fprintf( outfile, "\tmovl %d(%%ebx), %%edx\n", CONTEXTOFFSET(Edx) ); - fprintf( outfile, "\tmovl %d(%%ebx), %%ecx\n", CONTEXTOFFSET(Ecx) ); - fprintf( outfile, "\tmovl %d(%%ebx), %%ebx\n", CONTEXTOFFSET(Ebx) ); + output( "\tmovl %d(%%ebx), %%ebp\n", CONTEXTOFFSET(Ebp) ); + output( "\tmovl %d(%%ebx), %%esi\n", CONTEXTOFFSET(Esi) ); + output( "\tmovl %d(%%ebx), %%edi\n", CONTEXTOFFSET(Edi) ); + output( "\tmovl %d(%%ebx), %%eax\n", CONTEXTOFFSET(Eax) ); + output( "\tmovl %d(%%ebx), %%edx\n", CONTEXTOFFSET(Edx) ); + output( "\tmovl %d(%%ebx), %%ecx\n", CONTEXTOFFSET(Ecx) ); + output( "\tmovl %d(%%ebx), %%ebx\n", CONTEXTOFFSET(Ebx) ); - fprintf( outfile, "\tpopl %%ds\n" ); - fprintf( outfile, "\tpopfl\n" ); - fprintf( outfile, "\tlret\n" ); + output( "\tpopl %%ds\n" ); + output( "\tpopfl\n" ); + output( "\tlret\n" ); } else { /* Switch stack back */ - fprintf( outfile, "\t.byte 0x64\n\tmovw (%d), %%ss\n", STACKOFFSET+2 ); - fprintf( outfile, "\t.byte 0x64\n\tmovzwl (%d), %%esp\n", STACKOFFSET ); - fprintf( outfile, "\t.byte 0x64\n\tpopl (%d)\n", STACKOFFSET ); + output( "\t.byte 0x64\n\tmovw (%d), %%ss\n", STACKOFFSET+2 ); + output( "\t.byte 0x64\n\tmovzwl (%d), %%esp\n", STACKOFFSET ); + output( "\t.byte 0x64\n\tpopl (%d)\n", STACKOFFSET ); /* Restore registers */ - fprintf( outfile, "\tpopl %%edx\n" ); - fprintf( outfile, "\tpopl %%ecx\n" ); - fprintf( outfile, "\tpopl %%ebp\n" ); - fprintf( outfile, "\tpopw %%ds\n" ); - fprintf( outfile, "\tpopw %%es\n" ); - fprintf( outfile, "\tpopw %%fs\n" ); - fprintf( outfile, "\tpopw %%gs\n" ); + output( "\tpopl %%edx\n" ); + output( "\tpopl %%ecx\n" ); + output( "\tpopl %%ebp\n" ); + output( "\tpopw %%ds\n" ); + output( "\tpopw %%es\n" ); + output( "\tpopw %%fs\n" ); + output( "\tpopw %%gs\n" ); /* Return to return stub which will return to caller */ - fprintf( outfile, "\tlret $12\n" ); + output( "\tlret $12\n" ); } - if (thunk) output_function_size( outfile, "__wine_call_from_16_thunk" ); - else if (reg_func) output_function_size( outfile, "__wine_call_from_16_regs" ); - else output_function_size( outfile, "__wine_call_from_16" ); + if (thunk) output_function_size( "__wine_call_from_16_thunk" ); + else if (reg_func) output_function_size( "__wine_call_from_16_regs" ); + else output_function_size( "__wine_call_from_16" ); } @@ -377,44 +389,44 @@ static void BuildCallFrom16Core( FILE *outfile, int reg_func, int thunk ) * or else set to default values. The target routine address is either * given directly or taken from the CONTEXT86. */ -static void BuildCallTo16Core( FILE *outfile, int reg_func ) +static void BuildCallTo16Core( int reg_func ) { const char *name = reg_func ? "wine_call_to_16_regs" : "wine_call_to_16"; /* Function header */ - function_header( outfile, name ); + function_header( name ); /* Function entry sequence */ - fprintf( outfile, "\tpushl %%ebp\n" ); - fprintf( outfile, "\tmovl %%esp, %%ebp\n" ); + output( "\tpushl %%ebp\n" ); + output( "\tmovl %%esp, %%ebp\n" ); /* Save the 32-bit registers */ - fprintf( outfile, "\tpushl %%ebx\n" ); - fprintf( outfile, "\tpushl %%esi\n" ); - fprintf( outfile, "\tpushl %%edi\n" ); - fprintf( outfile, "\t.byte 0x64\n\tmov %%gs,(%d)\n", STRUCTOFFSET(TEB,gs_sel) ); + output( "\tpushl %%ebx\n" ); + output( "\tpushl %%esi\n" ); + output( "\tpushl %%edi\n" ); + output( "\t.byte 0x64\n\tmov %%gs,(%d)\n", GS_OFFSET ); /* Setup exception frame */ - fprintf( outfile, "\t.byte 0x64\n\tpushl (%d)\n", STACKOFFSET ); - fprintf( outfile, "\tpushl 16(%%ebp)\n" ); /* handler */ - fprintf( outfile, "\t.byte 0x64\n\tpushl (%d)\n", STRUCTOFFSET(TEB,Tib.ExceptionList) ); - fprintf( outfile, "\t.byte 0x64\n\tmovl %%esp,(%d)\n", STRUCTOFFSET(TEB,Tib.ExceptionList) ); + output( "\t.byte 0x64\n\tpushl (%d)\n", STACKOFFSET ); + output( "\tpushl 16(%%ebp)\n" ); /* handler */ + output( "\t.byte 0x64\n\tpushl (0)\n" ); + output( "\t.byte 0x64\n\tmovl %%esp,(0)\n" ); /* Call the actual CallTo16 routine (simulate a lcall) */ - fprintf( outfile, "\tpushl %%cs\n" ); - fprintf( outfile, "\tcall .L%s\n", name ); + output( "\tpushl %%cs\n" ); + output( "\tcall .L%s\n", name ); /* Remove exception frame */ - fprintf( outfile, "\t.byte 0x64\n\tpopl (%d)\n", STRUCTOFFSET(TEB,Tib.ExceptionList) ); - fprintf( outfile, "\taddl $4, %%esp\n" ); - fprintf( outfile, "\t.byte 0x64\n\tpopl (%d)\n", STACKOFFSET ); + output( "\t.byte 0x64\n\tpopl (0)\n" ); + output( "\taddl $4, %%esp\n" ); + output( "\t.byte 0x64\n\tpopl (%d)\n", STACKOFFSET ); if ( !reg_func ) { /* Convert return value */ - fprintf( outfile, "\tandl $0xffff,%%eax\n" ); - fprintf( outfile, "\tshll $16,%%edx\n" ); - fprintf( outfile, "\torl %%edx,%%eax\n" ); + output( "\tandl $0xffff,%%eax\n" ); + output( "\tshll $16,%%edx\n" ); + output( "\torl %%edx,%%eax\n" ); } else { @@ -428,94 +440,94 @@ static void BuildCallTo16Core( FILE *outfile, int reg_func ) * at the cost of a somewhat less efficient return path.] */ - fprintf( outfile, "\tmovl %d(%%esp), %%edi\n", STACK32OFFSET(target) - STACK32OFFSET(edi)); + output( "\tmovl %d(%%esp), %%edi\n", STACK32OFFSET(target) - STACK32OFFSET(edi)); /* everything above edi has been popped already */ - fprintf( outfile, "\tmovl %%eax, %d(%%edi)\n", CONTEXTOFFSET(Eax) ); - fprintf( outfile, "\tmovl %%ebx, %d(%%edi)\n", CONTEXTOFFSET(Ebx) ); - fprintf( outfile, "\tmovl %%ecx, %d(%%edi)\n", CONTEXTOFFSET(Ecx) ); - fprintf( outfile, "\tmovl %%edx, %d(%%edi)\n", CONTEXTOFFSET(Edx) ); - fprintf( outfile, "\tmovl %%ebp, %d(%%edi)\n", CONTEXTOFFSET(Ebp) ); - fprintf( outfile, "\tmovl %%esi, %d(%%edi)\n", CONTEXTOFFSET(Esp) ); + output( "\tmovl %%eax, %d(%%edi)\n", CONTEXTOFFSET(Eax) ); + output( "\tmovl %%ebx, %d(%%edi)\n", CONTEXTOFFSET(Ebx) ); + output( "\tmovl %%ecx, %d(%%edi)\n", CONTEXTOFFSET(Ecx) ); + output( "\tmovl %%edx, %d(%%edi)\n", CONTEXTOFFSET(Edx) ); + output( "\tmovl %%ebp, %d(%%edi)\n", CONTEXTOFFSET(Ebp) ); + output( "\tmovl %%esi, %d(%%edi)\n", CONTEXTOFFSET(Esp) ); /* The return glue code saved %esp into %esi */ } /* Restore the 32-bit registers */ - fprintf( outfile, "\tpopl %%edi\n" ); - fprintf( outfile, "\tpopl %%esi\n" ); - fprintf( outfile, "\tpopl %%ebx\n" ); + output( "\tpopl %%edi\n" ); + output( "\tpopl %%esi\n" ); + output( "\tpopl %%ebx\n" ); /* Function exit sequence */ - fprintf( outfile, "\tpopl %%ebp\n" ); - fprintf( outfile, "\tret $12\n" ); + output( "\tpopl %%ebp\n" ); + output( "\tret $12\n" ); /* Start of the actual CallTo16 routine */ - fprintf( outfile, ".L%s:\n", name ); + output( ".L%s:\n", name ); /* Switch to the 16-bit stack */ - fprintf( outfile, "\tmovl %%esp,%%edx\n" ); - fprintf( outfile, "%s\t.byte 0x64\n\tmovw (%d),%%ss\n", data16_prefix(), STACKOFFSET + 2); - fprintf( outfile, "\t.byte 0x64\n\tmovw (%d),%%sp\n", STACKOFFSET ); - fprintf( outfile, "\t.byte 0x64\n\tmovl %%edx,(%d)\n", STACKOFFSET ); + output( "\tmovl %%esp,%%edx\n" ); + output( "\t.byte 0x64\n\tmovw (%d),%%ss\n", STACKOFFSET + 2); + output( "\t.byte 0x64\n\tmovw (%d),%%sp\n", STACKOFFSET ); + output( "\t.byte 0x64\n\tmovl %%edx,(%d)\n", STACKOFFSET ); /* Make %bp point to the previous stackframe (built by CallFrom16) */ - fprintf( outfile, "\tmovzwl %%sp,%%ebp\n" ); - fprintf( outfile, "\tleal %d(%%ebp),%%ebp\n", STACK16OFFSET(bp) ); + output( "\tmovzwl %%sp,%%ebp\n" ); + output( "\tleal %d(%%ebp),%%ebp\n", STACK16OFFSET(bp) ); /* Add the specified offset to the new sp */ - fprintf( outfile, "\tsubw %d(%%edx), %%sp\n", STACK32OFFSET(nb_args) ); + output( "\tsubw %d(%%edx), %%sp\n", STACK32OFFSET(nb_args) ); if (reg_func) { /* Push the called routine address */ - fprintf( outfile, "\tmovl %d(%%edx),%%edx\n", STACK32OFFSET(target) ); - fprintf( outfile, "\tpushw %d(%%edx)\n", CONTEXTOFFSET(SegCs) ); - fprintf( outfile, "\tpushw %d(%%edx)\n", CONTEXTOFFSET(Eip) ); + output( "\tmovl %d(%%edx),%%edx\n", STACK32OFFSET(target) ); + output( "\tpushw %d(%%edx)\n", CONTEXTOFFSET(SegCs) ); + output( "\tpushw %d(%%edx)\n", CONTEXTOFFSET(Eip) ); /* Get the registers */ - fprintf( outfile, "\tpushw %d(%%edx)\n", CONTEXTOFFSET(SegDs) ); - fprintf( outfile, "\tpushl %d(%%edx)\n", CONTEXTOFFSET(SegEs) ); - fprintf( outfile, "\tpopl %%es\n" ); - fprintf( outfile, "\tpushl %d(%%edx)\n", CONTEXTOFFSET(SegFs) ); - fprintf( outfile, "\tpopl %%fs\n" ); - fprintf( outfile, "\tpushl %d(%%edx)\n", CONTEXTOFFSET(SegGs) ); - fprintf( outfile, "\tpopl %%gs\n" ); - fprintf( outfile, "\tmovl %d(%%edx),%%ebp\n", CONTEXTOFFSET(Ebp) ); - fprintf( outfile, "\tmovl %d(%%edx),%%esi\n", CONTEXTOFFSET(Esi) ); - fprintf( outfile, "\tmovl %d(%%edx),%%edi\n", CONTEXTOFFSET(Edi) ); - fprintf( outfile, "\tmovl %d(%%edx),%%eax\n", CONTEXTOFFSET(Eax) ); - fprintf( outfile, "\tmovl %d(%%edx),%%ebx\n", CONTEXTOFFSET(Ebx) ); - fprintf( outfile, "\tmovl %d(%%edx),%%ecx\n", CONTEXTOFFSET(Ecx) ); - fprintf( outfile, "\tmovl %d(%%edx),%%edx\n", CONTEXTOFFSET(Edx) ); + output( "\tpushw %d(%%edx)\n", CONTEXTOFFSET(SegDs) ); + output( "\tpushl %d(%%edx)\n", CONTEXTOFFSET(SegEs) ); + output( "\tpopl %%es\n" ); + output( "\tpushl %d(%%edx)\n", CONTEXTOFFSET(SegFs) ); + output( "\tpopl %%fs\n" ); + output( "\tpushl %d(%%edx)\n", CONTEXTOFFSET(SegGs) ); + output( "\tpopl %%gs\n" ); + output( "\tmovl %d(%%edx),%%ebp\n", CONTEXTOFFSET(Ebp) ); + output( "\tmovl %d(%%edx),%%esi\n", CONTEXTOFFSET(Esi) ); + output( "\tmovl %d(%%edx),%%edi\n", CONTEXTOFFSET(Edi) ); + output( "\tmovl %d(%%edx),%%eax\n", CONTEXTOFFSET(Eax) ); + output( "\tmovl %d(%%edx),%%ebx\n", CONTEXTOFFSET(Ebx) ); + output( "\tmovl %d(%%edx),%%ecx\n", CONTEXTOFFSET(Ecx) ); + output( "\tmovl %d(%%edx),%%edx\n", CONTEXTOFFSET(Edx) ); /* Get the 16-bit ds */ - fprintf( outfile, "\tpopw %%ds\n" ); + output( "\tpopw %%ds\n" ); } else /* not a register function */ { /* Push the called routine address */ - fprintf( outfile, "\tpushl %d(%%edx)\n", STACK32OFFSET(target) ); + output( "\tpushl %d(%%edx)\n", STACK32OFFSET(target) ); /* Set %fs and %gs to the value saved by the last CallFrom16 */ - fprintf( outfile, "\tpushw %d(%%ebp)\n", STACK16OFFSET(fs)-STACK16OFFSET(bp) ); - fprintf( outfile, "\tpopw %%fs\n" ); - fprintf( outfile, "\tpushw %d(%%ebp)\n", STACK16OFFSET(gs)-STACK16OFFSET(bp) ); - fprintf( outfile, "\tpopw %%gs\n" ); + output( "\tpushw %d(%%ebp)\n", STACK16OFFSET(fs)-STACK16OFFSET(bp) ); + output( "\tpopw %%fs\n" ); + output( "\tpushw %d(%%ebp)\n", STACK16OFFSET(gs)-STACK16OFFSET(bp) ); + output( "\tpopw %%gs\n" ); /* Set %ds and %es (and %ax just in case) equal to %ss */ - fprintf( outfile, "\tmovw %%ss,%%ax\n" ); - fprintf( outfile, "\tmovw %%ax,%%ds\n" ); - fprintf( outfile, "\tmovw %%ax,%%es\n" ); + output( "\tmovw %%ss,%%ax\n" ); + output( "\tmovw %%ax,%%ds\n" ); + output( "\tmovw %%ax,%%es\n" ); } /* Jump to the called routine */ - fprintf( outfile, "\t.byte 0x66\n" ); - fprintf( outfile, "\tlret\n" ); + output( "\t.byte 0x66\n" ); + output( "\tlret\n" ); /* Function footer */ - output_function_size( outfile, name ); + output_function_size( name ); } @@ -524,34 +536,34 @@ static void BuildCallTo16Core( FILE *outfile, int reg_func ) * * Build the return code for 16-bit callbacks */ -static void BuildRet16Func( FILE *outfile ) +static void BuildRet16Func(void) { - function_header( outfile, "__wine_call_to_16_ret" ); + function_header( "__wine_call_to_16_ret" ); /* Save %esp into %esi */ - fprintf( outfile, "\tmovl %%esp,%%esi\n" ); + output( "\tmovl %%esp,%%esi\n" ); /* Restore 32-bit segment registers */ - fprintf( outfile, "\t.byte 0x2e\n\tmovl %s", asm_name("CallTo16_DataSelector") ); - fprintf( outfile, "-%s,%%edi\n", asm_name("__wine_call16_start") ); - fprintf( outfile, "%s\tmovw %%di,%%ds\n", data16_prefix() ); - fprintf( outfile, "%s\tmovw %%di,%%es\n", data16_prefix() ); + output( "\t.byte 0x2e\n\tmovl %s", asm_name("CallTo16_DataSelector") ); + output( "-%s,%%edi\n", asm_name("__wine_call16_start") ); + output( "\tmovw %%di,%%ds\n" ); + output( "\tmovw %%di,%%es\n" ); - fprintf( outfile, "\t.byte 0x2e\n\tmov %s", asm_name("CallTo16_TebSelector") ); - fprintf( outfile, "-%s,%%fs\n", asm_name("__wine_call16_start") ); + output( "\t.byte 0x2e\n\tmov %s", asm_name("CallTo16_TebSelector") ); + output( "-%s,%%fs\n", asm_name("__wine_call16_start") ); - fprintf( outfile, "\t.byte 0x64\n\tmov (%d),%%gs\n", STRUCTOFFSET(TEB,gs_sel) ); + output( "\t.byte 0x64\n\tmov (%d),%%gs\n", GS_OFFSET ); /* Restore the 32-bit stack */ - fprintf( outfile, "%s\tmovw %%di,%%ss\n", data16_prefix() ); - fprintf( outfile, "\t.byte 0x64\n\tmovl (%d),%%esp\n", STACKOFFSET ); + output( "\tmovw %%di,%%ss\n" ); + output( "\t.byte 0x64\n\tmovl (%d),%%esp\n", STACKOFFSET ); /* Return to caller */ - fprintf( outfile, "\tlret\n" ); - output_function_size( outfile, "__wine_call_to_16_ret" ); + output( "\tlret\n" ); + output_function_size( "__wine_call_to_16_ret" ); } @@ -645,77 +657,77 @@ static void BuildRet16Func( FILE *outfile ) * (ebp+4) ret addr * (ebp) ebp */ -static void BuildCallTo32CBClient( FILE *outfile, BOOL isEx ) +static void BuildCallTo32CBClient( BOOL isEx ) { - function_header( outfile, isEx ? "CALL32_CBClientEx" : "CALL32_CBClient" ); + function_header( isEx ? "CALL32_CBClientEx" : "CALL32_CBClient" ); /* Entry code */ - fprintf( outfile, "\tpushl %%ebp\n" ); - fprintf( outfile, "\tmovl %%esp,%%ebp\n" ); - fprintf( outfile, "\tpushl %%edi\n" ); - fprintf( outfile, "\tpushl %%esi\n" ); - fprintf( outfile, "\tpushl %%ebx\n" ); + output( "\tpushl %%ebp\n" ); + output( "\tmovl %%esp,%%ebp\n" ); + output( "\tpushl %%edi\n" ); + output( "\tpushl %%esi\n" ); + output( "\tpushl %%ebx\n" ); /* Get pointer to temporary area and save the 32-bit stack pointer */ - fprintf( outfile, "\tmovl 16(%%ebp), %%ebx\n" ); - fprintf( outfile, "\tleal -8(%%esp), %%eax\n" ); + output( "\tmovl 16(%%ebp), %%ebx\n" ); + output( "\tleal -8(%%esp), %%eax\n" ); if ( !isEx ) - fprintf( outfile, "\tmovl %%eax, -8(%%ebx)\n" ); + output( "\tmovl %%eax, -8(%%ebx)\n" ); else - fprintf( outfile, "\tmovl %%eax, 12(%%ebx)\n" ); + output( "\tmovl %%eax, 12(%%ebx)\n" ); /* Set up registers and call CBClient relay stub (simulating a far call) */ - fprintf( outfile, "\tmovl 20(%%ebp), %%esi\n" ); - fprintf( outfile, "\tmovl (%%esi), %%esi\n" ); + output( "\tmovl 20(%%ebp), %%esi\n" ); + output( "\tmovl (%%esi), %%esi\n" ); - fprintf( outfile, "\tmovl 8(%%ebp), %%eax\n" ); - fprintf( outfile, "\tmovl 12(%%ebp), %%ebp\n" ); + output( "\tmovl 8(%%ebp), %%eax\n" ); + output( "\tmovl 12(%%ebp), %%ebp\n" ); - fprintf( outfile, "\tpushl %%cs\n" ); - fprintf( outfile, "\tcall *%%eax\n" ); + output( "\tpushl %%cs\n" ); + output( "\tcall *%%eax\n" ); /* Return new esi value to caller */ - fprintf( outfile, "\tmovl 32(%%esp), %%edi\n" ); - fprintf( outfile, "\tmovl %%esi, (%%edi)\n" ); + output( "\tmovl 32(%%esp), %%edi\n" ); + output( "\tmovl %%esi, (%%edi)\n" ); /* Return argument size to caller */ if ( isEx ) { - fprintf( outfile, "\tmovl 36(%%esp), %%ebx\n" ); - fprintf( outfile, "\tmovl %%ebp, (%%ebx)\n" ); + output( "\tmovl 36(%%esp), %%ebx\n" ); + output( "\tmovl %%ebp, (%%ebx)\n" ); } /* Restore registers and return */ - fprintf( outfile, "\tpopl %%ebx\n" ); - fprintf( outfile, "\tpopl %%esi\n" ); - fprintf( outfile, "\tpopl %%edi\n" ); - fprintf( outfile, "\tpopl %%ebp\n" ); - fprintf( outfile, "\tret\n" ); - output_function_size( outfile, isEx ? "CALL32_CBClientEx" : "CALL32_CBClient" ); + output( "\tpopl %%ebx\n" ); + output( "\tpopl %%esi\n" ); + output( "\tpopl %%edi\n" ); + output( "\tpopl %%ebp\n" ); + output( "\tret\n" ); + output_function_size( isEx ? "CALL32_CBClientEx" : "CALL32_CBClient" ); /* '16-bit' return stub */ - function_header( outfile, isEx ? "CALL32_CBClientEx_Ret" : "CALL32_CBClient_Ret" ); + function_header( isEx ? "CALL32_CBClientEx_Ret" : "CALL32_CBClient_Ret" ); if ( !isEx ) { - fprintf( outfile, "\tmovzwl %%sp, %%ebx\n" ); - fprintf( outfile, "\tlssl %%ss:-16(%%ebx), %%esp\n" ); + output( "\tmovzwl %%sp, %%ebx\n" ); + output( "\tlssl %%ss:-16(%%ebx), %%esp\n" ); } else { - fprintf( outfile, "\tmovzwl %%bp, %%ebx\n" ); - fprintf( outfile, "\tsubw %%bp, %%sp\n" ); - fprintf( outfile, "\tmovzwl %%sp, %%ebp\n" ); - fprintf( outfile, "\tlssl %%ss:-12(%%ebx), %%esp\n" ); + output( "\tmovzwl %%bp, %%ebx\n" ); + output( "\tsubw %%bp, %%sp\n" ); + output( "\tmovzwl %%sp, %%ebp\n" ); + output( "\tlssl %%ss:-12(%%ebx), %%esp\n" ); } - fprintf( outfile, "\tlret\n" ); - output_function_size( outfile, isEx ? "CALL32_CBClientEx_Ret" : "CALL32_CBClient_Ret" ); + output( "\tlret\n" ); + output_function_size( isEx ? "CALL32_CBClientEx_Ret" : "CALL32_CBClient_Ret" ); } @@ -744,114 +756,114 @@ static void BuildCallTo32CBClient( FILE *outfile, BOOL isEx ) * pointer on return (with the return address and arguments already * removed). */ -static void BuildCallFrom32Regs( FILE *outfile ) +static void BuildCallFrom32Regs(void) { static const int STACK_SPACE = 128 + sizeof(CONTEXT86); /* Function header */ - function_header( outfile, "__wine_call_from_32_regs" ); + function_header( "__wine_call_from_32_regs" ); /* Allocate some buffer space on the stack */ - fprintf( outfile, "\tpushl %%ebp\n" ); - fprintf( outfile, "\tmovl %%esp,%%ebp\n "); - fprintf( outfile, "\tleal -%d(%%esp), %%esp\n", STACK_SPACE + 4 /* for context arg */); + output( "\tpushl %%ebp\n" ); + output( "\tmovl %%esp,%%ebp\n "); + output( "\tleal -%d(%%esp), %%esp\n", STACK_SPACE + 4 /* for context arg */); /* Build the context structure */ - fprintf( outfile, "\tpushfl\n" ); - fprintf( outfile, "\tpopl %%eax\n" ); - fprintf( outfile, "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(EFlags) - STACK_SPACE ); - fprintf( outfile, "\tmovl 0(%%ebp),%%eax\n" ); - fprintf( outfile, "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(Ebp) - STACK_SPACE ); - fprintf( outfile, "\tmovl 8(%%ebp),%%eax\n" ); - fprintf( outfile, "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(Eax) - STACK_SPACE ); - fprintf( outfile, "\tmovl %%ebx,%d(%%ebp)\n", CONTEXTOFFSET(Ebx) - STACK_SPACE ); - fprintf( outfile, "\tmovl %%ecx,%d(%%ebp)\n", CONTEXTOFFSET(Ecx) - STACK_SPACE ); - fprintf( outfile, "\tmovl %%edx,%d(%%ebp)\n", CONTEXTOFFSET(Edx) - STACK_SPACE ); - fprintf( outfile, "\tmovl %%esi,%d(%%ebp)\n", CONTEXTOFFSET(Esi) - STACK_SPACE ); - fprintf( outfile, "\tmovl %%edi,%d(%%ebp)\n", CONTEXTOFFSET(Edi) - STACK_SPACE ); + output( "\tpushfl\n" ); + output( "\tpopl %%eax\n" ); + output( "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(EFlags) - STACK_SPACE ); + output( "\tmovl 0(%%ebp),%%eax\n" ); + output( "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(Ebp) - STACK_SPACE ); + output( "\tmovl 8(%%ebp),%%eax\n" ); + output( "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(Eax) - STACK_SPACE ); + output( "\tmovl %%ebx,%d(%%ebp)\n", CONTEXTOFFSET(Ebx) - STACK_SPACE ); + output( "\tmovl %%ecx,%d(%%ebp)\n", CONTEXTOFFSET(Ecx) - STACK_SPACE ); + output( "\tmovl %%edx,%d(%%ebp)\n", CONTEXTOFFSET(Edx) - STACK_SPACE ); + output( "\tmovl %%esi,%d(%%ebp)\n", CONTEXTOFFSET(Esi) - STACK_SPACE ); + output( "\tmovl %%edi,%d(%%ebp)\n", CONTEXTOFFSET(Edi) - STACK_SPACE ); - fprintf( outfile, "\txorl %%eax,%%eax\n" ); - fprintf( outfile, "\tmovw %%cs,%%ax\n" ); - fprintf( outfile, "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(SegCs) - STACK_SPACE ); - fprintf( outfile, "\tmovw %%es,%%ax\n" ); - fprintf( outfile, "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(SegEs) - STACK_SPACE ); - fprintf( outfile, "\tmovw %%fs,%%ax\n" ); - fprintf( outfile, "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(SegFs) - STACK_SPACE ); - fprintf( outfile, "\tmovw %%gs,%%ax\n" ); - fprintf( outfile, "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(SegGs) - STACK_SPACE ); - fprintf( outfile, "\tmovw %%ss,%%ax\n" ); - fprintf( outfile, "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(SegSs) - STACK_SPACE ); - fprintf( outfile, "\tmovw %%ds,%%ax\n" ); - fprintf( outfile, "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(SegDs) - STACK_SPACE ); - fprintf( outfile, "\tmovw %%ax,%%es\n" ); /* set %es equal to %ds just in case */ + output( "\txorl %%eax,%%eax\n" ); + output( "\tmovw %%cs,%%ax\n" ); + output( "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(SegCs) - STACK_SPACE ); + output( "\tmovw %%es,%%ax\n" ); + output( "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(SegEs) - STACK_SPACE ); + output( "\tmovw %%fs,%%ax\n" ); + output( "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(SegFs) - STACK_SPACE ); + output( "\tmovw %%gs,%%ax\n" ); + output( "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(SegGs) - STACK_SPACE ); + output( "\tmovw %%ss,%%ax\n" ); + output( "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(SegSs) - STACK_SPACE ); + output( "\tmovw %%ds,%%ax\n" ); + output( "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(SegDs) - STACK_SPACE ); + output( "\tmovw %%ax,%%es\n" ); /* set %es equal to %ds just in case */ - fprintf( outfile, "\tmovl $0x%x,%%eax\n", CONTEXT86_FULL ); - fprintf( outfile, "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(ContextFlags) - STACK_SPACE ); + output( "\tmovl $0x%x,%%eax\n", CONTEXT86_FULL ); + output( "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(ContextFlags) - STACK_SPACE ); - fprintf( outfile, "\tmovl 12(%%ebp),%%eax\n" ); /* Get %eip at time of call */ - fprintf( outfile, "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(Eip) - STACK_SPACE ); + output( "\tmovl 12(%%ebp),%%eax\n" ); /* Get %eip at time of call */ + output( "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(Eip) - STACK_SPACE ); /* Transfer the arguments */ - fprintf( outfile, "\tmovl 4(%%ebp),%%ebx\n" ); /* get relay code addr */ - fprintf( outfile, "\tmovzbl 4(%%ebx),%%ecx\n" ); /* fetch number of args to copy */ - fprintf( outfile, "\tsubl %%ecx,%%esp\n" ); - fprintf( outfile, "\tandl $~15,%%esp\n" ); - fprintf( outfile, "\tleal 16(%%ebp),%%esi\n" ); /* get %esp at time of call */ - fprintf( outfile, "\tmovl %%esp,%%edi\n" ); - fprintf( outfile, "\tshrl $2,%%ecx\n" ); - fprintf( outfile, "\tjz 1f\n" ); - fprintf( outfile, "\tcld\n" ); - fprintf( outfile, "\trep\n\tmovsl\n" ); /* copy args */ - fprintf( outfile, "1:\tleal %d(%%ebp),%%eax\n", -STACK_SPACE ); /* get addr of context struct */ - fprintf( outfile, "\tmovl %%eax,(%%edi)\n" ); /* and pass it as extra arg */ - fprintf( outfile, "\tmovzbl 5(%%ebx),%%eax\n" ); /* fetch number of args to remove */ - fprintf( outfile, "\tleal 16(%%ebp,%%eax),%%eax\n" ); - fprintf( outfile, "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(Esp) - STACK_SPACE ); + output( "\tmovl 4(%%ebp),%%ebx\n" ); /* get relay code addr */ + output( "\tmovzbl 4(%%ebx),%%ecx\n" ); /* fetch number of args to copy */ + output( "\tsubl %%ecx,%%esp\n" ); + output( "\tandl $~15,%%esp\n" ); + output( "\tleal 16(%%ebp),%%esi\n" ); /* get %esp at time of call */ + output( "\tmovl %%esp,%%edi\n" ); + output( "\tshrl $2,%%ecx\n" ); + output( "\tjz 1f\n" ); + output( "\tcld\n" ); + output( "\trep\n\tmovsl\n" ); /* copy args */ + output( "1:\tleal %d(%%ebp),%%eax\n", -STACK_SPACE ); /* get addr of context struct */ + output( "\tmovl %%eax,(%%edi)\n" ); /* and pass it as extra arg */ + output( "\tmovzbl 5(%%ebx),%%eax\n" ); /* fetch number of args to remove */ + output( "\tleal 16(%%ebp,%%eax),%%eax\n" ); + output( "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(Esp) - STACK_SPACE ); /* Call the entry point */ - fprintf( outfile, "\taddl (%%ebx),%%ebx\n" ); - fprintf( outfile, "\tcall *%%ebx\n" ); - fprintf( outfile, "\tleal -%d(%%ebp),%%ecx\n", STACK_SPACE ); + output( "\taddl (%%ebx),%%ebx\n" ); + output( "\tcall *%%ebx\n" ); + output( "\tleal -%d(%%ebp),%%ecx\n", STACK_SPACE ); /* Restore the context structure */ - fprintf( outfile, "2:\tpushl %d(%%ecx)\n", CONTEXTOFFSET(SegEs) ); - fprintf( outfile, "\tpopl %%es\n" ); - fprintf( outfile, "\tpushl %d(%%ecx)\n", CONTEXTOFFSET(SegFs) ); - fprintf( outfile, "\tpopl %%fs\n" ); - fprintf( outfile, "\tpushl %d(%%ecx)\n", CONTEXTOFFSET(SegGs) ); - fprintf( outfile, "\tpopl %%gs\n" ); + output( "2:\tpushl %d(%%ecx)\n", CONTEXTOFFSET(SegEs) ); + output( "\tpopl %%es\n" ); + output( "\tpushl %d(%%ecx)\n", CONTEXTOFFSET(SegFs) ); + output( "\tpopl %%fs\n" ); + output( "\tpushl %d(%%ecx)\n", CONTEXTOFFSET(SegGs) ); + output( "\tpopl %%gs\n" ); - fprintf( outfile, "\tmovl %d(%%ecx),%%edi\n", CONTEXTOFFSET(Edi) ); - fprintf( outfile, "\tmovl %d(%%ecx),%%esi\n", CONTEXTOFFSET(Esi) ); - fprintf( outfile, "\tmovl %d(%%ecx),%%edx\n", CONTEXTOFFSET(Edx) ); - fprintf( outfile, "\tmovl %d(%%ecx),%%ebx\n", CONTEXTOFFSET(Ebx) ); - fprintf( outfile, "\tmovl %d(%%ecx),%%eax\n", CONTEXTOFFSET(Eax) ); - fprintf( outfile, "\tmovl %d(%%ecx),%%ebp\n", CONTEXTOFFSET(Ebp) ); + output( "\tmovl %d(%%ecx),%%edi\n", CONTEXTOFFSET(Edi) ); + output( "\tmovl %d(%%ecx),%%esi\n", CONTEXTOFFSET(Esi) ); + output( "\tmovl %d(%%ecx),%%edx\n", CONTEXTOFFSET(Edx) ); + output( "\tmovl %d(%%ecx),%%ebx\n", CONTEXTOFFSET(Ebx) ); + output( "\tmovl %d(%%ecx),%%eax\n", CONTEXTOFFSET(Eax) ); + output( "\tmovl %d(%%ecx),%%ebp\n", CONTEXTOFFSET(Ebp) ); - fprintf( outfile, "\tpushl %d(%%ecx)\n", CONTEXTOFFSET(SegSs) ); - fprintf( outfile, "\tpopl %%ss\n" ); - fprintf( outfile, "\tmovl %d(%%ecx),%%esp\n", CONTEXTOFFSET(Esp) ); + output( "\tpushl %d(%%ecx)\n", CONTEXTOFFSET(SegSs) ); + output( "\tpopl %%ss\n" ); + output( "\tmovl %d(%%ecx),%%esp\n", CONTEXTOFFSET(Esp) ); - fprintf( outfile, "\tpushl %d(%%ecx)\n", CONTEXTOFFSET(EFlags) ); - fprintf( outfile, "\tpushl %d(%%ecx)\n", CONTEXTOFFSET(SegCs) ); - fprintf( outfile, "\tpushl %d(%%ecx)\n", CONTEXTOFFSET(Eip) ); - fprintf( outfile, "\tpushl %d(%%ecx)\n", CONTEXTOFFSET(SegDs) ); - fprintf( outfile, "\tmovl %d(%%ecx),%%ecx\n", CONTEXTOFFSET(Ecx) ); + output( "\tpushl %d(%%ecx)\n", CONTEXTOFFSET(EFlags) ); + output( "\tpushl %d(%%ecx)\n", CONTEXTOFFSET(SegCs) ); + output( "\tpushl %d(%%ecx)\n", CONTEXTOFFSET(Eip) ); + output( "\tpushl %d(%%ecx)\n", CONTEXTOFFSET(SegDs) ); + output( "\tmovl %d(%%ecx),%%ecx\n", CONTEXTOFFSET(Ecx) ); - fprintf( outfile, "\tpopl %%ds\n" ); - fprintf( outfile, "\tiret\n" ); - output_function_size( outfile, "__wine_call_from_32_regs" ); + output( "\tpopl %%ds\n" ); + output( "\tiret\n" ); + output_function_size( "__wine_call_from_32_regs" ); - function_header( outfile, "__wine_call_from_32_restore_regs" ); - fprintf( outfile, "\tmovl 4(%%esp),%%ecx\n" ); - fprintf( outfile, "\tjmp 2b\n" ); - output_function_size( outfile, "__wine_call_from_32_restore_regs" ); + function_header( "__wine_call_from_32_restore_regs" ); + output( "\tmovl 4(%%esp),%%ecx\n" ); + output( "\tjmp 2b\n" ); + output_function_size( "__wine_call_from_32_restore_regs" ); } @@ -862,7 +874,7 @@ static void BuildCallFrom32Regs( FILE *outfile ) * pending DPMI events. * * Stack layout: - * + * * (sp+12) long eflags * (sp+6) long cs * (sp+2) long ip @@ -871,38 +883,34 @@ static void BuildCallFrom32Regs( FILE *outfile ) * On entry to function, fs register points to a valid TEB. * On exit from function, stack will be popped. */ -static void BuildPendingEventCheck( FILE *outfile ) +static void BuildPendingEventCheck(void) { /* Function header */ - function_header( outfile, "DPMI_PendingEventCheck" ); + function_header( "DPMI_PendingEventCheck" ); /* Check for pending events. */ - fprintf( outfile, "\t.byte 0x64\n\ttestl $0xffffffff,(%d)\n", - STRUCTOFFSET(TEB,vm86_pending) ); - fprintf( outfile, "\tje %s\n", asm_name("DPMI_PendingEventCheck_Cleanup") ); - - fprintf( outfile, "\t.byte 0x64\n\ttestl $0xffffffff,(%d)\n", - STRUCTOFFSET(TEB,dpmi_vif) ); - - fprintf( outfile, "\tje %s\n", asm_name("DPMI_PendingEventCheck_Cleanup") ); + output( "\t.byte 0x64\n\ttestl $0xffffffff,(%d)\n", STRUCTOFFSET(TEB,vm86_pending) ); + output( "\tje %s\n", asm_name("DPMI_PendingEventCheck_Cleanup") ); + output( "\t.byte 0x64\n\ttestl $0xffffffff,(%d)\n", STRUCTOFFSET(TEB,dpmi_vif) ); + output( "\tje %s\n", asm_name("DPMI_PendingEventCheck_Cleanup") ); /* Process pending events. */ - fprintf( outfile, "\tsti\n" ); + output( "\tsti\n" ); /* Start cleanup. Restore fs register. */ - fprintf( outfile, "%s\n", asm_globl("DPMI_PendingEventCheck_Cleanup") ); - fprintf( outfile, "\tpopw %%fs\n" ); + output( "%s\n", asm_globl("DPMI_PendingEventCheck_Cleanup") ); + output( "\tpopw %%fs\n" ); /* Return from function. */ - fprintf( outfile, "%s\n", asm_globl("DPMI_PendingEventCheck_Return") ); - fprintf( outfile, "\tiret\n" ); + output( "%s\n", asm_globl("DPMI_PendingEventCheck_Return") ); + output( "\tiret\n" ); - output_function_size( outfile, "DPMI_PendingEventCheck" ); + output_function_size( "DPMI_PendingEventCheck" ); } @@ -911,58 +919,59 @@ static void BuildPendingEventCheck( FILE *outfile ) * * Build all the 16-bit relay callbacks */ -void BuildRelays16( FILE *outfile ) +void BuildRelays16(void) { if (target_cpu != CPU_x86) { - fprintf( outfile, "/* File not used with this architecture. Do not edit! */\n\n" ); + output( "/* File not used with this architecture. Do not edit! */\n\n" ); return; } /* File header */ - fprintf( outfile, "/* File generated automatically. Do not edit! */\n\n" ); - fprintf( outfile, "\t.text\n" ); + output( "/* File generated automatically. Do not edit! */\n\n" ); + output( "\t.text\n" ); - fprintf( outfile, "%s:\n\n", asm_name("__wine_spec_thunk_text_16") ); + output( "%s:\n\n", asm_name("__wine_spec_thunk_text_16") ); - fprintf( outfile, "%s\n", asm_globl("__wine_call16_start") ); + output( "%s\n", asm_globl("__wine_call16_start") ); /* Standard CallFrom16 routine */ - BuildCallFrom16Core( outfile, FALSE, FALSE ); + BuildCallFrom16Core( FALSE, FALSE ); /* Register CallFrom16 routine */ - BuildCallFrom16Core( outfile, TRUE, FALSE ); + BuildCallFrom16Core( TRUE, FALSE ); /* C16ThkSL CallFrom16 routine */ - BuildCallFrom16Core( outfile, FALSE, TRUE ); + BuildCallFrom16Core( FALSE, TRUE ); /* Standard CallTo16 routine */ - BuildCallTo16Core( outfile, 0 ); + BuildCallTo16Core( 0 ); /* Register CallTo16 routine */ - BuildCallTo16Core( outfile, 1 ); + BuildCallTo16Core( 1 ); /* Standard CallTo16 return stub */ - BuildRet16Func( outfile ); + BuildRet16Func(); /* CBClientThunkSL routine */ - BuildCallTo32CBClient( outfile, FALSE ); + BuildCallTo32CBClient( FALSE ); /* CBClientThunkSLEx routine */ - BuildCallTo32CBClient( outfile, TRUE ); + BuildCallTo32CBClient( TRUE ); /* Pending DPMI events check stub */ - BuildPendingEventCheck( outfile ); + BuildPendingEventCheck(); - fprintf( outfile, "%s\n", asm_globl("__wine_call16_end") ); - output_function_size( outfile, "__wine_spec_thunk_text_16" ); + output( "%s\n", asm_globl("__wine_call16_end") ); + output_function_size( "__wine_spec_thunk_text_16" ); /* Declare the return address and data selector variables */ - fprintf( outfile, "\n\t.data\n\t.align %d\n", get_alignment(4) ); - fprintf( outfile, "%s\n\t.long 0\n", asm_globl("CallTo16_DataSelector") ); - fprintf( outfile, "%s\n\t.long 0\n", asm_globl("CallTo16_TebSelector") ); - if (UsePIC) fprintf( outfile, "wine_ldt_copy_ptr:\t.long %s\n", asm_name("wine_ldt_copy") ); + output( "\n\t.data\n\t.align %d\n", get_alignment(4) ); + output( "%s\n\t.long 0\n", asm_globl("CallTo16_DataSelector") ); + output( "%s\n\t.long 0\n", asm_globl("CallTo16_TebSelector") ); + if (UsePIC) output( "wine_ldt_copy_ptr:\t.long %s\n", asm_name("wine_ldt_copy") ); + output_gnu_stack_note(); } /******************************************************************* @@ -970,22 +979,23 @@ void BuildRelays16( FILE *outfile ) * * Build all the 32-bit relay callbacks */ -void BuildRelays32( FILE *outfile ) +void BuildRelays32(void) { if (target_cpu != CPU_x86) { - fprintf( outfile, "/* File not used with this architecture. Do not edit! */\n\n" ); + output( "/* File not used with this architecture. Do not edit! */\n\n" ); return; } /* File header */ - fprintf( outfile, "/* File generated automatically. Do not edit! */\n\n" ); - fprintf( outfile, "\t.text\n" ); - fprintf( outfile, "%s:\n\n", asm_name("__wine_spec_thunk_text_32") ); + output( "/* File generated automatically. Do not edit! */\n\n" ); + output( "\t.text\n" ); + output( "%s:\n\n", asm_name("__wine_spec_thunk_text_32") ); /* 32-bit register entry point */ - BuildCallFrom32Regs( outfile ); + BuildCallFrom32Regs(); - output_function_size( outfile, "__wine_spec_thunk_text_32" ); + output_function_size( "__wine_spec_thunk_text_32" ); + output_gnu_stack_note(); } diff --git a/reactos/tools/winebuild/res16.c b/reactos/tools/winebuild/res16.c index dec1d6bb423..8648190ed24 100644 --- a/reactos/tools/winebuild/res16.c +++ b/reactos/tools/winebuild/res16.c @@ -15,10 +15,11 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include "config.h" +#include "wine/port.h" #include #include @@ -37,7 +38,8 @@ #include #endif -#include "winglue.h" +#include "windef.h" +#include "winbase.h" #include "build.h" /* Unicode string or integer id */ @@ -77,7 +79,7 @@ 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( DLLSPEC *spec ) +static inline struct resource *add_resource( DLLSPEC *spec ) { spec->resources = xrealloc( spec->resources, (spec->nb_resources + 1) * sizeof(*spec->resources) ); return &spec->resources[spec->nb_resources++]; @@ -140,7 +142,7 @@ static void get_string( struct string_id *str ) } else { - char *p = xmalloc( (strlen((char*)file_pos) + 1) ); + char *p = xmalloc(strlen((const char *)file_pos) + 1); str->str = p; str->id = 0; while ((*p++ = get_byte())); @@ -240,16 +242,16 @@ static void free_resource_tree( struct res_tree *tree ) } /* output a string preceded by its length */ -static void output_string( FILE *outfile, const char *str ) +static void output_string( const char *str ) { unsigned int i, len = strlen(str); - fprintf( outfile, "\t.byte 0x%02x", len ); - for (i = 0; i < len; i++) fprintf( outfile, ",0x%02x", (unsigned char)str[i] ); - fprintf( outfile, " /* %s */\n", str ); + output( "\t.byte 0x%02x", len ); + for (i = 0; i < len; i++) output( ",0x%02x", (unsigned char)str[i] ); + output( " /* %s */\n", str ); } /* output the resource data */ -void output_res16_data( FILE *outfile, DLLSPEC *spec ) +void output_res16_data( DLLSPEC *spec ) { const struct resource *res; unsigned int i; @@ -258,14 +260,14 @@ void output_res16_data( FILE *outfile, DLLSPEC *spec ) for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++) { - fprintf( outfile, ".L__wine_spec_resource_%u:\n", i ); - dump_bytes( outfile, res->data, res->data_size ); - fprintf( outfile, ".L__wine_spec_resource_%u_end:\n", i ); + output( ".L__wine_spec_resource_%u:\n", i ); + dump_bytes( res->data, res->data_size ); + output( ".L__wine_spec_resource_%u_end:\n", i ); } } /* output the resource definitions */ -void output_res16_directory( FILE *outfile, DLLSPEC *spec, const char *header_name ) +void output_res16_directory( DLLSPEC *spec, const char *header_name ) { unsigned int i, j; struct res_tree *tree; @@ -274,38 +276,39 @@ void output_res16_directory( FILE *outfile, DLLSPEC *spec, const char *header_na tree = build_resource_tree( spec ); - fprintf( outfile, "\n.L__wine_spec_ne_rsrctab:\n" ); - fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* alignment */ + output( "\n.L__wine_spec_ne_rsrctab:\n" ); + output( "\t%s 0\n", get_asm_short_keyword() ); /* alignment */ /* type and name structures */ for (i = 0, type = tree->types; i < tree->nb_types; i++, type++) { if (type->type->str) - fprintf( outfile, "\t%s .L__wine_spec_restype_%u-.L__wine_spec_ne_rsrctab\n", + output( "\t%s .L__wine_spec_restype_%u-.L__wine_spec_ne_rsrctab\n", get_asm_short_keyword(), i ); else - fprintf( outfile, "\t%s 0x%04x\n", get_asm_short_keyword(), type->type->id | 0x8000 ); + output( "\t%s 0x%04x\n", get_asm_short_keyword(), type->type->id | 0x8000 ); - fprintf( outfile, "\t%s %u,0,0\n", get_asm_short_keyword(), type->nb_names ); + output( "\t%s %u,0,0\n", get_asm_short_keyword(), type->nb_names ); for (j = 0, res = type->res; j < type->nb_names; j++, res++) { - fprintf( outfile, "\t%s .L__wine_spec_resource_%u-%s\n", - get_asm_short_keyword(), res - spec->resources, header_name ); - fprintf( outfile, "\t%s .L__wine_spec_resource_%u_end-.L__wine_spec_resource_%u\n", - get_asm_short_keyword(), res - spec->resources, res - spec->resources ); - fprintf( outfile, "\t%s 0x%04x\n", get_asm_short_keyword(), res->memopt ); + output( "\t%s .L__wine_spec_resource_%lu-%s\n", + get_asm_short_keyword(), (unsigned long)(res - spec->resources), header_name ); + output( "\t%s .L__wine_spec_resource_%lu_end-.L__wine_spec_resource_%lu\n", + get_asm_short_keyword(), (unsigned long)(res - spec->resources), + (unsigned long)(res - spec->resources) ); + output( "\t%s 0x%04x\n", get_asm_short_keyword(), res->memopt ); if (res->name.str) - fprintf( outfile, "\t%s .L__wine_spec_resname_%u_%u-.L__wine_spec_ne_rsrctab\n", + output( "\t%s .L__wine_spec_resname_%u_%u-.L__wine_spec_ne_rsrctab\n", get_asm_short_keyword(), i, j ); else - fprintf( outfile, "\t%s 0x%04x\n", get_asm_short_keyword(), res->name.id | 0x8000 ); + output( "\t%s 0x%04x\n", get_asm_short_keyword(), res->name.id | 0x8000 ); - fprintf( outfile, "\t%s 0,0\n", get_asm_short_keyword() ); + output( "\t%s 0,0\n", get_asm_short_keyword() ); } } - fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* terminator */ + output( "\t%s 0\n", get_asm_short_keyword() ); /* terminator */ /* name strings */ @@ -313,19 +316,19 @@ void output_res16_directory( FILE *outfile, DLLSPEC *spec, const char *header_na { if (type->type->str) { - fprintf( outfile, ".L__wine_spec_restype_%u:\n", i ); - output_string( outfile, type->type->str ); + output( ".L__wine_spec_restype_%u:\n", i ); + output_string( type->type->str ); } for (j = 0, res = type->res; j < type->nb_names; j++, res++) { if (res->name.str) { - fprintf( outfile, ".L__wine_spec_resname_%u_%u:\n", i, j ); - output_string( outfile, res->name.str ); + output( ".L__wine_spec_resname_%u_%u:\n", i, j ); + output_string( res->name.str ); } } } - fprintf( outfile, "\t.byte 0\n" ); /* names terminator */ + output( "\t.byte 0\n" ); /* names terminator */ free_resource_tree( tree ); } diff --git a/reactos/tools/winebuild/res32.c b/reactos/tools/winebuild/res32.c index 85a354b7794..5d480ad28bf 100644 --- a/reactos/tools/winebuild/res32.c +++ b/reactos/tools/winebuild/res32.c @@ -15,10 +15,11 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include "config.h" +#include "wine/port.h" #include #include @@ -36,7 +37,8 @@ #include #endif -#include "winglue.h" +#include "windef.h" +#include "winbase.h" #include "build.h" /* Unicode string or integer id */ @@ -91,7 +93,7 @@ static const char *file_name; /* current resource file name */ #define RESDIR_SIZE(n) (sizeof(IMAGE_RESOURCE_DIRECTORY) + (n) * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY)) -inline static struct resource *add_resource( DLLSPEC *spec ) +static inline struct resource *add_resource( DLLSPEC *spec ) { spec->resources = xrealloc( spec->resources, (spec->nb_resources + 1) * sizeof(spec->resources[0]) ); return &spec->resources[spec->nb_resources++]; @@ -314,29 +316,29 @@ static void free_resource_tree( struct res_tree *tree ) } /* output a Unicode string */ -static void output_string( FILE *outfile, const WCHAR *name ) +static void output_string( const WCHAR *name ) { int i, len = strlenW(name); - fprintf( outfile, "\t%s 0x%04x", get_asm_short_keyword(), len ); - for (i = 0; i < len; i++) fprintf( outfile, ",0x%04x", name[i] ); - fprintf( outfile, " /* " ); - for (i = 0; i < len; i++) fprintf( outfile, "%c", isprint((char)name[i]) ? (char)name[i] : '?' ); - fprintf( outfile, " */\n" ); + output( "\t%s 0x%04x", get_asm_short_keyword(), len ); + for (i = 0; i < len; i++) output( ",0x%04x", name[i] ); + output( " /* " ); + for (i = 0; i < len; i++) output( "%c", isprint((char)name[i]) ? (char)name[i] : '?' ); + output( " */\n" ); } /* output a resource directory */ -static inline void output_res_dir( FILE *outfile, unsigned int nb_names, unsigned int nb_ids ) +static inline void output_res_dir( unsigned int nb_names, unsigned int nb_ids ) { - fprintf( outfile, "\t.long 0\n" ); /* Characteristics */ - fprintf( outfile, "\t.long 0\n" ); /* TimeDateStamp */ - fprintf( outfile, "\t%s 0,0\n", /* Major/MinorVersion */ + output( "\t.long 0\n" ); /* Characteristics */ + output( "\t.long 0\n" ); /* TimeDateStamp */ + output( "\t%s 0,0\n", /* Major/MinorVersion */ get_asm_short_keyword() ); - fprintf( outfile, "\t%s %u,%u\n", /* NumberOfNamed/IdEntries */ + output( "\t%s %u,%u\n", /* NumberOfNamed/IdEntries */ get_asm_short_keyword(), nb_names, nb_ids ); } /* output the resource definitions */ -void output_resources( FILE *outfile, DLLSPEC *spec ) +void output_resources( DLLSPEC *spec ) { int k, nb_id_types; unsigned int i, n, offset, data_offset; @@ -386,19 +388,19 @@ void output_resources( FILE *outfile, DLLSPEC *spec ) /* output the resource directories */ - fprintf( outfile, "\n/* resources */\n\n" ); - fprintf( outfile, "\t.data\n" ); - fprintf( outfile, "\t.align %d\n", get_alignment(get_ptr_size()) ); - fprintf( outfile, ".L__wine_spec_resources:\n" ); + output( "\n/* resources */\n\n" ); + output( "\t.data\n" ); + output( "\t.align %d\n", get_alignment(get_ptr_size()) ); + output( ".L__wine_spec_resources:\n" ); - output_res_dir( outfile, tree->nb_types - nb_id_types, nb_id_types ); + output_res_dir( tree->nb_types - nb_id_types, nb_id_types ); /* dump the type directory */ offset = RESDIR_SIZE( tree->nb_types ); for (i = 0, type = tree->types; i < tree->nb_types; i++, type++) { - fprintf( outfile, "\t.long 0x%08x,0x%08x\n", + output( "\t.long 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++) @@ -412,22 +414,22 @@ void output_resources( FILE *outfile, DLLSPEC *spec ) for (i = 0, type = tree->types; i < tree->nb_types; i++, type++) { - output_res_dir( outfile, type->nb_names - type->nb_id_names, type->nb_id_names ); + output_res_dir( type->nb_names - type->nb_id_names, type->nb_id_names ); offset += RESDIR_SIZE( type->nb_names ); for (n = 0, name = type->names; n < type->nb_names; n++, name++) { - fprintf( outfile, "\t.long 0x%08x,0x%08x\n", + output( "\t.long 0x%08x,0x%08x\n", name->name_offset, offset | 0x80000000 ); offset += RESDIR_SIZE( name->nb_languages ); } for (n = 0, name = type->names; n < type->nb_names; n++, name++) { - output_res_dir( outfile, 0, name->nb_languages ); + output_res_dir( 0, name->nb_languages ); for (k = 0, res = name->res; k < name->nb_languages; k++, res++) { - fprintf( outfile, "\t.long 0x%08x,0x%08x\n", res->lang, - data_offset + (res - spec->resources) * sizeof(IMAGE_RESOURCE_DATA_ENTRY) ); + unsigned int entry_offset = (res - spec->resources) * sizeof(IMAGE_RESOURCE_DATA_ENTRY); + output( "\t.long 0x%08x,0x%08x\n", res->lang, data_offset + entry_offset ); } } } @@ -435,28 +437,28 @@ void output_resources( FILE *outfile, DLLSPEC *spec ) /* dump the resource data entries */ for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++) - fprintf( outfile, "\t.long .L__wine_spec_res_%d-.L__wine_spec_rva_base,%u,0,0\n", + output( "\t.long .L__wine_spec_res_%d-.L__wine_spec_rva_base,%u,0,0\n", i, res->data_size ); /* dump the name strings */ for (i = 0, type = tree->types; i < tree->nb_types; i++, type++) { - if (type->type->str) output_string( outfile, type->type->str ); + if (type->type->str) output_string( type->type->str ); for (n = 0, name = type->names; n < type->nb_names; n++, name++) - if (name->name->str) output_string( outfile, name->name->str ); + if (name->name->str) output_string( name->name->str ); } /* resource data */ for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++) { - fprintf( outfile, "\n\t.align %d\n", get_alignment(get_ptr_size()) ); - fprintf( outfile, ".L__wine_spec_res_%d:\n", i ); - dump_bytes( outfile, res->data, res->data_size ); + output( "\n\t.align %d\n", get_alignment(get_ptr_size()) ); + output( ".L__wine_spec_res_%d:\n", i ); + dump_bytes( res->data, res->data_size ); } - fprintf( outfile, ".L__wine_spec_resources_end:\n" ); - fprintf( outfile, "\t.byte 0\n" ); + output( ".L__wine_spec_resources_end:\n" ); + output( "\t.byte 0\n" ); free_resource_tree( tree ); } diff --git a/reactos/tools/winebuild/spec16.c b/reactos/tools/winebuild/spec16.c index 4c89f8bc519..dc86b1b40ae 100644 --- a/reactos/tools/winebuild/spec16.c +++ b/reactos/tools/winebuild/spec16.c @@ -19,10 +19,11 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include "config.h" +#include "wine/port.h" #include #include @@ -53,31 +54,31 @@ static inline int is_function( const ORDDEF *odp ) * * Output entries for individual symbols in the entry table. */ -static void output_entries( FILE *outfile, DLLSPEC *spec, int first, int count ) +static void output_entries( DLLSPEC *spec, int first, int count ) { int i; for (i = 0; i < count; i++) { ORDDEF *odp = spec->ordinals[first + i]; - fprintf( outfile, "\t.byte 0x03\n" ); /* flags: exported & public data */ + output( "\t.byte 0x03\n" ); /* flags: exported & public data */ switch (odp->type) { case TYPE_CDECL: case TYPE_PASCAL: case TYPE_VARARGS: case TYPE_STUB: - fprintf( outfile, "\t%s .L__wine_%s_%u-.L__wine_spec_code_segment\n", + output( "\t%s .L__wine_%s_%u-.L__wine_spec_code_segment\n", get_asm_short_keyword(), make_c_identifier(spec->dll_name), first + i ); break; case TYPE_VARIABLE: - fprintf( outfile, "\t%s .L__wine_%s_%u-.L__wine_spec_data_segment\n", + output( "\t%s .L__wine_%s_%u-.L__wine_spec_data_segment\n", get_asm_short_keyword(), make_c_identifier(spec->dll_name), first + i ); break; case TYPE_ABS: - fprintf( outfile, "\t%s 0x%04x /* %s */\n", + output( "\t%s 0x%04x /* %s */\n", get_asm_short_keyword(), odp->u.abs.value, odp->name ); break; default: @@ -90,7 +91,7 @@ static void output_entries( FILE *outfile, DLLSPEC *spec, int first, int count ) /******************************************************************* * output_entry_table */ -static void output_entry_table( FILE *outfile, DLLSPEC *spec ) +static void output_entry_table( DLLSPEC *spec ) { int i, prev = 0, prev_sel = -1, bundle_count = 0; @@ -125,10 +126,10 @@ static void output_entry_table( FILE *outfile, DLLSPEC *spec ) /* flush previous bundle */ if (bundle_count) { - fprintf( outfile, "\t/* %s.%d - %s.%d */\n", + output( "\t/* %s.%d - %s.%d */\n", spec->dll_name, prev - bundle_count + 1, spec->dll_name, prev ); - fprintf( outfile, "\t.byte 0x%02x,0x%02x\n", bundle_count, prev_sel ); - output_entries( outfile, spec, prev - bundle_count + 1, bundle_count ); + output( "\t.byte 0x%02x,0x%02x\n", bundle_count, prev_sel ); + output_entries( spec, prev - bundle_count + 1, bundle_count ); } if (prev + 1 != i) @@ -136,10 +137,10 @@ static void output_entry_table( FILE *outfile, DLLSPEC *spec ) int skip = i - (prev + 1); while (skip > 255) { - fprintf( outfile, "\t.byte 0xff,0x00\n" ); + output( "\t.byte 0xff,0x00\n" ); skip -= 255; } - fprintf( outfile, "\t.byte 0x%02x,0x00\n", skip ); + output( "\t.byte 0x%02x,0x00\n", skip ); } bundle_count = 0; @@ -152,24 +153,24 @@ static void output_entry_table( FILE *outfile, DLLSPEC *spec ) /* flush last bundle */ if (bundle_count) { - fprintf( outfile, "\t.byte 0x%02x,0x%02x\n", bundle_count, prev_sel ); - output_entries( outfile, spec, prev - bundle_count + 1, bundle_count ); + output( "\t.byte 0x%02x,0x%02x\n", bundle_count, prev_sel ); + output_entries( spec, prev - bundle_count + 1, bundle_count ); } - fprintf( outfile, "\t.byte 0x00\n" ); + output( "\t.byte 0x00\n" ); } /******************************************************************* * output_resident_name */ -static void output_resident_name( FILE *outfile, const char *string, int ordinal ) +static void output_resident_name( const char *string, int ordinal ) { unsigned int i, len = strlen(string); - fprintf( outfile, "\t.byte 0x%02x", len ); - for (i = 0; i < len; i++) fprintf( outfile, ",0x%02x", (unsigned char)toupper(string[i]) ); - fprintf( outfile, " /* %s */\n", string ); - fprintf( outfile, "\t%s %u\n", get_asm_short_keyword(), ordinal ); + output( "\t.byte 0x%02x", len ); + for (i = 0; i < len; i++) output( ",0x%02x", (unsigned char)toupper(string[i]) ); + output( " /* %s */\n", string ); + output( "\t%s %u\n", get_asm_short_keyword(), ordinal ); } @@ -282,7 +283,7 @@ static int get_function_argsize( const ORDDEF *odp ) * 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. */ -static void output_call16_function( FILE *outfile, ORDDEF *odp ) +static void output_call16_function( ORDDEF *odp ) { char name[256]; int i, pos, stack_words; @@ -292,41 +293,41 @@ static void output_call16_function( FILE *outfile, ORDDEF *odp ) sprintf( name, ".L__wine_spec_call16_%s", get_relay_name(odp) ); - fprintf( outfile, "\t.align %d\n", get_alignment(4) ); - fprintf( outfile, "\t%s\n", func_declaration(name) ); - fprintf( outfile, "%s:\n", name ); - fprintf( outfile, "\tpushl %%ebp\n" ); - fprintf( outfile, "\tmovl %%esp,%%ebp\n" ); + output( "\t.align %d\n", get_alignment(4) ); + output( "\t%s\n", func_declaration(name) ); + output( "%s:\n", name ); + output( "\tpushl %%ebp\n" ); + output( "\tmovl %%esp,%%ebp\n" ); stack_words = 2; if (needs_ldt) { - fprintf( outfile, "\tpushl %%esi\n" ); + output( "\tpushl %%esi\n" ); stack_words++; if (UsePIC) { - fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") ); - fprintf( outfile, "1:\tmovl wine_ldt_copy_ptr-1b(%%eax),%%esi\n" ); + output( "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") ); + output( "1:\tmovl wine_ldt_copy_ptr-1b(%%eax),%%esi\n" ); } else - fprintf( outfile, "\tmovl $%s,%%esi\n", asm_name("wine_ldt_copy") ); + output( "\tmovl $%s,%%esi\n", asm_name("wine_ldt_copy") ); } /* preserve 16-byte stack alignment */ stack_words += strlen(args); if ((odp->flags & FLAG_REGISTER) || (odp->type == TYPE_VARARGS)) stack_words++; - if (stack_words % 4) fprintf( outfile, "\tsubl $%d,%%esp\n", 16 - 4 * (stack_words % 4) ); + if (stack_words % 4) output( "\tsubl $%d,%%esp\n", 16 - 4 * (stack_words % 4) ); if (args[0] || odp->type == TYPE_VARARGS) - fprintf( outfile, "\tmovl 12(%%ebp),%%ecx\n" ); /* args */ + output( "\tmovl 12(%%ebp),%%ecx\n" ); /* args */ if (odp->flags & FLAG_REGISTER) { - fprintf( outfile, "\tpushl 16(%%ebp)\n" ); /* context */ + output( "\tpushl 16(%%ebp)\n" ); /* context */ } else if (odp->type == TYPE_VARARGS) { - fprintf( outfile, "\tleal %d(%%ecx),%%eax\n", argsize ); - fprintf( outfile, "\tpushl %%eax\n" ); /* va_list16 */ + output( "\tleal %d(%%ecx),%%eax\n", argsize ); + output( "\tpushl %%eax\n" ); /* va_list16 */ } pos = (odp->type == TYPE_PASCAL) ? 0 : argsize; @@ -336,33 +337,33 @@ static void output_call16_function( FILE *outfile, ORDDEF *odp ) { case 'w': /* word */ if (odp->type != TYPE_PASCAL) pos -= 2; - fprintf( outfile, "\tmovzwl %d(%%ecx),%%eax\n", pos ); - fprintf( outfile, "\tpushl %%eax\n" ); + output( "\tmovzwl %d(%%ecx),%%eax\n", pos ); + output( "\tpushl %%eax\n" ); if (odp->type == TYPE_PASCAL) pos += 2; break; case 's': /* s_word */ if (odp->type != TYPE_PASCAL) pos -= 2; - fprintf( outfile, "\tmovswl %d(%%ecx),%%eax\n", pos ); - fprintf( outfile, "\tpushl %%eax\n" ); + output( "\tmovswl %d(%%ecx),%%eax\n", pos ); + output( "\tpushl %%eax\n" ); if (odp->type == TYPE_PASCAL) pos += 2; break; case 'l': /* long or segmented pointer */ case 'T': /* segmented pointer to null-terminated string */ if (odp->type != TYPE_PASCAL) pos -= 4; - fprintf( outfile, "\tpushl %d(%%ecx)\n", pos ); + output( "\tpushl %d(%%ecx)\n", pos ); if (odp->type == TYPE_PASCAL) pos += 4; break; case 'p': /* linear pointer */ case 't': /* linear pointer to null-terminated string */ if (odp->type != TYPE_PASCAL) pos -= 4; - fprintf( outfile, "\tmovzwl %d(%%ecx),%%edx\n", pos + 2 ); /* sel */ - fprintf( outfile, "\tshr $3,%%edx\n" ); - fprintf( outfile, "\tmovzwl %d(%%ecx),%%eax\n", pos ); /* offset */ - fprintf( outfile, "\taddl (%%esi,%%edx,4),%%eax\n" ); - fprintf( outfile, "\tpushl %%eax\n" ); + output( "\tmovzwl %d(%%ecx),%%edx\n", pos + 2 ); /* sel */ + output( "\tshr $3,%%edx\n" ); + output( "\tmovzwl %d(%%ecx),%%eax\n", pos ); /* offset */ + output( "\taddl (%%esi,%%edx,4),%%eax\n" ); + output( "\tpushl %%eax\n" ); if (odp->type == TYPE_PASCAL) pos += 4; break; @@ -371,14 +372,13 @@ static void output_call16_function( FILE *outfile, ORDDEF *odp ) } } - fprintf( outfile, "\tcall *8(%%ebp)\n" ); + output( "\tcall *8(%%ebp)\n" ); - if (needs_ldt) fprintf( outfile, "\tmovl -4(%%ebp),%%esi\n" ); - if (odp->flags & FLAG_RET16) fprintf( outfile, "\tmovzwl %%ax,%%eax\n" ); + if (needs_ldt) output( "\tmovl -4(%%ebp),%%esi\n" ); - fprintf( outfile, "\tleave\n" ); - fprintf( outfile, "\tret\n" ); - output_function_size( outfile, name ); + output( "\tleave\n" ); + output( "\tret\n" ); + output_function_size( name ); } @@ -450,72 +450,72 @@ static int sort_func_list( ORDDEF **list, int count, * * Output the dll initialization code. */ -static void output_init_code( FILE *outfile, const DLLSPEC *spec, const char *header_name ) +static void output_init_code( const DLLSPEC *spec, const char *header_name ) { char name[80]; sprintf( name, ".L__wine_spec_%s_init", make_c_identifier(spec->dll_name) ); - fprintf( outfile, "\n/* dll initialization code */\n\n" ); - fprintf( outfile, "\t.text\n" ); - fprintf( outfile, "\t.align 4\n" ); - fprintf( outfile, "\t%s\n", func_declaration(name) ); - fprintf( outfile, "%s:\n", name ); - fprintf( outfile, "subl $4,%%esp\n" ); + output( "\n/* dll initialization code */\n\n" ); + output( "\t.text\n" ); + output( "\t.align 4\n" ); + output( "\t%s\n", func_declaration(name) ); + output( "%s:\n", name ); + output( "subl $4,%%esp\n" ); if (UsePIC) { - fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") ); - fprintf( outfile, "1:\tleal .L__wine_spec_file_name-1b(%%eax),%%ecx\n" ); - fprintf( outfile, "\tpushl %%ecx\n" ); - fprintf( outfile, "\tleal %s-1b(%%eax),%%ecx\n", header_name ); - fprintf( outfile, "\tpushl %%ecx\n" ); + output( "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") ); + output( "1:\tleal .L__wine_spec_file_name-1b(%%eax),%%ecx\n" ); + output( "\tpushl %%ecx\n" ); + output( "\tleal %s-1b(%%eax),%%ecx\n", header_name ); + output( "\tpushl %%ecx\n" ); } else { - fprintf( outfile, "\tpushl $.L__wine_spec_file_name\n" ); - fprintf( outfile, "\tpushl $%s\n", header_name ); + output( "\tpushl $.L__wine_spec_file_name\n" ); + output( "\tpushl $%s\n", header_name ); } - fprintf( outfile, "\tcall %s\n", asm_name("__wine_dll_register_16") ); - fprintf( outfile, "\taddl $12,%%esp\n" ); - fprintf( outfile, "\tret\n" ); - output_function_size( outfile, name ); + output( "\tcall %s\n", asm_name("__wine_dll_register_16") ); + output( "\taddl $12,%%esp\n" ); + output( "\tret\n" ); + output_function_size( name ); sprintf( name, ".L__wine_spec_%s_fini", make_c_identifier(spec->dll_name) ); - fprintf( outfile, "\t.align 4\n" ); - fprintf( outfile, "\t%s\n", func_declaration(name) ); - fprintf( outfile, "%s:\n", name ); - fprintf( outfile, "subl $8,%%esp\n" ); + output( "\t.align 4\n" ); + output( "\t%s\n", func_declaration(name) ); + output( "%s:\n", name ); + output( "subl $8,%%esp\n" ); if (UsePIC) { - fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") ); - fprintf( outfile, "1:\tleal %s-1b(%%eax),%%ecx\n", header_name ); - fprintf( outfile, "\tpushl %%ecx\n" ); + output( "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") ); + output( "1:\tleal %s-1b(%%eax),%%ecx\n", header_name ); + output( "\tpushl %%ecx\n" ); } else { - fprintf( outfile, "\tpushl $%s\n", header_name ); + output( "\tpushl $%s\n", header_name ); } - fprintf( outfile, "\tcall %s\n", asm_name("__wine_dll_unregister_16") ); - fprintf( outfile, "\taddl $12,%%esp\n" ); - fprintf( outfile, "\tret\n" ); - output_function_size( outfile, name ); + output( "\tcall %s\n", asm_name("__wine_dll_unregister_16") ); + output( "\taddl $12,%%esp\n" ); + output( "\tret\n" ); + output_function_size( name ); if (target_platform == PLATFORM_APPLE) { - fprintf( outfile, "\t.mod_init_func\n" ); - fprintf( outfile, "\t.align %d\n", get_alignment(4) ); - fprintf( outfile, "\t.long .L__wine_spec_%s_init\n", make_c_identifier(spec->dll_name) ); - fprintf( outfile, "\t.mod_term_func\n" ); - fprintf( outfile, "\t.align %d\n", get_alignment(4) ); - fprintf( outfile, "\t.long .L__wine_spec_%s_fini\n", make_c_identifier(spec->dll_name) ); + output( "\t.mod_init_func\n" ); + output( "\t.align %d\n", get_alignment(4) ); + output( "\t.long .L__wine_spec_%s_init\n", make_c_identifier(spec->dll_name) ); + output( "\t.mod_term_func\n" ); + output( "\t.align %d\n", get_alignment(4) ); + output( "\t.long .L__wine_spec_%s_fini\n", make_c_identifier(spec->dll_name) ); } else { - fprintf( outfile, "\t.section \".init\",\"ax\"\n" ); - fprintf( outfile, "\tcall .L__wine_spec_%s_init\n", make_c_identifier(spec->dll_name) ); - fprintf( outfile, "\t.section \".fini\",\"ax\"\n" ); - fprintf( outfile, "\tcall .L__wine_spec_%s_fini\n", make_c_identifier(spec->dll_name) ); + output( "\t.section \".init\",\"ax\"\n" ); + output( "\tcall .L__wine_spec_%s_init\n", make_c_identifier(spec->dll_name) ); + output( "\t.section \".fini\",\"ax\"\n" ); + output( "\tcall .L__wine_spec_%s_fini\n", make_c_identifier(spec->dll_name) ); } } @@ -525,7 +525,7 @@ static void output_init_code( FILE *outfile, const DLLSPEC *spec, const char *he * * Build a Win16 assembly file from a spec file. */ -void BuildSpec16File( FILE *outfile, DLLSPEC *spec ) +void BuildSpec16File( DLLSPEC *spec ) { ORDDEF **typelist; int i, j, nb_funcs; @@ -533,7 +533,7 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec ) /* File header */ - output_standard_file_header( outfile ); + output_standard_file_header(); if (!spec->dll_name) /* set default name from file name */ { @@ -558,135 +558,135 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec ) /* Output the module structure */ sprintf( header_name, "__wine_spec_%s_dos_header", make_c_identifier(spec->dll_name) ); - fprintf( outfile, "\n/* module data */\n\n" ); - fprintf( outfile, "\t.data\n" ); - fprintf( outfile, "\t.align %d\n", get_alignment(4) ); - fprintf( outfile, "%s:\n", header_name ); - fprintf( outfile, "\t%s 0x%04x\n", get_asm_short_keyword(), /* e_magic */ + output( "\n/* module data */\n\n" ); + output( "\t.data\n" ); + output( "\t.align %d\n", get_alignment(4) ); + output( "%s:\n", header_name ); + output( "\t%s 0x%04x\n", get_asm_short_keyword(), /* e_magic */ IMAGE_DOS_SIGNATURE ); - fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* e_cblp */ - fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* e_cp */ - fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* e_crlc */ - fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* e_cparhdr */ - fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* e_minalloc */ - fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* e_maxalloc */ - fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* e_ss */ - fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* e_sp */ - fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* e_csum */ - fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* e_ip */ - fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* e_cs */ - fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* e_lfarlc */ - fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* e_ovno */ - fprintf( outfile, "\t%s 0,0,0,0\n", get_asm_short_keyword() ); /* e_res */ - fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* e_oemid */ - fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* e_oeminfo */ - fprintf( outfile, "\t%s 0,0,0,0,0,0,0,0,0,0\n", get_asm_short_keyword() ); /* e_res2 */ - fprintf( outfile, "\t.long .L__wine_spec_ne_header-%s\n", header_name ); /* e_lfanew */ + output( "\t%s 0\n", get_asm_short_keyword() ); /* e_cblp */ + output( "\t%s 0\n", get_asm_short_keyword() ); /* e_cp */ + output( "\t%s 0\n", get_asm_short_keyword() ); /* e_crlc */ + output( "\t%s 0\n", get_asm_short_keyword() ); /* e_cparhdr */ + output( "\t%s 0\n", get_asm_short_keyword() ); /* e_minalloc */ + output( "\t%s 0\n", get_asm_short_keyword() ); /* e_maxalloc */ + output( "\t%s 0\n", get_asm_short_keyword() ); /* e_ss */ + output( "\t%s 0\n", get_asm_short_keyword() ); /* e_sp */ + output( "\t%s 0\n", get_asm_short_keyword() ); /* e_csum */ + output( "\t%s 0\n", get_asm_short_keyword() ); /* e_ip */ + output( "\t%s 0\n", get_asm_short_keyword() ); /* e_cs */ + output( "\t%s 0\n", get_asm_short_keyword() ); /* e_lfarlc */ + output( "\t%s 0\n", get_asm_short_keyword() ); /* e_ovno */ + output( "\t%s 0,0,0,0\n", get_asm_short_keyword() ); /* e_res */ + output( "\t%s 0\n", get_asm_short_keyword() ); /* e_oemid */ + output( "\t%s 0\n", get_asm_short_keyword() ); /* e_oeminfo */ + output( "\t%s 0,0,0,0,0,0,0,0,0,0\n", get_asm_short_keyword() ); /* e_res2 */ + output( "\t.long .L__wine_spec_ne_header-%s\n", header_name ); /* e_lfanew */ - fprintf( outfile, ".L__wine_spec_ne_header:\n" ); - fprintf( outfile, "\t%s 0x%04x\n", get_asm_short_keyword(), /* ne_magic */ + output( ".L__wine_spec_ne_header:\n" ); + output( "\t%s 0x%04x\n", get_asm_short_keyword(), /* ne_magic */ IMAGE_OS2_SIGNATURE ); - fprintf( outfile, "\t.byte 0\n" ); /* ne_ver */ - fprintf( outfile, "\t.byte 0\n" ); /* ne_rev */ - fprintf( outfile, "\t%s .L__wine_spec_ne_enttab-.L__wine_spec_ne_header\n", /* ne_enttab */ + output( "\t.byte 0\n" ); /* ne_ver */ + output( "\t.byte 0\n" ); /* ne_rev */ + output( "\t%s .L__wine_spec_ne_enttab-.L__wine_spec_ne_header\n", /* ne_enttab */ get_asm_short_keyword() ); - fprintf( outfile, "\t%s .L__wine_spec_ne_enttab_end-.L__wine_spec_ne_enttab\n", /* ne_cbenttab */ + output( "\t%s .L__wine_spec_ne_enttab_end-.L__wine_spec_ne_enttab\n", /* ne_cbenttab */ get_asm_short_keyword() ); - fprintf( outfile, "\t.long 0\n" ); /* ne_crc */ - fprintf( outfile, "\t%s 0x%04x\n", get_asm_short_keyword(), /* ne_flags */ + output( "\t.long 0\n" ); /* ne_crc */ + output( "\t%s 0x%04x\n", get_asm_short_keyword(), /* ne_flags */ NE_FFLAGS_SINGLEDATA | NE_FFLAGS_LIBMODULE ); - fprintf( outfile, "\t%s 2\n", get_asm_short_keyword() ); /* ne_autodata */ - fprintf( outfile, "\t%s %u\n", get_asm_short_keyword(), spec->heap_size ); /* ne_heap */ - fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* ne_stack */ - fprintf( outfile, "\t.long 0\n" ); /* ne_csip */ - fprintf( outfile, "\t.long 0\n" ); /* ne_sssp */ - fprintf( outfile, "\t%s 2\n", get_asm_short_keyword() ); /* ne_cseg */ - fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* ne_cmod */ - fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* ne_cbnrestab */ - fprintf( outfile, "\t%s .L__wine_spec_ne_segtab-.L__wine_spec_ne_header\n", /* ne_segtab */ + output( "\t%s 2\n", get_asm_short_keyword() ); /* ne_autodata */ + output( "\t%s %u\n", get_asm_short_keyword(), spec->heap_size ); /* ne_heap */ + output( "\t%s 0\n", get_asm_short_keyword() ); /* ne_stack */ + output( "\t.long 0\n" ); /* ne_csip */ + output( "\t.long 0\n" ); /* ne_sssp */ + output( "\t%s 2\n", get_asm_short_keyword() ); /* ne_cseg */ + output( "\t%s 0\n", get_asm_short_keyword() ); /* ne_cmod */ + output( "\t%s 0\n", get_asm_short_keyword() ); /* ne_cbnrestab */ + output( "\t%s .L__wine_spec_ne_segtab-.L__wine_spec_ne_header\n", /* ne_segtab */ get_asm_short_keyword() ); - fprintf( outfile, "\t%s .L__wine_spec_ne_rsrctab-.L__wine_spec_ne_header\n", /* ne_rsrctab */ + output( "\t%s .L__wine_spec_ne_rsrctab-.L__wine_spec_ne_header\n", /* ne_rsrctab */ get_asm_short_keyword() ); - fprintf( outfile, "\t%s .L__wine_spec_ne_restab-.L__wine_spec_ne_header\n", /* ne_restab */ + output( "\t%s .L__wine_spec_ne_restab-.L__wine_spec_ne_header\n", /* ne_restab */ get_asm_short_keyword() ); - fprintf( outfile, "\t%s .L__wine_spec_ne_modtab-.L__wine_spec_ne_header\n", /* ne_modtab */ + output( "\t%s .L__wine_spec_ne_modtab-.L__wine_spec_ne_header\n", /* ne_modtab */ get_asm_short_keyword() ); - fprintf( outfile, "\t%s .L__wine_spec_ne_imptab-.L__wine_spec_ne_header\n", /* ne_imptab */ + output( "\t%s .L__wine_spec_ne_imptab-.L__wine_spec_ne_header\n", /* ne_imptab */ get_asm_short_keyword() ); - fprintf( outfile, "\t.long 0\n" ); /* ne_nrestab */ - fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* ne_cmovent */ - fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* ne_align */ - fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* ne_cres */ - fprintf( outfile, "\t.byte 0x%02x\n", NE_OSFLAGS_WINDOWS ); /* ne_exetyp */ - fprintf( outfile, "\t.byte 0x%02x\n", NE_AFLAGS_FASTLOAD ); /* ne_flagsothers */ - fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* ne_pretthunks */ - fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* ne_psegrefbytes */ - fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* ne_swaparea */ - fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* ne_expver */ + output( "\t.long 0\n" ); /* ne_nrestab */ + output( "\t%s 0\n", get_asm_short_keyword() ); /* ne_cmovent */ + output( "\t%s 0\n", get_asm_short_keyword() ); /* ne_align */ + output( "\t%s 0\n", get_asm_short_keyword() ); /* ne_cres */ + output( "\t.byte 0x%02x\n", NE_OSFLAGS_WINDOWS ); /* ne_exetyp */ + output( "\t.byte 0x%02x\n", NE_AFLAGS_FASTLOAD ); /* ne_flagsothers */ + output( "\t%s 0\n", get_asm_short_keyword() ); /* ne_pretthunks */ + output( "\t%s 0\n", get_asm_short_keyword() ); /* ne_psegrefbytes */ + output( "\t%s 0\n", get_asm_short_keyword() ); /* ne_swaparea */ + output( "\t%s 0\n", get_asm_short_keyword() ); /* ne_expver */ /* segment table */ - fprintf( outfile, "\n.L__wine_spec_ne_segtab:\n" ); + output( "\n.L__wine_spec_ne_segtab:\n" ); /* code segment entry */ - fprintf( outfile, "\t%s .L__wine_spec_code_segment-%s\n", /* filepos */ + output( "\t%s .L__wine_spec_code_segment-%s\n", /* filepos */ get_asm_short_keyword(), header_name ); - fprintf( outfile, "\t%s .L__wine_spec_code_segment_end-.L__wine_spec_code_segment\n", /* size */ + output( "\t%s .L__wine_spec_code_segment_end-.L__wine_spec_code_segment\n", /* size */ get_asm_short_keyword() ); - fprintf( outfile, "\t%s 0x%04x\n", get_asm_short_keyword(), NE_SEGFLAGS_32BIT ); /* flags */ - fprintf( outfile, "\t%s .L__wine_spec_code_segment_end-.L__wine_spec_code_segment\n", /* minsize */ + output( "\t%s 0x%04x\n", get_asm_short_keyword(), NE_SEGFLAGS_32BIT ); /* flags */ + output( "\t%s .L__wine_spec_code_segment_end-.L__wine_spec_code_segment\n", /* minsize */ get_asm_short_keyword() ); /* data segment entry */ - fprintf( outfile, "\t%s .L__wine_spec_data_segment-%s\n", /* filepos */ + output( "\t%s .L__wine_spec_data_segment-%s\n", /* filepos */ get_asm_short_keyword(), header_name ); - fprintf( outfile, "\t%s .L__wine_spec_data_segment_end-.L__wine_spec_data_segment\n", /* size */ + output( "\t%s .L__wine_spec_data_segment_end-.L__wine_spec_data_segment\n", /* size */ get_asm_short_keyword() ); - fprintf( outfile, "\t%s 0x%04x\n", get_asm_short_keyword(), NE_SEGFLAGS_DATA ); /* flags */ - fprintf( outfile, "\t%s .L__wine_spec_data_segment_end-.L__wine_spec_data_segment\n", /* minsize */ + output( "\t%s 0x%04x\n", get_asm_short_keyword(), NE_SEGFLAGS_DATA ); /* flags */ + output( "\t%s .L__wine_spec_data_segment_end-.L__wine_spec_data_segment\n", /* minsize */ get_asm_short_keyword() ); /* resource directory */ - output_res16_directory( outfile, spec, header_name ); + output_res16_directory( spec, header_name ); /* resident names table */ - fprintf( outfile, "\n\t.align %d\n", get_alignment(2) ); - fprintf( outfile, ".L__wine_spec_ne_restab:\n" ); - output_resident_name( outfile, spec->dll_name, 0 ); + output( "\n\t.align %d\n", get_alignment(2) ); + output( ".L__wine_spec_ne_restab:\n" ); + output_resident_name( spec->dll_name, 0 ); for (i = 1; i <= spec->limit; i++) { ORDDEF *odp = spec->ordinals[i]; if (!odp || !odp->name[0]) continue; - output_resident_name( outfile, odp->name, i ); + output_resident_name( odp->name, i ); } - fprintf( outfile, "\t.byte 0\n" ); + output( "\t.byte 0\n" ); /* imported names table */ - fprintf( outfile, "\n\t.align %d\n", get_alignment(2) ); - fprintf( outfile, ".L__wine_spec_ne_modtab:\n" ); - fprintf( outfile, ".L__wine_spec_ne_imptab:\n" ); - fprintf( outfile, "\t.byte 0,0\n" ); + output( "\n\t.align %d\n", get_alignment(2) ); + output( ".L__wine_spec_ne_modtab:\n" ); + output( ".L__wine_spec_ne_imptab:\n" ); + output( "\t.byte 0,0\n" ); /* entry table */ - fprintf( outfile, "\n.L__wine_spec_ne_enttab:\n" ); - output_entry_table( outfile, spec ); - fprintf( outfile, ".L__wine_spec_ne_enttab_end:\n" ); + output( "\n.L__wine_spec_ne_enttab:\n" ); + output_entry_table( spec ); + output( ".L__wine_spec_ne_enttab_end:\n" ); /* code segment */ - fprintf( outfile, "\n\t.align %d\n", get_alignment(2) ); - fprintf( outfile, ".L__wine_spec_code_segment:\n" ); + output( "\n\t.align %d\n", get_alignment(2) ); + output( ".L__wine_spec_code_segment:\n" ); for ( i = 0; i < nb_funcs; i++ ) { unsigned int arg_types[2]; - int j, nop_words, argsize = 0; + int nop_words, argsize = 0; if ( typelist[i]->type == TYPE_PASCAL ) argsize = get_function_argsize( typelist[i] ); @@ -709,9 +709,9 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec ) } if (typelist[i]->type == TYPE_VARARGS) arg_types[j / 10] |= ARG_VARARG << (3 * (j % 10)); - fprintf( outfile, ".L__wine_spec_callfrom16_%s:\n", get_callfrom16_name(typelist[i]) ); - fprintf( outfile, "\tpushl $.L__wine_spec_call16_%s\n", get_relay_name(typelist[i]) ); - fprintf( outfile, "\tlcall $0,$0\n" ); + output( ".L__wine_spec_callfrom16_%s:\n", get_callfrom16_name(typelist[i]) ); + output( "\tpushl $.L__wine_spec_call16_%s\n", get_relay_name(typelist[i]) ); + output( "\tlcall $0,$0\n" ); if (typelist[i]->flags & FLAG_REGISTER) { @@ -719,90 +719,91 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec ) } else if (typelist[i]->flags & FLAG_RET16) { - fprintf( outfile, "\torw %%ax,%%ax\n" ); - fprintf( outfile, "\tnop\n" ); /* so that the lretw is aligned */ + output( "\torw %%ax,%%ax\n" ); + output( "\tnop\n" ); /* so that the lretw is aligned */ nop_words = 2; } else { - fprintf( outfile, "shld $16,%%eax,%%edx\n" ); - fprintf( outfile, "orl %%eax,%%eax\n" ); + output( "\tshld $16,%%eax,%%edx\n" ); + output( "\torl %%eax,%%eax\n" ); nop_words = 1; } if (argsize) { - fprintf( outfile, "lretw $%u\n", argsize ); + output( "\tlretw $%u\n", argsize ); nop_words--; } - else fprintf( outfile, "lretw\n" ); + else output( "\tlretw\n" ); - if (nop_words) fprintf( outfile, "\t%s\n", nop_sequence[nop_words-1] ); + if (nop_words) output( "\t%s\n", nop_sequence[nop_words-1] ); /* the movl is here so that the code contains only valid instructions, */ /* it's never actually executed, we only care about the arg_types[] values */ - fprintf( outfile, "\t%s 0x86c7\n", get_asm_short_keyword() ); - fprintf( outfile, "\t.long 0x%08x,0x%08x\n", arg_types[0], arg_types[1] ); + output( "\t%s 0x86c7\n", get_asm_short_keyword() ); + output( "\t.long 0x%08x,0x%08x\n", arg_types[0], arg_types[1] ); } for (i = 0; i <= spec->limit; i++) { ORDDEF *odp = spec->ordinals[i]; if (!odp || !is_function( odp )) continue; - fprintf( outfile, ".L__wine_%s_%u:\n", make_c_identifier(spec->dll_name), i ); - fprintf( outfile, "\tpushw %%bp\n" ); - fprintf( outfile, "\tpushl $%s\n", + output( ".L__wine_%s_%u:\n", make_c_identifier(spec->dll_name), i ); + output( "\tpushw %%bp\n" ); + output( "\tpushl $%s\n", asm_name( odp->type == TYPE_STUB ? get_stub_name( odp, spec ) : odp->link_name )); - fprintf( outfile, "\tcallw .L__wine_spec_callfrom16_%s\n", get_callfrom16_name( odp ) ); + output( "\tcallw .L__wine_spec_callfrom16_%s\n", get_callfrom16_name( odp ) ); } - fprintf( outfile, ".L__wine_spec_code_segment_end:\n" ); + output( ".L__wine_spec_code_segment_end:\n" ); /* data segment */ - fprintf( outfile, "\n.L__wine_spec_data_segment:\n" ); - fprintf( outfile, "\t.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n" ); /* instance data */ + output( "\n.L__wine_spec_data_segment:\n" ); + output( "\t.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n" ); /* instance data */ for (i = 0; i <= spec->limit; i++) { ORDDEF *odp = spec->ordinals[i]; if (!odp || odp->type != TYPE_VARIABLE) continue; - fprintf( outfile, ".L__wine_%s_%u:\n", make_c_identifier(spec->dll_name), i ); - fprintf( outfile, "\t.long " ); + output( ".L__wine_%s_%u:\n", make_c_identifier(spec->dll_name), i ); + output( "\t.long " ); for (j = 0; j < odp->u.var.n_values-1; j++) - fprintf( outfile, "0x%08x,", odp->u.var.values[j] ); - fprintf( outfile, "0x%08x\n", odp->u.var.values[j] ); + output( "0x%08x,", odp->u.var.values[j] ); + output( "0x%08x\n", odp->u.var.values[j] ); } - fprintf( outfile, ".L__wine_spec_data_segment_end:\n" ); + output( ".L__wine_spec_data_segment_end:\n" ); /* resource data */ if (spec->nb_resources) { - fprintf( outfile, "\n.L__wine_spec_resource_data:\n" ); - output_res16_data( outfile, spec ); + output( "\n.L__wine_spec_resource_data:\n" ); + output_res16_data( spec ); } - fprintf( outfile, "\t.byte 0\n" ); /* make sure the last symbol points to something */ + output( "\t.byte 0\n" ); /* make sure the last symbol points to something */ /* relay functions */ nb_funcs = sort_func_list( typelist, nb_funcs, relay_type_compare ); if (nb_funcs) { - fprintf( outfile, "\n/* relay functions */\n\n" ); - fprintf( outfile, "\t.text\n" ); - for ( i = 0; i < nb_funcs; i++ ) output_call16_function( outfile, typelist[i] ); - fprintf( outfile, "\t.data\n" ); - fprintf( outfile, "wine_ldt_copy_ptr:\n" ); - fprintf( outfile, "\t.long %s\n", asm_name("wine_ldt_copy") ); + output( "\n/* relay functions */\n\n" ); + output( "\t.text\n" ); + for ( i = 0; i < nb_funcs; i++ ) output_call16_function( typelist[i] ); + output( "\t.data\n" ); + output( "wine_ldt_copy_ptr:\n" ); + output( "\t.long %s\n", asm_name("wine_ldt_copy") ); } - fprintf( outfile, "\n\t%s\n", get_asm_string_section() ); - fprintf( outfile, ".L__wine_spec_file_name:\n" ); - fprintf( outfile, "\t%s \"%s\"\n", get_asm_string_keyword(), spec->file_name ); + output( "\n\t%s\n", get_asm_string_section() ); + output( ".L__wine_spec_file_name:\n" ); + output( "\t%s \"%s\"\n", get_asm_string_keyword(), spec->file_name ); - output_stubs( outfile, spec ); - output_get_pc_thunk( outfile ); - output_init_code( outfile, spec, header_name ); + output_stubs( spec ); + output_get_pc_thunk(); + output_init_code( spec, header_name ); + output_gnu_stack_note(); free( typelist ); } diff --git a/reactos/tools/winebuild/spec32.c b/reactos/tools/winebuild/spec32.c index bf45ffdb469..c37fdac112e 100644 --- a/reactos/tools/winebuild/spec32.c +++ b/reactos/tools/winebuild/spec32.c @@ -19,21 +19,20 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include "config.h" +#include "wine/port.h" #include #include #include #include -#include "winglue.h" - -#define EXCEPTION_WINE_STUB 0x80000100 /* stub entry point called */ -#define EH_NONCONTINUABLE 0x01 - +#include "windef.h" +#include "winbase.h" +//#include "wine/exception.h" #include "build.h" @@ -52,7 +51,7 @@ static inline int needs_relay( const ORDDEF *odp ) /* check if dll will output relay thunks */ int has_relays( DLLSPEC *spec ) { - unsigned int i; + int i; if (target_cpu != CPU_x86) return 0; @@ -91,30 +90,31 @@ static const char *make_internal_name( const ORDDEF *odp, DLLSPEC *spec, const c * * Output entry points for relay debugging */ -static void output_relay_debug( FILE *outfile, DLLSPEC *spec ) +static void output_relay_debug( DLLSPEC *spec ) { - unsigned int i, j, args, flags; + int i; + unsigned int j, args, flags; /* first the table of entry point offsets */ - fprintf( outfile, "\t%s\n", get_asm_rodata_section() ); - fprintf( outfile, "\t.align %d\n", get_alignment(4) ); - fprintf( outfile, ".L__wine_spec_relay_entry_point_offsets:\n" ); + output( "\t%s\n", get_asm_rodata_section() ); + output( "\t.align %d\n", get_alignment(4) ); + output( ".L__wine_spec_relay_entry_point_offsets:\n" ); for (i = spec->base; i <= spec->limit; i++) { ORDDEF *odp = spec->ordinals[i]; if (needs_relay( odp )) - fprintf( outfile, "\t.long .L__wine_spec_relay_entry_point_%d-__wine_spec_relay_entry_points\n", i ); + output( "\t.long .L__wine_spec_relay_entry_point_%d-__wine_spec_relay_entry_points\n", i ); else - fprintf( outfile, "\t.long 0\n" ); + output( "\t.long 0\n" ); } /* then the table of argument types */ - fprintf( outfile, "\t.align %d\n", get_alignment(4) ); - fprintf( outfile, ".L__wine_spec_relay_arg_types:\n" ); + output( "\t.align %d\n", get_alignment(4) ); + output( ".L__wine_spec_relay_arg_types:\n" ); for (i = spec->base; i <= spec->limit; i++) { @@ -129,14 +129,14 @@ static void output_relay_debug( FILE *outfile, DLLSPEC *spec ) if (odp->u.func.arg_types[j] == 'W') mask |= 2<< (j*2); } } - fprintf( outfile, "\t.long 0x%08x\n", mask ); + output( "\t.long 0x%08x\n", mask ); } /* then the relay thunks */ - fprintf( outfile, "\t.text\n" ); - fprintf( outfile, "__wine_spec_relay_entry_points:\n" ); - fprintf( outfile, "\tnop\n" ); /* to avoid 0 offset */ + output( "\t.text\n" ); + output( "__wine_spec_relay_entry_points:\n" ); + output( "\tnop\n" ); /* to avoid 0 offset */ for (i = spec->base; i <= spec->limit; i++) { @@ -144,39 +144,39 @@ static void output_relay_debug( FILE *outfile, DLLSPEC *spec ) if (!needs_relay( odp )) continue; - fprintf( outfile, "\t.align %d\n", get_alignment(4) ); - fprintf( outfile, ".L__wine_spec_relay_entry_point_%d:\n", i ); + output( "\t.align %d\n", get_alignment(4) ); + output( ".L__wine_spec_relay_entry_point_%d:\n", i ); if (odp->flags & FLAG_REGISTER) - fprintf( outfile, "\tpushl %%eax\n" ); + output( "\tpushl %%eax\n" ); else - fprintf( outfile, "\tpushl %%esp\n" ); + output( "\tpushl %%esp\n" ); args = strlen(odp->u.func.arg_types); flags = 0; if (odp->flags & FLAG_RET64) flags |= 1; if (odp->type == TYPE_STDCALL) flags |= 2; - fprintf( outfile, "\tpushl $%u\n", (flags << 24) | (args << 16) | (i - spec->base) ); + output( "\tpushl $%u\n", (flags << 24) | (args << 16) | (i - spec->base) ); if (UsePIC) { - fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") ); - fprintf( outfile, "1:\tleal .L__wine_spec_relay_descr-1b(%%eax),%%eax\n" ); + output( "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") ); + output( "1:\tleal .L__wine_spec_relay_descr-1b(%%eax),%%eax\n" ); } - else fprintf( outfile, "\tmovl $.L__wine_spec_relay_descr,%%eax\n" ); - fprintf( outfile, "\tpushl %%eax\n" ); + else output( "\tmovl $.L__wine_spec_relay_descr,%%eax\n" ); + output( "\tpushl %%eax\n" ); if (odp->flags & FLAG_REGISTER) { - fprintf( outfile, "\tcall *8(%%eax)\n" ); + output( "\tcall *8(%%eax)\n" ); } else { - fprintf( outfile, "\tcall *4(%%eax)\n" ); + output( "\tcall *4(%%eax)\n" ); if (odp->type == TYPE_STDCALL) - fprintf( outfile, "\tret $%u\n", args * get_ptr_size() ); + output( "\tret $%u\n", args * get_ptr_size() ); else - fprintf( outfile, "\tret\n" ); + output( "\tret\n" ); } } } @@ -186,46 +186,46 @@ static void output_relay_debug( FILE *outfile, DLLSPEC *spec ) * * Output the export table for a Win32 module. */ -static void output_exports( FILE *outfile, DLLSPEC *spec ) +static void output_exports( DLLSPEC *spec ) { int i, fwd_size = 0; int nr_exports = spec->base <= spec->limit ? spec->limit - spec->base + 1 : 0; if (!nr_exports) return; - fprintf( outfile, "\n/* export table */\n\n" ); - fprintf( outfile, "\t.data\n" ); - fprintf( outfile, "\t.align %d\n", get_alignment(4) ); - fprintf( outfile, ".L__wine_spec_exports:\n" ); + output( "\n/* export table */\n\n" ); + output( "\t.data\n" ); + output( "\t.align %d\n", get_alignment(4) ); + output( ".L__wine_spec_exports:\n" ); /* export directory header */ - fprintf( outfile, "\t.long 0\n" ); /* Characteristics */ - fprintf( outfile, "\t.long 0\n" ); /* TimeDateStamp */ - fprintf( outfile, "\t.long 0\n" ); /* MajorVersion/MinorVersion */ - fprintf( outfile, "\t.long .L__wine_spec_exp_names-.L__wine_spec_rva_base\n" ); /* Name */ - fprintf( outfile, "\t.long %u\n", spec->base ); /* Base */ - fprintf( outfile, "\t.long %u\n", nr_exports ); /* NumberOfFunctions */ - fprintf( outfile, "\t.long %u\n", spec->nb_names ); /* NumberOfNames */ - fprintf( outfile, "\t.long .L__wine_spec_exports_funcs-.L__wine_spec_rva_base\n" ); /* AddressOfFunctions */ + output( "\t.long 0\n" ); /* Characteristics */ + output( "\t.long 0\n" ); /* TimeDateStamp */ + output( "\t.long 0\n" ); /* MajorVersion/MinorVersion */ + output( "\t.long .L__wine_spec_exp_names-.L__wine_spec_rva_base\n" ); /* Name */ + output( "\t.long %u\n", spec->base ); /* Base */ + output( "\t.long %u\n", nr_exports ); /* NumberOfFunctions */ + output( "\t.long %u\n", spec->nb_names ); /* NumberOfNames */ + output( "\t.long .L__wine_spec_exports_funcs-.L__wine_spec_rva_base\n" ); /* AddressOfFunctions */ if (spec->nb_names) { - fprintf( outfile, "\t.long .L__wine_spec_exp_name_ptrs-.L__wine_spec_rva_base\n" ); /* AddressOfNames */ - fprintf( outfile, "\t.long .L__wine_spec_exp_ordinals-.L__wine_spec_rva_base\n" ); /* AddressOfNameOrdinals */ + output( "\t.long .L__wine_spec_exp_name_ptrs-.L__wine_spec_rva_base\n" ); /* AddressOfNames */ + output( "\t.long .L__wine_spec_exp_ordinals-.L__wine_spec_rva_base\n" ); /* AddressOfNameOrdinals */ } else { - fprintf( outfile, "\t.long 0\n" ); /* AddressOfNames */ - fprintf( outfile, "\t.long 0\n" ); /* AddressOfNameOrdinals */ + output( "\t.long 0\n" ); /* AddressOfNames */ + output( "\t.long 0\n" ); /* AddressOfNameOrdinals */ } /* output the function pointers */ - fprintf( outfile, "\n.L__wine_spec_exports_funcs:\n" ); + output( "\n.L__wine_spec_exports_funcs:\n" ); for (i = spec->base; i <= spec->limit; i++) { ORDDEF *odp = spec->ordinals[i]; - if (!odp) fprintf( outfile, "\t.long 0\n" ); + if (!odp) output( "\t%s 0\n", get_asm_ptr_keyword() ); else switch(odp->type) { case TYPE_EXTERN: @@ -234,21 +234,21 @@ static void output_exports( FILE *outfile, DLLSPEC *spec ) case TYPE_CDECL: if (odp->flags & FLAG_FORWARD) { - fprintf( outfile, "\t%s .L__wine_spec_forwards+%u\n", get_asm_ptr_keyword(), fwd_size ); + output( "\t%s .L__wine_spec_forwards+%u\n", get_asm_ptr_keyword(), fwd_size ); fwd_size += strlen(odp->link_name) + 1; } else if (odp->flags & FLAG_EXT_LINK) { - fprintf( outfile, "\t%s %s_%s\n", + output( "\t%s %s_%s\n", get_asm_ptr_keyword(), asm_name("__wine_spec_ext_link"), odp->link_name ); } else { - fprintf( outfile, "\t%s %s\n", get_asm_ptr_keyword(), asm_name(odp->link_name) ); + output( "\t%s %s\n", get_asm_ptr_keyword(), asm_name(odp->link_name) ); } break; case TYPE_STUB: - fprintf( outfile, "\t%s %s\n", get_asm_ptr_keyword(), + output( "\t%s %s\n", get_asm_ptr_keyword(), asm_name( get_stub_name( odp, spec )) ); break; default: @@ -262,68 +262,68 @@ static void output_exports( FILE *outfile, DLLSPEC *spec ) int namepos = strlen(spec->file_name) + 1; - fprintf( outfile, "\n.L__wine_spec_exp_name_ptrs:\n" ); + output( "\n.L__wine_spec_exp_name_ptrs:\n" ); for (i = 0; i < spec->nb_names; i++) { - fprintf( outfile, "\t.long .L__wine_spec_exp_names+%u-.L__wine_spec_rva_base\n", namepos ); + output( "\t.long .L__wine_spec_exp_names+%u-.L__wine_spec_rva_base\n", namepos ); namepos += strlen(spec->names[i]->name) + 1; } /* output the function ordinals */ - fprintf( outfile, "\n.L__wine_spec_exp_ordinals:\n" ); + output( "\n.L__wine_spec_exp_ordinals:\n" ); for (i = 0; i < spec->nb_names; i++) { - fprintf( outfile, "\t%s %d\n", + output( "\t%s %d\n", get_asm_short_keyword(), spec->names[i]->ordinal - spec->base ); } if (spec->nb_names % 2) { - fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); + output( "\t%s 0\n", get_asm_short_keyword() ); } } /* output the export name strings */ - fprintf( outfile, "\n.L__wine_spec_exp_names:\n" ); - fprintf( outfile, "\t%s \"%s\"\n", get_asm_string_keyword(), spec->file_name ); + output( "\n.L__wine_spec_exp_names:\n" ); + output( "\t%s \"%s\"\n", get_asm_string_keyword(), spec->file_name ); for (i = 0; i < spec->nb_names; i++) - fprintf( outfile, "\t%s \"%s\"\n", + output( "\t%s \"%s\"\n", get_asm_string_keyword(), spec->names[i]->name ); /* output forward strings */ if (fwd_size) { - fprintf( outfile, "\n.L__wine_spec_forwards:\n" ); + output( "\n.L__wine_spec_forwards:\n" ); for (i = spec->base; i <= spec->limit; i++) { ORDDEF *odp = spec->ordinals[i]; if (odp && (odp->flags & FLAG_FORWARD)) - fprintf( outfile, "\t%s \"%s\"\n", get_asm_string_keyword(), odp->link_name ); + output( "\t%s \"%s\"\n", get_asm_string_keyword(), odp->link_name ); } } - fprintf( outfile, "\t.align %d\n", get_alignment(get_ptr_size()) ); - fprintf( outfile, ".L__wine_spec_exports_end:\n" ); + output( "\t.align %d\n", get_alignment(get_ptr_size()) ); + output( ".L__wine_spec_exports_end:\n" ); /* output relays */ /* we only support relay debugging on i386 */ if (target_cpu != CPU_x86) { - fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() ); + output( "\t%s 0\n", get_asm_ptr_keyword() ); return; } - fprintf( outfile, ".L__wine_spec_relay_descr:\n" ); - fprintf( outfile, "\t%s 0xdeb90001\n", get_asm_ptr_keyword() ); /* magic */ - fprintf( outfile, "\t%s 0,0\n", get_asm_ptr_keyword() ); /* relay funcs */ - fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() ); /* private data */ - fprintf( outfile, "\t%s __wine_spec_relay_entry_points\n", get_asm_ptr_keyword() ); - fprintf( outfile, "\t%s .L__wine_spec_relay_entry_point_offsets\n", get_asm_ptr_keyword() ); - fprintf( outfile, "\t%s .L__wine_spec_relay_arg_types\n", get_asm_ptr_keyword() ); + output( ".L__wine_spec_relay_descr:\n" ); + output( "\t%s 0xdeb90001\n", get_asm_ptr_keyword() ); /* magic */ + output( "\t%s 0,0\n", get_asm_ptr_keyword() ); /* relay funcs */ + output( "\t%s 0\n", get_asm_ptr_keyword() ); /* private data */ + output( "\t%s __wine_spec_relay_entry_points\n", get_asm_ptr_keyword() ); + output( "\t%s .L__wine_spec_relay_entry_point_offsets\n", get_asm_ptr_keyword() ); + output( "\t%s .L__wine_spec_relay_arg_types\n", get_asm_ptr_keyword() ); - output_relay_debug( outfile, spec ); + output_relay_debug( spec ); } @@ -332,7 +332,7 @@ static void output_exports( FILE *outfile, DLLSPEC *spec ) * * Output the functions for stub entry points */ -static void output_stub_funcs( FILE *outfile, DLLSPEC *spec ) +static void output_stub_funcs( DLLSPEC *spec ) { int i; @@ -354,13 +354,13 @@ static void output_stub_funcs( FILE *outfile, DLLSPEC *spec ) { const ORDDEF *odp = &spec->entry_points[i]; if (odp->type != TYPE_STUB) continue; - fprintf( outfile, "void %s(void) ", make_internal_name( odp, spec, "stub" ) ); + output( "void %s(void) ", make_internal_name( odp, spec, "stub" ) ); if (odp->name) - fprintf( outfile, "{ __wine_spec_unimplemented_stub(__wine_spec_file_name, \"%s\"); }\n", odp->name ); + output( "{ __wine_spec_unimplemented_stub(__wine_spec_file_name, \"%s\"); }\n", odp->name ); else if (odp->export_name) - fprintf( outfile, "{ __wine_spec_unimplemented_stub(__wine_spec_file_name, \"%s\"); }\n", odp->export_name ); + output( "{ __wine_spec_unimplemented_stub(__wine_spec_file_name, \"%s\"); }\n", odp->export_name ); else - fprintf( outfile, "{ __wine_spec_unimplemented_stub(__wine_spec_file_name, \"%d\"); }\n", odp->ordinal ); + output( "{ __wine_spec_unimplemented_stub(__wine_spec_file_name, \"%d\"); }\n", odp->ordinal ); } } @@ -370,33 +370,33 @@ static void output_stub_funcs( FILE *outfile, DLLSPEC *spec ) * * Output code for calling a dll constructor. */ -static void output_asm_constructor( FILE *outfile, const char *constructor ) +static void output_asm_constructor( const char *constructor ) { if (target_platform == PLATFORM_APPLE) { /* Mach-O doesn't have an init section */ - fprintf( outfile, "\n\t.mod_init_func\n" ); - fprintf( outfile, "\t.align %d\n", get_alignment(4) ); - fprintf( outfile, "\t.long %s\n", asm_name(constructor) ); + output( "\n\t.mod_init_func\n" ); + output( "\t.align %d\n", get_alignment(4) ); + output( "\t.long %s\n", asm_name(constructor) ); } else { - fprintf( outfile, "\n\t.section \".init\",\"ax\"\n" ); + output( "\n\t.section \".init\",\"ax\"\n" ); switch(target_cpu) { case CPU_x86: case CPU_x86_64: - fprintf( outfile, "\tcall %s\n", asm_name(constructor) ); + output( "\tcall %s\n", asm_name(constructor) ); break; case CPU_SPARC: - fprintf( outfile, "\tcall %s\n", asm_name(constructor) ); - fprintf( outfile, "\tnop\n" ); + output( "\tcall %s\n", asm_name(constructor) ); + output( "\tnop\n" ); break; case CPU_ALPHA: - fprintf( outfile, "\tjsr $26,%s\n", asm_name(constructor) ); + output( "\tjsr $26,%s\n", asm_name(constructor) ); break; case CPU_POWERPC: - fprintf( outfile, "\tbl %s\n", asm_name(constructor) ); + output( "\tbl %s\n", asm_name(constructor) ); break; } } @@ -408,32 +408,32 @@ static void output_asm_constructor( FILE *outfile, const char *constructor ) * * Build a Win32 C file from a spec file. */ -void BuildSpec32File( FILE *outfile, DLLSPEC *spec ) +void BuildSpec32File( DLLSPEC *spec ) { int machine = 0; unsigned int page_size = get_page_size(); resolve_imports( spec ); - output_standard_file_header( outfile ); + output_standard_file_header(); /* Reserve some space for the PE header */ - fprintf( outfile, "\t.text\n" ); - fprintf( outfile, "\t.align %d\n", get_alignment(page_size) ); - fprintf( outfile, "__wine_spec_pe_header:\n" ); + output( "\t.text\n" ); + output( "\t.align %d\n", get_alignment(page_size) ); + output( "__wine_spec_pe_header:\n" ); if (target_platform == PLATFORM_APPLE) - fprintf( outfile, "\t.space 65536\n" ); + output( "\t.space 65536\n" ); else - fprintf( outfile, "\t.skip 65536\n" ); + output( "\t.skip 65536\n" ); /* Output the NT header */ - fprintf( outfile, "\n\t.data\n" ); - fprintf( outfile, "\t.align %d\n", get_alignment(get_ptr_size()) ); - fprintf( outfile, "%s\n", asm_globl("__wine_spec_nt_header") ); - fprintf( outfile, ".L__wine_spec_rva_base:\n" ); + output( "\n\t.data\n" ); + output( "\t.align %d\n", get_alignment(get_ptr_size()) ); + output( "%s\n", asm_globl("__wine_spec_nt_header") ); + output( ".L__wine_spec_rva_base:\n" ); - fprintf( outfile, "\t.long 0x%04x\n", IMAGE_NT_SIGNATURE ); /* Signature */ + output( "\t.long 0x%04x\n", IMAGE_NT_SIGNATURE ); /* Signature */ switch(target_cpu) { case CPU_x86: machine = IMAGE_FILE_MACHINE_I386; break; @@ -442,104 +442,105 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec ) case CPU_ALPHA: machine = IMAGE_FILE_MACHINE_ALPHA; break; case CPU_SPARC: machine = IMAGE_FILE_MACHINE_UNKNOWN; break; } - fprintf( outfile, "\t%s 0x%04x\n", /* Machine */ + output( "\t%s 0x%04x\n", /* Machine */ get_asm_short_keyword(), machine ); - fprintf( outfile, "\t%s 0\n", /* NumberOfSections */ + output( "\t%s 0\n", /* NumberOfSections */ get_asm_short_keyword() ); - fprintf( outfile, "\t.long 0\n" ); /* TimeDateStamp */ - fprintf( outfile, "\t.long 0\n" ); /* PointerToSymbolTable */ - fprintf( outfile, "\t.long 0\n" ); /* NumberOfSymbols */ - fprintf( outfile, "\t%s %d\n", /* SizeOfOptionalHeader */ + output( "\t.long 0\n" ); /* TimeDateStamp */ + output( "\t.long 0\n" ); /* PointerToSymbolTable */ + output( "\t.long 0\n" ); /* NumberOfSymbols */ + output( "\t%s %d\n", /* SizeOfOptionalHeader */ get_asm_short_keyword(), get_ptr_size() == 8 ? IMAGE_SIZEOF_NT_OPTIONAL64_HEADER : IMAGE_SIZEOF_NT_OPTIONAL32_HEADER ); - fprintf( outfile, "\t%s 0x%04x\n", /* Characteristics */ + output( "\t%s 0x%04x\n", /* Characteristics */ get_asm_short_keyword(), spec->characteristics ); - fprintf( outfile, "\t%s 0x%04x\n", /* Magic */ + output( "\t%s 0x%04x\n", /* Magic */ get_asm_short_keyword(), get_ptr_size() == 8 ? IMAGE_NT_OPTIONAL_HDR64_MAGIC : IMAGE_NT_OPTIONAL_HDR32_MAGIC ); - fprintf( outfile, "\t.byte 0\n" ); /* MajorLinkerVersion */ - fprintf( outfile, "\t.byte 0\n" ); /* MinorLinkerVersion */ - fprintf( outfile, "\t.long 0\n" ); /* SizeOfCode */ - fprintf( outfile, "\t.long 0\n" ); /* SizeOfInitializedData */ - fprintf( outfile, "\t.long 0\n" ); /* SizeOfUninitializedData */ + output( "\t.byte 0\n" ); /* MajorLinkerVersion */ + output( "\t.byte 0\n" ); /* MinorLinkerVersion */ + output( "\t.long 0\n" ); /* SizeOfCode */ + output( "\t.long 0\n" ); /* SizeOfInitializedData */ + output( "\t.long 0\n" ); /* SizeOfUninitializedData */ /* note: we expand the AddressOfEntryPoint field on 64-bit by overwriting the BaseOfCode field */ - fprintf( outfile, "\t%s %s\n", /* AddressOfEntryPoint */ + output( "\t%s %s\n", /* AddressOfEntryPoint */ get_asm_ptr_keyword(), asm_name(spec->init_func) ); if (get_ptr_size() == 4) { - fprintf( outfile, "\t.long 0\n" ); /* BaseOfCode */ - fprintf( outfile, "\t.long 0\n" ); /* BaseOfData */ + output( "\t.long 0\n" ); /* BaseOfCode */ + output( "\t.long 0\n" ); /* BaseOfData */ } - fprintf( outfile, "\t%s __wine_spec_pe_header\n", /* ImageBase */ + output( "\t%s __wine_spec_pe_header\n", /* ImageBase */ get_asm_ptr_keyword() ); - fprintf( outfile, "\t.long %u\n", page_size ); /* SectionAlignment */ - fprintf( outfile, "\t.long %u\n", page_size ); /* FileAlignment */ - fprintf( outfile, "\t%s 1,0\n", /* Major/MinorOperatingSystemVersion */ + output( "\t.long %u\n", page_size ); /* SectionAlignment */ + output( "\t.long %u\n", page_size ); /* FileAlignment */ + output( "\t%s 1,0\n", /* Major/MinorOperatingSystemVersion */ get_asm_short_keyword() ); - fprintf( outfile, "\t%s 0,0\n", /* Major/MinorImageVersion */ + output( "\t%s 0,0\n", /* Major/MinorImageVersion */ get_asm_short_keyword() ); - fprintf( outfile, "\t%s %u,%u\n", /* Major/MinorSubsystemVersion */ + output( "\t%s %u,%u\n", /* Major/MinorSubsystemVersion */ get_asm_short_keyword(), spec->subsystem_major, spec->subsystem_minor ); - fprintf( outfile, "\t.long 0\n" ); /* Win32VersionValue */ - fprintf( outfile, "\t.long %s-.L__wine_spec_rva_base\n", /* SizeOfImage */ + output( "\t.long 0\n" ); /* Win32VersionValue */ + output( "\t.long %s-.L__wine_spec_rva_base\n", /* SizeOfImage */ asm_name("_end") ); - fprintf( outfile, "\t.long %u\n", page_size ); /* SizeOfHeaders */ - fprintf( outfile, "\t.long 0\n" ); /* CheckSum */ - fprintf( outfile, "\t%s 0x%04x\n", /* Subsystem */ + output( "\t.long %u\n", page_size ); /* SizeOfHeaders */ + output( "\t.long 0\n" ); /* CheckSum */ + output( "\t%s 0x%04x\n", /* Subsystem */ get_asm_short_keyword(), spec->subsystem ); - fprintf( outfile, "\t%s 0\n", /* DllCharacteristics */ - get_asm_short_keyword() ); - fprintf( outfile, "\t%s %u,%u\n", /* SizeOfStackReserve/Commit */ + output( "\t%s 0x%04x\n", /* DllCharacteristics */ + get_asm_short_keyword(), spec->dll_characteristics ); + output( "\t%s %u,%u\n", /* SizeOfStackReserve/Commit */ get_asm_ptr_keyword(), (spec->stack_size ? spec->stack_size : 1024) * 1024, page_size ); - fprintf( outfile, "\t%s %u,%u\n", /* SizeOfHeapReserve/Commit */ + output( "\t%s %u,%u\n", /* SizeOfHeapReserve/Commit */ get_asm_ptr_keyword(), (spec->heap_size ? spec->heap_size : 1024) * 1024, page_size ); - fprintf( outfile, "\t.long 0\n" ); /* LoaderFlags */ - fprintf( outfile, "\t.long 16\n" ); /* NumberOfRvaAndSizes */ + output( "\t.long 0\n" ); /* LoaderFlags */ + output( "\t.long 16\n" ); /* NumberOfRvaAndSizes */ if (spec->base <= spec->limit) /* DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT] */ - fprintf( outfile, "\t.long .L__wine_spec_exports-.L__wine_spec_rva_base," + output( "\t.long .L__wine_spec_exports-.L__wine_spec_rva_base," ".L__wine_spec_exports_end-.L__wine_spec_exports\n" ); else - fprintf( outfile, "\t.long 0,0\n" ); + output( "\t.long 0,0\n" ); if (has_imports()) /* DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] */ - fprintf( outfile, "\t.long .L__wine_spec_imports-.L__wine_spec_rva_base," + output( "\t.long .L__wine_spec_imports-.L__wine_spec_rva_base," ".L__wine_spec_imports_end-.L__wine_spec_imports\n" ); else - fprintf( outfile, "\t.long 0,0\n" ); + output( "\t.long 0,0\n" ); if (spec->nb_resources) /* DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE] */ - fprintf( outfile, "\t.long .L__wine_spec_resources-.L__wine_spec_rva_base," + output( "\t.long .L__wine_spec_resources-.L__wine_spec_rva_base," ".L__wine_spec_resources_end-.L__wine_spec_resources\n" ); else - fprintf( outfile, "\t.long 0,0\n" ); + output( "\t.long 0,0\n" ); - fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[3] */ - fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[4] */ - fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[5] */ - fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[6] */ - fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[7] */ - fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[8] */ - fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[9] */ - fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[10] */ - fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[11] */ - fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[12] */ - fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[13] */ - fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[14] */ - fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[15] */ + output( "\t.long 0,0\n" ); /* DataDirectory[3] */ + output( "\t.long 0,0\n" ); /* DataDirectory[4] */ + output( "\t.long 0,0\n" ); /* DataDirectory[5] */ + output( "\t.long 0,0\n" ); /* DataDirectory[6] */ + output( "\t.long 0,0\n" ); /* DataDirectory[7] */ + output( "\t.long 0,0\n" ); /* DataDirectory[8] */ + output( "\t.long 0,0\n" ); /* DataDirectory[9] */ + output( "\t.long 0,0\n" ); /* DataDirectory[10] */ + output( "\t.long 0,0\n" ); /* DataDirectory[11] */ + output( "\t.long 0,0\n" ); /* DataDirectory[12] */ + output( "\t.long 0,0\n" ); /* DataDirectory[13] */ + output( "\t.long 0,0\n" ); /* DataDirectory[14] */ + output( "\t.long 0,0\n" ); /* DataDirectory[15] */ - fprintf( outfile, "\n\t%s\n", get_asm_string_section() ); - fprintf( outfile, "%s\n", asm_globl("__wine_spec_file_name") ); - fprintf( outfile, ".L__wine_spec_file_name:\n" ); - fprintf( outfile, "\t%s \"%s\"\n", get_asm_string_keyword(), spec->file_name ); + output( "\n\t%s\n", get_asm_string_section() ); + output( "%s\n", asm_globl("__wine_spec_file_name") ); + output( ".L__wine_spec_file_name:\n" ); + output( "\t%s \"%s\"\n", get_asm_string_keyword(), spec->file_name ); if (target_platform == PLATFORM_APPLE) - fprintf( outfile, "\t.lcomm %s,4\n", asm_name("_end") ); + output( "\t.lcomm %s,4\n", asm_name("_end") ); - output_stubs( outfile, spec ); - output_exports( outfile, spec ); - output_imports( outfile, spec ); - output_resources( outfile, spec ); - output_asm_constructor( outfile, "__wine_spec_init_ctor" ); + output_stubs( spec ); + output_exports( spec ); + output_imports( spec ); + output_resources( spec ); + output_asm_constructor( "__wine_spec_init_ctor" ); + output_gnu_stack_note(); } @@ -548,20 +549,19 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec ) * * Build a Win32 def file from a spec file. */ -void BuildDef32File( FILE *outfile, DLLSPEC *spec ) +void BuildDef32File( DLLSPEC *spec ) { const char *name; int i, total; if (spec_file_name) - fprintf( outfile, "; File generated automatically from %s; do not edit!\n\n", + output( "; File generated automatically from %s; do not edit!\n\n", spec_file_name ); else - fprintf( outfile, "; File generated automatically; do not edit!\n\n" ); + output( "; File generated automatically; do not edit!\n\n" ); - fprintf(outfile, "LIBRARY %s\n\n", spec->file_name); - - fprintf(outfile, "EXPORTS\n"); + output( "LIBRARY %s\n\n", spec->file_name); + output( "EXPORTS\n"); /* Output the exports and relay entry points */ @@ -573,13 +573,13 @@ void BuildDef32File( FILE *outfile, DLLSPEC *spec ) if (!odp) continue; if (odp->name) name = odp->name; - else if (odp->type == TYPE_STUB) name = make_internal_name( odp, spec, "stub" ); else if (odp->export_name) name = odp->export_name; - else name = make_internal_name( odp, spec, "noname_export" ); + else continue; if (!(odp->flags & FLAG_PRIVATE)) total++; - fprintf(outfile, " %s", name); + + output( " %s", name ); switch(odp->type) { @@ -590,20 +590,20 @@ void BuildDef32File( FILE *outfile, DLLSPEC *spec ) case TYPE_CDECL: /* try to reduce output */ if(strcmp(name, odp->link_name) || (odp->flags & FLAG_FORWARD)) - fprintf(outfile, "=%s", odp->link_name); + output( "=%s", odp->link_name ); break; case TYPE_STDCALL: { int at_param = strlen(odp->u.func.arg_types) * get_ptr_size(); - if (!kill_at) fprintf(outfile, "@%d", at_param); + if (!kill_at) output( "@%d", at_param ); if (odp->flags & FLAG_FORWARD) { - fprintf(outfile, "=%s", odp->link_name); + output( "=%s", odp->link_name ); } else if (strcmp(name, odp->link_name)) /* try to reduce output */ { - fprintf(outfile, "=%s", odp->link_name); - if (!kill_at) fprintf(outfile, "@%d", at_param); + output( "=%s", odp->link_name ); + if (!kill_at) output( "@%d", at_param ); } break; } @@ -620,30 +620,23 @@ void BuildDef32File( FILE *outfile, DLLSPEC *spec ) if (name != check && check != name + strlen(name) && '@' == check[-1]) { - fprintf(outfile, "%s", check - 1); + output("%s", check - 1); } } if (NULL != odp->name) { - fprintf(outfile, "=%s", make_internal_name( odp, spec, "stub" )); + output("=%s", make_internal_name( odp, spec, "stub" )); } break; } default: assert(0); } - fprintf( outfile, " @%d", odp->ordinal ); -#if 0 /* MinGW binutils cannot handle this correctly */ - if (!odp->name) fprintf( outfile, " NONAME" ); -#else - if (!odp->name && (odp->type == TYPE_STUB || odp->export_name)) fprintf( outfile, " NONAME" ); -#endif - 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" ); + output( " @%d", odp->ordinal ); + if (!odp->name || (odp->flags & FLAG_ORDINAL)) output( " NONAME" ); + if (is_data) output( " DATA" ); + if (odp->flags & FLAG_PRIVATE) output( " PRIVATE" ); + output( "\n" ); } if (!total) warning( "%s: Import library doesn't export anything\n", spec->file_name ); } @@ -654,34 +647,34 @@ void BuildDef32File( FILE *outfile, DLLSPEC *spec ) * * Build a PE DLL C file from a spec file. */ -void BuildPedllFile( FILE *outfile, DLLSPEC *spec ) +void BuildPedllFile( DLLSPEC *spec ) { int nr_exports; nr_exports = spec->base <= spec->limit ? spec->limit - spec->base + 1 : 0; - output_standard_file_header( outfile ); + output_standard_file_header(); - fprintf( outfile, "#include \n"); - fprintf( outfile, "#include \"windef.h\"\n"); - fprintf( outfile, "#include \"winbase.h\"\n"); - fprintf( outfile, "#include \"wine/config.h\"\n"); - fprintf( outfile, "#include \"wine/exception.h\"\n\n"); + output( "#include \n"); + output( "#include \"windef.h\"\n"); + output( "#include \"winbase.h\"\n"); + output( "#include \"wine/config.h\"\n"); + output( "#include \"wine/exception.h\"\n\n"); - fprintf( outfile, "void __wine_spec_unimplemented_stub( const char *module, const char *function )\n"); - fprintf( outfile, "{\n"); - fprintf( outfile, " ULONG_PTR args[2];\n"); - fprintf( outfile, "\n"); - fprintf( outfile, " args[0] = (ULONG_PTR)module;\n"); - fprintf( outfile, " args[1] = (ULONG_PTR)function;\n"); - fprintf( outfile, " RaiseException( EXCEPTION_WINE_STUB, EH_NONCONTINUABLE, 2, args );\n"); - fprintf( outfile, "}\n\n"); + output( "void __wine_spec_unimplemented_stub( const char *module, const char *function )\n"); + output( "{\n"); + output( " ULONG_PTR args[2];\n"); + output( "\n"); + output( " args[0] = (ULONG_PTR)module;\n"); + output( " args[1] = (ULONG_PTR)function;\n"); + output( " RaiseException( EXCEPTION_WINE_STUB, EH_NONCONTINUABLE, 2, args );\n"); + output( "}\n\n"); - fprintf( outfile, "static const char __wine_spec_file_name[] = \"%s\";\n\n", spec->file_name ); + output( "static const char __wine_spec_file_name[] = \"%s\";\n\n", spec->file_name ); if (nr_exports) { /* Output the stub functions */ - output_stub_funcs( outfile, spec ); + output_stub_funcs( spec ); } } diff --git a/reactos/tools/winebuild/utils.c b/reactos/tools/winebuild/utils.c index 85d552355a2..8f137d87fe5 100644 --- a/reactos/tools/winebuild/utils.c +++ b/reactos/tools/winebuild/utils.c @@ -15,14 +15,11 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include "config.h" - -#if !defined(WIN32) -#undef strdup -#endif +#include "wine/port.h" #include #include @@ -34,6 +31,8 @@ # include #endif +#include "windef.h" +#include "winnt.h" #include "build.h" #define MAX_TMP_FILES 8 @@ -165,6 +164,18 @@ void warning( const char *msg, ... ) va_end( valist ); } +int output( const char *format, ... ) +{ + int ret; + va_list valist; + + va_start( valist, format ); + ret = vfprintf( output_file, format, valist ); + va_end( valist ); + if (ret < 0) fatal_perror( "Output error" ); + return ret; +} + /* get a name for a temp file, automatically cleaned up on exit */ char *get_temp_file_name( const char *prefix, const char *suffix ) { @@ -196,31 +207,29 @@ char *get_temp_file_name( const char *prefix, const char *suffix ) } /* output a standard header for generated files */ -void output_standard_file_header( FILE *outfile ) +void output_standard_file_header(void) { if (spec_file_name) - fprintf( outfile, "/* File generated automatically from %s; do not edit! */\n", - spec_file_name ); + output( "/* File generated automatically from %s; do not edit! */\n", spec_file_name ); else - fprintf( outfile, "/* File generated automatically; do not edit! */\n" ); - fprintf( outfile, - "/* This file can be copied, modified and distributed without restriction. */\n\n" ); + output( "/* File generated automatically; do not edit! */\n" ); + output( "/* This file can be copied, modified and distributed without restriction. */\n\n" ); } /* dump a byte stream into the assembly code */ -void dump_bytes( FILE *outfile, const void *buffer, unsigned int size ) +void dump_bytes( const void *buffer, unsigned int size ) { unsigned int i; const unsigned char *ptr = buffer; if (!size) return; - fprintf( outfile, "\t.byte " ); + output( "\t.byte " ); for (i = 0; i < size - 1; i++, ptr++) { - if ((i % 16) == 15) fprintf( outfile, "0x%02x\n\t.byte ", *ptr ); - else fprintf( outfile, "0x%02x,", *ptr ); + if ((i % 16) == 15) output( "0x%02x\n\t.byte ", *ptr ); + else output( "0x%02x,", *ptr ); } - fprintf( outfile, "0x%02x\n", *ptr ); + output( "0x%02x\n", *ptr ); } @@ -324,7 +333,12 @@ DLLSPEC *alloc_dll_spec(void) spec->alloc_entry_points = 0; spec->nb_names = 0; spec->nb_resources = 0; - spec->characteristics = 0; + spec->characteristics = IMAGE_FILE_EXECUTABLE_IMAGE; + if (get_ptr_size() > 4) + spec->characteristics |= IMAGE_FILE_LARGE_ADDRESS_AWARE; + else + spec->characteristics |= IMAGE_FILE_32BIT_MACHINE; + spec->dll_characteristics = IMAGE_DLLCHARACTERISTICS_NX_COMPAT; spec->subsystem = 0; spec->subsystem_major = 4; spec->subsystem_minor = 0; @@ -444,7 +458,7 @@ unsigned int get_alignment(unsigned int align) case CPU_POWERPC: case CPU_ALPHA: n = 0; - while ((1 << n) != align) n++; + while ((1u << n) != align) n++; return n; } /* unreached */ @@ -523,7 +537,7 @@ const char *func_declaration( const char *func ) } /* output a size declaration for an assembly function */ -void output_function_size( FILE *outfile, const char *name ) +void output_function_size( const char *name ) { switch (target_platform) { @@ -531,7 +545,21 @@ void output_function_size( FILE *outfile, const char *name ) case PLATFORM_WINDOWS: break; default: - fprintf( outfile, "\t.size %s, .-%s\n", name, name ); + output( "\t.size %s, .-%s\n", name, name ); + break; + } +} + +/* output the GNU note for non-exec stack */ +void output_gnu_stack_note(void) +{ + switch (target_platform) + { + case PLATFORM_WINDOWS: + case PLATFORM_APPLE: + break; + default: + output( "\t.section .note.GNU-stack,\"\",@progbits\n" ); break; } } diff --git a/reactos/tools/winebuild/winebuild.man.in b/reactos/tools/winebuild/winebuild.man.in index 6c9bafcbdd5..d13596812fc 100644 --- a/reactos/tools/winebuild/winebuild.man.in +++ b/reactos/tools/winebuild/winebuild.man.in @@ -73,11 +73,11 @@ Specify the module entry point function; if not specified, the default is .B DllMain for dlls, and -.B WinMain -for executables (if -.B WinMain -is not defined, the standard C .B main +for executables (if the standard C +.B main +is not defined, +.B WinMain is used instead). This is only valid for Win32 modules. .TP .BI \-E,\ --export= filename @@ -85,6 +85,14 @@ Specify a .spec file (see \fBSPEC FILE SYNTAX\fR for details), or a standard Windows .def file that defines the exports of the DLL or executable that is being built. .TP +.B \--external-symbols +Allow linking to external symbols directly from the spec +file. Normally symbols exported by a dll have to be defined in the dll +itself; this option makes it possible to use symbols defined in +another Unix library (for symbols defined in another dll, a +.I forward +specification must be used instead). +.TP .BI \-f\ flags Ignored for compatibility with the C compiler. .TP @@ -145,6 +153,10 @@ KRNL386.EXE. It shouldn't be needed otherwise. Specify the command to use to get the list of undefined symbols; the default is \fBnm\fR. .TP +.BI --nxcompat= yes|no +Specify whether the module is compatible with no-exec support. The +default is yes. +.TP .BI \-o,\ --output= file Set the name of the output file (default is standard output). If the output file name end in \fB.o\fR, the text output is sent to a @@ -248,7 +260,8 @@ The entry point is not displayed in relay debugging traces (Win32 only). .TP .B -noname -The entry point will be imported by ordinal instead of by name. +The entry point will be exported by ordinal instead of by name. The +name is still available for importing. .TP .B -ret16 The function returns a 16-bit value (Win16 only). @@ -265,6 +278,10 @@ The function uses CPU register to pass arguments. .B -private The function cannot be imported from other dlls, it can only be accessed through GetProcAddress. +.TP +.B -ordinal +The entry point will be imported by ordinal instead of by name. The +name is still exported. .SS "Function ordinals" Syntax: .br diff --git a/reactos/tools/winebuild/winglue.h b/reactos/tools/winebuild/winglue.h index 1c138b84338..af333d71d5a 100644 --- a/reactos/tools/winebuild/winglue.h +++ b/reactos/tools/winebuild/winglue.h @@ -1,132 +1,10 @@ #ifndef _WINGLUE_H #define _WINGLUE_H -typedef unsigned char BYTE; -typedef unsigned short WORD; -typedef unsigned long DWORD; -typedef unsigned short WCHAR; -#if defined(_WIN64) -typedef unsigned __int64 UINT_PTR; -#else -typedef unsigned int UINT_PTR; -#endif - -#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 -#define IMAGE_FILE_MACHINE_UNKNOWN 0 -#define IMAGE_FILE_MACHINE_I386 0x014c +/* Stuff missing in the host's PSDK */ +#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT 0x0100 #define IMAGE_FILE_MACHINE_ALPHA 0x0184 -#define IMAGE_FILE_MACHINE_POWERPC 0x01f0 -#define IMAGE_FILE_MACHINE_AMD64 0x8664 -#define IMAGE_NT_SIGNATURE 0x00004550 #define IMAGE_SIZEOF_NT_OPTIONAL32_HEADER 224 #define IMAGE_SIZEOF_NT_OPTIONAL64_HEADER 240 -#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b -#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b -#if defined(_WIN64) -#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER IMAGE_SIZEOF_NT_OPTIONAL64_HEADER -#define IMAGE_NT_OPTIONAL_HDR_MAGIC IMAGE_NT_OPTIONAL_HDR64_MAGIC -#else -#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER IMAGE_SIZEOF_NT_OPTIONAL32_HEADER -#define IMAGE_NT_OPTIONAL_HDR_MAGIC IMAGE_NT_OPTIONAL_HDR32_MAGIC -#endif - -#ifdef __GNUC__ -#ifndef NONAMELESSUNION -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) -#define _ANONYMOUS_UNION __extension__ -#define _ANONYMOUS_STRUCT __extension__ -#else -#if defined(__cplusplus) -#define _ANONYMOUS_UNION __extension__ -#endif /* __cplusplus */ -#endif /* __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) */ -#endif /* NONAMELESSUNION */ -#elif defined(__WATCOMC__) || defined(_MSC_VER) -#define _ANONYMOUS_UNION -#define _ANONYMOUS_STRUCT -#endif /* __GNUC__/__WATCOMC__ */ -#ifndef _ANONYMOUS_UNION -#define _ANONYMOUS_UNION -#define _UNION_NAME(x) x -#define DUMMYUNIONNAME u -#define DUMMYUNIONNAME2 u2 -#define DUMMYUNIONNAME3 u3 -#define DUMMYUNIONNAME4 u4 -#define DUMMYUNIONNAME5 u5 -#define DUMMYUNIONNAME6 u6 -#define DUMMYUNIONNAME7 u7 -#define DUMMYUNIONNAME8 u8 -#else -#define _UNION_NAME(x) -#define DUMMYUNIONNAME -#define DUMMYUNIONNAME2 -#define DUMMYUNIONNAME3 -#define DUMMYUNIONNAME4 -#define DUMMYUNIONNAME5 -#define DUMMYUNIONNAME6 -#define DUMMYUNIONNAME7 -#define DUMMYUNIONNAME8 -#endif -#ifndef _ANONYMOUS_STRUCT -#define _ANONYMOUS_STRUCT -#define _STRUCT_NAME(x) x -#define DUMMYSTRUCTNAME s -#define DUMMYSTRUCTNAME2 s2 -#define DUMMYSTRUCTNAME3 s3 -#else -#define _STRUCT_NAME(x) -#define DUMMYSTRUCTNAME -#define DUMMYSTRUCTNAME2 -#define DUMMYSTRUCTNAME3 -#endif - -typedef struct _IMAGE_RESOURCE_DIRECTORY { - DWORD Characteristics; - DWORD TimeDateStamp; - WORD MajorVersion; - WORD MinorVersion; - WORD NumberOfNamedEntries; - WORD NumberOfIdEntries; -} IMAGE_RESOURCE_DIRECTORY,*PIMAGE_RESOURCE_DIRECTORY; -_ANONYMOUS_STRUCT typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY { - _ANONYMOUS_UNION union { - _ANONYMOUS_STRUCT struct { - DWORD NameOffset:31; - DWORD NameIsString:1; - }DUMMYSTRUCTNAME; - DWORD Name; - WORD Id; - } DUMMYUNIONNAME; - _ANONYMOUS_UNION union { - DWORD OffsetToData; - _ANONYMOUS_STRUCT struct { - DWORD OffsetToDirectory:31; - DWORD DataIsDirectory:1; - } DUMMYSTRUCTNAME2; - } DUMMYUNIONNAME2; -} IMAGE_RESOURCE_DIRECTORY_ENTRY,*PIMAGE_RESOURCE_DIRECTORY_ENTRY; -typedef struct _IMAGE_RESOURCE_DATA_ENTRY { - DWORD OffsetToData; - DWORD Size; - DWORD CodePage; - DWORD Reserved; -} IMAGE_RESOURCE_DATA_ENTRY,*PIMAGE_RESOURCE_DATA_ENTRY; - -#ifndef max -#define max(a,b) ((a)>(b)?(a):(b)) -#endif -#ifndef min -#define min(a,b) ((a)<(b)?(a):(b)) -#endif #endif /* _WINGLUE_H */