diff --git a/Make.rules.in b/Make.rules.in index 7ebc1729892..519b1ec15ee 100644 --- a/Make.rules.in +++ b/Make.rules.in @@ -289,9 +289,9 @@ $(SUBDIRS:%=%/__uninstall__): dummy # Misc. rules -$(SPEC_SRCS:.spec=.spec.c): $(BUILD) $(TOPSRCDIR)/include/builtin16.h $(TOPSRCDIR)/include/builtin32.h +$(SPEC_SRCS:.spec=.spec.c): $(BUILD) $(TOPSRCDIR)/include/builtin16.h -$(GLUE:.c=.glue.c): $(BUILD) $(TOPSRCDIR)/include/builtin16.h $(TOPSRCDIR)/include/builtin32.h +$(GLUE:.c=.glue.c): $(BUILD) $(TOPSRCDIR)/include/builtin16.h $(RC_SRCS:.rc=.s): $(WRC) diff --git a/include/builtin32.h b/include/builtin32.h deleted file mode 100644 index 7df211155d6..00000000000 --- a/include/builtin32.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Win32 built-in DLLs definitions - * - * Copyright 1997 Alexandre Julliard - */ - -#ifndef __WINE_BUILTIN32_H -#define __WINE_BUILTIN32_H - -/* Warning: this must match the definition in tools/winebuild/spec32.c */ -typedef struct -{ - const char* filename; /* DLL file name */ - int nb_imports; /* Number of imported DLLs */ - void *pe_header; /* Buffer for PE header */ - void *exports; /* Pointer to export directory */ - unsigned int exports_size; /* Total size of export directory */ - const char * const *imports; /* Pointer to imports */ - void (*dllentrypoint)(); /* Pointer to entry point function */ - int characteristics; - void *rsrc; /* Resource descriptor */ -} BUILTIN32_DESCRIPTOR; - -extern void BUILTIN32_RegisterDLL( const BUILTIN32_DESCRIPTOR *descr ); -extern void RELAY_SetupDLL( const char *module ); - -#endif /* __WINE_BUILTIN32_H */ diff --git a/miscemu/.cvsignore b/miscemu/.cvsignore index f3c7a7c5da6..25613a4affe 100644 --- a/miscemu/.cvsignore +++ b/miscemu/.cvsignore @@ -1 +1,2 @@ Makefile +wine.spec.c diff --git a/miscemu/Makefile.in b/miscemu/Makefile.in index 1030b0c3fda..cf1e072ef53 100644 --- a/miscemu/Makefile.in +++ b/miscemu/Makefile.in @@ -5,6 +5,8 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = miscemu +SPEC_SRCS = wine.spec + C_SRCS = \ main.c diff --git a/miscemu/main.c b/miscemu/main.c index b35d94db4a1..764c5d21348 100644 --- a/miscemu/main.c +++ b/miscemu/main.c @@ -8,7 +8,6 @@ #include "wingdi.h" #include "winuser.h" -#include "builtin32.h" #include "callback.h" #include "options.h" #include "process.h" @@ -17,7 +16,7 @@ /*********************************************************************** * Main loop of initial task */ -static void initial_task(void) +void wine_initial_task(void) { MSG msg; HINSTANCE16 instance; @@ -55,13 +54,6 @@ static void initial_task(void) */ int main( int argc, char *argv[] ) { - BUILTIN32_DESCRIPTOR descriptor; - - memset( &descriptor, 0, sizeof(descriptor) ); - descriptor.filename = argv[0]; - descriptor.dllentrypoint = initial_task; - BUILTIN32_RegisterDLL( &descriptor ); - PROCESS_InitWine( argc, argv ); return 1; /* not reached */ } diff --git a/miscemu/wine.spec b/miscemu/wine.spec new file mode 100644 index 00000000000..02ced9437e2 --- /dev/null +++ b/miscemu/wine.spec @@ -0,0 +1,4 @@ +name wine +mode cuiexe_no_main +type win32 +init wine_initial_task diff --git a/relay32/builtin32.c b/relay32/builtin32.c index afbb77b6092..233eafd70bb 100644 --- a/relay32/builtin32.c +++ b/relay32/builtin32.c @@ -20,7 +20,6 @@ #include "windef.h" #include "wine/winbase16.h" -#include "builtin32.h" #include "elfdll.h" #include "global.h" #include "neexe.h" @@ -43,7 +42,15 @@ typedef struct #define MAX_DLLS 100 -static const BUILTIN32_DESCRIPTOR *builtin_dlls[MAX_DLLS]; +typedef struct +{ + const IMAGE_NT_HEADERS *nt; /* NT header */ + const char *filename; /* DLL file name */ +} BUILTIN32_DESCRIPTOR; + +extern void RELAY_SetupDLL( const char *module ); + +static BUILTIN32_DESCRIPTOR builtin_dlls[MAX_DLLS]; static int nb_dlls; @@ -119,8 +126,6 @@ static HMODULE BUILTIN32_DoLoadImage( const BUILTIN32_DESCRIPTOR *descr ) IMAGE_DOS_HEADER *dos; IMAGE_NT_HEADERS *nt; IMAGE_SECTION_HEADER *sec; - IMAGE_IMPORT_DESCRIPTOR *imp; - IMAGE_EXPORT_DIRECTORY *exports = descr->exports; INT i, size, nb_sections; BYTE *addr, *code_start, *data_start; int page_size = VIRTUAL_GetPageSize(); @@ -131,17 +136,17 @@ static HMODULE BUILTIN32_DoLoadImage( const BUILTIN32_DESCRIPTOR *descr ) size = (sizeof(IMAGE_DOS_HEADER) + sizeof(IMAGE_NT_HEADERS) - + nb_sections * sizeof(IMAGE_SECTION_HEADER) - + (descr->nb_imports+1) * sizeof(IMAGE_IMPORT_DESCRIPTOR)); + + nb_sections * sizeof(IMAGE_SECTION_HEADER)); assert( size <= page_size ); - if (descr->pe_header) + if (descr->nt->OptionalHeader.ImageBase) { - if ((addr = VIRTUAL_mmap( -1, descr->pe_header, page_size, 0, - PROT_READ|PROT_WRITE, MAP_FIXED )) != descr->pe_header) + void *base = (void *)descr->nt->OptionalHeader.ImageBase; + if ((addr = VIRTUAL_mmap( -1, base, page_size, 0, + PROT_READ|PROT_WRITE, MAP_FIXED )) != base) { - ERR("failed to map over PE header for %s at %p\n", descr->filename, descr->pe_header ); + ERR("failed to map over PE header for %s at %p\n", descr->filename, base ); return 0; } } @@ -153,7 +158,6 @@ static HMODULE BUILTIN32_DoLoadImage( const BUILTIN32_DESCRIPTOR *descr ) dos = (IMAGE_DOS_HEADER *)addr; nt = (IMAGE_NT_HEADERS *)(dos + 1); sec = (IMAGE_SECTION_HEADER *)(nt + 1); - imp = (IMAGE_IMPORT_DESCRIPTOR *)(sec + nb_sections); code_start = addr + page_size; /* HACK! */ @@ -164,29 +168,16 @@ static HMODULE BUILTIN32_DoLoadImage( const BUILTIN32_DESCRIPTOR *descr ) dos->e_magic = IMAGE_DOS_SIGNATURE; dos->e_lfanew = sizeof(*dos); - nt->Signature = IMAGE_NT_SIGNATURE; - nt->FileHeader.Machine = IMAGE_FILE_MACHINE_I386; - nt->FileHeader.NumberOfSections = nb_sections; - nt->FileHeader.SizeOfOptionalHeader = sizeof(nt->OptionalHeader); - nt->FileHeader.Characteristics = descr->characteristics; + *nt = *descr->nt; - nt->OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR_MAGIC; + nt->FileHeader.NumberOfSections = nb_sections; nt->OptionalHeader.SizeOfCode = data_start - code_start; nt->OptionalHeader.SizeOfInitializedData = 0; nt->OptionalHeader.SizeOfUninitializedData = 0; nt->OptionalHeader.ImageBase = (DWORD)addr; - nt->OptionalHeader.SectionAlignment = page_size; - nt->OptionalHeader.FileAlignment = page_size; - nt->OptionalHeader.MajorOperatingSystemVersion = 1; - nt->OptionalHeader.MinorOperatingSystemVersion = 0; - nt->OptionalHeader.MajorSubsystemVersion = 4; - nt->OptionalHeader.MinorSubsystemVersion = 0; - nt->OptionalHeader.SizeOfImage = page_size; - nt->OptionalHeader.SizeOfHeaders = page_size; - nt->OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES; - if (descr->dllentrypoint) - nt->OptionalHeader.AddressOfEntryPoint = (DWORD)descr->dllentrypoint - (DWORD)addr; - + + fixup_rva_ptrs( &nt->OptionalHeader.AddressOfEntryPoint, addr, 1 ); + /* Build the code section */ strcpy( sec->Name, ".text" ); @@ -210,44 +201,34 @@ static HMODULE BUILTIN32_DoLoadImage( const BUILTIN32_DESCRIPTOR *descr ) /* Build the import directory */ - if (descr->nb_imports) + dir = &nt->OptionalHeader.DataDirectory[IMAGE_FILE_IMPORT_DIRECTORY]; + if (dir->Size) { - dir = &nt->OptionalHeader.DataDirectory[IMAGE_FILE_IMPORT_DIRECTORY]; - dir->VirtualAddress = (BYTE *)imp - addr; - dir->Size = sizeof(*imp) * (descr->nb_imports + 1); - - /* Build the imports */ - for (i = 0; i < descr->nb_imports; i++) - { - imp[i].u.Characteristics = 0; - imp[i].ForwarderChain = -1; - imp[i].Name = (BYTE *)descr->imports[i] - addr; - /* hack: make first thunk point to some zero value */ - imp[i].FirstThunk = (PIMAGE_THUNK_DATA)((BYTE *)&imp[i].u.Characteristics - addr); - } + IMAGE_IMPORT_DESCRIPTOR *imports = (void *)dir->VirtualAddress; + fixup_rva_ptrs( &dir->VirtualAddress, addr, 1 ); + /* we can fixup everything at once since we only have pointers and 0 values */ + fixup_rva_ptrs( imports, addr, dir->Size / sizeof(void*) ); } /* Build the resource directory */ - if (descr->rsrc) + dir = &nt->OptionalHeader.DataDirectory[IMAGE_FILE_RESOURCE_DIRECTORY]; + if (dir->VirtualAddress) { - BUILTIN32_RESOURCE *rsrc = descr->rsrc; - IMAGE_RESOURCE_DATA_ENTRY *rdep; - dir = &nt->OptionalHeader.DataDirectory[IMAGE_FILE_RESOURCE_DIRECTORY]; - dir->VirtualAddress = (BYTE *)rsrc->restab - addr; - dir->Size = rsrc->restabsize; - rdep = rsrc->entries; - for (i = 0; i < rsrc->nresources; i++) rdep[i].OffsetToData += dir->VirtualAddress; + BUILTIN32_RESOURCE *rsrc = (BUILTIN32_RESOURCE *)dir->VirtualAddress; + IMAGE_RESOURCE_DATA_ENTRY *rdep = rsrc->entries; + dir->VirtualAddress = (BYTE *)rsrc->restab - addr; + dir->Size = rsrc->restabsize; + for (i = 0; i < rsrc->nresources; i++) rdep[i].OffsetToData += dir->VirtualAddress; } /* Build the export directory */ - if (exports) + dir = &nt->OptionalHeader.DataDirectory[IMAGE_FILE_EXPORT_DIRECTORY]; + if (dir->Size) { - dir = &nt->OptionalHeader.DataDirectory[IMAGE_FILE_EXPORT_DIRECTORY]; - dir->VirtualAddress = (BYTE *)exports - addr; - dir->Size = descr->exports_size; - + IMAGE_EXPORT_DIRECTORY *exports = (void *)dir->VirtualAddress; + fixup_rva_ptrs( &dir->VirtualAddress, addr, 1 ); fixup_rva_ptrs( (void *)exports->AddressOfFunctions, addr, exports->NumberOfFunctions ); fixup_rva_ptrs( (void *)exports->AddressOfNames, addr, exports->NumberOfNames ); fixup_rva_ptrs( &exports->Name, addr, 1 ); @@ -290,12 +271,12 @@ WINE_MODREF *BUILTIN32_LoadLibraryExA(LPCSTR path, DWORD flags) /* Search built-in descriptor */ for (i = 0; i < nb_dlls; i++) - if (!strcasecmp( builtin_dlls[i]->filename, dllname )) goto found; + if (!strcasecmp( builtin_dlls[i].filename, dllname )) goto found; if ((handle = BUILTIN32_dlopen( dllname ))) { for (i = 0; i < nb_dlls; i++) - if (!strcasecmp( builtin_dlls[i]->filename, dllname )) goto found; + if (!strcasecmp( builtin_dlls[i].filename, dllname )) goto found; ERR( "loaded .so but dll %s still not found\n", dllname ); BUILTIN32_dlclose( handle ); } @@ -306,7 +287,7 @@ WINE_MODREF *BUILTIN32_LoadLibraryExA(LPCSTR path, DWORD flags) found: /* Load built-in module */ - if (!(module = BUILTIN32_DoLoadImage( builtin_dlls[i] ))) return NULL; + if (!(module = BUILTIN32_DoLoadImage( &builtin_dlls[i] ))) return NULL; /* Create 32-bit MODREF */ if ( !(wm = PE_CreateModule( module, path, flags, -1, TRUE )) ) @@ -329,7 +310,7 @@ HMODULE BUILTIN32_LoadExeModule(void) /* Search built-in EXE descriptor */ for ( i = 0; i < nb_dlls; i++ ) - if ( !(builtin_dlls[i]->characteristics & IMAGE_FILE_DLL) ) + if ( !(builtin_dlls[i].nt->FileHeader.Characteristics & IMAGE_FILE_DLL) ) { if ( exe != -1 ) { @@ -347,7 +328,7 @@ HMODULE BUILTIN32_LoadExeModule(void) } /* Load built-in module */ - return BUILTIN32_DoLoadImage( builtin_dlls[exe] ); + return BUILTIN32_DoLoadImage( &builtin_dlls[exe] ); } @@ -356,10 +337,12 @@ HMODULE BUILTIN32_LoadExeModule(void) * * Register a built-in DLL descriptor. */ -void BUILTIN32_RegisterDLL( const BUILTIN32_DESCRIPTOR *descr ) +void BUILTIN32_RegisterDLL( const IMAGE_NT_HEADERS *header, const char *filename ) { assert( nb_dlls < MAX_DLLS ); - builtin_dlls[nb_dlls++] = descr; + builtin_dlls[nb_dlls].nt = header; + builtin_dlls[nb_dlls].filename = filename; + nb_dlls++; } /*********************************************************************** diff --git a/tools/winebuild/Makefile.in b/tools/winebuild/Makefile.in index 031dd8fe063..d73e5e59582 100644 --- a/tools/winebuild/Makefile.in +++ b/tools/winebuild/Makefile.in @@ -8,6 +8,7 @@ PROGRAMS = winebuild MODULE = none C_SRCS = \ + import.c \ main.c \ parser.c \ relay.c \ diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h index ac62ec40671..622fb245ab3 100644 --- a/tools/winebuild/build.h +++ b/tools/winebuild/build.h @@ -61,7 +61,9 @@ typedef enum { SPEC_MODE_DLL, SPEC_MODE_GUIEXE, - SPEC_MODE_CUIEXE + SPEC_MODE_CUIEXE, + SPEC_MODE_GUIEXE_NO_MAIN, + SPEC_MODE_CUIEXE_NO_MAIN } SPEC_MODE; typedef struct @@ -126,7 +128,6 @@ typedef struct #define MAX_ORDINALS 2048 -#define MAX_IMPORTS 16 /* global functions */ @@ -135,7 +136,11 @@ extern void *xrealloc (void *ptr, size_t size); extern char *xstrdup( const char *str ); extern char *strupper(char *s); extern void fatal_error( const char *msg, ... ); +extern void warning( const char *msg, ... ); extern void dump_bytes( FILE *outfile, const unsigned char *data, int len, const char *label ); +extern void add_import_dll( const char *name ); +extern void resolve_imports( FILE *outfile ); +extern int output_imports( FILE *outfile ); extern void BuildGlue( FILE *outfile, FILE *infile ); extern void BuildRelays( FILE *outfile ); @@ -148,7 +153,6 @@ extern SPEC_TYPE ParseTopLevel( FILE *file ); extern int current_line; extern int nb_entry_points; extern int nb_names; -extern int nb_imports; extern int Base; extern int Limit; extern int DLLHeapSize; @@ -163,7 +167,6 @@ extern char DLLFileName[80]; extern char DLLInitFunc[80]; extern char rsrc_name[80]; extern char owner_name[80]; -extern char *DLLImports[MAX_IMPORTS]; extern const char *input_file_name; extern const char *output_file_name; diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c new file mode 100644 index 00000000000..e27fe47dd9e --- /dev/null +++ b/tools/winebuild/import.c @@ -0,0 +1,114 @@ +/* + * DLL imports support + * + * Copyright 2000 Alexandre Julliard + */ + +#include +#include +#include + +#include "winnt.h" +#include "build.h" + +struct import +{ + char *dll; /* dll name */ + char **imports; /* functions we want to import from this dll */ + int nb_imports; /* number of imported functions */ +}; + + +static struct import **dll_imports = NULL; +static int nb_imports = 0; /* number of imported dlls */ +static int total_imports = 0; /* total number of imported functions */ + + +/* add a dll to the list of imports */ +void add_import_dll( const char *name ) +{ + struct import *imp = xmalloc( sizeof(*imp) ); + imp->dll = xstrdup( name ); + imp->imports = NULL; + imp->nb_imports = 0; + + dll_imports = xrealloc( dll_imports, (nb_imports+1) * sizeof(*dll_imports) ); + dll_imports[nb_imports++] = imp; +} + +#ifdef notyet +/* add a function to the list of imports from a given dll */ +static void add_import_func( struct import *imp, const char *name ) +{ + imp->imports = xrealloc( imp->imports, (imp->nb_imports+1) * sizeof(*imp->imports) ); + imp->imports[imp->nb_imports++] = xstrdup( name ); + total_imports++; +} +#endif + +/* output the import table of a Win32 module */ +int output_imports( FILE *outfile ) +{ + int i, j, pos; + + if (!nb_imports) goto done; + + /* main import header */ + + fprintf( outfile, "\n\n/* imports */\n\n" ); + fprintf( outfile, "static struct {\n" ); + fprintf( outfile, " struct {\n" ); + fprintf( outfile, " void *OriginalFirstThunk;\n" ); + fprintf( outfile, " unsigned int TimeDateStamp;\n" ); + fprintf( outfile, " unsigned int ForwarderChain;\n" ); + fprintf( outfile, " const char *Name;\n" ); + fprintf( outfile, " void *FirstThunk;\n" ); + fprintf( outfile, " } imp[%d];\n", nb_imports+1 ); + fprintf( outfile, " const char *data[%d];\n", total_imports + nb_imports ); + fprintf( outfile, "} imports = {\n {\n" ); + + /* list of dlls */ + + for (i = j = 0; i < nb_imports; i++) + { + fprintf( outfile, " { 0, 0, 0, \"%s\", &imports.data[%d] },\n", + dll_imports[i]->dll, j ); + j += dll_imports[i]->nb_imports + 1; + } + fprintf( outfile, " { 0, 0, 0, 0, 0 },\n" ); + fprintf( outfile, " },\n {\n" ); + + /* list of imported functions */ + + for (i = 0; i < nb_imports; i++) + { + fprintf( outfile, " /* %s */\n", dll_imports[i]->dll ); + for (j = 0; j < dll_imports[i]->nb_imports; j++) + fprintf( outfile, " \"\\0\\0%s\",\n", dll_imports[i]->imports[j] ); + fprintf( outfile, " 0,\n" ); + } + fprintf( outfile, " }\n};\n\n" ); + + /* thunks for imported functions */ + + fprintf( outfile, "#ifndef __GNUC__\nstatic void __asm__dummy_import(void) {\n#endif\n\n" ); + pos = 20 * (nb_imports + 1); /* offset of imports.data from start of imports */ + fprintf( outfile, "asm(\".align 4\");\n" ); + for (i = 0; i < nb_imports; i++, pos += 4) + { + for (j = 0; j < dll_imports[i]->nb_imports; j++, pos += 4) + { + fprintf( outfile, + "asm(\".type " PREFIX "%s,@function\\n\\t" + ".globl " PREFIX "%s\\n" + PREFIX "%s:\\tjmp *(imports+%d)\\n\\t" + "movl %%esi,%%esi\");\n", + dll_imports[i]->imports[j], dll_imports[i]->imports[j], + dll_imports[i]->imports[j], pos ); + } + } + fprintf( outfile, "#ifndef __GNUC__\n}\n#endif\n\n" ); + + done: + return nb_imports; +} diff --git a/tools/winebuild/main.c b/tools/winebuild/main.c index 1cb5776287f..8564036204d 100644 --- a/tools/winebuild/main.c +++ b/tools/winebuild/main.c @@ -38,13 +38,11 @@ int DLLHeapSize = 0; int UsePIC = 0; int nb_entry_points = 0; int nb_names = 0; -int nb_imports = 0; int debugging = 1; char DLLName[80]; char DLLFileName[80]; char DLLInitFunc[80]; -char *DLLImports[MAX_IMPORTS]; char rsrc_name[80]; char owner_name[80]; diff --git a/tools/winebuild/parser.c b/tools/winebuild/parser.c index 12a5c9336ee..93332f9d182 100644 --- a/tools/winebuild/parser.c +++ b/tools/winebuild/parser.c @@ -310,6 +310,20 @@ static void ParseForward( ORDDEF *odp ) } +/******************************************************************* + * fix_export_name + * + * Fix an exported function name by removing a possible @xx suffix + */ +static void fix_export_name( char *name ) +{ + char *p, *end = strrchr( name, '@' ); + if (!end || !end[1] || end == name) return; + /* make sure all the rest is digits */ + for (p = end + 1; *p; p++) if (!isdigit(*p)) return; + *end = 0; +} + /******************************************************************* * ParseOrdinal * @@ -333,6 +347,7 @@ static void ParseOrdinal(int ordinal) if (!(token = GetToken())) fatal_error( "Expected name after type\n" ); strcpy( odp->name, token ); + fix_export_name( odp->name ); odp->lineno = current_line; odp->ordinal = ordinal; @@ -436,7 +451,9 @@ SPEC_TYPE ParseTopLevel( FILE *file ) if (!strcmp(token, "dll" )) SpecMode = SPEC_MODE_DLL; else if (!strcmp(token, "guiexe" )) SpecMode = SPEC_MODE_GUIEXE; else if (!strcmp(token, "cuiexe" )) SpecMode = SPEC_MODE_CUIEXE; - else fatal_error( "Mode must be 'dll', 'guiexe' or 'cuiexe'\n" ); + else if (!strcmp(token, "guiexe_no_main" )) SpecMode = SPEC_MODE_GUIEXE_NO_MAIN; + else if (!strcmp(token, "cuiexe_no_main" )) SpecMode = SPEC_MODE_CUIEXE_NO_MAIN; + else fatal_error( "Mode must be 'dll', 'guiexe', 'cuiexe', 'guiexe_no_main' or 'cuiexe_no_main'\n" ); } else if (strcmp(token, "heap") == 0) { @@ -456,11 +473,9 @@ SPEC_TYPE ParseTopLevel( FILE *file ) } else if (strcmp(token, "import") == 0) { - if (nb_imports >= MAX_IMPORTS) - fatal_error( "Too many imports (limit %d)\n", MAX_IMPORTS ); if (SpecType != SPEC_WIN32) fatal_error( "Imports not supported for Win16\n" ); - DLLImports[nb_imports++] = xstrdup(GetToken()); + add_import_dll( GetToken() ); } else if (strcmp(token, "rsrc") == 0) { diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c index e01d1749274..413c1411739 100644 --- a/tools/winebuild/spec32.c +++ b/tools/winebuild/spec32.c @@ -269,7 +269,8 @@ void BuildSpec32File( FILE *outfile ) { ORDDEF *odp; int i, fwd_size = 0, have_regs = FALSE; - int nr_exports; + int nr_exports, nr_imports; + int characteristics, subsystem; const char *init_func; DWORD page_size; @@ -370,24 +371,17 @@ void BuildSpec32File( FILE *outfile ) /* Output the DLL imports */ - if (nb_imports) - { - fprintf( outfile, "static const char * const Imports[%d] =\n{\n", nb_imports ); - for (i = 0; i < nb_imports; i++) - { - fprintf( outfile, " \"%s\"", DLLImports[i] ); - if (i < nb_imports-1) fprintf( outfile, ",\n" ); - } - fprintf( outfile, "\n};\n\n" ); - } + nr_imports = output_imports( outfile ); /* Output LibMain function */ init_func = DLLInitFunc[0] ? DLLInitFunc : NULL; + characteristics = subsystem = 0; switch(SpecMode) { case SPEC_MODE_DLL: if (init_func) fprintf( outfile, "extern void %s();\n", init_func ); + characteristics = IMAGE_FILE_DLL; break; case SPEC_MODE_GUIEXE: if (!init_func) init_func = "WinMain"; @@ -412,6 +406,7 @@ void BuildSpec32File( FILE *outfile ) " return 1;\n" "}\n\n" ); init_func = "exe_main"; + subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI; break; case SPEC_MODE_CUIEXE: if (!init_func) init_func = "wine_main"; @@ -432,6 +427,15 @@ void BuildSpec32File( FILE *outfile ) " return 1;\n" "}\n\n" ); init_func = "exe_main"; + subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI; + break; + case SPEC_MODE_GUIEXE_NO_MAIN: + if (init_func) fprintf( outfile, "extern void %s();\n", init_func ); + subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI; + break; + case SPEC_MODE_CUIEXE_NO_MAIN: + if (init_func) fprintf( outfile, "extern void %s();\n", init_func ); + subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI; break; } @@ -439,28 +443,87 @@ void BuildSpec32File( FILE *outfile ) if (rsrc_name[0]) fprintf( outfile, "extern char %s[];\n\n", rsrc_name ); - /* Warning: this must match the definition in builtin32.h */ - fprintf( outfile, "static const struct dll_descriptor\n{\n" ); - fprintf( outfile, " const char* filename;\n" ); - fprintf( outfile, " int nb_imports;\n" ); - fprintf( outfile, " void *pe_header;\n" ); - fprintf( outfile, " void *exports;\n" ); - fprintf( outfile, " unsigned int exports_size;\n" ); - fprintf( outfile, " const char * const *imports;\n" ); - fprintf( outfile, " void (*dllentrypoint)();\n" ); - fprintf( outfile, " int characteristics;\n" ); - fprintf( outfile, " void *rsrc;\n" ); - fprintf( outfile, "} descriptor = {\n" ); - fprintf( outfile, " \"%s\",\n", DLLFileName ); - fprintf( outfile, " %d,\n", nb_imports ); - fprintf( outfile, " pe_header,\n" ); - fprintf( outfile, " %s,\n", nr_exports ? "&exports" : "0" ); - fprintf( outfile, " %s,\n", nr_exports ? "sizeof(exports.exp)" : "0" ); - fprintf( outfile, " %s,\n", nb_imports ? "Imports" : "0" ); - fprintf( outfile, " %s,\n", init_func ? init_func : "0" ); - fprintf( outfile, " %d,\n", SpecMode == SPEC_MODE_DLL ? IMAGE_FILE_DLL : 0 ); - fprintf( outfile, " %s\n", rsrc_name[0] ? rsrc_name : "0" ); - fprintf( outfile, "};\n" ); + /* Output the NT header */ + + /* this is the IMAGE_NT_HEADERS structure, but we cannot include winnt.h here */ + fprintf( outfile, "static const struct image_nt_headers\n{\n" ); + fprintf( outfile, " int Signature;\n" ); + fprintf( outfile, " struct file_header {\n" ); + fprintf( outfile, " short Machine;\n" ); + fprintf( outfile, " short NumberOfSections;\n" ); + fprintf( outfile, " int TimeDateStamp;\n" ); + fprintf( outfile, " void *PointerToSymbolTable;\n" ); + fprintf( outfile, " int NumberOfSymbols;\n" ); + fprintf( outfile, " short SizeOfOptionalHeader;\n" ); + fprintf( outfile, " short Characteristics;\n" ); + fprintf( outfile, " } FileHeader;\n" ); + fprintf( outfile, " struct opt_header {\n" ); + fprintf( outfile, " short Magic;\n" ); + fprintf( outfile, " char MajorLinkerVersion, MinorLinkerVersion;\n" ); + fprintf( outfile, " int SizeOfCode;\n" ); + fprintf( outfile, " int SizeOfInitializedData;\n" ); + fprintf( outfile, " int SizeOfUninitializedData;\n" ); + fprintf( outfile, " void *AddressOfEntryPoint;\n" ); + fprintf( outfile, " void *BaseOfCode;\n" ); + fprintf( outfile, " void *BaseOfData;\n" ); + fprintf( outfile, " void *ImageBase;\n" ); + fprintf( outfile, " int SectionAlignment;\n" ); + fprintf( outfile, " int FileAlignment;\n" ); + fprintf( outfile, " short MajorOperatingSystemVersion;\n" ); + fprintf( outfile, " short MinorOperatingSystemVersion;\n" ); + fprintf( outfile, " short MajorImageVersion;\n" ); + fprintf( outfile, " short MinorImageVersion;\n" ); + fprintf( outfile, " short MajorSubsystemVersion;\n" ); + fprintf( outfile, " short MinorSubsystemVersion;\n" ); + fprintf( outfile, " int Win32VersionValue;\n" ); + fprintf( outfile, " int SizeOfImage;\n" ); + fprintf( outfile, " int SizeOfHeaders;\n" ); + fprintf( outfile, " int CheckSum;\n" ); + fprintf( outfile, " short Subsystem;\n" ); + fprintf( outfile, " short DllCharacteristics;\n" ); + fprintf( outfile, " int SizeOfStackReserve;\n" ); + fprintf( outfile, " int SizeOfStackCommit;\n" ); + fprintf( outfile, " int SizeOfHeapReserve;\n" ); + fprintf( outfile, " int SizeOfHeapCommit;\n" ); + fprintf( outfile, " int LoaderFlags;\n" ); + fprintf( outfile, " int NumberOfRvaAndSizes;\n" ); + fprintf( outfile, " struct { void *VirtualAddress; int Size; } DataDirectory[%d];\n", + IMAGE_NUMBEROF_DIRECTORY_ENTRIES ); + fprintf( outfile, " } OptionalHeader;\n" ); + fprintf( outfile, "} nt_header = {\n" ); + fprintf( outfile, " 0x%04x,\n", IMAGE_NT_SIGNATURE ); /* Signature */ + + fprintf( outfile, " { 0x%04x,\n", IMAGE_FILE_MACHINE_I386 ); /* Machine */ + fprintf( outfile, " 0, 0, 0, 0,\n" ); + fprintf( outfile, " sizeof(nt_header.OptionalHeader),\n" ); /* SizeOfOptionalHeader */ + fprintf( outfile, " 0x%04x },\n", characteristics ); /* Characteristics */ + + fprintf( outfile, " { 0x%04x,\n", IMAGE_NT_OPTIONAL_HDR_MAGIC ); /* Magic */ + fprintf( outfile, " 0, 0,\n" ); /* Major/MinorLinkerVersion */ + fprintf( outfile, " 0, 0, 0,\n" ); /* SizeOfCode/Data */ + fprintf( outfile, " %s,\n", init_func ? init_func : "0" ); /* AddressOfEntryPoint */ + fprintf( outfile, " 0, 0,\n" ); /* BaseOfCode/Data */ + fprintf( outfile, " pe_header,\n" ); /* ImageBase */ + fprintf( outfile, " %ld,\n", page_size ); /* SectionAlignment */ + fprintf( outfile, " %ld,\n", page_size ); /* FileAlignment */ + fprintf( outfile, " 1, 0,\n" ); /* Major/MinorOperatingSystemVersion */ + fprintf( outfile, " 0, 0,\n" ); /* Major/MinorImageVersion */ + fprintf( outfile, " 4, 0,\n" ); /* Major/MinorSubsystemVersion */ + fprintf( outfile, " 0,\n" ); /* Win32VersionValue */ + fprintf( outfile, " %ld,\n", page_size ); /* SizeOfImage */ + fprintf( outfile, " %ld,\n", page_size ); /* SizeOfHeaders */ + fprintf( outfile, " 0,\n" ); /* CheckSum */ + fprintf( outfile, " 0x%04x,\n", subsystem ); /* Subsystem */ + fprintf( outfile, " 0, 0, 0, 0, 0, 0,\n" ); + fprintf( outfile, " %d,\n", IMAGE_NUMBEROF_DIRECTORY_ENTRIES ); /* NumberOfRvaAndSizes */ + fprintf( outfile, " {\n" ); + fprintf( outfile, " { %s, %s },\n", /* IMAGE_DIRECTORY_ENTRY_EXPORT */ + nr_exports ? "&exports" : "0", nr_exports ? "sizeof(exports.exp)" : "0" ); + fprintf( outfile, " { %s, %s },\n", /* IMAGE_DIRECTORY_ENTRY_IMPORT */ + nr_imports ? "&imports" : "0", nr_imports ? "sizeof(imports)" : "0" ); + fprintf( outfile, " { %s, 0 },\n", /* IMAGE_DIRECTORY_ENTRY_RESOURCE */ + rsrc_name[0] ? rsrc_name : "0" ); + fprintf( outfile, " }\n }\n};\n\n" ); /* Output the DLL constructor */ @@ -474,6 +537,6 @@ void BuildSpec32File( FILE *outfile ) fprintf( outfile, "}\n" ); fprintf( outfile, "#endif /* defined(__GNUC__) */\n" ); fprintf( outfile, "static void %s_init(void)\n{\n", DLLName ); - fprintf( outfile, " extern void BUILTIN32_RegisterDLL( const struct dll_descriptor * );\n" ); - fprintf( outfile, " BUILTIN32_RegisterDLL( &descriptor );\n}\n" ); + fprintf( outfile, " extern void BUILTIN32_RegisterDLL( const struct image_nt_headers *, const char * );\n" ); + fprintf( outfile, " BUILTIN32_RegisterDLL( &nt_header, \"%s\" );\n}\n", DLLFileName ); } diff --git a/tools/winebuild/utils.c b/tools/winebuild/utils.c index 19b50bae139..f859408bc57 100644 --- a/tools/winebuild/utils.c +++ b/tools/winebuild/utils.c @@ -55,13 +55,34 @@ void fatal_error( const char *msg, ... ) { va_list valist; va_start( valist, msg ); - if (input_file_name && current_line) - fprintf( stderr, "%s:%d: ", input_file_name, current_line ); + if (input_file_name) + { + fprintf( stderr, "%s:", input_file_name ); + if (current_line) + fprintf( stderr, "%d:", current_line ); + fputc( ' ', stderr ); + } vfprintf( stderr, msg, valist ); va_end( valist ); exit(1); } +void warning( const char *msg, ... ) +{ + va_list valist; + va_start( valist, msg ); + if (input_file_name) + { + fprintf( stderr, "%s:", input_file_name ); + if (current_line) + fprintf( stderr, "%d:", current_line ); + fputc( ' ', stderr ); + } + fprintf( stderr, "warning: " ); + vfprintf( stderr, msg, valist ); + va_end( valist ); +} + /* dump a byte stream into the assembly code */ void dump_bytes( FILE *outfile, const unsigned char *data, int len, const char *label ) {