Sync to Wine-20050830:
Alexandre Julliard <julliard(a)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(a)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]