Beginnings of an infrastructure to allow specifying the target CPU and
platform at run-time.
This commit is contained in:
parent
51bb3f6079
commit
803c8d9693
|
@ -109,6 +109,19 @@ typedef struct
|
|||
struct resource *resources; /* array of dll resources (format differs between Win16/Win32) */
|
||||
} DLLSPEC;
|
||||
|
||||
enum target_cpu
|
||||
{
|
||||
CPU_x86, CPU_SPARC, CPU_ALPHA, CPU_POWERPC
|
||||
};
|
||||
|
||||
enum target_platform
|
||||
{
|
||||
PLATFORM_UNSPECIFIED, PLATFORM_APPLE, PLATFORM_SVR4, PLATFORM_WINDOWS
|
||||
};
|
||||
|
||||
extern enum target_cpu target_cpu;
|
||||
extern enum target_platform target_platform;
|
||||
|
||||
/* entry point flags */
|
||||
#define FLAG_NORELAY 0x01 /* don't use relay debugging for this function */
|
||||
#define FLAG_NONAME 0x02 /* don't import function by name */
|
||||
|
@ -166,7 +179,11 @@ extern int remove_stdcall_decoration( char *name );
|
|||
extern DLLSPEC *alloc_dll_spec(void);
|
||||
extern void free_dll_spec( DLLSPEC *spec );
|
||||
extern const char *make_c_identifier( const char *str );
|
||||
extern int get_alignment(int alignBoundary);
|
||||
extern unsigned int get_alignment(unsigned int align);
|
||||
extern unsigned int get_page_size(void);
|
||||
extern const char *func_name( const char *func );
|
||||
extern const char *func_declaration( const char *func );
|
||||
extern const char *func_size( const char *func );
|
||||
|
||||
extern void add_import_dll( const char *name, const char *filename );
|
||||
extern void add_delayed_import( const char *name );
|
||||
|
|
|
@ -121,23 +121,16 @@ static const char * const default_ignored_symbols[] =
|
|||
"tanh"
|
||||
};
|
||||
|
||||
#ifdef __powerpc__
|
||||
# ifdef __APPLE__
|
||||
# define ppc_high(mem) "ha16(" mem ")"
|
||||
# define ppc_low(mem) "lo16(" mem ")"
|
||||
static const char * const ppc_reg[32] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
||||
"r8", "r9", "r10","r11","r12","r13","r14","r15",
|
||||
"r16","r17","r18","r19","r20","r21","r22","r23",
|
||||
"r24","r25","r26","r27","r28","r29","r30","r31" };
|
||||
# else /* __APPLE__ */
|
||||
# define ppc_high(mem) "(" mem ")@hi"
|
||||
# define ppc_low(mem) "(" mem ")@l"
|
||||
static const char * const ppc_reg[32] = { "0", "1", "2", "3", "4", "5", "6", "7",
|
||||
"8", "9", "10","11","12","13","14","15",
|
||||
"16","17","18","19","20","21","22","23",
|
||||
"24","25","26","27","28","29","30","31" };
|
||||
# endif /* __APPLE__ */
|
||||
#endif /* __powerpc__ */
|
||||
|
||||
static inline const char *ppc_reg( int reg )
|
||||
{
|
||||
static const char * const ppc_regs[32] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
||||
"r8", "r9", "r10","r11","r12","r13","r14","r15",
|
||||
"r16","r17","r18","r19","r20","r21","r22","r23",
|
||||
"r24","r25","r26","r27","r28","r29","r30","r31" };
|
||||
if (target_platform == PLATFORM_APPLE) return ppc_regs[reg];
|
||||
return ppc_regs[reg] + 1; /* skip the 'r' */
|
||||
}
|
||||
|
||||
/* compare function names; helper for resolve_imports */
|
||||
static int name_cmp( const void *name, const void *entry )
|
||||
|
@ -187,9 +180,8 @@ inline static void sort_symbols( char **table, int size )
|
|||
|
||||
inline static void output_function_size( FILE *outfile, const char *name )
|
||||
{
|
||||
#ifdef HAVE_ASM_DOT_SIZE
|
||||
fprintf( outfile, " \"\\t.size " __ASM_NAME("%s") ", . - " __ASM_NAME("%s") "\\n\"\n", name, name);
|
||||
#endif
|
||||
const char *size = func_size( name );
|
||||
if (size[0]) fprintf( outfile, " \"\\t%s\\n\"\n", size );
|
||||
}
|
||||
|
||||
/* free an import structure */
|
||||
|
@ -603,15 +595,17 @@ static const char *ldcombine_files( char **argv )
|
|||
/* read in the list of undefined symbols */
|
||||
void read_undef_symbols( char **argv )
|
||||
{
|
||||
static const char name_prefix[] = __ASM_NAME("");
|
||||
static const int prefix_len = sizeof(name_prefix) - 1;
|
||||
size_t prefix_len;
|
||||
FILE *f;
|
||||
char *cmd, buffer[1024];
|
||||
char *cmd, buffer[1024], name_prefix[16];
|
||||
int err;
|
||||
const char *name;
|
||||
|
||||
if (!argv[0]) return;
|
||||
|
||||
strcpy( name_prefix, func_name("") );
|
||||
prefix_len = strlen( name_prefix );
|
||||
|
||||
undef_size = nb_undef_symbols = 0;
|
||||
|
||||
/* if we have multiple object files, link them together */
|
||||
|
@ -695,91 +689,105 @@ int resolve_imports( DLLSPEC *spec )
|
|||
static void output_import_thunk( FILE *outfile, const char *name, const char *table, int pos )
|
||||
{
|
||||
fprintf( outfile, " \"\\t.align %d\\n\"\n", get_alignment(8) );
|
||||
fprintf( outfile, " \"\\t" __ASM_FUNC("%s") "\\n\"\n", name );
|
||||
fprintf( outfile, " \"\\t%s\\n\"\n", func_declaration(name) );
|
||||
fprintf( outfile, " \"\\t.globl " __ASM_NAME("%s") "\\n\"\n", name );
|
||||
fprintf( outfile, " \"" __ASM_NAME("%s") ":\\n\"\n", name);
|
||||
|
||||
#if defined(__i386__)
|
||||
if (!UsePIC)
|
||||
switch(target_cpu)
|
||||
{
|
||||
if (strstr( name, "__wine_call_from_16" )) fprintf( outfile, " \"\\t.byte 0x2e\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tjmp *(imports+%d)\\n\"\n", pos );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!strcmp( name, "__wine_call_from_32_regs" ) ||
|
||||
!strcmp( name, "__wine_call_from_16_regs" ))
|
||||
case CPU_x86:
|
||||
if (!UsePIC)
|
||||
{
|
||||
/* special case: need to preserve all registers */
|
||||
fprintf( outfile, " \"\\tpushl %%eax\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tpushfl\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tcall .L__wine_spec_%s\\n\"\n", name );
|
||||
fprintf( outfile, " \".L__wine_spec_%s:\\n\"\n", name );
|
||||
fprintf( outfile, " \"\\tpopl %%eax\\n\"\n" );
|
||||
fprintf( outfile, " \"\\taddl $%d+" __ASM_NAME("%s") "-.L__wine_spec_%s,%%eax\\n\"\n", pos, table, name );
|
||||
if (!strcmp( name, "__wine_call_from_16_regs" ))
|
||||
fprintf( outfile, " \"\\t.byte 0x2e\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tmovl 0(%%eax),%%eax\\n\"\n" );
|
||||
fprintf( outfile, " \"\\txchgl 4(%%esp),%%eax\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tpopfl\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tret\\n\"\n" );
|
||||
if (strstr( name, "__wine_call_from_16" )) fprintf( outfile, " \"\\t.byte 0x2e\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tjmp *(imports+%d)\\n\"\n", pos );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( outfile, " \"\\tcall .L__wine_spec_%s\\n\"\n", name );
|
||||
fprintf( outfile, " \".L__wine_spec_%s:\\n\"\n", name );
|
||||
fprintf( outfile, " \"\\tpopl %%eax\\n\"\n" );
|
||||
fprintf( outfile, " \"\\taddl $%d+" __ASM_NAME("%s") "-.L__wine_spec_%s,%%eax\\n\"\n", pos, table, name );
|
||||
if (strstr( name, "__wine_call_from_16" ))
|
||||
fprintf( outfile, " \"\\t.byte 0x2e\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tjmp *0(%%eax)\\n\"\n" );
|
||||
if (!strcmp( name, "__wine_call_from_32_regs" ) ||
|
||||
!strcmp( name, "__wine_call_from_16_regs" ))
|
||||
{
|
||||
/* special case: need to preserve all registers */
|
||||
fprintf( outfile, " \"\\tpushl %%eax\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tpushfl\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tcall .L__wine_spec_%s\\n\"\n", name );
|
||||
fprintf( outfile, " \".L__wine_spec_%s:\\n\"\n", name );
|
||||
fprintf( outfile, " \"\\tpopl %%eax\\n\"\n" );
|
||||
fprintf( outfile, " \"\\taddl $%d+" __ASM_NAME("%s") "-.L__wine_spec_%s,%%eax\\n\"\n", pos, table, name );
|
||||
if (!strcmp( name, "__wine_call_from_16_regs" ))
|
||||
fprintf( outfile, " \"\\t.byte 0x2e\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tmovl 0(%%eax),%%eax\\n\"\n" );
|
||||
fprintf( outfile, " \"\\txchgl 4(%%esp),%%eax\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tpopfl\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tret\\n\"\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( outfile, " \"\\tcall .L__wine_spec_%s\\n\"\n", name );
|
||||
fprintf( outfile, " \".L__wine_spec_%s:\\n\"\n", name );
|
||||
fprintf( outfile, " \"\\tpopl %%eax\\n\"\n" );
|
||||
fprintf( outfile, " \"\\taddl $%d+" __ASM_NAME("%s") "-.L__wine_spec_%s,%%eax\\n\"\n", pos, table, name );
|
||||
if (strstr( name, "__wine_call_from_16" ))
|
||||
fprintf( outfile, " \"\\t.byte 0x2e\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tjmp *0(%%eax)\\n\"\n" );
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CPU_SPARC:
|
||||
if ( !UsePIC )
|
||||
{
|
||||
fprintf( outfile, " \"\\tsethi %%hi(%s+%d), %%g1\\n\"\n", table, pos );
|
||||
fprintf( outfile, " \"\\tld [%%g1+%%lo(%s+%d)], %%g1\\n\"\n", table, pos );
|
||||
fprintf( outfile, " \"\\tjmp %%g1\\n\\tnop\\n\"\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Hmpf. Stupid sparc assembler always interprets global variable
|
||||
names as GOT offsets, so we have to do it the long way ... */
|
||||
fprintf( outfile, " \"\\tsave %%sp, -96, %%sp\\n\"\n" );
|
||||
fprintf( outfile, " \"0:\\tcall 1f\\n\\tnop\\n\"\n" );
|
||||
fprintf( outfile, " \"1:\\tsethi %%hi(%s+%d-0b), %%g1\\n\"\n", table, pos );
|
||||
fprintf( outfile, " \"\\tor %%g1, %%lo(%s+%d-0b), %%g1\\n\"\n", table, pos );
|
||||
fprintf( outfile, " \"\\tld [%%g1+%%o7], %%g1\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tjmp %%g1\\n\\trestore\\n\"\n" );
|
||||
}
|
||||
break;
|
||||
case CPU_ALPHA:
|
||||
fprintf( outfile, " \"\\tlda $0,%s\\n\"\n", table );
|
||||
fprintf( outfile, " \"\\tlda $0,%d($0)\\n\"\n", pos);
|
||||
fprintf( outfile, " \"\\tjmp $31,($0)\\n\"\n" );
|
||||
break;
|
||||
case CPU_POWERPC:
|
||||
fprintf(outfile, " \"\\taddi %s, %s, -0x4\\n\"\n", ppc_reg(1), ppc_reg(1));
|
||||
fprintf(outfile, " \"\\tstw %s, 0(%s)\\n\"\n", ppc_reg(9), ppc_reg(1));
|
||||
fprintf(outfile, " \"\\taddi %s, %s, -0x4\\n\"\n", ppc_reg(1), ppc_reg(1));
|
||||
fprintf(outfile, " \"\\tstw %s, 0(%s)\\n\"\n", ppc_reg(8), ppc_reg(1));
|
||||
fprintf(outfile, " \"\\taddi %s, %s, -0x4\\n\"\n", ppc_reg(1), ppc_reg(1));
|
||||
fprintf(outfile, " \"\\tstw %s, 0(%s)\\n\"\n", ppc_reg(7), ppc_reg(1));
|
||||
if (target_platform == PLATFORM_APPLE)
|
||||
{
|
||||
fprintf(outfile, " \"\\tlis %s, ha16(" __ASM_NAME("%s") "+ %d)\\n\"\n",
|
||||
ppc_reg(9), table, pos);
|
||||
fprintf(outfile, " \"\\tla %s, lo16(" __ASM_NAME("%s") "+ %d)(%s)\\n\"\n",
|
||||
ppc_reg(8), table, pos, ppc_reg(9));
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(outfile, " \"\\tlis %s, (" __ASM_NAME("%s") "+ %d)@hi\\n\"\n",
|
||||
ppc_reg(9), table, pos);
|
||||
fprintf(outfile, " \"\\tla %s, (" __ASM_NAME("%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, " \"\\tmtctr %s\\n\"\n", ppc_reg(7));
|
||||
fprintf(outfile, " \"\\tlwz %s, 0(%s)\\n\"\n", ppc_reg(7), ppc_reg(1));
|
||||
fprintf(outfile, " \"\\taddi %s, %s, 0x4\\n\"\n", ppc_reg(1), ppc_reg(1));
|
||||
fprintf(outfile, " \"\\tlwz %s, 0(%s)\\n\"\n", ppc_reg(8), ppc_reg(1));
|
||||
fprintf(outfile, " \"\\taddi %s, %s, 0x4\\n\"\n", ppc_reg(1), ppc_reg(1));
|
||||
fprintf(outfile, " \"\\tlwz %s, 0(%s)\\n\"\n", ppc_reg(9), ppc_reg(1));
|
||||
fprintf(outfile, " \"\\taddi %s, %s, 0x4\\n\"\n", ppc_reg(1), ppc_reg(1));
|
||||
fprintf(outfile, " \"\\tbctr\\n\"\n");
|
||||
break;
|
||||
}
|
||||
#elif defined(__sparc__)
|
||||
if ( !UsePIC )
|
||||
{
|
||||
fprintf( outfile, " \"\\tsethi %%hi(%s+%d), %%g1\\n\"\n", table, pos );
|
||||
fprintf( outfile, " \"\\tld [%%g1+%%lo(%s+%d)], %%g1\\n\"\n", table, pos );
|
||||
fprintf( outfile, " \"\\tjmp %%g1\\n\\tnop\\n\"\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Hmpf. Stupid sparc assembler always interprets global variable
|
||||
names as GOT offsets, so we have to do it the long way ... */
|
||||
fprintf( outfile, " \"\\tsave %%sp, -96, %%sp\\n\"\n" );
|
||||
fprintf( outfile, " \"0:\\tcall 1f\\n\\tnop\\n\"\n" );
|
||||
fprintf( outfile, " \"1:\\tsethi %%hi(%s+%d-0b), %%g1\\n\"\n", table, pos );
|
||||
fprintf( outfile, " \"\\tor %%g1, %%lo(%s+%d-0b), %%g1\\n\"\n", table, pos );
|
||||
fprintf( outfile, " \"\\tld [%%g1+%%o7], %%g1\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tjmp %%g1\\n\\trestore\\n\"\n" );
|
||||
}
|
||||
#elif defined(__powerpc__)
|
||||
fprintf(outfile, " \"\\taddi %s, %s, -0x4\\n\"\n", ppc_reg[1], ppc_reg[1]);
|
||||
fprintf(outfile, " \"\\tstw %s, 0(%s)\\n\"\n", ppc_reg[9], ppc_reg[1]);
|
||||
fprintf(outfile, " \"\\taddi %s, %s, -0x4\\n\"\n", ppc_reg[1], ppc_reg[1]);
|
||||
fprintf(outfile, " \"\\tstw %s, 0(%s)\\n\"\n", ppc_reg[8], ppc_reg[1]);
|
||||
fprintf(outfile, " \"\\taddi %s, %s, -0x4\\n\"\n", ppc_reg[1], ppc_reg[1]);
|
||||
fprintf(outfile, " \"\\tstw %s, 0(%s)\\n\"\n", ppc_reg[7], ppc_reg[1]);
|
||||
fprintf(outfile, " \"\\tlis %s, " ppc_high(__ASM_NAME("%s") "+ %d") "\\n\"\n",
|
||||
ppc_reg[9], table, pos);
|
||||
fprintf(outfile, " \"\\tla %s, " ppc_low (__ASM_NAME("%s") "+ %d") "(%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, " \"\\tmtctr %s\\n\"\n", ppc_reg[7]);
|
||||
fprintf(outfile, " \"\\tlwz %s, 0(%s)\\n\"\n", ppc_reg[7], ppc_reg[1]);
|
||||
fprintf(outfile, " \"\\taddi %s, %s, 0x4\\n\"\n", ppc_reg[1], ppc_reg[1]);
|
||||
fprintf(outfile, " \"\\tlwz %s, 0(%s)\\n\"\n", ppc_reg[8], ppc_reg[1]);
|
||||
fprintf(outfile, " \"\\taddi %s, %s, 0x4\\n\"\n", ppc_reg[1], ppc_reg[1]);
|
||||
fprintf(outfile, " \"\\tlwz %s, 0(%s)\\n\"\n", ppc_reg[9], ppc_reg[1]);
|
||||
fprintf(outfile, " \"\\taddi %s, %s, 0x4\\n\"\n", ppc_reg[1], ppc_reg[1]);
|
||||
fprintf(outfile, " \"\\tbctr\\n\"\n");
|
||||
#elif defined(__ALPHA__)
|
||||
fprintf( outfile, " \"\\tlda $0,%s\\n\"\n", table );
|
||||
fprintf( outfile, " \"\\tlda $0,%d($0)\\n\"\n", pos);
|
||||
fprintf( outfile, " \"\\tjmp $31,($0)\\n\"\n" );
|
||||
#else
|
||||
#error You need to define import thunks for your architecture!
|
||||
#endif
|
||||
output_function_size( outfile, name );
|
||||
}
|
||||
|
||||
|
@ -973,7 +981,7 @@ static int output_delayed_imports( FILE *outfile, const DLLSPEC *spec )
|
|||
/* output the delayed import thunks of a Win32 module */
|
||||
static void output_delayed_import_thunks( FILE *outfile, const DLLSPEC *spec )
|
||||
{
|
||||
int i, idx, j, pos;
|
||||
int i, idx, j, pos, extra_stack_storage = 0;
|
||||
static const char delayed_import_loaders[] = "__wine_spec_delayed_import_loaders";
|
||||
static const char delayed_import_thunks[] = "__wine_spec_delayed_import_thunks";
|
||||
|
||||
|
@ -983,75 +991,75 @@ static void output_delayed_import_thunks( FILE *outfile, const DLLSPEC *spec )
|
|||
fprintf( outfile, "asm(\".text\\n\"\n" );
|
||||
fprintf( outfile, " \"\\t.align %d\\n\"\n", get_alignment(8) );
|
||||
fprintf( outfile, " \"" __ASM_NAME("%s") ":\\n\"\n", delayed_import_loaders);
|
||||
fprintf( outfile, " \"\\t" __ASM_FUNC("__wine_delay_load_asm") "\\n\"\n" );
|
||||
fprintf( outfile, " \"\\t%s\\n\"\n", func_declaration("__wine_delay_load_asm") );
|
||||
fprintf( outfile, " \"" __ASM_NAME("__wine_delay_load_asm") ":\\n\"\n" );
|
||||
#if defined(__i386__)
|
||||
fprintf( outfile, " \"\\tpushl %%ecx\\n\\tpushl %%edx\\n\\tpushl %%eax\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tcall " __ASM_NAME("__wine_delay_load") "\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tpopl %%edx\\n\\tpopl %%ecx\\n\\tjmp *%%eax\\n\"\n" );
|
||||
#elif defined(__sparc__)
|
||||
fprintf( outfile, " \"\\tsave %%sp, -96, %%sp\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tcall " __ASM_NAME("__wine_delay_load") "\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tmov %%g1, %%o0\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tjmp %%o0\\n\\trestore\\n\"\n" );
|
||||
#elif defined(__powerpc__)
|
||||
# if defined(__APPLE__)
|
||||
/* On darwin an extra 56 bytes must be allowed for the linkage area+param area */
|
||||
# define extra_stack_storage 56
|
||||
# else
|
||||
# define extra_stack_storage 0
|
||||
# endif
|
||||
/* 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, " \"\\tstw %s, %d(%s)\\n\"\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\"\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\"\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\"\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\"\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]);
|
||||
switch(target_cpu)
|
||||
{
|
||||
case CPU_x86:
|
||||
fprintf( outfile, " \"\\tpushl %%ecx\\n\\tpushl %%edx\\n\\tpushl %%eax\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tcall " __ASM_NAME("__wine_delay_load") "\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tpopl %%edx\\n\\tpopl %%ecx\\n\\tjmp *%%eax\\n\"\n" );
|
||||
break;
|
||||
case CPU_SPARC:
|
||||
fprintf( outfile, " \"\\tsave %%sp, -96, %%sp\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tcall " __ASM_NAME("__wine_delay_load") "\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tmov %%g1, %%o0\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tjmp %%o0\\n\\trestore\\n\"\n" );
|
||||
break;
|
||||
case CPU_ALPHA:
|
||||
fprintf( outfile, " \"\\tjsr $26," __ASM_NAME("__wine_delay_load") "\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tjmp $31,($0)\\n\"\n" );
|
||||
break;
|
||||
case CPU_POWERPC:
|
||||
if (target_platform == PLATFORM_APPLE) extra_stack_storage = 56;
|
||||
|
||||
/* r0 -> r3 (arg1) */
|
||||
fprintf( outfile, " \"\\tmr %s, %s\\n\"\n", ppc_reg[3], ppc_reg[0]);
|
||||
/* 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, " \"\\tstw %s, %d(%s)\\n\"\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\"\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\"\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\"\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\"\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));
|
||||
|
||||
/* save return address */
|
||||
fprintf( outfile, " \"\\tmflr %s\\n\"\n", ppc_reg[0]);
|
||||
fprintf( outfile, " \"\\tstw %s, %d(%s)\\n\"\n", ppc_reg[0], 44+extra_stack_storage, ppc_reg[1]);
|
||||
/* r0 -> r3 (arg1) */
|
||||
fprintf( outfile, " \"\\tmr %s, %s\\n\"\n", ppc_reg(3), ppc_reg(0));
|
||||
|
||||
/* Call the __wine_delay_load function, arg1 is arg1. */
|
||||
fprintf( outfile, " \"\\tbl " __ASM_NAME("__wine_delay_load") "\\n\"\n");
|
||||
/* save return address */
|
||||
fprintf( outfile, " \"\\tmflr %s\\n\"\n", ppc_reg(0));
|
||||
fprintf( outfile, " \"\\tstw %s, %d(%s)\\n\"\n", ppc_reg(0), 44+extra_stack_storage, ppc_reg(1));
|
||||
|
||||
/* Load return value from call into ctr register */
|
||||
fprintf( outfile, " \"\\tmtctr %s\\n\"\n", ppc_reg[3]);
|
||||
/* Call the __wine_delay_load function, arg1 is arg1. */
|
||||
fprintf( outfile, " \"\\tbl " __ASM_NAME("__wine_delay_load") "\\n\"\n");
|
||||
|
||||
/* 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\"\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\"\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\"\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\"\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\"\n", ppc_reg[12],40+extra_stack_storage, ppc_reg[1]);
|
||||
/* Load return value from call into ctr register */
|
||||
fprintf( outfile, " \"\\tmtctr %s\\n\"\n", ppc_reg(3));
|
||||
|
||||
/* 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, " \"\\tmtlr %s\\n\"\n", ppc_reg[0]);
|
||||
fprintf( outfile, " \"\\taddi %s, %s, %d\\n\"\n", ppc_reg[1], ppc_reg[1], 48+extra_stack_storage);
|
||||
/* 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\"\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\"\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\"\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\"\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\"\n", ppc_reg(12),40+extra_stack_storage, ppc_reg(1));
|
||||
|
||||
/* branch to ctr register. */
|
||||
fprintf( outfile, " \"bctr\\n\"\n");
|
||||
#elif defined(__ALPHA__)
|
||||
fprintf( outfile, " \"\\tjsr $26," __ASM_NAME("__wine_delay_load") "\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tjmp $31,($0)\\n\"\n" );
|
||||
#else
|
||||
#error You need to defined delayed import thunks for your architecture!
|
||||
#endif
|
||||
/* 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, " \"\\tmtlr %s\\n\"\n", ppc_reg(0));
|
||||
fprintf( outfile, " \"\\taddi %s, %s, %d\\n\"\n", ppc_reg(1), ppc_reg(1), 48+extra_stack_storage);
|
||||
|
||||
/* branch to ctr register. */
|
||||
fprintf( outfile, " \"bctr\\n\"\n");
|
||||
break;
|
||||
}
|
||||
output_function_size( outfile, "__wine_delay_load_asm" );
|
||||
|
||||
for (i = idx = 0; i < nb_imports; i++)
|
||||
|
@ -1064,43 +1072,51 @@ static void output_delayed_import_thunks( FILE *outfile, const DLLSPEC *spec )
|
|||
const char *name = odp->name ? odp->name : odp->export_name;
|
||||
|
||||
sprintf( buffer, "__wine_delay_imp_%d_%s", i, name );
|
||||
fprintf( outfile, " \"\\t" __ASM_FUNC("%s") "\\n\"\n", buffer );
|
||||
fprintf( outfile, " \"\\t%s\\n\"\n", func_declaration(buffer) );
|
||||
fprintf( outfile, " \"" __ASM_NAME("%s") ":\\n\"\n", buffer );
|
||||
#if defined(__i386__)
|
||||
fprintf( outfile, " \"\\tmovl $%d, %%eax\\n\"\n", (idx << 16) | j );
|
||||
fprintf( outfile, " \"\\tjmp " __ASM_NAME("__wine_delay_load_asm") "\\n\"\n" );
|
||||
#elif defined(__sparc__)
|
||||
fprintf( outfile, " \"\\tset %d, %%g1\\n\"\n", (idx << 16) | j );
|
||||
fprintf( outfile, " \"\\tb,a " __ASM_NAME("__wine_delay_load_asm") "\\n\"\n" );
|
||||
#elif defined(__powerpc__)
|
||||
#ifdef __APPLE__
|
||||
/* On Darwin we can use r0 and r2 */
|
||||
/* Upper part in r2 */
|
||||
fprintf( outfile, " \"\\tlis %s, %d\\n\"\n", ppc_reg[2], idx);
|
||||
/* 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, " \"\\tb " __ASM_NAME("__wine_delay_load_asm") "\\n\"\n");
|
||||
#else /* __APPLE__ */
|
||||
/* On linux we can't use r2 since r2 is not a scratch register (hold the TOC) */
|
||||
/* Save r13 on the stack */
|
||||
fprintf( outfile, " \"\\taddi %s, %s, -0x4\\n\"\n", ppc_reg[1], ppc_reg[1]);
|
||||
fprintf( outfile, " \"\\tstw %s, 0(%s)\\n\"\n", ppc_reg[13], ppc_reg[1]);
|
||||
/* Upper part in r13 */
|
||||
fprintf( outfile, " \"\\tlis %s, %d\\n\"\n", ppc_reg[13], idx);
|
||||
/* 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);
|
||||
/* Restore r13 */
|
||||
fprintf( outfile, " \"\\tstw %s, 0(%s)\\n\"\n", ppc_reg[13], ppc_reg[1]);
|
||||
fprintf( outfile, " \"\\taddic %s, %s, 0x4\\n\"\n", ppc_reg[1], ppc_reg[1]);
|
||||
fprintf( outfile, " \"\\tb " __ASM_NAME("__wine_delay_load_asm") "\\n\"\n");
|
||||
#endif /* __APPLE__ */
|
||||
#elif defined(__ALPHA__)
|
||||
fprintf( outfile, " \"\\tlda $0,%d($31)\\n\"\n", j);
|
||||
fprintf( outfile, " \"\\tldah $0,%d($0)\\n\"\n", idx);
|
||||
fprintf( outfile, " \"\\tjmp $31," __ASM_NAME("__wine_delay_load_asm") "\\n\"\n" );
|
||||
#else
|
||||
#error You need to defined delayed import thunks for your architecture!
|
||||
#endif
|
||||
switch(target_cpu)
|
||||
{
|
||||
case CPU_x86:
|
||||
fprintf( outfile, " \"\\tmovl $%d, %%eax\\n\"\n", (idx << 16) | j );
|
||||
fprintf( outfile, " \"\\tjmp " __ASM_NAME("__wine_delay_load_asm") "\\n\"\n" );
|
||||
break;
|
||||
case CPU_SPARC:
|
||||
fprintf( outfile, " \"\\tset %d, %%g1\\n\"\n", (idx << 16) | j );
|
||||
fprintf( outfile, " \"\\tb,a " __ASM_NAME("__wine_delay_load_asm") "\\n\"\n" );
|
||||
break;
|
||||
case CPU_ALPHA:
|
||||
fprintf( outfile, " \"\\tlda $0,%d($31)\\n\"\n", j);
|
||||
fprintf( outfile, " \"\\tldah $0,%d($0)\\n\"\n", idx);
|
||||
fprintf( outfile, " \"\\tjmp $31," __ASM_NAME("__wine_delay_load_asm") "\\n\"\n" );
|
||||
break;
|
||||
case CPU_POWERPC:
|
||||
switch(target_platform)
|
||||
{
|
||||
case PLATFORM_APPLE:
|
||||
/* On Darwin we can use r0 and r2 */
|
||||
/* Upper part in r2 */
|
||||
fprintf( outfile, " \"\\tlis %s, %d\\n\"\n", ppc_reg(2), idx);
|
||||
/* 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, " \"\\tb " __ASM_NAME("__wine_delay_load_asm") "\\n\"\n");
|
||||
break;
|
||||
default:
|
||||
/* On linux we can't use r2 since r2 is not a scratch register (hold the TOC) */
|
||||
/* Save r13 on the stack */
|
||||
fprintf( outfile, " \"\\taddi %s, %s, -0x4\\n\"\n", ppc_reg(1), ppc_reg(1));
|
||||
fprintf( outfile, " \"\\tstw %s, 0(%s)\\n\"\n", ppc_reg(13), ppc_reg(1));
|
||||
/* Upper part in r13 */
|
||||
fprintf( outfile, " \"\\tlis %s, %d\\n\"\n", ppc_reg(13), idx);
|
||||
/* 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);
|
||||
/* Restore r13 */
|
||||
fprintf( outfile, " \"\\tstw %s, 0(%s)\\n\"\n", ppc_reg(13), ppc_reg(1));
|
||||
fprintf( outfile, " \"\\taddic %s, %s, 0x4\\n\"\n", ppc_reg(1), ppc_reg(1));
|
||||
fprintf( outfile, " \"\\tb " __ASM_NAME("__wine_delay_load_asm") "\\n\"\n");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
output_function_size( outfile, name );
|
||||
}
|
||||
idx++;
|
||||
|
|
|
@ -46,12 +46,28 @@ int nb_lib_paths = 0;
|
|||
int nb_errors = 0;
|
||||
int display_warnings = 0;
|
||||
int kill_at = 0;
|
||||
|
||||
/* we only support relay debugging on i386 */
|
||||
#ifdef __i386__
|
||||
int debugging = 1;
|
||||
#else
|
||||
int debugging = 0;
|
||||
|
||||
#ifdef __i386__
|
||||
enum target_cpu target_cpu = CPU_x86;
|
||||
#elif defined(__sparc__)
|
||||
enum target_cpu target_cpu = CPU_SPARC;
|
||||
#elif defined(__ALPHA__)
|
||||
enum target_cpu target_cpu = CPU_ALPHA;
|
||||
#elif defined(__powerpc__)
|
||||
enum target_cpu target_cpu = CPU_POWERPC;
|
||||
#else
|
||||
#error Unsupported CPU
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
enum target_platform target_platform = PLATFORM_APPLE;
|
||||
#elif defined(__svr4__)
|
||||
enum target_platform target_platform = PLATFORM_SVR4;
|
||||
#elif defined(_WINDOWS)
|
||||
enum target_platform target_platform = PLATFORM_WINDOWS;
|
||||
#else
|
||||
enum target_platform target_platform = PLATFORM_UNSPECIFIED;
|
||||
#endif
|
||||
|
||||
char **debug_channels = NULL;
|
||||
|
@ -447,6 +463,9 @@ int main(int argc, char **argv)
|
|||
output_file = stdout;
|
||||
argv = parse_options( argc, argv, spec );
|
||||
|
||||
/* we only support relay debugging on i386 */
|
||||
debugging = (target_cpu == CPU_x86);
|
||||
|
||||
switch(exec_mode)
|
||||
{
|
||||
case MODE_DLL:
|
||||
|
|
|
@ -487,14 +487,12 @@ static int parse_spec_ordinal( int ordinal, DLLSPEC *spec )
|
|||
assert( 0 );
|
||||
}
|
||||
|
||||
#ifndef __i386__
|
||||
if (odp->flags & FLAG_I386)
|
||||
if ((target_cpu != CPU_x86) && (odp->flags & FLAG_I386))
|
||||
{
|
||||
/* ignore this entry point on non-Intel archs */
|
||||
spec->nb_entry_points--;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ordinal != -1)
|
||||
{
|
||||
|
|
|
@ -32,12 +32,10 @@
|
|||
|
||||
#include "build.h"
|
||||
|
||||
#ifdef __i386__
|
||||
|
||||
static void function_header( FILE *outfile, const char *name )
|
||||
{
|
||||
fprintf( outfile, "\n\t.align %d\n", get_alignment(4) );
|
||||
fprintf( outfile, "\t" __ASM_FUNC("%s") "\n", name );
|
||||
fprintf( outfile, "\t%s\n", func_declaration(name) );
|
||||
fprintf( outfile, "\t.globl " __ASM_NAME("%s") "\n", name );
|
||||
fprintf( outfile, __ASM_NAME("%s") ":\n", name );
|
||||
}
|
||||
|
@ -45,9 +43,13 @@ static void function_header( FILE *outfile, const char *name )
|
|||
|
||||
static void function_footer( FILE *outfile, const char *name )
|
||||
{
|
||||
#ifdef HAVE_ASM_DOT_SIZE
|
||||
fprintf( outfile, "\t.size " __ASM_NAME("%s") ", . - " __ASM_NAME("%s") "\n", name, name );
|
||||
#endif
|
||||
const char *size = func_size( name );
|
||||
if (size[0]) fprintf( outfile, "\t%s\n", size );
|
||||
}
|
||||
|
||||
static inline const char *data16_prefix(void)
|
||||
{
|
||||
return (target_platform == PLATFORM_SVR4) ? "\tdata16\n" : "";
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
|
@ -157,14 +159,8 @@ static void BuildCallFrom16Core( FILE *outfile, int reg_func, int thunk, int sho
|
|||
fprintf( outfile, "\t.byte 0x2e\n\tmovl " __ASM_NAME("CallTo16_DataSelector") ",%%edx\n" );
|
||||
|
||||
/* Load 32-bit segment registers */
|
||||
#ifdef __svr4__
|
||||
fprintf( outfile, "\tdata16\n");
|
||||
#endif
|
||||
fprintf( outfile, "\tmovw %%dx, %%ds\n" );
|
||||
#ifdef __svr4__
|
||||
fprintf( outfile, "\tdata16\n");
|
||||
#endif
|
||||
fprintf( outfile, "\tmovw %%dx, %%es\n" );
|
||||
fprintf( outfile, "%s\tmovw %%dx, %%ds\n", data16_prefix() );
|
||||
fprintf( outfile, "%s\tmovw %%dx, %%es\n", data16_prefix() );
|
||||
|
||||
if ( UsePIC )
|
||||
{
|
||||
|
@ -198,10 +194,7 @@ static void BuildCallFrom16Core( FILE *outfile, int reg_func, int thunk, int sho
|
|||
fprintf( outfile, "\tpushl %%ebp\n" );
|
||||
|
||||
/* Switch stacks */
|
||||
#ifdef __svr4__
|
||||
fprintf( outfile,"\tdata16\n");
|
||||
#endif
|
||||
fprintf( outfile, "\t.byte 0x64\n\tmovw %%ss, (%d)\n", STACKOFFSET + 2 );
|
||||
fprintf( outfile, "%s\t.byte 0x64\n\tmovw %%ss, (%d)\n", data16_prefix(), STACKOFFSET + 2 );
|
||||
fprintf( outfile, "\t.byte 0x64\n\tmovw %%sp, (%d)\n", STACKOFFSET );
|
||||
fprintf( outfile, "\tpushl %%ds\n" );
|
||||
fprintf( outfile, "\tpopl %%ss\n" );
|
||||
|
@ -548,10 +541,7 @@ static void BuildCallTo16Core( FILE *outfile, int reg_func )
|
|||
|
||||
/* Switch to the 16-bit stack */
|
||||
fprintf( outfile, "\tmovl %%esp,%%edx\n" );
|
||||
#ifdef __svr4__
|
||||
fprintf( outfile,"\tdata16\n");
|
||||
#endif
|
||||
fprintf( outfile, "\t.byte 0x64\n\tmovw (%d),%%ss\n", STACKOFFSET + 2);
|
||||
fprintf( outfile, "%s\t.byte 0x64\n\tmovw (%d),%%ss\n", data16_prefix(), STACKOFFSET + 2);
|
||||
fprintf( outfile, "\t.byte 0x64\n\tmovw (%d),%%sp\n", STACKOFFSET );
|
||||
fprintf( outfile, "\t.byte 0x64\n\tmovl %%edx,(%d)\n", STACKOFFSET );
|
||||
|
||||
|
@ -629,14 +619,8 @@ static void BuildRet16Func( FILE *outfile )
|
|||
/* Restore 32-bit segment registers */
|
||||
|
||||
fprintf( outfile, "\t.byte 0x2e\n\tmovl " __ASM_NAME("CallTo16_DataSelector") "-" __ASM_NAME("Call16_Ret_Start") ",%%edi\n" );
|
||||
#ifdef __svr4__
|
||||
fprintf( outfile, "\tdata16\n");
|
||||
#endif
|
||||
fprintf( outfile, "\tmovw %%di,%%ds\n" );
|
||||
#ifdef __svr4__
|
||||
fprintf( outfile, "\tdata16\n");
|
||||
#endif
|
||||
fprintf( outfile, "\tmovw %%di,%%es\n" );
|
||||
fprintf( outfile, "%s\tmovw %%di,%%ds\n", data16_prefix() );
|
||||
fprintf( outfile, "%s\tmovw %%di,%%es\n", data16_prefix() );
|
||||
|
||||
fprintf( outfile, "\t.byte 0x2e\n\tmov " __ASM_NAME("CallTo16_TebSelector") "-" __ASM_NAME("Call16_Ret_Start") ",%%fs\n" );
|
||||
|
||||
|
@ -644,10 +628,7 @@ static void BuildRet16Func( FILE *outfile )
|
|||
|
||||
/* Restore the 32-bit stack */
|
||||
|
||||
#ifdef __svr4__
|
||||
fprintf( outfile, "\tdata16\n");
|
||||
#endif
|
||||
fprintf( outfile, "\tmovw %%di,%%ss\n" );
|
||||
fprintf( outfile, "%s\tmovw %%di,%%ss\n", data16_prefix() );
|
||||
fprintf( outfile, "\t.byte 0x64\n\tmovl (%d),%%esp\n", STACKOFFSET );
|
||||
|
||||
/* Return to caller */
|
||||
|
@ -1141,6 +1122,12 @@ static void BuildPendingEventCheck( FILE *outfile )
|
|||
*/
|
||||
void BuildRelays16( FILE *outfile )
|
||||
{
|
||||
if (target_cpu != CPU_x86)
|
||||
{
|
||||
fprintf( outfile, "/* File not used with this architecture. Do not edit! */\n\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
/* File header */
|
||||
|
||||
fprintf( outfile, "/* File generated automatically. Do not edit! */\n\n" );
|
||||
|
@ -1211,6 +1198,12 @@ void BuildRelays16( FILE *outfile )
|
|||
*/
|
||||
void BuildRelays32( FILE *outfile )
|
||||
{
|
||||
if (target_cpu != CPU_x86)
|
||||
{
|
||||
fprintf( outfile, "/* File not used with this architecture. Do not edit! */\n\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
/* File header */
|
||||
|
||||
fprintf( outfile, "/* File generated automatically. Do not edit! */\n\n" );
|
||||
|
@ -1222,17 +1215,3 @@ void BuildRelays32( FILE *outfile )
|
|||
|
||||
function_footer( outfile, "__wine_spec_thunk_text_32" );
|
||||
}
|
||||
|
||||
#else /* __i386__ */
|
||||
|
||||
void BuildRelays16( FILE *outfile )
|
||||
{
|
||||
fprintf( outfile, "/* File not used with this architecture. Do not edit! */\n\n" );
|
||||
}
|
||||
|
||||
void BuildRelays32( FILE *outfile )
|
||||
{
|
||||
fprintf( outfile, "/* File not used with this architecture. Do not edit! */\n\n" );
|
||||
}
|
||||
|
||||
#endif /* __i386__ */
|
||||
|
|
|
@ -36,12 +36,6 @@
|
|||
#include "build.h"
|
||||
|
||||
|
||||
#ifdef __APPLE__
|
||||
# define __ASM_SKIP ".space"
|
||||
#else
|
||||
# define __ASM_SKIP ".skip"
|
||||
#endif
|
||||
|
||||
static int string_compare( const void *ptr1, const void *ptr2 )
|
||||
{
|
||||
const char * const *str1 = ptr1;
|
||||
|
@ -79,14 +73,15 @@ static const char *make_internal_name( const ORDDEF *odp, DLLSPEC *spec, const c
|
|||
static void declare_weak_function( FILE *outfile, const char *ret_type, const char *name, const char *params)
|
||||
{
|
||||
fprintf( outfile, "#ifdef __GNUC__\n" );
|
||||
fprintf( outfile, "# ifdef __APPLE__\n" );
|
||||
fprintf( outfile, "extern %s %s(%s) __attribute__((weak_import));\n", ret_type, name, params );
|
||||
fprintf( outfile, "static %s (*__wine_spec_weak_%s)(%s) = %s;\n", ret_type, name, params, name );
|
||||
fprintf( outfile, "#define %s __wine_spec_weak_%s\n", name, name );
|
||||
fprintf( outfile, "asm(\".weak_reference " __ASM_NAME("%s") "\");\n", name );
|
||||
fprintf( outfile, "# else\n" );
|
||||
fprintf( outfile, "extern %s %s(%s) __attribute__((weak));\n", ret_type, name, params );
|
||||
fprintf( outfile, "# endif\n" );
|
||||
if (target_platform == PLATFORM_APPLE)
|
||||
{
|
||||
fprintf( outfile, "extern %s %s(%s) __attribute__((weak_import));\n", ret_type, name, params );
|
||||
fprintf( outfile, "static %s (*__wine_spec_weak_%s)(%s) = %s;\n", ret_type, name, params, name );
|
||||
fprintf( outfile, "#define %s __wine_spec_weak_%s\n", name, name );
|
||||
fprintf( outfile, "asm(\".weak_reference " __ASM_NAME("%s") "\");\n", name );
|
||||
}
|
||||
else fprintf( outfile, "extern %s %s(%s) __attribute__((weak));\n", ret_type, name, params );
|
||||
|
||||
fprintf( outfile, "#else\n" );
|
||||
fprintf( outfile, "extern %s %s(%s);\n", ret_type, name, params );
|
||||
fprintf( outfile, "static void __asm__dummy_%s(void)", name );
|
||||
|
@ -407,79 +402,85 @@ static void output_stub_funcs( FILE *outfile, DLLSPEC *spec )
|
|||
*/
|
||||
void output_dll_init( FILE *outfile, const char *constructor, const char *destructor )
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
/* Mach-O doesn't have an init section */
|
||||
if (constructor)
|
||||
if (target_platform == PLATFORM_APPLE)
|
||||
{
|
||||
fprintf( outfile, "asm(\"\\t.mod_init_func\\n\"\n" );
|
||||
fprintf( outfile, " \"\\t.align 2\\n\"\n" );
|
||||
fprintf( outfile, " \"\\t.long " __ASM_NAME("%s") "\\n\"\n", constructor );
|
||||
fprintf( outfile, " \"\\t.text\\n\");\n" );
|
||||
/* Mach-O doesn't have an init section */
|
||||
if (constructor)
|
||||
{
|
||||
fprintf( outfile, "asm(\"\\t.mod_init_func\\n\"\n" );
|
||||
fprintf( outfile, " \"\\t.align 2\\n\"\n" );
|
||||
fprintf( outfile, " \"\\t.long " __ASM_NAME("%s") "\\n\"\n", constructor );
|
||||
fprintf( outfile, " \"\\t.text\\n\");\n" );
|
||||
}
|
||||
if (destructor)
|
||||
{
|
||||
fprintf( outfile, "asm(\"\\t.mod_term_func\\n\"\n" );
|
||||
fprintf( outfile, " \"\\t.align 2\\n\"\n" );
|
||||
fprintf( outfile, " \"\\t.long " __ASM_NAME("%s") "\\n\"\n", destructor );
|
||||
fprintf( outfile, " \"\\t.text\\n\");\n" );
|
||||
}
|
||||
}
|
||||
if (destructor)
|
||||
else switch(target_cpu)
|
||||
{
|
||||
fprintf( outfile, "asm(\"\\t.mod_term_func\\n\"\n" );
|
||||
fprintf( outfile, " \"\\t.align 2\\n\"\n" );
|
||||
fprintf( outfile, " \"\\t.long " __ASM_NAME("%s") "\\n\"\n", destructor );
|
||||
fprintf( outfile, " \"\\t.text\\n\");\n" );
|
||||
case CPU_x86:
|
||||
if (constructor)
|
||||
{
|
||||
fprintf( outfile, "asm(\"\\t.section\\t\\\".init\\\" ,\\\"ax\\\"\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tcall " __ASM_NAME("%s") "\\n\"\n", constructor );
|
||||
fprintf( outfile, " \"\\t.section\\t\\\".text\\\"\\n\");\n" );
|
||||
}
|
||||
if (destructor)
|
||||
{
|
||||
fprintf( outfile, "asm(\"\\t.section\\t\\\".fini\\\" ,\\\"ax\\\"\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tcall " __ASM_NAME("%s") "\\n\"\n", destructor );
|
||||
fprintf( outfile, " \"\\t.section\\t\\\".text\\\"\\n\");\n" );
|
||||
}
|
||||
break;
|
||||
case CPU_SPARC:
|
||||
if (constructor)
|
||||
{
|
||||
fprintf( outfile, "asm(\"\\t.section\\t\\\".init\\\" ,\\\"ax\\\"\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tcall " __ASM_NAME("%s") "\\n\"\n", constructor );
|
||||
fprintf( outfile, " \"\\tnop\\n\"\n" );
|
||||
fprintf( outfile, " \"\\t.section\\t\\\".text\\\"\\n\");\n" );
|
||||
}
|
||||
if (destructor)
|
||||
{
|
||||
fprintf( outfile, "asm(\"\\t.section\\t\\\".fini\\\" ,\\\"ax\\\"\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tcall " __ASM_NAME("%s") "\\n\"\n", destructor );
|
||||
fprintf( outfile, " \"\\tnop\\n\"\n" );
|
||||
fprintf( outfile, " \"\\t.section\\t\\\".text\\\"\\n\");\n" );
|
||||
}
|
||||
break;
|
||||
case CPU_ALPHA:
|
||||
if (constructor)
|
||||
{
|
||||
fprintf( outfile, "asm(\"\\t.section\\t\\\".init\\\" ,\\\"ax\\\"\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tjsr $26," __ASM_NAME("%s") "\\n\"\n", constructor );
|
||||
fprintf( outfile, " \"\\t.section\\t\\\".text\\\"\\n\");\n" );
|
||||
}
|
||||
if (destructor)
|
||||
{
|
||||
fprintf( outfile, "asm(\"\\t.section\\t\\\".fini\\\" ,\\\"ax\\\"\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tjsr $26," __ASM_NAME("%s") "\\n\"\n", destructor );
|
||||
fprintf( outfile, " \"\\t.section\\t\\\".text\\\"\\n\");\n" );
|
||||
}
|
||||
break;
|
||||
case CPU_POWERPC:
|
||||
if (constructor)
|
||||
{
|
||||
fprintf( outfile, "asm(\"\\t.section\\t\\\".init\\\" ,\\\"ax\\\"\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tbl " __ASM_NAME("%s") "\\n\"\n", constructor );
|
||||
fprintf( outfile, " \"\\t.section\\t\\\".text\\\"\\n\");\n" );
|
||||
}
|
||||
if (destructor)
|
||||
{
|
||||
fprintf( outfile, "asm(\"\\t.section\\t\\\".fini\\\" ,\\\"ax\\\"\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tbl " __ASM_NAME("%s") "\\n\"\n", destructor );
|
||||
fprintf( outfile, " \"\\t.section\\t\\\".text\\\"\\n\");\n" );
|
||||
}
|
||||
break;
|
||||
}
|
||||
#elif defined(__i386__)
|
||||
if (constructor)
|
||||
{
|
||||
fprintf( outfile, "asm(\"\\t.section\\t\\\".init\\\" ,\\\"ax\\\"\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tcall " __ASM_NAME("%s") "\\n\"\n", constructor );
|
||||
fprintf( outfile, " \"\\t.section\\t\\\".text\\\"\\n\");\n" );
|
||||
}
|
||||
if (destructor)
|
||||
{
|
||||
fprintf( outfile, "asm(\"\\t.section\\t\\\".fini\\\" ,\\\"ax\\\"\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tcall " __ASM_NAME("%s") "\\n\"\n", destructor );
|
||||
fprintf( outfile, " \"\\t.section\\t\\\".text\\\"\\n\");\n" );
|
||||
}
|
||||
#elif defined(__sparc__)
|
||||
if (constructor)
|
||||
{
|
||||
fprintf( outfile, "asm(\"\\t.section\\t\\\".init\\\" ,\\\"ax\\\"\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tcall " __ASM_NAME("%s") "\\n\"\n", constructor );
|
||||
fprintf( outfile, " \"\\tnop\\n\"\n" );
|
||||
fprintf( outfile, " \"\\t.section\\t\\\".text\\\"\\n\");\n" );
|
||||
}
|
||||
if (destructor)
|
||||
{
|
||||
fprintf( outfile, "asm(\"\\t.section\\t\\\".fini\\\" ,\\\"ax\\\"\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tcall " __ASM_NAME("%s") "\\n\"\n", destructor );
|
||||
fprintf( outfile, " \"\\tnop\\n\"\n" );
|
||||
fprintf( outfile, " \"\\t.section\\t\\\".text\\\"\\n\");\n" );
|
||||
}
|
||||
#elif defined(__powerpc__)
|
||||
if (constructor)
|
||||
{
|
||||
fprintf( outfile, "asm(\"\\t.section\\t\\\".init\\\" ,\\\"ax\\\"\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tbl " __ASM_NAME("%s") "\\n\"\n", constructor );
|
||||
fprintf( outfile, " \"\\t.section\\t\\\".text\\\"\\n\");\n" );
|
||||
}
|
||||
if (destructor)
|
||||
{
|
||||
fprintf( outfile, "asm(\"\\t.section\\t\\\".fini\\\" ,\\\"ax\\\"\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tbl " __ASM_NAME("%s") "\\n\"\n", destructor );
|
||||
fprintf( outfile, " \"\\t.section\\t\\\".text\\\"\\n\");\n" );
|
||||
}
|
||||
#elif defined(__ALPHA__)
|
||||
if (constructor)
|
||||
{
|
||||
fprintf( outfile, "asm(\"\\t.section\\t\\\".init\\\" ,\\\"ax\\\"\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tjsr $26," __ASM_NAME("%s") "\\n\"\n", constructor );
|
||||
fprintf( outfile, " \"\\t.section\\t\\\".text\\\"\\n\");\n" );
|
||||
}
|
||||
if (destructor)
|
||||
{
|
||||
fprintf( outfile, "asm(\"\\t.section\\t\\\".fini\\\" ,\\\"ax\\\"\\n\"\n" );
|
||||
fprintf( outfile, " \"\\tjsr $26," __ASM_NAME("%s") "\\n\"\n", destructor );
|
||||
fprintf( outfile, " \"\\t.section\\t\\\".text\\\"\\n\");\n" );
|
||||
}
|
||||
#else
|
||||
#error You need to define the DLL constructor for your architecture
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -492,23 +493,9 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
|
|||
{
|
||||
int exports_size = 0;
|
||||
int nr_exports, nr_imports, nr_delayed;
|
||||
DWORD page_size;
|
||||
unsigned int page_size = get_page_size();
|
||||
const char *init_func = spec->init_func;
|
||||
|
||||
#ifdef HAVE_GETPAGESIZE
|
||||
page_size = getpagesize();
|
||||
#elif defined(__svr4__)
|
||||
page_size = sysconf(_SC_PAGESIZE);
|
||||
#elif defined(_WINDOWS)
|
||||
{
|
||||
SYSTEM_INFO si;
|
||||
GetSystemInfo(&si);
|
||||
page_size = si.dwPageSize;
|
||||
}
|
||||
#else
|
||||
# error Cannot get the page size on this platform
|
||||
#endif
|
||||
|
||||
nr_exports = spec->base <= spec->limit ? spec->limit - spec->base + 1 : 0;
|
||||
resolve_imports( spec );
|
||||
exports_size = get_exports_size( spec );
|
||||
|
@ -522,7 +509,11 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
|
|||
fprintf( outfile, "#endif\n" );
|
||||
fprintf( outfile, "asm(\".text\\n\\t\"\n" );
|
||||
fprintf( outfile, " \".align %d\\n\"\n", get_alignment(page_size) );
|
||||
fprintf( outfile, " \"" __ASM_NAME("__wine_spec_pe_header") ":\\t" __ASM_SKIP " 65536\\n\\t\"\n" );
|
||||
fprintf( outfile, " \"" __ASM_NAME("__wine_spec_pe_header") ":\\t\"\n" );
|
||||
if (target_platform == PLATFORM_APPLE)
|
||||
fprintf( outfile, " \".space 65536\\n\\t\"\n" );
|
||||
else
|
||||
fprintf( outfile, " \".skip 65536\\n\\t\"\n" );
|
||||
fprintf( outfile, " \".data\\n\\t\"\n" );
|
||||
fprintf( outfile, " \".align %d\\n\"\n", get_alignment(4) );
|
||||
fprintf( outfile, " \"" __ASM_NAME("__wine_spec_data_start") ":\\t.long 1\");\n" );
|
||||
|
@ -530,19 +521,17 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
|
|||
fprintf( outfile, "}\n" );
|
||||
fprintf( outfile, "#endif\n" );
|
||||
|
||||
#ifdef __APPLE__
|
||||
fprintf( outfile, "static char _end[4];\n" );
|
||||
#else
|
||||
fprintf( outfile, "extern char _end[];\n" );
|
||||
#endif
|
||||
if (target_platform == PLATFORM_APPLE)
|
||||
fprintf( outfile, "static char _end[4];\n" );
|
||||
else
|
||||
fprintf( outfile, "extern char _end[];\n" );
|
||||
|
||||
fprintf( outfile, "extern int __wine_spec_data_start[], __wine_spec_exports[];\n\n" );
|
||||
|
||||
#ifdef __i386__
|
||||
fprintf( outfile, "#define __stdcall __attribute__((__stdcall__))\n\n" );
|
||||
#else
|
||||
fprintf( outfile, "#define __stdcall\n\n" );
|
||||
#endif
|
||||
if (target_cpu == CPU_x86)
|
||||
fprintf( outfile, "#define __stdcall __attribute__((__stdcall__))\n\n" );
|
||||
else
|
||||
fprintf( outfile, "#define __stdcall\n\n" );
|
||||
|
||||
output_stub_funcs( outfile, spec );
|
||||
output_export_names( outfile, spec );
|
||||
|
@ -562,26 +551,29 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
|
|||
fprintf( outfile, "extern char **__wine_main_argv;\n" );
|
||||
fprintf( outfile, "extern char **__wine_main_environ;\n" );
|
||||
fprintf( outfile, "extern unsigned short **__wine_main_wargv;\n" );
|
||||
#ifdef __APPLE__
|
||||
fprintf( outfile, "extern _dyld_func_lookup(char *, void *);" );
|
||||
fprintf( outfile, "static void __wine_spec_hidden_init(int argc, char** argv, char** envp)\n" );
|
||||
fprintf( outfile, "{\n" );
|
||||
fprintf( outfile, " void (*init)(void);\n" );
|
||||
fprintf( outfile, " _dyld_func_lookup(\"__dyld_make_delayed_module_initializer_calls\", (unsigned long *)&init);\n" );
|
||||
fprintf( outfile, " init();\n" );
|
||||
fprintf( outfile, "}\n" );
|
||||
fprintf( outfile, "static void __wine_spec_hidden_fini()\n" );
|
||||
fprintf( outfile, "{\n" );
|
||||
fprintf( outfile, " void (*fini)(void);\n" );
|
||||
fprintf( outfile, " _dyld_func_lookup(\"__dyld_mod_term_funcs\", (unsigned long *)&fini);\n" );
|
||||
fprintf( outfile, " fini();\n" );
|
||||
fprintf( outfile, "}\n" );
|
||||
fprintf( outfile, "#define _init __wine_spec_hidden_init\n" );
|
||||
fprintf( outfile, "#define _fini __wine_spec_hidden_fini\n" );
|
||||
#else
|
||||
fprintf( outfile, "extern void _init(int, char**, char**);\n" );
|
||||
fprintf( outfile, "extern void _fini();\n" );
|
||||
#endif
|
||||
if (target_platform == PLATFORM_APPLE)
|
||||
{
|
||||
fprintf( outfile, "extern _dyld_func_lookup(char *, void *);" );
|
||||
fprintf( outfile, "static void __wine_spec_hidden_init(int argc, char** argv, char** envp)\n" );
|
||||
fprintf( outfile, "{\n" );
|
||||
fprintf( outfile, " void (*init)(void);\n" );
|
||||
fprintf( outfile, " _dyld_func_lookup(\"__dyld_make_delayed_module_initializer_calls\", (unsigned long *)&init);\n" );
|
||||
fprintf( outfile, " init();\n" );
|
||||
fprintf( outfile, "}\n" );
|
||||
fprintf( outfile, "static void __wine_spec_hidden_fini()\n" );
|
||||
fprintf( outfile, "{\n" );
|
||||
fprintf( outfile, " void (*fini)(void);\n" );
|
||||
fprintf( outfile, " _dyld_func_lookup(\"__dyld_mod_term_funcs\", (unsigned long *)&fini);\n" );
|
||||
fprintf( outfile, " fini();\n" );
|
||||
fprintf( outfile, "}\n" );
|
||||
fprintf( outfile, "#define _init __wine_spec_hidden_init\n" );
|
||||
fprintf( outfile, "#define _fini __wine_spec_hidden_fini\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( outfile, "extern void _init(int, char**, char**);\n" );
|
||||
fprintf( outfile, "extern void _fini();\n" );
|
||||
}
|
||||
|
||||
if (spec->characteristics & IMAGE_FILE_DLL)
|
||||
{
|
||||
|
@ -750,15 +742,21 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
|
|||
fprintf( outfile, " } OptionalHeader;\n" );
|
||||
fprintf( outfile, "} nt_header = {\n" );
|
||||
fprintf( outfile, " 0x%04x,\n", IMAGE_NT_SIGNATURE ); /* Signature */
|
||||
#ifdef __i386__
|
||||
fprintf( outfile, " { 0x%04x,\n", IMAGE_FILE_MACHINE_I386 ); /* Machine */
|
||||
#elif defined(__powerpc__)
|
||||
fprintf( outfile, " { 0x%04x,\n", IMAGE_FILE_MACHINE_POWERPC ); /* Machine */
|
||||
#elif defined(__ALPHA__)
|
||||
fprintf( outfile, " { 0x%04x,\n", IMAGE_FILE_MACHINE_ALPHA ); /* Machine */
|
||||
#else
|
||||
fprintf( outfile, " { 0x%04x,\n", IMAGE_FILE_MACHINE_UNKNOWN ); /* Machine */
|
||||
#endif
|
||||
switch(target_cpu)
|
||||
{
|
||||
case CPU_x86:
|
||||
fprintf( outfile, " { 0x%04x,\n", IMAGE_FILE_MACHINE_I386 ); /* Machine */
|
||||
break;
|
||||
case CPU_POWERPC:
|
||||
fprintf( outfile, " { 0x%04x,\n", IMAGE_FILE_MACHINE_POWERPC ); /* Machine */
|
||||
break;
|
||||
case CPU_ALPHA:
|
||||
fprintf( outfile, " { 0x%04x,\n", IMAGE_FILE_MACHINE_ALPHA ); /* Machine */
|
||||
break;
|
||||
case CPU_SPARC:
|
||||
fprintf( outfile, " { 0x%04x,\n", IMAGE_FILE_MACHINE_UNKNOWN ); /* Machine */
|
||||
break;
|
||||
}
|
||||
fprintf( outfile, " 0, 0, 0, 0,\n" );
|
||||
fprintf( outfile, " sizeof(nt_header.OptionalHeader),\n" ); /* SizeOfOptionalHeader */
|
||||
fprintf( outfile, " 0x%04x },\n", spec->characteristics ); /* Characteristics */
|
||||
|
@ -769,21 +767,21 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
|
|||
fprintf( outfile, " %s,\n", init_func ); /* AddressOfEntryPoint */
|
||||
fprintf( outfile, " 0, __wine_spec_data_start,\n" ); /* BaseOfCode/Data */
|
||||
fprintf( outfile, " __wine_spec_pe_header,\n" ); /* ImageBase */
|
||||
fprintf( outfile, " %ld,\n", page_size ); /* SectionAlignment */
|
||||
fprintf( outfile, " %ld,\n", page_size ); /* FileAlignment */
|
||||
fprintf( outfile, " %u,\n", page_size ); /* SectionAlignment */
|
||||
fprintf( outfile, " %u,\n", page_size ); /* FileAlignment */
|
||||
fprintf( outfile, " 1, 0,\n" ); /* Major/MinorOperatingSystemVersion */
|
||||
fprintf( outfile, " 0, 0,\n" ); /* Major/MinorImageVersion */
|
||||
fprintf( outfile, " %d,\n", spec->subsystem_major ); /* MajorSubsystemVersion */
|
||||
fprintf( outfile, " %d,\n", spec->subsystem_minor ); /* MinorSubsystemVersion */
|
||||
fprintf( outfile, " 0,\n" ); /* Win32VersionValue */
|
||||
fprintf( outfile, " _end,\n" ); /* SizeOfImage */
|
||||
fprintf( outfile, " %ld,\n", page_size ); /* SizeOfHeaders */
|
||||
fprintf( outfile, " %u,\n", page_size ); /* SizeOfHeaders */
|
||||
fprintf( outfile, " 0,\n" ); /* CheckSum */
|
||||
fprintf( outfile, " 0x%04x,\n", spec->subsystem );/* Subsystem */
|
||||
fprintf( outfile, " 0,\n" ); /* DllCharacteristics */
|
||||
fprintf( outfile, " %d, %ld,\n", /* SizeOfStackReserve/Commit */
|
||||
fprintf( outfile, " %u, %u,\n", /* SizeOfStackReserve/Commit */
|
||||
(spec->stack_size ? spec->stack_size : 1024) * 1024, page_size );
|
||||
fprintf( outfile, " %d, %ld,\n", /* SizeOfHeapReserve/Commit */
|
||||
fprintf( outfile, " %u, %u,\n", /* SizeOfHeapReserve/Commit */
|
||||
(spec->heap_size ? spec->heap_size : 1024) * 1024, page_size );
|
||||
fprintf( outfile, " 0,\n" ); /* LoaderFlags */
|
||||
fprintf( outfile, " %d,\n", IMAGE_NUMBEROF_DIRECTORY_ENTRIES ); /* NumberOfRvaAndSizes */
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
@ -339,81 +340,70 @@ const char *make_c_identifier( const char *str )
|
|||
*
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* align -- the number of bytes to align to. Must be a power of 2.
|
||||
*/
|
||||
int get_alignment(int alignBoundary)
|
||||
unsigned int get_alignment(unsigned int align)
|
||||
{
|
||||
#if defined(__powerpc__) || defined(__ALPHA__) || defined(__APPLE__)
|
||||
unsigned int n;
|
||||
|
||||
int n = 0;
|
||||
assert( !(align & (align - 1)) );
|
||||
|
||||
switch(alignBoundary)
|
||||
switch(target_cpu)
|
||||
{
|
||||
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);
|
||||
case CPU_x86:
|
||||
case CPU_SPARC:
|
||||
if (target_platform != PLATFORM_APPLE) return align;
|
||||
/* fall through */
|
||||
case CPU_POWERPC:
|
||||
case CPU_ALPHA:
|
||||
n = 0;
|
||||
while ((1 << n) != align) n++;
|
||||
return n;
|
||||
}
|
||||
return n;
|
||||
/* unreached */
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif defined(__i386__) || defined(__sparc__)
|
||||
/* return the page size for the target CPU */
|
||||
unsigned int get_page_size(void)
|
||||
{
|
||||
switch(target_cpu)
|
||||
{
|
||||
case CPU_x86: return 4096;
|
||||
case CPU_POWERPC: return 4096;
|
||||
case CPU_SPARC: return 8192;
|
||||
case CPU_ALPHA: return 8192;
|
||||
}
|
||||
/* unreached */
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return alignBoundary;
|
||||
/* return the assembly name for a C function name */
|
||||
const char *func_name( const char *func )
|
||||
{
|
||||
static char buffer[256];
|
||||
sprintf( buffer, __ASM_NAME("%s"), func );
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/* return an assembly function declaration for a C function name */
|
||||
const char *func_declaration( const char *func )
|
||||
{
|
||||
static char buffer[256];
|
||||
sprintf( buffer, __ASM_FUNC("%s"), func );
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/* return a size declaration for an assembly function */
|
||||
const char *func_size( const char *func )
|
||||
{
|
||||
#ifdef HAVE_ASM_DOT_SIZE
|
||||
static char buffer[256];
|
||||
sprintf( buffer, ".size " __ASM_NAME("%s") ", .-" __ASM_NAME("%s"), func, func );
|
||||
return buffer;
|
||||
#else
|
||||
#error "How does the '.align' assembler directive work on your architecture?"
|
||||
return "";
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue