From d005fc9f1ad35d2e4b5129be2b21ec3ba0def67c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9=20van=20Geldorp?= Date: Tue, 5 Jul 2005 21:17:01 +0000 Subject: [PATCH] Sync to Wine-20050628: Alexandre Julliard - Generate the resource data directly inside the resource directory. - Replaced all uses of the __ASM_NAME macro by the asm_name function to allow run-time determination of the correct format. - Beginnings of an infrastructure to allow specifying the target CPU and platform at run-time. - Output the exported names as a C string so that they end up in the correct section. - Reuse output_dll_init for the constructor of debug files. - Moved all assembly code to the end of the generated C files to avoid conflicting with the compiler over section changes. - Switch back to .data at the end of asm sections to work around an optimization in recent gcc versions. - Remove some i386 ifdefs for 16-bit entry points since they are no longer used by default on other platforms anyway. - Make import thunks position-independent to avoid text relocations. - Generate proper PIC code for CALL32_CBClient. - Store a relative pointer for registry entry points to avoid some text relocations. - Allocate ordinals in the order of the declarations in the spec file. Wolfgang Thaller - Winebuild darwin/x86-specific fixes: - Assembler interprets .align as power-of-two - Add .weak_reference to output where gcc 3.3 swallows it - Use __ASM_NAME and HAVE_ASM_DOT_SIZE in a few places in winebuild where they have been missing (needed for Darwin/x86). Pierre d'Herbemont - Use .mod_*_func sections on Mac OS X/i386 instead of the elf constructor/destructor. svn path=/trunk/; revision=16438 --- reactos/tools/winebuild/build.h | 20 +- reactos/tools/winebuild/import.c | 547 +++++++++++++++--------------- reactos/tools/winebuild/main.c | 29 +- reactos/tools/winebuild/parser.c | 14 +- reactos/tools/winebuild/relay.c | 218 ++++++------ reactos/tools/winebuild/res32.c | 42 +-- reactos/tools/winebuild/spec16.c | 57 +--- reactos/tools/winebuild/spec32.c | 506 ++++++++++++++------------- reactos/tools/winebuild/utils.c | 122 +++---- reactos/tools/winebuild/winglue.h | 5 +- 10 files changed, 788 insertions(+), 772 deletions(-) diff --git a/reactos/tools/winebuild/build.h b/reactos/tools/winebuild/build.h index 10573db60cf..344d8189dbb 100644 --- a/reactos/tools/winebuild/build.h +++ b/reactos/tools/winebuild/build.h @@ -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 *asm_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 ); @@ -174,6 +191,7 @@ extern void add_ignore_symbol( const char *name ); extern void read_undef_symbols( char **argv ); extern int resolve_imports( DLLSPEC *spec ); extern int output_imports( FILE *outfile, DLLSPEC *spec, int *nb_delayed ); +extern void output_import_thunks( FILE *outfile, DLLSPEC *spec ); extern int load_res32_file( const char *name, DLLSPEC *spec ); extern void output_resources( FILE *outfile, DLLSPEC *spec ); extern void load_res16_file( const char *name, DLLSPEC *spec ); diff --git a/reactos/tools/winebuild/import.c b/reactos/tools/winebuild/import.c index c442e1da461..f1c2520a499 100644 --- a/reactos/tools/winebuild/import.c +++ b/reactos/tools/winebuild/import.c @@ -125,23 +125,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 ) @@ -191,9 +184,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 */ @@ -607,15 +599,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, asm_name("") ); + prefix_len = strlen( name_prefix ); + undef_size = nb_undef_symbols = 0; /* if we have multiple object files, link them together */ @@ -695,14 +689,120 @@ int resolve_imports( DLLSPEC *spec ) return 1; } +/* output a single import thunk */ +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%s\\n\"\n", func_declaration(name) ); + fprintf( outfile, " \"\\t.globl %s\\n\"\n", asm_name(name) ); + fprintf( outfile, " \"%s:\\n\"\n", asm_name(name) ); + + switch(target_cpu) + { + case CPU_x86: + if (!UsePIC) + { + 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" )) + { + /* 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+%s-.L__wine_spec_%s,%%eax\\n\"\n", + pos, asm_name(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+%s-.L__wine_spec_%s,%%eax\\n\"\n", + pos, asm_name(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(%s+%d)\\n\"\n", + ppc_reg(9), asm_name(table), pos); + fprintf(outfile, " \"\\tla %s, lo16(%s+%d)(%s)\\n\"\n", + ppc_reg(8), asm_name(table), pos, ppc_reg(9)); + } + else + { + fprintf(outfile, " \"\\tlis %s, (%s+%d)@hi\\n\"\n", + ppc_reg(9), asm_name(table), pos); + fprintf(outfile, " \"\\tla %s, (%s+%d)@l(%s)\\n\"\n", + ppc_reg(8), asm_name(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; + } + output_function_size( outfile, name ); +} + /* output the import table of a Win32 module */ static int output_immediate_imports( FILE *outfile ) { - int i, j, pos; - int nb_imm = nb_imports - nb_delayed; - static const char import_thunks[] = "__wine_spec_import_thunks"; + int i, j, nb_imm = nb_imports - nb_delayed; - if (!nb_imm) goto done; + if (!nb_imm) return 0; /* main import header */ @@ -753,13 +853,23 @@ static int output_immediate_imports( FILE *outfile ) } fprintf( outfile, " }\n};\n\n" ); - /* thunks for imported functions */ + return nb_imm; +} + +/* output the import thunks of a Win32 module */ +static void output_immediate_import_thunks( FILE *outfile ) +{ + int i, j, pos; + int nb_imm = nb_imports - nb_delayed; + static const char import_thunks[] = "__wine_spec_import_thunks"; + + if (!nb_imm) return; - fprintf( outfile, "#ifndef __GNUC__\nstatic void __asm__dummy_import(void) {\n#endif\n\n" ); pos = (sizeof(void *) + 2*sizeof(unsigned int) + sizeof(const char *) + sizeof(void *)) * (nb_imm + 1); /* offset of imports.data from start of imports */ + fprintf( outfile, "/* immediate import thunks */\n" ); fprintf( outfile, "asm(\".text\\n\\t.align %d\\n\"\n", get_alignment(8) ); - fprintf( outfile, " \"" __ASM_NAME("%s") ":\\n\"\n", import_thunks); + fprintf( outfile, " \"%s:\\n\"\n", asm_name(import_thunks)); for (i = 0; i < nb_imports; i++) { @@ -767,84 +877,21 @@ static int output_immediate_imports( FILE *outfile ) for (j = 0; j < dll_imports[i]->nb_imports; j++, pos += sizeof(const char *)) { ORDDEF *odp = dll_imports[i]->imports[j]; - const char *name = odp->name ? odp->name : odp->export_name; - fprintf( outfile, " \"\\t" __ASM_FUNC("%s") "\\n\"\n", name ); - fprintf( outfile, " \"\\t.globl " __ASM_NAME("%s") "\\n\"\n", name ); - fprintf( outfile, " \"" __ASM_NAME("%s") ":\\n\\t", name); - -#ifndef __REACTOS__ -#if defined(__i386__) - if (strstr( name, "__wine_call_from_16" )) - fprintf( outfile, ".byte 0x2e\\n\\tjmp *(imports+%d)\\n\\tnop\\n", pos ); - else - fprintf( outfile, "jmp *(imports+%d)\\n\\tmovl %%esi,%%esi\\n", pos ); -#elif defined(__sparc__) - if ( !UsePIC ) - { - fprintf( outfile, "sethi %%hi(imports+%d), %%g1\\n\\t", pos ); - fprintf( outfile, "ld [%%g1+%%lo(imports+%d)], %%g1\\n\\t", pos ); - fprintf( outfile, "jmp %%g1\\n\\tnop\\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, "save %%sp, -96, %%sp\\n" ); - fprintf( outfile, "0:\\tcall 1f\\n\\tnop\\n" ); - fprintf( outfile, "1:\\tsethi %%hi(imports+%d-0b), %%g1\\n\\t", pos ); - fprintf( outfile, "or %%g1, %%lo(imports+%d-0b), %%g1\\n\\t", pos ); - fprintf( outfile, "ld [%%g1+%%o7], %%g1\\n\\t" ); - fprintf( outfile, "jmp %%g1\\n\\trestore\\n" ); - } - -#elif defined(__powerpc__) - fprintf(outfile, "\taddi %s, %s, -0x4\\n\"\n", ppc_reg[1], ppc_reg[1]); - fprintf(outfile, "\t\"\\tstw %s, 0(%s)\\n\"\n", ppc_reg[9], ppc_reg[1]); - fprintf(outfile, "\t\"\\taddi %s, %s, -0x4\\n\"\n", ppc_reg[1], ppc_reg[1]); - fprintf(outfile, "\t\"\\tstw %s, 0(%s)\\n\"\n", ppc_reg[8], ppc_reg[1]); - fprintf(outfile, "\t\"\\taddi %s, %s, -0x4\\n\"\n", ppc_reg[1], ppc_reg[1]); - fprintf(outfile, "\t\"\\tstw %s, 0(%s)\\n\"\n", ppc_reg[7], ppc_reg[1]); - - fprintf(outfile, "\t\"\\tlis %s, " ppc_high(__ASM_NAME("imports") "+ %d") "\\n\"\n", ppc_reg[9], pos); - fprintf(outfile, "\t\"\\tla %s, " ppc_low (__ASM_NAME("imports") "+ %d") "(%s)\\n\"\n", ppc_reg[8], pos, ppc_reg[9]); - fprintf(outfile, "\t\"\\tlwz %s, 0(%s)\\n\"\n", ppc_reg[7], ppc_reg[8]); - fprintf(outfile, "\t\"\\tmtctr %s\\n\"\n", ppc_reg[7]); - - fprintf(outfile, "\t\"\\tlwz %s, 0(%s)\\n\"\n", ppc_reg[7], ppc_reg[1]); - fprintf(outfile, "\t\"\\taddi %s, %s, 0x4\\n\"\n", ppc_reg[1], ppc_reg[1]); - fprintf(outfile, "\t\"\\tlwz %s, 0(%s)\\n\"\n", ppc_reg[8], ppc_reg[1]); - fprintf(outfile, "\t\"\\taddi %s, %s, 0x4\\n\"\n", ppc_reg[1], ppc_reg[1]); - fprintf(outfile, "\t\"\\tlwz %s, 0(%s)\\n\"\n", ppc_reg[9], ppc_reg[1]); - fprintf(outfile, "\t\"\\taddi %s, %s, 0x4\\n\"\n", ppc_reg[1], ppc_reg[1]); - fprintf(outfile, "\t\"\\tbctr\\n"); -#elif defined(__ALPHA__) - fprintf( outfile, "\tlda $0,imports\\n\"\n" ); - fprintf( outfile, "\t\"\\tlda $0,%d($0)\\n\"\n", pos); - fprintf( outfile, "\t\"\\tjmp $31,($0)\\n" ); -#else -#error You need to define import thunks for your architecture! -#endif -#endif /*__REACTOS__*/ - fprintf( outfile, "\"\n" ); - output_function_size( outfile, name ); + output_import_thunk( outfile, odp->name ? odp->name : odp->export_name, + "imports", pos ); } pos += 4; } output_function_size( outfile, import_thunks ); - fprintf( outfile, " \".text\");\n#ifndef __GNUC__\n}\n#endif\n\n" ); - - done: - return nb_imm; + fprintf( outfile, ");\n" ); } /* output the delayed import table of a Win32 module */ static int output_delayed_imports( FILE *outfile, const DLLSPEC *spec ) { - int i, idx, j, pos; - static const char delayed_import_loaders[] = "__wine_spec_delayed_import_loaders"; - static const char delayed_import_thunks[] = "__wine_spec_delayed_import_thunks"; + int i, j; - if (!nb_delayed) goto done; + if (!nb_delayed) return 0; fprintf( outfile, "static void *__wine_delay_imp_hmod[%d];\n", nb_delayed ); for (i = 0; i < nb_imports; i++) @@ -932,83 +979,93 @@ static int output_delayed_imports( FILE *outfile, const DLLSPEC *spec ) fprintf( outfile, " RaiseException( 0x%08x, %d, 2, args );\n", EXCEPTION_WINE_STUB, EXCEPTION_NONCONTINUABLE ); fprintf( outfile, " return 0;\n" ); - fprintf( outfile, " }\n}\n\n" ); + fprintf( outfile, " }\n}\n" ); - fprintf( outfile, "#ifndef __GNUC__\n" ); - fprintf( outfile, "static void __asm__dummy_delay_import(void) {\n" ); - fprintf( outfile, "#endif\n" ); + return nb_delayed; +} - fprintf( outfile, "asm(\".align %d\\n\"\n", get_alignment(8) ); - fprintf( outfile, " \"" __ASM_NAME("%s") ":\\n\"\n", delayed_import_loaders); - fprintf( outfile, " \"\\t" __ASM_FUNC("__wine_delay_load_asm") "\\n\"\n" ); - fprintf( outfile, " \"" __ASM_NAME("__wine_delay_load_asm") ":\\n\"\n" ); -#if defined(__i386__) - fprintf( outfile, " \"\\tpushl %%ecx\\n\\tpushl %%edx\\n\\tpushl %%eax\\n\"\n" ); - fprintf( outfile, " \"\\tcall __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 __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]); +/* 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, 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"; - /* r0 -> r3 (arg1) */ - fprintf( outfile, " \"\\tmr %s, %s\\n\"\n", ppc_reg[3], ppc_reg[0]); + if (!nb_delayed) return; - /* 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]); + fprintf( outfile, "/* delayed import thunks */\n" ); + fprintf( outfile, "asm(\".text\\n\"\n" ); + fprintf( outfile, " \"\\t.align %d\\n\"\n", get_alignment(8) ); + fprintf( outfile, " \"%s:\\n\"\n", asm_name(delayed_import_loaders)); + fprintf( outfile, " \"\\t%s\\n\"\n", func_declaration("__wine_delay_load_asm") ); + fprintf( outfile, " \"%s:\\n\"\n", asm_name("__wine_delay_load_asm") ); + switch(target_cpu) + { + case CPU_x86: + fprintf( outfile, " \"\\tpushl %%ecx\\n\\tpushl %%edx\\n\\tpushl %%eax\\n\"\n" ); + fprintf( outfile, " \"\\tcall %s\\n\"\n", asm_name("__wine_delay_load") ); + 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 %s\\n\"\n", asm_name("__wine_delay_load") ); + fprintf( outfile, " \"\\tmov %%g1, %%o0\\n\"\n" ); + fprintf( outfile, " \"\\tjmp %%o0\\n\\trestore\\n\"\n" ); + break; + case CPU_ALPHA: + fprintf( outfile, " \"\\tjsr $26,%s\\n\"\n", asm_name("__wine_delay_load") ); + fprintf( outfile, " \"\\tjmp $31,($0)\\n\"\n" ); + break; + case CPU_POWERPC: + if (target_platform == PLATFORM_APPLE) extra_stack_storage = 56; - /* Call the __wine_delay_load function, arg1 is arg1. */ - fprintf( outfile, " \"\\tbl " __ASM_NAME("__wine_delay_load") "\\n\"\n"); + /* 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)); - /* Load return value from call into ctr register */ - fprintf( outfile, " \"\\tmtctr %s\\n\"\n", ppc_reg[3]); + /* r0 -> r3 (arg1) */ + fprintf( outfile, " \"\\tmr %s, %s\\n\"\n", ppc_reg(3), ppc_reg(0)); - /* 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]); + /* 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 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); + /* Call the __wine_delay_load function, arg1 is arg1. */ + fprintf( outfile, " \"\\tbl %s\\n\"\n", asm_name("__wine_delay_load") ); - /* branch to ctr register. */ - fprintf( outfile, " \"bctr\\n\"\n"); -#elif defined(__ALPHA__) - fprintf( outfile, " \"\\tjsr $26,__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 ctr register */ + fprintf( outfile, " \"\\tmtctr %s\\n\"\n", ppc_reg(3)); + + /* 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 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++) @@ -1021,43 +1078,51 @@ static int output_delayed_imports( 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, " \"" __ASM_NAME("%s") ":\\n\"\n", buffer ); -#if defined(__i386__) - fprintf( outfile, " \"\\tmovl $%d, %%eax\\n\"\n", (idx << 16) | j ); - fprintf( outfile, " \"\\tjmp __wine_delay_load_asm\\n\"\n" ); -#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(__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,__wine_delay_load_asm\\n\"\n" ); -#else -#error You need to defined delayed import thunks for your architecture! -#endif + fprintf( outfile, " \"\\t%s\\n\"\n", func_declaration(buffer) ); + fprintf( outfile, " \"%s:\\n\"\n", asm_name(buffer) ); + switch(target_cpu) + { + case CPU_x86: + fprintf( outfile, " \"\\tmovl $%d, %%eax\\n\"\n", (idx << 16) | j ); + fprintf( outfile, " \"\\tjmp %s\\n\"\n", asm_name("__wine_delay_load_asm") ); + break; + case CPU_SPARC: + fprintf( outfile, " \"\\tset %d, %%g1\\n\"\n", (idx << 16) | j ); + fprintf( outfile, " \"\\tb,a %s\\n\"\n", asm_name("__wine_delay_load_asm") ); + 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,%s\\n\"\n", asm_name("__wine_delay_load_asm") ); + 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 %s\\n\"\n", asm_name("__wine_delay_load_asm") ); + 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 %s\\n\"\n", asm_name("__wine_delay_load_asm") ); + break; + } + break; + } output_function_size( outfile, name ); } idx++; @@ -1065,7 +1130,7 @@ static int output_delayed_imports( FILE *outfile, const DLLSPEC *spec ) output_function_size( outfile, delayed_import_loaders ); fprintf( outfile, "\n \".align %d\\n\"\n", get_alignment(8) ); - fprintf( outfile, " \"" __ASM_NAME("%s") ":\\n\"\n", delayed_import_thunks); + fprintf( outfile, " \"%s:\\n\"\n", asm_name(delayed_import_thunks)); pos = nb_delayed * 32; for (i = 0; i < nb_imports; i++) { @@ -1073,75 +1138,12 @@ static int output_delayed_imports( FILE *outfile, const DLLSPEC *spec ) for (j = 0; j < dll_imports[i]->nb_imports; j++, pos += 4) { ORDDEF *odp = dll_imports[i]->imports[j]; - const char *name = odp->name ? odp->name : odp->export_name; - - fprintf( outfile, " \"\\t" __ASM_FUNC("%s") "\\n\"\n", name ); - fprintf( outfile, " \"\\t.globl " __ASM_NAME("%s") "\\n\"\n", name ); - fprintf( outfile, " \"" __ASM_NAME("%s") ":\\n\\t\"", name ); -#if defined(__i386__) - if (strstr( name, "__wine_call_from_16" )) - fprintf( outfile, "\".byte 0x2e\\n\\tjmp *(delay_imports+%d)\\n\\tnop\\n\"", pos ); - else - fprintf( outfile, "\"jmp *(delay_imports+%d)\\n\\tmovl %%esi,%%esi\\n\"", pos ); -#elif defined(__sparc__) - if ( !UsePIC ) - { - fprintf( outfile, "\"sethi %%hi(delay_imports+%d), %%g1\\n\\t\"", pos ); - fprintf( outfile, "\"ld [%%g1+%%lo(delay_imports+%d)], %%g1\\n\\t\"", pos ); - fprintf( outfile, "\"jmp %%g1\\n\\tnop\\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, "\"save %%sp, -96, %%sp\\n\"" ); - fprintf( outfile, "\"0:\\tcall 1f\\n\\tnop\\n\"" ); - fprintf( outfile, "\"1:\\tsethi %%hi(delay_imports+%d-0b), %%g1\\n\\t\"", pos ); - fprintf( outfile, "\"or %%g1, %%lo(delay_imports+%d-0b), %%g1\\n\\t\"", pos ); - fprintf( outfile, "\"ld [%%g1+%%o7], %%g1\\n\\t\"" ); - fprintf( outfile, "\"jmp %%g1\\n\\trestore\\n\"" ); - } - -#elif defined(__powerpc__) - fprintf( outfile, "\t\"addi %s, %s, -0x4\\n\"\n", ppc_reg[1], ppc_reg[1]); - fprintf( outfile, "\t\"\\tstw %s, 0(%s)\\n\"\n", ppc_reg[9], ppc_reg[1]); - fprintf( outfile, "\t\"\\taddi %s, %s, -0x4\\n\"\n", ppc_reg[1], ppc_reg[1]); - fprintf( outfile, "\t\"\\tstw %s, 0(%s)\\n\"\n", ppc_reg[8], ppc_reg[1]); - fprintf( outfile, "\t\"\\taddi %s, %s, -0x4\\n\"\n", ppc_reg[1], ppc_reg[1]); - fprintf( outfile, "\t\"\\tstw %s, 0(%s)\\n\"\n", ppc_reg[7], ppc_reg[1]); - - fprintf( outfile, "\t\"\\tlis %s, " ppc_high(__ASM_NAME("delay_imports") "+ %d") "\\n\"\n", ppc_reg[9], pos); - fprintf( outfile, "\t\"\\tla %s, " ppc_low (__ASM_NAME("delay_imports") "+ %d") "(%s)\\n\"\n", ppc_reg[8], pos, ppc_reg[9]); - fprintf( outfile, "\t\"\\tlwz %s, 0(%s)\\n\"\n", ppc_reg[7], ppc_reg[8]); - fprintf( outfile, "\t\"\\tmtctr %s\\n\"\n", ppc_reg[7]); - - fprintf( outfile, "\t\"\\tlwz %s, 0(%s)\\n\"\n", ppc_reg[7], ppc_reg[1]); - fprintf( outfile, "\t\"\\taddi %s, %s, 0x4\\n\"\n", ppc_reg[1], ppc_reg[1]); - fprintf( outfile, "\t\"\\tlwz %s, 0(%s)\\n\"\n", ppc_reg[8], ppc_reg[1]); - fprintf( outfile, "\t\"\\taddi %s, %s, 0x4\\n\"\n", ppc_reg[1], ppc_reg[1]); - fprintf( outfile, "\t\"\\tlwz %s, 0(%s)\\n\"\n", ppc_reg[9], ppc_reg[1]); - fprintf( outfile, "\t\"\\taddi %s, %s, 0x4\\n\"\n", ppc_reg[1], ppc_reg[1]); - fprintf( outfile, "\t\"\\tbctr\\n\""); -#elif defined(__ALPHA__) - fprintf( outfile, "\t\"lda $0,delay_imports\\n\"\n" ); - fprintf( outfile, "\t\"\\tlda $0,%d($0)\\n\"\n", pos); - fprintf( outfile, "\t\"\\tjmp $31,($0)\\n\"" ); -#else -#error You need to define delayed import thunks for your architecture! -#endif - fprintf( outfile, "\n" ); - output_function_size( outfile, name ); + output_import_thunk( outfile, odp->name ? odp->name : odp->export_name, + "delay_imports", pos ); } } output_function_size( outfile, delayed_import_thunks ); fprintf( outfile, ");\n" ); - fprintf( outfile, "#ifndef __GNUC__\n" ); - fprintf( outfile, "}\n" ); - fprintf( outfile, "#endif\n" ); - fprintf( outfile, "\n" ); - - done: - return nb_delayed; } /* output the import and delayed import tables of a Win32 module @@ -1152,3 +1154,10 @@ int output_imports( FILE *outfile, DLLSPEC *spec, int *nb_delayed ) *nb_delayed = output_delayed_imports( outfile, spec ); return output_immediate_imports( outfile ); } + +/* output the import and delayed import thunks of a Win32 module */ +void output_import_thunks( FILE *outfile, DLLSPEC *spec ) +{ + output_delayed_import_thunks( outfile, spec ); + output_immediate_import_thunks( outfile ); +} diff --git a/reactos/tools/winebuild/main.c b/reactos/tools/winebuild/main.c index 3f98a88a46c..6deadbdb83b 100644 --- a/reactos/tools/winebuild/main.c +++ b/reactos/tools/winebuild/main.c @@ -44,12 +44,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; @@ -454,6 +470,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: diff --git a/reactos/tools/winebuild/parser.c b/reactos/tools/winebuild/parser.c index 424a0ef499b..6043018fd24 100644 --- a/reactos/tools/winebuild/parser.c +++ b/reactos/tools/winebuild/parser.c @@ -485,14 +485,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) { @@ -627,17 +625,17 @@ static void assign_ordinals( DLLSPEC *spec ) } /* now assign ordinals to the rest */ - for (i = 0, ordinal = spec->base; i < spec->nb_names; i++) + for (i = 0, ordinal = spec->base; i < spec->nb_entry_points; i++) { - if (spec->names[i]->ordinal != -1) continue; /* already has an ordinal */ + if (spec->entry_points[i].ordinal != -1) continue; while (spec->ordinals[ordinal]) ordinal++; if (ordinal >= MAX_ORDINALS) { - current_line = spec->names[i]->lineno; + current_line = spec->entry_points[i].lineno; fatal_error( "Too many functions defined (max %d)\n", MAX_ORDINALS ); } - spec->names[i]->ordinal = ordinal; - spec->ordinals[ordinal] = spec->names[i]; + spec->entry_points[i].ordinal = ordinal; + spec->ordinals[ordinal] = &spec->entry_points[i]; } if (ordinal > spec->limit) spec->limit = ordinal; } diff --git a/reactos/tools/winebuild/relay.c b/reactos/tools/winebuild/relay.c index abac75ae4d9..3eec149a3ba 100644 --- a/reactos/tools/winebuild/relay.c +++ b/reactos/tools/winebuild/relay.c @@ -31,20 +31,24 @@ #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.globl " __ASM_NAME("%s") "\n", name ); - fprintf( outfile, __ASM_NAME("%s") ":\n", name ); + fprintf( outfile, "\t%s\n", func_declaration(name) ); + fprintf( outfile, "\t.globl %s\n", asm_name(name) ); + fprintf( outfile, "%s:\n", asm_name(name) ); } static void function_footer( FILE *outfile, const char *name ) { - fprintf( outfile, ".size " __ASM_NAME("%s") ", . - " __ASM_NAME("%s") "\n", name, name ); + 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" : ""; } /******************************************************************* @@ -147,37 +151,31 @@ static void BuildCallFrom16Core( FILE *outfile, int reg_func, int thunk, int sho if (UsePIC) { - fprintf( outfile, "\t.byte 0x2e\n\tmovl " __ASM_NAME("CallTo16_DataSelector@GOT") "(%%ecx), %%edx\n" ); + fprintf( outfile, "\t.byte 0x2e\n\tmovl %s(%%ecx), %%edx\n", asm_name("CallTo16_DataSelector@GOT") ); fprintf( outfile, "\t.byte 0x2e\n\tmovl (%%edx), %%edx\n" ); } else - fprintf( outfile, "\t.byte 0x2e\n\tmovl " __ASM_NAME("CallTo16_DataSelector") ",%%edx\n" ); + fprintf( outfile, "\t.byte 0x2e\n\tmovl %s,%%edx\n", asm_name("CallTo16_DataSelector") ); /* 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 ) { - fprintf( outfile, "\tmovl " __ASM_NAME("CallTo16_TebSelector@GOT") "(%%ecx), %%edx\n" ); + fprintf( outfile, "\tmovl %s(%%ecx), %%edx\n", asm_name("CallTo16_TebSelector@GOT") ); fprintf( outfile, "\tmovw (%%edx), %%fs\n" ); } else - fprintf( outfile, "\tmovw " __ASM_NAME("CallTo16_TebSelector") ", %%fs\n" ); + fprintf( outfile, "\tmovw %s, %%fs\n", asm_name("CallTo16_TebSelector") ); fprintf( outfile, "\t.byte 0x64\n\tmov (%d),%%gs\n", STRUCTOFFSET(TEB,gs_sel) ); /* Get address of wine_ldt_copy array into %ecx */ if ( UsePIC ) - fprintf( outfile, "\tmovl " __ASM_NAME("wine_ldt_copy@GOT") "(%%ecx), %%ecx\n" ); + fprintf( outfile, "\tmovl %s(%%ecx), %%ecx\n", asm_name("wine_ldt_copy@GOT") ); else - fprintf( outfile, "\tmovl $" __ASM_NAME("wine_ldt_copy") ", %%ecx\n" ); + fprintf( outfile, "\tmovl $%s, %%ecx\n", asm_name("wine_ldt_copy") ); /* Translate STACK16FRAME base to flat offset in %edx */ fprintf( outfile, "\tmovw %%ss, %%dx\n" ); @@ -195,10 +193,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" ); @@ -320,9 +315,9 @@ static void BuildCallFrom16Core( FILE *outfile, int reg_func, int thunk, int sho fprintf( outfile, "\tpushl $0\n" ); if ( UsePIC ) - fprintf( outfile, "\tcall " __ASM_NAME("RELAY_DebugCallFrom16@PLT") "\n "); + fprintf( outfile, "\tcall %s\n ", asm_name("RELAY_DebugCallFrom16@PLT")); else - fprintf( outfile, "\tcall " __ASM_NAME("RELAY_DebugCallFrom16") "\n "); + fprintf( outfile, "\tcall %s\n ", asm_name("RELAY_DebugCallFrom16")); fprintf( outfile, "\tpopl %%edx\n" ); fprintf( outfile, "\tpopl %%edx\n" ); @@ -359,9 +354,9 @@ static void BuildCallFrom16Core( FILE *outfile, int reg_func, int thunk, int sho fprintf( outfile, "\tpushl $0\n" ); if ( UsePIC ) - fprintf( outfile, "\tcall " __ASM_NAME("RELAY_DebugCallFrom16Ret@PLT") "\n "); + fprintf( outfile, "\tcall %s\n ", asm_name("RELAY_DebugCallFrom16Ret@PLT")); else - fprintf( outfile, "\tcall " __ASM_NAME("RELAY_DebugCallFrom16Ret") "\n "); + fprintf( outfile, "\tcall %s\n ", asm_name("RELAY_DebugCallFrom16Ret")); fprintf( outfile, "\tpopl %%eax\n" ); fprintf( outfile, "\tpopl %%eax\n" ); @@ -545,10 +540,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 ); @@ -625,26 +617,19 @@ 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, "\t.byte 0x2e\n\tmovl %s", asm_name("CallTo16_DataSelector") ); + fprintf( outfile, "-%s,%%edi\n", asm_name("Call16_Ret_Start") ); + 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" ); + fprintf( outfile, "\t.byte 0x2e\n\tmov %s", asm_name("CallTo16_TebSelector") ); + fprintf( outfile, "-%s,%%fs\n", asm_name("Call16_Ret_Start") ); fprintf( outfile, "\t.byte 0x64\n\tmov (%d),%%gs\n", STRUCTOFFSET(TEB,gs_sel) ); /* 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 */ @@ -657,10 +642,10 @@ static void BuildRet16Func( FILE *outfile ) /* Declare the return address and data selector variables */ fprintf( outfile, "\n\t.align %d\n", get_alignment(4) ); - fprintf( outfile, "\t.globl " __ASM_NAME("CallTo16_DataSelector") "\n" ); - fprintf( outfile, __ASM_NAME("CallTo16_DataSelector") ":\t.long 0\n" ); - fprintf( outfile, "\t.globl " __ASM_NAME("CallTo16_TebSelector") "\n" ); - fprintf( outfile, __ASM_NAME("CallTo16_TebSelector") ":\t.long 0\n" ); + fprintf( outfile, "\t.globl %s\n", asm_name("CallTo16_DataSelector") ); + fprintf( outfile, "%s:\t.long 0\n", asm_name("CallTo16_DataSelector") ); + fprintf( outfile, "\t.globl %s\n", asm_name("CallTo16_TebSelector") ); + fprintf( outfile, "%s:\t.long 0\n", asm_name("CallTo16_TebSelector") ); } @@ -756,14 +741,14 @@ static void BuildRet16Func( FILE *outfile ) */ static void BuildCallTo32CBClient( FILE *outfile, BOOL isEx ) { - const char *name = isEx? "CBClientEx" : "CBClient"; + const char *name = isEx? "CALL32_CBClientEx" : "CALL32_CBClient"; int size = isEx? 24 : 12; /* Function header */ fprintf( outfile, "\n\t.align %d\n", get_alignment(4) ); - fprintf( outfile, "\t.globl " __ASM_NAME("CALL32_%s") "\n", name ); - fprintf( outfile, __ASM_NAME("CALL32_%s") ":\n", name ); + fprintf( outfile, "\t.globl %s\n", asm_name(name) ); + fprintf( outfile, "%s:\n", asm_name(name) ); /* Entry code */ @@ -773,6 +758,15 @@ static void BuildCallTo32CBClient( FILE *outfile, BOOL isEx ) fprintf( outfile, "\tpushl %%esi\n" ); fprintf( outfile, "\tpushl %%ebx\n" ); + if (UsePIC) + { + /* Get Global Offset Table into %edx */ + fprintf( outfile, "\tcall .L__wine_%s.getgot1\n", name ); + fprintf( outfile, ".L__wine_%s.getgot1:\n", name ); + fprintf( outfile, "\tpopl %%edx\n" ); + fprintf( outfile, "\taddl $_GLOBAL_OFFSET_TABLE_+[.-.L__wine_%s.getgot1], %%edx\n", name ); + } + /* Get the 16-bit stack */ fprintf( outfile, "\t.byte 0x64\n\tmovl (%d),%%ebx\n", STACKOFFSET); @@ -782,7 +776,13 @@ static void BuildCallTo32CBClient( FILE *outfile, BOOL isEx ) fprintf( outfile, "\tshldl $16,%%ebx,%%eax\n" ); fprintf( outfile, "\tandl $0xfff8,%%eax\n" ); fprintf( outfile, "\tshrl $1,%%eax\n" ); - fprintf( outfile, "\tmovl " __ASM_NAME("wine_ldt_copy") "(%%eax),%%esi\n" ); + if (!UsePIC) + fprintf( outfile, "\tmovl %s(%%eax),%%esi\n", asm_name("wine_ldt_copy") ); + else + { + fprintf( outfile, "\tmovl %s(%%edx), %%esi\n", asm_name("wine_ldt_copy@GOT") ); + fprintf( outfile, "\tmovl (%%esi,%%eax), %%esi\n" ); + } fprintf( outfile, "\tmovw %%bx,%%ax\n" ); fprintf( outfile, "\taddl %%eax,%%esi\n" ); @@ -815,7 +815,13 @@ static void BuildCallTo32CBClient( FILE *outfile, BOOL isEx ) fprintf( outfile, "\taddl $%d, %%ebx\n", sizeof(STACK16FRAME)-size+4 + 4 ); fprintf( outfile, "\tmovl %%ebx, 0(%%edi)\n" ); /* 16-bit ss:sp */ - fprintf( outfile, "\tmovl " __ASM_NAME("CALL32_%s_RetAddr") ", %%eax\n", name ); + if (!UsePIC) + fprintf( outfile, "\tmovl %s_RetAddr, %%eax\n", asm_name(name) ); + else + { + fprintf( outfile, "\tmovl %s_RetAddr@GOT(%%edx), %%eax\n", asm_name(name) ); + fprintf( outfile, "\tmovl (%%eax), %%eax\n" ); + } fprintf( outfile, "\tmovl %%eax, 4(%%edi)\n" ); /* overwrite return address */ } else @@ -836,7 +842,13 @@ static void BuildCallTo32CBClient( FILE *outfile, BOOL isEx ) fprintf( outfile, "\tandl $0x0000ffff, %%eax\n" ); fprintf( outfile, "\tmovl %%eax, 16(%%edi)\n" ); - fprintf( outfile, "\tmovl " __ASM_NAME("CALL32_%s_RetAddr") ", %%eax\n", name ); + if (!UsePIC) + fprintf( outfile, "\tmovl %s_RetAddr, %%eax\n", asm_name(name) ); + else + { + fprintf( outfile, "\tmovl %s_RetAddr@GOT(%%edx), %%eax\n", asm_name(name) ); + fprintf( outfile, "\tmovl (%%eax), %%eax\n" ); + } fprintf( outfile, "\tmovl %%eax, 20(%%edi)\n" ); } @@ -885,17 +897,17 @@ static void BuildCallTo32CBClient( FILE *outfile, BOOL isEx ) fprintf( outfile, "\tpopl %%edi\n" ); fprintf( outfile, "\tpopl %%ebp\n" ); fprintf( outfile, "\tret\n" ); - fprintf( outfile, ".size " __ASM_NAME("CALL32_%s") ", . - " __ASM_NAME("CALL32_%s") "\n", name, name ); + function_footer( outfile, name ); } static void BuildCallTo32CBClientRet( FILE *outfile, BOOL isEx ) { - const char *name = isEx? "CBClientEx" : "CBClient"; + const char *name = isEx? "CALL32_CBClientEx_Ret" : "CALL32_CBClient_Ret"; /* '16-bit' return stub */ - fprintf( outfile, "\n\t.globl " __ASM_NAME("CALL32_%s_Ret") "\n", name ); - fprintf( outfile, __ASM_NAME("CALL32_%s_Ret") ":\n", name ); + fprintf( outfile, "\n\t.globl %s\n", asm_name(name) ); + fprintf( outfile, "%s:\n", asm_name(name) ); if ( !isEx ) { @@ -910,13 +922,12 @@ static void BuildCallTo32CBClientRet( FILE *outfile, BOOL isEx ) fprintf( outfile, "\tlssl %%ss:-12(%%ebx), %%esp\n" ); } fprintf( outfile, "\tlret\n" ); - - fprintf( outfile, ".size " __ASM_NAME("CALL32_%s_Ret") ", . - " __ASM_NAME("CALL32_%s_Ret") "\n", name, name ); + function_footer( outfile, name ); /* Declare the return address variable */ - fprintf( outfile, "\n\t.globl " __ASM_NAME("CALL32_%s_RetAddr") "\n", name ); - fprintf( outfile, __ASM_NAME("CALL32_%s_RetAddr") ":\t.long 0\n", name ); + fprintf( outfile, "\n\t.globl %sAddr\n", asm_name(name) ); + fprintf( outfile, "%sAddr:\t.long 0\n", asm_name(name) ); } @@ -1011,7 +1022,8 @@ static void BuildCallFrom32Regs( FILE *outfile ) /* Call the entry point */ - fprintf( outfile, "\tcall *0(%%ebx)\n" ); + fprintf( outfile, "\taddl (%%ebx),%%ebx\n" ); + fprintf( outfile, "\tcall *%%ebx\n" ); fprintf( outfile, "\tleal -%d(%%ebp),%%ecx\n", STACK_SPACE ); /* Restore the context structure */ @@ -1074,30 +1086,30 @@ static void BuildPendingEventCheck( FILE *outfile ) function_header( outfile, "DPMI_PendingEventCheck" ); /* Check for pending events. */ - - fprintf( outfile, "\t.byte 0x64\n\ttestl $0xffffffff,(%d)\n", - STRUCTOFFSET(TEB,vm86_pending) ); - fprintf( outfile, "\tje " __ASM_NAME("DPMI_PendingEventCheck_Cleanup") "\n" ); - fprintf( outfile, "\t.byte 0x64\n\ttestl $0xffffffff,(%d)\n", + fprintf( outfile, "\t.byte 0x64\n\ttestl $0xffffffff,(%d)\n", + STRUCTOFFSET(TEB,vm86_pending) ); + fprintf( outfile, "\tje %s\n", asm_name("DPMI_PendingEventCheck_Cleanup") ); + + fprintf( outfile, "\t.byte 0x64\n\ttestl $0xffffffff,(%d)\n", STRUCTOFFSET(TEB,dpmi_vif) ); - fprintf( outfile, "\tje " __ASM_NAME("DPMI_PendingEventCheck_Cleanup") "\n" ); + fprintf( outfile, "\tje %s\n", asm_name("DPMI_PendingEventCheck_Cleanup") ); /* Process pending events. */ fprintf( outfile, "\tsti\n" ); - + /* Start cleanup. Restore fs register. */ - fprintf( outfile, ".globl " __ASM_NAME("DPMI_PendingEventCheck_Cleanup") "\n" ); - fprintf( outfile, __ASM_NAME("DPMI_PendingEventCheck_Cleanup") ":\n" ); + fprintf( outfile, ".globl %s\n", asm_name("DPMI_PendingEventCheck_Cleanup") ); + fprintf( outfile, "%s:\n", asm_name("DPMI_PendingEventCheck_Cleanup") ); fprintf( outfile, "\tpopw %%fs\n" ); /* Return from function. */ - fprintf( outfile, ".globl " __ASM_NAME("DPMI_PendingEventCheck_Return") "\n" ); - fprintf( outfile, __ASM_NAME("DPMI_PendingEventCheck_Return") ":\n" ); + fprintf( outfile, ".globl %s\n", asm_name("DPMI_PendingEventCheck_Return") ); + fprintf( outfile, "%s:\n", asm_name("DPMI_PendingEventCheck_Return") ); fprintf( outfile, "\tiret\n" ); function_footer( outfile, "DPMI_PendingEventCheck" ); @@ -1111,15 +1123,21 @@ 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" ); fprintf( outfile, "\t.text\n" ); - fprintf( outfile, __ASM_NAME("__wine_spec_thunk_text_16") ":\n\n" ); + fprintf( outfile, "%s:\n\n", asm_name("__wine_spec_thunk_text_16") ); - fprintf( outfile, __ASM_NAME("Call16_Start") ":\n" ); - fprintf( outfile, "\t.globl " __ASM_NAME("Call16_Start") "\n" ); + fprintf( outfile, "\t.globl %s\n", asm_name("Call16_Start") ); + fprintf( outfile, "%s:\n", asm_name("Call16_Start") ); fprintf( outfile, "\t.byte 0\n\n" ); /* Standard CallFrom16 routine (WORD return) */ @@ -1146,15 +1164,15 @@ void BuildRelays16( FILE *outfile ) /* CBClientThunkSLEx routine */ BuildCallTo32CBClient( outfile, TRUE ); - fprintf( outfile, __ASM_NAME("Call16_End") ":\n" ); - fprintf( outfile, "\t.globl " __ASM_NAME("Call16_End") "\n" ); - fprintf( outfile, "\t.size " __ASM_NAME("__wine_spec_thunk_text_16") ",. - " __ASM_NAME("__wine_spec_thunk_text_16") "\n" ); + fprintf( outfile, "\t.globl %s\n", asm_name("Call16_End") ); + fprintf( outfile, "%s:\n", asm_name("Call16_End") ); + function_footer( outfile, "__wine_spec_thunk_text_16" ); /* The whole Call16_Ret segment must lie within the .data section */ fprintf( outfile, "\n\t.data\n" ); - fprintf( outfile, __ASM_NAME("__wine_spec_thunk_data_16") ":\n\n" ); - fprintf( outfile, "\t.globl " __ASM_NAME("Call16_Ret_Start") "\n" ); - fprintf( outfile, __ASM_NAME("Call16_Ret_Start") ":\n" ); + fprintf( outfile, "%s:\n\n", asm_name("__wine_spec_thunk_data_16") ); + fprintf( outfile, "\t.globl %s\n", asm_name("Call16_Ret_Start") ); + fprintf( outfile, "%s:\n", asm_name("Call16_Ret_Start") ); /* Standard CallTo16 return stub */ BuildRet16Func( outfile ); @@ -1169,9 +1187,9 @@ void BuildRelays16( FILE *outfile ) BuildPendingEventCheck( outfile ); /* End of Call16_Ret segment */ - fprintf( outfile, "\n\t.globl " __ASM_NAME("Call16_Ret_End") "\n" ); - fprintf( outfile, __ASM_NAME("Call16_Ret_End") ":\n" ); - fprintf( outfile, "\t.size " __ASM_NAME("__wine_spec_thunk_data_16") ",. - " __ASM_NAME("__wine_spec_thunk_data_16") "\n" ); + fprintf( outfile, "\n\t.globl %s\n", asm_name("Call16_Ret_End") ); + fprintf( outfile, "%s:\n", asm_name("Call16_Ret_End") ); + function_footer( outfile, "__wine_spec_thunk_data_16" ); } /******************************************************************* @@ -1181,28 +1199,20 @@ 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" ); fprintf( outfile, "\t.text\n" ); - fprintf( outfile, __ASM_NAME("__wine_spec_thunk_text_32") ":\n\n" ); + fprintf( outfile, "%s:\n\n", asm_name("__wine_spec_thunk_text_32") ); /* 32-bit register entry point */ BuildCallFrom32Regs( outfile ); - fprintf( outfile, "\t.size " __ASM_NAME("__wine_spec_thunk_text_32") ",. - " __ASM_NAME("__wine_spec_thunk_text_32") "\n" ); + 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__ */ diff --git a/reactos/tools/winebuild/res32.c b/reactos/tools/winebuild/res32.c index 6fb12adcc10..2a8dbc39876 100644 --- a/reactos/tools/winebuild/res32.c +++ b/reactos/tools/winebuild/res32.c @@ -329,22 +329,6 @@ void output_resources( FILE *outfile, DLLSPEC *spec ) tree = build_resource_tree( spec ); - /* resource data */ - - for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++) - { - const unsigned int *p = res->data; - int size = res->data_size / 4; - /* dump data as ints to ensure correct alignment */ - fprintf( outfile, "static const unsigned int res_%d[%d] = {\n ", i, size ); - for (j = 0; j < size - 1; j++, p++) - { - fprintf( outfile, "0x%08x,", *p ); - if ((j % 8) == 7) fprintf( outfile, "\n " ); - } - fprintf( outfile, "0x%08x\n};\n\n", *p ); - } - /* directory structures */ fprintf( outfile, "struct res_dir {\n" ); @@ -412,10 +396,12 @@ void output_resources( FILE *outfile, DLLSPEC *spec ) else name->name_offset = name->name->id; } } + for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++) + fprintf( outfile, " unsigned int res_%d[%d];\n", i, res->data_size / 4 ); /* resource directory contents */ - fprintf( outfile, "} resources = {\n" ); + fprintf( outfile, "} __wine_spec_resources = {\n" ); fprintf( outfile, " { 0, 0, 0, 0, %d, %d },\n", tree->nb_types - nb_id_types, nb_id_types ); /* dump the type directory */ @@ -463,7 +449,7 @@ void output_resources( FILE *outfile, DLLSPEC *spec ) fprintf( outfile, " {\n" ); for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++) { - fprintf( outfile, " { res_%d, sizeof(res_%d), 0, 0 }, /* %08x */\n", i, i, + fprintf( outfile, " { __wine_spec_resources.res_%d, sizeof(__wine_spec_resources.res_%d), 0, 0 }, /* %08x */\n", i, i, data_offset + i * 4 * sizeof(int) ); } @@ -484,6 +470,24 @@ void output_resources( FILE *outfile, DLLSPEC *spec ) } } } - fprintf( outfile, " }\n};\n\n" ); + fprintf( outfile, " },\n" ); + + /* resource data */ + + for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++) + { + const unsigned int *p = res->data; + int size = res->data_size / 4; + /* dump data as ints to ensure correct alignment */ + fprintf( outfile, " { /* res_%d */\n ", i ); + for (j = 0; j < size - 1; j++, p++) + { + fprintf( outfile, "0x%08x,", *p ); + if ((j % 8) == 7) fprintf( outfile, "\n " ); + } + fprintf( outfile, "0x%08x\n },\n", *p ); + } + fprintf( outfile, "};\n\n" ); + free_resource_tree( tree ); } diff --git a/reactos/tools/winebuild/spec16.c b/reactos/tools/winebuild/spec16.c index d8871ea0050..e22251ac0e5 100644 --- a/reactos/tools/winebuild/spec16.c +++ b/reactos/tools/winebuild/spec16.c @@ -36,20 +36,18 @@ /******************************************************************* * get_cs */ -#ifdef __i386__ static inline unsigned short get_cs(void) { - unsigned short res; -#ifdef __GNUC__ + unsigned short res = 0; +#ifdef __i386__ +# ifdef __GNUC__ __asm__("movw %%cs,%w0" : "=r"(res)); -#elif defined(_MSC_VER) +# elif defined(_MSC_VER) __asm { mov res, cs } -#else - res = 0; -#endif +# endif +#endif /* __i386__ */ return res; } -#endif /* __i386__ */ /******************************************************************* @@ -65,11 +63,7 @@ static void output_file_header( FILE *outfile ) fprintf( outfile, " unsigned long limit[8192];\n" ); fprintf( outfile, " unsigned char flags[8192];\n" ); fprintf( outfile, "} wine_ldt_copy;\n\n" ); -#ifdef __i386__ fprintf( outfile, "#define __stdcall __attribute__((__stdcall__))\n\n" ); -#else - fprintf( outfile, "#define __stdcall\n\n" ); -#endif } @@ -166,7 +160,6 @@ static void output_bytes( FILE *outfile, const void *buffer, unsigned int size ) } -#ifdef __i386__ /******************************************************************* * BuildCallFrom16Func * @@ -310,7 +303,6 @@ static void BuildCallFrom16Func( FILE *outfile, const char *profile, const char fprintf( outfile, "%s args + %d", i? ",\n" : "", argsize ); fprintf( outfile, " );\n}\n\n" ); } -#endif /******************************************************************* @@ -416,9 +408,7 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec ) unsigned int et_size, et_offset; char constructor[100], destructor[100]; -#ifdef __i386__ unsigned short code_selector = get_cs(); -#endif /* File header */ @@ -473,7 +463,6 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec ) } /* Output CallFrom16 routines needed by this .spec file */ -#ifdef __i386__ for ( i = 0; i < nTypes; i++ ) { char profile[101]; @@ -481,17 +470,11 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec ) strcpy( profile, get_function_name( typelist[i] )); BuildCallFrom16Func( outfile, profile, spec->file_name ); } -#endif /* compute code and data sizes, set offsets, and output prototypes */ -#ifdef __i386__ entrypoint_size = 2 + 5 + 4; /* pushw bp + pushl target + call */ callfrom_size = 5 + 7 + 4 + 8; /* pushl relay + lcall cs:glue + lret n + args */ -#else - entrypoint_size = 4 + 4; /* target + call */ - callfrom_size = 4 + 8; /* lret n + args */ -#endif code_size = nTypes * callfrom_size; for (i = 0; i <= spec->limit; i++) @@ -638,22 +621,18 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec ) code_offset = et_offset + et_size; fprintf( outfile, " struct {\n" ); -#ifdef __i386__ fprintf( outfile, " unsigned char pushl;\n" ); /* pushl $relay */ fprintf( outfile, " void *relay;\n" ); fprintf( outfile, " unsigned char lcall;\n" ); /* lcall __FLATCS__:glue */ fprintf( outfile, " void *glue;\n" ); fprintf( outfile, " unsigned short flatcs;\n" ); -#endif fprintf( outfile, " unsigned short lret;\n" ); /* lret $args */ fprintf( outfile, " unsigned short args;\n" ); fprintf( outfile, " unsigned int arg_types[2];\n" ); fprintf( outfile, " } call[%d];\n", nTypes ); fprintf( outfile, " struct {\n" ); -#ifdef __i386__ fprintf( outfile, " unsigned short pushw_bp;\n" ); /* pushw %bp */ fprintf( outfile, " unsigned char pushl;\n" ); /* pushl $target */ -#endif fprintf( outfile, " void (*target)();\n" ); fprintf( outfile, " unsigned short call;\n" ); /* call CALLFROM16 */ fprintf( outfile, " short callfrom16;\n" ); @@ -804,7 +783,6 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec ) if (typelist[i]->flags & FLAG_REGISTER) arg_types[0] |= ARG_REGISTER; if (typelist[i]->flags & FLAG_RET16) arg_types[0] |= ARG_RET16; -#ifdef __i386__ fprintf( outfile, " { 0x68, __wine_%s_CallFrom16_%s, 0x9a, __wine_call_from_16_%s,\n", make_c_identifier(spec->file_name), profile, (typelist[i]->flags & FLAG_REGISTER) ? "regs": @@ -815,14 +793,6 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec ) else fprintf( outfile, " 0x%04x, 0xcb66, 0x9090, { 0x%08x, 0x%08x } },\n", code_selector, arg_types[0], arg_types[1] ); -#else - if (argsize) - fprintf( outfile, " { 0xca66, %d, { 0x%08x, 0x%08x } },\n", - argsize, arg_types[0], arg_types[1] ); - else - fprintf( outfile, " { 0xcb66, 0x9090, { 0x%08x, 0x%08x } },\n", - arg_types[0], arg_types[1] ); -#endif } fprintf( outfile, " },\n {\n" ); @@ -841,11 +811,7 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec ) fprintf( outfile, " /* %s.%d */ ", spec->dll_name, i ); fprintf( outfile, -#ifdef __i386__ "{ 0x5566, 0x68, %s, 0xe866, %d /* %s */ },\n", -#else - "{ %s, 0xe866, %d, /* %s */ },\n", -#endif odp->link_name, (type - typelist) * callfrom_size - (odp->offset + entrypoint_size), get_function_name( odp ) ); @@ -877,7 +843,6 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec ) sprintf( constructor, "__wine_spec_%s_init", make_c_identifier(spec->file_name) ); sprintf( destructor, "__wine_spec_%s_fini", make_c_identifier(spec->file_name) ); - output_dll_init( outfile, constructor, destructor ); fprintf( outfile, "void %s(void)\n" @@ -891,4 +856,14 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec ) " extern void __wine_dll_unregister_16( const struct module_data * );\n" " __wine_dll_unregister_16( &module );\n" "}\n", destructor ); + + fprintf( outfile, "#ifndef __GNUC__\n" ); + fprintf( outfile, "static void __asm__dummy_dll_init(void) {\n" ); + fprintf( outfile, "#endif\n" ); + + output_dll_init( outfile, constructor, destructor ); + + fprintf( outfile, "#ifndef __GNUC__\n" ); + fprintf( outfile, "}\n" ); + fprintf( outfile, "#endif\n" ); } diff --git a/reactos/tools/winebuild/spec32.c b/reactos/tools/winebuild/spec32.c index 6c3e1ee88dd..0f111026c6c 100644 --- a/reactos/tools/winebuild/spec32.c +++ b/reactos/tools/winebuild/spec32.c @@ -37,12 +37,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; @@ -80,17 +74,19 @@ 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, "# 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 %s\");\n", asm_name(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 ); - fprintf( outfile, " { asm(\".weak " __ASM_NAME("%s") "\"); }\n", name ); + fprintf( outfile, " { asm(\".weak %s\"); }\n", asm_name(name) ); fprintf( outfile, "#endif\n\n" ); } @@ -124,27 +120,85 @@ static int output_debug( FILE *outfile ) } +/******************************************************************* + * get_exports_size + * + * Compute the size of the export table. + */ +static int get_exports_size( DLLSPEC *spec ) +{ + int nr_exports = spec->base <= spec->limit ? spec->limit - spec->base + 1 : 0; + int i, fwd_size = 0, total_size; + + if (!nr_exports) return 0; + + /* export directory header */ + total_size = 10 * sizeof(int); + + /* function pointers */ + total_size += nr_exports * sizeof(int); + + /* function name pointers */ + total_size += spec->nb_names * sizeof(int); + + /* function ordinals */ + total_size += spec->nb_names * sizeof(short); + if (spec->nb_names % 2) total_size += sizeof(short); + + /* forward strings */ + for (i = spec->base; i <= spec->limit; i++) + { + ORDDEF *odp = spec->ordinals[i]; + if (odp && odp->flags & FLAG_FORWARD) fwd_size += strlen(odp->link_name) + 1; + } + total_size += (fwd_size + 3) & ~3; + + return total_size; +} + + +/******************************************************************* + * output_export_names + * + * Output all the exported names for a Win32 module. + */ +static void output_export_names( FILE *outfile, DLLSPEC *spec ) +{ + int i, nr_exports = spec->base <= spec->limit ? spec->limit - spec->base + 1 : 0; + + if (!nr_exports) return; + + fprintf( outfile, "\nconst char __wine_spec_exp_names[] =" ); + fprintf( outfile, "\n \"%s\\0\"", spec->file_name ); + for (i = 0; i < spec->nb_names; i++) + fprintf( outfile, "\n \"%s\\0\"", spec->names[i]->name ); + fprintf( outfile, ";\n" ); +} + + /******************************************************************* * output_exports * * Output the export table for a Win32 module. */ -static int output_exports( FILE *outfile, int nr_exports, DLLSPEC *spec ) +static void output_exports( FILE *outfile, DLLSPEC *spec ) { - int i, fwd_size = 0, total_size = 0; + int i, fwd_size = 0; + int nr_exports = spec->base <= spec->limit ? spec->limit - spec->base + 1 : 0; - if (!nr_exports) return 0; + if (!nr_exports) return; + fprintf( outfile, "/* export table */\n" ); fprintf( outfile, "asm(\".data\\n\"\n" ); fprintf( outfile, " \"\\t.align %d\\n\"\n", get_alignment(4) ); - fprintf( outfile, " \"" __ASM_NAME("__wine_spec_exports") ":\\n\"\n" ); + fprintf( outfile, " \"%s:\\n\"\n", asm_name("__wine_spec_exports") ); /* export directory header */ fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* Characteristics */ fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* TimeDateStamp */ fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* MajorVersion/MinorVersion */ - fprintf( outfile, " \"\\t.long __wine_spec_exp_names\\n\"\n" ); /* Name */ + fprintf( outfile, " \"\\t.long %s\\n\"\n", asm_name("__wine_spec_exp_names") ); /* Name */ fprintf( outfile, " \"\\t.long %d\\n\"\n", spec->base ); /* Base */ fprintf( outfile, " \"\\t.long %d\\n\"\n", nr_exports ); /* NumberOfFunctions */ fprintf( outfile, " \"\\t.long %d\\n\"\n", spec->nb_names ); /* NumberOfNames */ @@ -159,7 +213,6 @@ static int output_exports( FILE *outfile, int nr_exports, DLLSPEC *spec ) fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* AddressOfNames */ fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* AddressOfNameOrdinals */ } - total_size += 10 * sizeof(int); /* output the function pointers */ @@ -176,7 +229,7 @@ static int output_exports( FILE *outfile, int nr_exports, DLLSPEC *spec ) case TYPE_CDECL: if (!(odp->flags & FLAG_FORWARD)) { - fprintf( outfile, " \"\\t.long " __ASM_NAME("%s") "\\n\"\n", odp->link_name ); + fprintf( outfile, " \"\\t.long %s\\n\"\n", asm_name(odp->link_name) ); } else { @@ -185,14 +238,13 @@ static int output_exports( FILE *outfile, int nr_exports, DLLSPEC *spec ) } break; case TYPE_STUB: - fprintf( outfile, " \"\\t.long " __ASM_NAME("%s") "\\n\"\n", - make_internal_name( odp, spec, "stub" ) ); + fprintf( outfile, " \"\\t.long %s\\n\"\n", + asm_name( make_internal_name( odp, spec, "stub" )) ); break; default: assert(0); } } - total_size += (spec->limit - spec->base + 1) * sizeof(int); if (spec->nb_names) { @@ -203,21 +255,11 @@ static int output_exports( FILE *outfile, int nr_exports, DLLSPEC *spec ) fprintf( outfile, " \"__wine_spec_exp_name_ptrs:\\n\"\n" ); for (i = 0; i < spec->nb_names; i++) { - fprintf( outfile, " \"\\t.long __wine_spec_exp_names+%d\\n\"\n", namepos ); + fprintf( outfile, " \"\\t.long %s+%d\\n\"\n", asm_name("__wine_spec_exp_names"), namepos ); namepos += strlen(spec->names[i]->name) + 1; } - total_size += spec->nb_names * sizeof(int); } - /* output the function names */ - - fprintf( outfile, " \"\\t.text\\n\"\n" ); - fprintf( outfile, " \"__wine_spec_exp_names:\\n\"\n" ); - fprintf( outfile, " \"\\t" __ASM_STRING " \\\"%s\\\"\\n\"\n", spec->file_name ); - for (i = 0; i < spec->nb_names; i++) - fprintf( outfile, " \"\\t" __ASM_STRING " \\\"%s\\\"\\n\"\n", spec->names[i]->name ); - fprintf( outfile, " \"\\t.data\\n\"\n" ); - if (spec->nb_names) { /* output the function ordinals */ @@ -228,11 +270,9 @@ static int output_exports( FILE *outfile, int nr_exports, DLLSPEC *spec ) fprintf( outfile, " \"\\t" __ASM_SHORT " %d\\n\"\n", spec->names[i]->ordinal - spec->base ); } - total_size += spec->nb_names * sizeof(short); if (spec->nb_names % 2) { fprintf( outfile, " \"\\t" __ASM_SHORT " 0\\n\"\n" ); - total_size += sizeof(short); } } @@ -248,7 +288,6 @@ static int output_exports( FILE *outfile, int nr_exports, DLLSPEC *spec ) fprintf( outfile, " \"\\t" __ASM_STRING " \\\"%s\\\"\\n\"\n", odp->link_name ); } fprintf( outfile, " \"\\t.align %d\\n\"\n", get_alignment(4) ); - total_size += (fwd_size + 3) & ~3; } /* output relays */ @@ -279,15 +318,15 @@ static int output_exports( FILE *outfile, int nr_exports, DLLSPEC *spec ) switch(odp->type) { case TYPE_STDCALL: - fprintf( outfile, " \"\\tjmp " __ASM_NAME("%s") "\\n\"\n", odp->link_name ); + fprintf( outfile, " \"\\tjmp %s\\n\"\n", asm_name(odp->link_name) ); fprintf( outfile, " \"\\tret $%d\\n\"\n", args ); - fprintf( outfile, " \"\\t.long " __ASM_NAME("%s") ",0x%08x\\n\"\n", odp->link_name, mask ); + fprintf( outfile, " \"\\t.long %s,0x%08x\\n\"\n", asm_name(odp->link_name), mask ); break; case TYPE_CDECL: - fprintf( outfile, " \"\\tjmp " __ASM_NAME("%s") "\\n\"\n", odp->link_name ); + fprintf( outfile, " \"\\tjmp %s\\n\"\n", asm_name(odp->link_name) ); fprintf( outfile, " \"\\tret\\n\"\n" ); fprintf( outfile, " \"\\t" __ASM_SHORT " %d\\n\"\n", args ); - fprintf( outfile, " \"\\t.long " __ASM_NAME("%s") ",0x%08x\\n\"\n", odp->link_name, mask ); + fprintf( outfile, " \"\\t.long %s,0x%08x\\n\"\n", asm_name(odp->link_name), mask ); break; default: assert(0); @@ -298,12 +337,7 @@ static int output_exports( FILE *outfile, int nr_exports, DLLSPEC *spec ) fprintf( outfile, " \"\\t.long 0,0,0,0\\n\"\n" ); } } - - fprintf( outfile, " \"\\t.text\\n\"\n" ); - fprintf( outfile, " \"\\t.align %d\\n\"\n", get_alignment(4) ); - fprintf( outfile, ");\n\n" ); - - return total_size; + fprintf( outfile, ");\n" ); } @@ -369,88 +403,85 @@ static void output_stub_funcs( FILE *outfile, DLLSPEC *spec ) */ void output_dll_init( FILE *outfile, const char *constructor, const char *destructor ) { - fprintf( outfile, "#ifndef __GNUC__\n" ); - fprintf( outfile, "static void __asm__dummy_dll_init(void) {\n" ); - fprintf( outfile, "#endif\n" ); - -#if defined(__i386__) - if (constructor) + if (target_platform == PLATFORM_APPLE) { - 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" ); + /* 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 %s\\n\"\n", asm_name(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 %s\\n\"\n", asm_name(destructor) ); + fprintf( outfile, " \"\\t.text\\n\");\n" ); + } } - if (destructor) + else switch(target_cpu) { - 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" ); + case CPU_x86: + if (constructor) + { + fprintf( outfile, "asm(\"\\t.section\\t\\\".init\\\" ,\\\"ax\\\"\\n\"\n" ); + fprintf( outfile, " \"\\tcall %s\\n\"\n", asm_name(constructor) ); + fprintf( outfile, " \"\\t.section\\t\\\".text\\\"\\n\");\n" ); + } + if (destructor) + { + fprintf( outfile, "asm(\"\\t.section\\t\\\".fini\\\" ,\\\"ax\\\"\\n\"\n" ); + fprintf( outfile, " \"\\tcall %s\\n\"\n", asm_name(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 %s\\n\"\n", asm_name(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 %s\\n\"\n", asm_name(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,%s\\n\"\n", asm_name(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,%s\\n\"\n", asm_name(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 %s\\n\"\n", asm_name(constructor) ); + fprintf( outfile, " \"\\t.section\\t\\\".text\\\"\\n\");\n" ); + } + if (destructor) + { + fprintf( outfile, "asm(\"\\t.section\\t\\\".fini\\\" ,\\\"ax\\\"\\n\"\n" ); + fprintf( outfile, " \"\\tbl %s\\n\"\n", asm_name(destructor) ); + fprintf( outfile, " \"\\t.section\\t\\\".text\\\"\\n\");\n" ); + } + break; } -#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__) -# ifdef __APPLE__ -/* 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" ); - } -# else /* __APPLE__ */ - 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" ); - } -# endif /* __APPLE__ */ -#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 - fprintf( outfile, "#ifndef __GNUC__\n" ); - fprintf( outfile, "}\n" ); - fprintf( outfile, "#endif\n" ); } @@ -463,25 +494,12 @@ 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 ); output_standard_file_header( outfile ); /* Reserve some space for the PE header */ @@ -492,46 +510,32 @@ 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, " \"%s:\\t\"\n", asm_name("__wine_spec_pe_header") ); + 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" ); + fprintf( outfile, " \"%s:\\t.long 1\");\n", asm_name("__wine_spec_data_start") ); fprintf( outfile, "#ifndef __GNUC__\n" ); 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" ); - if (nr_exports) - { - /* Output the stub functions */ - - output_stub_funcs( outfile, spec ); - - fprintf( outfile, "#ifndef __GNUC__\n" ); - fprintf( outfile, "static void __asm__dummy(void) {\n" ); - fprintf( outfile, "#endif /* !defined(__GNUC__) */\n" ); - - /* Output the exports and relay entry points */ - - exports_size = output_exports( outfile, nr_exports, spec ); - - fprintf( outfile, "#ifndef __GNUC__\n" ); - fprintf( outfile, "}\n" ); - fprintf( outfile, "#endif /* !defined(__GNUC__) */\n" ); - } + output_stub_funcs( outfile, spec ); + output_export_names( outfile, spec ); /* Output the DLL imports */ @@ -548,26 +552,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) { @@ -736,15 +743,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 */ @@ -755,21 +768,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 */ @@ -779,8 +792,8 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec ) fprintf( outfile, " { %s, %s },\n", /* IMAGE_DIRECTORY_ENTRY_IMPORT */ nr_imports ? "&imports" : "0", nr_imports ? "sizeof(imports)" : "0" ); fprintf( outfile, " { %s, %s },\n", /* IMAGE_DIRECTORY_ENTRY_RESOURCE */ - spec->nb_resources ? "&resources" : "0", - spec->nb_resources ? "sizeof(resources)" : "0" ); + spec->nb_resources ? "&__wine_spec_resources" : "0", + spec->nb_resources ? "sizeof(__wine_spec_resources)" : "0" ); fprintf( outfile, " }\n }\n};\n\n" ); /* Output the DLL constructor */ @@ -794,7 +807,6 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec ) "}\n\n", spec->file_name ); - output_dll_init( outfile, "__wine_spec_init_ctor", NULL ); fprintf( outfile, "void __wine_spec_init_ctor(void)\n" "{\n" @@ -802,6 +814,18 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec ) " __wine_spec_init();\n" " __wine_spec_init_state = 2;\n" "}\n" ); + + fprintf( outfile, "#ifndef __GNUC__\n" ); + fprintf( outfile, "static void __asm__dummy(void) {\n" ); + fprintf( outfile, "#endif\n" ); + + output_exports( outfile, spec ); + output_import_thunks( outfile, spec ); + output_dll_init( outfile, "__wine_spec_init_ctor", NULL ); + + fprintf( outfile, "#ifndef __GNUC__\n" ); + fprintf( outfile, "}\n" ); + fprintf( outfile, "#endif\n" ); } @@ -915,7 +939,7 @@ void BuildDef32File( FILE *outfile, DLLSPEC *spec ) void BuildDebugFile( FILE *outfile, const char *srcdir, char **argv ) { int nr_debug; - char *prefix, *p; + char *prefix, *p, *constructor, *destructor; while (*argv) { @@ -941,69 +965,35 @@ void BuildDebugFile( FILE *outfile, const char *srcdir, char **argv ) /* Output the DLL constructor */ + constructor = xmalloc( strlen(prefix) + 17 ); + destructor = xmalloc( strlen(prefix) + 17 ); + sprintf( constructor, "__wine_dbg_%s_init", prefix ); + sprintf( destructor, "__wine_dbg_%s_fini", prefix ); fprintf( outfile, "#ifdef __GNUC__\n" - "void __wine_dbg_%s_init(void) __attribute__((constructor));\n" - "void __wine_dbg_%s_fini(void) __attribute__((destructor));\n" + "void %s(void) __attribute__((constructor));\n" + "void %s(void) __attribute__((destructor));\n" "#else\n" "static void __asm__dummy_dll_init(void) {\n", - prefix, prefix ); - -#if defined(__i386__) - fprintf( outfile, "asm(\"\\t.section\\t\\\".init\\\" ,\\\"ax\\\"\\n\"\n" ); - fprintf( outfile, " \"\\tcall " __ASM_NAME("__wine_dbg_%s_init") "\\n\"\n", prefix ); - fprintf( outfile, " \"\\t.section\\t\\\".fini\\\" ,\\\"ax\\\"\\n\"\n" ); - fprintf( outfile, " \"\\tcall " __ASM_NAME("__wine_dbg_%s_fini") "\\n\"\n", prefix ); - fprintf( outfile, " \"\\t.section\\t\\\".text\\\"\\n\");\n" ); -#elif defined(__sparc__) - fprintf( outfile, "asm(\"\\t.section\\t\\\".init\\\" ,\\\"ax\\\"\\n\"\n" ); - fprintf( outfile, " \"\\tcall " __ASM_NAME("__wine_dbg_%s_init") "\\n\"\n", prefix ); - fprintf( outfile, " \"\\tnop\\n\"\n" ); - fprintf( outfile, " \"\\t.section\\t\\\".fini\\\" ,\\\"ax\\\"\\n\"\n" ); - fprintf( outfile, " \"\\tcall " __ASM_NAME("__wine_dbg_%s_fini") "\\n\"\n", prefix ); - fprintf( outfile, " \"\\tnop\\n\"\n" ); - fprintf( outfile, " \"\\t.section\t\\\".text\\\"\\n\");\n" ); -#elif defined(__powerpc__) -# ifdef __APPLE__ - fprintf( outfile, "asm(\"\\t.mod_init_func\\n\"\n" ); - fprintf( outfile, " \"\\t.align 2\\n\"\n" ); - fprintf( outfile, " \"\\t.long " __ASM_NAME("__wine_dbg_%s_init") "\\n\"\n", prefix ); - fprintf( outfile, " \"\\t.text\\n\");\n" ); - fprintf( outfile, "asm(\"\\t.mod_term_func\\n\"\n" ); - fprintf( outfile, " \"\\t.align 2\\n\"\n" ); - fprintf( outfile, " \"\\t.long " __ASM_NAME("__wine_dbg_%s_fini") "\\n\"\n", prefix ); - fprintf( outfile, " \"\\t.text\\n\");\n" ); -# else - fprintf( outfile, "asm(\"\\t.section\\t\\\".init\\\" ,\\\"ax\\\"\\n\"\n" ); - fprintf( outfile, " \"\\tbl " __ASM_NAME("__wine_dbg_%s_init") "\\n\"\n", prefix ); - fprintf( outfile, " \"\\t.section\\t\\\".fini\\\" ,\\\"ax\\\"\\n\"\n" ); - fprintf( outfile, " \"\\tbl " __ASM_NAME("__wine_dbg_%s_fini") "\\n\"\n", prefix ); - fprintf( outfile, " \"\\t.text\\n\");\n" ); -# endif -#elif defined(__ALPHA__) - fprintf( outfile, "asm(\"\\t.section\\t\\\".init\\\" ,\\\"ax\\\"\\n\"\n" ); - fprintf( outfile, " \"\\tjsr $26," __ASM_NAME("__wine_dbg_%s_init") "\\n\"\n", prefix ); - fprintf( outfile, " \"\\t.section\\t\\\".fini\\\" ,\\\"ax\\\"\\n\"\n" ); - fprintf( outfile, " \"\\tjsr $26," __ASM_NAME("__wine_dbg_%s_fini") "\\n\"\n", prefix ); - fprintf( outfile, " \"\\t.section\\t\\\".text\\\"\\n\");\n" ); -#else -#error You need to define the DLL constructor for your architecture -#endif + constructor, destructor ); + output_dll_init( outfile, constructor, destructor ); fprintf( outfile, "}\n#endif /* defined(__GNUC__) */\n\n" ); fprintf( outfile, - "void __wine_dbg_%s_init(void)\n" + "void %s(void)\n" "{\n" " extern void *__wine_dbg_register( char * const *, int );\n" " if (!debug_registration) debug_registration = __wine_dbg_register( debug_channels, %d );\n" - "}\n\n", prefix, nr_debug ); + "}\n\n", constructor, nr_debug ); fprintf( outfile, - "void __wine_dbg_%s_fini(void)\n" + "void %s(void)\n" "{\n" " extern void __wine_dbg_unregister( void* );\n" " __wine_dbg_unregister( debug_registration );\n" - "}\n", prefix ); + "}\n", destructor ); + free( constructor ); + free( destructor ); free( prefix ); } diff --git a/reactos/tools/winebuild/utils.c b/reactos/tools/winebuild/utils.c index 1fe09aa30f8..0e64d801c37 100644 --- a/reactos/tools/winebuild/utils.c +++ b/reactos/tools/winebuild/utils.c @@ -24,6 +24,7 @@ #undef strdup #endif +#include #include #include #include @@ -342,81 +343,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__) + 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 symbol */ +const char *asm_name( const char *sym ) +{ + static char buffer[256]; + sprintf( buffer, __ASM_NAME("%s"), sym ); + 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 } diff --git a/reactos/tools/winebuild/winglue.h b/reactos/tools/winebuild/winglue.h index ecbb4f86588..6d3712d5158 100644 --- a/reactos/tools/winebuild/winglue.h +++ b/reactos/tools/winebuild/winglue.h @@ -17,7 +17,10 @@ typedef unsigned short WCHAR; #define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 #define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 -#define IMAGE_FILE_MACHINE_I386 332 +#define IMAGE_FILE_MACHINE_UNKNOWN 0 +#define IMAGE_FILE_MACHINE_I386 0x014c +#define IMAGE_FILE_MACHINE_ALPHA 0x0184 +#define IMAGE_FILE_MACHINE_POWERPC 0x01f0 #define IMAGE_NT_SIGNATURE 0x00004550 #define IMAGE_NT_OPTIONAL_HDR_MAGIC 0x10b