More portable .align directive.
Ignore -delay directive on ppc only. Added code to call the dll constructors.
This commit is contained in:
parent
4b1eb5171c
commit
0b64cfb3f7
@ -133,6 +133,8 @@ extern void fatal_perror( const char *msg, ... );
|
||||
extern void warning( const char *msg, ... );
|
||||
extern void dump_bytes( FILE *outfile, const unsigned char *data, int len,
|
||||
const char *label, int constant );
|
||||
extern int get_alignment(int alignBoundary);
|
||||
|
||||
extern void add_import_dll( const char *name, int delay );
|
||||
extern void add_ignore_symbol( const char *name );
|
||||
extern int resolve_imports( FILE *outfile );
|
||||
|
@ -397,7 +397,7 @@ static int output_immediate_imports( FILE *outfile )
|
||||
|
||||
fprintf( outfile, "#ifndef __GNUC__\nstatic void __asm__dummy_import(void) {\n#endif\n\n" );
|
||||
pos = 20 * (nb_imm + 1); /* offset of imports.data from start of imports */
|
||||
fprintf( outfile, "asm(\".data\\n\\t.align 8\\n\"\n" );
|
||||
fprintf( outfile, "asm(\".data\\n\\t.align %d\\n\"\n", get_alignment(8) );
|
||||
for (i = 0; i < nb_imports; i++)
|
||||
{
|
||||
if (dll_imports[i]->delay) continue;
|
||||
@ -436,6 +436,27 @@ static int output_immediate_imports( FILE *outfile )
|
||||
fprintf( outfile, "ld [%%g1+%%o7], %%g1\\n\\t" );
|
||||
fprintf( outfile, "jmp %%g1\\n\\trestore\\n" );
|
||||
}
|
||||
|
||||
#elif defined(__PPC__)
|
||||
fprintf(outfile, "\taddi 1, 1, -0x4\\n\"\n");
|
||||
fprintf(outfile, "\t\"\\tstw 9, 0(1)\\n\"\n");
|
||||
fprintf(outfile, "\t\"\\taddi 1, 1, -0x4\\n\"\n");
|
||||
fprintf(outfile, "\t\"\\tstw 8, 0(1)\\n\"\n");
|
||||
fprintf(outfile, "\t\"\\taddi 1, 1, -0x4\\n\"\n");
|
||||
fprintf(outfile, "\t\"\\tstw 7, 0(1)\\n\"\n");
|
||||
|
||||
fprintf(outfile, "\t\"\\tlis 9,imports+%d@ha\\n\"\n", pos);
|
||||
fprintf(outfile, "\t\"\\tla 8,imports+%d@l(9)\\n\"\n", pos);
|
||||
fprintf(outfile, "\t\"\\tlwz 7, 0(8)\\n\"\n");
|
||||
fprintf(outfile, "\t\"\\tmtctr 7\\n\"\n");
|
||||
|
||||
fprintf(outfile, "\t\"\\tlwz 7, 0(1)\\n\"\n");
|
||||
fprintf(outfile, "\t\"\\taddi 1, 1, 0x4\\n\"\n");
|
||||
fprintf(outfile, "\t\"\\tlwz 8, 0(1)\\n\"\n");
|
||||
fprintf(outfile, "\t\"\\taddi 1, 1, 0x4\\n\"\n");
|
||||
fprintf(outfile, "\t\"\\tlwz 9, 0(1)\\n\"\n");
|
||||
fprintf(outfile, "\t\"\\taddi 1, 1, 0x4\\n\"\n");
|
||||
fprintf(outfile, "\t\"\\tbctr\\n");
|
||||
#else
|
||||
#error You need to define import thunks for your architecture!
|
||||
#endif
|
||||
@ -563,7 +584,7 @@ static int output_delayed_imports( FILE *outfile )
|
||||
fprintf( outfile, "static void __asm__dummy_delay_import(void) {\n" );
|
||||
fprintf( outfile, "#endif\n" );
|
||||
|
||||
fprintf( outfile, "asm(\".align 8\\n\"\n" );
|
||||
fprintf( outfile, "asm(\".align %d\\n\"\n", get_alignment(8) );
|
||||
fprintf( outfile, " \"\\t" __ASM_FUNC("__wine_delay_load_asm") "\\n\"\n" );
|
||||
fprintf( outfile, " \"" PREFIX "__wine_delay_load_asm:\\n\"\n" );
|
||||
#if defined(__i386__)
|
||||
@ -575,6 +596,8 @@ static int output_delayed_imports( FILE *outfile )
|
||||
fprintf( outfile, " \"\\tcall __wine_delay_load\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tmov %%g1, %%o0\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tjmp %%o0\\n\\trestore\\n\"\n" );
|
||||
#elif defined(__PPC__)
|
||||
fprintf(outfile, "#error: DELAYED IMPORTS NOT SUPPORTED ON PPC!!!\n");
|
||||
#else
|
||||
#error You need to defined delayed import thunks for your architecture!
|
||||
#endif
|
||||
@ -594,6 +617,8 @@ static int output_delayed_imports( FILE *outfile )
|
||||
#elif defined(__sparc__)
|
||||
fprintf( outfile, " \"\\tset %d, %%g1\\n\"\n", (idx << 16) | j );
|
||||
fprintf( outfile, " \"\\tb,a __wine_delay_load_asm\\n\"\n" );
|
||||
#elif defined(__PPC__)
|
||||
fprintf(outfile, "#error: DELAYED IMPORTS NOT SUPPORTED ON PPC!!!\n");
|
||||
#else
|
||||
#error You need to defined delayed import thunks for your architecture!
|
||||
#endif
|
||||
@ -601,7 +626,7 @@ static int output_delayed_imports( FILE *outfile )
|
||||
idx++;
|
||||
}
|
||||
|
||||
fprintf( outfile, "\n \".data\\n\\t.align 8\\n\"\n" );
|
||||
fprintf( outfile, "\n \".data\\n\\t.align %d\\n\"\n", get_alignment(8) );
|
||||
pos = nb_delayed * 32;
|
||||
for (i = 0; i < nb_imports; i++)
|
||||
{
|
||||
@ -636,8 +661,11 @@ static int output_delayed_imports( FILE *outfile )
|
||||
fprintf( outfile, "ld [%%g1+%%o7], %%g1\\n\\t" );
|
||||
fprintf( outfile, "jmp %%g1\\n\\trestore\\n" );
|
||||
}
|
||||
|
||||
#elif defined(__PPC__)
|
||||
fprintf(outfile, "#error: DELAYED IMPORTS NOT SUPPORTED ON PPC!!!\n");
|
||||
#else
|
||||
#error You need to define import thunks for your architecture!
|
||||
#error You need to define delayed import thunks for your architecture!
|
||||
#endif
|
||||
fprintf( outfile, "\"\n" );
|
||||
}
|
||||
|
@ -591,8 +591,13 @@ SPEC_TYPE ParseTopLevel( FILE *file )
|
||||
name = GetToken(0);
|
||||
if (!strcmp(name, "delay"))
|
||||
{
|
||||
|
||||
name = GetToken(0);
|
||||
#ifndef __PPC__
|
||||
delay = 1;
|
||||
#else
|
||||
warning( "The 'delay' option is not yet supported on the PPC. 'delay' will be ignored.\n");
|
||||
#endif /* __PPC__ */
|
||||
}
|
||||
else fatal_error( "Unknown option '%s' for import directive\n", name );
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ static void BuildCallFrom16Core( FILE *outfile, int reg_func, int thunk, int sho
|
||||
char *name = thunk? "thunk" : reg_func? "regs" : short_ret? "word" : "long";
|
||||
|
||||
/* Function header */
|
||||
fprintf( outfile, "\n\t.align 4\n" );
|
||||
fprintf( outfile, "\n\t.align %d\n", get_alignment(4) );
|
||||
#ifdef USE_STABS
|
||||
fprintf( outfile, ".stabs \"__wine_call_from_16_%s:F1\",36,0,0," PREFIX "__wine_call_from_16_%s\n", name, name);
|
||||
#endif
|
||||
@ -448,7 +448,7 @@ static void BuildCallTo16Core( FILE *outfile, int short_ret, int reg_func )
|
||||
short_ret? "word" : "long";
|
||||
|
||||
/* Function header */
|
||||
fprintf( outfile, "\n\t.align 4\n" );
|
||||
fprintf( outfile, "\n\t.align %d\n", get_alignment(4) );
|
||||
#ifdef USE_STABS
|
||||
fprintf( outfile, ".stabs \"wine_call_to_16_%s:F1\",36,0,0," PREFIX "wine_call_to_16_%s\n",
|
||||
name, name);
|
||||
@ -725,7 +725,7 @@ static void BuildRet16Func( FILE *outfile )
|
||||
|
||||
/* Declare the return address and data selector variables */
|
||||
|
||||
fprintf( outfile, "\n\t.align 4\n" );
|
||||
fprintf( outfile, "\n\t.align %d\n", get_alignment(4) );
|
||||
fprintf( outfile, "\t.globl " PREFIX "CallTo16_DataSelector\n" );
|
||||
fprintf( outfile, PREFIX "CallTo16_DataSelector:\t.long 0\n" );
|
||||
fprintf( outfile, "\t.globl " PREFIX "CallTo16_RetAddr\n" );
|
||||
@ -830,7 +830,7 @@ static void BuildCallTo32CBClient( FILE *outfile, BOOL isEx )
|
||||
|
||||
/* Function header */
|
||||
|
||||
fprintf( outfile, "\n\t.align 4\n" );
|
||||
fprintf( outfile, "\n\t.align %d\n", get_alignment(4) );
|
||||
#ifdef USE_STABS
|
||||
fprintf( outfile, ".stabs \"CALL32_%s:F1\",36,0,0," PREFIX "CALL32_%s\n",
|
||||
name, name );
|
||||
@ -1019,7 +1019,7 @@ static void BuildCallFrom32Regs( FILE *outfile )
|
||||
|
||||
/* Function header */
|
||||
|
||||
fprintf( outfile, "\n\t.align 4\n" );
|
||||
fprintf( outfile, "\n\t.align %d\n", get_alignment(4) );
|
||||
#ifdef USE_STABS
|
||||
fprintf( outfile, ".stabs \"CALL32_Regs:F1\",36,0,0," PREFIX "CALL32_Regs\n" );
|
||||
#endif
|
||||
|
@ -800,6 +800,10 @@ void BuildSpec16File( FILE *outfile )
|
||||
fprintf( outfile, " \"\\tcall " PREFIX "__wine_spec_%s_init\\n\"\n", DLLName );
|
||||
fprintf( outfile, " \"\\tnop\\n\"\n" );
|
||||
fprintf( outfile, " \"\\t.previous\\n\");\n" );
|
||||
#elif defined(__PPC__)
|
||||
fprintf( outfile, "asm(\"\\t.section\t.init ,\\\"ax\\\"\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tbl " PREFIX "__wine_spec_%s_init\\n\"\n", DLLName );
|
||||
fprintf( outfile, " \"\\t.previous\\n\");\n" );
|
||||
#else
|
||||
#error You need to define the DLL constructor for your architecture
|
||||
#endif
|
||||
|
@ -117,7 +117,7 @@ static int output_exports( FILE *outfile, int nr_exports )
|
||||
if (!nr_exports) return 0;
|
||||
|
||||
fprintf( outfile, "asm(\".data\\n\"\n" );
|
||||
fprintf( outfile, " \"\\t.align 4\\n\"\n" );
|
||||
fprintf( outfile, " \"\\t.align %d\\n\"\n", get_alignment(4) );
|
||||
fprintf( outfile, " \"" PREFIX "__wine_spec_exports:\\n\"\n" );
|
||||
|
||||
/* export directory header */
|
||||
@ -194,7 +194,7 @@ static int output_exports( FILE *outfile, int nr_exports )
|
||||
|
||||
/* output the function names */
|
||||
|
||||
fprintf( outfile, " \"\\t.text\\n\"\n" );
|
||||
fprintf( outfile, " \"\\t.text 1\\n\"\n" );
|
||||
fprintf( outfile, " \"__wine_spec_exp_names:\\n\"\n" );
|
||||
for (i = 0; i < nb_names; i++)
|
||||
fprintf( outfile, " \"\\t" STRING " \\\"%s\\\"\\n\"\n", Names[i]->name );
|
||||
@ -226,7 +226,7 @@ static int output_exports( FILE *outfile, int nr_exports )
|
||||
if (odp && odp->type == TYPE_FORWARD)
|
||||
fprintf( outfile, " \"\\t" STRING " \\\"%s\\\"\\n\"\n", odp->link_name );
|
||||
}
|
||||
fprintf( outfile, " \"\\t.align 4\\n\"\n" );
|
||||
fprintf( outfile, " \"\\t.align %d\\n\"\n", get_alignment(4) );
|
||||
total_size += (fwd_size + 3) & ~3;
|
||||
}
|
||||
|
||||
@ -402,12 +402,13 @@ static void output_register_funcs( FILE *outfile )
|
||||
if (odp->type != TYPE_REGISTER) continue;
|
||||
name = make_internal_name( odp, "regs" );
|
||||
fprintf( outfile,
|
||||
"asm(\".align 4\\n\\t\"\n"
|
||||
"asm(\".align %d\\n\\t\"\n"
|
||||
" \"" __ASM_FUNC("%s") "\\n\\t\"\n"
|
||||
" \"" PREFIX "%s:\\n\\t\"\n"
|
||||
" \"call " PREFIX "CALL32_Regs\\n\\t\"\n"
|
||||
" \".long " PREFIX "%s\\n\\t\"\n"
|
||||
" \".byte %d,%d\");\n",
|
||||
get_alignment(4),
|
||||
name, name, odp->link_name,
|
||||
4 * strlen(odp->u.func.arg_types), 4 * strlen(odp->u.func.arg_types) );
|
||||
}
|
||||
@ -448,7 +449,7 @@ void BuildSpec32File( FILE *outfile )
|
||||
|
||||
fprintf( outfile, "extern char pe_header[];\n" );
|
||||
fprintf( outfile, "asm(\".section .text\\n\\t\"\n" );
|
||||
fprintf( outfile, " \".align %ld\\n\"\n", page_size );
|
||||
fprintf( outfile, " \".align %d\\n\"\n", get_alignment(page_size) );
|
||||
fprintf( outfile, " \"pe_header:\\t.fill %ld,1,0\\n\\t\");\n", page_size );
|
||||
|
||||
fprintf( outfile, "static const char dllname[] = \"%s\";\n\n", DLLName );
|
||||
@ -693,6 +694,18 @@ void BuildSpec32File( FILE *outfile )
|
||||
fprintf( outfile, " \"\\tnop\\n\"\n" );
|
||||
fprintf( outfile, " \"\\t.previous\\n\");\n" );
|
||||
}
|
||||
#elif defined(__PPC__)
|
||||
fprintf( outfile, "asm(\"\\t.section\t.init ,\\\"ax\\\"\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tbl " PREFIX "__wine_spec_%s_init\\n\"\n",
|
||||
DLLName );
|
||||
fprintf( outfile, " \"\\t.previous\\n\");\n" );
|
||||
if (nr_debug)
|
||||
{
|
||||
fprintf( outfile, "asm(\"\\t.section\t.fini ,\\\"ax\\\"\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tbl " PREFIX "__wine_spec_%s_fini\\n\"\n",
|
||||
DLLName );
|
||||
fprintf( outfile, " \"\\t.previous\\n\");\n" );
|
||||
}
|
||||
#else
|
||||
#error You need to define the DLL constructor for your architecture
|
||||
#endif
|
||||
|
@ -116,3 +116,104 @@ void dump_bytes( FILE *outfile, const unsigned char *data, int len,
|
||||
}
|
||||
fprintf( outfile, "\n};\n" );
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
* Function: get_alignment
|
||||
*
|
||||
* Description:
|
||||
* According to the info page for gas, the .align directive behaves
|
||||
* differently on different systems. On some architectures, the
|
||||
* argument of a .align directive is the number of bytes to pad to, so
|
||||
* to align on an 8-byte boundary you'd say
|
||||
* .align 8
|
||||
* On other systems, the argument is "the number of low-order zero bits
|
||||
* that the location counter must have after advancement." So to
|
||||
* align on an 8-byte boundary you'd say
|
||||
* .align 3
|
||||
*
|
||||
* The reason gas is written this way is that it's trying to mimick
|
||||
* native assemblers for the various architectures it runs on. gas
|
||||
* provides other directives that work consistantly across
|
||||
* architectures, but of course we want to work on all arches with or
|
||||
* without gas. Hence this function.
|
||||
*
|
||||
*
|
||||
* Parameters:
|
||||
* alignBoundary -- the number of bytes to align to.
|
||||
* If we're on an architecture where
|
||||
* the assembler requires a 'number
|
||||
* of low-order zero bits' as a
|
||||
* .align argument, then this number
|
||||
* must be a power of 2.
|
||||
*
|
||||
*/
|
||||
int get_alignment(int alignBoundary)
|
||||
{
|
||||
#ifdef __PPC__
|
||||
|
||||
int n = 0;
|
||||
|
||||
switch(alignBoundary)
|
||||
{
|
||||
case 2:
|
||||
n = 1;
|
||||
break;
|
||||
case 4:
|
||||
n = 2;
|
||||
break;
|
||||
case 8:
|
||||
n = 3;
|
||||
break;
|
||||
case 16:
|
||||
n = 4;
|
||||
break;
|
||||
case 32:
|
||||
n = 5;
|
||||
break;
|
||||
case 64:
|
||||
n = 6;
|
||||
break;
|
||||
case 128:
|
||||
n = 7;
|
||||
break;
|
||||
case 256:
|
||||
n = 8;
|
||||
break;
|
||||
case 512:
|
||||
n = 9;
|
||||
break;
|
||||
case 1024:
|
||||
n = 10;
|
||||
break;
|
||||
case 2048:
|
||||
n = 11;
|
||||
break;
|
||||
case 4096:
|
||||
n = 12;
|
||||
break;
|
||||
case 8192:
|
||||
n = 13;
|
||||
break;
|
||||
case 16384:
|
||||
n = 14;
|
||||
break;
|
||||
case 32768:
|
||||
n = 15;
|
||||
break;
|
||||
case 65536:
|
||||
n = 16;
|
||||
break;
|
||||
default:
|
||||
fatal_error("Alignment to %d-byte boundary not supported on this architecture.\n",
|
||||
alignBoundary);
|
||||
}
|
||||
return n;
|
||||
|
||||
#elif defined(__i386__) || defined(__sparc__)
|
||||
|
||||
return alignBoundary;
|
||||
|
||||
#else
|
||||
#error "How does the '.align' assembler directive work on your architecture?"
|
||||
#endif
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user