From cf6d1c80e6e4b528a153cc6710d67d24029593fe Mon Sep 17 00:00:00 2001 From: Colin Finck Date: Mon, 17 Dec 2007 23:36:09 +0000 Subject: [PATCH] Revert 31292, 31294 and 31297. Every change I try for fixing the build in one component breaks the build for another component. winebuild wasn't synchronized completely to the Wine version anyway, and the current Wine version removed support for the --pedll option we use, so a full clean sync isn't possible. svn path=/trunk/; revision=31298 --- reactos/tools/winebuild/Makefile.in | 13 +- reactos/tools/winebuild/build.h | 66 +- reactos/tools/winebuild/import.c | 720 ++++++++++---------- reactos/tools/winebuild/main.c | 71 +- reactos/tools/winebuild/parser.c | 39 +- reactos/tools/winebuild/relay.c | 810 +++++++++++------------ reactos/tools/winebuild/res16.c | 64 +- reactos/tools/winebuild/res32.c | 67 +- reactos/tools/winebuild/spec16.c | 423 ++++++------ reactos/tools/winebuild/spec32.c | 434 ++++++------ reactos/tools/winebuild/utils.c | 67 +- reactos/tools/winebuild/winebuild.man.in | 27 +- reactos/tools/winebuild/winglue.h | 4 - 13 files changed, 1366 insertions(+), 1439 deletions(-) diff --git a/reactos/tools/winebuild/Makefile.in b/reactos/tools/winebuild/Makefile.in index 77f36917113..62d7f6bd794 100644 --- a/reactos/tools/winebuild/Makefile.in +++ b/reactos/tools/winebuild/Makefile.in @@ -19,8 +19,6 @@ C_SRCS = \ spec32.c \ utils.c -INSTALLDIRS = $(DESTDIR)$(bindir) $(DESTDIR)$(mandir)/man$(prog_manext) - all: $(PROGRAMS) $(MANPAGES) @MAKE_RULES@ @@ -28,11 +26,12 @@ all: $(PROGRAMS) $(MANPAGES) winebuild$(EXEEXT): $(OBJS) $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBPORT) $(LDFLAGS) -install:: $(PROGRAMS) $(MANPAGES) $(INSTALLDIRS) - $(INSTALL_PROGRAM) winebuild$(EXEEXT) $(DESTDIR)$(bindir)/winebuild$(EXEEXT) - $(INSTALL_DATA) winebuild.man $(DESTDIR)$(mandir)/man$(prog_manext)/winebuild.$(prog_manext) +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) uninstall:: - $(RM) $(DESTDIR)$(bindir)/winebuild$(EXEEXT) $(DESTDIR)$(mandir)/man$(prog_manext)/winebuild.$(prog_manext) + $(RM) $(bindir)/winebuild$(EXEEXT) $(mandir)/man$(prog_manext)/winebuild.$(prog_manext) -@DEPENDENCIES@ # everything below this line is overwritten by make depend +### Dependencies: diff --git a/reactos/tools/winebuild/build.h b/reactos/tools/winebuild/build.h index e876755395e..c5c646bf2a0 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __WINE_BUILD_H @@ -85,7 +85,6 @@ 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 */ @@ -99,7 +98,6 @@ 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 */ @@ -116,7 +114,7 @@ enum target_cpu enum target_platform { - PLATFORM_UNSPECIFIED, PLATFORM_APPLE, PLATFORM_WINDOWS + PLATFORM_UNSPECIFIED, PLATFORM_APPLE, PLATFORM_SVR4, PLATFORM_WINDOWS }; extern enum target_cpu target_cpu; @@ -124,16 +122,31 @@ 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 export function by name */ +#define FLAG_NONAME 0x02 /* don't import 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 0x100 /* function is a forwarded name */ -#define FLAG_EXT_LINK 0x200 /* function links to an external symbol */ +#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 MAX_ORDINALS 65535 @@ -156,13 +169,11 @@ 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(void); +extern void output_standard_file_header( FILE *outfile ); extern FILE *open_input_file( const char *srcdir, const char *name ); extern void close_input_file( FILE *file ); -extern void dump_bytes( const void *buffer, unsigned int size ); +extern void dump_bytes( FILE *outfile, 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); @@ -180,8 +191,7 @@ 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( const char *name ); -extern void output_gnu_stack_note(void); +extern void output_function_size( FILE *outfile, const char *name ); extern void add_import_dll( const char *name, const char *filename ); extern void add_delayed_import( const char *name ); @@ -191,25 +201,27 @@ 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(void); -extern void output_stubs( DLLSPEC *spec ); -extern void output_imports( 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 int load_res32_file( const char *name, DLLSPEC *spec ); -extern void output_resources( DLLSPEC *spec ); +extern void output_resources( FILE *outfile, DLLSPEC *spec ); extern void load_res16_file( const char *name, DLLSPEC *spec ); -extern void output_res16_data( DLLSPEC *spec ); -extern void output_res16_directory( DLLSPEC *spec, const char *header_name ); +extern void output_res16_data( FILE *outfile, DLLSPEC *spec ); +extern void output_res16_directory( FILE *outfile, DLLSPEC *spec, const char *header_name ); -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 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 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; @@ -220,11 +232,9 @@ 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 904e92c1010..a51eb30cbce 100644 --- a/reactos/tools/winebuild/import.c +++ b/reactos/tools/winebuild/import.c @@ -16,11 +16,10 @@ * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" -#include "wine/port.h" #include #include @@ -38,6 +37,12 @@ #include "winglue.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 */ @@ -69,6 +74,57 @@ 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 ) { @@ -96,7 +152,7 @@ static int func_cmp( const void *func1, const void *func2 ) } /* add a name to a name table */ -static inline void add_name( struct name_table *table, const char *name ) +inline static void add_name( struct name_table *table, const char *name ) { if (table->count == table->size) { @@ -108,7 +164,7 @@ static inline void add_name( struct name_table *table, const char *name ) } /* remove a name from a name table */ -static inline void remove_name( struct name_table *table, unsigned int idx ) +inline static void remove_name( struct name_table *table, unsigned int idx ) { assert( idx < table->count ); free( table->names[idx] ); @@ -118,7 +174,7 @@ static inline void remove_name( struct name_table *table, unsigned int idx ) } /* make a name table empty */ -static inline void empty_name_table( struct name_table *table ) +inline static void empty_name_table( struct name_table *table ) { unsigned int i; @@ -127,7 +183,7 @@ static inline void empty_name_table( struct name_table *table ) } /* locate a name in a (sorted) list */ -static inline const char *find_name( const char *name, const struct name_table *table ) +inline static const char *find_name( const char *name, const struct name_table *table ) { char **res = NULL; @@ -136,21 +192,20 @@ static inline const char *find_name( const char *name, const struct name_table * } /* sort a name table */ -static inline void sort_names( struct name_table *table ) +inline static 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 */ -static inline ORDDEF *find_export( const char *name, ORDDEF **table, int size ) +inline static ORDDEF *find_export( const char *name, ORDDEF **table, int size ) { ORDDEF func, *odp, **res = NULL; - func.name = xstrdup(name); + func.name = (char *)name; func.ordinal = -1; odp = &func; if (table) res = bsearch( &odp, table, size, sizeof(*table), func_cmp ); - free( func.name ); return res ? *res : NULL; } @@ -167,7 +222,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 ) { - unsigned int i; + int i; for (i = 0; i < delayed_imports.count; i++) { @@ -253,13 +308,19 @@ static int read_import_lib( struct import *imp ) nb_delayed++; } - if (spec->nb_entry_points) + imp->exports = xmalloc( spec->nb_entry_points * sizeof(*imp->exports) ); + + for (i = 0; i < spec->nb_entry_points; i++) { - 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 ); + 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) + qsort( imp->exports, imp->nb_exports, sizeof(*imp->exports), func_cmp ); return 1; } @@ -341,12 +402,23 @@ 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 */ @@ -422,42 +494,6 @@ 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 ) { @@ -470,25 +506,8 @@ static void check_undefined_exports( DLLSPEC *spec ) if (odp->flags & FLAG_FORWARD) continue; if (find_name( odp->link_name, &undef_symbols )) { - 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; - } + odp->flags |= FLAG_EXT_LINK; + add_name( &ext_link_imports, odp->link_name ); } } } @@ -497,8 +516,7 @@ static void check_undefined_exports( DLLSPEC *spec ) static char *create_undef_symbols_file( DLLSPEC *spec ) { char *as_file, *obj_file; - int i; - unsigned int j; + unsigned int i; FILE *f; as_file = get_temp_file_name( output_file_name, ".s" ); @@ -512,8 +530,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 (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]) ); + 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]) ); fclose( f ); obj_file = get_temp_file_name( output_file_name, ".o" ); @@ -587,12 +605,11 @@ void read_undef_symbols( DLLSPEC *spec, char **argv ) /* resolve the imports for a Win32 module */ int resolve_imports( DLLSPEC *spec ) { - int i; - unsigned int j, removed; + unsigned int i, 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++) { @@ -604,23 +621,15 @@ int resolve_imports( DLLSPEC *spec ) odp = find_export( undef_symbols.names[j], imp->exports, imp->nb_exports ); if (odp) { - 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++; - } + add_import_func( imp, odp ); + remove_name( &undef_symbols, j-- ); + removed++; } } - if (!removed) + if (!removed && check_unused( imp, spec )) { /* the dll is not used, get rid of it */ - if (check_unused( imp, spec )) - warning( "winebuild: %s imported but no symbols used\n", imp->spec->file_name ); + warning( "%s imported but no symbols used\n", imp->spec->file_name ); remove_import_dll( i ); i--; } @@ -633,99 +642,99 @@ int resolve_imports( DLLSPEC *spec ) } /* output the get_pc thunk if needed */ -void output_get_pc_thunk(void) +void output_get_pc_thunk( FILE *outfile ) { if (target_cpu != CPU_x86) return; if (!UsePIC) return; - 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" ); + 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 a single import thunk */ -static void output_import_thunk( const char *name, const char *table, int pos ) +static void output_import_thunk( FILE *outfile, const char *name, const char *table, int pos ) { - output( "\n\t.align %d\n", get_alignment(4) ); - output( "\t%s\n", func_declaration(name) ); - output( "%s\n", asm_globl(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) ); switch(target_cpu) { case CPU_x86: if (!UsePIC) { - output( "\tjmp *(%s+%d)\n", table, pos ); + fprintf( outfile, "\tjmp *(%s+%d)\n", table, pos ); } else { - output( "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") ); - output( "1:\tjmp *%s+%d-1b(%%eax)\n", table, pos ); + fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") ); + fprintf( outfile, "1:\tjmp *%s+%d-1b(%%eax)\n", table, pos ); } break; case CPU_x86_64: - output( "\tjmpq *%s+%d(%%rip)\n", table, pos ); + fprintf( outfile, "\tjmpq *%s+%d(%%rip)\n", table, pos ); break; case CPU_SPARC: if ( !UsePIC ) { - 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" ); + 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" ); } else { /* Hmpf. Stupid sparc assembler always interprets global variable names as GOT offsets, so we have to do it the long way ... */ - 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" ); + 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" ); } break; case CPU_ALPHA: - output( "\tlda $0,%s\n", table ); - output( "\tlda $0,%d($0)\n", pos ); - output( "\tjmp $31,($0)\n" ); + fprintf( outfile, "\tlda $0,%s\n", table ); + fprintf( outfile, "\tlda $0,%d($0)\n", pos ); + fprintf( outfile, "\tjmp $31,($0)\n" ); break; case CPU_POWERPC: - 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) ); + 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) ); if (target_platform == PLATFORM_APPLE) { - 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) ); + 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) ); } else { - 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, "\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( "\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" ); + 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" ); break; } - output_function_size( name ); + output_function_size( outfile, name ); } /* check if we need an import directory */ @@ -735,7 +744,7 @@ int has_imports(void) } /* output the import table of a Win32 module */ -static void output_immediate_imports(void) +static void output_immediate_imports( FILE *outfile ) { int i, j; const char *dll_name; @@ -744,10 +753,10 @@ static void output_immediate_imports(void) /* main import header */ - output( "\n/* import table */\n" ); - output( "\n\t.data\n" ); - output( "\t.align %d\n", get_alignment(4) ); - output( ".L__wine_spec_imports:\n" ); + 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" ); /* list of dlls */ @@ -755,23 +764,23 @@ static void output_immediate_imports(void) { if (dll_imports[i]->delay) continue; dll_name = make_c_identifier( dll_imports[i]->spec->file_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 */ + 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 */ dll_name ); - output( "\t.long .L__wine_spec_import_data_ptrs+%d-.L__wine_spec_rva_base\n", /* FirstThunk */ + fprintf( outfile, "\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; } - 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, "\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( "\n\t.align %d\n", get_alignment(get_ptr_size()) ); - output( ".L__wine_spec_import_data_ptrs:\n" ); + fprintf( outfile, "\n\t.align %d\n", get_alignment(get_ptr_size()) ); + fprintf( outfile, ".L__wine_spec_import_data_ptrs:\n" ); for (i = 0; i < nb_imports; i++) { if (dll_imports[i]->delay) continue; @@ -780,19 +789,19 @@ static void output_immediate_imports(void) { ORDDEF *odp = dll_imports[i]->imports[j]; if (!(odp->flags & FLAG_NONAME)) - output( "\t%s .L__wine_spec_import_data_%s_%s-.L__wine_spec_rva_base\n", + fprintf( outfile, "\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) - output( "\t.quad 0x800000000000%04x\n", odp->ordinal ); + fprintf( outfile, "\t.quad 0x800000000000%04x\n", odp->ordinal ); else - output( "\t.long 0x8000%04x\n", odp->ordinal ); + fprintf( outfile, "\t.long 0x8000%04x\n", odp->ordinal ); } } - output( "\t%s 0\n", get_asm_ptr_keyword() ); + fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() ); } - output( ".L__wine_spec_imports_end:\n" ); + fprintf( outfile, ".L__wine_spec_imports_end:\n" ); for (i = 0; i < nb_imports; i++) { @@ -803,10 +812,10 @@ static void output_immediate_imports(void) ORDDEF *odp = dll_imports[i]->imports[j]; if (!(odp->flags & FLAG_NONAME)) { - 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 ); + 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 ); } } } @@ -815,13 +824,13 @@ static void output_immediate_imports(void) { if (dll_imports[i]->delay) continue; dll_name = make_c_identifier( dll_imports[i]->spec->file_name ); - output( ".L__wine_spec_import_name_%s:\n\t%s \"%s\"\n", + fprintf( outfile, ".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(void) +static void output_immediate_import_thunks( FILE *outfile ) { int i, j, pos; int nb_imm = nb_imports - nb_delayed; @@ -829,10 +838,10 @@ static void output_immediate_import_thunks(void) if (!nb_imm) return; - 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)); + 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)); for (i = pos = 0; i < nb_imports; i++) { @@ -840,56 +849,55 @@ static void output_immediate_import_thunks(void) for (j = 0; j < dll_imports[i]->nb_imports; j++, pos += get_ptr_size()) { ORDDEF *odp = dll_imports[i]->imports[j]; - output_import_thunk( odp->name ? odp->name : odp->export_name, + output_import_thunk( outfile, odp->name ? odp->name : odp->export_name, ".L__wine_spec_import_data_ptrs", pos ); } pos += get_ptr_size(); } - output_function_size( import_thunks ); + output_function_size( outfile, import_thunks ); } /* output the delayed import table of a Win32 module */ -static void output_delayed_imports( const DLLSPEC *spec ) +static void output_delayed_imports( FILE *outfile, const DLLSPEC *spec ) { - int i, j, mod; + int i, j; if (!nb_delayed) return; - 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") ); + 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") ); /* list of dlls */ - for (i = j = mod = 0; i < nb_imports; i++) + for (i = j = 0; i < nb_imports; i++) { if (!dll_imports[i]->delay) continue; - output( "\t%s 0\n", get_asm_ptr_keyword() ); /* grAttrs */ - output( "\t%s .L__wine_delay_name_%d\n", /* szName */ + fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() ); /* grAttrs */ + fprintf( outfile, "\t%s .L__wine_delay_name_%d\n", /* szName */ get_asm_ptr_keyword(), i ); - 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 */ + 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 */ get_asm_ptr_keyword(), j * get_ptr_size() ); - output( "\t%s .L__wine_delay_INT+%d\n", /* pINT */ + fprintf( outfile, "\t%s .L__wine_delay_INT+%d\n", /* pINT */ get_asm_ptr_keyword(), j * get_ptr_size() ); - 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, "\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 */ j += dll_imports[i]->nb_imports; - mod++; } - 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, "\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( "\n.L__wine_delay_IAT:\n" ); + fprintf( outfile, "\n.L__wine_delay_IAT:\n" ); for (i = 0; i < nb_imports; i++) { if (!dll_imports[i]->delay) continue; @@ -897,12 +905,12 @@ static void output_delayed_imports( const DLLSPEC *spec ) { ORDDEF *odp = dll_imports[i]->imports[j]; const char *name = odp->name ? odp->name : odp->export_name; - output( "\t%s .L__wine_delay_imp_%d_%s\n", + fprintf( outfile, "\t%s .L__wine_delay_imp_%d_%s\n", get_asm_ptr_keyword(), i, name ); } } - output( "\n.L__wine_delay_INT:\n" ); + fprintf( outfile, "\n.L__wine_delay_INT:\n" ); for (i = 0; i < nb_imports; i++) { if (!dll_imports[i]->delay) continue; @@ -910,24 +918,24 @@ static void output_delayed_imports( const DLLSPEC *spec ) { ORDDEF *odp = dll_imports[i]->imports[j]; if (!odp->name) - output( "\t%s %d\n", get_asm_ptr_keyword(), odp->ordinal ); + fprintf( outfile, "\t%s %d\n", get_asm_ptr_keyword(), odp->ordinal ); else - output( "\t%s .L__wine_delay_data_%d_%s\n", + fprintf( outfile, "\t%s .L__wine_delay_data_%d_%s\n", get_asm_ptr_keyword(), i, odp->name ); } } - output( "\n.L__wine_delay_modules:\n" ); + fprintf( outfile, "\n.L__wine_delay_modules:\n" ); for (i = 0; i < nb_imports; i++) { - if (dll_imports[i]->delay) output( "\t%s 0\n", get_asm_ptr_keyword() ); + if (dll_imports[i]->delay) fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() ); } for (i = 0; i < nb_imports; i++) { if (!dll_imports[i]->delay) continue; - output( ".L__wine_delay_name_%d:\n", i ); - output( "\t%s \"%s\"\n", + fprintf( outfile, ".L__wine_delay_name_%d:\n", i ); + fprintf( outfile, "\t%s \"%s\"\n", get_asm_string_keyword(), dll_imports[i]->spec->file_name ); } @@ -938,15 +946,15 @@ static void output_delayed_imports( const DLLSPEC *spec ) { ORDDEF *odp = dll_imports[i]->imports[j]; if (!odp->name) continue; - output( ".L__wine_delay_data_%d_%s:\n", i, odp->name ); - output( "\t%s \"%s\"\n", get_asm_string_keyword(), odp->name ); + 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_function_size( "__wine_spec_delay_imports" ); + output_function_size( outfile, "__wine_spec_delay_imports" ); } /* output the delayed import thunks of a Win32 module */ -static void output_delayed_import_thunks( const DLLSPEC *spec ) +static void output_delayed_import_thunks( FILE *outfile, const DLLSPEC *spec ) { int i, idx, j, pos, extra_stack_storage = 0; static const char delayed_import_loaders[] = "__wine_spec_delayed_import_loaders"; @@ -954,105 +962,95 @@ static void output_delayed_import_thunks( const DLLSPEC *spec ) if (!nb_delayed) return; - 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") ); + 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") ); switch(target_cpu) { case CPU_x86: - 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" ); + 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" ); break; case CPU_x86_64: - 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" ); + 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" ); break; case CPU_SPARC: - 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" ); + 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" ); break; case CPU_ALPHA: - output( "\tjsr $26,%s\n", asm_name("__wine_spec_delay_load") ); - output( "\tjmp $31,($0)\n" ); + fprintf( outfile, "\tjsr $26,%s\n", asm_name("__wine_spec_delay_load") ); + fprintf( outfile, "\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. */ - 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)); + 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)); /* r0 -> r3 (arg1) */ - output( "\tmr %s, %s\n", ppc_reg(3), ppc_reg(0)); + fprintf( outfile, "\tmr %s, %s\n", ppc_reg(3), ppc_reg(0)); /* save return address */ - output( "\tmflr %s\n", ppc_reg(0)); - output( "\tstw %s, %d(%s)\n", ppc_reg(0), 44+extra_stack_storage, ppc_reg(1)); + 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)); /* Call the __wine_delay_load function, arg1 is arg1. */ - output( "\tbl %s\n", asm_name("__wine_spec_delay_load") ); + fprintf( outfile, "\tbl %s\n", asm_name("__wine_spec_delay_load") ); /* Load return value from call into ctr register */ - output( "\tmtctr %s\n", ppc_reg(3)); + fprintf( outfile, "\tmtctr %s\n", ppc_reg(3)); /* restore all saved registers and drop stackframe. */ - 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)); + 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)); /* Load return value from call into return register */ - 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); + 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); /* branch to ctr register. */ - output( "\tbctr\n"); + fprintf( outfile, "\tbctr\n"); break; } - output_function_size( "__wine_delay_load_asm" ); - output( "\n" ); + output_function_size( outfile, "__wine_delay_load_asm" ); + fprintf( outfile, "\n" ); for (i = idx = 0; i < nb_imports; i++) { @@ -1062,25 +1060,25 @@ static void output_delayed_import_thunks( const DLLSPEC *spec ) ORDDEF *odp = dll_imports[i]->imports[j]; const char *name = odp->name ? odp->name : odp->export_name; - output( ".L__wine_delay_imp_%d_%s:\n", i, name ); + fprintf( outfile, ".L__wine_delay_imp_%d_%s:\n", i, name ); switch(target_cpu) { case CPU_x86: - output( "\tmovl $%d, %%eax\n", (idx << 16) | j ); - output( "\tjmp %s\n", asm_name("__wine_delay_load_asm") ); + fprintf( outfile, "\tmovl $%d, %%eax\n", (idx << 16) | j ); + fprintf( outfile, "\tjmp %s\n", asm_name("__wine_delay_load_asm") ); break; case CPU_x86_64: - output( "\tmovq $%d,%%r11\n", (idx << 16) | j ); - output( "\tjmp %s\n", asm_name("__wine_delay_load_asm") ); + fprintf( outfile, "\tmovq $%d,%%r11\n", (idx << 16) | j ); + fprintf( outfile, "\tjmp %s\n", asm_name("__wine_delay_load_asm") ); break; case CPU_SPARC: - output( "\tset %d, %%g1\n", (idx << 16) | j ); - output( "\tb,a %s\n", asm_name("__wine_delay_load_asm") ); + fprintf( outfile, "\tset %d, %%g1\n", (idx << 16) | j ); + fprintf( outfile, "\tb,a %s\n", asm_name("__wine_delay_load_asm") ); break; case CPU_ALPHA: - 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") ); + 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") ); break; case CPU_POWERPC: switch(target_platform) @@ -1088,24 +1086,24 @@ static void output_delayed_import_thunks( const DLLSPEC *spec ) case PLATFORM_APPLE: /* On Darwin we can use r0 and r2 */ /* Upper part in r2 */ - output( "\tlis %s, %d\n", ppc_reg(2), idx); + fprintf( outfile, "\tlis %s, %d\n", ppc_reg(2), idx); /* Lower part + r2 -> r0, Note we can't use r0 directly */ - output( "\taddi %s, %s, %d\n", ppc_reg(0), ppc_reg(2), j); - output( "\tb %s\n", asm_name("__wine_delay_load_asm") ); + 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") ); break; default: /* On linux we can't use r2 since r2 is not a scratch register (hold the TOC) */ /* Save r13 on the stack */ - output( "\taddi %s, %s, -0x4\n", ppc_reg(1), ppc_reg(1)); - output( "\tstw %s, 0(%s)\n", ppc_reg(13), 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(13), ppc_reg(1)); /* Upper part in r13 */ - output( "\tlis %s, %d\n", ppc_reg(13), idx); + fprintf( outfile, "\tlis %s, %d\n", ppc_reg(13), idx); /* Lower part + r13 -> r0, Note we can't use r0 directly */ - output( "\taddi %s, %s, %d\n", ppc_reg(0), ppc_reg(13), j); + fprintf( outfile, "\taddi %s, %s, %d\n", ppc_reg(0), ppc_reg(13), j); /* Restore r13 */ - 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") ); + 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") ); break; } break; @@ -1113,25 +1111,25 @@ static void output_delayed_import_thunks( const DLLSPEC *spec ) } idx++; } - output_function_size( delayed_import_loaders ); + output_function_size( outfile, delayed_import_loaders ); - output( "\n\t.align %d\n", get_alignment(get_ptr_size()) ); - output( "%s:\n", asm_name(delayed_import_thunks)); + fprintf( outfile, "\n\t.align %d\n", get_alignment(get_ptr_size()) ); + fprintf( outfile, "%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( odp->name ? odp->name : odp->export_name, + output_import_thunk( outfile, odp->name ? odp->name : odp->export_name, ".L__wine_delay_IAT", pos ); } } - output_function_size( delayed_import_thunks ); + output_function_size( outfile, delayed_import_thunks ); } /* output import stubs for exported entry points that link to external symbols */ -static void output_external_link_imports( DLLSPEC *spec ) +static void output_external_link_imports( FILE *outfile, DLLSPEC *spec ) { unsigned int i, pos; @@ -1146,25 +1144,25 @@ static void output_external_link_imports( DLLSPEC *spec ) remove_name( &ext_link_imports, i-- ); } - 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" ); + 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" ); for (i = 0; i < ext_link_imports.count; i++) - output( "\t%s %s\n", get_asm_ptr_keyword(), asm_name(ext_link_imports.names[i]) ); + fprintf( outfile, "\t%s %s\n", get_asm_ptr_keyword(), asm_name(ext_link_imports.names[i]) ); - 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") ); + 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") ); 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( buffer, ".L__wine_spec_external_links", pos ); + output_import_thunk( outfile, buffer, ".L__wine_spec_external_links", pos ); pos += get_ptr_size(); } - output_function_size( "__wine_spec_external_link_thunks" ); + output_function_size( outfile, "__wine_spec_external_link_thunks" ); } /******************************************************************* @@ -1172,95 +1170,81 @@ static void output_external_link_imports( DLLSPEC *spec ) * * Output the functions for stub entry points */ -void output_stubs( DLLSPEC *spec ) +void output_stubs( FILE *outfile, DLLSPEC *spec ) { const char *name, *exp_name; - int i, count; + int i, pos; if (!has_stubs( spec )) return; - output( "\n/* stub functions */\n\n" ); - output( "\t.text\n" ); + fprintf( outfile, "\n/* stub functions */\n\n" ); + fprintf( outfile, "\t.text\n" ); - for (i = count = 0; i < spec->nb_entry_points; i++) + for (i = pos = 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; - output( "\t.align %d\n", get_alignment(4) ); - output( "\t%s\n", func_declaration(name) ); - output( "%s:\n", asm_name(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" ); - /* 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) { - output( "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") ); - output( "1:" ); + fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") ); + fprintf( outfile, "1:" ); if (exp_name) { - output( "\tleal .L%s_string-1b(%%eax),%%ecx\n", name ); - output( "\tpushl %%ecx\n" ); - count++; + fprintf( outfile, "\tleal .L__wine_stub_strings+%d-1b(%%eax),%%ecx\n", pos ); + fprintf( outfile, "\tpushl %%ecx\n" ); + pos += strlen(exp_name) + 1; } else - output( "\tpushl $%d\n", odp->ordinal ); - output( "\tleal .L__wine_spec_file_name-1b(%%eax),%%ecx\n" ); - output( "\tpushl %%ecx\n" ); + fprintf( outfile, "\tpushl $%d\n", odp->ordinal ); + fprintf( outfile, "\tleal .L__wine_spec_file_name-1b(%%eax),%%ecx\n" ); + fprintf( outfile, "\tpushl %%ecx\n" ); } else { if (exp_name) { - output( "\tpushl $.L%s_string\n", name ); - count++; + fprintf( outfile, "\tpushl $.L__wine_stub_strings+%d\n", pos ); + pos += strlen(exp_name) + 1; } else - output( "\tpushl $%d\n", odp->ordinal ); - output( "\tpushl $.L__wine_spec_file_name\n" ); + fprintf( outfile, "\tpushl $%d\n", odp->ordinal ); + fprintf( outfile, "\tpushl $.L__wine_spec_file_name\n" ); } - output( "\tcall %s\n", asm_name("__wine_spec_unimplemented_stub") ); - output_function_size( name ); + fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_unimplemented_stub") ); + output_function_size( outfile, name ); } - if (count) + if (pos) { - output( "\t%s\n", get_asm_string_section() ); + fprintf( outfile, "\t%s\n", get_asm_string_section() ); + fprintf( outfile, ".L__wine_stub_strings:\n" ); 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) - { - name = get_stub_name( odp, spec ); - output( ".L%s_string:\n", name ); - output( "\t%s \"%s\"\n", get_asm_string_keyword(), exp_name ); - } + fprintf( outfile, "\t%s \"%s\"\n", get_asm_string_keyword(), exp_name ); } } } /* output the import and delayed import tables of a Win32 module */ -void output_imports( DLLSPEC *spec ) +void output_imports( FILE *outfile, DLLSPEC *spec ) { - output_immediate_imports(); - output_delayed_imports( spec ); - output_immediate_import_thunks(); - output_delayed_import_thunks( spec ); - output_external_link_imports( 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 ); if (nb_imports || ext_link_imports.count || has_stubs(spec) || has_relays(spec)) - output_get_pc_thunk(); + output_get_pc_thunk( outfile ); } diff --git a/reactos/tools/winebuild/main.c b/reactos/tools/winebuild/main.c index 6614680f5a8..e9750412ba4 100644 --- a/reactos/tools/winebuild/main.c +++ b/reactos/tools/winebuild/main.c @@ -19,14 +19,16 @@ * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" -#include "wine/port.h" #include #include +#ifdef WIN32 +#include /* unlink() */ +#endif//WIN32 #include #include #include @@ -46,7 +48,6 @@ 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__) enum target_cpu target_cpu = CPU_x86; @@ -64,6 +65,8 @@ 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 @@ -74,7 +77,6 @@ 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; @@ -82,6 +84,7 @@ 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; @@ -124,6 +127,7 @@ static const struct { { "macos", PLATFORM_APPLE }, { "darwin", PLATFORM_APPLE }, + { "sunos", PLATFORM_SVR4 }, { "windows", PLATFORM_WINDOWS }, { "winnt", PLATFORM_WINDOWS } }; @@ -244,9 +248,8 @@ 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, --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" +" -e, --entry=FUNC Set the DLL entry point function (default: DllMain)\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" @@ -260,7 +263,6 @@ 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" @@ -276,7 +278,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\n" +" --relay32 Build the 32-bit relay assembly routines\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"; @@ -286,16 +288,14 @@ 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_TARGET, LONG_OPT_VERSION, + LONG_OPT_TARGET, LONG_OPT_PEDLL }; @@ -303,21 +303,19 @@ 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 }, - { "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 }, + { "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 }, /* aliases for short options */ { "delay-lib", 1, 0, 'd' }, { "export", 1, 0, 'E' }, @@ -473,19 +471,12 @@ 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; @@ -573,7 +564,6 @@ 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 @@ -602,8 +592,7 @@ int main(int argc, char **argv) switch(exec_mode) { case MODE_DLL: - if (spec->subsystem != IMAGE_SUBSYSTEM_NATIVE) - spec->characteristics |= IMAGE_FILE_DLL; + spec->characteristics |= IMAGE_FILE_DLL; load_resources( argv, spec ); load_import_libs( argv ); if (!spec_file_name) fatal_error( "missing .spec file\n" ); @@ -615,7 +604,7 @@ int main(int argc, char **argv) break; case SPEC_WIN32: read_undef_symbols( spec, argv ); - BuildSpec32File( spec ); + BuildSpec32File( output_file, spec ); break; default: assert(0); } @@ -627,14 +616,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( spec ); + BuildSpec32File( output_file, spec ); break; case MODE_DEF: if (argv[0]) fatal_error( "file argument '%s' not allowed in this mode\n", argv[0] ); if (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( spec ); + BuildDef32File( output_file, spec ); break; case MODE_RELAY16: fatal_error( "Win16 relays are not supported in ReactOS version of winebuild\n" ); @@ -645,7 +634,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( spec ); + BuildPedllFile( output_file, spec ); break; default: usage(1); @@ -654,7 +643,7 @@ int main(int argc, char **argv) if (nb_errors) exit(1); if (output_file_name) { - if (fclose( output_file ) < 0) fatal_perror( "fclose" ); + fclose( output_file ); 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 5e876a262c2..1ea33766523 100644 --- a/reactos/tools/winebuild/parser.c +++ b/reactos/tools/winebuild/parser.c @@ -19,11 +19,10 @@ * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" -#include "wine/port.h" #include #include @@ -45,9 +44,6 @@ 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 */ @@ -69,7 +65,6 @@ static const char * const FlagNames[] = "i386", /* FLAG_I386 */ "register", /* FLAG_REGISTER */ "private", /* FLAG_PRIVATE */ - "ordinal", /* FLAG_ORDINAL */ NULL }; @@ -79,12 +74,12 @@ static int IsNumberString(const char *s) return 1; } -static inline int is_token_separator( char ch ) +inline static int is_token_separator( char ch ) { return strchr( separator_chars, ch ) != NULL; } -static inline int is_token_comment( char ch ) +inline static int is_token_comment( char ch ) { return strchr( comment_chars, ch ) != NULL; } @@ -450,7 +445,6 @@ 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) ); @@ -474,13 +468,6 @@ 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: @@ -545,14 +532,11 @@ static int parse_spec_ordinal( int ordinal, DLLSPEC *spec ) } } - if (!strcmp( odp->name, "@" ) || odp->flags & (FLAG_NONAME | FLAG_ORDINAL)) + if (!strcmp( odp->name, "@" ) || odp->flags & FLAG_NONAME) { if (ordinal == -1) { - 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" ); + error( "Nameless function needs an explicit ordinal number\n" ); goto error; } if (spec->type != SPEC_WIN32) @@ -560,16 +544,9 @@ 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 ); - odp->name = NULL; - } - else if (!(odp->flags & FLAG_ORDINAL)) /* -ordinal only affects the import library */ - { - odp->export_name = odp->name; - odp->name = NULL; - } + if (!strcmp( odp->name, "@" )) free( odp->name ); + else 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 0ddcc55f51e..dd3b9c07c20 100644 --- a/reactos/tools/winebuild/relay.c +++ b/reactos/tools/winebuild/relay.c @@ -19,11 +19,10 @@ * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" -#include "wine/port.h" #include @@ -32,32 +31,19 @@ #include "build.h" -/* 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 ) +static void function_header( FILE *outfile, const char *name ) { - output( "\n\t.align %d\n", get_alignment(4) ); - output( "\t%s\n", func_declaration(name) ); - output( "%s\n", asm_globl(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) ); } +static inline const char *data16_prefix(void) +{ + return (target_platform == PLATFORM_SVR4) ? "\tdata16\n" : ""; +} + /******************************************************************* * BuildCallFrom16Core * @@ -125,73 +111,74 @@ static void function_header( const char *name ) * (sp-20) long saved edx * (sp-24) long saved previous stack */ -static void BuildCallFrom16Core( int reg_func, int thunk ) +static void BuildCallFrom16Core( FILE *outfile, int reg_func, int thunk ) { /* Function header */ - 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" ); + 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" ); /* Create STACK16FRAME (except STACK32FRAME link) */ - 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" ); + 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" ); /* Save original EFlags register */ - if (reg_func) output( "\tpushfl\n" ); + if (reg_func) fprintf( outfile, "\tpushfl\n" ); if ( UsePIC ) { - output( "\tcall 1f\n" ); - output( "1:\tpopl %%ecx\n" ); - output( "\t.byte 0x2e\n\tmovl %s-1b(%%ecx),%%edx\n", asm_name("CallTo16_DataSelector") ); + 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") ); } else - output( "\t.byte 0x2e\n\tmovl %s,%%edx\n", asm_name("CallTo16_DataSelector") ); + fprintf( outfile, "\t.byte 0x2e\n\tmovl %s,%%edx\n", asm_name("CallTo16_DataSelector") ); /* Load 32-bit segment registers */ - output( "\tmovw %%dx, %%ds\n" ); - output( "\tmovw %%dx, %%es\n" ); + fprintf( outfile, "%s\tmovw %%dx, %%ds\n", data16_prefix() ); + fprintf( outfile, "%s\tmovw %%dx, %%es\n", data16_prefix() ); if ( UsePIC ) - output( "\tmovw %s-1b(%%ecx), %%fs\n", asm_name("CallTo16_TebSelector") ); + fprintf( outfile, "\tmovw %s-1b(%%ecx), %%fs\n", asm_name("CallTo16_TebSelector") ); else - output( "\tmovw %s, %%fs\n", asm_name("CallTo16_TebSelector") ); + fprintf( outfile, "\tmovw %s, %%fs\n", asm_name("CallTo16_TebSelector") ); - output( "\t.byte 0x64\n\tmov (%d),%%gs\n", GS_OFFSET ); + fprintf( outfile, "\t.byte 0x64\n\tmov (%d),%%gs\n", STRUCTOFFSET(TEB,gs_sel) ); /* Translate STACK16FRAME base to flat offset in %edx */ - output( "\tmovw %%ss, %%dx\n" ); - output( "\tandl $0xfff8, %%edx\n" ); - output( "\tshrl $1, %%edx\n" ); + fprintf( outfile, "\tmovw %%ss, %%dx\n" ); + fprintf( outfile, "\tandl $0xfff8, %%edx\n" ); + fprintf( outfile, "\tshrl $1, %%edx\n" ); if (UsePIC) { - output( "\taddl wine_ldt_copy_ptr-1b(%%ecx),%%edx\n" ); - output( "\tmovl (%%edx), %%edx\n" ); + fprintf( outfile, "\taddl wine_ldt_copy_ptr-1b(%%ecx),%%edx\n" ); + fprintf( outfile, "\tmovl (%%edx), %%edx\n" ); } else - 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 ); + 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 ); /* Get saved flags into %ecx */ - if (reg_func) output( "\tpopl %%ecx\n" ); + if (reg_func) fprintf( outfile, "\tpopl %%ecx\n" ); /* Get the 32-bit stack pointer from the TEB and complete STACK16FRAME */ - output( "\t.byte 0x64\n\tmovl (%d), %%ebp\n", STACKOFFSET ); - output( "\tpushl %%ebp\n" ); + fprintf( outfile, "\t.byte 0x64\n\tmovl (%d), %%ebp\n", STACKOFFSET ); + fprintf( outfile, "\tpushl %%ebp\n" ); /* Switch stacks */ - 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) ); + 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) ); /* At this point: @@ -208,32 +195,32 @@ static void BuildCallFrom16Core( int reg_func, int thunk ) if ( thunk ) { /* Set up registers as expected and call thunk */ - output( "\tleal %d(%%edx), %%ebx\n", (int)sizeof(STACK16FRAME)-22 ); - output( "\tleal -4(%%esp), %%ebp\n" ); + fprintf( outfile, "\tleal %d(%%edx), %%ebx\n", sizeof(STACK16FRAME)-22 ); + fprintf( outfile, "\tleal -4(%%esp), %%ebp\n" ); - output( "\tcall *%d(%%edx)\n", STACK16OFFSET(entry_point) ); + fprintf( outfile, "\tcall *%d(%%edx)\n", STACK16OFFSET(entry_point) ); /* Switch stack back */ - 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 ); + 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 ); /* Restore registers and return directly to caller */ - 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, "\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( "\txorb %%ch, %%ch\n" ); - output( "\tpopl %%ebx\n" ); - output( "\taddw %%cx, %%sp\n" ); - output( "\tpush %%ebx\n" ); + fprintf( outfile, "\txorb %%ch, %%ch\n" ); + fprintf( outfile, "\tpopl %%ebx\n" ); + fprintf( outfile, "\taddw %%cx, %%sp\n" ); + fprintf( outfile, "\tpush %%ebx\n" ); - output( "\t.byte 0x66\n" ); - output( "\tlret\n" ); + fprintf( outfile, "\t.byte 0x66\n" ); + fprintf( outfile, "\tlret\n" ); return; } @@ -242,131 +229,132 @@ static void BuildCallFrom16Core( int reg_func, int thunk ) /* Build register CONTEXT */ if ( reg_func ) { - output( "\tsubl $%d, %%esp\n", (int)sizeof(CONTEXT86) ); + fprintf( outfile, "\tsubl $%d, %%esp\n", sizeof(CONTEXT86) ); - output( "\tmovl %%ecx, %d(%%esp)\n", CONTEXTOFFSET(EFlags) ); + fprintf( outfile, "\tmovl %%ecx, %d(%%esp)\n", CONTEXTOFFSET(EFlags) ); - 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 %%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 %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, "\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( "\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(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(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, "\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( "\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) ); + 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) ); #if 0 - output( "\tfsave %d(%%esp)\n", CONTEXTOFFSET(FloatSave) ); + fprintf( outfile, "\tfsave %d(%%esp)\n", CONTEXTOFFSET(FloatSave) ); #endif /* Push address of CONTEXT86 structure -- popped by the relay routine */ - output( "\tmovl %%esp,%%eax\n" ); - output( "\tandl $~15,%%esp\n" ); - output( "\tsubl $4,%%esp\n" ); - output( "\tpushl %%eax\n" ); + fprintf( outfile, "\tmovl %%esp,%%eax\n" ); + fprintf( outfile, "\tandl $~15,%%esp\n" ); + fprintf( outfile, "\tsubl $4,%%esp\n" ); + fprintf( outfile, "\tpushl %%eax\n" ); } else { - output( "\tsubl $8,%%esp\n" ); - output( "\tandl $~15,%%esp\n" ); - output( "\taddl $8,%%esp\n" ); + fprintf( outfile, "\tsubl $8,%%esp\n" ); + fprintf( outfile, "\tandl $~15,%%esp\n" ); + fprintf( outfile, "\taddl $8,%%esp\n" ); } /* Call relay routine (which will call the API entry point) */ - 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) ); + 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) ); if ( reg_func ) { - output( "\tleal -%d(%%ebp), %%ebx\n", (int)sizeof(CONTEXT) + STACK32OFFSET(ebp) ); + fprintf( outfile, "\tleal -%d(%%ebp), %%ebx\n", + sizeof(CONTEXT) + STRUCTOFFSET(STACK32FRAME, ebp) ); /* Switch stack back */ - 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 ); + 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 ); /* Get return address to CallFrom16 stub */ - output( "\taddw $%d, %%sp\n", STACK16OFFSET(callfrom_ip)-4 ); - output( "\tpopl %%eax\n" ); - output( "\tpopl %%edx\n" ); + fprintf( outfile, "\taddw $%d, %%sp\n", STACK16OFFSET(callfrom_ip)-4 ); + fprintf( outfile, "\tpopl %%eax\n" ); + fprintf( outfile, "\tpopl %%edx\n" ); /* Restore all registers from CONTEXT */ - 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, "\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( "\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, "\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( "\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, "\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( "\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, "\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( "\tpopl %%ds\n" ); - output( "\tpopfl\n" ); - output( "\tlret\n" ); + fprintf( outfile, "\tpopl %%ds\n" ); + fprintf( outfile, "\tpopfl\n" ); + fprintf( outfile, "\tlret\n" ); } else { /* Switch stack back */ - 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 ); + 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 ); /* Restore registers */ - 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" ); + 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" ); /* Return to return stub which will return to caller */ - output( "\tlret $12\n" ); + fprintf( outfile, "\tlret $12\n" ); } - 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" ); + 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" ); } @@ -389,44 +377,44 @@ static void BuildCallFrom16Core( 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( int reg_func ) +static void BuildCallTo16Core( FILE *outfile, int reg_func ) { const char *name = reg_func ? "wine_call_to_16_regs" : "wine_call_to_16"; /* Function header */ - function_header( name ); + function_header( outfile, name ); /* Function entry sequence */ - output( "\tpushl %%ebp\n" ); - output( "\tmovl %%esp, %%ebp\n" ); + fprintf( outfile, "\tpushl %%ebp\n" ); + fprintf( outfile, "\tmovl %%esp, %%ebp\n" ); /* Save the 32-bit registers */ - output( "\tpushl %%ebx\n" ); - output( "\tpushl %%esi\n" ); - output( "\tpushl %%edi\n" ); - output( "\t.byte 0x64\n\tmov %%gs,(%d)\n", GS_OFFSET ); + 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) ); /* Setup exception frame */ - 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" ); + 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) ); /* Call the actual CallTo16 routine (simulate a lcall) */ - output( "\tpushl %%cs\n" ); - output( "\tcall .L%s\n", name ); + fprintf( outfile, "\tpushl %%cs\n" ); + fprintf( outfile, "\tcall .L%s\n", name ); /* Remove exception frame */ - output( "\t.byte 0x64\n\tpopl (0)\n" ); - output( "\taddl $4, %%esp\n" ); - output( "\t.byte 0x64\n\tpopl (%d)\n", STACKOFFSET ); + 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 ); if ( !reg_func ) { /* Convert return value */ - output( "\tandl $0xffff,%%eax\n" ); - output( "\tshll $16,%%edx\n" ); - output( "\torl %%edx,%%eax\n" ); + fprintf( outfile, "\tandl $0xffff,%%eax\n" ); + fprintf( outfile, "\tshll $16,%%edx\n" ); + fprintf( outfile, "\torl %%edx,%%eax\n" ); } else { @@ -440,94 +428,94 @@ static void BuildCallTo16Core( int reg_func ) * at the cost of a somewhat less efficient return path.] */ - output( "\tmovl %d(%%esp), %%edi\n", STACK32OFFSET(target) - STACK32OFFSET(edi)); + fprintf( outfile, "\tmovl %d(%%esp), %%edi\n", STACK32OFFSET(target) - STACK32OFFSET(edi)); /* everything above edi has been popped already */ - 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) ); + 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) ); /* The return glue code saved %esp into %esi */ } /* Restore the 32-bit registers */ - output( "\tpopl %%edi\n" ); - output( "\tpopl %%esi\n" ); - output( "\tpopl %%ebx\n" ); + fprintf( outfile, "\tpopl %%edi\n" ); + fprintf( outfile, "\tpopl %%esi\n" ); + fprintf( outfile, "\tpopl %%ebx\n" ); /* Function exit sequence */ - output( "\tpopl %%ebp\n" ); - output( "\tret $12\n" ); + fprintf( outfile, "\tpopl %%ebp\n" ); + fprintf( outfile, "\tret $12\n" ); /* Start of the actual CallTo16 routine */ - output( ".L%s:\n", name ); + fprintf( outfile, ".L%s:\n", name ); /* Switch to the 16-bit stack */ - 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 ); + 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 ); /* Make %bp point to the previous stackframe (built by CallFrom16) */ - output( "\tmovzwl %%sp,%%ebp\n" ); - output( "\tleal %d(%%ebp),%%ebp\n", STACK16OFFSET(bp) ); + fprintf( outfile, "\tmovzwl %%sp,%%ebp\n" ); + fprintf( outfile, "\tleal %d(%%ebp),%%ebp\n", STACK16OFFSET(bp) ); /* Add the specified offset to the new sp */ - output( "\tsubw %d(%%edx), %%sp\n", STACK32OFFSET(nb_args) ); + fprintf( outfile, "\tsubw %d(%%edx), %%sp\n", STACK32OFFSET(nb_args) ); if (reg_func) { /* Push the called routine address */ - output( "\tmovl %d(%%edx),%%edx\n", STACK32OFFSET(target) ); - output( "\tpushw %d(%%edx)\n", CONTEXTOFFSET(SegCs) ); - output( "\tpushw %d(%%edx)\n", CONTEXTOFFSET(Eip) ); + 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) ); /* Get the registers */ - 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) ); + 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) ); /* Get the 16-bit ds */ - output( "\tpopw %%ds\n" ); + fprintf( outfile, "\tpopw %%ds\n" ); } else /* not a register function */ { /* Push the called routine address */ - output( "\tpushl %d(%%edx)\n", STACK32OFFSET(target) ); + fprintf( outfile, "\tpushl %d(%%edx)\n", STACK32OFFSET(target) ); /* Set %fs and %gs to the value saved by the last CallFrom16 */ - 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" ); + 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" ); /* Set %ds and %es (and %ax just in case) equal to %ss */ - output( "\tmovw %%ss,%%ax\n" ); - output( "\tmovw %%ax,%%ds\n" ); - output( "\tmovw %%ax,%%es\n" ); + fprintf( outfile, "\tmovw %%ss,%%ax\n" ); + fprintf( outfile, "\tmovw %%ax,%%ds\n" ); + fprintf( outfile, "\tmovw %%ax,%%es\n" ); } /* Jump to the called routine */ - output( "\t.byte 0x66\n" ); - output( "\tlret\n" ); + fprintf( outfile, "\t.byte 0x66\n" ); + fprintf( outfile, "\tlret\n" ); /* Function footer */ - output_function_size( name ); + output_function_size( outfile, name ); } @@ -536,34 +524,34 @@ static void BuildCallTo16Core( int reg_func ) * * Build the return code for 16-bit callbacks */ -static void BuildRet16Func(void) +static void BuildRet16Func( FILE *outfile ) { - function_header( "__wine_call_to_16_ret" ); + function_header( outfile, "__wine_call_to_16_ret" ); /* Save %esp into %esi */ - output( "\tmovl %%esp,%%esi\n" ); + fprintf( outfile, "\tmovl %%esp,%%esi\n" ); /* Restore 32-bit segment registers */ - 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\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\tmov %s", asm_name("CallTo16_TebSelector") ); - output( "-%s,%%fs\n", asm_name("__wine_call16_start") ); + 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 0x64\n\tmov (%d),%%gs\n", GS_OFFSET ); + fprintf( outfile, "\t.byte 0x64\n\tmov (%d),%%gs\n", STRUCTOFFSET(TEB,gs_sel) ); /* Restore the 32-bit stack */ - output( "\tmovw %%di,%%ss\n" ); - output( "\t.byte 0x64\n\tmovl (%d),%%esp\n", STACKOFFSET ); + fprintf( outfile, "%s\tmovw %%di,%%ss\n", data16_prefix() ); + fprintf( outfile, "\t.byte 0x64\n\tmovl (%d),%%esp\n", STACKOFFSET ); /* Return to caller */ - output( "\tlret\n" ); - output_function_size( "__wine_call_to_16_ret" ); + fprintf( outfile, "\tlret\n" ); + output_function_size( outfile, "__wine_call_to_16_ret" ); } @@ -657,77 +645,77 @@ static void BuildRet16Func(void) * (ebp+4) ret addr * (ebp) ebp */ -static void BuildCallTo32CBClient( BOOL isEx ) +static void BuildCallTo32CBClient( FILE *outfile, BOOL isEx ) { - function_header( isEx ? "CALL32_CBClientEx" : "CALL32_CBClient" ); + function_header( outfile, isEx ? "CALL32_CBClientEx" : "CALL32_CBClient" ); /* Entry code */ - output( "\tpushl %%ebp\n" ); - output( "\tmovl %%esp,%%ebp\n" ); - output( "\tpushl %%edi\n" ); - output( "\tpushl %%esi\n" ); - output( "\tpushl %%ebx\n" ); + 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" ); /* Get pointer to temporary area and save the 32-bit stack pointer */ - output( "\tmovl 16(%%ebp), %%ebx\n" ); - output( "\tleal -8(%%esp), %%eax\n" ); + fprintf( outfile, "\tmovl 16(%%ebp), %%ebx\n" ); + fprintf( outfile, "\tleal -8(%%esp), %%eax\n" ); if ( !isEx ) - output( "\tmovl %%eax, -8(%%ebx)\n" ); + fprintf( outfile, "\tmovl %%eax, -8(%%ebx)\n" ); else - output( "\tmovl %%eax, 12(%%ebx)\n" ); + fprintf( outfile, "\tmovl %%eax, 12(%%ebx)\n" ); /* Set up registers and call CBClient relay stub (simulating a far call) */ - output( "\tmovl 20(%%ebp), %%esi\n" ); - output( "\tmovl (%%esi), %%esi\n" ); + fprintf( outfile, "\tmovl 20(%%ebp), %%esi\n" ); + fprintf( outfile, "\tmovl (%%esi), %%esi\n" ); - output( "\tmovl 8(%%ebp), %%eax\n" ); - output( "\tmovl 12(%%ebp), %%ebp\n" ); + fprintf( outfile, "\tmovl 8(%%ebp), %%eax\n" ); + fprintf( outfile, "\tmovl 12(%%ebp), %%ebp\n" ); - output( "\tpushl %%cs\n" ); - output( "\tcall *%%eax\n" ); + fprintf( outfile, "\tpushl %%cs\n" ); + fprintf( outfile, "\tcall *%%eax\n" ); /* Return new esi value to caller */ - output( "\tmovl 32(%%esp), %%edi\n" ); - output( "\tmovl %%esi, (%%edi)\n" ); + fprintf( outfile, "\tmovl 32(%%esp), %%edi\n" ); + fprintf( outfile, "\tmovl %%esi, (%%edi)\n" ); /* Return argument size to caller */ if ( isEx ) { - output( "\tmovl 36(%%esp), %%ebx\n" ); - output( "\tmovl %%ebp, (%%ebx)\n" ); + fprintf( outfile, "\tmovl 36(%%esp), %%ebx\n" ); + fprintf( outfile, "\tmovl %%ebp, (%%ebx)\n" ); } /* Restore registers and return */ - 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" ); + 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" ); /* '16-bit' return stub */ - function_header( isEx ? "CALL32_CBClientEx_Ret" : "CALL32_CBClient_Ret" ); + function_header( outfile, isEx ? "CALL32_CBClientEx_Ret" : "CALL32_CBClient_Ret" ); if ( !isEx ) { - output( "\tmovzwl %%sp, %%ebx\n" ); - output( "\tlssl %%ss:-16(%%ebx), %%esp\n" ); + fprintf( outfile, "\tmovzwl %%sp, %%ebx\n" ); + fprintf( outfile, "\tlssl %%ss:-16(%%ebx), %%esp\n" ); } else { - output( "\tmovzwl %%bp, %%ebx\n" ); - output( "\tsubw %%bp, %%sp\n" ); - output( "\tmovzwl %%sp, %%ebp\n" ); - output( "\tlssl %%ss:-12(%%ebx), %%esp\n" ); + 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( "\tlret\n" ); - output_function_size( isEx ? "CALL32_CBClientEx_Ret" : "CALL32_CBClient_Ret" ); + fprintf( outfile, "\tlret\n" ); + output_function_size( outfile, isEx ? "CALL32_CBClientEx_Ret" : "CALL32_CBClient_Ret" ); } @@ -756,114 +744,114 @@ static void BuildCallTo32CBClient( BOOL isEx ) * pointer on return (with the return address and arguments already * removed). */ -static void BuildCallFrom32Regs(void) +static void BuildCallFrom32Regs( FILE *outfile ) { static const int STACK_SPACE = 128 + sizeof(CONTEXT86); /* Function header */ - function_header( "__wine_call_from_32_regs" ); + function_header( outfile, "__wine_call_from_32_regs" ); /* Allocate some buffer space on the stack */ - output( "\tpushl %%ebp\n" ); - output( "\tmovl %%esp,%%ebp\n "); - output( "\tleal -%d(%%esp), %%esp\n", STACK_SPACE + 4 /* for context arg */); + fprintf( outfile, "\tpushl %%ebp\n" ); + fprintf( outfile, "\tmovl %%esp,%%ebp\n "); + fprintf( outfile, "\tleal -%d(%%esp), %%esp\n", STACK_SPACE + 4 /* for context arg */); /* Build the context structure */ - 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, "\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( "\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, "\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( "\tmovl $0x%x,%%eax\n", CONTEXT86_FULL ); - output( "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(ContextFlags) - STACK_SPACE ); + fprintf( outfile, "\tmovl $0x%x,%%eax\n", CONTEXT86_FULL ); + fprintf( outfile, "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(ContextFlags) - STACK_SPACE ); - output( "\tmovl 12(%%ebp),%%eax\n" ); /* Get %eip at time of call */ - output( "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(Eip) - 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 ); /* Transfer the arguments */ - 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 ); + 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 ); /* Call the entry point */ - output( "\taddl (%%ebx),%%ebx\n" ); - output( "\tcall *%%ebx\n" ); - output( "\tleal -%d(%%ebp),%%ecx\n", STACK_SPACE ); + fprintf( outfile, "\taddl (%%ebx),%%ebx\n" ); + fprintf( outfile, "\tcall *%%ebx\n" ); + fprintf( outfile, "\tleal -%d(%%ebp),%%ecx\n", STACK_SPACE ); /* Restore the context structure */ - 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, "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( "\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, "\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( "\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(SegSs) ); + fprintf( outfile, "\tpopl %%ss\n" ); + fprintf( outfile, "\tmovl %d(%%ecx),%%esp\n", CONTEXTOFFSET(Esp) ); - 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, "\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( "\tpopl %%ds\n" ); - output( "\tiret\n" ); - output_function_size( "__wine_call_from_32_regs" ); + fprintf( outfile, "\tpopl %%ds\n" ); + fprintf( outfile, "\tiret\n" ); + output_function_size( outfile, "__wine_call_from_32_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" ); + 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" ); } @@ -874,7 +862,7 @@ static void BuildCallFrom32Regs(void) * pending DPMI events. * * Stack layout: - * + * * (sp+12) long eflags * (sp+6) long cs * (sp+2) long ip @@ -883,34 +871,38 @@ static void BuildCallFrom32Regs(void) * On entry to function, fs register points to a valid TEB. * On exit from function, stack will be popped. */ -static void BuildPendingEventCheck(void) +static void BuildPendingEventCheck( FILE *outfile ) { /* Function header */ - function_header( "DPMI_PendingEventCheck" ); + function_header( outfile, "DPMI_PendingEventCheck" ); /* Check for pending events. */ - 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") ); + 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") ); /* Process pending events. */ - output( "\tsti\n" ); + fprintf( outfile, "\tsti\n" ); /* Start cleanup. Restore fs register. */ - output( "%s\n", asm_globl("DPMI_PendingEventCheck_Cleanup") ); - output( "\tpopw %%fs\n" ); + fprintf( outfile, "%s\n", asm_globl("DPMI_PendingEventCheck_Cleanup") ); + fprintf( outfile, "\tpopw %%fs\n" ); /* Return from function. */ - output( "%s\n", asm_globl("DPMI_PendingEventCheck_Return") ); - output( "\tiret\n" ); + fprintf( outfile, "%s\n", asm_globl("DPMI_PendingEventCheck_Return") ); + fprintf( outfile, "\tiret\n" ); - output_function_size( "DPMI_PendingEventCheck" ); + output_function_size( outfile, "DPMI_PendingEventCheck" ); } @@ -919,59 +911,58 @@ static void BuildPendingEventCheck(void) * * Build all the 16-bit relay callbacks */ -void BuildRelays16(void) +void BuildRelays16( FILE *outfile ) { if (target_cpu != CPU_x86) { - output( "/* File not used with this architecture. Do not edit! */\n\n" ); + fprintf( outfile, "/* File not used with this architecture. Do not edit! */\n\n" ); return; } /* File header */ - output( "/* File generated automatically. Do not edit! */\n\n" ); - output( "\t.text\n" ); + fprintf( outfile, "/* File generated automatically. Do not edit! */\n\n" ); + fprintf( outfile, "\t.text\n" ); - output( "%s:\n\n", asm_name("__wine_spec_thunk_text_16") ); + fprintf( outfile, "%s:\n\n", asm_name("__wine_spec_thunk_text_16") ); - output( "%s\n", asm_globl("__wine_call16_start") ); + fprintf( outfile, "%s\n", asm_globl("__wine_call16_start") ); /* Standard CallFrom16 routine */ - BuildCallFrom16Core( FALSE, FALSE ); + BuildCallFrom16Core( outfile, FALSE, FALSE ); /* Register CallFrom16 routine */ - BuildCallFrom16Core( TRUE, FALSE ); + BuildCallFrom16Core( outfile, TRUE, FALSE ); /* C16ThkSL CallFrom16 routine */ - BuildCallFrom16Core( FALSE, TRUE ); + BuildCallFrom16Core( outfile, FALSE, TRUE ); /* Standard CallTo16 routine */ - BuildCallTo16Core( 0 ); + BuildCallTo16Core( outfile, 0 ); /* Register CallTo16 routine */ - BuildCallTo16Core( 1 ); + BuildCallTo16Core( outfile, 1 ); /* Standard CallTo16 return stub */ - BuildRet16Func(); + BuildRet16Func( outfile ); /* CBClientThunkSL routine */ - BuildCallTo32CBClient( FALSE ); + BuildCallTo32CBClient( outfile, FALSE ); /* CBClientThunkSLEx routine */ - BuildCallTo32CBClient( TRUE ); + BuildCallTo32CBClient( outfile, TRUE ); /* Pending DPMI events check stub */ - BuildPendingEventCheck(); + BuildPendingEventCheck( outfile ); - output( "%s\n", asm_globl("__wine_call16_end") ); - output_function_size( "__wine_spec_thunk_text_16" ); + fprintf( outfile, "%s\n", asm_globl("__wine_call16_end") ); + output_function_size( outfile, "__wine_spec_thunk_text_16" ); /* Declare the return address and data selector variables */ - 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(); + 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") ); } /******************************************************************* @@ -979,23 +970,22 @@ void BuildRelays16(void) * * Build all the 32-bit relay callbacks */ -void BuildRelays32(void) +void BuildRelays32( FILE *outfile ) { if (target_cpu != CPU_x86) { - output( "/* File not used with this architecture. Do not edit! */\n\n" ); + fprintf( outfile, "/* File not used with this architecture. Do not edit! */\n\n" ); return; } /* File header */ - output( "/* File generated automatically. Do not edit! */\n\n" ); - output( "\t.text\n" ); - output( "%s:\n\n", asm_name("__wine_spec_thunk_text_32") ); + 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") ); /* 32-bit register entry point */ - BuildCallFrom32Regs(); + BuildCallFrom32Regs( outfile ); - output_function_size( "__wine_spec_thunk_text_32" ); - output_gnu_stack_note(); + output_function_size( outfile, "__wine_spec_thunk_text_32" ); } diff --git a/reactos/tools/winebuild/res16.c b/reactos/tools/winebuild/res16.c index 858ea321f02..dec1d6bb423 100644 --- a/reactos/tools/winebuild/res16.c +++ b/reactos/tools/winebuild/res16.c @@ -15,11 +15,10 @@ * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" -#include "wine/port.h" #include #include @@ -78,7 +77,7 @@ static const unsigned char *file_end; /* end of resource file */ static const char *file_name; /* current resource file name */ -static inline struct resource *add_resource( DLLSPEC *spec ) +inline static struct resource *add_resource( DLLSPEC *spec ) { spec->resources = xrealloc( spec->resources, (spec->nb_resources + 1) * sizeof(*spec->resources) ); return &spec->resources[spec->nb_resources++]; @@ -141,7 +140,7 @@ static void get_string( struct string_id *str ) } else { - char *p = xmalloc(strlen((const char *)file_pos) + 1); + char *p = xmalloc( (strlen((char*)file_pos) + 1) ); str->str = p; str->id = 0; while ((*p++ = get_byte())); @@ -241,16 +240,16 @@ static void free_resource_tree( struct res_tree *tree ) } /* output a string preceded by its length */ -static void output_string( const char *str ) +static void output_string( FILE *outfile, const char *str ) { unsigned int i, len = strlen(str); - output( "\t.byte 0x%02x", len ); - for (i = 0; i < len; i++) output( ",0x%02x", (unsigned char)str[i] ); - output( " /* %s */\n", 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 the resource data */ -void output_res16_data( DLLSPEC *spec ) +void output_res16_data( FILE *outfile, DLLSPEC *spec ) { const struct resource *res; unsigned int i; @@ -259,14 +258,14 @@ void output_res16_data( DLLSPEC *spec ) for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++) { - output( ".L__wine_spec_resource_%u:\n", i ); - dump_bytes( res->data, res->data_size ); - output( ".L__wine_spec_resource_%u_end:\n", i ); + 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 the resource definitions */ -void output_res16_directory( DLLSPEC *spec, const char *header_name ) +void output_res16_directory( FILE *outfile, DLLSPEC *spec, const char *header_name ) { unsigned int i, j; struct res_tree *tree; @@ -275,39 +274,38 @@ void output_res16_directory( DLLSPEC *spec, const char *header_name ) tree = build_resource_tree( spec ); - output( "\n.L__wine_spec_ne_rsrctab:\n" ); - output( "\t%s 0\n", get_asm_short_keyword() ); /* alignment */ + fprintf( outfile, "\n.L__wine_spec_ne_rsrctab:\n" ); + fprintf( outfile, "\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) - output( "\t%s .L__wine_spec_restype_%u-.L__wine_spec_ne_rsrctab\n", + fprintf( outfile, "\t%s .L__wine_spec_restype_%u-.L__wine_spec_ne_rsrctab\n", get_asm_short_keyword(), i ); else - output( "\t%s 0x%04x\n", get_asm_short_keyword(), type->type->id | 0x8000 ); + fprintf( outfile, "\t%s 0x%04x\n", get_asm_short_keyword(), type->type->id | 0x8000 ); - output( "\t%s %u,0,0\n", get_asm_short_keyword(), type->nb_names ); + fprintf( outfile, "\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++) { - 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 ); + 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 ); if (res->name.str) - output( "\t%s .L__wine_spec_resname_%u_%u-.L__wine_spec_ne_rsrctab\n", + fprintf( outfile, "\t%s .L__wine_spec_resname_%u_%u-.L__wine_spec_ne_rsrctab\n", get_asm_short_keyword(), i, j ); else - output( "\t%s 0x%04x\n", get_asm_short_keyword(), res->name.id | 0x8000 ); + fprintf( outfile, "\t%s 0x%04x\n", get_asm_short_keyword(), res->name.id | 0x8000 ); - output( "\t%s 0,0\n", get_asm_short_keyword() ); + fprintf( outfile, "\t%s 0,0\n", get_asm_short_keyword() ); } } - output( "\t%s 0\n", get_asm_short_keyword() ); /* terminator */ + fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* terminator */ /* name strings */ @@ -315,19 +313,19 @@ void output_res16_directory( DLLSPEC *spec, const char *header_name ) { if (type->type->str) { - output( ".L__wine_spec_restype_%u:\n", i ); - output_string( type->type->str ); + fprintf( outfile, ".L__wine_spec_restype_%u:\n", i ); + output_string( outfile, type->type->str ); } for (j = 0, res = type->res; j < type->nb_names; j++, res++) { if (res->name.str) { - output( ".L__wine_spec_resname_%u_%u:\n", i, j ); - output_string( res->name.str ); + fprintf( outfile, ".L__wine_spec_resname_%u_%u:\n", i, j ); + output_string( outfile, res->name.str ); } } } - output( "\t.byte 0\n" ); /* names terminator */ + fprintf( outfile, "\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 82e938c7332..85a354b7794 100644 --- a/reactos/tools/winebuild/res32.c +++ b/reactos/tools/winebuild/res32.c @@ -15,11 +15,10 @@ * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" -#include "wine/port.h" #include #include @@ -92,7 +91,7 @@ static const char *file_name; /* current resource file name */ #define RESDIR_SIZE(n) (sizeof(IMAGE_RESOURCE_DIRECTORY) + (n) * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY)) -static inline struct resource *add_resource( DLLSPEC *spec ) +inline static 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++]; @@ -315,29 +314,29 @@ static void free_resource_tree( struct res_tree *tree ) } /* output a Unicode string */ -static void output_string( const WCHAR *name ) +static void output_string( FILE *outfile, const WCHAR *name ) { int i, len = strlenW(name); - 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" ); + 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 a resource directory */ -static inline void output_res_dir( unsigned int nb_names, unsigned int nb_ids ) +static inline void output_res_dir( FILE *outfile, unsigned int nb_names, unsigned int nb_ids ) { - output( "\t.long 0\n" ); /* Characteristics */ - output( "\t.long 0\n" ); /* TimeDateStamp */ - output( "\t%s 0,0\n", /* Major/MinorVersion */ + fprintf( outfile, "\t.long 0\n" ); /* Characteristics */ + fprintf( outfile, "\t.long 0\n" ); /* TimeDateStamp */ + fprintf( outfile, "\t%s 0,0\n", /* Major/MinorVersion */ get_asm_short_keyword() ); - output( "\t%s %u,%u\n", /* NumberOfNamed/IdEntries */ + fprintf( outfile, "\t%s %u,%u\n", /* NumberOfNamed/IdEntries */ get_asm_short_keyword(), nb_names, nb_ids ); } /* output the resource definitions */ -void output_resources( DLLSPEC *spec ) +void output_resources( FILE *outfile, DLLSPEC *spec ) { int k, nb_id_types; unsigned int i, n, offset, data_offset; @@ -387,19 +386,19 @@ void output_resources( DLLSPEC *spec ) /* output the resource directories */ - 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" ); + 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_res_dir( tree->nb_types - nb_id_types, nb_id_types ); + output_res_dir( outfile, 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++) { - output( "\t.long 0x%08x,0x%08x\n", + fprintf( outfile, "\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++) @@ -413,22 +412,22 @@ void output_resources( DLLSPEC *spec ) for (i = 0, type = tree->types; i < tree->nb_types; i++, type++) { - output_res_dir( type->nb_names - type->nb_id_names, type->nb_id_names ); + output_res_dir( outfile, 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++) { - output( "\t.long 0x%08x,0x%08x\n", + fprintf( outfile, "\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( 0, name->nb_languages ); + output_res_dir( outfile, 0, name->nb_languages ); for (k = 0, res = name->res; k < name->nb_languages; k++, res++) { - 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 ); + fprintf( outfile, "\t.long 0x%08x,0x%08x\n", res->lang, + data_offset + (res - spec->resources) * sizeof(IMAGE_RESOURCE_DATA_ENTRY) ); } } } @@ -436,28 +435,28 @@ void output_resources( DLLSPEC *spec ) /* dump the resource data entries */ for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++) - output( "\t.long .L__wine_spec_res_%d-.L__wine_spec_rva_base,%u,0,0\n", + fprintf( outfile, "\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( type->type->str ); + if (type->type->str) output_string( outfile, type->type->str ); for (n = 0, name = type->names; n < type->nb_names; n++, name++) - if (name->name->str) output_string( name->name->str ); + if (name->name->str) output_string( outfile, name->name->str ); } /* resource data */ for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++) { - 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, "\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( ".L__wine_spec_resources_end:\n" ); - output( "\t.byte 0\n" ); + fprintf( outfile, ".L__wine_spec_resources_end:\n" ); + fprintf( outfile, "\t.byte 0\n" ); free_resource_tree( tree ); } diff --git a/reactos/tools/winebuild/spec16.c b/reactos/tools/winebuild/spec16.c index dc86b1b40ae..4c89f8bc519 100644 --- a/reactos/tools/winebuild/spec16.c +++ b/reactos/tools/winebuild/spec16.c @@ -19,11 +19,10 @@ * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" -#include "wine/port.h" #include #include @@ -54,31 +53,31 @@ static inline int is_function( const ORDDEF *odp ) * * Output entries for individual symbols in the entry table. */ -static void output_entries( DLLSPEC *spec, int first, int count ) +static void output_entries( FILE *outfile, DLLSPEC *spec, int first, int count ) { int i; for (i = 0; i < count; i++) { ORDDEF *odp = spec->ordinals[first + i]; - output( "\t.byte 0x03\n" ); /* flags: exported & public data */ + fprintf( outfile, "\t.byte 0x03\n" ); /* flags: exported & public data */ switch (odp->type) { case TYPE_CDECL: case TYPE_PASCAL: case TYPE_VARARGS: case TYPE_STUB: - output( "\t%s .L__wine_%s_%u-.L__wine_spec_code_segment\n", + fprintf( outfile, "\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: - output( "\t%s .L__wine_%s_%u-.L__wine_spec_data_segment\n", + fprintf( outfile, "\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: - output( "\t%s 0x%04x /* %s */\n", + fprintf( outfile, "\t%s 0x%04x /* %s */\n", get_asm_short_keyword(), odp->u.abs.value, odp->name ); break; default: @@ -91,7 +90,7 @@ static void output_entries( DLLSPEC *spec, int first, int count ) /******************************************************************* * output_entry_table */ -static void output_entry_table( DLLSPEC *spec ) +static void output_entry_table( FILE *outfile, DLLSPEC *spec ) { int i, prev = 0, prev_sel = -1, bundle_count = 0; @@ -126,10 +125,10 @@ static void output_entry_table( DLLSPEC *spec ) /* flush previous bundle */ if (bundle_count) { - output( "\t/* %s.%d - %s.%d */\n", + fprintf( outfile, "\t/* %s.%d - %s.%d */\n", spec->dll_name, prev - bundle_count + 1, spec->dll_name, prev ); - 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 0x%02x,0x%02x\n", bundle_count, prev_sel ); + output_entries( outfile, spec, prev - bundle_count + 1, bundle_count ); } if (prev + 1 != i) @@ -137,10 +136,10 @@ static void output_entry_table( DLLSPEC *spec ) int skip = i - (prev + 1); while (skip > 255) { - output( "\t.byte 0xff,0x00\n" ); + fprintf( outfile, "\t.byte 0xff,0x00\n" ); skip -= 255; } - output( "\t.byte 0x%02x,0x00\n", skip ); + fprintf( outfile, "\t.byte 0x%02x,0x00\n", skip ); } bundle_count = 0; @@ -153,24 +152,24 @@ static void output_entry_table( DLLSPEC *spec ) /* flush last bundle */ if (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 0x%02x,0x%02x\n", bundle_count, prev_sel ); + output_entries( outfile, spec, prev - bundle_count + 1, bundle_count ); } - output( "\t.byte 0x00\n" ); + fprintf( outfile, "\t.byte 0x00\n" ); } /******************************************************************* * output_resident_name */ -static void output_resident_name( const char *string, int ordinal ) +static void output_resident_name( FILE *outfile, const char *string, int ordinal ) { unsigned int i, len = strlen(string); - 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 ); + 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 ); } @@ -283,7 +282,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( ORDDEF *odp ) +static void output_call16_function( FILE *outfile, ORDDEF *odp ) { char name[256]; int i, pos, stack_words; @@ -293,41 +292,41 @@ static void output_call16_function( ORDDEF *odp ) sprintf( name, ".L__wine_spec_call16_%s", get_relay_name(odp) ); - 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" ); + 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" ); stack_words = 2; if (needs_ldt) { - output( "\tpushl %%esi\n" ); + fprintf( outfile, "\tpushl %%esi\n" ); stack_words++; if (UsePIC) { - output( "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") ); - output( "1:\tmovl wine_ldt_copy_ptr-1b(%%eax),%%esi\n" ); + 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" ); } else - output( "\tmovl $%s,%%esi\n", asm_name("wine_ldt_copy") ); + fprintf( outfile, "\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) output( "\tsubl $%d,%%esp\n", 16 - 4 * (stack_words % 4) ); + if (stack_words % 4) fprintf( outfile, "\tsubl $%d,%%esp\n", 16 - 4 * (stack_words % 4) ); if (args[0] || odp->type == TYPE_VARARGS) - output( "\tmovl 12(%%ebp),%%ecx\n" ); /* args */ + fprintf( outfile, "\tmovl 12(%%ebp),%%ecx\n" ); /* args */ if (odp->flags & FLAG_REGISTER) { - output( "\tpushl 16(%%ebp)\n" ); /* context */ + fprintf( outfile, "\tpushl 16(%%ebp)\n" ); /* context */ } else if (odp->type == TYPE_VARARGS) { - output( "\tleal %d(%%ecx),%%eax\n", argsize ); - output( "\tpushl %%eax\n" ); /* va_list16 */ + fprintf( outfile, "\tleal %d(%%ecx),%%eax\n", argsize ); + fprintf( outfile, "\tpushl %%eax\n" ); /* va_list16 */ } pos = (odp->type == TYPE_PASCAL) ? 0 : argsize; @@ -337,33 +336,33 @@ static void output_call16_function( ORDDEF *odp ) { case 'w': /* word */ if (odp->type != TYPE_PASCAL) pos -= 2; - output( "\tmovzwl %d(%%ecx),%%eax\n", pos ); - output( "\tpushl %%eax\n" ); + fprintf( outfile, "\tmovzwl %d(%%ecx),%%eax\n", pos ); + fprintf( outfile, "\tpushl %%eax\n" ); if (odp->type == TYPE_PASCAL) pos += 2; break; case 's': /* s_word */ if (odp->type != TYPE_PASCAL) pos -= 2; - output( "\tmovswl %d(%%ecx),%%eax\n", pos ); - output( "\tpushl %%eax\n" ); + fprintf( outfile, "\tmovswl %d(%%ecx),%%eax\n", pos ); + fprintf( outfile, "\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; - output( "\tpushl %d(%%ecx)\n", pos ); + fprintf( outfile, "\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; - 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" ); + 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" ); if (odp->type == TYPE_PASCAL) pos += 4; break; @@ -372,13 +371,14 @@ static void output_call16_function( ORDDEF *odp ) } } - output( "\tcall *8(%%ebp)\n" ); + fprintf( outfile, "\tcall *8(%%ebp)\n" ); - if (needs_ldt) output( "\tmovl -4(%%ebp),%%esi\n" ); + if (needs_ldt) fprintf( outfile, "\tmovl -4(%%ebp),%%esi\n" ); + if (odp->flags & FLAG_RET16) fprintf( outfile, "\tmovzwl %%ax,%%eax\n" ); - output( "\tleave\n" ); - output( "\tret\n" ); - output_function_size( name ); + fprintf( outfile, "\tleave\n" ); + fprintf( outfile, "\tret\n" ); + output_function_size( outfile, name ); } @@ -450,72 +450,72 @@ static int sort_func_list( ORDDEF **list, int count, * * Output the dll initialization code. */ -static void output_init_code( const DLLSPEC *spec, const char *header_name ) +static void output_init_code( FILE *outfile, const DLLSPEC *spec, const char *header_name ) { char name[80]; sprintf( name, ".L__wine_spec_%s_init", make_c_identifier(spec->dll_name) ); - 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" ); + 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" ); if (UsePIC) { - 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" ); + 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" ); } else { - output( "\tpushl $.L__wine_spec_file_name\n" ); - output( "\tpushl $%s\n", header_name ); + fprintf( outfile, "\tpushl $.L__wine_spec_file_name\n" ); + fprintf( outfile, "\tpushl $%s\n", header_name ); } - output( "\tcall %s\n", asm_name("__wine_dll_register_16") ); - output( "\taddl $12,%%esp\n" ); - output( "\tret\n" ); - output_function_size( 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 ); sprintf( name, ".L__wine_spec_%s_fini", make_c_identifier(spec->dll_name) ); - output( "\t.align 4\n" ); - output( "\t%s\n", func_declaration(name) ); - output( "%s:\n", name ); - output( "subl $8,%%esp\n" ); + 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" ); if (UsePIC) { - 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" ); + 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" ); } else { - output( "\tpushl $%s\n", header_name ); + fprintf( outfile, "\tpushl $%s\n", header_name ); } - output( "\tcall %s\n", asm_name("__wine_dll_unregister_16") ); - output( "\taddl $12,%%esp\n" ); - output( "\tret\n" ); - output_function_size( 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 ); if (target_platform == PLATFORM_APPLE) { - 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) ); + 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) ); } else { - 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) ); + 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) ); } } @@ -525,7 +525,7 @@ static void output_init_code( const DLLSPEC *spec, const char *header_name ) * * Build a Win16 assembly file from a spec file. */ -void BuildSpec16File( DLLSPEC *spec ) +void BuildSpec16File( FILE *outfile, DLLSPEC *spec ) { ORDDEF **typelist; int i, j, nb_funcs; @@ -533,7 +533,7 @@ void BuildSpec16File( DLLSPEC *spec ) /* File header */ - output_standard_file_header(); + output_standard_file_header( outfile ); if (!spec->dll_name) /* set default name from file name */ { @@ -558,135 +558,135 @@ void BuildSpec16File( DLLSPEC *spec ) /* Output the module structure */ sprintf( header_name, "__wine_spec_%s_dos_header", make_c_identifier(spec->dll_name) ); - 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 */ + 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 */ IMAGE_DOS_SIGNATURE ); - 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, "\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( ".L__wine_spec_ne_header:\n" ); - output( "\t%s 0x%04x\n", get_asm_short_keyword(), /* ne_magic */ + fprintf( outfile, ".L__wine_spec_ne_header:\n" ); + fprintf( outfile, "\t%s 0x%04x\n", get_asm_short_keyword(), /* ne_magic */ IMAGE_OS2_SIGNATURE ); - 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 */ + 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 */ get_asm_short_keyword() ); - output( "\t%s .L__wine_spec_ne_enttab_end-.L__wine_spec_ne_enttab\n", /* ne_cbenttab */ + fprintf( outfile, "\t%s .L__wine_spec_ne_enttab_end-.L__wine_spec_ne_enttab\n", /* ne_cbenttab */ get_asm_short_keyword() ); - output( "\t.long 0\n" ); /* ne_crc */ - output( "\t%s 0x%04x\n", get_asm_short_keyword(), /* ne_flags */ + fprintf( outfile, "\t.long 0\n" ); /* ne_crc */ + fprintf( outfile, "\t%s 0x%04x\n", get_asm_short_keyword(), /* ne_flags */ NE_FFLAGS_SINGLEDATA | NE_FFLAGS_LIBMODULE ); - 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 */ + 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 */ get_asm_short_keyword() ); - output( "\t%s .L__wine_spec_ne_rsrctab-.L__wine_spec_ne_header\n", /* ne_rsrctab */ + fprintf( outfile, "\t%s .L__wine_spec_ne_rsrctab-.L__wine_spec_ne_header\n", /* ne_rsrctab */ get_asm_short_keyword() ); - output( "\t%s .L__wine_spec_ne_restab-.L__wine_spec_ne_header\n", /* ne_restab */ + fprintf( outfile, "\t%s .L__wine_spec_ne_restab-.L__wine_spec_ne_header\n", /* ne_restab */ get_asm_short_keyword() ); - output( "\t%s .L__wine_spec_ne_modtab-.L__wine_spec_ne_header\n", /* ne_modtab */ + fprintf( outfile, "\t%s .L__wine_spec_ne_modtab-.L__wine_spec_ne_header\n", /* ne_modtab */ get_asm_short_keyword() ); - output( "\t%s .L__wine_spec_ne_imptab-.L__wine_spec_ne_header\n", /* ne_imptab */ + fprintf( outfile, "\t%s .L__wine_spec_ne_imptab-.L__wine_spec_ne_header\n", /* ne_imptab */ get_asm_short_keyword() ); - 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 */ + 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 */ /* segment table */ - output( "\n.L__wine_spec_ne_segtab:\n" ); + fprintf( outfile, "\n.L__wine_spec_ne_segtab:\n" ); /* code segment entry */ - output( "\t%s .L__wine_spec_code_segment-%s\n", /* filepos */ + fprintf( outfile, "\t%s .L__wine_spec_code_segment-%s\n", /* filepos */ get_asm_short_keyword(), header_name ); - output( "\t%s .L__wine_spec_code_segment_end-.L__wine_spec_code_segment\n", /* size */ + fprintf( outfile, "\t%s .L__wine_spec_code_segment_end-.L__wine_spec_code_segment\n", /* size */ get_asm_short_keyword() ); - 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 */ + 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 */ get_asm_short_keyword() ); /* data segment entry */ - output( "\t%s .L__wine_spec_data_segment-%s\n", /* filepos */ + fprintf( outfile, "\t%s .L__wine_spec_data_segment-%s\n", /* filepos */ get_asm_short_keyword(), header_name ); - output( "\t%s .L__wine_spec_data_segment_end-.L__wine_spec_data_segment\n", /* size */ + fprintf( outfile, "\t%s .L__wine_spec_data_segment_end-.L__wine_spec_data_segment\n", /* size */ get_asm_short_keyword() ); - 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 */ + 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 */ get_asm_short_keyword() ); /* resource directory */ - output_res16_directory( spec, header_name ); + output_res16_directory( outfile, spec, header_name ); /* resident names table */ - output( "\n\t.align %d\n", get_alignment(2) ); - output( ".L__wine_spec_ne_restab:\n" ); - output_resident_name( spec->dll_name, 0 ); + 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 ); for (i = 1; i <= spec->limit; i++) { ORDDEF *odp = spec->ordinals[i]; if (!odp || !odp->name[0]) continue; - output_resident_name( odp->name, i ); + output_resident_name( outfile, odp->name, i ); } - output( "\t.byte 0\n" ); + fprintf( outfile, "\t.byte 0\n" ); /* imported names table */ - 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" ); + 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" ); /* entry table */ - output( "\n.L__wine_spec_ne_enttab:\n" ); - output_entry_table( spec ); - output( ".L__wine_spec_ne_enttab_end:\n" ); + fprintf( outfile, "\n.L__wine_spec_ne_enttab:\n" ); + output_entry_table( outfile, spec ); + fprintf( outfile, ".L__wine_spec_ne_enttab_end:\n" ); /* code segment */ - output( "\n\t.align %d\n", get_alignment(2) ); - output( ".L__wine_spec_code_segment:\n" ); + fprintf( outfile, "\n\t.align %d\n", get_alignment(2) ); + fprintf( outfile, ".L__wine_spec_code_segment:\n" ); for ( i = 0; i < nb_funcs; i++ ) { unsigned int arg_types[2]; - int nop_words, argsize = 0; + int j, nop_words, argsize = 0; if ( typelist[i]->type == TYPE_PASCAL ) argsize = get_function_argsize( typelist[i] ); @@ -709,9 +709,9 @@ void BuildSpec16File( DLLSPEC *spec ) } if (typelist[i]->type == TYPE_VARARGS) arg_types[j / 10] |= ARG_VARARG << (3 * (j % 10)); - 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" ); + 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" ); if (typelist[i]->flags & FLAG_REGISTER) { @@ -719,91 +719,90 @@ void BuildSpec16File( DLLSPEC *spec ) } else if (typelist[i]->flags & FLAG_RET16) { - output( "\torw %%ax,%%ax\n" ); - output( "\tnop\n" ); /* so that the lretw is aligned */ + fprintf( outfile, "\torw %%ax,%%ax\n" ); + fprintf( outfile, "\tnop\n" ); /* so that the lretw is aligned */ nop_words = 2; } else { - output( "\tshld $16,%%eax,%%edx\n" ); - output( "\torl %%eax,%%eax\n" ); + fprintf( outfile, "shld $16,%%eax,%%edx\n" ); + fprintf( outfile, "orl %%eax,%%eax\n" ); nop_words = 1; } if (argsize) { - output( "\tlretw $%u\n", argsize ); + fprintf( outfile, "lretw $%u\n", argsize ); nop_words--; } - else output( "\tlretw\n" ); + else fprintf( outfile, "lretw\n" ); - if (nop_words) output( "\t%s\n", nop_sequence[nop_words-1] ); + if (nop_words) fprintf( outfile, "\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 */ - output( "\t%s 0x86c7\n", get_asm_short_keyword() ); - output( "\t.long 0x%08x,0x%08x\n", arg_types[0], arg_types[1] ); + 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] ); } for (i = 0; i <= spec->limit; i++) { ORDDEF *odp = spec->ordinals[i]; if (!odp || !is_function( odp )) continue; - output( ".L__wine_%s_%u:\n", make_c_identifier(spec->dll_name), i ); - output( "\tpushw %%bp\n" ); - output( "\tpushl $%s\n", + fprintf( outfile, ".L__wine_%s_%u:\n", make_c_identifier(spec->dll_name), i ); + fprintf( outfile, "\tpushw %%bp\n" ); + fprintf( outfile, "\tpushl $%s\n", asm_name( odp->type == TYPE_STUB ? get_stub_name( odp, spec ) : odp->link_name )); - output( "\tcallw .L__wine_spec_callfrom16_%s\n", get_callfrom16_name( odp ) ); + fprintf( outfile, "\tcallw .L__wine_spec_callfrom16_%s\n", get_callfrom16_name( odp ) ); } - output( ".L__wine_spec_code_segment_end:\n" ); + fprintf( outfile, ".L__wine_spec_code_segment_end:\n" ); /* data segment */ - 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 */ + 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 */ for (i = 0; i <= spec->limit; i++) { ORDDEF *odp = spec->ordinals[i]; if (!odp || odp->type != TYPE_VARIABLE) continue; - output( ".L__wine_%s_%u:\n", make_c_identifier(spec->dll_name), i ); - output( "\t.long " ); + fprintf( outfile, ".L__wine_%s_%u:\n", make_c_identifier(spec->dll_name), i ); + fprintf( outfile, "\t.long " ); for (j = 0; j < odp->u.var.n_values-1; j++) - output( "0x%08x,", odp->u.var.values[j] ); - output( "0x%08x\n", odp->u.var.values[j] ); + fprintf( outfile, "0x%08x,", odp->u.var.values[j] ); + fprintf( outfile, "0x%08x\n", odp->u.var.values[j] ); } - output( ".L__wine_spec_data_segment_end:\n" ); + fprintf( outfile, ".L__wine_spec_data_segment_end:\n" ); /* resource data */ if (spec->nb_resources) { - output( "\n.L__wine_spec_resource_data:\n" ); - output_res16_data( spec ); + fprintf( outfile, "\n.L__wine_spec_resource_data:\n" ); + output_res16_data( outfile, spec ); } - output( "\t.byte 0\n" ); /* make sure the last symbol points to something */ + fprintf( outfile, "\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) { - 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/* 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\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 ); + 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_stubs( spec ); - output_get_pc_thunk(); - output_init_code( spec, header_name ); - output_gnu_stack_note(); + output_stubs( outfile, spec ); + output_get_pc_thunk( outfile ); + output_init_code( outfile, spec, header_name ); free( typelist ); } diff --git a/reactos/tools/winebuild/spec32.c b/reactos/tools/winebuild/spec32.c index 2f8cf7567f7..bf45ffdb469 100644 --- a/reactos/tools/winebuild/spec32.c +++ b/reactos/tools/winebuild/spec32.c @@ -19,11 +19,10 @@ * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" -#include "wine/port.h" #include #include @@ -31,7 +30,10 @@ #include #include "winglue.h" -//#include "wine/exception.h" + +#define EXCEPTION_WINE_STUB 0x80000100 /* stub entry point called */ +#define EH_NONCONTINUABLE 0x01 + #include "build.h" @@ -50,7 +52,7 @@ static inline int needs_relay( const ORDDEF *odp ) /* check if dll will output relay thunks */ int has_relays( DLLSPEC *spec ) { - int i; + unsigned int i; if (target_cpu != CPU_x86) return 0; @@ -62,36 +64,57 @@ int has_relays( DLLSPEC *spec ) return 0; } +/******************************************************************* + * make_internal_name + * + * Generate an internal name for an entry point. Used for stubs etc. + */ +static const char *make_internal_name( const ORDDEF *odp, DLLSPEC *spec, const char *prefix ) +{ + static char buffer[256]; + if (odp->name || odp->export_name) + { + char *p; + sprintf( buffer, "__wine_%s_%s_%s", prefix, spec->file_name, + odp->name ? odp->name : odp->export_name ); + /* make sure name is a legal C identifier */ + for (p = buffer; *p; p++) if (!isalnum(*p) && *p != '_') break; + if (!*p) return buffer; + } + sprintf( buffer, "__wine_%s_%s_%d", prefix, make_c_identifier(spec->file_name), odp->ordinal ); + return buffer; +} + + /******************************************************************* * output_relay_debug * * Output entry points for relay debugging */ -static void output_relay_debug( DLLSPEC *spec ) +static void output_relay_debug( FILE *outfile, DLLSPEC *spec ) { - int i; - unsigned int j, args, flags; + unsigned int i, j, args, flags; /* first the table of entry point offsets */ - 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" ); + 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" ); for (i = spec->base; i <= spec->limit; i++) { ORDDEF *odp = spec->ordinals[i]; if (needs_relay( odp )) - output( "\t.long .L__wine_spec_relay_entry_point_%d-__wine_spec_relay_entry_points\n", i ); + fprintf( outfile, "\t.long .L__wine_spec_relay_entry_point_%d-__wine_spec_relay_entry_points\n", i ); else - output( "\t.long 0\n" ); + fprintf( outfile, "\t.long 0\n" ); } /* then the table of argument types */ - output( "\t.align %d\n", get_alignment(4) ); - output( ".L__wine_spec_relay_arg_types:\n" ); + fprintf( outfile, "\t.align %d\n", get_alignment(4) ); + fprintf( outfile, ".L__wine_spec_relay_arg_types:\n" ); for (i = spec->base; i <= spec->limit; i++) { @@ -106,14 +129,14 @@ static void output_relay_debug( DLLSPEC *spec ) if (odp->u.func.arg_types[j] == 'W') mask |= 2<< (j*2); } } - output( "\t.long 0x%08x\n", mask ); + fprintf( outfile, "\t.long 0x%08x\n", mask ); } /* then the relay thunks */ - output( "\t.text\n" ); - output( "__wine_spec_relay_entry_points:\n" ); - output( "\tnop\n" ); /* to avoid 0 offset */ + fprintf( outfile, "\t.text\n" ); + fprintf( outfile, "__wine_spec_relay_entry_points:\n" ); + fprintf( outfile, "\tnop\n" ); /* to avoid 0 offset */ for (i = spec->base; i <= spec->limit; i++) { @@ -121,39 +144,39 @@ static void output_relay_debug( DLLSPEC *spec ) if (!needs_relay( odp )) continue; - output( "\t.align %d\n", get_alignment(4) ); - output( ".L__wine_spec_relay_entry_point_%d:\n", i ); + fprintf( outfile, "\t.align %d\n", get_alignment(4) ); + fprintf( outfile, ".L__wine_spec_relay_entry_point_%d:\n", i ); if (odp->flags & FLAG_REGISTER) - output( "\tpushl %%eax\n" ); + fprintf( outfile, "\tpushl %%eax\n" ); else - output( "\tpushl %%esp\n" ); + fprintf( outfile, "\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; - output( "\tpushl $%u\n", (flags << 24) | (args << 16) | (i - spec->base) ); + fprintf( outfile, "\tpushl $%u\n", (flags << 24) | (args << 16) | (i - spec->base) ); if (UsePIC) { - output( "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") ); - output( "1:\tleal .L__wine_spec_relay_descr-1b(%%eax),%%eax\n" ); + 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" ); } - else output( "\tmovl $.L__wine_spec_relay_descr,%%eax\n" ); - output( "\tpushl %%eax\n" ); + else fprintf( outfile, "\tmovl $.L__wine_spec_relay_descr,%%eax\n" ); + fprintf( outfile, "\tpushl %%eax\n" ); if (odp->flags & FLAG_REGISTER) { - output( "\tcall *8(%%eax)\n" ); + fprintf( outfile, "\tcall *8(%%eax)\n" ); } else { - output( "\tcall *4(%%eax)\n" ); + fprintf( outfile, "\tcall *4(%%eax)\n" ); if (odp->type == TYPE_STDCALL) - output( "\tret $%u\n", args * get_ptr_size() ); + fprintf( outfile, "\tret $%u\n", args * get_ptr_size() ); else - output( "\tret\n" ); + fprintf( outfile, "\tret\n" ); } } } @@ -163,46 +186,46 @@ static void output_relay_debug( DLLSPEC *spec ) * * Output the export table for a Win32 module. */ -static void output_exports( DLLSPEC *spec ) +static void output_exports( FILE *outfile, DLLSPEC *spec ) { int i, fwd_size = 0; int nr_exports = spec->base <= spec->limit ? spec->limit - spec->base + 1 : 0; if (!nr_exports) return; - output( "\n/* export table */\n\n" ); - output( "\t.data\n" ); - output( "\t.align %d\n", get_alignment(4) ); - output( ".L__wine_spec_exports:\n" ); + 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" ); /* export directory header */ - 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 */ + 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 */ if (spec->nb_names) { - 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 */ + 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 */ } else { - output( "\t.long 0\n" ); /* AddressOfNames */ - output( "\t.long 0\n" ); /* AddressOfNameOrdinals */ + fprintf( outfile, "\t.long 0\n" ); /* AddressOfNames */ + fprintf( outfile, "\t.long 0\n" ); /* AddressOfNameOrdinals */ } /* output the function pointers */ - output( "\n.L__wine_spec_exports_funcs:\n" ); + fprintf( outfile, "\n.L__wine_spec_exports_funcs:\n" ); for (i = spec->base; i <= spec->limit; i++) { ORDDEF *odp = spec->ordinals[i]; - if (!odp) output( "\t%s 0\n", get_asm_ptr_keyword() ); + if (!odp) fprintf( outfile, "\t.long 0\n" ); else switch(odp->type) { case TYPE_EXTERN: @@ -211,21 +234,21 @@ static void output_exports( DLLSPEC *spec ) case TYPE_CDECL: if (odp->flags & FLAG_FORWARD) { - output( "\t%s .L__wine_spec_forwards+%u\n", get_asm_ptr_keyword(), fwd_size ); + fprintf( outfile, "\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) { - output( "\t%s %s_%s\n", + fprintf( outfile, "\t%s %s_%s\n", get_asm_ptr_keyword(), asm_name("__wine_spec_ext_link"), odp->link_name ); } else { - output( "\t%s %s\n", get_asm_ptr_keyword(), asm_name(odp->link_name) ); + fprintf( outfile, "\t%s %s\n", get_asm_ptr_keyword(), asm_name(odp->link_name) ); } break; case TYPE_STUB: - output( "\t%s %s\n", get_asm_ptr_keyword(), + fprintf( outfile, "\t%s %s\n", get_asm_ptr_keyword(), asm_name( get_stub_name( odp, spec )) ); break; default: @@ -239,68 +262,68 @@ static void output_exports( DLLSPEC *spec ) int namepos = strlen(spec->file_name) + 1; - output( "\n.L__wine_spec_exp_name_ptrs:\n" ); + fprintf( outfile, "\n.L__wine_spec_exp_name_ptrs:\n" ); for (i = 0; i < spec->nb_names; i++) { - output( "\t.long .L__wine_spec_exp_names+%u-.L__wine_spec_rva_base\n", namepos ); + fprintf( outfile, "\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 */ - output( "\n.L__wine_spec_exp_ordinals:\n" ); + fprintf( outfile, "\n.L__wine_spec_exp_ordinals:\n" ); for (i = 0; i < spec->nb_names; i++) { - output( "\t%s %d\n", + fprintf( outfile, "\t%s %d\n", get_asm_short_keyword(), spec->names[i]->ordinal - spec->base ); } if (spec->nb_names % 2) { - output( "\t%s 0\n", get_asm_short_keyword() ); + fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); } } /* output the export name strings */ - output( "\n.L__wine_spec_exp_names:\n" ); - output( "\t%s \"%s\"\n", get_asm_string_keyword(), spec->file_name ); + fprintf( outfile, "\n.L__wine_spec_exp_names:\n" ); + fprintf( outfile, "\t%s \"%s\"\n", get_asm_string_keyword(), spec->file_name ); for (i = 0; i < spec->nb_names; i++) - output( "\t%s \"%s\"\n", + fprintf( outfile, "\t%s \"%s\"\n", get_asm_string_keyword(), spec->names[i]->name ); /* output forward strings */ if (fwd_size) { - output( "\n.L__wine_spec_forwards:\n" ); + fprintf( outfile, "\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)) - output( "\t%s \"%s\"\n", get_asm_string_keyword(), odp->link_name ); + fprintf( outfile, "\t%s \"%s\"\n", get_asm_string_keyword(), odp->link_name ); } } - output( "\t.align %d\n", get_alignment(get_ptr_size()) ); - output( ".L__wine_spec_exports_end:\n" ); + fprintf( outfile, "\t.align %d\n", get_alignment(get_ptr_size()) ); + fprintf( outfile, ".L__wine_spec_exports_end:\n" ); /* output relays */ /* we only support relay debugging on i386 */ if (target_cpu != CPU_x86) { - output( "\t%s 0\n", get_asm_ptr_keyword() ); + fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() ); return; } - 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() ); + 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_relay_debug( spec ); + output_relay_debug( outfile, spec ); } @@ -309,7 +332,7 @@ static void output_exports( DLLSPEC *spec ) * * Output the functions for stub entry points */ -static void output_stub_funcs( DLLSPEC *spec ) +static void output_stub_funcs( FILE *outfile, DLLSPEC *spec ) { int i; @@ -331,13 +354,13 @@ static void output_stub_funcs( DLLSPEC *spec ) { const ORDDEF *odp = &spec->entry_points[i]; if (odp->type != TYPE_STUB) continue; - output( "void %s(void) ", (odp->name ? odp->name : odp->export_name) ); + fprintf( outfile, "void %s(void) ", make_internal_name( odp, spec, "stub" ) ); if (odp->name) - output( "{ __wine_spec_unimplemented_stub(__wine_spec_file_name, \"%s\"); }\n", odp->name ); + fprintf( outfile, "{ __wine_spec_unimplemented_stub(__wine_spec_file_name, \"%s\"); }\n", odp->name ); else if (odp->export_name) - output( "{ __wine_spec_unimplemented_stub(__wine_spec_file_name, \"%s\"); }\n", odp->export_name ); + fprintf( outfile, "{ __wine_spec_unimplemented_stub(__wine_spec_file_name, \"%s\"); }\n", odp->export_name ); else - output( "{ __wine_spec_unimplemented_stub(__wine_spec_file_name, \"%d\"); }\n", odp->ordinal ); + fprintf( outfile, "{ __wine_spec_unimplemented_stub(__wine_spec_file_name, \"%d\"); }\n", odp->ordinal ); } } @@ -347,33 +370,33 @@ static void output_stub_funcs( DLLSPEC *spec ) * * Output code for calling a dll constructor. */ -static void output_asm_constructor( const char *constructor ) +static void output_asm_constructor( FILE *outfile, const char *constructor ) { if (target_platform == PLATFORM_APPLE) { /* Mach-O doesn't have an init section */ - output( "\n\t.mod_init_func\n" ); - output( "\t.align %d\n", get_alignment(4) ); - output( "\t.long %s\n", asm_name(constructor) ); + 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) ); } else { - output( "\n\t.section \".init\",\"ax\"\n" ); + fprintf( outfile, "\n\t.section \".init\",\"ax\"\n" ); switch(target_cpu) { case CPU_x86: case CPU_x86_64: - output( "\tcall %s\n", asm_name(constructor) ); + fprintf( outfile, "\tcall %s\n", asm_name(constructor) ); break; case CPU_SPARC: - output( "\tcall %s\n", asm_name(constructor) ); - output( "\tnop\n" ); + fprintf( outfile, "\tcall %s\n", asm_name(constructor) ); + fprintf( outfile, "\tnop\n" ); break; case CPU_ALPHA: - output( "\tjsr $26,%s\n", asm_name(constructor) ); + fprintf( outfile, "\tjsr $26,%s\n", asm_name(constructor) ); break; case CPU_POWERPC: - output( "\tbl %s\n", asm_name(constructor) ); + fprintf( outfile, "\tbl %s\n", asm_name(constructor) ); break; } } @@ -385,32 +408,32 @@ static void output_asm_constructor( const char *constructor ) * * Build a Win32 C file from a spec file. */ -void BuildSpec32File( DLLSPEC *spec ) +void BuildSpec32File( FILE *outfile, DLLSPEC *spec ) { int machine = 0; unsigned int page_size = get_page_size(); resolve_imports( spec ); - output_standard_file_header(); + output_standard_file_header( outfile ); /* Reserve some space for the PE header */ - output( "\t.text\n" ); - output( "\t.align %d\n", get_alignment(page_size) ); - output( "__wine_spec_pe_header:\n" ); + fprintf( outfile, "\t.text\n" ); + fprintf( outfile, "\t.align %d\n", get_alignment(page_size) ); + fprintf( outfile, "__wine_spec_pe_header:\n" ); if (target_platform == PLATFORM_APPLE) - output( "\t.space 65536\n" ); + fprintf( outfile, "\t.space 65536\n" ); else - output( "\t.skip 65536\n" ); + fprintf( outfile, "\t.skip 65536\n" ); /* Output the NT header */ - 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, "\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( "\t.long 0x%04x\n", IMAGE_NT_SIGNATURE ); /* Signature */ + fprintf( outfile, "\t.long 0x%04x\n", IMAGE_NT_SIGNATURE ); /* Signature */ switch(target_cpu) { case CPU_x86: machine = IMAGE_FILE_MACHINE_I386; break; @@ -419,105 +442,104 @@ void BuildSpec32File( DLLSPEC *spec ) case CPU_ALPHA: machine = IMAGE_FILE_MACHINE_ALPHA; break; case CPU_SPARC: machine = IMAGE_FILE_MACHINE_UNKNOWN; break; } - output( "\t%s 0x%04x\n", /* Machine */ + fprintf( outfile, "\t%s 0x%04x\n", /* Machine */ get_asm_short_keyword(), machine ); - output( "\t%s 0\n", /* NumberOfSections */ + fprintf( outfile, "\t%s 0\n", /* NumberOfSections */ get_asm_short_keyword() ); - output( "\t.long 0\n" ); /* TimeDateStamp */ - output( "\t.long 0\n" ); /* PointerToSymbolTable */ - output( "\t.long 0\n" ); /* NumberOfSymbols */ - output( "\t%s %d\n", /* SizeOfOptionalHeader */ + 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 */ get_asm_short_keyword(), get_ptr_size() == 8 ? IMAGE_SIZEOF_NT_OPTIONAL64_HEADER : IMAGE_SIZEOF_NT_OPTIONAL32_HEADER ); - output( "\t%s 0x%04x\n", /* Characteristics */ + fprintf( outfile, "\t%s 0x%04x\n", /* Characteristics */ get_asm_short_keyword(), spec->characteristics ); - output( "\t%s 0x%04x\n", /* Magic */ + fprintf( outfile, "\t%s 0x%04x\n", /* Magic */ get_asm_short_keyword(), get_ptr_size() == 8 ? IMAGE_NT_OPTIONAL_HDR64_MAGIC : IMAGE_NT_OPTIONAL_HDR32_MAGIC ); - 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 */ + 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 */ /* note: we expand the AddressOfEntryPoint field on 64-bit by overwriting the BaseOfCode field */ - output( "\t%s %s\n", /* AddressOfEntryPoint */ + fprintf( outfile, "\t%s %s\n", /* AddressOfEntryPoint */ get_asm_ptr_keyword(), asm_name(spec->init_func) ); if (get_ptr_size() == 4) { - output( "\t.long 0\n" ); /* BaseOfCode */ - output( "\t.long 0\n" ); /* BaseOfData */ + fprintf( outfile, "\t.long 0\n" ); /* BaseOfCode */ + fprintf( outfile, "\t.long 0\n" ); /* BaseOfData */ } - output( "\t%s __wine_spec_pe_header\n", /* ImageBase */ + fprintf( outfile, "\t%s __wine_spec_pe_header\n", /* ImageBase */ get_asm_ptr_keyword() ); - output( "\t.long %u\n", page_size ); /* SectionAlignment */ - output( "\t.long %u\n", page_size ); /* FileAlignment */ - output( "\t%s 1,0\n", /* Major/MinorOperatingSystemVersion */ + 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 */ get_asm_short_keyword() ); - output( "\t%s 0,0\n", /* Major/MinorImageVersion */ + fprintf( outfile, "\t%s 0,0\n", /* Major/MinorImageVersion */ get_asm_short_keyword() ); - output( "\t%s %u,%u\n", /* Major/MinorSubsystemVersion */ + fprintf( outfile, "\t%s %u,%u\n", /* Major/MinorSubsystemVersion */ get_asm_short_keyword(), spec->subsystem_major, spec->subsystem_minor ); - output( "\t.long 0\n" ); /* Win32VersionValue */ - output( "\t.long %s-.L__wine_spec_rva_base\n", /* SizeOfImage */ + fprintf( outfile, "\t.long 0\n" ); /* Win32VersionValue */ + fprintf( outfile, "\t.long %s-.L__wine_spec_rva_base\n", /* SizeOfImage */ asm_name("_end") ); - output( "\t.long %u\n", page_size ); /* SizeOfHeaders */ - output( "\t.long 0\n" ); /* CheckSum */ - output( "\t%s 0x%04x\n", /* Subsystem */ + fprintf( outfile, "\t.long %u\n", page_size ); /* SizeOfHeaders */ + fprintf( outfile, "\t.long 0\n" ); /* CheckSum */ + fprintf( outfile, "\t%s 0x%04x\n", /* Subsystem */ get_asm_short_keyword(), spec->subsystem ); - output( "\t%s 0x%04x\n", /* DllCharacteristics */ - get_asm_short_keyword(), spec->dll_characteristics ); - output( "\t%s %u,%u\n", /* SizeOfStackReserve/Commit */ + fprintf( outfile, "\t%s 0\n", /* DllCharacteristics */ + get_asm_short_keyword() ); + fprintf( outfile, "\t%s %u,%u\n", /* SizeOfStackReserve/Commit */ get_asm_ptr_keyword(), (spec->stack_size ? spec->stack_size : 1024) * 1024, page_size ); - output( "\t%s %u,%u\n", /* SizeOfHeapReserve/Commit */ + fprintf( outfile, "\t%s %u,%u\n", /* SizeOfHeapReserve/Commit */ get_asm_ptr_keyword(), (spec->heap_size ? spec->heap_size : 1024) * 1024, page_size ); - output( "\t.long 0\n" ); /* LoaderFlags */ - output( "\t.long 16\n" ); /* NumberOfRvaAndSizes */ + fprintf( outfile, "\t.long 0\n" ); /* LoaderFlags */ + fprintf( outfile, "\t.long 16\n" ); /* NumberOfRvaAndSizes */ if (spec->base <= spec->limit) /* DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT] */ - output( "\t.long .L__wine_spec_exports-.L__wine_spec_rva_base," + fprintf( outfile, "\t.long .L__wine_spec_exports-.L__wine_spec_rva_base," ".L__wine_spec_exports_end-.L__wine_spec_exports\n" ); else - output( "\t.long 0,0\n" ); + fprintf( outfile, "\t.long 0,0\n" ); if (has_imports()) /* DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] */ - output( "\t.long .L__wine_spec_imports-.L__wine_spec_rva_base," + fprintf( outfile, "\t.long .L__wine_spec_imports-.L__wine_spec_rva_base," ".L__wine_spec_imports_end-.L__wine_spec_imports\n" ); else - output( "\t.long 0,0\n" ); + fprintf( outfile, "\t.long 0,0\n" ); if (spec->nb_resources) /* DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE] */ - output( "\t.long .L__wine_spec_resources-.L__wine_spec_rva_base," + fprintf( outfile, "\t.long .L__wine_spec_resources-.L__wine_spec_rva_base," ".L__wine_spec_resources_end-.L__wine_spec_resources\n" ); else - output( "\t.long 0,0\n" ); + fprintf( outfile, "\t.long 0,0\n" ); - 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, "\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( "\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 ); + 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 ); if (target_platform == PLATFORM_APPLE) - output( "\t.lcomm %s,4\n", asm_name("_end") ); + fprintf( outfile, "\t.lcomm %s,4\n", asm_name("_end") ); - output_stubs( spec ); - output_exports( spec ); - output_imports( spec ); - output_resources( spec ); - output_asm_constructor( "__wine_spec_init_ctor" ); - output_gnu_stack_note(); + output_stubs( outfile, spec ); + output_exports( outfile, spec ); + output_imports( outfile, spec ); + output_resources( outfile, spec ); + output_asm_constructor( outfile, "__wine_spec_init_ctor" ); } @@ -526,19 +548,20 @@ void BuildSpec32File( DLLSPEC *spec ) * * Build a Win32 def file from a spec file. */ -void BuildDef32File( DLLSPEC *spec ) +void BuildDef32File( FILE *outfile, DLLSPEC *spec ) { const char *name; int i, total; if (spec_file_name) - output( "; File generated automatically from %s; do not edit!\n\n", + fprintf( outfile, "; File generated automatically from %s; do not edit!\n\n", spec_file_name ); else - output( "; File generated automatically; do not edit!\n\n" ); + fprintf( outfile, "; File generated automatically; do not edit!\n\n" ); - output( "LIBRARY %s\n\n", spec->file_name); - output( "EXPORTS\n"); + fprintf(outfile, "LIBRARY %s\n\n", spec->file_name); + + fprintf(outfile, "EXPORTS\n"); /* Output the exports and relay entry points */ @@ -550,13 +573,13 @@ void BuildDef32File( 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 continue; + else name = make_internal_name( odp, spec, "noname_export" ); if (!(odp->flags & FLAG_PRIVATE)) total++; - - output( " %s", name ); + fprintf(outfile, " %s", name); switch(odp->type) { @@ -567,20 +590,20 @@ void BuildDef32File( DLLSPEC *spec ) case TYPE_CDECL: /* try to reduce output */ if(strcmp(name, odp->link_name) || (odp->flags & FLAG_FORWARD)) - output( "=%s", odp->link_name ); + fprintf(outfile, "=%s", odp->link_name); break; case TYPE_STDCALL: { int at_param = strlen(odp->u.func.arg_types) * get_ptr_size(); - if (!kill_at) output( "@%d", at_param ); + if (!kill_at) fprintf(outfile, "@%d", at_param); if (odp->flags & FLAG_FORWARD) { - output( "=%s", odp->link_name ); + fprintf(outfile, "=%s", odp->link_name); } else if (strcmp(name, odp->link_name)) /* try to reduce output */ { - output( "=%s", odp->link_name ); - if (!kill_at) output( "@%d", at_param ); + fprintf(outfile, "=%s", odp->link_name); + if (!kill_at) fprintf(outfile, "@%d", at_param); } break; } @@ -597,23 +620,30 @@ void BuildDef32File( DLLSPEC *spec ) if (name != check && check != name + strlen(name) && '@' == check[-1]) { - output("%s", check - 1); + fprintf(outfile, "%s", check - 1); } } if (NULL != odp->name) { - output("=%s", odp->name); + fprintf(outfile, "=%s", make_internal_name( odp, spec, "stub" )); } break; } default: assert(0); } - 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" ); + 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" ); } if (!total) warning( "%s: Import library doesn't export anything\n", spec->file_name ); } @@ -624,34 +654,34 @@ void BuildDef32File( DLLSPEC *spec ) * * Build a PE DLL C file from a spec file. */ -void BuildPedllFile( DLLSPEC *spec ) +void BuildPedllFile( FILE *outfile, DLLSPEC *spec ) { int nr_exports; nr_exports = spec->base <= spec->limit ? spec->limit - spec->base + 1 : 0; - output_standard_file_header(); + output_standard_file_header( outfile ); - 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, "#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( "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, "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( "static const char __wine_spec_file_name[] = \"%s\";\n\n", spec->file_name ); + fprintf( outfile, "static const char __wine_spec_file_name[] = \"%s\";\n\n", spec->file_name ); if (nr_exports) { /* Output the stub functions */ - output_stub_funcs( spec ); + output_stub_funcs( outfile, spec ); } } diff --git a/reactos/tools/winebuild/utils.c b/reactos/tools/winebuild/utils.c index b0972abc1cd..85d552355a2 100644 --- a/reactos/tools/winebuild/utils.c +++ b/reactos/tools/winebuild/utils.c @@ -15,11 +15,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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" -#include "wine/port.h" + +#if !defined(WIN32) +#undef strdup +#endif #include #include @@ -31,7 +34,6 @@ # include #endif -#include "winglue.h" #include "build.h" #define MAX_TMP_FILES 8 @@ -163,18 +165,6 @@ 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 ) { @@ -206,29 +196,31 @@ char *get_temp_file_name( const char *prefix, const char *suffix ) } /* output a standard header for generated files */ -void output_standard_file_header(void) +void output_standard_file_header( FILE *outfile ) { if (spec_file_name) - output( "/* File generated automatically from %s; do not edit! */\n", spec_file_name ); + fprintf( outfile, "/* File generated automatically from %s; do not edit! */\n", + spec_file_name ); else - output( "/* File generated automatically; do not edit! */\n" ); - output( "/* This file can be copied, modified and distributed without restriction. */\n\n" ); + fprintf( outfile, "/* File generated automatically; do not edit! */\n" ); + fprintf( outfile, + "/* This file can be copied, modified and distributed without restriction. */\n\n" ); } /* dump a byte stream into the assembly code */ -void dump_bytes( const void *buffer, unsigned int size ) +void dump_bytes( FILE *outfile, const void *buffer, unsigned int size ) { unsigned int i; const unsigned char *ptr = buffer; if (!size) return; - output( "\t.byte " ); + fprintf( outfile, "\t.byte " ); for (i = 0; i < size - 1; i++, ptr++) { - if ((i % 16) == 15) output( "0x%02x\n\t.byte ", *ptr ); - else output( "0x%02x,", *ptr ); + if ((i % 16) == 15) fprintf( outfile, "0x%02x\n\t.byte ", *ptr ); + else fprintf( outfile, "0x%02x,", *ptr ); } - output( "0x%02x\n", *ptr ); + fprintf( outfile, "0x%02x\n", *ptr ); } @@ -332,12 +324,7 @@ DLLSPEC *alloc_dll_spec(void) spec->alloc_entry_points = 0; spec->nb_names = 0; spec->nb_resources = 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->characteristics = 0; spec->subsystem = 0; spec->subsystem_major = 4; spec->subsystem_minor = 0; @@ -457,7 +444,7 @@ unsigned int get_alignment(unsigned int align) case CPU_POWERPC: case CPU_ALPHA: n = 0; - while ((1u << n) != align) n++; + while ((1 << n) != align) n++; return n; } /* unreached */ @@ -536,7 +523,7 @@ const char *func_declaration( const char *func ) } /* output a size declaration for an assembly function */ -void output_function_size( const char *name ) +void output_function_size( FILE *outfile, const char *name ) { switch (target_platform) { @@ -544,21 +531,7 @@ void output_function_size( const char *name ) case PLATFORM_WINDOWS: break; default: - 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" ); + fprintf( outfile, "\t.size %s, .-%s\n", name, name ); break; } } diff --git a/reactos/tools/winebuild/winebuild.man.in b/reactos/tools/winebuild/winebuild.man.in index d13596812fc..6c9bafcbdd5 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 main -for executables (if the standard C -.B main -is not defined, .B WinMain +for executables (if +.B WinMain +is not defined, the standard C +.B main is used instead). This is only valid for Win32 modules. .TP .BI \-E,\ --export= filename @@ -85,14 +85,6 @@ 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 @@ -153,10 +145,6 @@ 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 @@ -260,8 +248,7 @@ The entry point is not displayed in relay debugging traces (Win32 only). .TP .B -noname -The entry point will be exported by ordinal instead of by name. The -name is still available for importing. +The entry point will be imported by ordinal instead of by name. .TP .B -ret16 The function returns a 16-bit value (Win16 only). @@ -278,10 +265,6 @@ 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 39591341221..1c138b84338 100644 --- a/reactos/tools/winebuild/winglue.h +++ b/reactos/tools/winebuild/winglue.h @@ -17,9 +17,6 @@ typedef unsigned int UINT_PTR; #define DLL_PROCESS_ATTACH 1 #define DLL_PROCESS_DETACH 0 -#define IMAGE_FILE_EXECUTABLE_IMAGE 2 -#define IMAGE_FILE_LARGE_ADDRESS_AWARE 32 -#define IMAGE_FILE_32BIT_MACHINE 256 #define IMAGE_FILE_DLL 8192 #define IMAGE_SUBSYSTEM_NATIVE 1 #define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 @@ -31,7 +28,6 @@ typedef unsigned int UINT_PTR; #define IMAGE_FILE_MACHINE_POWERPC 0x01f0 #define IMAGE_FILE_MACHINE_AMD64 0x8664 #define IMAGE_NT_SIGNATURE 0x00004550 -#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT 0x0100 #define IMAGE_SIZEOF_NT_OPTIONAL32_HEADER 224 #define IMAGE_SIZEOF_NT_OPTIONAL64_HEADER 240 #define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b