From 43bd5512c3a1c5dac3801d36dfe3f467980b9e4f Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 8 Sep 2005 11:35:19 +0000 Subject: [PATCH] Added support for 64-bit format NT header and export/import tables. --- tools/winebuild/build.h | 2 +- tools/winebuild/import.c | 85 +++++++++++++++++++--------------------- tools/winebuild/parser.c | 2 +- tools/winebuild/spec32.c | 74 ++++++++-------------------------- 4 files changed, 59 insertions(+), 104 deletions(-) diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h index ed5bb2a4451..87c69f8b666 100644 --- a/tools/winebuild/build.h +++ b/tools/winebuild/build.h @@ -194,7 +194,7 @@ extern void add_ignore_symbol( const char *name ); 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 get_imports_size(void); +extern int has_imports(void); extern void output_imports( FILE *outfile, DLLSPEC *spec ); extern int load_res32_file( const char *name, DLLSPEC *spec ); extern int output_resources( FILE *outfile, DLLSPEC *spec ); diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c index d3cb54a6582..d2406e3244c 100644 --- a/tools/winebuild/import.c +++ b/tools/winebuild/import.c @@ -743,23 +743,10 @@ static void output_import_thunk( FILE *outfile, const char *name, const char *ta output_function_size( outfile, name ); } -/* compute the size of the import table */ -int get_imports_size(void) +/* check if we need an import directory */ +int has_imports(void) { - int i, total_size, nb_imm = nb_imports - nb_delayed; - - if (!nb_imm) return 0; - - /* list of dlls */ - total_size = 5 * 4 * (nb_imm + 1); - - for (i = 0; i < nb_imports; i++) - { - if (dll_imports[i]->delay) continue; - total_size += (dll_imports[i]->nb_imports + 1) * 4; - } - /* Note: the strings are not counted as being part of the import directory */ - return total_size; + return (nb_imports - nb_delayed) > 0; } /* output the import table of a Win32 module */ @@ -786,7 +773,8 @@ static void output_immediate_imports( FILE *outfile ) fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* TimeDateStamp */ fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* ForwarderChain */ fprintf( outfile, " \"\\t.long .L__wine_spec_import_name_%s\\n\"\n", dll_name ); /* Name */ - fprintf( outfile, " \"\\t.long .L__wine_spec_import_data_ptrs+%d\\n\"\n", j * 4 ); /* FirstThunk */ + fprintf( outfile, " \"\\t.long .L__wine_spec_import_data_ptrs+%d\\n\"\n", /* FirstThunk */ + j * get_ptr_size() ); j += dll_imports[i]->nb_imports + 1; } fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* OriginalFirstThunk */ @@ -795,6 +783,7 @@ static void output_immediate_imports( FILE *outfile ) fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* Name */ fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* FirstThunk */ + fprintf( outfile, " \"\\t.align %d\\n\"\n", get_alignment(get_ptr_size()) ); fprintf( outfile, " \".L__wine_spec_import_data_ptrs:\\n\"\n" ); for (i = 0; i < nb_imports; i++) { @@ -804,12 +793,12 @@ static void output_immediate_imports( FILE *outfile ) { ORDDEF *odp = dll_imports[i]->imports[j]; if (!(odp->flags & FLAG_NONAME)) - fprintf( outfile, " \"\\t.long .L__wine_spec_import_data_%s_%s\\n\"\n", - dll_name, odp->name ); + fprintf( outfile, " \"\\t%s .L__wine_spec_import_data_%s_%s\\n\"\n", + get_asm_ptr_keyword(), dll_name, odp->name ); else - fprintf( outfile, " \"\\t.long %d\\n\"\n", odp->ordinal ); + fprintf( outfile, " \"\\t%s %d\\n\"\n", get_asm_ptr_keyword(), odp->ordinal ); } - fprintf( outfile, " \"\\t.long 0\\n\"\n" ); + fprintf( outfile, " \"\\t%s 0\\n\"\n", get_asm_ptr_keyword() ); } fprintf( outfile, " \".L__wine_spec_imports_end:\\n\"\n" ); @@ -857,13 +846,13 @@ static void output_immediate_import_thunks( FILE *outfile ) for (i = pos = 0; i < nb_imports; i++) { if (dll_imports[i]->delay) continue; - for (j = 0; j < dll_imports[i]->nb_imports; j++, pos += sizeof(const char *)) + for (j = 0; j < dll_imports[i]->nb_imports; j++, pos += get_ptr_size()) { ORDDEF *odp = dll_imports[i]->imports[j]; output_import_thunk( outfile, odp->name ? odp->name : odp->export_name, ".L__wine_spec_import_data_ptrs", pos ); } - pos += 4; + pos += get_ptr_size(); } output_function_size( outfile, import_thunks ); fprintf( outfile, ");\n" ); @@ -877,7 +866,7 @@ static void output_delayed_imports( FILE *outfile, const DLLSPEC *spec ) if (!nb_delayed) return; fprintf( outfile, "/* delayed imports */\n" ); - fprintf( outfile, "asm(\".data\\n\\t.align %d\\n\"\n", get_alignment(4) ); + fprintf( outfile, "asm(\".data\\n\\t.align %d\\n\"\n", get_alignment(get_ptr_size()) ); fprintf( outfile, " \"\\t.globl %s\\n\"\n", asm_name("__wine_spec_delay_imports") ); fprintf( outfile, " \"%s:\\n\"\n", asm_name("__wine_spec_delay_imports")); @@ -886,24 +875,28 @@ static void output_delayed_imports( FILE *outfile, const DLLSPEC *spec ) for (i = j = 0; i < nb_imports; i++) { if (!dll_imports[i]->delay) continue; - fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* grAttrs */ - fprintf( outfile, " \"\\t.long .L__wine_delay_name_%d\\n\"\n", i ); /* szName */ - fprintf( outfile, " \"\\t.long .L__wine_delay_modules+%d\\n\"\n", i * 4 ); /* phmod */ - fprintf( outfile, " \"\\t.long .L__wine_delay_IAT+%d\\n\"\n", j * 4 ); /* pIAT */ - fprintf( outfile, " \"\\t.long .L__wine_delay_INT+%d\\n\"\n", j * 4 ); /* pINT */ - fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* pBoundIAT */ - fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* pUnloadIAT */ - fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* dwTimeStamp */ + fprintf( outfile, " \"\\t%s 0\\n\"\n", get_asm_ptr_keyword() ); /* grAttrs */ + fprintf( outfile, " \"\\t%s .L__wine_delay_name_%d\\n\"\n", /* szName */ + get_asm_ptr_keyword(), i ); + fprintf( outfile, " \"\\t%s .L__wine_delay_modules+%d\\n\"\n", /* phmod */ + get_asm_ptr_keyword(), i * get_ptr_size() ); + fprintf( outfile, " \"\\t%s .L__wine_delay_IAT+%d\\n\"\n", /* pIAT */ + get_asm_ptr_keyword(), j * get_ptr_size() ); + fprintf( outfile, " \"\\t%s .L__wine_delay_INT+%d\\n\"\n", /* pINT */ + get_asm_ptr_keyword(), j * get_ptr_size() ); + fprintf( outfile, " \"\\t%s 0\\n\"\n", get_asm_ptr_keyword() ); /* pBoundIAT */ + fprintf( outfile, " \"\\t%s 0\\n\"\n", get_asm_ptr_keyword() ); /* pUnloadIAT */ + fprintf( outfile, " \"\\t%s 0\\n\"\n", get_asm_ptr_keyword() ); /* dwTimeStamp */ j += dll_imports[i]->nb_imports; } - fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* grAttrs */ - fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* szName */ - fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* phmod */ - fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* pIAT */ - fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* pINT */ - fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* pBoundIAT */ - fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* pUnloadIAT */ - fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* dwTimeStamp */ + fprintf( outfile, " \"\\t%s 0\\n\"\n", get_asm_ptr_keyword() ); /* grAttrs */ + fprintf( outfile, " \"\\t%s 0\\n\"\n", get_asm_ptr_keyword() ); /* szName */ + fprintf( outfile, " \"\\t%s 0\\n\"\n", get_asm_ptr_keyword() ); /* phmod */ + fprintf( outfile, " \"\\t%s 0\\n\"\n", get_asm_ptr_keyword() ); /* pIAT */ + fprintf( outfile, " \"\\t%s 0\\n\"\n", get_asm_ptr_keyword() ); /* pINT */ + fprintf( outfile, " \"\\t%s 0\\n\"\n", get_asm_ptr_keyword() ); /* pBoundIAT */ + fprintf( outfile, " \"\\t%s 0\\n\"\n", get_asm_ptr_keyword() ); /* pUnloadIAT */ + fprintf( outfile, " \"\\t%s 0\\n\"\n", get_asm_ptr_keyword() ); /* dwTimeStamp */ fprintf( outfile, " \".L__wine_delay_IAT:\\n\"\n" ); for (i = 0; i < nb_imports; i++) @@ -913,7 +906,8 @@ static void output_delayed_imports( FILE *outfile, const DLLSPEC *spec ) { ORDDEF *odp = dll_imports[i]->imports[j]; const char *name = odp->name ? odp->name : odp->export_name; - fprintf( outfile, " \"\\t.long .L__wine_delay_imp_%d_%s\\n\"\n", i, name ); + fprintf( outfile, " \"\\t%s .L__wine_delay_imp_%d_%s\\n\"\n", + get_asm_ptr_keyword(), i, name ); } } @@ -925,16 +919,17 @@ static void output_delayed_imports( FILE *outfile, const DLLSPEC *spec ) { ORDDEF *odp = dll_imports[i]->imports[j]; if (!odp->name) - fprintf( outfile, " \"\\t.long %d\\n\"\n", odp->ordinal ); + fprintf( outfile, " \"\\t%s %d\\n\"\n", get_asm_ptr_keyword(), odp->ordinal ); else - fprintf( outfile, " \"\\t.long .L__wine_delay_data_%d_%s\\n\"\n", i, odp->name ); + fprintf( outfile, " \"\\t%s .L__wine_delay_data_%d_%s\\n\"\n", + get_asm_ptr_keyword(), i, odp->name ); } } fprintf( outfile, " \".L__wine_delay_modules:\\n\"\n" ); for (i = 0; i < nb_imports; i++) { - if (dll_imports[i]->delay) fprintf( outfile, " \"\\t.long 0\\n\"\n" ); + if (dll_imports[i]->delay) fprintf( outfile, " \"\\t%s 0\\n\"\n", get_asm_ptr_keyword() ); } for (i = 0; i < nb_imports; i++) @@ -1108,7 +1103,7 @@ static void output_delayed_import_thunks( FILE *outfile, const DLLSPEC *spec ) for (i = pos = 0; i < nb_imports; i++) { if (!dll_imports[i]->delay) continue; - for (j = 0; j < dll_imports[i]->nb_imports; j++, pos += 4) + for (j = 0; j < dll_imports[i]->nb_imports; j++, pos += get_ptr_size()) { ORDDEF *odp = dll_imports[i]->imports[j]; output_import_thunk( outfile, odp->name ? odp->name : odp->export_name, diff --git a/tools/winebuild/parser.c b/tools/winebuild/parser.c index aa548da752d..5c3e74930d9 100644 --- a/tools/winebuild/parser.c +++ b/tools/winebuild/parser.c @@ -791,7 +791,7 @@ static int parse_def_export( char *name, DLLSPEC *spec ) else { odp->type = TYPE_STDCALL; - args /= sizeof(int); + args /= get_ptr_size(); if (args >= sizeof(odp->u.func.arg_types)) { error( "Too many arguments in stdcall function '%s'\n", odp->name ); diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c index a5cc915434b..8b181e37298 100644 --- a/tools/winebuild/spec32.c +++ b/tools/winebuild/spec32.c @@ -95,48 +95,6 @@ static int output_debug( FILE *outfile ) } -/******************************************************************* - * get_exports_size - * - * Compute the size of the export table. - */ -static int get_exports_size( DLLSPEC *spec ) -{ - int nr_exports = spec->base <= spec->limit ? spec->limit - spec->base + 1 : 0; - int i, strings_size, total_size; - - if (!nr_exports) return 0; - - /* export directory header */ - total_size = 10 * sizeof(int); - - /* function pointers */ - total_size += nr_exports * sizeof(int); - - /* function name pointers */ - total_size += spec->nb_names * sizeof(int); - - /* function ordinals */ - 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) strings_size += strlen(odp->link_name) + 1; - } - total_size += (strings_size + 3) & ~3; - - return total_size; -} - - /******************************************************************* * output_exports * @@ -281,7 +239,7 @@ static void output_exports( FILE *outfile, DLLSPEC *spec ) } if ((odp->flags & FLAG_RET64) && (j < 16)) mask |= 0x80000000; - args = strlen(odp->u.func.arg_types) * sizeof(int); + args = strlen(odp->u.func.arg_types) * get_ptr_size(); switch(odp->type) { @@ -444,12 +402,10 @@ void output_dll_init( FILE *outfile, const char *constructor, const char *destru */ void BuildSpec32File( FILE *outfile, DLLSPEC *spec ) { - int exports_size, imports_size, resources_size, machine = 0; + int resources_size, machine = 0; unsigned int page_size = get_page_size(); resolve_imports( spec ); - exports_size = get_exports_size( spec ); - imports_size = get_imports_size(); output_standard_file_header( outfile ); /* Reserve some space for the PE header */ @@ -510,16 +466,19 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec ) } fprintf( outfile, " \"\\t%s 0x%04x\\n\"\n", /* Machine */ get_asm_short_keyword(), machine ); - fprintf( outfile, " \"\\t.short 0\\n\"\n" ); /* NumberOfSections */ + fprintf( outfile, " \"\\t%s 0\\n\"\n", /* NumberOfSections */ + get_asm_short_keyword() ); fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* TimeDateStamp */ fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* PointerToSymbolTable */ fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* NumberOfSymbols */ fprintf( outfile, " \"\\t%s %d\\n\"\n", /* SizeOfOptionalHeader */ - get_asm_short_keyword(), IMAGE_SIZEOF_NT_OPTIONAL32_HEADER ); + get_asm_short_keyword(), + get_ptr_size() == 8 ? IMAGE_SIZEOF_NT_OPTIONAL64_HEADER : IMAGE_SIZEOF_NT_OPTIONAL32_HEADER ); fprintf( outfile, " \"\\t%s 0x%04x\\n\"\n", /* Characteristics */ get_asm_short_keyword(), spec->characteristics ); fprintf( outfile, " \"\\t%s 0x%04x\\n\"\n", /* Magic */ - get_asm_short_keyword(), IMAGE_NT_OPTIONAL_HDR_MAGIC ); + get_asm_short_keyword(), + get_ptr_size() == 8 ? IMAGE_NT_OPTIONAL_HDR64_MAGIC : IMAGE_NT_OPTIONAL_HDR32_MAGIC ); fprintf( outfile, " \"\\t.byte 0\\n\"\n" ); /* MajorLinkerVersion */ fprintf( outfile, " \"\\t.byte 0\\n\"\n" ); /* MinorLinkerVersion */ fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* SizeOfCode */ @@ -529,7 +488,8 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec ) asm_name(spec->init_func) ); fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* BaseOfCode */ fprintf( outfile, " \"\\t.long .L__wine_spec_data_start\\n\"\n" ); /* BaseOfData */ - fprintf( outfile, " \"\\t.long __wine_spec_pe_header\\n\"\n" ); /* ImageBase */ + fprintf( outfile, " \"\\t%s __wine_spec_pe_header\\n\"\n", /* ImageBase */ + get_asm_ptr_keyword() ); fprintf( outfile, " \"\\t.long %u\\n\"\n", page_size ); /* SectionAlignment */ fprintf( outfile, " \"\\t.long %u\\n\"\n", page_size ); /* FileAlignment */ fprintf( outfile, " \"\\t%s 1,0\\n\"\n", /* Major/MinorOperatingSystemVersion */ @@ -547,19 +507,19 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec ) get_asm_short_keyword(), spec->subsystem ); fprintf( outfile, " \"\\t%s 0\\n\"\n", /* DllCharacteristics */ get_asm_short_keyword() ); - fprintf( outfile, " \"\\t.long %u,%u\\n\"\n", /* SizeOfStackReserve/Commit */ - (spec->stack_size ? spec->stack_size : 1024) * 1024, page_size ); - fprintf( outfile, " \"\\t.long %u,%u\\n\"\n", /* SizeOfHeapReserve/Commit */ - (spec->heap_size ? spec->heap_size : 1024) * 1024, page_size ); + fprintf( outfile, " \"\\t%s %u,%u\\n\"\n", /* SizeOfStackReserve/Commit */ + get_asm_ptr_keyword(), (spec->stack_size ? spec->stack_size : 1024) * 1024, page_size ); + fprintf( outfile, " \"\\t%s %u,%u\\n\"\n", /* SizeOfHeapReserve/Commit */ + get_asm_ptr_keyword(), (spec->heap_size ? spec->heap_size : 1024) * 1024, page_size ); fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* LoaderFlags */ fprintf( outfile, " \"\\t.long 16\\n\"\n" ); /* NumberOfRvaAndSizes */ - if (exports_size) /* DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT] */ + if (spec->base <= spec->limit) /* DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT] */ fprintf( outfile, " \"\\t.long .L__wine_spec_exports, .L__wine_spec_exports_end-.L__wine_spec_exports\\n\"\n" ); else fprintf( outfile, " \"\\t.long 0,0\\n\"\n" ); - if (imports_size) /* DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] */ + if (has_imports()) /* DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] */ fprintf( outfile, " \"\\t.long .L__wine_spec_imports, .L__wine_spec_imports_end-.L__wine_spec_imports\\n\"\n" ); else fprintf( outfile, " \"\\t.long 0,0\\n\"\n" ); @@ -644,7 +604,7 @@ void BuildDef32File( FILE *outfile, DLLSPEC *spec ) break; case TYPE_STDCALL: { - int at_param = strlen(odp->u.func.arg_types) * sizeof(int); + int at_param = strlen(odp->u.func.arg_types) * get_ptr_size(); if (!kill_at) fprintf(outfile, "@%d", at_param); if (odp->flags & FLAG_FORWARD) {