Moved all assembly code to the end of the generated C files to avoid

conflicting with the compiler over section changes.
This commit is contained in:
Alexandre Julliard 2005-06-06 15:59:50 +00:00
parent 69c3e6ff11
commit 5c9b7cf55f
4 changed files with 107 additions and 67 deletions

View File

@ -174,6 +174,7 @@ extern void add_ignore_symbol( const char *name );
extern void read_undef_symbols( char **argv ); extern void read_undef_symbols( char **argv );
extern int resolve_imports( DLLSPEC *spec ); extern int resolve_imports( DLLSPEC *spec );
extern int output_imports( FILE *outfile, DLLSPEC *spec, int *nb_delayed ); 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 int load_res32_file( const char *name, DLLSPEC *spec );
extern void output_resources( FILE *outfile, DLLSPEC *spec ); extern void output_resources( FILE *outfile, DLLSPEC *spec );
extern void load_res16_file( const char *name, DLLSPEC *spec ); extern void load_res16_file( const char *name, DLLSPEC *spec );

View File

@ -694,11 +694,9 @@ int resolve_imports( DLLSPEC *spec )
/* output the import table of a Win32 module */ /* output the import table of a Win32 module */
static int output_immediate_imports( FILE *outfile ) static int output_immediate_imports( FILE *outfile )
{ {
int i, j, pos; int i, j, nb_imm = nb_imports - nb_delayed;
int nb_imm = nb_imports - nb_delayed;
static const char import_thunks[] = "__wine_spec_import_thunks";
if (!nb_imm) goto done; if (!nb_imm) return 0;
/* main import header */ /* main import header */
@ -749,11 +747,21 @@ static int output_immediate_imports( FILE *outfile )
} }
fprintf( outfile, " }\n};\n\n" ); 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 *)) * pos = (sizeof(void *) + 2*sizeof(unsigned int) + sizeof(const char *) + sizeof(void *)) *
(nb_imm + 1); /* offset of imports.data from start of imports */ (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(\".text\\n\\t.align %d\\n\"\n", get_alignment(8) );
fprintf( outfile, " \"" __ASM_NAME("%s") ":\\n\"\n", import_thunks); fprintf( outfile, " \"" __ASM_NAME("%s") ":\\n\"\n", import_thunks);
@ -825,20 +833,15 @@ static int output_immediate_imports( FILE *outfile )
pos += 4; pos += 4;
} }
output_function_size( outfile, import_thunks ); output_function_size( outfile, import_thunks );
fprintf( outfile, " \".data\");\n#ifndef __GNUC__\n}\n#endif\n\n" ); fprintf( outfile, ");\n" );
done:
return nb_imm;
} }
/* output the delayed import table of a Win32 module */ /* output the delayed import table of a Win32 module */
static int output_delayed_imports( FILE *outfile, const DLLSPEC *spec ) static int output_delayed_imports( FILE *outfile, const DLLSPEC *spec )
{ {
int i, idx, j, pos; int i, j;
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) goto done; if (!nb_delayed) return 0;
fprintf( outfile, "static void *__wine_delay_imp_hmod[%d];\n", nb_delayed ); fprintf( outfile, "static void *__wine_delay_imp_hmod[%d];\n", nb_delayed );
for (i = 0; i < nb_imports; i++) 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", fprintf( outfile, " RaiseException( 0x%08x, %d, 2, args );\n",
EXCEPTION_WINE_STUB, EH_NONCONTINUABLE ); EXCEPTION_WINE_STUB, EH_NONCONTINUABLE );
fprintf( outfile, " return 0;\n" ); fprintf( outfile, " return 0;\n" );
fprintf( outfile, " }\n}\n\n" ); fprintf( outfile, " }\n}\n" );
fprintf( outfile, "#ifndef __GNUC__\n" ); return nb_delayed;
fprintf( outfile, "static void __asm__dummy_delay_import(void) {\n" ); }
fprintf( outfile, "#endif\n" );
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, " \"" __ASM_NAME("%s") ":\\n\"\n", delayed_import_loaders);
fprintf( outfile, " \"\\t" __ASM_FUNC("__wine_delay_load_asm") "\\n\"\n" ); fprintf( outfile, " \"\\t" __ASM_FUNC("__wine_delay_load_asm") "\\n\"\n" );
fprintf( outfile, " \"" __ASM_NAME("__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 ); output_function_size( outfile, delayed_import_thunks );
fprintf( outfile, ");\n" ); 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 /* 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 ); *nb_delayed = output_delayed_imports( outfile, spec );
return output_immediate_imports( outfile ); 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 );
}

View File

@ -878,7 +878,6 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec )
sprintf( constructor, "__wine_spec_%s_init", make_c_identifier(spec->file_name) ); sprintf( constructor, "__wine_spec_%s_init", make_c_identifier(spec->file_name) );
sprintf( destructor, "__wine_spec_%s_fini", 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, fprintf( outfile,
"void %s(void)\n" "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" " extern void __wine_dll_unregister_16( const struct module_data * );\n"
" __wine_dll_unregister_16( &module );\n" " __wine_dll_unregister_16( &module );\n"
"}\n", destructor ); "}\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" );
} }

View File

@ -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_exports
* *
* Output the export table for a Win32 module. * 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, "asm(\".data\\n\"\n" );
fprintf( outfile, " \"\\t.align %d\\n\"\n", get_alignment(4) ); fprintf( outfile, " \"\\t.align %d\\n\"\n", get_alignment(4) );
fprintf( outfile, " \"" __ASM_NAME("__wine_spec_exports") ":\\n\"\n" ); 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" ); /* AddressOfNames */
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* AddressOfNameOrdinals */ fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* AddressOfNameOrdinals */
} }
total_size += 10 * sizeof(int);
/* output the function pointers */ /* output the function pointers */
@ -191,7 +229,6 @@ static int output_exports( FILE *outfile, int nr_exports, DLLSPEC *spec )
assert(0); assert(0);
} }
} }
total_size += (spec->limit - spec->base + 1) * sizeof(int);
if (spec->nb_names) 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 ); fprintf( outfile, " \"\\t.long __wine_spec_exp_names+%d\\n\"\n", namepos );
namepos += strlen(spec->names[i]->name) + 1; namepos += strlen(spec->names[i]->name) + 1;
} }
total_size += spec->nb_names * sizeof(int);
} }
/* output the function names */ /* 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", fprintf( outfile, " \"\\t" __ASM_SHORT " %d\\n\"\n",
spec->names[i]->ordinal - spec->base ); spec->names[i]->ordinal - spec->base );
} }
total_size += spec->nb_names * sizeof(short);
if (spec->nb_names % 2) if (spec->nb_names % 2)
{ {
fprintf( outfile, " \"\\t" __ASM_SHORT " 0\\n\"\n" ); 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" __ASM_STRING " \\\"%s\\\"\\n\"\n", odp->link_name );
} }
fprintf( outfile, " \"\\t.align %d\\n\"\n", get_alignment(4) ); fprintf( outfile, " \"\\t.align %d\\n\"\n", get_alignment(4) );
total_size += (fwd_size + 3) & ~3;
} }
/* output relays */ /* 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.long 0,0,0,0\\n\"\n" );
} }
} }
fprintf( outfile, ");\n" );
fprintf( outfile, " \"\\t.data\\n\"\n" );
fprintf( outfile, ");\n\n" );
return total_size;
} }
@ -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 ) 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 defined(__i386__)
if (constructor) if (constructor)
{ {
@ -446,9 +471,6 @@ void output_dll_init( FILE *outfile, const char *constructor, const char *destru
#else #else
#error You need to define the DLL constructor for your architecture #error You need to define the DLL constructor for your architecture
#endif #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; nr_exports = spec->base <= spec->limit ? spec->limit - spec->base + 1 : 0;
resolve_imports( spec ); resolve_imports( spec );
exports_size = get_exports_size( spec );
output_standard_file_header( outfile ); output_standard_file_header( outfile );
/* Reserve some space for the PE header */ /* Reserve some space for the PE header */
@ -512,24 +535,7 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
fprintf( outfile, "#define __stdcall\n\n" ); fprintf( outfile, "#define __stdcall\n\n" );
#endif #endif
if (nr_exports) output_stub_funcs( outfile, spec );
{
/* 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 the DLL imports */ /* Output the DLL imports */
@ -792,7 +798,6 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
"}\n\n", "}\n\n",
spec->file_name ); spec->file_name );
output_dll_init( outfile, "__wine_spec_init_ctor", NULL );
fprintf( outfile, fprintf( outfile,
"void __wine_spec_init_ctor(void)\n" "void __wine_spec_init_ctor(void)\n"
"{\n" "{\n"
@ -800,6 +805,18 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
" __wine_spec_init();\n" " __wine_spec_init();\n"
" __wine_spec_init_state = 2;\n" " __wine_spec_init_state = 2;\n"
"}\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" );
} }