From 5c9b7cf55f442fc7028ea52551253650de1fbaf5 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 6 Jun 2005 15:59:50 +0000 Subject: [PATCH] Moved all assembly code to the end of the generated C files to avoid conflicting with the compiler over section changes. --- tools/winebuild/build.h | 1 + tools/winebuild/import.c | 65 ++++++++++++++++----------- tools/winebuild/spec16.c | 11 ++++- tools/winebuild/spec32.c | 97 +++++++++++++++++++++++----------------- 4 files changed, 107 insertions(+), 67 deletions(-) diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h index 1fd4693e1e7..e1c17934b4e 100644 --- a/tools/winebuild/build.h +++ b/tools/winebuild/build.h @@ -174,6 +174,7 @@ extern void add_ignore_symbol( const char *name ); extern void read_undef_symbols( 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 ); extern int load_res32_file( const char *name, DLLSPEC *spec ); extern void output_resources( FILE *outfile, DLLSPEC *spec ); extern void load_res16_file( const char *name, DLLSPEC *spec ); diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c index d155d758ff1..dbf3b2cff48 100644 --- a/tools/winebuild/import.c +++ b/tools/winebuild/import.c @@ -694,11 +694,9 @@ int resolve_imports( DLLSPEC *spec ) /* output the import table of a Win32 module */ static int output_immediate_imports( FILE *outfile ) { - int i, j, pos; - int nb_imm = nb_imports - nb_delayed; - static const char import_thunks[] = "__wine_spec_import_thunks"; + int i, j, nb_imm = nb_imports - nb_delayed; - if (!nb_imm) goto done; + if (!nb_imm) return 0; /* main import header */ @@ -749,11 +747,21 @@ static int output_immediate_imports( FILE *outfile ) } fprintf( outfile, " }\n};\n\n" ); - /* thunks for imported functions */ + return nb_imm; +} + +/* output the import thunks of a Win32 module */ +static void output_immediate_import_thunks( FILE *outfile ) +{ + int i, j, pos; + int nb_imm = nb_imports - nb_delayed; + static const char import_thunks[] = "__wine_spec_import_thunks"; + + if (!nb_imm) return; - fprintf( outfile, "#ifndef __GNUC__\nstatic void __asm__dummy_import(void) {\n#endif\n\n" ); pos = (sizeof(void *) + 2*sizeof(unsigned int) + sizeof(const char *) + sizeof(void *)) * (nb_imm + 1); /* offset of imports.data from start of imports */ + fprintf( outfile, "/* immediate import thunks */\n" ); fprintf( outfile, "asm(\".text\\n\\t.align %d\\n\"\n", get_alignment(8) ); fprintf( outfile, " \"" __ASM_NAME("%s") ":\\n\"\n", import_thunks); @@ -825,20 +833,15 @@ static int output_immediate_imports( FILE *outfile ) pos += 4; } output_function_size( outfile, import_thunks ); - fprintf( outfile, " \".data\");\n#ifndef __GNUC__\n}\n#endif\n\n" ); - - done: - return nb_imm; + fprintf( outfile, ");\n" ); } /* output the delayed import table of a Win32 module */ static int output_delayed_imports( FILE *outfile, const DLLSPEC *spec ) { - int i, idx, j, pos; - static const char delayed_import_loaders[] = "__wine_spec_delayed_import_loaders"; - static const char delayed_import_thunks[] = "__wine_spec_delayed_import_thunks"; + int i, j; - if (!nb_delayed) goto done; + if (!nb_delayed) return 0; fprintf( outfile, "static void *__wine_delay_imp_hmod[%d];\n", nb_delayed ); for (i = 0; i < nb_imports; i++) @@ -926,13 +929,23 @@ static int output_delayed_imports( FILE *outfile, const DLLSPEC *spec ) fprintf( outfile, " RaiseException( 0x%08x, %d, 2, args );\n", EXCEPTION_WINE_STUB, EH_NONCONTINUABLE ); fprintf( outfile, " return 0;\n" ); - fprintf( outfile, " }\n}\n\n" ); + fprintf( outfile, " }\n}\n" ); - fprintf( outfile, "#ifndef __GNUC__\n" ); - fprintf( outfile, "static void __asm__dummy_delay_import(void) {\n" ); - fprintf( outfile, "#endif\n" ); + return nb_delayed; +} - fprintf( outfile, "asm(\".align %d\\n\"\n", get_alignment(8) ); +/* output the delayed import thunks of a Win32 module */ +static void output_delayed_import_thunks( FILE *outfile, const DLLSPEC *spec ) +{ + int i, idx, j, pos; + static const char delayed_import_loaders[] = "__wine_spec_delayed_import_loaders"; + static const char delayed_import_thunks[] = "__wine_spec_delayed_import_thunks"; + + if (!nb_delayed) return; + + fprintf( outfile, "/* delayed import thunks */\n" ); + fprintf( outfile, "asm(\".text\\n\"\n" ); + fprintf( outfile, " \"\\t.align %d\\n\"\n", get_alignment(8) ); fprintf( outfile, " \"" __ASM_NAME("%s") ":\\n\"\n", delayed_import_loaders); fprintf( outfile, " \"\\t" __ASM_FUNC("__wine_delay_load_asm") "\\n\"\n" ); fprintf( outfile, " \"" __ASM_NAME("__wine_delay_load_asm") ":\\n\"\n" ); @@ -1129,13 +1142,6 @@ static int output_delayed_imports( FILE *outfile, const DLLSPEC *spec ) } output_function_size( outfile, delayed_import_thunks ); fprintf( outfile, ");\n" ); - fprintf( outfile, "#ifndef __GNUC__\n" ); - fprintf( outfile, "}\n" ); - fprintf( outfile, "#endif\n" ); - fprintf( outfile, "\n" ); - - done: - return nb_delayed; } /* output the import and delayed import tables of a Win32 module @@ -1146,3 +1152,10 @@ int output_imports( FILE *outfile, DLLSPEC *spec, int *nb_delayed ) *nb_delayed = output_delayed_imports( outfile, spec ); return output_immediate_imports( outfile ); } + +/* output the import and delayed import thunks of a Win32 module */ +void output_import_thunks( FILE *outfile, DLLSPEC *spec ) +{ + output_delayed_import_thunks( outfile, spec ); + output_immediate_import_thunks( outfile ); +} diff --git a/tools/winebuild/spec16.c b/tools/winebuild/spec16.c index 2b0a07d4826..227350d7543 100644 --- a/tools/winebuild/spec16.c +++ b/tools/winebuild/spec16.c @@ -878,7 +878,6 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec ) sprintf( constructor, "__wine_spec_%s_init", make_c_identifier(spec->file_name) ); sprintf( destructor, "__wine_spec_%s_fini", make_c_identifier(spec->file_name) ); - output_dll_init( outfile, constructor, destructor ); fprintf( outfile, "void %s(void)\n" @@ -892,4 +891,14 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec ) " extern void __wine_dll_unregister_16( const struct module_data * );\n" " __wine_dll_unregister_16( &module );\n" "}\n", destructor ); + + fprintf( outfile, "#ifndef __GNUC__\n" ); + fprintf( outfile, "static void __asm__dummy_dll_init(void) {\n" ); + fprintf( outfile, "#endif\n" ); + + output_dll_init( outfile, constructor, destructor ); + + fprintf( outfile, "#ifndef __GNUC__\n" ); + fprintf( outfile, "}\n" ); + fprintf( outfile, "#endif\n" ); } diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c index ceb4828a38b..96013e6efa8 100644 --- a/tools/winebuild/spec32.c +++ b/tools/winebuild/spec32.c @@ -123,17 +123,56 @@ 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, fwd_size = 0, 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); + + /* 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; + } + total_size += (fwd_size + 3) & ~3; + + return total_size; +} + + /******************************************************************* * output_exports * * Output the export table for a Win32 module. */ -static int output_exports( FILE *outfile, int nr_exports, DLLSPEC *spec ) +static void output_exports( FILE *outfile, DLLSPEC *spec ) { - int i, fwd_size = 0, total_size = 0; + int i, fwd_size = 0; + int nr_exports = spec->base <= spec->limit ? spec->limit - spec->base + 1 : 0; - if (!nr_exports) return 0; + if (!nr_exports) return; + fprintf( outfile, "/* export table */\n" ); fprintf( outfile, "asm(\".data\\n\"\n" ); fprintf( outfile, " \"\\t.align %d\\n\"\n", get_alignment(4) ); fprintf( outfile, " \"" __ASM_NAME("__wine_spec_exports") ":\\n\"\n" ); @@ -158,7 +197,6 @@ static int output_exports( FILE *outfile, int nr_exports, DLLSPEC *spec ) fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* AddressOfNames */ fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* AddressOfNameOrdinals */ } - total_size += 10 * sizeof(int); /* output the function pointers */ @@ -191,7 +229,6 @@ static int output_exports( FILE *outfile, int nr_exports, DLLSPEC *spec ) assert(0); } } - total_size += (spec->limit - spec->base + 1) * sizeof(int); if (spec->nb_names) { @@ -205,7 +242,6 @@ static int output_exports( FILE *outfile, int nr_exports, DLLSPEC *spec ) fprintf( outfile, " \"\\t.long __wine_spec_exp_names+%d\\n\"\n", namepos ); namepos += strlen(spec->names[i]->name) + 1; } - total_size += spec->nb_names * sizeof(int); } /* output the function names */ @@ -227,11 +263,9 @@ static int output_exports( FILE *outfile, int nr_exports, DLLSPEC *spec ) fprintf( outfile, " \"\\t" __ASM_SHORT " %d\\n\"\n", spec->names[i]->ordinal - spec->base ); } - total_size += spec->nb_names * sizeof(short); if (spec->nb_names % 2) { fprintf( outfile, " \"\\t" __ASM_SHORT " 0\\n\"\n" ); - total_size += sizeof(short); } } @@ -247,7 +281,6 @@ static int output_exports( FILE *outfile, int nr_exports, DLLSPEC *spec ) fprintf( outfile, " \"\\t" __ASM_STRING " \\\"%s\\\"\\n\"\n", odp->link_name ); } fprintf( outfile, " \"\\t.align %d\\n\"\n", get_alignment(4) ); - total_size += (fwd_size + 3) & ~3; } /* output relays */ @@ -297,11 +330,7 @@ static int output_exports( FILE *outfile, int nr_exports, DLLSPEC *spec ) fprintf( outfile, " \"\\t.long 0,0,0,0\\n\"\n" ); } } - - fprintf( outfile, " \"\\t.data\\n\"\n" ); - fprintf( outfile, ");\n\n" ); - - return total_size; + fprintf( outfile, ");\n" ); } @@ -367,10 +396,6 @@ static void output_stub_funcs( FILE *outfile, DLLSPEC *spec ) */ void output_dll_init( FILE *outfile, const char *constructor, const char *destructor ) { - fprintf( outfile, "#ifndef __GNUC__\n" ); - fprintf( outfile, "static void __asm__dummy_dll_init(void) {\n" ); - fprintf( outfile, "#endif\n" ); - #if defined(__i386__) if (constructor) { @@ -446,9 +471,6 @@ void output_dll_init( FILE *outfile, const char *constructor, const char *destru #else #error You need to define the DLL constructor for your architecture #endif - fprintf( outfile, "#ifndef __GNUC__\n" ); - fprintf( outfile, "}\n" ); - fprintf( outfile, "#endif\n" ); } @@ -480,6 +502,7 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec ) nr_exports = spec->base <= spec->limit ? spec->limit - spec->base + 1 : 0; resolve_imports( spec ); + exports_size = get_exports_size( spec ); output_standard_file_header( outfile ); /* Reserve some space for the PE header */ @@ -512,24 +535,7 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec ) fprintf( outfile, "#define __stdcall\n\n" ); #endif - if (nr_exports) - { - /* Output the stub functions */ - - output_stub_funcs( outfile, spec ); - - fprintf( outfile, "#ifndef __GNUC__\n" ); - fprintf( outfile, "static void __asm__dummy(void) {\n" ); - fprintf( outfile, "#endif /* !defined(__GNUC__) */\n" ); - - /* Output the exports and relay entry points */ - - exports_size = output_exports( outfile, nr_exports, spec ); - - fprintf( outfile, "#ifndef __GNUC__\n" ); - fprintf( outfile, "}\n" ); - fprintf( outfile, "#endif /* !defined(__GNUC__) */\n" ); - } + output_stub_funcs( outfile, spec ); /* Output the DLL imports */ @@ -792,7 +798,6 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec ) "}\n\n", spec->file_name ); - output_dll_init( outfile, "__wine_spec_init_ctor", NULL ); fprintf( outfile, "void __wine_spec_init_ctor(void)\n" "{\n" @@ -800,6 +805,18 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec ) " __wine_spec_init();\n" " __wine_spec_init_state = 2;\n" "}\n" ); + + fprintf( outfile, "#ifndef __GNUC__\n" ); + fprintf( outfile, "static void __asm__dummy(void) {\n" ); + fprintf( outfile, "#endif\n" ); + + output_exports( outfile, spec ); + output_import_thunks( outfile, spec ); + output_dll_init( outfile, "__wine_spec_init_ctor", NULL ); + + fprintf( outfile, "#ifndef __GNUC__\n" ); + fprintf( outfile, "}\n" ); + fprintf( outfile, "#endif\n" ); }