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:
parent
69c3e6ff11
commit
5c9b7cf55f
|
@ -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 );
|
||||||
|
|
|
@ -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 );
|
||||||
|
}
|
||||||
|
|
|
@ -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" );
|
||||||
}
|
}
|
||||||
|
|
|
@ -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" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue