Sync to Wine-20050830: Alexandre Julliard julliard@winehq.org - Beginnings of a crt0 library. - Added a warning for DllGetVersion and DllInstall not being declared private. Also warn when one of the Dll* functions is using a different internal name. - Added a --undefined option to allow forcing some symbols to be resolved by the linker. - Byteswap the resources if we detect that the header is in the wrong endianness. - Moved more of the spec initialization code to the winecrt0 library, and get rid of implicit kernel32 imports. - Use __wine_unimplemented_stub from crt0 for 16-bit spec files too. - Moved the delay loading support code to the winecrt0 library. - Avoid using common symbols, they are broken on Mac OS. - Moved the implementation of spec file stubs to the winecrt0 library. - The exported name strings should be inside the export directory (found by Vitaliy Margolen). - Added some general purpose routines for managing list of symbol names. - Print a warning when a generated import library doesn't export anything useful. - Implemented DelayLoadFailureHook and use it in the winebuild-generated delay load code. - Compute the ordinal base and limit in assign_ordinals instead of doing it while parsing. - Get rid of the unused owner_name field. Ge van Geldorp gvg@reactos.org - Adapt changes to ReactOS Modified: trunk/reactos/tools/winebuild/build.h Modified: trunk/reactos/tools/winebuild/import.c Modified: trunk/reactos/tools/winebuild/main.c Modified: trunk/reactos/tools/winebuild/parser.c Modified: trunk/reactos/tools/winebuild/res32.c Modified: trunk/reactos/tools/winebuild/spec16.c Modified: trunk/reactos/tools/winebuild/spec32.c Modified: trunk/reactos/tools/winebuild/utils.c Modified: trunk/reactos/tools/winebuild/winebuild.man.in _____
Modified: trunk/reactos/tools/winebuild/build.h --- trunk/reactos/tools/winebuild/build.h 2005-09-05 10:18:07 UTC (rev 17658) +++ trunk/reactos/tools/winebuild/build.h 2005-09-05 17:35:31 UTC (rev 17659) @@ -88,7 +88,6 @@
{ char *file_name; /* file name of the dll */ char *dll_name; /* internal name of the dll */ - char *owner_name; /* name of the 32-bit dll owning this one */ char *init_func; /* initialization routine */ SPEC_TYPE type; /* type of dll (Win16/Win32) */ int base; /* ordinal base */ @@ -190,7 +189,8 @@ extern void add_import_dll( const char *name, const char *filename ); extern void add_delayed_import( const char *name ); extern void add_ignore_symbol( const char *name ); -extern void read_undef_symbols( char **argv ); +extern void add_extra_ld_symbol( const char *name ); +extern void read_undef_symbols( DLLSPEC *spec, char **argv ); extern int resolve_imports( DLLSPEC *spec ); extern int output_imports( FILE *outfile, DLLSPEC *spec, int *nb_delayed ); extern void output_import_thunks( FILE *outfile, DLLSPEC *spec ); _____
Modified: trunk/reactos/tools/winebuild/import.c --- trunk/reactos/tools/winebuild/import.c 2005-09-05 10:18:07 UTC (rev 17658) +++ trunk/reactos/tools/winebuild/import.c 2005-09-05 17:35:31 UTC (rev 17659) @@ -21,6 +21,7 @@
#include "config.h"
+#include <assert.h> #include <ctype.h> #include <fcntl.h> #include <stdio.h> @@ -34,7 +35,6 @@ #endif
#include "winglue.h" -//#include "wine/exception.h" #include "build.h"
#ifndef EXCEPTION_NONCONTINUABLE @@ -56,13 +56,16 @@ int nb_imports; /* number of imported functions */ };
-static char **undef_symbols; /* list of undefined symbols */ -static int nb_undef_symbols = -1; -static int undef_size; +struct name_table +{ + char **names; + unsigned int count, size; +};
-static char **ignore_symbols; /* list of symbols to ignore */ -static int nb_ignore_symbols; -static int ignore_size; +static struct name_table undef_symbols; /* list of undefined symbols */ +static struct name_table ignore_symbols; /* list of symbols to ignore */ +static struct name_table extra_ld_symbols; /* list of extra symbols that ld should resolve */ +static struct name_table delayed_imports; /* list of delayed import dlls */
static char *ld_tmp_file; /* ld temp file name */
@@ -71,8 +74,6 @@ static int nb_delayed = 0; /* number of delayed dlls */ static int total_imports = 0; /* total number of imported functions */ static int total_delayed = 0; /* total number of imported functions in delayed DLLs */ -static char **delayed_imports; /* names of delayed import dlls */ -static int nb_delayed_imports; /* size of the delayed_imports array */
/* list of symbols that are ignored by default */ static const char * const default_ignored_symbols[] = @@ -151,18 +152,52 @@ odp2->name ? odp2->name : odp2->export_name ); }
-/* locate a symbol in a (sorted) list */ -inline static const char *find_symbol( const char *name, char **table, int size ) +/* add a name to a name table */ +inline static void add_name( struct name_table *table, const char *name ) { - char **res = NULL; - - if (table) { - res = bsearch( &name, table, size, sizeof(*table), name_cmp ); + if (table->count == table->size) + { + table->size += (table->size / 2); + if (table->size < 32) table->size = 32; + table->names = xrealloc( table->names, table->size * sizeof(*table->names) ); } + table->names[table->count++] = xstrdup( name ); +}
+/* remove a name from a name table */ +inline static void remove_name( struct name_table *table, unsigned int idx ) +{ + assert( idx < table->count ); + free( table->names[idx] ); + memmove( table->names + idx, table->names + idx + 1, + (table->count - idx - 1) * sizeof(*table->names) ); + table->count--; +} + +/* make a name table empty */ +inline static void empty_name_table( struct name_table *table ) +{ + unsigned int i; + + for (i = 0; i < table->count; i++) free( table->names[i] ); + table->count = 0; +} + +/* locate a name in a (sorted) list */ +inline static const char *find_name( const char *name, const struct name_table *table ) +{ + char **res = NULL; + + if (table->count) res = bsearch( &name, table->names, table->count, sizeof(*table->names), name_cmp ); return res ? *res : NULL; }
+/* sort a name 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 */ inline static ORDDEF *find_export( const char *name, ORDDEF **table, int size ) { @@ -175,13 +210,6 @@ return res ? *res : NULL; }
-/* sort a symbol table */ -inline static void sort_symbols( char **table, int size ) -{ - if (table ) - qsort( table, size, sizeof(*table), name_cmp ); -} - inline static void output_function_size( FILE *outfile, const char *name ) { const char *size = func_size( name ); @@ -209,9 +237,9 @@ { int i;
- for (i = 0; i < nb_delayed_imports; i++) + for (i = 0; i < delayed_imports.count; i++) { - if (!strcmp( delayed_imports[i], name )) return 1; + if (!strcmp( delayed_imports.names[i], name )) return 1; } return 0; } @@ -367,13 +395,13 @@ struct import *imp; char *fullname = get_dll_name( name, NULL );
- delayed_imports = xrealloc( delayed_imports, (nb_delayed_imports+1) * sizeof(*delayed_imports) ); - delayed_imports[nb_delayed_imports++] = fullname; + add_name( &delayed_imports, fullname ); if ((imp = is_already_imported( fullname )) && !imp->delay) { imp->delay = 1; nb_delayed++; } + free( fullname ); }
/* remove an imported dll, based on its index in the dll_imports array */ @@ -390,54 +418,37 @@ /* initialize the list of ignored symbols */ static void init_ignored_symbols(void) { - int i; + unsigned int i;
- nb_ignore_symbols = sizeof(default_ignored_symbols)/sizeof(default_ignored_symbols[0]); - ignore_size = nb_ignore_symbols + 32; - ignore_symbols = xmalloc( ignore_size * sizeof(*ignore_symbols) ); - for (i = 0; i < nb_ignore_symbols; i++) - ignore_symbols[i] = xstrdup( default_ignored_symbols[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 ) { - int i; + unsigned int i;
- if (!ignore_symbols) init_ignored_symbols(); /* first time around, fill list with defaults */ + if (!ignore_symbols.size) init_ignored_symbols(); /* first time around, fill list with defaults */
if (name[0] == '-') /* remove it */ { - if (!name[1]) /* remove everything */ + if (!name[1]) empty_name_table( &ignore_symbols ); /* remove everything */ + else for (i = 0; i < ignore_symbols.count; i++) { - for (i = 0; i < nb_ignore_symbols; i++) free( ignore_symbols[i] ); - nb_ignore_symbols = 0; + if (!strcmp( ignore_symbols.names[i], name+1 )) remove_name( &ignore_symbols, i-- ); } - else - { - for (i = 0; i < nb_ignore_symbols; i++) - { - if (!strcmp( ignore_symbols[i], name+1 )) - { - free( ignore_symbols[i] ); - memmove( &ignore_symbols[i], &ignore_symbols[i+1], nb_ignore_symbols - i - 1 ); - nb_ignore_symbols--; - } - } - } } - else - { - if (nb_ignore_symbols == ignore_size) - { - ignore_size += 32; - ignore_symbols = xrealloc( ignore_symbols, ignore_size * sizeof(*ignore_symbols) ); - } - ignore_symbols[nb_ignore_symbols++] = xstrdup( name ); - } + else add_name( &ignore_symbols, name ); }
+/* add a symbol to the list of extra symbols that ld must resolve */ +void add_extra_ld_symbol( const char *name ) +{ + add_name( &extra_ld_symbols, name ); +} + /* add a function to the list of imports from a given dll */ static void add_import_func( struct import *imp, ORDDEF *func ) { @@ -447,103 +458,33 @@ if (imp->delay) total_delayed++; }
-/* add a symbol to the undef list */ -inline static void add_undef_symbol( const char *name ) +/* check if the spec file exports any stubs */ +static int has_stubs( const DLLSPEC *spec ) { - if (nb_undef_symbols == undef_size) + int i; + for (i = 0; i < spec->nb_entry_points; i++) { - undef_size += 128; - undef_symbols = xrealloc( undef_symbols, undef_size * sizeof(*undef_symbols) ); + ORDDEF *odp = &spec->entry_points[i]; + if (odp->type == TYPE_STUB) return 1; } - undef_symbols[nb_undef_symbols++] = xstrdup( name ); + return 0; }
-/* remove all the holes in the undefined symbol list; return the number of removed symbols */ -static int remove_symbol_holes(void) +/* get the default entry point for a given spec file */ +static const char *get_default_entry_point( const DLLSPEC *spec ) { - int i, off; - for (i = off = 0; i < nb_undef_symbols; i++) - { - if (!undef_symbols[i]) off++; - else undef_symbols[i - off] = undef_symbols[i]; - } - nb_undef_symbols -= off; - return off; + if (spec->characteristics & IMAGE_FILE_DLL) return "__wine_spec_dll_entry"; + if (spec->subsystem == IMAGE_SUBSYSTEM_NATIVE) return "DriverEntry"; + return "__wine_spec_exe_entry"; }
-/* add a symbol to the extra list, but only if needed */ -static int add_extra_symbol( const char **extras, int *count, const char *name, const DLLSPEC *spec ) -{ - int i; - - if (!find_symbol( name, undef_symbols, nb_undef_symbols )) - { - /* check if the symbol is being exported by this dll */ - for (i = 0; i < spec->nb_entry_points; i++) - { - ORDDEF *odp = &spec->entry_points[i]; - if (odp->type == TYPE_STDCALL || - odp->type == TYPE_CDECL || - odp->type == TYPE_VARARGS || - odp->type == TYPE_EXTERN) - { - if (odp->name && !strcmp( odp->name, name )) return 0; - } - } - extras[*count] = name; - (*count)++; - } - return 1; -} - /* add the extra undefined symbols that will be contained in the generated spec file itself */ -static void add_extra_undef_symbols( const DLLSPEC *spec ) +static void add_extra_undef_symbols( DLLSPEC *spec ) { - const char *extras[10]; - int i, count = 0, nb_stubs = 0; - int kernel_imports = 0, ntdll_imports = 0; - - sort_symbols( undef_symbols, nb_undef_symbols ); - - for (i = 0; i < spec->nb_entry_points; i++) - { - ORDDEF *odp = &spec->entry_points[i]; - if (odp->type == TYPE_STUB) nb_stubs++; - } - - /* add symbols that will be contained in the spec file itself */ - if (!(spec->characteristics & IMAGE_FILE_DLL)) - { - switch (spec->subsystem) - { - case IMAGE_SUBSYSTEM_WINDOWS_GUI: - case IMAGE_SUBSYSTEM_WINDOWS_CUI: - kernel_imports += add_extra_symbol( extras, &count, "GetCommandLineA", spec ); - kernel_imports += add_extra_symbol( extras, &count, "GetStartupInfoA", spec ); - kernel_imports += add_extra_symbol( extras, &count, "GetModuleHandleA", spec ); - kernel_imports += add_extra_symbol( extras, &count, "ExitProcess", spec ); - break; - } - } - if (nb_delayed) - { - kernel_imports += add_extra_symbol( extras, &count, "LoadLibraryA", spec ); - kernel_imports += add_extra_symbol( extras, &count, "FreeLibrary", spec ); - kernel_imports += add_extra_symbol( extras, &count, "GetProcAddress", spec ); - kernel_imports += add_extra_symbol( extras, &count, "RaiseException", spec ); - } - if (nb_stubs) - ntdll_imports += add_extra_symbol( extras, &count, "RtlRaiseException", spec ); - - /* make sure we import the dlls that contain these functions */ - if (kernel_imports) add_import_dll( "kernel32", NULL ); - if (ntdll_imports) add_import_dll( "ntdll", NULL ); - - if (count) - { - for (i = 0; i < count; i++) add_undef_symbol( extras[i] ); - sort_symbols( undef_symbols, nb_undef_symbols ); - } + if (!spec->init_func) spec->init_func = xstrdup( get_default_entry_point(spec) ); + add_extra_ld_symbol( spec->init_func ); + if (has_stubs( spec )) add_extra_ld_symbol( "__wine_spec_unimplemented_stub" ); + if (nb_delayed) add_extra_ld_symbol( "__wine_spec_delay_load" ); }
/* check if a given imported dll is not needed, taking forwards into account */ @@ -570,8 +511,8 @@ /* returns the name of the combined file */ static const char *ldcombine_files( char **argv ) { - int i, len = 0; - char *cmd; + unsigned int i, len = 0; + char *cmd, *p; int fd, err;
if (output_file_name && output_file_name[0]) @@ -587,10 +528,14 @@ atexit( remove_ld_tmp_file );
if (!ld_command) ld_command = xstrdup("ld"); + for (i = 0; i < extra_ld_symbols.count; i++) len += strlen(extra_ld_symbols.names[i]) + 5; for (i = 0; argv[i]; i++) len += strlen(argv[i]) + 1; - cmd = xmalloc( len + strlen(ld_tmp_file) + 8 + strlen(ld_command) ); - sprintf( cmd, "%s -r -o %s", ld_command, ld_tmp_file ); - for (i = 0; argv[i]; i++) sprintf( cmd + strlen(cmd), " %s", argv[i] ); + cmd = p = xmalloc( len + strlen(ld_tmp_file) + 8 + strlen(ld_command) ); + p += sprintf( cmd, "%s -r -o %s", ld_command, ld_tmp_file ); + for (i = 0; i < extra_ld_symbols.count; i++) + p += sprintf( p, " -u %s", asm_name(extra_ld_symbols.names[i]) ); + for (i = 0; argv[i]; i++) + p += sprintf( p, " %s", argv[i] ); err = system( cmd ); if (err) fatal_error( "%s -r failed with status %d\n", ld_command, err ); free( cmd ); @@ -598,7 +543,7 @@ }
/* read in the list of undefined symbols */ -void read_undef_symbols( char **argv ) +void read_undef_symbols( DLLSPEC *spec, char **argv ) { size_t prefix_len; FILE *f; @@ -608,15 +553,13 @@
if (!argv[0]) return;
+ add_extra_undef_symbols( spec ); + strcpy( name_prefix, asm_name("") ); prefix_len = strlen( name_prefix );
- undef_size = nb_undef_symbols = 0; + name = ldcombine_files( argv );
- /* if we have multiple object files, link them together */ - if (argv[1]) name = ldcombine_files( argv ); - else name = argv[0]; - if (!nm_command) nm_command = xstrdup("nm"); cmd = xmalloc( strlen(nm_command) + strlen(name) + 5 ); sprintf( cmd, "%s -u %s", nm_command, name ); @@ -632,7 +575,7 @@ while (*p == ' ') p++; if (p[0] == 'U' && p[1] == ' ' && p[2]) p += 2; if (prefix_len && !strncmp( p, name_prefix, prefix_len )) p += prefix_len; - add_undef_symbol( p ); + add_name( &undef_symbols, p ); } if ((err = pclose( f ))) warning( "%s failed with status %d\n", cmd, err ); free( cmd ); @@ -640,47 +583,39 @@
static void remove_ignored_symbols(void) { - int i; + unsigned int i;
- if (!ignore_symbols) init_ignored_symbols(); - sort_symbols( ignore_symbols, nb_ignore_symbols ); - for (i = 0; i < nb_undef_symbols; i++) + if (!ignore_symbols.size) init_ignored_symbols(); + sort_names( &ignore_symbols ); + for (i = 0; i < undef_symbols.count; i++) { - if (find_symbol( undef_symbols[i], ignore_symbols, nb_ignore_symbols )) - { - free( undef_symbols[i] ); - undef_symbols[i] = NULL; - } + if (find_name( undef_symbols.names[i], &ignore_symbols )) + remove_name( &undef_symbols, i-- ); } - remove_symbol_holes(); }
/* resolve the imports for a Win32 module */ int resolve_imports( DLLSPEC *spec ) { - int i, j; + unsigned int i, j, removed;
- if (nb_undef_symbols == -1) return 0; /* no symbol file specified */ - - add_extra_undef_symbols( spec ); remove_ignored_symbols();
for (i = 0; i < nb_imports; i++) { struct import *imp = dll_imports[i];
- for (j = 0; j < nb_undef_symbols; j++) + for (j = removed = 0; j < undef_symbols.count; j++) { - ORDDEF *odp = find_export( undef_symbols[j], imp->exports, imp->nb_exports ); + ORDDEF *odp = find_export( undef_symbols.names[j], imp->exports, imp->nb_exports ); if (odp) { add_import_func( imp, odp ); - free( undef_symbols[j] ); - undef_symbols[j] = NULL; + remove_name( &undef_symbols, j-- ); + removed++; } } - /* remove all the holes in the undef symbols list */ - if (!remove_symbol_holes() && check_unused( imp, spec )) + if (!removed && check_unused( imp, spec )) { /* the dll is not used, get rid of it */ warning( "%s imported but no symbols used\n", imp->spec->file_name ); @@ -919,7 +854,7 @@ } } fprintf( outfile, "\n" ); - fprintf( outfile, "static struct {\n" ); + fprintf( outfile, "struct {\n" ); fprintf( outfile, " struct ImgDelayDescr {\n" ); fprintf( outfile, " unsigned int grAttrs;\n" ); fprintf( outfile, " const char *szName;\n" ); @@ -929,15 +864,15 @@ fprintf( outfile, " void* pBoundIAT;\n" ); fprintf( outfile, " void* pUnloadIAT;\n" ); fprintf( outfile, " unsigned long dwTimeStamp;\n" ); - fprintf( outfile, " } imp[%d];\n", nb_delayed ); + fprintf( outfile, " } imp[%d];\n", nb_delayed + 1 ); fprintf( outfile, " void *IAT[%d];\n", total_delayed ); fprintf( outfile, " const char *INT[%d];\n", total_delayed ); - fprintf( outfile, "} delay_imports = {\n" ); + fprintf( outfile, "} __wine_spec_delay_imports = {\n" ); fprintf( outfile, " {\n" ); for (i = j = 0; i < nb_imports; i++) { if (!dll_imports[i]->delay) continue; - fprintf( outfile, " { 0, "%s", &__wine_delay_imp_hmod[%d], &delay_imports.IAT[%d], &delay_imports.INT[%d], 0, 0, 0 },\n", + fprintf( outfile, " { 0, "%s", &__wine_delay_imp_hmod[%d], &__wine_spec_delay_imports.IAT[%d], &__wine_spec_delay_imports.INT[%d], 0, 0, 0 },\n", dll_imports[i]->spec->file_name, i, j, j ); j += dll_imports[i]->nb_imports; } @@ -969,32 +904,6 @@ } fprintf( outfile, " }\n};\n\n" );
- fprintf( outfile, "extern void __stdcall RaiseException(unsigned int, unsigned int, unsigned int, const void *args[]);\n" ); - fprintf( outfile, "extern void * __stdcall LoadLibraryA(const char*);\n"); - fprintf( outfile, "extern void * __stdcall GetProcAddress(void *, const char*);\n"); - fprintf( outfile, "\n" ); - - fprintf( outfile, "void *__stdcall __wine_delay_load( int idx_nr )\n" ); - fprintf( outfile, "{\n" ); - fprintf( outfile, " int idx = idx_nr >> 16, nr = idx_nr & 0xffff;\n" ); - fprintf( outfile, " struct ImgDelayDescr *imd = delay_imports.imp + idx;\n" ); - fprintf( outfile, " void **pIAT = imd->pIAT + nr;\n" ); - fprintf( outfile, " const char** pINT = imd->pINT + nr;\n" ); - fprintf( outfile, " void *fn;\n\n" ); - - fprintf( outfile, " if (!*imd->phmod) *imd->phmod = LoadLibraryA(imd->szName);\n" ); - fprintf( outfile, " if (*imd->phmod && (fn = GetProcAddress(*imd->phmod, *pINT)))\n"); - fprintf( outfile, " /* patch IAT with final value */\n" ); - fprintf( outfile, " return *pIAT = fn;\n" ); - fprintf( outfile, " else {\n"); - fprintf( outfile, " const void *args[2];\n" ); - fprintf( outfile, " args[0] = imd->szName;\n" ); - fprintf( outfile, " args[1] = *pINT;\n" ); - fprintf( outfile, " RaiseException( 0x%08x, %d, 2, args );\n", - EXCEPTION_WINE_STUB, EXCEPTION_NONCONTINUABLE ); - fprintf( outfile, " return 0;\n" ); - fprintf( outfile, " }\n}\n" ); - return nb_delayed; }
@@ -1017,17 +926,17 @@ { case CPU_x86: fprintf( outfile, " "\tpushl %%ecx\n\tpushl %%edx\n\tpushl %%eax\n"\n" ); - fprintf( outfile, " "\tcall %s\n"\n", asm_name("__wine_delay_load") ); + fprintf( outfile, " "\tcall %s\n"\n", asm_name("__wine_spec_delay_load") ); fprintf( outfile, " "\tpopl %%edx\n\tpopl %%ecx\n\tjmp *%%eax\n"\n" ); break; case CPU_SPARC: fprintf( outfile, " "\tsave %%sp, -96, %%sp\n"\n" ); - fprintf( outfile, " "\tcall %s\n"\n", asm_name("__wine_delay_load") ); + fprintf( outfile, " "\tcall %s\n"\n", asm_name("__wine_spec_delay_load") ); fprintf( outfile, " "\tmov %%g1, %%o0\n"\n" ); fprintf( outfile, " "\tjmp %%o0\n\trestore\n"\n" ); break; case CPU_ALPHA: - fprintf( outfile, " "\tjsr $26,%s\n"\n", asm_name("__wine_delay_load") ); + fprintf( outfile, " "\tjsr $26,%s\n"\n", asm_name("__wine_spec_delay_load") ); fprintf( outfile, " "\tjmp $31,($0)\n"\n" ); break; case CPU_POWERPC: @@ -1054,7 +963,7 @@ fprintf( outfile, " "\tstw %s, %d(%s)\n"\n", ppc_reg(0), 44+extra_stack_storage, ppc_reg(1));
/* Call the __wine_delay_load function, arg1 is arg1. */ - fprintf( outfile, " "\tbl %s\n"\n", asm_name("__wine_delay_load") ); + fprintf( outfile, " "\tbl %s\n"\n", asm_name("__wine_spec_delay_load") );
/* Load return value from call into ctr register */ fprintf( outfile, " "\tmtctr %s\n"\n", ppc_reg(3)); @@ -1145,7 +1054,7 @@
fprintf( outfile, "\n ".align %d\n"\n", get_alignment(8) ); fprintf( outfile, " "%s:\n"\n", asm_name(delayed_import_thunks)); - pos = nb_delayed * 32; + pos = (nb_delayed + 1) * 32; for (i = 0; i < nb_imports; i++) { if (!dll_imports[i]->delay) continue; @@ -1153,7 +1062,7 @@ { ORDDEF *odp = dll_imports[i]->imports[j]; output_import_thunk( outfile, odp->name ? odp->name : odp->export_name, - "delay_imports", pos ); + "__wine_spec_delay_imports", pos ); } } output_function_size( outfile, delayed_import_thunks ); _____
Modified: trunk/reactos/tools/winebuild/main.c --- trunk/reactos/tools/winebuild/main.c 2005-09-05 10:18:07 UTC (rev 17658) +++ trunk/reactos/tools/winebuild/main.c 2005-09-05 17:35:31 UTC (rev 17659) @@ -233,31 +233,32 @@
static const char usage_str[] = "Usage: winebuild [OPTIONS] [FILES]\n\n" "Options:\n" -" -C --source-dir=DIR Look for source files in DIR\n" -" -d --delay-lib=LIB Import the specified library in delayed mode\n" -" -D SYM Ignored for C flags compatibility\n" -" -E --export=FILE Export the symbols defined in the .spec or .def file\n" -" -e --entry=FUNC Set the DLL entry point function (default: DllMain)\n" -" -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" -" -H --heap=SIZE Set the heap size for a Win16 dll\n" -" -i --ignore=SYM[,SYM] Ignore specified symbols when resolving imports\n" -" -I DIR Ignored for C flags compatibility\n" -" -k --kill-at Kill stdcall decorations in generated .def files\n" -" -K FLAGS Compiler flags (only -KPIC is supported)\n" +" -C, --source-dir=DIR Look for source files in DIR\n" +" -d, --delay-lib=LIB Import the specified library in delayed mode\n" +" -D SYM Ignored for C flags compatibility\n" +" -E, --export=FILE Export the symbols defined in the .spec or .def file\n" +" -e, --entry=FUNC Set the DLL entry point function (default: DllMain)\n" +" -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" +" -H, --heap=SIZE Set the heap size for a Win16 dll\n" +" -i, --ignore=SYM[,SYM] Ignore specified symbols when resolving imports\n" +" -I DIR Ignored for C flags compatibility\n" +" -k, --kill-at Kill stdcall decorations in generated .def files\n" +" -K, FLAGS Compiler flags (only -KPIC is supported)\n" " --ld-cmd=LD Command to use for linking (default: ld)\n" -" -l --library=LIB Import the specified library\n" -" -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" +" -l, --library=LIB Import the specified library\n" +" -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" -" -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" +" -N, --dll-name=DLLNAME Set the DLL name (default: from input file name)\n" +" -o, --output=NAME Set the output file name (default: stdout)\n" +" -r, --res=RSRC.RES Load resources from RSRC.RES\n" " --subsystem=SUBSYS Set the subsystem (one of native, windows, console)\n" " --target=TARGET Specify target CPU and platform for cross-compiling\n" +" -u, --undefined=SYMBOL Add an undefined reference to SYMBOL when linking\n" " --version Print the version and exit\n" -" -w --warnings Turn on warnings\n" +" -w, --warnings Turn on warnings\n" "\nMode options:\n" " --dll Build a .c file from a .spec or .def file\n" " --def Build a .def file from a .spec file\n" @@ -284,7 +285,7 @@ LONG_OPT_PEDLL };
-static const char short_options[] = "C:D:E:F:H:I:K:L:M:N:d:e:f:hi:kl:m:o:r:w"; +static const char short_options[] = "C:D:E:F:H:I:K:L:M:N:d:e:f:hi:kl:m:o:r:u:w";
static const struct option long_options[] = { @@ -316,6 +317,7 @@ { "dll-name", 1, 0, 'N' }, { "output", 1, 0, 'o' }, { "res", 1, 0, 'r' }, + { "undefined", 1, 0, 'u' }, { "warnings", 0, 0, 'w' }, { NULL, 0, 0, 0 } }; @@ -373,7 +375,6 @@ lib_path[nb_lib_paths++] = xstrdup( optarg ); break; case 'M': - spec->owner_name = xstrdup( optarg ); spec->type = SPEC_WIN16; break; case 'N': @@ -423,6 +424,9 @@ res_files = xrealloc( res_files, (nb_res_files+1) * sizeof(*res_files) ); res_files[nb_res_files++] = xstrdup( optarg ); break; + case 'u': + add_extra_ld_symbol( optarg ); + break; case 'w': display_warnings = 1; break; @@ -568,7 +572,7 @@ fatal_error( "Win16 specs are not supported in ReactOS version of winebuild\n" ); break; case SPEC_WIN32: - read_undef_symbols( argv ); + read_undef_symbols( spec, argv ); BuildSpec32File( output_file, spec ); break; default: assert(0); @@ -580,7 +584,7 @@ load_resources( argv, spec ); load_import_libs( argv ); if (spec_file_name && !parse_input_file( spec )) break; - read_undef_symbols( argv ); + read_undef_symbols( spec, argv ); BuildSpec32File( output_file, spec ); break; case MODE_DEF: _____
Modified: trunk/reactos/tools/winebuild/parser.c --- trunk/reactos/tools/winebuild/parser.c 2005-09-05 10:18:07 UTC (rev 17658) +++ trunk/reactos/tools/winebuild/parser.c 2005-09-05 17:35:31 UTC (rev 17659) @@ -520,9 +520,14 @@
if (!strcmp( odp->name, "DllRegisterServer" ) || !strcmp( odp->name, "DllUnregisterServer" ) || !strcmp( odp->name, "DllGetClassObject" ) || + !strcmp( odp->name, "DllGetVersion" ) || + !strcmp( odp->name, "DllInstall" ) || !strcmp( odp->name, "DllCanUnloadNow" )) { warning( "Function %s should be marked private\n", odp->name ); + if (strcmp( odp->name, odp->link_name )) + warning( "Function %s should not use a different internal name (%s)\n", + odp->name, odp->link_name ); } }
@@ -602,6 +607,16 @@ int i, count, ordinal;
/* start assigning from base, or from 1 if no ordinal defined yet */ + + spec->base = MAX_ORDINALS; + spec->limit = 0; + for (i = 0; i < spec->nb_entry_points; i++) + { + ordinal = spec->entry_points[i].ordinal; + if (ordinal == -1) continue; + if (ordinal > spec->limit) spec->limit = ordinal; + if (ordinal < spec->base) spec->base = ordinal; + } if (spec->base == MAX_ORDINALS) spec->base = 1; if (spec->limit < spec->base) spec->limit = spec->base;
@@ -819,8 +834,6 @@ error( "Ordinal number %d too large\n", ordinal ); goto error; } - if (ordinal > spec->limit) spec->limit = ordinal; - if (ordinal < spec->base) spec->base = ordinal; odp->ordinal = ordinal; token = GetToken(1); } _____
Modified: trunk/reactos/tools/winebuild/res32.c --- trunk/reactos/tools/winebuild/res32.c 2005-09-05 10:18:07 UTC (rev 17658) +++ trunk/reactos/tools/winebuild/res32.c 2005-09-05 17:35:31 UTC (rev 17659) @@ -82,6 +82,7 @@
unsigned int nb_types; /* total number of types */ };
+static int byte_swapped; /* whether the current resource file is byte-swapped */ static const unsigned char *file_pos; /* current position in resource file */ static const unsigned char *file_end; /* end of resource file */ static const char *file_name; /* current resource file name */ @@ -137,6 +138,7 @@ static WORD get_word(void) { WORD ret = *(const WORD *)file_pos; + if (byte_swapped) ret = (ret << 8) | (ret >> 8); file_pos += sizeof(WORD); if (file_pos > file_end) fatal_error( "%s is a truncated file\n", file_name ); return ret; @@ -146,6 +148,8 @@ static DWORD get_dword(void) { DWORD ret = *(const DWORD *)file_pos; + if (byte_swapped) + ret = ((ret << 24) | ((ret << 8) & 0x00ff0000) | ((ret >> 8) & 0x0000ff00) | (ret >> 24)); file_pos += sizeof(DWORD); if (file_pos > file_end) fatal_error( "%s is a truncated file\n", file_name ); return ret; @@ -173,8 +177,12 @@ /* all values must be zero except header size */ static int check_header(void) { + DWORD size; + if (get_dword()) return 0; /* data size */ - if (get_dword() != 32) return 0; /* header size */ + size = get_dword(); /* header size */ + if (size == 0x20000000) byte_swapped = 1; + else if (size != 0x20) return 0; if (get_word() != 0xffff || get_word()) return 0; /* type, must be id 0 */ if (get_word() != 0xffff || get_word()) return 0; /* name, must be id 0 */ if (get_dword()) return 0; /* data version */ @@ -228,6 +236,7 @@ fatal_error( "Cannot read %s\n", name ); }
+ byte_swapped = 0; file_name = name; file_pos = base; file_end = file_pos + st.st_size; _____
Modified: trunk/reactos/tools/winebuild/spec16.c --- trunk/reactos/tools/winebuild/spec16.c 2005-09-05 10:18:07 UTC (rev 17658) +++ trunk/reactos/tools/winebuild/spec16.c 2005-09-05 17:35:31 UTC (rev 17659) @@ -362,15 +362,10 @@
ORDDEF *odp = spec->ordinals[i]; if (!odp || odp->type != TYPE_STUB) continue; fprintf( outfile, "#ifdef __GNUC__\n" ); - fprintf( outfile, "static void __wine_unimplemented( const char *func ) __attribute__((noreturn));\n" ); - fprintf( outfile, "#endif\n" ); - fprintf( outfile, "static void __wine_unimplemented( const char *func )\n{\n" ); - fprintf( outfile, " extern void __stdcall RaiseException( unsigned int, unsigned int, unsigned int, const void ** );\n" ); - fprintf( outfile, " const void *args[2];\n" ); - fprintf( outfile, " args[0] = "%s";\n", spec->file_name ); - fprintf( outfile, " args[1] = func;\n" ); - fprintf( outfile, " for (;;) RaiseException( 0x%08x, %d, 2, args );\n}\n\n", - EXCEPTION_WINE_STUB, EH_NONCONTINUABLE ); + fprintf( outfile, "extern void __wine_spec_unimplemented_stub( const char *module, const char *func ) __attribute__((noreturn));\n" ); + fprintf( outfile, "#else\n" ); + fprintf( outfile, "extern void __wine_spec_unimplemented_stub( const char *module, const char *func );\n" ); + fprintf( outfile, "#endif\n\n" ); break; } for (i = 0; i <= spec->limit; i++) @@ -381,7 +376,7 @@ strcpy( odp->link_name, "__wine_stub_" ); strcat( odp->link_name, odp->name ); for (p = odp->link_name; *p; p++) if (!isalnum(*p)) *p = '_'; - fprintf( outfile, "static void %s(void) { __wine_unimplemented("%s"); }\n", + fprintf( outfile, "static void %s(void) { __wine_spec_unimplemented_stub(__wine_spec16_file_name, "%s"); }\n", odp->link_name, odp->name ); } } @@ -413,6 +408,7 @@ /* File header */
output_file_header( outfile ); + fprintf( outfile, "static const char __wine_spec16_file_name[] = "%s";\n", spec->file_name ); fprintf( outfile, "extern unsigned short __wine_call_from_16_word();\n" ); fprintf( outfile, "extern unsigned int __wine_call_from_16_long();\n" ); fprintf( outfile, "extern void __wine_call_from_16_regs();\n" ); _____
Modified: trunk/reactos/tools/winebuild/spec32.c --- trunk/reactos/tools/winebuild/spec32.c 2005-09-05 10:18:07 UTC (rev 17658) +++ trunk/reactos/tools/winebuild/spec32.c 2005-09-05 17:35:31 UTC (rev 17659) @@ -66,31 +66,7 @@
return buffer; }
-/******************************************************************* - * declare_weak_function - * - * Output a prototype for a weak function. - */ -static void declare_weak_function( FILE *outfile, const char *ret_type, const char *name, const char *params) -{ - fprintf( outfile, "#ifdef __GNUC__\n" ); - if (target_platform == PLATFORM_APPLE) - { - fprintf( outfile, "extern %s %s(%s) __attribute__((weak_import));\n", ret_type, name, params ); - fprintf( outfile, "static %s (*__wine_spec_weak_%s)(%s) = %s;\n", ret_type, name, params, name ); - fprintf( outfile, "#define %s __wine_spec_weak_%s\n", name, name ); - fprintf( outfile, "asm(".weak_reference %s");\n", asm_name(name) ); - } - else fprintf( outfile, "extern %s %s(%s) __attribute__((weak));\n", ret_type, name, params );
- fprintf( outfile, "#else\n" ); - fprintf( outfile, "extern %s %s(%s);\n", ret_type, name, params ); - fprintf( outfile, "static void __asm__dummy_%s(void)", name ); - fprintf( outfile, " { asm(".weak %s"); }\n", asm_name(name) ); - fprintf( outfile, "#endif\n\n" ); -} - - /******************************************************************* * output_debug * @@ -128,7 +104,7 @@ static int get_exports_size( DLLSPEC *spec ) { int nr_exports = spec->base <= spec->limit ? spec->limit - spec->base + 1 : 0; - int i, fwd_size = 0, total_size; + int i, strings_size, total_size;
if (!nr_exports) return 0;
@@ -145,38 +121,24 @@ total_size += spec->nb_names * sizeof(short); if (spec->nb_names % 2) total_size += sizeof(short);
+ /* export name strings */ + strings_size = strlen(spec->file_name) + 1; + for (i = 0; i < spec->nb_names; i++) + strings_size += strlen(spec->names[i]->name) + 1; + /* forward strings */ for (i = spec->base; i <= spec->limit; i++) { ORDDEF *odp = spec->ordinals[i]; - if (odp && odp->flags & FLAG_FORWARD) fwd_size += strlen(odp->link_name) + 1; + if (odp && odp->flags & FLAG_FORWARD) strings_size += strlen(odp->link_name) + 1; } - total_size += (fwd_size + 3) & ~3; + total_size += (strings_size + 3) & ~3;
return total_size; }
/******************************************************************* - * output_export_names - * - * Output all the exported names for a Win32 module. - */ -static void output_export_names( FILE *outfile, DLLSPEC *spec ) -{ - int i, nr_exports = spec->base <= spec->limit ? spec->limit - spec->base + 1 : 0; - - if (!nr_exports) return; - - fprintf( outfile, "\nconst char __wine_spec_exp_names[] =" ); - fprintf( outfile, "\n "%s\0"", spec->file_name ); - for (i = 0; i < spec->nb_names; i++) - fprintf( outfile, "\n "%s\0"", spec->names[i]->name ); - fprintf( outfile, ";\n" ); -} - - -/******************************************************************* * output_exports * * Output the export table for a Win32 module. @@ -198,7 +160,7 @@ fprintf( outfile, " "\t.long 0\n"\n" ); /* Characteristics */ fprintf( outfile, " "\t.long 0\n"\n" ); /* TimeDateStamp */ fprintf( outfile, " "\t.long 0\n"\n" ); /* MajorVersion/MinorVersion */ - fprintf( outfile, " "\t.long %s\n"\n", asm_name("__wine_spec_exp_names") ); /* Name */ + fprintf( outfile, " "\t.long __wine_spec_exp_names\n"\n" ); /* Name */ fprintf( outfile, " "\t.long %d\n"\n", spec->base ); /* Base */ fprintf( outfile, " "\t.long %d\n"\n", nr_exports ); /* NumberOfFunctions */ fprintf( outfile, " "\t.long %d\n"\n", spec->nb_names ); /* NumberOfNames */ @@ -255,13 +217,10 @@ fprintf( outfile, " "__wine_spec_exp_name_ptrs:\n"\n" ); for (i = 0; i < spec->nb_names; i++) { - fprintf( outfile, " "\t.long %s+%d\n"\n", asm_name("__wine_spec_exp_names"), namepos ); + fprintf( outfile, " "\t.long __wine_spec_exp_names+%d\n"\n", namepos ); namepos += strlen(spec->names[i]->name) + 1; } - }
- if (spec->nb_names) - { /* output the function ordinals */
fprintf( outfile, " "__wine_spec_exp_ordinals:\n"\n" ); @@ -276,6 +235,14 @@ } }
+ /* output the export name strings */ + + fprintf( outfile, " "__wine_spec_exp_names:\n"\n" ); + fprintf( outfile, " "\t%s \"%s\"\n"\n", get_asm_string_keyword(), spec->file_name ); + for (i = 0; i < spec->nb_names; i++) + fprintf( outfile, " "\t%s \"%s\"\n"\n", + get_asm_string_keyword(), spec->names[i]->name ); + /* output forward strings */
if (fwd_size) @@ -287,8 +254,8 @@ if (odp && (odp->flags & FLAG_FORWARD)) fprintf( outfile, " "\t%s \"%s\"\n"\n", get_asm_string_keyword(), odp->link_name ); } - fprintf( outfile, " "\t.align %d\n"\n", get_alignment(4) ); } + fprintf( outfile, " "\t.align %d\n"\n", get_alignment(4) );
/* output relays */
@@ -356,29 +323,10 @@ ORDDEF *odp = &spec->entry_points[i]; if (odp->type != TYPE_STUB) continue; fprintf( outfile, "#ifdef __GNUC__\n" ); - fprintf( outfile, "static void __wine_unimplemented( const char *func ) __attribute__((noreturn));\n" ); - fprintf( outfile, "#endif\n\n" ); - fprintf( outfile, "struct exc_record {\n" ); - fprintf( outfile, " unsigned int code, flags;\n" ); - fprintf( outfile, " void *rec, *addr;\n" ); - fprintf( outfile, " unsigned int params;\n" ); - fprintf( outfile, " const void *info[15];\n" ); - fprintf( outfile, "};\n\n" ); [truncated at 1000 lines; 337 more skipped]