From 3cd7379d267506e90e5e2f598d3b4f5a591a58e9 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 21 Sep 2005 10:57:04 +0000 Subject: [PATCH] Moved stub function generation to import.c. Added a get_stub_name function to ensure naming consistency. --- tools/winebuild/build.h | 4 +- tools/winebuild/import.c | 85 ++++++++++++++++++++++++++++++++++- tools/winebuild/spec32.c | 97 +--------------------------------------- tools/winebuild/utils.c | 38 +++++++++------- 4 files changed, 110 insertions(+), 114 deletions(-) diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h index 62193a4fc55..a22a4df8f67 100644 --- a/tools/winebuild/build.h +++ b/tools/winebuild/build.h @@ -180,8 +180,8 @@ extern int remove_stdcall_decoration( char *name ); extern void assemble_file( const char *src_file, const char *obj_file ); extern DLLSPEC *alloc_dll_spec(void); extern void free_dll_spec( DLLSPEC *spec ); -extern int has_stubs( const DLLSPEC *spec ); extern const char *make_c_identifier( const char *str ); +extern const char *get_stub_name( const ORDDEF *odp, const DLLSPEC *spec ); extern unsigned int get_alignment(unsigned int align); extern unsigned int get_page_size(void); extern unsigned int get_ptr_size(void); @@ -201,6 +201,8 @@ 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 has_imports(void); +extern void output_get_pc_thunk( FILE *outfile ); +extern void output_stubs( FILE *outfile, DLLSPEC *spec ); extern void output_imports( FILE *outfile, DLLSPEC *spec ); extern int load_res32_file( const char *name, DLLSPEC *spec ); extern void output_resources( FILE *outfile, DLLSPEC *spec ); diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c index 07567d5f750..61fa30daf3d 100644 --- a/tools/winebuild/import.c +++ b/tools/winebuild/import.c @@ -455,6 +455,18 @@ static const char *get_default_entry_point( const DLLSPEC *spec ) return "__wine_spec_exe_entry"; } +/* check if the spec file exports any stubs */ +static int has_stubs( const DLLSPEC *spec ) +{ + int i; + for (i = 0; i < spec->nb_entry_points; i++) + { + ORDDEF *odp = &spec->entry_points[i]; + if (odp->type == TYPE_STUB) return 1; + } + return 0; +} + /* add the extra undefined symbols that will be contained in the generated spec file itself */ static void add_extra_undef_symbols( DLLSPEC *spec ) { @@ -632,7 +644,7 @@ int resolve_imports( DLLSPEC *spec ) } /* output the get_pc thunk if needed */ -static void output_get_pc_thunk( FILE *outfile ) +void output_get_pc_thunk( FILE *outfile ) { if (target_cpu != CPU_x86) return; if (!UsePIC) return; @@ -1155,6 +1167,77 @@ static void output_external_link_imports( FILE *outfile, DLLSPEC *spec ) output_function_size( outfile, "__wine_spec_external_link_thunks" ); } +/******************************************************************* + * output_stubs + * + * Output the functions for stub entry points + */ +void output_stubs( FILE *outfile, DLLSPEC *spec ) +{ + const char *name, *exp_name; + int i, pos; + + if (!has_stubs( spec )) return; + + fprintf( outfile, "\n/* stub functions */\n\n" ); + fprintf( outfile, "\t.text\n" ); + + for (i = pos = 0; i < spec->nb_entry_points; i++) + { + ORDDEF *odp = &spec->entry_points[i]; + if (odp->type != TYPE_STUB) continue; + + name = get_stub_name( odp, spec ); + exp_name = odp->name ? odp->name : odp->export_name; + fprintf( outfile, "\t.align %d\n", get_alignment(4) ); + fprintf( outfile, "\t%s\n", func_declaration(name) ); + fprintf( outfile, "%s:\n", asm_name(name) ); + + if (UsePIC) + { + fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") ); + fprintf( outfile, "1:" ); + if (exp_name) + { + fprintf( outfile, "\tleal .L__wine_stub_strings+%d-1b(%%eax),%%ecx\n", pos ); + fprintf( outfile, "\tpushl %%ecx\n" ); + pos += strlen(exp_name) + 1; + } + else + fprintf( outfile, "\tpushl $%d\n", odp->ordinal ); + fprintf( outfile, "\tleal .L__wine_spec_file_name-1b(%%eax),%%ecx\n" ); + fprintf( outfile, "\tpushl %%ecx\n" ); + } + else + { + if (exp_name) + { + fprintf( outfile, "\tpushl $.L__wine_stub_strings+%d\n", pos ); + pos += strlen(exp_name) + 1; + } + else + fprintf( outfile, "\tpushl $%d\n", odp->ordinal ); + fprintf( outfile, "\tpushl $.L__wine_spec_file_name\n" ); + } + fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_unimplemented_stub") ); + fprintf( outfile, "\t%s\n", func_size(name) ); + } + + if (pos) + { + fprintf( outfile, "\t%s\n", get_asm_string_section() ); + fprintf( outfile, ".L__wine_stub_strings:\n" ); + for (i = 0; i < spec->nb_entry_points; i++) + { + ORDDEF *odp = &spec->entry_points[i]; + if (odp->type != TYPE_STUB) continue; + exp_name = odp->name ? odp->name : odp->export_name; + if (exp_name) + fprintf( outfile, "\t%s \"%s\"\n", get_asm_string_keyword(), exp_name ); + } + } +} + /* output the import and delayed import tables of a Win32 module */ void output_imports( FILE *outfile, DLLSPEC *spec ) { diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c index 1057b81922d..6b939312945 100644 --- a/tools/winebuild/spec32.c +++ b/tools/winebuild/spec32.c @@ -44,28 +44,6 @@ static int string_compare( const void *ptr1, const void *ptr2 ) } -/******************************************************************* - * make_internal_name - * - * Generate an internal name for an entry point. Used for stubs etc. - */ -static const char *make_internal_name( const ORDDEF *odp, DLLSPEC *spec, const char *prefix ) -{ - static char buffer[256]; - if (odp->name || odp->export_name) - { - char *p; - sprintf( buffer, "__wine_%s_%s_%s", prefix, spec->file_name, - odp->name ? odp->name : odp->export_name ); - /* make sure name is a legal C identifier */ - for (p = buffer; *p; p++) if (!isalnum(*p) && *p != '_') break; - if (!*p) return buffer; - } - sprintf( buffer, "__wine_%s_%s_%d", prefix, make_c_identifier(spec->file_name), odp->ordinal ); - return buffer; -} - - /******************************************************************* * output_debug * @@ -163,7 +141,7 @@ static void output_exports( FILE *outfile, DLLSPEC *spec ) break; case TYPE_STUB: fprintf( outfile, "\t%s %s\n", get_asm_ptr_keyword(), - asm_name( make_internal_name( odp, spec, "stub" )) ); + asm_name( get_stub_name( odp, spec )) ); break; default: assert(0); @@ -272,78 +250,6 @@ static void output_exports( FILE *outfile, DLLSPEC *spec ) } -/******************************************************************* - * output_stubs - * - * Output the functions for stub entry points -*/ -static void output_stubs( FILE *outfile, DLLSPEC *spec ) -{ - const char *name, *exp_name; - int i, pos; - - if (!has_stubs( spec )) return; - - fprintf( outfile, "\n/* stub functions */\n\n" ); - fprintf( outfile, "\t.text\n" ); - - for (i = pos = 0; i < spec->nb_entry_points; i++) - { - ORDDEF *odp = &spec->entry_points[i]; - if (odp->type != TYPE_STUB) continue; - - name = make_internal_name( odp, spec, "stub" ); - exp_name = odp->name ? odp->name : odp->export_name; - fprintf( outfile, "\t.align %d\n", get_alignment(4) ); - fprintf( outfile, "\t%s\n", func_declaration(name) ); - fprintf( outfile, "%s:\n", asm_name(name) ); - - if (UsePIC) - { - fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") ); - fprintf( outfile, "1:" ); - if (exp_name) - { - fprintf( outfile, "\tleal .L__wine_stub_strings+%d-1b(%%eax),%%ecx\n", pos ); - fprintf( outfile, "\tpushl %%ecx\n" ); - pos += strlen(exp_name) + 1; - } - else - fprintf( outfile, "\tpushl $%d\n", odp->ordinal ); - fprintf( outfile, "\tleal %s-1b(%%eax),%%ecx\n", asm_name("__wine_spec_file_name") ); - fprintf( outfile, "\tpushl %%ecx\n" ); - } - else - { - if (exp_name) - { - fprintf( outfile, "\tpushl $.L__wine_stub_strings+%d\n", pos ); - pos += strlen(exp_name) + 1; - } - else - fprintf( outfile, "\tpushl $%d\n", odp->ordinal ); - fprintf( outfile, "\tpushl $%s\n", asm_name("__wine_spec_file_name") ); - } - fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_unimplemented_stub") ); - fprintf( outfile, "\t%s\n", func_size(name) ); - } - - if (pos) - { - fprintf( outfile, "\t%s\n", get_asm_string_section() ); - fprintf( outfile, ".L__wine_stub_strings:\n" ); - for (i = 0; i < spec->nb_entry_points; i++) - { - ORDDEF *odp = &spec->entry_points[i]; - if (odp->type != TYPE_STUB) continue; - exp_name = odp->name ? odp->name : odp->export_name; - if (exp_name) - fprintf( outfile, "\t%s \"%s\"\n", get_asm_string_keyword(), exp_name ); - } - } -} - - /******************************************************************* * output_dll_init * @@ -599,6 +505,7 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec ) fprintf( outfile, "\n\t%s\n", get_asm_string_section() ); fprintf( outfile, "%s\n", asm_globl("__wine_spec_file_name") ); + fprintf( outfile, ".L__wine_spec_file_name:\n" ); fprintf( outfile, "\t%s \"%s\"\n", get_asm_string_keyword(), spec->file_name ); if (target_platform == PLATFORM_APPLE) fprintf( outfile, "\t.lcomm %s,4\n", asm_name("_end") ); diff --git a/tools/winebuild/utils.c b/tools/winebuild/utils.c index 810491f28dc..358514f2078 100644 --- a/tools/winebuild/utils.c +++ b/tools/winebuild/utils.c @@ -361,23 +361,6 @@ void free_dll_spec( DLLSPEC *spec ) } -/******************************************************************* - * has_stubs - * - * Check if the spec file exports any stubs - */ -int has_stubs( const DLLSPEC *spec ) -{ - int i; - for (i = 0; i < spec->nb_entry_points; i++) - { - ORDDEF *odp = &spec->entry_points[i]; - if (odp->type == TYPE_STUB) return 1; - } - return 0; -} - - /******************************************************************* * make_c_identifier * @@ -398,6 +381,27 @@ const char *make_c_identifier( const char *str ) } +/******************************************************************* + * get_stub_name + * + * Generate an internal name for a stub entry point. + */ +const char *get_stub_name( const ORDDEF *odp, const DLLSPEC *spec ) +{ + static char buffer[256]; + if (odp->name || odp->export_name) + { + char *p; + sprintf( buffer, "__wine_stub_%s", odp->name ? odp->name : odp->export_name ); + /* make sure name is a legal C identifier */ + for (p = buffer; *p; p++) if (!isalnum(*p) && *p != '_') break; + if (!*p) return buffer; + } + sprintf( buffer, "__wine_stub_%s_%d", make_c_identifier(spec->file_name), odp->ordinal ); + return buffer; +} + + /***************************************************************** * Function: get_alignment *