Commit 5c9b7cf5 authored by Alexandre Julliard's avatar Alexandre Julliard

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

conflicting with the compiler over section changes.
parent 69c3e6ff
......@@ -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 );
......
......@@ -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" );
return nb_delayed;
}
/* 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";
fprintf( outfile, "#ifndef __GNUC__\n" );
fprintf( outfile, "static void __asm__dummy_delay_import(void) {\n" );
fprintf( outfile, "#endif\n" );
if (!nb_delayed) return;
fprintf( outfile, "asm(\".align %d\\n\"\n", get_alignment(8) );
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 );
}
......@@ -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" );
}
......@@ -124,16 +124,55 @@ 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" );
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment