Commit 9f498891 authored by Alexandre Julliard's avatar Alexandre Julliard

Now that everything is done in assembly in the spec file, directly

generate a .s file to bypass gcc inefficiency with large data structures.
parent a861f4df
...@@ -67,7 +67,7 @@ lib$(BASEMODULE).a: $(SPEC_DEF) $(IMPLIB_OBJS) ...@@ -67,7 +67,7 @@ lib$(BASEMODULE).a: $(SPEC_DEF) $(IMPLIB_OBJS)
$(WIN16_FILES:%=__checklink16__%): checklink16 $(WIN16_FILES:%=__checklink16__%): checklink16
checklink16:: $(MAINSPEC).o $(OBJS) $(MODULE).dbg.o dummy checklink16:: $(MAINSPEC).o $(OBJS) $(MODULE).dbg.o dummy
$(CC) -o checklink -Wl,-rpath,$(TOPOBJDIR)/libs $(TOPSRCDIR)/dlls/checklink.c $(MAINSPEC).o $(OBJS) $(MODULE).dbg.o -L$(DLLDIR) $(ALL_LIBS) -lwinecrt0 -lm && $(RM) checklink $(MAINSPEC).c $(MAINSPEC).o $(CC) -o checklink -Wl,-rpath,$(TOPOBJDIR)/libs $(TOPSRCDIR)/dlls/checklink.c $(MAINSPEC).o $(OBJS) $(MODULE).dbg.o -L$(DLLDIR) $(ALL_LIBS) -lwinecrt0 -lm && $(RM) checklink $(MAINSPEC).s $(MAINSPEC).o
checklink:: $(WIN16_FILES:%=__checklink16__%) checklink:: $(WIN16_FILES:%=__checklink16__%)
...@@ -79,7 +79,7 @@ crosstest:: $(SUBDIRS:%=%/__crosstest__) ...@@ -79,7 +79,7 @@ crosstest:: $(SUBDIRS:%=%/__crosstest__)
# Rule to explicitly generate the .spec.c for debugging # Rule to explicitly generate the .spec.c for debugging
$(MAINSPEC).c: $(MAINSPEC) $(ALL_OBJS) $(MAINSPEC).s: $(MAINSPEC) $(ALL_OBJS)
$(WINEBUILD) $(DEFS) $(DLLFLAGS) --dll -o $@ --export $(SRCDIR)/$(MAINSPEC) $(SUBSYSTEM:%=--subsystem %) $(ALL_OBJS) $(DLL_LDPATH) $(ALL_IMPORTS:%=-l%) $(DELAYIMPORTS:%=-d%) $(DLLDIR)/libwinecrt0.a $(WINEBUILD) $(DEFS) $(DLLFLAGS) --dll -o $@ --export $(SRCDIR)/$(MAINSPEC) $(SUBSYSTEM:%=--subsystem %) $(ALL_OBJS) $(DLL_LDPATH) $(ALL_IMPORTS:%=-l%) $(DELAYIMPORTS:%=-d%) $(DLLDIR)/libwinecrt0.a
# Rules for auto documentation # Rules for auto documentation
......
...@@ -209,7 +209,7 @@ inline static ORDDEF *find_export( const char *name, ORDDEF **table, int size ) ...@@ -209,7 +209,7 @@ inline static ORDDEF *find_export( const char *name, ORDDEF **table, int size )
inline static void output_function_size( FILE *outfile, const char *name ) inline static void output_function_size( FILE *outfile, const char *name )
{ {
const char *size = func_size( name ); const char *size = func_size( name );
if (size[0]) fprintf( outfile, " \"\\t%s\\n\"\n", size ); if (size[0]) fprintf( outfile, "\t%s\n", size );
} }
/* free an import structure */ /* free an import structure */
...@@ -613,10 +613,10 @@ int resolve_imports( DLLSPEC *spec ) ...@@ -613,10 +613,10 @@ int resolve_imports( DLLSPEC *spec )
/* output a single import thunk */ /* output a single import thunk */
static void output_import_thunk( FILE *outfile, const char *name, const char *table, int pos ) static void output_import_thunk( FILE *outfile, const char *name, const char *table, int pos )
{ {
fprintf( outfile, " \"\\t.align %d\\n\"\n", get_alignment(4) ); fprintf( outfile, "\n\t.align %d\n", get_alignment(4) );
fprintf( outfile, " \"\\t%s\\n\"\n", func_declaration(name) ); fprintf( outfile, "\t%s\n", func_declaration(name) );
fprintf( outfile, " \"\\t.globl %s\\n\"\n", asm_name(name) ); fprintf( outfile, "\t.globl %s\n", asm_name(name) );
fprintf( outfile, " \"%s:\\n\"\n", asm_name(name) ); fprintf( outfile, "%s:\n", asm_name(name) );
switch(target_cpu) switch(target_cpu)
{ {
...@@ -624,50 +624,50 @@ static void output_import_thunk( FILE *outfile, const char *name, const char *ta ...@@ -624,50 +624,50 @@ static void output_import_thunk( FILE *outfile, const char *name, const char *ta
case CPU_x86: case CPU_x86:
if (!UsePIC) if (!UsePIC)
{ {
if (strstr( name, "__wine_call_from_16" )) fprintf( outfile, " \"\\t.byte 0x2e\\n\"\n" ); if (strstr( name, "__wine_call_from_16" )) fprintf( outfile, "\t.byte 0x2e\n" );
fprintf( outfile, " \"\\tjmp *(%s+%d)\\n\"\n", table, pos ); fprintf( outfile, "\tjmp *(%s+%d)\n", table, pos );
} }
else else
{ {
if (!strcmp( name, "__wine_call_from_32_regs" )) if (!strcmp( name, "__wine_call_from_32_regs" ))
{ {
/* special case: need to preserve all registers */ /* special case: need to preserve all registers */
fprintf( outfile, " \"\\tpushl %%eax\\n\"\n" ); fprintf( outfile, "\tpushl %%eax\n" );
fprintf( outfile, " \"\\tcall .L__wine_spec_%s\\n\"\n", name ); fprintf( outfile, "\tcall .L__wine_spec_%s\n", name );
fprintf( outfile, " \".L__wine_spec_%s:\\n\"\n", name ); fprintf( outfile, ".L__wine_spec_%s:\n", name );
fprintf( outfile, " \"\\tpopl %%eax\\n\"\n" ); fprintf( outfile, "\tpopl %%eax\n" );
if (!strcmp( name, "__wine_call_from_16_regs" )) if (!strcmp( name, "__wine_call_from_16_regs" ))
fprintf( outfile, " \"\\t.byte 0x2e\\n\"\n" ); fprintf( outfile, "\t.byte 0x2e\n" );
fprintf( outfile, " \"\\tmovl %s+%d-.L__wine_spec_%s(%%eax),%%eax\\n\"\n", fprintf( outfile, "\tmovl %s+%d-.L__wine_spec_%s(%%eax),%%eax\n",
table, pos, name ); table, pos, name );
fprintf( outfile, " \"\\txchgl %%eax,(%%esp)\\n\"\n" ); fprintf( outfile, "\txchgl %%eax,(%%esp)\n" );
fprintf( outfile, " \"\\tret\\n\"\n" ); fprintf( outfile, "\tret\n" );
} }
else if (!strcmp( name, "__wine_call_from_16_regs" )) else if (!strcmp( name, "__wine_call_from_16_regs" ))
{ {
/* special case: need to preserve all registers */ /* special case: need to preserve all registers */
fprintf( outfile, " \"\\tpushl %%eax\\n\"\n" ); fprintf( outfile, "\tpushl %%eax\n" );
fprintf( outfile, " \"\\tpushl %%ecx\\n\"\n" ); fprintf( outfile, "\tpushl %%ecx\n" );
fprintf( outfile, " \"\\tcall .L__wine_spec_%s\\n\"\n", name ); fprintf( outfile, "\tcall .L__wine_spec_%s\n", name );
fprintf( outfile, " \".L__wine_spec_%s:\\n\"\n", name ); fprintf( outfile, ".L__wine_spec_%s:\n", name );
fprintf( outfile, " \"\\tpopl %%eax\\n\"\n" ); fprintf( outfile, "\tpopl %%eax\n" );
fprintf( outfile, " \"\\t.byte 0x2e\\n\"\n" ); fprintf( outfile, "\t.byte 0x2e\n" );
fprintf( outfile, " \"\\tmovl %s+%d-.L__wine_spec_%s(%%eax),%%eax\\n\"\n", fprintf( outfile, "\tmovl %s+%d-.L__wine_spec_%s(%%eax),%%eax\n",
table, pos, name ); table, pos, name );
fprintf( outfile, " \"\\tmovzwl %%sp, %%ecx\\n\"\n" ); fprintf( outfile, "\tmovzwl %%sp, %%ecx\n" );
fprintf( outfile, " \"\\t.byte 0x36\\n\"\n" ); fprintf( outfile, "\t.byte 0x36\n" );
fprintf( outfile, " \"\\txchgl %%eax,4(%%ecx)\\n\"\n" ); fprintf( outfile, "\txchgl %%eax,4(%%ecx)\n" );
fprintf( outfile, " \"\\tpopl %%ecx\\n\"\n" ); fprintf( outfile, "\tpopl %%ecx\n" );
fprintf( outfile, " \"\\tret\\n\"\n" ); fprintf( outfile, "\tret\n" );
} }
else else
{ {
fprintf( outfile, " \"\\tcall .L__wine_spec_%s\\n\"\n", name ); fprintf( outfile, "\tcall .L__wine_spec_%s\n", name );
fprintf( outfile, " \".L__wine_spec_%s:\\n\"\n", name ); fprintf( outfile, ".L__wine_spec_%s:\n", name );
fprintf( outfile, " \"\\tpopl %%eax\\n\"\n" ); fprintf( outfile, "\tpopl %%eax\n" );
if (strstr( name, "__wine_call_from_16" )) if (strstr( name, "__wine_call_from_16" ))
fprintf( outfile, " \"\\t.byte 0x2e\\n\"\n" ); fprintf( outfile, "\t.byte 0x2e\n" );
fprintf( outfile, " \"\\tjmp *%s+%d-.L__wine_spec_%s(%%eax)\\n\"\n", fprintf( outfile, "\tjmp *%s+%d-.L__wine_spec_%s(%%eax)\n",
table, pos, name ); table, pos, name );
} }
} }
...@@ -675,57 +675,56 @@ static void output_import_thunk( FILE *outfile, const char *name, const char *ta ...@@ -675,57 +675,56 @@ static void output_import_thunk( FILE *outfile, const char *name, const char *ta
case CPU_SPARC: case CPU_SPARC:
if ( !UsePIC ) if ( !UsePIC )
{ {
fprintf( outfile, " \"\\tsethi %%hi(%s+%d), %%g1\\n\"\n", table, pos ); fprintf( outfile, "\tsethi %%hi(%s+%d), %%g1\n", table, pos );
fprintf( outfile, " \"\\tld [%%g1+%%lo(%s+%d)], %%g1\\n\"\n", table, pos ); fprintf( outfile, "\tld [%%g1+%%lo(%s+%d)], %%g1\n", table, pos );
fprintf( outfile, " \"\\tjmp %%g1\\n\\tnop\\n\"\n" ); fprintf( outfile, "\tjmp %%g1\n" );
fprintf( outfile, "\tnop\n" );
} }
else else
{ {
/* Hmpf. Stupid sparc assembler always interprets global variable /* Hmpf. Stupid sparc assembler always interprets global variable
names as GOT offsets, so we have to do it the long way ... */ names as GOT offsets, so we have to do it the long way ... */
fprintf( outfile, " \"\\tsave %%sp, -96, %%sp\\n\"\n" ); fprintf( outfile, "\tsave %%sp, -96, %%sp\n" );
fprintf( outfile, " \"0:\\tcall 1f\\n\\tnop\\n\"\n" ); fprintf( outfile, "0:\tcall 1f\n" );
fprintf( outfile, " \"1:\\tsethi %%hi(%s+%d-0b), %%g1\\n\"\n", table, pos ); fprintf( outfile, "\tnop\n" );
fprintf( outfile, " \"\\tor %%g1, %%lo(%s+%d-0b), %%g1\\n\"\n", table, pos ); fprintf( outfile, "1:\tsethi %%hi(%s+%d-0b), %%g1\n", table, pos );
fprintf( outfile, " \"\\tld [%%g1+%%o7], %%g1\\n\"\n" ); fprintf( outfile, "\tor %%g1, %%lo(%s+%d-0b), %%g1\n", table, pos );
fprintf( outfile, " \"\\tjmp %%g1\\n\\trestore\\n\"\n" ); fprintf( outfile, "\tld [%%g1+%%o7], %%g1\n" );
fprintf( outfile, "\tjmp %%g1\n" );
fprintf( outfile, "\trestore\n" );
} }
break; break;
case CPU_ALPHA: case CPU_ALPHA:
fprintf( outfile, " \"\\tlda $0,%s\\n\"\n", table ); fprintf( outfile, "\tlda $0,%s\n", table );
fprintf( outfile, " \"\\tlda $0,%d($0)\\n\"\n", pos); fprintf( outfile, "\tlda $0,%d($0)\n", pos );
fprintf( outfile, " \"\\tjmp $31,($0)\\n\"\n" ); fprintf( outfile, "\tjmp $31,($0)\n" );
break; break;
case CPU_POWERPC: case CPU_POWERPC:
fprintf(outfile, " \"\\taddi %s, %s, -0x4\\n\"\n", ppc_reg(1), ppc_reg(1)); fprintf( outfile, "\taddi %s, %s, -0x4\n", ppc_reg(1), ppc_reg(1) );
fprintf(outfile, " \"\\tstw %s, 0(%s)\\n\"\n", ppc_reg(9), ppc_reg(1)); fprintf( outfile, "\tstw %s, 0(%s)\n", ppc_reg(9), ppc_reg(1) );
fprintf(outfile, " \"\\taddi %s, %s, -0x4\\n\"\n", ppc_reg(1), ppc_reg(1)); fprintf( outfile, "\taddi %s, %s, -0x4\n", ppc_reg(1), ppc_reg(1) );
fprintf(outfile, " \"\\tstw %s, 0(%s)\\n\"\n", ppc_reg(8), ppc_reg(1)); fprintf( outfile, "\tstw %s, 0(%s)\n", ppc_reg(8), ppc_reg(1) );
fprintf(outfile, " \"\\taddi %s, %s, -0x4\\n\"\n", ppc_reg(1), ppc_reg(1)); fprintf( outfile, "\taddi %s, %s, -0x4\n", ppc_reg(1), ppc_reg(1) );
fprintf(outfile, " \"\\tstw %s, 0(%s)\\n\"\n", ppc_reg(7), ppc_reg(1)); fprintf( outfile, "\tstw %s, 0(%s)\n", ppc_reg(7), ppc_reg(1) );
if (target_platform == PLATFORM_APPLE) if (target_platform == PLATFORM_APPLE)
{ {
fprintf(outfile, " \"\\tlis %s, ha16(%s+%d)\\n\"\n", fprintf( outfile, "\tlis %s, ha16(%s+%d)\n", ppc_reg(9), table, pos );
ppc_reg(9), table, pos); fprintf( outfile, "\tla %s, lo16(%s+%d)(%s)\n", ppc_reg(8), table, pos, ppc_reg(9) );
fprintf(outfile, " \"\\tla %s, lo16(%s+%d)(%s)\\n\"\n",
ppc_reg(8), table, pos, ppc_reg(9));
} }
else else
{ {
fprintf(outfile, " \"\\tlis %s, (%s+%d)@hi\\n\"\n", fprintf( outfile, "\tlis %s, (%s+%d)@hi\n", ppc_reg(9), table, pos );
ppc_reg(9), table, pos); fprintf( outfile, "\tla %s, (%s+%d)@l(%s)\n", ppc_reg(8), table, pos, ppc_reg(9) );
fprintf(outfile, " \"\\tla %s, (%s+%d)@l(%s)\\n\"\n",
ppc_reg(8), table, pos, ppc_reg(9));
} }
fprintf(outfile, " \"\\tlwz %s, 0(%s)\\n\"\n", ppc_reg(7), ppc_reg(8)); fprintf( outfile, "\tlwz %s, 0(%s)\n", ppc_reg(7), ppc_reg(8) );
fprintf(outfile, " \"\\tmtctr %s\\n\"\n", ppc_reg(7)); fprintf( outfile, "\tmtctr %s\n", ppc_reg(7) );
fprintf(outfile, " \"\\tlwz %s, 0(%s)\\n\"\n", ppc_reg(7), ppc_reg(1)); fprintf( outfile, "\tlwz %s, 0(%s)\n", ppc_reg(7), ppc_reg(1) );
fprintf(outfile, " \"\\taddi %s, %s, 0x4\\n\"\n", ppc_reg(1), ppc_reg(1)); fprintf( outfile, "\taddi %s, %s, 0x4\n", ppc_reg(1), ppc_reg(1) );
fprintf(outfile, " \"\\tlwz %s, 0(%s)\\n\"\n", ppc_reg(8), ppc_reg(1)); fprintf( outfile, "\tlwz %s, 0(%s)\n", ppc_reg(8), ppc_reg(1) );
fprintf(outfile, " \"\\taddi %s, %s, 0x4\\n\"\n", ppc_reg(1), ppc_reg(1)); fprintf( outfile, "\taddi %s, %s, 0x4\n", ppc_reg(1), ppc_reg(1) );
fprintf(outfile, " \"\\tlwz %s, 0(%s)\\n\"\n", ppc_reg(9), ppc_reg(1)); fprintf( outfile, "\tlwz %s, 0(%s)\n", ppc_reg(9), ppc_reg(1) );
fprintf(outfile, " \"\\taddi %s, %s, 0x4\\n\"\n", ppc_reg(1), ppc_reg(1)); fprintf( outfile, "\taddi %s, %s, 0x4\n", ppc_reg(1), ppc_reg(1) );
fprintf(outfile, " \"\\tbctr\\n\"\n"); fprintf( outfile, "\tbctr\n" );
break; break;
} }
output_function_size( outfile, name ); output_function_size( outfile, name );
...@@ -747,9 +746,10 @@ static void output_immediate_imports( FILE *outfile ) ...@@ -747,9 +746,10 @@ static void output_immediate_imports( FILE *outfile )
/* main import header */ /* main import header */
fprintf( outfile, "/* import table */\n" ); fprintf( outfile, "\n/* import table */\n" );
fprintf( outfile, "asm(\".data\\n\\t.align %d\\n\"\n", get_alignment(4) ); fprintf( outfile, "\n\t.data\n" );
fprintf( outfile, " \".L__wine_spec_imports:\\n\"\n" ); fprintf( outfile, "\t.align %d\n", get_alignment(4) );
fprintf( outfile, ".L__wine_spec_imports:\n" );
/* list of dlls */ /* list of dlls */
...@@ -757,22 +757,22 @@ static void output_immediate_imports( FILE *outfile ) ...@@ -757,22 +757,22 @@ static void output_immediate_imports( FILE *outfile )
{ {
if (dll_imports[i]->delay) continue; if (dll_imports[i]->delay) continue;
dll_name = make_c_identifier( dll_imports[i]->spec->file_name ); dll_name = make_c_identifier( dll_imports[i]->spec->file_name );
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* OriginalFirstThunk */ fprintf( outfile, "\t.long 0\n" ); /* OriginalFirstThunk */
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* TimeDateStamp */ fprintf( outfile, "\t.long 0\n" ); /* TimeDateStamp */
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* ForwarderChain */ fprintf( outfile, "\t.long 0\n" ); /* ForwarderChain */
fprintf( outfile, " \"\\t.long .L__wine_spec_import_name_%s\\n\"\n", dll_name ); /* Name */ fprintf( outfile, "\t.long .L__wine_spec_import_name_%s\n", dll_name ); /* Name */
fprintf( outfile, " \"\\t.long .L__wine_spec_import_data_ptrs+%d\\n\"\n", /* FirstThunk */ fprintf( outfile, "\t.long .L__wine_spec_import_data_ptrs+%d\n", /* FirstThunk */
j * get_ptr_size() ); j * get_ptr_size() );
j += dll_imports[i]->nb_imports + 1; j += dll_imports[i]->nb_imports + 1;
} }
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* OriginalFirstThunk */ fprintf( outfile, "\t.long 0\n" ); /* OriginalFirstThunk */
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* TimeDateStamp */ fprintf( outfile, "\t.long 0\n" ); /* TimeDateStamp */
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* ForwarderChain */ fprintf( outfile, "\t.long 0\n" ); /* ForwarderChain */
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* Name */ fprintf( outfile, "\t.long 0\n" ); /* Name */
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* FirstThunk */ fprintf( outfile, "\t.long 0\n" ); /* FirstThunk */
fprintf( outfile, " \"\\t.align %d\\n\"\n", get_alignment(get_ptr_size()) ); fprintf( outfile, "\n\t.align %d\n", get_alignment(get_ptr_size()) );
fprintf( outfile, " \".L__wine_spec_import_data_ptrs:\\n\"\n" ); fprintf( outfile, ".L__wine_spec_import_data_ptrs:\n" );
for (i = 0; i < nb_imports; i++) for (i = 0; i < nb_imports; i++)
{ {
if (dll_imports[i]->delay) continue; if (dll_imports[i]->delay) continue;
...@@ -781,14 +781,14 @@ static void output_immediate_imports( FILE *outfile ) ...@@ -781,14 +781,14 @@ static void output_immediate_imports( FILE *outfile )
{ {
ORDDEF *odp = dll_imports[i]->imports[j]; ORDDEF *odp = dll_imports[i]->imports[j];
if (!(odp->flags & FLAG_NONAME)) if (!(odp->flags & FLAG_NONAME))
fprintf( outfile, " \"\\t%s .L__wine_spec_import_data_%s_%s\\n\"\n", fprintf( outfile, "\t%s .L__wine_spec_import_data_%s_%s\n",
get_asm_ptr_keyword(), dll_name, odp->name ); get_asm_ptr_keyword(), dll_name, odp->name );
else else
fprintf( outfile, " \"\\t%s %d\\n\"\n", get_asm_ptr_keyword(), odp->ordinal ); fprintf( outfile, "\t%s %d\n", get_asm_ptr_keyword(), odp->ordinal );
} }
fprintf( outfile, " \"\\t%s 0\\n\"\n", get_asm_ptr_keyword() ); fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() );
} }
fprintf( outfile, " \".L__wine_spec_imports_end:\\n\"\n" ); fprintf( outfile, ".L__wine_spec_imports_end:\n" );
for (i = 0; i < nb_imports; i++) for (i = 0; i < nb_imports; i++)
{ {
...@@ -799,10 +799,10 @@ static void output_immediate_imports( FILE *outfile ) ...@@ -799,10 +799,10 @@ static void output_immediate_imports( FILE *outfile )
ORDDEF *odp = dll_imports[i]->imports[j]; ORDDEF *odp = dll_imports[i]->imports[j];
if (!(odp->flags & FLAG_NONAME)) if (!(odp->flags & FLAG_NONAME))
{ {
fprintf( outfile, " \"\\t.align %d\\n\"\n", get_alignment(2) ); fprintf( outfile, "\t.align %d\n", get_alignment(2) );
fprintf( outfile, " \".L__wine_spec_import_data_%s_%s:\\n\"\n", dll_name, odp->name ); fprintf( outfile, ".L__wine_spec_import_data_%s_%s:\n", dll_name, odp->name );
fprintf( outfile, " \"\\t%s %d\\n\"\n", get_asm_short_keyword(), odp->ordinal ); fprintf( outfile, "\t%s %d\n", get_asm_short_keyword(), odp->ordinal );
fprintf( outfile, " \"\\t%s \\\"%s\\\"\\n\"\n", get_asm_string_keyword(), odp->name ); fprintf( outfile, "\t%s \"%s\"\n", get_asm_string_keyword(), odp->name );
} }
} }
} }
...@@ -811,11 +811,9 @@ static void output_immediate_imports( FILE *outfile ) ...@@ -811,11 +811,9 @@ static void output_immediate_imports( FILE *outfile )
{ {
if (dll_imports[i]->delay) continue; if (dll_imports[i]->delay) continue;
dll_name = make_c_identifier( dll_imports[i]->spec->file_name ); dll_name = make_c_identifier( dll_imports[i]->spec->file_name );
fprintf( outfile, " \".L__wine_spec_import_name_%s:\\t%s \\\"%s\\\"\\n\"\n", fprintf( outfile, ".L__wine_spec_import_name_%s:\n\t%s \"%s\"\n",
dll_name, get_asm_string_keyword(), dll_imports[i]->spec->file_name ); dll_name, get_asm_string_keyword(), dll_imports[i]->spec->file_name );
} }
fprintf( outfile, ");\n" );
} }
/* output the import thunks of a Win32 module */ /* output the import thunks of a Win32 module */
...@@ -827,9 +825,10 @@ static void output_immediate_import_thunks( FILE *outfile ) ...@@ -827,9 +825,10 @@ static void output_immediate_import_thunks( FILE *outfile )
if (!nb_imm) return; if (!nb_imm) return;
fprintf( outfile, "/* immediate import thunks */\n" ); fprintf( outfile, "\n/* immediate import thunks */\n\n" );
fprintf( outfile, "asm(\".text\\n\\t.align %d\\n\"\n", get_alignment(8) ); fprintf( outfile, "\t.text\n" );
fprintf( outfile, " \"%s:\\n\"\n", asm_name(import_thunks)); fprintf( outfile, "\t.align %d\n", get_alignment(8) );
fprintf( outfile, "%s:\n", asm_name(import_thunks));
for (i = pos = 0; i < nb_imports; i++) for (i = pos = 0; i < nb_imports; i++)
{ {
...@@ -843,7 +842,6 @@ static void output_immediate_import_thunks( FILE *outfile ) ...@@ -843,7 +842,6 @@ static void output_immediate_import_thunks( FILE *outfile )
pos += get_ptr_size(); pos += get_ptr_size();
} }
output_function_size( outfile, import_thunks ); output_function_size( outfile, import_thunks );
fprintf( outfile, ");\n" );
} }
/* output the delayed import table of a Win32 module */ /* output the delayed import table of a Win32 module */
...@@ -853,40 +851,41 @@ static void output_delayed_imports( FILE *outfile, const DLLSPEC *spec ) ...@@ -853,40 +851,41 @@ static void output_delayed_imports( FILE *outfile, const DLLSPEC *spec )
if (!nb_delayed) return; if (!nb_delayed) return;
fprintf( outfile, "/* delayed imports */\n" ); fprintf( outfile, "\n/* delayed imports */\n\n" );
fprintf( outfile, "asm(\".data\\n\\t.align %d\\n\"\n", get_alignment(get_ptr_size()) ); fprintf( outfile, "\t.data\n" );
fprintf( outfile, " \"\\t.globl %s\\n\"\n", asm_name("__wine_spec_delay_imports") ); fprintf( outfile, "\t.align %d\n", get_alignment(get_ptr_size()) );
fprintf( outfile, " \"%s:\\n\"\n", asm_name("__wine_spec_delay_imports")); fprintf( outfile, "\t.globl %s\n", asm_name("__wine_spec_delay_imports") );
fprintf( outfile, "%s:\n", asm_name("__wine_spec_delay_imports"));
/* list of dlls */ /* list of dlls */
for (i = j = 0; i < nb_imports; i++) for (i = j = 0; i < nb_imports; i++)
{ {
if (!dll_imports[i]->delay) continue; if (!dll_imports[i]->delay) continue;
fprintf( outfile, " \"\\t%s 0\\n\"\n", get_asm_ptr_keyword() ); /* grAttrs */ fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() ); /* grAttrs */
fprintf( outfile, " \"\\t%s .L__wine_delay_name_%d\\n\"\n", /* szName */ fprintf( outfile, "\t%s .L__wine_delay_name_%d\n", /* szName */
get_asm_ptr_keyword(), i ); get_asm_ptr_keyword(), i );
fprintf( outfile, " \"\\t%s .L__wine_delay_modules+%d\\n\"\n", /* phmod */ fprintf( outfile, "\t%s .L__wine_delay_modules+%d\n", /* phmod */
get_asm_ptr_keyword(), i * get_ptr_size() ); get_asm_ptr_keyword(), i * get_ptr_size() );
fprintf( outfile, " \"\\t%s .L__wine_delay_IAT+%d\\n\"\n", /* pIAT */ fprintf( outfile, "\t%s .L__wine_delay_IAT+%d\n", /* pIAT */
get_asm_ptr_keyword(), j * get_ptr_size() ); get_asm_ptr_keyword(), j * get_ptr_size() );
fprintf( outfile, " \"\\t%s .L__wine_delay_INT+%d\\n\"\n", /* pINT */ fprintf( outfile, "\t%s .L__wine_delay_INT+%d\n", /* pINT */
get_asm_ptr_keyword(), j * get_ptr_size() ); get_asm_ptr_keyword(), j * get_ptr_size() );
fprintf( outfile, " \"\\t%s 0\\n\"\n", get_asm_ptr_keyword() ); /* pBoundIAT */ fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() ); /* pBoundIAT */
fprintf( outfile, " \"\\t%s 0\\n\"\n", get_asm_ptr_keyword() ); /* pUnloadIAT */ fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() ); /* pUnloadIAT */
fprintf( outfile, " \"\\t%s 0\\n\"\n", get_asm_ptr_keyword() ); /* dwTimeStamp */ fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() ); /* dwTimeStamp */
j += dll_imports[i]->nb_imports; j += dll_imports[i]->nb_imports;
} }
fprintf( outfile, " \"\\t%s 0\\n\"\n", get_asm_ptr_keyword() ); /* grAttrs */ fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() ); /* grAttrs */
fprintf( outfile, " \"\\t%s 0\\n\"\n", get_asm_ptr_keyword() ); /* szName */ fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() ); /* szName */
fprintf( outfile, " \"\\t%s 0\\n\"\n", get_asm_ptr_keyword() ); /* phmod */ fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() ); /* phmod */
fprintf( outfile, " \"\\t%s 0\\n\"\n", get_asm_ptr_keyword() ); /* pIAT */ fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() ); /* pIAT */
fprintf( outfile, " \"\\t%s 0\\n\"\n", get_asm_ptr_keyword() ); /* pINT */ fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() ); /* pINT */
fprintf( outfile, " \"\\t%s 0\\n\"\n", get_asm_ptr_keyword() ); /* pBoundIAT */ fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() ); /* pBoundIAT */
fprintf( outfile, " \"\\t%s 0\\n\"\n", get_asm_ptr_keyword() ); /* pUnloadIAT */ fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() ); /* pUnloadIAT */
fprintf( outfile, " \"\\t%s 0\\n\"\n", get_asm_ptr_keyword() ); /* dwTimeStamp */ fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() ); /* dwTimeStamp */
fprintf( outfile, " \".L__wine_delay_IAT:\\n\"\n" ); fprintf( outfile, "\n.L__wine_delay_IAT:\n" );
for (i = 0; i < nb_imports; i++) for (i = 0; i < nb_imports; i++)
{ {
if (!dll_imports[i]->delay) continue; if (!dll_imports[i]->delay) continue;
...@@ -894,12 +893,12 @@ static void output_delayed_imports( FILE *outfile, const DLLSPEC *spec ) ...@@ -894,12 +893,12 @@ static void output_delayed_imports( FILE *outfile, const DLLSPEC *spec )
{ {
ORDDEF *odp = dll_imports[i]->imports[j]; ORDDEF *odp = dll_imports[i]->imports[j];
const char *name = odp->name ? odp->name : odp->export_name; const char *name = odp->name ? odp->name : odp->export_name;
fprintf( outfile, " \"\\t%s .L__wine_delay_imp_%d_%s\\n\"\n", fprintf( outfile, "\t%s .L__wine_delay_imp_%d_%s\n",
get_asm_ptr_keyword(), i, name ); get_asm_ptr_keyword(), i, name );
} }
} }
fprintf( outfile, " \".L__wine_delay_INT:\\n\"\n" ); fprintf( outfile, "\n.L__wine_delay_INT:\n" );
for (i = 0; i < nb_imports; i++) for (i = 0; i < nb_imports; i++)
{ {
if (!dll_imports[i]->delay) continue; if (!dll_imports[i]->delay) continue;
...@@ -907,24 +906,24 @@ static void output_delayed_imports( FILE *outfile, const DLLSPEC *spec ) ...@@ -907,24 +906,24 @@ static void output_delayed_imports( FILE *outfile, const DLLSPEC *spec )
{ {
ORDDEF *odp = dll_imports[i]->imports[j]; ORDDEF *odp = dll_imports[i]->imports[j];
if (!odp->name) if (!odp->name)
fprintf( outfile, " \"\\t%s %d\\n\"\n", get_asm_ptr_keyword(), odp->ordinal ); fprintf( outfile, "\t%s %d\n", get_asm_ptr_keyword(), odp->ordinal );
else else
fprintf( outfile, " \"\\t%s .L__wine_delay_data_%d_%s\\n\"\n", fprintf( outfile, "\t%s .L__wine_delay_data_%d_%s\n",
get_asm_ptr_keyword(), i, odp->name ); get_asm_ptr_keyword(), i, odp->name );
} }
} }
fprintf( outfile, " \".L__wine_delay_modules:\\n\"\n" ); fprintf( outfile, "\n.L__wine_delay_modules:\n" );
for (i = 0; i < nb_imports; i++) for (i = 0; i < nb_imports; i++)
{ {
if (dll_imports[i]->delay) fprintf( outfile, " \"\\t%s 0\\n\"\n", get_asm_ptr_keyword() ); if (dll_imports[i]->delay) fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() );
} }
for (i = 0; i < nb_imports; i++) for (i = 0; i < nb_imports; i++)
{ {
if (!dll_imports[i]->delay) continue; if (!dll_imports[i]->delay) continue;
fprintf( outfile, " \".L__wine_delay_name_%d:\\n\"\n", i ); fprintf( outfile, ".L__wine_delay_name_%d:\n", i );
fprintf( outfile, " \"\\t%s \\\"%s\\\"\\n\"\n", fprintf( outfile, "\t%s \"%s\"\n",
get_asm_string_keyword(), dll_imports[i]->spec->file_name ); get_asm_string_keyword(), dll_imports[i]->spec->file_name );
} }
...@@ -935,12 +934,11 @@ static void output_delayed_imports( FILE *outfile, const DLLSPEC *spec ) ...@@ -935,12 +934,11 @@ static void output_delayed_imports( FILE *outfile, const DLLSPEC *spec )
{ {
ORDDEF *odp = dll_imports[i]->imports[j]; ORDDEF *odp = dll_imports[i]->imports[j];
if (!odp->name) continue; if (!odp->name) continue;
fprintf( outfile, " \".L__wine_delay_data_%d_%s:\\n\"\n", i, odp->name ); fprintf( outfile, ".L__wine_delay_data_%d_%s:\n", i, odp->name );
fprintf( outfile, " \"\\t%s \\\"%s\\\"\\n\"\n", get_asm_string_keyword(), odp->name ); fprintf( outfile, "\t%s \"%s\"\n", get_asm_string_keyword(), odp->name );
} }
} }
output_function_size( outfile, "__wine_spec_delay_imports" ); output_function_size( outfile, "__wine_spec_delay_imports" );
fprintf( outfile, ");\n" );
} }
/* output the delayed import thunks of a Win32 module */ /* output the delayed import thunks of a Win32 module */
...@@ -952,81 +950,87 @@ static void output_delayed_import_thunks( FILE *outfile, const DLLSPEC *spec ) ...@@ -952,81 +950,87 @@ static void output_delayed_import_thunks( FILE *outfile, const DLLSPEC *spec )
if (!nb_delayed) return; if (!nb_delayed) return;
fprintf( outfile, "/* delayed import thunks */\n" ); fprintf( outfile, "\n/* delayed import thunks */\n\n" );
fprintf( outfile, "asm(\".text\\n\"\n" ); fprintf( outfile, "\t.text\n" );
fprintf( outfile, " \"\\t.align %d\\n\"\n", get_alignment(8) ); fprintf( outfile, "\t.align %d\n", get_alignment(8) );
fprintf( outfile, " \"%s:\\n\"\n", asm_name(delayed_import_loaders)); fprintf( outfile, "%s:\n", asm_name(delayed_import_loaders));
fprintf( outfile, " \"\\t%s\\n\"\n", func_declaration("__wine_delay_load_asm") ); fprintf( outfile, "\t%s\n", func_declaration("__wine_delay_load_asm") );
fprintf( outfile, " \"%s:\\n\"\n", asm_name("__wine_delay_load_asm") ); fprintf( outfile, "%s:\n", asm_name("__wine_delay_load_asm") );
switch(target_cpu) switch(target_cpu)
{ {
case CPU_x86_64: /* FIXME */ case CPU_x86_64: /* FIXME */
case CPU_x86: case CPU_x86:
fprintf( outfile, " \"\\tpushl %%ecx\\n\\tpushl %%edx\\n\\tpushl %%eax\\n\"\n" ); fprintf( outfile, "\tpushl %%ecx\n" );
fprintf( outfile, " \"\\tcall %s\\n\"\n", asm_name("__wine_spec_delay_load") ); fprintf( outfile, "\tpushl %%edx\n" );
fprintf( outfile, " \"\\tpopl %%edx\\n\\tpopl %%ecx\\n\\tjmp *%%eax\\n\"\n" ); fprintf( outfile, "\tpushl %%eax\n" );
fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_delay_load") );
fprintf( outfile, "\tpopl %%edx\n" );
fprintf( outfile, "\tpopl %%ecx\n" );
fprintf( outfile, "\tjmp *%%eax\n" );
break; break;
case CPU_SPARC: case CPU_SPARC:
fprintf( outfile, " \"\\tsave %%sp, -96, %%sp\\n\"\n" ); fprintf( outfile, "\tsave %%sp, -96, %%sp\n" );
fprintf( outfile, " \"\\tcall %s\\n\"\n", asm_name("__wine_spec_delay_load") ); fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_delay_load") );
fprintf( outfile, " \"\\tmov %%g1, %%o0\\n\"\n" ); fprintf( outfile, "\tmov %%g1, %%o0\n" );
fprintf( outfile, " \"\\tjmp %%o0\\n\\trestore\\n\"\n" ); fprintf( outfile, "\tjmp %%o0\n" );
fprintf( outfile, "\trestore\n" );
break; break;
case CPU_ALPHA: case CPU_ALPHA:
fprintf( outfile, " \"\\tjsr $26,%s\\n\"\n", asm_name("__wine_spec_delay_load") ); fprintf( outfile, "\tjsr $26,%s\n", asm_name("__wine_spec_delay_load") );
fprintf( outfile, " \"\\tjmp $31,($0)\\n\"\n" ); fprintf( outfile, "\tjmp $31,($0)\n" );
break; break;
case CPU_POWERPC: case CPU_POWERPC:
if (target_platform == PLATFORM_APPLE) extra_stack_storage = 56; if (target_platform == PLATFORM_APPLE) extra_stack_storage = 56;
/* Save all callee saved registers into a stackframe. */ /* Save all callee saved registers into a stackframe. */
fprintf( outfile, " \"\\tstwu %s, -%d(%s)\\n\"\n",ppc_reg(1), 48+extra_stack_storage, ppc_reg(1)); fprintf( outfile, "\tstwu %s, -%d(%s)\n",ppc_reg(1), 48+extra_stack_storage, ppc_reg(1));
fprintf( outfile, " \"\\tstw %s, %d(%s)\\n\"\n", ppc_reg(3), 4+extra_stack_storage, ppc_reg(1)); fprintf( outfile, "\tstw %s, %d(%s)\n", ppc_reg(3), 4+extra_stack_storage, ppc_reg(1));
fprintf( outfile, " \"\\tstw %s, %d(%s)\\n\"\n", ppc_reg(4), 8+extra_stack_storage, ppc_reg(1)); fprintf( outfile, "\tstw %s, %d(%s)\n", ppc_reg(4), 8+extra_stack_storage, ppc_reg(1));
fprintf( outfile, " \"\\tstw %s, %d(%s)\\n\"\n", ppc_reg(5), 12+extra_stack_storage, ppc_reg(1)); fprintf( outfile, "\tstw %s, %d(%s)\n", ppc_reg(5), 12+extra_stack_storage, ppc_reg(1));
fprintf( outfile, " \"\\tstw %s, %d(%s)\\n\"\n", ppc_reg(6), 16+extra_stack_storage, ppc_reg(1)); fprintf( outfile, "\tstw %s, %d(%s)\n", ppc_reg(6), 16+extra_stack_storage, ppc_reg(1));
fprintf( outfile, " \"\\tstw %s, %d(%s)\\n\"\n", ppc_reg(7), 20+extra_stack_storage, ppc_reg(1)); fprintf( outfile, "\tstw %s, %d(%s)\n", ppc_reg(7), 20+extra_stack_storage, ppc_reg(1));
fprintf( outfile, " \"\\tstw %s, %d(%s)\\n\"\n", ppc_reg(8), 24+extra_stack_storage, ppc_reg(1)); fprintf( outfile, "\tstw %s, %d(%s)\n", ppc_reg(8), 24+extra_stack_storage, ppc_reg(1));
fprintf( outfile, " \"\\tstw %s, %d(%s)\\n\"\n", ppc_reg(9), 28+extra_stack_storage, ppc_reg(1)); fprintf( outfile, "\tstw %s, %d(%s)\n", ppc_reg(9), 28+extra_stack_storage, ppc_reg(1));
fprintf( outfile, " \"\\tstw %s, %d(%s)\\n\"\n", ppc_reg(10),32+extra_stack_storage, ppc_reg(1)); fprintf( outfile, "\tstw %s, %d(%s)\n", ppc_reg(10),32+extra_stack_storage, ppc_reg(1));
fprintf( outfile, " \"\\tstw %s, %d(%s)\\n\"\n", ppc_reg(11),36+extra_stack_storage, ppc_reg(1)); fprintf( outfile, "\tstw %s, %d(%s)\n", ppc_reg(11),36+extra_stack_storage, ppc_reg(1));
fprintf( outfile, " \"\\tstw %s, %d(%s)\\n\"\n", ppc_reg(12),40+extra_stack_storage, ppc_reg(1)); fprintf( outfile, "\tstw %s, %d(%s)\n", ppc_reg(12),40+extra_stack_storage, ppc_reg(1));
/* r0 -> r3 (arg1) */ /* r0 -> r3 (arg1) */
fprintf( outfile, " \"\\tmr %s, %s\\n\"\n", ppc_reg(3), ppc_reg(0)); fprintf( outfile, "\tmr %s, %s\n", ppc_reg(3), ppc_reg(0));
/* save return address */ /* save return address */
fprintf( outfile, " \"\\tmflr %s\\n\"\n", ppc_reg(0)); fprintf( outfile, "\tmflr %s\n", ppc_reg(0));
fprintf( outfile, " \"\\tstw %s, %d(%s)\\n\"\n", ppc_reg(0), 44+extra_stack_storage, ppc_reg(1)); fprintf( outfile, "\tstw %s, %d(%s)\n", ppc_reg(0), 44+extra_stack_storage, ppc_reg(1));
/* Call the __wine_delay_load function, arg1 is arg1. */ /* Call the __wine_delay_load function, arg1 is arg1. */
fprintf( outfile, " \"\\tbl %s\\n\"\n", asm_name("__wine_spec_delay_load") ); fprintf( outfile, "\tbl %s\n", asm_name("__wine_spec_delay_load") );
/* Load return value from call into ctr register */ /* Load return value from call into ctr register */
fprintf( outfile, " \"\\tmtctr %s\\n\"\n", ppc_reg(3)); fprintf( outfile, "\tmtctr %s\n", ppc_reg(3));
/* restore all saved registers and drop stackframe. */ /* restore all saved registers and drop stackframe. */
fprintf( outfile, " \"\\tlwz %s, %d(%s)\\n\"\n", ppc_reg(3), 4+extra_stack_storage, ppc_reg(1)); fprintf( outfile, "\tlwz %s, %d(%s)\n", ppc_reg(3), 4+extra_stack_storage, ppc_reg(1));
fprintf( outfile, " \"\\tlwz %s, %d(%s)\\n\"\n", ppc_reg(4), 8+extra_stack_storage, ppc_reg(1)); fprintf( outfile, "\tlwz %s, %d(%s)\n", ppc_reg(4), 8+extra_stack_storage, ppc_reg(1));
fprintf( outfile, " \"\\tlwz %s, %d(%s)\\n\"\n", ppc_reg(5), 12+extra_stack_storage, ppc_reg(1)); fprintf( outfile, "\tlwz %s, %d(%s)\n", ppc_reg(5), 12+extra_stack_storage, ppc_reg(1));
fprintf( outfile, " \"\\tlwz %s, %d(%s)\\n\"\n", ppc_reg(6), 16+extra_stack_storage, ppc_reg(1)); fprintf( outfile, "\tlwz %s, %d(%s)\n", ppc_reg(6), 16+extra_stack_storage, ppc_reg(1));
fprintf( outfile, " \"\\tlwz %s, %d(%s)\\n\"\n", ppc_reg(7), 20+extra_stack_storage, ppc_reg(1)); fprintf( outfile, "\tlwz %s, %d(%s)\n", ppc_reg(7), 20+extra_stack_storage, ppc_reg(1));
fprintf( outfile, " \"\\tlwz %s, %d(%s)\\n\"\n", ppc_reg(8), 24+extra_stack_storage, ppc_reg(1)); fprintf( outfile, "\tlwz %s, %d(%s)\n", ppc_reg(8), 24+extra_stack_storage, ppc_reg(1));
fprintf( outfile, " \"\\tlwz %s, %d(%s)\\n\"\n", ppc_reg(9), 28+extra_stack_storage, ppc_reg(1)); fprintf( outfile, "\tlwz %s, %d(%s)\n", ppc_reg(9), 28+extra_stack_storage, ppc_reg(1));
fprintf( outfile, " \"\\tlwz %s, %d(%s)\\n\"\n", ppc_reg(10),32+extra_stack_storage, ppc_reg(1)); fprintf( outfile, "\tlwz %s, %d(%s)\n", ppc_reg(10),32+extra_stack_storage, ppc_reg(1));
fprintf( outfile, " \"\\tlwz %s, %d(%s)\\n\"\n", ppc_reg(11),36+extra_stack_storage, ppc_reg(1)); fprintf( outfile, "\tlwz %s, %d(%s)\n", ppc_reg(11),36+extra_stack_storage, ppc_reg(1));
fprintf( outfile, " \"\\tlwz %s, %d(%s)\\n\"\n", ppc_reg(12),40+extra_stack_storage, ppc_reg(1)); fprintf( outfile, "\tlwz %s, %d(%s)\n", ppc_reg(12),40+extra_stack_storage, ppc_reg(1));
/* Load return value from call into return register */ /* Load return value from call into return register */
fprintf( outfile, " \"\\tlwz %s, %d(%s)\\n\"\n", ppc_reg(0), 44+extra_stack_storage, ppc_reg(1)); fprintf( outfile, "\tlwz %s, %d(%s)\n", ppc_reg(0), 44+extra_stack_storage, ppc_reg(1));
fprintf( outfile, " \"\\tmtlr %s\\n\"\n", ppc_reg(0)); fprintf( outfile, "\tmtlr %s\n", ppc_reg(0));
fprintf( outfile, " \"\\taddi %s, %s, %d\\n\"\n", ppc_reg(1), ppc_reg(1), 48+extra_stack_storage); fprintf( outfile, "\taddi %s, %s, %d\n", ppc_reg(1), ppc_reg(1), 48+extra_stack_storage);
/* branch to ctr register. */ /* branch to ctr register. */
fprintf( outfile, " \"bctr\\n\"\n"); fprintf( outfile, "\tbctr\n");
break; break;
} }
output_function_size( outfile, "__wine_delay_load_asm" ); output_function_size( outfile, "__wine_delay_load_asm" );
fprintf( outfile, "\n" );
for (i = idx = 0; i < nb_imports; i++) for (i = idx = 0; i < nb_imports; i++)
{ {
...@@ -1036,22 +1040,22 @@ static void output_delayed_import_thunks( FILE *outfile, const DLLSPEC *spec ) ...@@ -1036,22 +1040,22 @@ static void output_delayed_import_thunks( FILE *outfile, const DLLSPEC *spec )
ORDDEF *odp = dll_imports[i]->imports[j]; ORDDEF *odp = dll_imports[i]->imports[j];
const char *name = odp->name ? odp->name : odp->export_name; const char *name = odp->name ? odp->name : odp->export_name;
fprintf( outfile, " \".L__wine_delay_imp_%d_%s:\\n\"\n", i, name ); fprintf( outfile, ".L__wine_delay_imp_%d_%s:\n", i, name );
switch(target_cpu) switch(target_cpu)
{ {
case CPU_x86_64: /* FIXME */ case CPU_x86_64: /* FIXME */
case CPU_x86: case CPU_x86:
fprintf( outfile, " \"\\tmovl $%d, %%eax\\n\"\n", (idx << 16) | j ); fprintf( outfile, "\tmovl $%d, %%eax\n", (idx << 16) | j );
fprintf( outfile, " \"\\tjmp %s\\n\"\n", asm_name("__wine_delay_load_asm") ); fprintf( outfile, "\tjmp %s\n", asm_name("__wine_delay_load_asm") );
break; break;
case CPU_SPARC: case CPU_SPARC:
fprintf( outfile, " \"\\tset %d, %%g1\\n\"\n", (idx << 16) | j ); fprintf( outfile, "\tset %d, %%g1\n", (idx << 16) | j );
fprintf( outfile, " \"\\tb,a %s\\n\"\n", asm_name("__wine_delay_load_asm") ); fprintf( outfile, "\tb,a %s\n", asm_name("__wine_delay_load_asm") );
break; break;
case CPU_ALPHA: case CPU_ALPHA:
fprintf( outfile, " \"\\tlda $0,%d($31)\\n\"\n", j); fprintf( outfile, "\tlda $0,%d($31)\n", j);
fprintf( outfile, " \"\\tldah $0,%d($0)\\n\"\n", idx); fprintf( outfile, "\tldah $0,%d($0)\n", idx);
fprintf( outfile, " \"\\tjmp $31,%s\\n\"\n", asm_name("__wine_delay_load_asm") ); fprintf( outfile, "\tjmp $31,%s\n", asm_name("__wine_delay_load_asm") );
break; break;
case CPU_POWERPC: case CPU_POWERPC:
switch(target_platform) switch(target_platform)
...@@ -1059,24 +1063,24 @@ static void output_delayed_import_thunks( FILE *outfile, const DLLSPEC *spec ) ...@@ -1059,24 +1063,24 @@ static void output_delayed_import_thunks( FILE *outfile, const DLLSPEC *spec )
case PLATFORM_APPLE: case PLATFORM_APPLE:
/* On Darwin we can use r0 and r2 */ /* On Darwin we can use r0 and r2 */
/* Upper part in r2 */ /* Upper part in r2 */
fprintf( outfile, " \"\\tlis %s, %d\\n\"\n", ppc_reg(2), idx); fprintf( outfile, "\tlis %s, %d\n", ppc_reg(2), idx);
/* Lower part + r2 -> r0, Note we can't use r0 directly */ /* Lower part + r2 -> r0, Note we can't use r0 directly */
fprintf( outfile, " \"\\taddi %s, %s, %d\\n\"\n", ppc_reg(0), ppc_reg(2), j); fprintf( outfile, "\taddi %s, %s, %d\n", ppc_reg(0), ppc_reg(2), j);
fprintf( outfile, " \"\\tb %s\\n\"\n", asm_name("__wine_delay_load_asm") ); fprintf( outfile, "\tb %s\n", asm_name("__wine_delay_load_asm") );
break; break;
default: default:
/* On linux we can't use r2 since r2 is not a scratch register (hold the TOC) */ /* On linux we can't use r2 since r2 is not a scratch register (hold the TOC) */
/* Save r13 on the stack */ /* Save r13 on the stack */
fprintf( outfile, " \"\\taddi %s, %s, -0x4\\n\"\n", ppc_reg(1), ppc_reg(1)); fprintf( outfile, "\taddi %s, %s, -0x4\n", ppc_reg(1), ppc_reg(1));
fprintf( outfile, " \"\\tstw %s, 0(%s)\\n\"\n", ppc_reg(13), ppc_reg(1)); fprintf( outfile, "\tstw %s, 0(%s)\n", ppc_reg(13), ppc_reg(1));
/* Upper part in r13 */ /* Upper part in r13 */
fprintf( outfile, " \"\\tlis %s, %d\\n\"\n", ppc_reg(13), idx); fprintf( outfile, "\tlis %s, %d\n", ppc_reg(13), idx);
/* Lower part + r13 -> r0, Note we can't use r0 directly */ /* Lower part + r13 -> r0, Note we can't use r0 directly */
fprintf( outfile, " \"\\taddi %s, %s, %d\\n\"\n", ppc_reg(0), ppc_reg(13), j); fprintf( outfile, "\taddi %s, %s, %d\n", ppc_reg(0), ppc_reg(13), j);
/* Restore r13 */ /* Restore r13 */
fprintf( outfile, " \"\\tstw %s, 0(%s)\\n\"\n", ppc_reg(13), ppc_reg(1)); fprintf( outfile, "\tstw %s, 0(%s)\n", ppc_reg(13), ppc_reg(1));
fprintf( outfile, " \"\\taddic %s, %s, 0x4\\n\"\n", ppc_reg(1), ppc_reg(1)); fprintf( outfile, "\taddic %s, %s, 0x4\n", ppc_reg(1), ppc_reg(1));
fprintf( outfile, " \"\\tb %s\\n\"\n", asm_name("__wine_delay_load_asm") ); fprintf( outfile, "\tb %s\n", asm_name("__wine_delay_load_asm") );
break; break;
} }
break; break;
...@@ -1086,8 +1090,8 @@ static void output_delayed_import_thunks( FILE *outfile, const DLLSPEC *spec ) ...@@ -1086,8 +1090,8 @@ static void output_delayed_import_thunks( FILE *outfile, const DLLSPEC *spec )
} }
output_function_size( outfile, delayed_import_loaders ); output_function_size( outfile, delayed_import_loaders );
fprintf( outfile, "\n \".align %d\\n\"\n", get_alignment(8) ); fprintf( outfile, "\n\t.align %d\n", get_alignment(get_ptr_size()) );
fprintf( outfile, " \"%s:\\n\"\n", asm_name(delayed_import_thunks)); fprintf( outfile, "%s:\n", asm_name(delayed_import_thunks));
for (i = pos = 0; i < nb_imports; i++) for (i = pos = 0; i < nb_imports; i++)
{ {
if (!dll_imports[i]->delay) continue; if (!dll_imports[i]->delay) continue;
...@@ -1099,7 +1103,6 @@ static void output_delayed_import_thunks( FILE *outfile, const DLLSPEC *spec ) ...@@ -1099,7 +1103,6 @@ static void output_delayed_import_thunks( FILE *outfile, const DLLSPEC *spec )
} }
} }
output_function_size( outfile, delayed_import_thunks ); output_function_size( outfile, delayed_import_thunks );
fprintf( outfile, ");\n" );
} }
/* output the import and delayed import tables of a Win32 module */ /* output the import and delayed import tables of a Win32 module */
......
...@@ -319,9 +319,9 @@ static void free_resource_tree( struct res_tree *tree ) ...@@ -319,9 +319,9 @@ static void free_resource_tree( struct res_tree *tree )
static void output_string( FILE *outfile, const WCHAR *name ) static void output_string( FILE *outfile, const WCHAR *name )
{ {
int i, len = strlenW(name); int i, len = strlenW(name);
fprintf( outfile, " \"\\t%s 0x%04x", get_asm_short_keyword(), len ); fprintf( outfile, "\t%s 0x%04x", get_asm_short_keyword(), len );
for (i = 0; i < len; i++) fprintf( outfile, ",0x%04x", name[i] ); for (i = 0; i < len; i++) fprintf( outfile, ",0x%04x", name[i] );
fprintf( outfile, "\\n\" /* " ); fprintf( outfile, " /* " );
for (i = 0; i < len; i++) fprintf( outfile, "%c", isprint((char)name[i]) ? (char)name[i] : '?' ); for (i = 0; i < len; i++) fprintf( outfile, "%c", isprint((char)name[i]) ? (char)name[i] : '?' );
fprintf( outfile, " */\n" ); fprintf( outfile, " */\n" );
} }
...@@ -329,11 +329,11 @@ static void output_string( FILE *outfile, const WCHAR *name ) ...@@ -329,11 +329,11 @@ static void output_string( FILE *outfile, const WCHAR *name )
/* output a resource directory */ /* output a resource directory */
static inline void output_res_dir( FILE *outfile, unsigned int nb_names, unsigned int nb_ids ) static inline void output_res_dir( FILE *outfile, unsigned int nb_names, unsigned int nb_ids )
{ {
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* Characteristics */ fprintf( outfile, "\t.long 0\n" ); /* Characteristics */
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* TimeDateStamp */ fprintf( outfile, "\t.long 0\n" ); /* TimeDateStamp */
fprintf( outfile, " \"\\t%s 0,0\\n\"\n", /* Major/MinorVersion */ fprintf( outfile, "\t%s 0,0\n", /* Major/MinorVersion */
get_asm_short_keyword() ); get_asm_short_keyword() );
fprintf( outfile, " \"\\t%s %u,%u\\n\"\n", /* NumberOfNamed/IdEntries */ fprintf( outfile, "\t%s %u,%u\n", /* NumberOfNamed/IdEntries */
get_asm_short_keyword(), nb_names, nb_ids ); get_asm_short_keyword(), nb_names, nb_ids );
} }
...@@ -388,8 +388,10 @@ void output_resources( FILE *outfile, DLLSPEC *spec ) ...@@ -388,8 +388,10 @@ void output_resources( FILE *outfile, DLLSPEC *spec )
/* output the resource directories */ /* output the resource directories */
fprintf( outfile, "asm(\".data\\n\\t.align %d\\n\"\n", get_alignment(get_ptr_size()) ); fprintf( outfile, "\n/* resources */\n\n" );
fprintf( outfile, " \".L__wine_spec_resources:\\n\"\n" ); fprintf( outfile, "\t.data\n" );
fprintf( outfile, "\t.align %d\n", get_alignment(get_ptr_size()) );
fprintf( outfile, ".L__wine_spec_resources:\n" );
output_res_dir( outfile, tree->nb_types - nb_id_types, nb_id_types ); output_res_dir( outfile, tree->nb_types - nb_id_types, nb_id_types );
...@@ -398,7 +400,7 @@ void output_resources( FILE *outfile, DLLSPEC *spec ) ...@@ -398,7 +400,7 @@ void output_resources( FILE *outfile, DLLSPEC *spec )
offset = RESDIR_SIZE( tree->nb_types ); offset = RESDIR_SIZE( tree->nb_types );
for (i = 0, type = tree->types; i < tree->nb_types; i++, type++) for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
{ {
fprintf( outfile, " \"\\t.long 0x%08x,0x%08x\\n\"\n", fprintf( outfile, "\t.long 0x%08x,0x%08x\n",
type->name_offset, offset | 0x80000000 ); type->name_offset, offset | 0x80000000 );
offset += RESDIR_SIZE( type->nb_names ); offset += RESDIR_SIZE( type->nb_names );
for (n = 0, name = type->names; n < type->nb_names; n++, name++) for (n = 0, name = type->names; n < type->nb_names; n++, name++)
...@@ -416,7 +418,7 @@ void output_resources( FILE *outfile, DLLSPEC *spec ) ...@@ -416,7 +418,7 @@ void output_resources( FILE *outfile, DLLSPEC *spec )
offset += RESDIR_SIZE( type->nb_names ); offset += RESDIR_SIZE( type->nb_names );
for (n = 0, name = type->names; n < type->nb_names; n++, name++) for (n = 0, name = type->names; n < type->nb_names; n++, name++)
{ {
fprintf( outfile, " \"\\t.long 0x%08x,0x%08x\\n\"\n", fprintf( outfile, "\t.long 0x%08x,0x%08x\n",
name->name_offset, offset | 0x80000000 ); name->name_offset, offset | 0x80000000 );
offset += RESDIR_SIZE( name->nb_languages ); offset += RESDIR_SIZE( name->nb_languages );
} }
...@@ -426,7 +428,7 @@ void output_resources( FILE *outfile, DLLSPEC *spec ) ...@@ -426,7 +428,7 @@ void output_resources( FILE *outfile, DLLSPEC *spec )
output_res_dir( outfile, 0, name->nb_languages ); output_res_dir( outfile, 0, name->nb_languages );
for (k = 0, res = name->res; k < name->nb_languages; k++, res++) for (k = 0, res = name->res; k < name->nb_languages; k++, res++)
{ {
fprintf( outfile, " \"\\t.long 0x%08x,0x%08x\\n\"\n", res->lang, fprintf( outfile, "\t.long 0x%08x,0x%08x\n", res->lang,
data_offset + (res - spec->resources) * sizeof(IMAGE_RESOURCE_DATA_ENTRY) ); data_offset + (res - spec->resources) * sizeof(IMAGE_RESOURCE_DATA_ENTRY) );
} }
} }
...@@ -435,7 +437,7 @@ void output_resources( FILE *outfile, DLLSPEC *spec ) ...@@ -435,7 +437,7 @@ void output_resources( FILE *outfile, DLLSPEC *spec )
/* dump the resource data entries */ /* dump the resource data entries */
for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++) for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++)
fprintf( outfile, " \"\\t.long .L__wine_spec_res_%d,%u,0,0\\n\"\n", fprintf( outfile, "\t.long .L__wine_spec_res_%d,%u,0,0\n",
i, res->data_size ); i, res->data_size );
/* dump the name strings */ /* dump the name strings */
...@@ -446,28 +448,24 @@ void output_resources( FILE *outfile, DLLSPEC *spec ) ...@@ -446,28 +448,24 @@ void output_resources( FILE *outfile, DLLSPEC *spec )
for (n = 0, name = type->names; n < type->nb_names; n++, name++) for (n = 0, name = type->names; n < type->nb_names; n++, name++)
if (name->name->str) output_string( outfile, name->name->str ); if (name->name->str) output_string( outfile, name->name->str );
} }
fprintf( outfile, ");\n" );
/* resource data */ /* resource data */
for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++) for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++)
{ {
const unsigned char *p = res->data; const unsigned char *p = res->data;
fprintf( outfile, "asm(\".data\\n\\t.align %d\\n\"\n", get_alignment(get_ptr_size()) ); fprintf( outfile, "\n\t.align %d\n", get_alignment(get_ptr_size()) );
fprintf( outfile, " \".L__wine_spec_res_%d:\\n\"\n", i ); fprintf( outfile, ".L__wine_spec_res_%d:\n", i );
fprintf( outfile, " \"\\t.byte " ); fprintf( outfile, "\t.byte " );
for (j = 0; j < res->data_size - 1; j++, p++) for (j = 0; j < res->data_size - 1; j++, p++)
{ {
if ((j % 16) == 15) fprintf( outfile, "0x%02x\\n\"\n \"\\t.byte ", *p ); if ((j % 16) == 15) fprintf( outfile, "0x%02x\n\t.byte ", *p );
else fprintf( outfile, "0x%02x,", *p ); else fprintf( outfile, "0x%02x,", *p );
} }
fprintf( outfile, "0x%02x\\n\"\n", *p ); fprintf( outfile, "0x%02x\n", *p );
fprintf( outfile, ");\n" );
} }
fprintf( outfile, "asm(\".data\\n\"\n" ); fprintf( outfile, ".L__wine_spec_resources_end:\n" );
fprintf( outfile, " \".L__wine_spec_resources_end:\\n\"\n" ); fprintf( outfile, "\t.byte 0\n" );
fprintf( outfile, " \"\\t.byte 0\\n\"\n" );
fprintf( outfile, ");\n" );
free_resource_tree( tree ); free_resource_tree( tree );
} }
...@@ -107,39 +107,39 @@ static void output_exports( FILE *outfile, DLLSPEC *spec ) ...@@ -107,39 +107,39 @@ static void output_exports( FILE *outfile, DLLSPEC *spec )
if (!nr_exports) return; if (!nr_exports) return;
fprintf( outfile, "/* export table */\n" ); fprintf( outfile, "\n/* export table */\n\n" );
fprintf( outfile, "asm(\".data\\n\"\n" ); fprintf( outfile, "\t.data\n" );
fprintf( outfile, " \"\\t.align %d\\n\"\n", get_alignment(4) ); fprintf( outfile, "\t.align %d\n", get_alignment(4) );
fprintf( outfile, " \".L__wine_spec_exports:\\n\"\n" ); fprintf( outfile, ".L__wine_spec_exports:\n" );
/* export directory header */ /* export directory header */
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* Characteristics */ fprintf( outfile, "\t.long 0\n" ); /* Characteristics */
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* TimeDateStamp */ fprintf( outfile, "\t.long 0\n" ); /* TimeDateStamp */
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* MajorVersion/MinorVersion */ fprintf( outfile, "\t.long 0\n" ); /* MajorVersion/MinorVersion */
fprintf( outfile, " \"\\t.long .L__wine_spec_exp_names\\n\"\n" ); /* Name */ fprintf( outfile, "\t.long .L__wine_spec_exp_names\n" ); /* Name */
fprintf( outfile, " \"\\t.long %d\\n\"\n", spec->base ); /* Base */ fprintf( outfile, "\t.long %d\n", spec->base ); /* Base */
fprintf( outfile, " \"\\t.long %d\\n\"\n", nr_exports ); /* NumberOfFunctions */ fprintf( outfile, "\t.long %d\n", nr_exports ); /* NumberOfFunctions */
fprintf( outfile, " \"\\t.long %d\\n\"\n", spec->nb_names ); /* NumberOfNames */ fprintf( outfile, "\t.long %d\n", spec->nb_names ); /* NumberOfNames */
fprintf( outfile, " \"\\t.long .L__wine_spec_exports_funcs\\n\"\n" ); /* AddressOfFunctions */ fprintf( outfile, "\t.long .L__wine_spec_exports_funcs\n" ); /* AddressOfFunctions */
if (spec->nb_names) if (spec->nb_names)
{ {
fprintf( outfile, " \"\\t.long .L__wine_spec_exp_name_ptrs\\n\"\n" ); /* AddressOfNames */ fprintf( outfile, "\t.long .L__wine_spec_exp_name_ptrs\n" ); /* AddressOfNames */
fprintf( outfile, " \"\\t.long .L__wine_spec_exp_ordinals\\n\"\n" ); /* AddressOfNameOrdinals */ fprintf( outfile, "\t.long .L__wine_spec_exp_ordinals\n" ); /* AddressOfNameOrdinals */
} }
else else
{ {
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* AddressOfNames */ fprintf( outfile, "\t.long 0\n" ); /* AddressOfNames */
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* AddressOfNameOrdinals */ fprintf( outfile, "\t.long 0\n" ); /* AddressOfNameOrdinals */
} }
/* output the function pointers */ /* output the function pointers */
fprintf( outfile, " \".L__wine_spec_exports_funcs:\\n\"\n" ); fprintf( outfile, "\n.L__wine_spec_exports_funcs:\n" );
for (i = spec->base; i <= spec->limit; i++) for (i = spec->base; i <= spec->limit; i++)
{ {
ORDDEF *odp = spec->ordinals[i]; ORDDEF *odp = spec->ordinals[i];
if (!odp) fprintf( outfile, " \"\\t.long 0\\n\"\n" ); if (!odp) fprintf( outfile, "\t.long 0\n" );
else switch(odp->type) else switch(odp->type)
{ {
case TYPE_EXTERN: case TYPE_EXTERN:
...@@ -148,16 +148,16 @@ static void output_exports( FILE *outfile, DLLSPEC *spec ) ...@@ -148,16 +148,16 @@ static void output_exports( FILE *outfile, DLLSPEC *spec )
case TYPE_CDECL: case TYPE_CDECL:
if (!(odp->flags & FLAG_FORWARD)) if (!(odp->flags & FLAG_FORWARD))
{ {
fprintf( outfile, " \"\\t.long %s\\n\"\n", asm_name(odp->link_name) ); fprintf( outfile, "\t.long %s\n", asm_name(odp->link_name) );
} }
else else
{ {
fprintf( outfile, " \"\\t.long .L__wine_spec_forwards+%d\\n\"\n", fwd_size ); fprintf( outfile, "\t.long .L__wine_spec_forwards+%d\n", fwd_size );
fwd_size += strlen(odp->link_name) + 1; fwd_size += strlen(odp->link_name) + 1;
} }
break; break;
case TYPE_STUB: case TYPE_STUB:
fprintf( outfile, " \"\\t.long %s\\n\"\n", fprintf( outfile, "\t.long %s\n",
asm_name( make_internal_name( odp, spec, "stub" )) ); asm_name( make_internal_name( odp, spec, "stub" )) );
break; break;
default: default:
...@@ -171,49 +171,49 @@ static void output_exports( FILE *outfile, DLLSPEC *spec ) ...@@ -171,49 +171,49 @@ static void output_exports( FILE *outfile, DLLSPEC *spec )
int namepos = strlen(spec->file_name) + 1; int namepos = strlen(spec->file_name) + 1;
fprintf( outfile, " \".L__wine_spec_exp_name_ptrs:\\n\"\n" ); fprintf( outfile, "\n.L__wine_spec_exp_name_ptrs:\n" );
for (i = 0; i < spec->nb_names; i++) for (i = 0; i < spec->nb_names; i++)
{ {
fprintf( outfile, " \"\\t.long .L__wine_spec_exp_names+%d\\n\"\n", namepos ); fprintf( outfile, "\t.long .L__wine_spec_exp_names+%d\n", namepos );
namepos += strlen(spec->names[i]->name) + 1; namepos += strlen(spec->names[i]->name) + 1;
} }
/* output the function ordinals */ /* output the function ordinals */
fprintf( outfile, " \".L__wine_spec_exp_ordinals:\\n\"\n" ); fprintf( outfile, "\n.L__wine_spec_exp_ordinals:\n" );
for (i = 0; i < spec->nb_names; i++) for (i = 0; i < spec->nb_names; i++)
{ {
fprintf( outfile, " \"\\t%s %d\\n\"\n", fprintf( outfile, "\t%s %d\n",
get_asm_short_keyword(), spec->names[i]->ordinal - spec->base ); get_asm_short_keyword(), spec->names[i]->ordinal - spec->base );
} }
if (spec->nb_names % 2) if (spec->nb_names % 2)
{ {
fprintf( outfile, " \"\\t%s 0\\n\"\n", get_asm_short_keyword() ); fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() );
} }
} }
/* output the export name strings */ /* output the export name strings */
fprintf( outfile, " \".L__wine_spec_exp_names:\\n\"\n" ); fprintf( outfile, "\n.L__wine_spec_exp_names:\n" );
fprintf( outfile, " \"\\t%s \\\"%s\\\"\\n\"\n", get_asm_string_keyword(), spec->file_name ); fprintf( outfile, "\t%s \"%s\"\n", get_asm_string_keyword(), spec->file_name );
for (i = 0; i < spec->nb_names; i++) for (i = 0; i < spec->nb_names; i++)
fprintf( outfile, " \"\\t%s \\\"%s\\\"\\n\"\n", fprintf( outfile, "\t%s \"%s\"\n",
get_asm_string_keyword(), spec->names[i]->name ); get_asm_string_keyword(), spec->names[i]->name );
/* output forward strings */ /* output forward strings */
if (fwd_size) if (fwd_size)
{ {
fprintf( outfile, " \".L__wine_spec_forwards:\\n\"\n" ); fprintf( outfile, "\n.L__wine_spec_forwards:\n" );
for (i = spec->base; i <= spec->limit; i++) for (i = spec->base; i <= spec->limit; i++)
{ {
ORDDEF *odp = spec->ordinals[i]; ORDDEF *odp = spec->ordinals[i];
if (odp && (odp->flags & FLAG_FORWARD)) if (odp && (odp->flags & FLAG_FORWARD))
fprintf( outfile, " \"\\t%s \\\"%s\\\"\\n\"\n", get_asm_string_keyword(), odp->link_name ); fprintf( outfile, "\t%s \"%s\"\n", get_asm_string_keyword(), odp->link_name );
} }
} }
fprintf( outfile, " \"\\t.align %d\\n\"\n", get_alignment(4) ); fprintf( outfile, "\t.align %d\n", get_alignment(4) );
fprintf( outfile, " \".L__wine_spec_exports_end:\\n\"\n" ); fprintf( outfile, ".L__wine_spec_exports_end:\n" );
/* output relays */ /* output relays */
...@@ -244,15 +244,15 @@ static void output_exports( FILE *outfile, DLLSPEC *spec ) ...@@ -244,15 +244,15 @@ static void output_exports( FILE *outfile, DLLSPEC *spec )
switch(odp->type) switch(odp->type)
{ {
case TYPE_STDCALL: case TYPE_STDCALL:
fprintf( outfile, " \"\\tjmp %s\\n\"\n", asm_name(odp->link_name) ); fprintf( outfile, "\tjmp %s\n", asm_name(odp->link_name) );
fprintf( outfile, " \"\\tret $%d\\n\"\n", args ); fprintf( outfile, "\tret $%d\n", args );
fprintf( outfile, " \"\\t.long %s,0x%08x\\n\"\n", asm_name(odp->link_name), mask ); fprintf( outfile, "\t.long %s,0x%08x\n", asm_name(odp->link_name), mask );
break; break;
case TYPE_CDECL: case TYPE_CDECL:
fprintf( outfile, " \"\\tjmp %s\\n\"\n", asm_name(odp->link_name) ); fprintf( outfile, "\tjmp %s\n", asm_name(odp->link_name) );
fprintf( outfile, " \"\\tret\\n\"\n" ); fprintf( outfile, "\tret\n" );
fprintf( outfile, " \"\\t%s %d\\n\"\n", get_asm_short_keyword(), args ); fprintf( outfile, "\t%s %d\n", get_asm_short_keyword(), args );
fprintf( outfile, " \"\\t.long %s,0x%08x\\n\"\n", asm_name(odp->link_name), mask ); fprintf( outfile, "\t.long %s,0x%08x\n", asm_name(odp->link_name), mask );
break; break;
default: default:
assert(0); assert(0);
...@@ -260,12 +260,10 @@ static void output_exports( FILE *outfile, DLLSPEC *spec ) ...@@ -260,12 +260,10 @@ static void output_exports( FILE *outfile, DLLSPEC *spec )
continue; continue;
ignore: ignore:
fprintf( outfile, " \"\\t.long 0,0,0,0\\n\"\n" ); fprintf( outfile, "\t.long 0,0,0,0\n" );
} }
} }
else fprintf( outfile, " \"\\t.long 0\\n\"\n" ); else fprintf( outfile, "\t.long 0\n" );
fprintf( outfile, ");\n" );
} }
...@@ -281,7 +279,8 @@ static void output_stubs( FILE *outfile, DLLSPEC *spec ) ...@@ -281,7 +279,8 @@ static void output_stubs( FILE *outfile, DLLSPEC *spec )
if (!has_stubs( spec )) return; if (!has_stubs( spec )) return;
fprintf( outfile, "asm(\".text\\n\"\n" ); fprintf( outfile, "\n/* stub functions */\n\n" );
fprintf( outfile, "\t.text\n" );
for (i = pos = 0; i < spec->nb_entry_points; i++) for (i = pos = 0; i < spec->nb_entry_points; i++)
{ {
...@@ -290,43 +289,41 @@ static void output_stubs( FILE *outfile, DLLSPEC *spec ) ...@@ -290,43 +289,41 @@ static void output_stubs( FILE *outfile, DLLSPEC *spec )
name = make_internal_name( odp, spec, "stub" ); name = make_internal_name( odp, spec, "stub" );
exp_name = odp->name ? odp->name : odp->export_name; exp_name = odp->name ? odp->name : odp->export_name;
fprintf( outfile, " \"\\t.align %d\\n\"\n", get_alignment(4) ); fprintf( outfile, "\t.align %d\n", get_alignment(4) );
fprintf( outfile, " \"\\t%s\\n\"\n", func_declaration(name) ); fprintf( outfile, "\t%s\n", func_declaration(name) );
fprintf( outfile, " \"%s:\\n\"\n", asm_name(name) ); fprintf( outfile, "%s:\n", asm_name(name) );
fprintf( outfile, " \"\\tcall .L__wine_stub_getpc_%d\\n\"\n", i ); fprintf( outfile, "\tcall .L__wine_stub_getpc_%d\n", i );
fprintf( outfile, " \".L__wine_stub_getpc_%d:\\n\"\n", i ); fprintf( outfile, ".L__wine_stub_getpc_%d:\n", i );
fprintf( outfile, " \"\\tpopl %%eax\\n\"\n" ); fprintf( outfile, "\tpopl %%eax\n" );
if (exp_name) if (exp_name)
{ {
fprintf( outfile, " \"\\tleal .L__wine_stub_strings+%d-.L__wine_stub_getpc_%d(%%eax),%%ecx\\n\"\n", fprintf( outfile, "\tleal .L__wine_stub_strings+%d-.L__wine_stub_getpc_%d(%%eax),%%ecx\n",
pos, i ); pos, i );
fprintf( outfile, " \"\\tpushl %%ecx\\n\"\n" ); fprintf( outfile, "\tpushl %%ecx\n" );
pos += strlen(exp_name) + 1; pos += strlen(exp_name) + 1;
} }
else else
fprintf( outfile, " \"\\tpushl $%d\\n\"\n", odp->ordinal ); fprintf( outfile, "\tpushl $%d\n", odp->ordinal );
fprintf( outfile, " \"\\tleal %s-.L__wine_stub_getpc_%d(%%eax),%%ecx\\n\"\n", fprintf( outfile, "\tleal %s-.L__wine_stub_getpc_%d(%%eax),%%ecx\n",
asm_name("__wine_spec_file_name"), i ); asm_name("__wine_spec_file_name"), i );
fprintf( outfile, " \"\\tpushl %%ecx\\n\"\n" ); fprintf( outfile, "\tpushl %%ecx\n" );
fprintf( outfile, " \"\\tcall %s\\n\"\n", asm_name("__wine_spec_unimplemented_stub") ); fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_unimplemented_stub") );
fprintf( outfile, " \"\\t%s\\n\"\n", func_size(name) ); fprintf( outfile, "\t%s\n", func_size(name) );
} }
if (pos) if (pos)
{ {
fprintf( outfile, " \"\\t%s\\n\"\n", get_asm_string_section() ); fprintf( outfile, "\t%s\n", get_asm_string_section() );
fprintf( outfile, " \".L__wine_stub_strings:\\n\"\n" ); fprintf( outfile, ".L__wine_stub_strings:\n" );
for (i = 0; i < spec->nb_entry_points; i++) for (i = 0; i < spec->nb_entry_points; i++)
{ {
ORDDEF *odp = &spec->entry_points[i]; ORDDEF *odp = &spec->entry_points[i];
if (odp->type != TYPE_STUB) continue; if (odp->type != TYPE_STUB) continue;
exp_name = odp->name ? odp->name : odp->export_name; exp_name = odp->name ? odp->name : odp->export_name;
if (exp_name) if (exp_name)
fprintf( outfile, " \"\\t%s \\\"%s\\\"\\n\"\n", get_asm_string_keyword(), exp_name ); fprintf( outfile, "\t%s \"%s\"\n", get_asm_string_keyword(), exp_name );
} }
} }
fprintf( outfile, ");\n" );
} }
...@@ -421,6 +418,44 @@ void output_dll_init( FILE *outfile, const char *constructor, const char *destru ...@@ -421,6 +418,44 @@ void output_dll_init( FILE *outfile, const char *constructor, const char *destru
/******************************************************************* /*******************************************************************
* output_asm_constructor
*
* Output code for calling a dll constructor.
*/
static void output_asm_constructor( FILE *outfile, const char *constructor )
{
if (target_platform == PLATFORM_APPLE)
{
/* Mach-O doesn't have an init section */
fprintf( outfile, "\n\t.mod_init_func\n" );
fprintf( outfile, "\t.align %d\n", get_alignment(4) );
fprintf( outfile, "\t.long %s\n", asm_name(constructor) );
}
else
{
fprintf( outfile, "\n\t.section \".init\",\"ax\"\n" );
switch(target_cpu)
{
case CPU_x86:
case CPU_x86_64:
fprintf( outfile, "\tcall %s\n", asm_name(constructor) );
break;
case CPU_SPARC:
fprintf( outfile, "\tcall %s\n", asm_name(constructor) );
fprintf( outfile, "\tnop\n" );
break;
case CPU_ALPHA:
fprintf( outfile, "\tjsr $26,%s\n", asm_name(constructor) );
break;
case CPU_POWERPC:
fprintf( outfile, "\tbl %s\n", asm_name(constructor) );
break;
}
}
}
/*******************************************************************
* BuildSpec32File * BuildSpec32File
* *
* Build a Win32 C file from a spec file. * Build a Win32 C file from a spec file.
...@@ -435,26 +470,22 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec ) ...@@ -435,26 +470,22 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
/* Reserve some space for the PE header */ /* Reserve some space for the PE header */
fprintf( outfile, "#ifndef __GNUC__\n" ); fprintf( outfile, "\t.text\n" );
fprintf( outfile, "static void __asm__dummy(void) {\n" ); fprintf( outfile, "\t.align %d\n", get_alignment(page_size) );
fprintf( outfile, "#endif\n" ); fprintf( outfile, "__wine_spec_pe_header:\n" );
fprintf( outfile, "asm(\".text\\n\\t\"\n" );
fprintf( outfile, " \".align %d\\n\"\n", get_alignment(page_size) );
fprintf( outfile, " \"__wine_spec_pe_header:\\t\"\n" );
if (target_platform == PLATFORM_APPLE) if (target_platform == PLATFORM_APPLE)
fprintf( outfile, " \".space 65536\\n\\t\"\n" ); fprintf( outfile, "\t.space 65536\n" );
else else
fprintf( outfile, " \".skip 65536\\n\\t\"\n" ); fprintf( outfile, "\t.skip 65536\n" );
/* Output the NT header */ /* Output the NT header */
fprintf( outfile, " \"\\t.data\\n\\t\"\n" ); fprintf( outfile, "\n\t.data\n" );
fprintf( outfile, " \"\\t.align %d\\n\"\n", get_alignment(get_ptr_size()) ); fprintf( outfile, "\t.align %d\n", get_alignment(get_ptr_size()) );
fprintf( outfile, " \"\\t.globl %s\\n\"\n", asm_name("__wine_spec_nt_header") ); fprintf( outfile, "\t.globl %s\n", asm_name("__wine_spec_nt_header") );
fprintf( outfile, " \"%s:\\n\"\n", asm_name("__wine_spec_nt_header")); fprintf( outfile, "%s:\n", asm_name("__wine_spec_nt_header"));
fprintf( outfile, " \"\\t.long 0x%04x\\n\"\n", IMAGE_NT_SIGNATURE ); /* Signature */ fprintf( outfile, "\t.long 0x%04x\n", IMAGE_NT_SIGNATURE ); /* Signature */
switch(target_cpu) switch(target_cpu)
{ {
case CPU_x86: machine = IMAGE_FILE_MACHINE_I386; break; case CPU_x86: machine = IMAGE_FILE_MACHINE_I386; break;
...@@ -463,105 +494,98 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec ) ...@@ -463,105 +494,98 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
case CPU_ALPHA: machine = IMAGE_FILE_MACHINE_ALPHA; break; case CPU_ALPHA: machine = IMAGE_FILE_MACHINE_ALPHA; break;
case CPU_SPARC: machine = IMAGE_FILE_MACHINE_UNKNOWN; break; case CPU_SPARC: machine = IMAGE_FILE_MACHINE_UNKNOWN; break;
} }
fprintf( outfile, " \"\\t%s 0x%04x\\n\"\n", /* Machine */ fprintf( outfile, "\t%s 0x%04x\n", /* Machine */
get_asm_short_keyword(), machine ); get_asm_short_keyword(), machine );
fprintf( outfile, " \"\\t%s 0\\n\"\n", /* NumberOfSections */ fprintf( outfile, "\t%s 0\n", /* NumberOfSections */
get_asm_short_keyword() ); get_asm_short_keyword() );
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* TimeDateStamp */ fprintf( outfile, "\t.long 0\n" ); /* TimeDateStamp */
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* PointerToSymbolTable */ fprintf( outfile, "\t.long 0\n" ); /* PointerToSymbolTable */
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* NumberOfSymbols */ fprintf( outfile, "\t.long 0\n" ); /* NumberOfSymbols */
fprintf( outfile, " \"\\t%s %d\\n\"\n", /* SizeOfOptionalHeader */ fprintf( outfile, "\t%s %d\n", /* SizeOfOptionalHeader */
get_asm_short_keyword(), get_asm_short_keyword(),
get_ptr_size() == 8 ? IMAGE_SIZEOF_NT_OPTIONAL64_HEADER : IMAGE_SIZEOF_NT_OPTIONAL32_HEADER ); get_ptr_size() == 8 ? IMAGE_SIZEOF_NT_OPTIONAL64_HEADER : IMAGE_SIZEOF_NT_OPTIONAL32_HEADER );
fprintf( outfile, " \"\\t%s 0x%04x\\n\"\n", /* Characteristics */ fprintf( outfile, "\t%s 0x%04x\n", /* Characteristics */
get_asm_short_keyword(), spec->characteristics ); get_asm_short_keyword(), spec->characteristics );
fprintf( outfile, " \"\\t%s 0x%04x\\n\"\n", /* Magic */ fprintf( outfile, "\t%s 0x%04x\n", /* Magic */
get_asm_short_keyword(), get_asm_short_keyword(),
get_ptr_size() == 8 ? IMAGE_NT_OPTIONAL_HDR64_MAGIC : IMAGE_NT_OPTIONAL_HDR32_MAGIC ); get_ptr_size() == 8 ? IMAGE_NT_OPTIONAL_HDR64_MAGIC : IMAGE_NT_OPTIONAL_HDR32_MAGIC );
fprintf( outfile, " \"\\t.byte 0\\n\"\n" ); /* MajorLinkerVersion */ fprintf( outfile, "\t.byte 0\n" ); /* MajorLinkerVersion */
fprintf( outfile, " \"\\t.byte 0\\n\"\n" ); /* MinorLinkerVersion */ fprintf( outfile, "\t.byte 0\n" ); /* MinorLinkerVersion */
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* SizeOfCode */ fprintf( outfile, "\t.long 0\n" ); /* SizeOfCode */
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* SizeOfInitializedData */ fprintf( outfile, "\t.long 0\n" ); /* SizeOfInitializedData */
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* SizeOfUninitializedData */ fprintf( outfile, "\t.long 0\n" ); /* SizeOfUninitializedData */
fprintf( outfile, " \"\\t.long %s\\n\"\n", /* AddressOfEntryPoint */ fprintf( outfile, "\t.long %s\n", /* AddressOfEntryPoint */
asm_name(spec->init_func) ); asm_name(spec->init_func) );
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* BaseOfCode */ fprintf( outfile, "\t.long 0\n" ); /* BaseOfCode */
if (get_ptr_size() == 4) if (get_ptr_size() == 4)
fprintf( outfile, " \"\\t.long %s\\n\"\n", asm_name("__wine_spec_nt_header") ); /* BaseOfData */ fprintf( outfile, "\t.long %s\n", asm_name("__wine_spec_nt_header") ); /* BaseOfData */
fprintf( outfile, " \"\\t%s __wine_spec_pe_header\\n\"\n", /* ImageBase */ fprintf( outfile, "\t%s __wine_spec_pe_header\n", /* ImageBase */
get_asm_ptr_keyword() ); get_asm_ptr_keyword() );
fprintf( outfile, " \"\\t.long %u\\n\"\n", page_size ); /* SectionAlignment */ fprintf( outfile, "\t.long %u\n", page_size ); /* SectionAlignment */
fprintf( outfile, " \"\\t.long %u\\n\"\n", page_size ); /* FileAlignment */ fprintf( outfile, "\t.long %u\n", page_size ); /* FileAlignment */
fprintf( outfile, " \"\\t%s 1,0\\n\"\n", /* Major/MinorOperatingSystemVersion */ fprintf( outfile, "\t%s 1,0\n", /* Major/MinorOperatingSystemVersion */
get_asm_short_keyword() ); get_asm_short_keyword() );
fprintf( outfile, " \"\\t%s 0,0\\n\"\n", /* Major/MinorImageVersion */ fprintf( outfile, "\t%s 0,0\n", /* Major/MinorImageVersion */
get_asm_short_keyword() ); get_asm_short_keyword() );
fprintf( outfile, " \"\\t%s %u,%u\\n\"\n", /* Major/MinorSubsystemVersion */ fprintf( outfile, "\t%s %u,%u\n", /* Major/MinorSubsystemVersion */
get_asm_short_keyword(), spec->subsystem_major, spec->subsystem_minor ); get_asm_short_keyword(), spec->subsystem_major, spec->subsystem_minor );
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* Win32VersionValue */ fprintf( outfile, "\t.long 0\n" ); /* Win32VersionValue */
fprintf( outfile, " \"\\t.long %s\\n\"\n", /* SizeOfImage */ fprintf( outfile, "\t.long %s\n", /* SizeOfImage */
asm_name("_end") ); asm_name("_end") );
fprintf( outfile, " \"\\t.long %u\\n\"\n", page_size ); /* SizeOfHeaders */ fprintf( outfile, "\t.long %u\n", page_size ); /* SizeOfHeaders */
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* CheckSum */ fprintf( outfile, "\t.long 0\n" ); /* CheckSum */
fprintf( outfile, " \"\\t%s 0x%04x\\n\"\n", /* Subsystem */ fprintf( outfile, "\t%s 0x%04x\n", /* Subsystem */
get_asm_short_keyword(), spec->subsystem ); get_asm_short_keyword(), spec->subsystem );
fprintf( outfile, " \"\\t%s 0\\n\"\n", /* DllCharacteristics */ fprintf( outfile, "\t%s 0\n", /* DllCharacteristics */
get_asm_short_keyword() ); get_asm_short_keyword() );
fprintf( outfile, " \"\\t%s %u,%u\\n\"\n", /* SizeOfStackReserve/Commit */ fprintf( outfile, "\t%s %u,%u\n", /* SizeOfStackReserve/Commit */
get_asm_ptr_keyword(), (spec->stack_size ? spec->stack_size : 1024) * 1024, page_size ); get_asm_ptr_keyword(), (spec->stack_size ? spec->stack_size : 1024) * 1024, page_size );
fprintf( outfile, " \"\\t%s %u,%u\\n\"\n", /* SizeOfHeapReserve/Commit */ fprintf( outfile, "\t%s %u,%u\n", /* SizeOfHeapReserve/Commit */
get_asm_ptr_keyword(), (spec->heap_size ? spec->heap_size : 1024) * 1024, page_size ); get_asm_ptr_keyword(), (spec->heap_size ? spec->heap_size : 1024) * 1024, page_size );
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* LoaderFlags */ fprintf( outfile, "\t.long 0\n" ); /* LoaderFlags */
fprintf( outfile, " \"\\t.long 16\\n\"\n" ); /* NumberOfRvaAndSizes */ fprintf( outfile, "\t.long 16\n" ); /* NumberOfRvaAndSizes */
if (spec->base <= spec->limit) /* DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT] */ if (spec->base <= spec->limit) /* DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT] */
fprintf( outfile, " \"\\t.long .L__wine_spec_exports, .L__wine_spec_exports_end-.L__wine_spec_exports\\n\"\n" ); fprintf( outfile, "\t.long .L__wine_spec_exports, .L__wine_spec_exports_end-.L__wine_spec_exports\n" );
else else
fprintf( outfile, " \"\\t.long 0,0\\n\"\n" ); fprintf( outfile, "\t.long 0,0\n" );
if (has_imports()) /* DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] */ if (has_imports()) /* DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] */
fprintf( outfile, " \"\\t.long .L__wine_spec_imports, .L__wine_spec_imports_end-.L__wine_spec_imports\\n\"\n" ); fprintf( outfile, "\t.long .L__wine_spec_imports, .L__wine_spec_imports_end-.L__wine_spec_imports\n" );
else else
fprintf( outfile, " \"\\t.long 0,0\\n\"\n" ); fprintf( outfile, "\t.long 0,0\n" );
if (spec->nb_resources) /* DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE] */ if (spec->nb_resources) /* DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE] */
fprintf( outfile, " \"\\t.long .L__wine_spec_resources, .L__wine_spec_resources_end-.L__wine_spec_resources\\n\"\n" ); fprintf( outfile, "\t.long .L__wine_spec_resources, .L__wine_spec_resources_end-.L__wine_spec_resources\n" );
else else
fprintf( outfile, " \"\\t.long 0,0\\n\"\n" ); fprintf( outfile, "\t.long 0,0\n" );
fprintf( outfile, " \"\\t.long 0,0\\n\"\n" ); /* DataDirectory[3] */ fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[3] */
fprintf( outfile, " \"\\t.long 0,0\\n\"\n" ); /* DataDirectory[4] */ fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[4] */
fprintf( outfile, " \"\\t.long 0,0\\n\"\n" ); /* DataDirectory[5] */ fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[5] */
fprintf( outfile, " \"\\t.long 0,0\\n\"\n" ); /* DataDirectory[6] */ fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[6] */
fprintf( outfile, " \"\\t.long 0,0\\n\"\n" ); /* DataDirectory[7] */ fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[7] */
fprintf( outfile, " \"\\t.long 0,0\\n\"\n" ); /* DataDirectory[8] */ fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[8] */
fprintf( outfile, " \"\\t.long 0,0\\n\"\n" ); /* DataDirectory[9] */ fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[9] */
fprintf( outfile, " \"\\t.long 0,0\\n\"\n" ); /* DataDirectory[10] */ fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[10] */
fprintf( outfile, " \"\\t.long 0,0\\n\"\n" ); /* DataDirectory[11] */ fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[11] */
fprintf( outfile, " \"\\t.long 0,0\\n\"\n" ); /* DataDirectory[12] */ fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[12] */
fprintf( outfile, " \"\\t.long 0,0\\n\"\n" ); /* DataDirectory[13] */ fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[13] */
fprintf( outfile, " \"\\t.long 0,0\\n\"\n" ); /* DataDirectory[14] */ fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[14] */
fprintf( outfile, " \"\\t.long 0,0\\n\"\n" ); /* DataDirectory[15] */ fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[15] */
fprintf( outfile, ");\n" );
fprintf( outfile, "\n\t%s\n", get_asm_string_section() );
fprintf( outfile, "asm(\"%s\\n\"\n", get_asm_string_section() ); fprintf( outfile, "\t.globl %s\n", asm_name("__wine_spec_file_name") );
fprintf( outfile, " \"\\t.globl %s\\n\"\n", asm_name("__wine_spec_file_name") ); fprintf( outfile, "%s:\n", asm_name("__wine_spec_file_name"));
fprintf( outfile, " \"%s:\\n\"\n", asm_name("__wine_spec_file_name")); fprintf( outfile, "\t%s \"%s\"\n", get_asm_string_keyword(), spec->file_name );
fprintf( outfile, " \"\\t%s \\\"%s\\\"\\n\"\n", get_asm_string_keyword(), spec->file_name );
if (target_platform == PLATFORM_APPLE) if (target_platform == PLATFORM_APPLE)
fprintf( outfile, " \"\\t.comm %s,4\\n\"\n", asm_name("_end") ); fprintf( outfile, "\t.comm %s,4\n", asm_name("_end") );
fprintf( outfile, ");\n" );
output_stubs( outfile, spec ); output_stubs( outfile, spec );
output_exports( outfile, spec ); output_exports( outfile, spec );
output_imports( outfile, spec ); output_imports( outfile, spec );
output_resources( outfile, spec ); output_resources( outfile, spec );
output_dll_init( outfile, "__wine_spec_init_ctor", NULL ); output_asm_constructor( outfile, "__wine_spec_init_ctor" );
fprintf( outfile, "#ifndef __GNUC__\n" );
fprintf( outfile, "}\n" );
fprintf( outfile, "#endif\n" );
} }
......
...@@ -4,6 +4,7 @@ DEFS = \ ...@@ -4,6 +4,7 @@ DEFS = \
-DLIBDIR="\"$(libdir)\"" \ -DLIBDIR="\"$(libdir)\"" \
-DDLLFLAGS="\"@DLLFLAGS@\"" \ -DDLLFLAGS="\"@DLLFLAGS@\"" \
-DLDDLLFLAGS="\"@LDDLLFLAGS@\"" \ -DLDDLLFLAGS="\"@LDDLLFLAGS@\"" \
-DAS="\"$(AS)\"" \
-DCC="\"$(CC)\"" \ -DCC="\"$(CC)\"" \
-DCPP="\"@CPPBIN@\"" \ -DCPP="\"@CPPBIN@\"" \
-DCXX="\"$(CXX)\"" \ -DCXX="\"$(CXX)\"" \
......
...@@ -142,9 +142,11 @@ static strarray* tmp_files; ...@@ -142,9 +142,11 @@ static strarray* tmp_files;
static sigset_t signal_mask; static sigset_t signal_mask;
#endif #endif
enum processor { proc_cc, proc_cxx, proc_cpp, proc_as };
struct options struct options
{ {
enum { proc_cc = 0, proc_cxx = 1, proc_cpp = 2} processor; enum processor processor;
int shared; int shared;
int use_msvcrt; int use_msvcrt;
int nostdinc; int nostdinc;
...@@ -209,13 +211,14 @@ static char* get_temp_file(const char* prefix, const char* suffix) ...@@ -209,13 +211,14 @@ static char* get_temp_file(const char* prefix, const char* suffix)
return tmp; return tmp;
} }
static const strarray* get_translator(struct options* opts) static const strarray* get_translator(enum processor processor)
{ {
static strarray* cpp = 0; static strarray* cpp = 0;
static strarray* as = 0;
static strarray* cc = 0; static strarray* cc = 0;
static strarray* cxx = 0; static strarray* cxx = 0;
switch(opts->processor) switch(processor)
{ {
case proc_cpp: case proc_cpp:
if (!cpp) cpp = strarray_fromstring(CPP, " "); if (!cpp) cpp = strarray_fromstring(CPP, " ");
...@@ -226,6 +229,9 @@ static const strarray* get_translator(struct options* opts) ...@@ -226,6 +229,9 @@ static const strarray* get_translator(struct options* opts)
case proc_cxx: case proc_cxx:
if (!cxx) cxx = strarray_fromstring(CXX, " "); if (!cxx) cxx = strarray_fromstring(CXX, " ");
return cxx; return cxx;
case proc_as:
if (!as) as = strarray_fromstring(AS, " ");
return as;
} }
error("Unknown processor"); error("Unknown processor");
} }
...@@ -247,8 +253,9 @@ static void compile(struct options* opts, const char* lang) ...@@ -247,8 +253,9 @@ static void compile(struct options* opts, const char* lang)
case proc_cc: gcc_defs = 0; break; case proc_cc: gcc_defs = 0; break;
case proc_cxx: gcc_defs = 0; break; case proc_cxx: gcc_defs = 0; break;
#endif #endif
case proc_as: gcc_defs = 0; break;
} }
strarray_addall(comp_args, get_translator(opts)); strarray_addall(comp_args, get_translator(opts->processor));
if (opts->processor != proc_cpp) if (opts->processor != proc_cpp)
{ {
...@@ -366,6 +373,48 @@ static const char* compile_to_object(struct options* opts, const char* file, con ...@@ -366,6 +373,48 @@ static const char* compile_to_object(struct options* opts, const char* file, con
return copts.output_name; return copts.output_name;
} }
static void assemble(struct options* opts)
{
int i;
for (i = 0; i < opts->files->size; i++ )
{
if (opts->files->base[i][0] != '-')
{
strarray* as_args = strarray_alloc();
strarray_addall(as_args, get_translator(proc_as));
if (opts->output_name)
{
strarray_add(as_args, "-o");
strarray_add(as_args, opts->output_name);
}
strarray_add(as_args, opts->files->base[i]);
spawn(opts->prefix, as_args, 0);
strarray_free(as_args);
}
}
}
static const char* assemble_to_object(struct options* opts, const char* file)
{
struct options copts;
char* base_name;
/* make a copy so we don't change any of the initial stuff */
/* a shallow copy is exactly what we want in this case */
base_name = get_basename(file);
copts = *opts;
copts.output_name = get_temp_file(base_name, ".o");
copts.files = strarray_alloc();
strarray_add(copts.files, file);
assemble(&copts);
strarray_free(copts.files);
free(base_name);
return copts.output_name;
}
/* check if there is a static lib associated to a given dll */ /* check if there is a static lib associated to a given dll */
static char *find_static_lib( const char *dll ) static char *find_static_lib( const char *dll )
{ {
...@@ -381,11 +430,10 @@ static void build(struct options* opts) ...@@ -381,11 +430,10 @@ static void build(struct options* opts)
strarray *lib_dirs, *files; strarray *lib_dirs, *files;
strarray *spec_args, *link_args; strarray *spec_args, *link_args;
char *output_file; char *output_file;
const char *spec_c_name, *spec_o_name; const char *spec_s_name, *spec_o_name;
const char *output_name, *spec_file, *lang; const char *output_name, *spec_file, *lang;
const char* winebuild = getenv("WINEBUILD"); const char* winebuild = getenv("WINEBUILD");
int generate_app_loader = 1; int generate_app_loader = 1;
int old_processor;
int j; int j;
/* NOTE: for the files array we'll use the following convention: /* NOTE: for the files array we'll use the following convention:
...@@ -540,14 +588,14 @@ static void build(struct options* opts) ...@@ -540,14 +588,14 @@ static void build(struct options* opts)
/* run winebuild to generate the .spec.c file */ /* run winebuild to generate the .spec.c file */
spec_args = strarray_alloc(); spec_args = strarray_alloc();
spec_c_name = get_temp_file(output_name, ".spec.c"); spec_s_name = get_temp_file(output_name, ".spec.s");
strarray_add(spec_args, winebuild); strarray_add(spec_args, winebuild);
strarray_add(spec_args, "--ld-cmd"); strarray_add(spec_args, "--ld-cmd");
strarray_add(spec_args, LD); strarray_add(spec_args, LD);
strarray_addall(spec_args, strarray_fromstring(DLLFLAGS, " ")); strarray_addall(spec_args, strarray_fromstring(DLLFLAGS, " "));
strarray_add(spec_args, opts->shared ? "--dll" : "--exe"); strarray_add(spec_args, opts->shared ? "--dll" : "--exe");
strarray_add(spec_args, "-o"); strarray_add(spec_args, "-o");
strarray_add(spec_args, spec_c_name); strarray_add(spec_args, spec_s_name);
if (spec_file) if (spec_file)
{ {
strarray_add(spec_args, "-E"); strarray_add(spec_args, "-E");
...@@ -593,16 +641,12 @@ static void build(struct options* opts) ...@@ -593,16 +641,12 @@ static void build(struct options* opts)
spawn(opts->prefix, spec_args, 0); spawn(opts->prefix, spec_args, 0);
/* compile the .spec.c file into a .spec.o file */ /* assemble the .spec.s file into a .spec.o file */
old_processor = opts->processor; spec_o_name = assemble_to_object(opts, spec_s_name);
/* Always compile spec.c as c, even if linking with g++ */
opts->processor = proc_cc;
spec_o_name = compile_to_object(opts, spec_c_name, 0);
opts->processor = old_processor;
/* link everything together now */ /* link everything together now */
link_args = strarray_alloc(); link_args = strarray_alloc();
strarray_addall(link_args, get_translator(opts)); strarray_addall(link_args, get_translator(opts->processor));
strarray_addall(link_args, strarray_fromstring(LDDLLFLAGS, " ")); strarray_addall(link_args, strarray_fromstring(LDDLLFLAGS, " "));
strarray_add(link_args, "-o"); strarray_add(link_args, "-o");
...@@ -679,7 +723,7 @@ static void forward(int argc, char **argv, struct options* opts) ...@@ -679,7 +723,7 @@ static void forward(int argc, char **argv, struct options* opts)
strarray* args = strarray_alloc(); strarray* args = strarray_alloc();
int j; int j;
strarray_addall(args, get_translator(opts)); strarray_addall(args, get_translator(opts->processor));
for( j = 1; j < argc; j++ ) for( j = 1; j < argc; j++ )
strarray_add(args, argv[j]); strarray_add(args, argv[j]);
......
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