Phil Krylov phil@newstar.rinet.ru - Fixed winebuild operation in Darwin. Steve Zellers zellers@mac.com - Fixed leftover import table name in output_import_thunk. Alexandre Julliard julliard@winehq.org - Replace configure macros by explicit platform checks (probably not correct on all platforms yet). - Moved most of the implementation of CALL32_CBClient(Ex) to the C code. - Don't use the full 32 bits of %esp when called from 16-bit code. - Added a --target option to allow cross-compilation. - Improve a bit the assembly generated for import thunks. - Don't depend on ELF features for PIC code. - A couple of optimizations. - Intercept functions for 16-bit relay debugging by patching the CALLFROM16 table instead of having the wine_call_from_16 functions call out the relay functions explicitly. - Added vararg argument type so that the relay code can distinguish from a normal cdecl function. - Don't rely on the relay thunk preserving the stack pointer. - Moved all 16-bit relay code to the text section. - Changed a few symbol names for better consistency. - Get rid of the global debugging flag. Mike McCormack mike@codeweavers.com - gcc 4.0 -Wpointer-sign fixes. Marcus Meissner marcus@jet.franken.de - Fixed signedness warnings. Modified: trunk/reactos/tools/winebuild/build.h Modified: trunk/reactos/tools/winebuild/import.c Modified: trunk/reactos/tools/winebuild/main.c Modified: trunk/reactos/tools/winebuild/relay.c Modified: trunk/reactos/tools/winebuild/spec16.c Modified: trunk/reactos/tools/winebuild/spec32.c Modified: trunk/reactos/tools/winebuild/utils.c Modified: trunk/reactos/tools/winebuild/winebuild.man.in _____
Modified: trunk/reactos/tools/winebuild/build.h --- trunk/reactos/tools/winebuild/build.h 2005-08-10 21:09:05 UTC (rev 17270) +++ trunk/reactos/tools/winebuild/build.h 2005-08-10 22:15:12 UTC (rev 17271) @@ -184,6 +184,8 @@
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 const char *get_asm_string_keyword(void); +extern const char *get_asm_short_keyword(void);
extern void add_import_dll( const char *name, const char *filename ); extern void add_delayed_import( const char *name ); @@ -220,7 +222,6 @@
extern int current_line; extern int UsePIC; -extern int debugging; extern int nb_debug_channels; extern int nb_lib_paths; extern int nb_errors; _____
Modified: trunk/reactos/tools/winebuild/import.c --- trunk/reactos/tools/winebuild/import.c 2005-08-10 21:09:05 UTC (rev 17270) +++ trunk/reactos/tools/winebuild/import.c 2005-08-10 22:15:12 UTC (rev 17271) @@ -586,6 +586,7 @@
close( fd ); atexit( remove_ld_tmp_file );
+ if (!ld_command) ld_command = xstrdup("ld"); for (i = 0; argv[i]; i++) len += strlen(argv[i]) + 1; cmd = xmalloc( len + strlen(ld_tmp_file) + 8 + strlen(ld_command) ); sprintf( cmd, "%s -r -o %s", ld_command, ld_tmp_file ); @@ -616,6 +617,7 @@ if (argv[1]) name = ldcombine_files( argv ); else name = argv[0];
+ if (!nm_command) nm_command = xstrdup("nm"); cmd = xmalloc( strlen(nm_command) + strlen(name) + 5 ); sprintf( cmd, "%s -u %s", nm_command, name ); if (!(f = popen( cmd, "r" ))) @@ -692,7 +694,7 @@ /* 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.align %d\n"\n", get_alignment(4) ); 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) ); @@ -703,38 +705,50 @@ if (!UsePIC) { if (strstr( name, "__wine_call_from_16" )) fprintf( outfile, " "\t.byte 0x2e\n"\n" ); - fprintf( outfile, " "\tjmp *(imports+%d)\n"\n", pos ); + fprintf( outfile, " "\tjmp *(%s+%d)\n"\n", asm_name(table), pos ); } else { - if (!strcmp( name, "__wine_call_from_32_regs" ) || - !strcmp( name, "__wine_call_from_16_regs" )) + if (!strcmp( name, "__wine_call_from_32_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, " "\tmovl %s+%d-.L__wine_spec_%s(%%eax),%%eax\n"\n", + asm_name(table), pos, name ); + fprintf( outfile, " "\txchgl %%eax,(%%esp)\n"\n" ); fprintf( outfile, " "\tret\n"\n" ); } + else if (!strcmp( name, "__wine_call_from_16_regs" )) + { + /* special case: need to preserve all registers */ + fprintf( outfile, " "\tpushl %%eax\n"\n" ); + fprintf( outfile, " "\tpushl %%ecx\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, " "\t.byte 0x2e\n"\n" ); + fprintf( outfile, " "\tmovl %s+%d-.L__wine_spec_%s(%%eax),%%eax\n"\n", + asm_name(table), pos, name ); + fprintf( outfile, " "\tmovzwl %%sp, %%ecx\n"\n" ); + fprintf( outfile, " "\t.byte 0x36\n"\n" ); + fprintf( outfile, " "\txchgl %%eax,4(%%ecx)\n"\n" ); + fprintf( outfile, " "\tpopl %%ecx\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" ); + fprintf( outfile, " "\tjmp *%s+%d-.L__wine_spec_%s(%%eax)\n"\n", + asm_name(table), pos, name ); } } break; _____
Modified: trunk/reactos/tools/winebuild/main.c --- trunk/reactos/tools/winebuild/main.c 2005-08-10 21:09:05 UTC (rev 17270) +++ trunk/reactos/tools/winebuild/main.c 2005-08-10 22:15:12 UTC (rev 17271) @@ -44,7 +44,6 @@
int nb_errors = 0; int display_warnings = 0; int kill_at = 0; -int debugging = 0;
#if defined(__i386__) || defined(__x86_64__) enum target_cpu target_cpu = CPU_x86; @@ -75,8 +74,8 @@ char *spec_file_name = NULL; const char *output_file_name = NULL;
-char *ld_command = "ld"; -char *nm_command = "nm"; +char *ld_command = NULL; +char *nm_command = NULL;
static FILE *output_file; static const char *current_src_dir; @@ -98,6 +97,35 @@
static enum exec_mode_values exec_mode = MODE_NONE;
+static const struct +{ + const char *name; + enum target_cpu cpu; +} cpu_names[] = +{ + { "i386", CPU_x86 }, + { "i486", CPU_x86 }, + { "i586", CPU_x86 }, + { "i686", CPU_x86 }, + { "i786", CPU_x86 }, + { "sparc", CPU_SPARC }, + { "alpha", CPU_ALPHA }, + { "powerpc", CPU_POWERPC } +}; + +static const struct +{ + const char *name; + enum target_platform platform; +} platform_names[] = +{ + { "macos", PLATFORM_APPLE }, + { "darwin", PLATFORM_APPLE }, + { "sunos", PLATFORM_SVR4 }, + { "windows", PLATFORM_WINDOWS }, + { "winnt", PLATFORM_WINDOWS } +}; + /* set the dll file name from the input file name */ static void set_dll_file_name( const char *name, DLLSPEC *spec ) { @@ -137,6 +165,56 @@ free( str ); }
+/* set the target CPU and platform */ +static void set_target( const char *target ) +{ + unsigned int i; + char *p, *platform, *spec = xstrdup( target ); + + /* target specification is in the form CPU-MANUFACTURER-OS or CPU-MANUFACTURER-KERNEL-OS */ + + /* get the CPU part */ + + if (!(p = strchr( spec, '-' ))) fatal_error( "Invalid target specification '%s'\n", target ); + *p++ = 0; + for (i = 0; i < sizeof(cpu_names)/sizeof(cpu_names[0]); i++) + { + if (!strcmp( cpu_names[i].name, spec )) break; + } + if (i < sizeof(cpu_names)/sizeof(cpu_names[0])) target_cpu = cpu_names[i].cpu; + else fatal_error( "Unrecognized CPU '%s'\n", spec ); + + platform = p; + if ((p = strrchr( p, '-' ))) platform = p + 1; + + /* get the OS part */ + + target_platform = PLATFORM_UNSPECIFIED; /* default value */ + for (i = 0; i < sizeof(platform_names)/sizeof(platform_names[0]); i++) + { + if (!strncmp( platform_names[i].name, platform, strlen(platform_names[i].name) )) + { + target_platform = platform_names[i].platform; + break; + } + } + + free( spec ); + + if (!ld_command) + { + ld_command = xmalloc( strlen(target) + sizeof("-ld") ); + strcpy( ld_command, target ); + strcat( ld_command, "-ld" ); + } + if (!nm_command) + { + nm_command = xmalloc( strlen(target) + sizeof("-nm") ); + strcpy( nm_command, target ); + strcat( nm_command, "-nm" ); + } +} + /* cleanup on program exit */ static void cleanup(void) { @@ -177,6 +255,7 @@ " -o --output=NAME Set the output file name (default: stdout)\n" " -r --res=RSRC.RES Load resources from RSRC.RES\n" " --subsystem=SUBSYS Set the subsystem (one of native, windows, console)\n" +" --target=TARGET Specify target CPU and platform for cross-compiling\n" " --version Print the version and exit\n" " -w --warnings Turn on warnings\n" "\nMode options:\n" @@ -201,6 +280,7 @@ LONG_OPT_RELAY32, LONG_OPT_SUBSYSTEM, LONG_OPT_VERSION, + LONG_OPT_TARGET, LONG_OPT_PEDLL };
@@ -217,6 +297,7 @@ { "relay16", 0, 0, LONG_OPT_RELAY16 }, { "relay32", 0, 0, LONG_OPT_RELAY32 }, { "subsystem",1, 0, LONG_OPT_SUBSYSTEM }, + { "target", 1, 0, LONG_OPT_TARGET }, { "version", 0, 0, LONG_OPT_VERSION }, { "pedll", 1, 0, LONG_OPT_PEDLL }, /* aliases for short options */ @@ -373,6 +454,9 @@ case LONG_OPT_SUBSYSTEM: set_subsystem( optarg, spec ); break; + case LONG_OPT_TARGET: + set_target( optarg ); + break; case LONG_OPT_VERSION: printf( "winebuild version " PACKAGE_VERSION "\n" ); exit(0); @@ -470,9 +554,6 @@ 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: _____
Modified: trunk/reactos/tools/winebuild/relay.c --- trunk/reactos/tools/winebuild/relay.c 2005-08-10 21:09:05 UTC (rev 17270) +++ trunk/reactos/tools/winebuild/relay.c 2005-08-10 22:15:12 UTC (rev 17271) @@ -138,22 +138,16 @@
fprintf( outfile, "\tpushl %%edx\n" );
/* Save original EFlags register */ - fprintf( outfile, "\tpushfl\n" ); + if (reg_func) fprintf( outfile, "\tpushfl\n" );
if ( UsePIC ) { - /* Get Global Offset Table into %ecx */ - fprintf( outfile, "\tcall .L__wine_call_from_16_%s.getgot1\n", name ); - fprintf( outfile, ".L__wine_call_from_16_%s.getgot1:\n", name ); + fprintf( outfile, "\tcall .Lcall_from_16_%s.getpc\n", name ); + fprintf( outfile, ".Lcall_from_16_%s.getpc:\n", name ); fprintf( outfile, "\tpopl %%ecx\n" ); - fprintf( outfile, "\taddl $_GLOBAL_OFFSET_TABLE_+[.-.L__wine_call_from_16_%s.getgot1], %%ecx\n", name ); + fprintf( outfile, "\t.byte 0x2e\n\tmovl %s-.Lcall_from_16_%s.getpc(%%ecx),%%edx\n", + asm_name("CallTo16_DataSelector"), name ); } - - if (UsePIC) - { - 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 %s,%%edx\n", asm_name("CallTo16_DataSelector") );
@@ -162,31 +156,29 @@ fprintf( outfile, "%s\tmovw %%dx, %%es\n", data16_prefix() );
if ( UsePIC ) - { - fprintf( outfile, "\tmovl %s(%%ecx), %%edx\n", asm_name("CallTo16_TebSelector@GOT") ); - fprintf( outfile, "\tmovw (%%edx), %%fs\n" ); - } + fprintf( outfile, "\tmovw %s-.Lcall_from_16_%s.getpc(%%ecx), %%fs\n", + asm_name("CallTo16_TebSelector"), name ); else 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 %s(%%ecx), %%ecx\n", asm_name("wine_ldt_copy@GOT") ); - else - 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" ); fprintf( outfile, "\tandl $0xfff8, %%edx\n" ); fprintf( outfile, "\tshrl $1, %%edx\n" ); - fprintf( outfile, "\tmovl (%%ecx,%%edx), %%edx\n" ); + if (UsePIC) + { + fprintf( outfile, "\taddl wine_ldt_copy_ptr-.Lcall_from_16_%s.getpc(%%ecx),%%edx\n", name ); + fprintf( outfile, "\tmovl (%%edx), %%edx\n" ); + } + else + fprintf( outfile, "\tmovl %s(%%edx), %%edx\n", asm_name("wine_ldt_copy") ); fprintf( outfile, "\tmovzwl %%sp, %%ebp\n" ); - fprintf( outfile, "\tleal (%%ebp,%%edx), %%edx\n" ); + fprintf( outfile, "\tleal %d(%%ebp,%%edx), %%edx\n", reg_func ? 0 : -4 );
/* Get saved flags into %ecx */ - fprintf( outfile, "\tpopl %%ecx\n" ); + if (reg_func) fprintf( outfile, "\tpopl %%ecx\n" );
/* Get the 32-bit stack pointer from the TEB and complete STACK16FRAME */ fprintf( outfile, "\t.byte 0x64\n\tmovl (%d), %%ebp\n", STACKOFFSET ); @@ -292,83 +284,16 @@ fprintf( outfile, "\tpushl %%esp\n" ); }
- - /* Print debug info before call */ - if ( debugging ) - { - if ( UsePIC ) - { - fprintf( outfile, "\tpushl %%ebx\n" ); - - /* Get Global Offset Table into %ebx (for PLT call) */ - fprintf( outfile, "\tcall .L__wine_call_from_16_%s.getgot2\n", name ); - fprintf( outfile, ".L__wine_call_from_16_%s.getgot2:\n", name ); - fprintf( outfile, "\tpopl %%ebx\n" ); - fprintf( outfile, "\taddl $_GLOBAL_OFFSET_TABLE_+[.-.L__wine_call_from_16_%s.getgot2], %%ebx\n", name ); - } - - fprintf( outfile, "\tpushl %%edx\n" ); - if ( reg_func ) - fprintf( outfile, "\tleal -%d(%%ebp), %%eax\n\tpushl %%eax\n", - sizeof(CONTEXT) + STRUCTOFFSET(STACK32FRAME, ebp) ); - else - fprintf( outfile, "\tpushl $0\n" ); - - if ( UsePIC ) - fprintf( outfile, "\tcall %s\n ", asm_name("RELAY_DebugCallFrom16@PLT")); - else - fprintf( outfile, "\tcall %s\n ", asm_name("RELAY_DebugCallFrom16")); - - fprintf( outfile, "\tpopl %%edx\n" ); - fprintf( outfile, "\tpopl %%edx\n" ); - - if ( UsePIC ) - fprintf( outfile, "\tpopl %%ebx\n" ); - } - /* Call relay routine (which will call the API entry point) */ fprintf( outfile, "\tleal %d(%%edx), %%eax\n", sizeof(STACK16FRAME) ); fprintf( outfile, "\tpushl %%eax\n" ); fprintf( outfile, "\tpushl %d(%%edx)\n", STACK16OFFSET(entry_point) ); fprintf( outfile, "\tcall *%d(%%edx)\n", STACK16OFFSET(relay) );
- /* Print debug info after call */ - if ( debugging ) - { - if ( UsePIC ) - { - fprintf( outfile, "\tpushl %%ebx\n" ); - - /* Get Global Offset Table into %ebx (for PLT call) */ - fprintf( outfile, "\tcall .L__wine_call_from_16_%s.getgot3\n", name ); - fprintf( outfile, ".L__wine_call_from_16_%s.getgot3:\n", name ); - fprintf( outfile, "\tpopl %%ebx\n" ); - fprintf( outfile, "\taddl $_GLOBAL_OFFSET_TABLE_+[.-.L__wine_call_from_16_%s.getgot3], %%ebx\n", name ); - } - - fprintf( outfile, "\tpushl %%eax\n" ); - if ( reg_func ) - fprintf( outfile, "\tleal -%d(%%ebp), %%eax\n\tpushl %%eax\n", - sizeof(CONTEXT) + STRUCTOFFSET(STACK32FRAME, ebp) ); - else - fprintf( outfile, "\tpushl $0\n" ); - - if ( UsePIC ) - fprintf( outfile, "\tcall %s\n ", asm_name("RELAY_DebugCallFrom16Ret@PLT")); - else - fprintf( outfile, "\tcall %s\n ", asm_name("RELAY_DebugCallFrom16Ret")); - - fprintf( outfile, "\tpopl %%eax\n" ); - fprintf( outfile, "\tpopl %%eax\n" ); - - if ( UsePIC ) - fprintf( outfile, "\tpopl %%ebx\n" ); - } - - if ( reg_func ) { - fprintf( outfile, "\tmovl %%esp, %%ebx\n" ); + fprintf( outfile, "\tleal -%d(%%ebp), %%ebx\n", + sizeof(CONTEXT) + STRUCTOFFSET(STACK32FRAME, ebp) );
/* Switch stack back */ fprintf( outfile, "\t.byte 0x64\n\tmovw (%d), %%ss\n", STACKOFFSET+2 ); @@ -610,7 +535,7 @@ */ static void BuildRet16Func( FILE *outfile ) { - function_header( outfile, "CallTo16_Ret" ); + function_header( outfile, "__wine_call_to_16_ret" );
/* Save %esp into %esi */ fprintf( outfile, "\tmovl %%esp,%%esi\n" ); @@ -618,12 +543,12 @@ /* Restore 32-bit segment registers */
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,%%edi\n", asm_name("__wine_call16_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 %s", asm_name("CallTo16_TebSelector") ); - fprintf( outfile, "-%s,%%fs\n", asm_name("Call16_Ret_Start") ); + fprintf( outfile, "-%s,%%fs\n", asm_name("__wine_call16_start") );
fprintf( outfile, "\t.byte 0x64\n\tmov (%d),%%gs\n", STRUCTOFFSET(TEB,gs_sel) );
@@ -635,17 +560,7 @@ /* Return to caller */
fprintf( outfile, "\tlret\n" ); - - /* Function footer */ - function_footer( outfile, "CallTo16_Ret" ); - - /* Declare the return address and data selector variables */ - - fprintf( outfile, "\n\t.align %d\n", get_alignment(4) ); - 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") ); + function_footer( outfile, "__wine_call_to_16_ret" ); }
@@ -741,15 +656,8 @@ */ static void BuildCallTo32CBClient( FILE *outfile, BOOL isEx ) { - const char *name = isEx? "CALL32_CBClientEx" : "CALL32_CBClient"; - int size = isEx? 24 : 12; + function_header( outfile, isEx ? "CALL32_CBClientEx" : "CALL32_CBClient" );
- /* Function header */ - - fprintf( outfile, "\n\t.align %d\n", get_alignment(4) ); - fprintf( outfile, "\t.globl %s\n", asm_name(name) ); - fprintf( outfile, "%s:\n", asm_name(name) ); - /* Entry code */
fprintf( outfile, "\tpushl %%ebp\n" ); @@ -758,106 +666,21 @@ 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 pointer to temporary area and save the 32-bit stack pointer */
- /* Get the 16-bit stack */ + fprintf( outfile, "\tmovl 16(%%ebp), %%ebx\n" ); + fprintf( outfile, "\tleal -8(%%esp), %%eax\n" );
- fprintf( outfile, "\t.byte 0x64\n\tmovl (%d),%%ebx\n", STACKOFFSET); - - /* Convert it to a flat address */ - - fprintf( outfile, "\tshldl $16,%%ebx,%%eax\n" ); - fprintf( outfile, "\tandl $0xfff8,%%eax\n" ); - fprintf( outfile, "\tshrl $1,%%eax\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" ); - - /* Allocate temporary area (simulate STACK16_PUSH) */ - - fprintf( outfile, "\tpushf\n" ); - fprintf( outfile, "\tcld\n" ); - fprintf( outfile, "\tleal -%d(%%esi), %%edi\n", size ); - fprintf( outfile, "\tmovl $%d, %%ecx\n", sizeof(STACK16FRAME) ); - fprintf( outfile, "\trep\n\tmovsb\n" ); - fprintf( outfile, "\tpopf\n" ); - - fprintf( outfile, "\t.byte 0x64\n\tsubw $%d,(%d)\n", size, STACKOFFSET ); - - fprintf( outfile, "\tpushl %%edi\n" ); /* remember address */ - - /* Set up temporary area */ - if ( !isEx ) - { - fprintf( outfile, "\tleal 4(%%edi), %%edi\n" ); - - fprintf( outfile, "\tleal -8(%%esp), %%eax\n" ); - fprintf( outfile, "\tmovl %%eax, -8(%%edi)\n" ); /* 32-bit sp */ - - fprintf( outfile, "\tmovw %%ss, %%ax\n" ); - fprintf( outfile, "\tandl $0x0000ffff, %%eax\n" ); - fprintf( outfile, "\tmovl %%eax, -4(%%edi)\n" ); /* 32-bit ss */ - - fprintf( outfile, "\taddl $%d, %%ebx\n", sizeof(STACK16FRAME)-size+4 + 4 ); - fprintf( outfile, "\tmovl %%ebx, 0(%%edi)\n" ); /* 16-bit ss:sp */ - - 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 */ - } + fprintf( outfile, "\tmovl %%eax, -8(%%ebx)\n" ); else - { - fprintf( outfile, "\taddl $%d, %%ebx\n", sizeof(STACK16FRAME)-size+4 ); - fprintf( outfile, "\tmovl %%ebx, 0(%%edi)\n" ); + fprintf( outfile, "\tmovl %%eax, 12(%%ebx)\n" );
- fprintf( outfile, "\tmovw %%ds, %%ax\n" ); - fprintf( outfile, "\tmovw %%ax, 4(%%edi)\n" ); - - fprintf( outfile, "\taddl $20, %%ebx\n" ); - fprintf( outfile, "\tmovw %%bx, 10(%%edi)\n" ); - - fprintf( outfile, "\tleal -8(%%esp), %%eax\n" ); - fprintf( outfile, "\tmovl %%eax, 12(%%edi)\n" ); - - fprintf( outfile, "\tmovw %%ss, %%ax\n" ); - fprintf( outfile, "\tandl $0x0000ffff, %%eax\n" ); - fprintf( outfile, "\tmovl %%eax, 16(%%edi)\n" ); - - 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" ); - } - /* Set up registers and call CBClient relay stub (simulating a far call) */
- fprintf( outfile, "\tmovl 16(%%ebp), %%esi\n" ); + fprintf( outfile, "\tmovl 20(%%ebp), %%esi\n" ); fprintf( outfile, "\tmovl (%%esi), %%esi\n" );
- fprintf( outfile, "\tmovl %%edi, %%ebx\n" ); fprintf( outfile, "\tmovl 8(%%ebp), %%eax\n" ); fprintf( outfile, "\tmovl 12(%%ebp), %%ebp\n" );
@@ -869,24 +692,10 @@ fprintf( outfile, "\tmovl 32(%%esp), %%edi\n" ); fprintf( outfile, "\tmovl %%esi, (%%edi)\n" );
- /* Cleanup temporary area (simulate STACK16_POP) */ - - fprintf( outfile, "\tpop %%esi\n" ); - - fprintf( outfile, "\tpushf\n" ); - fprintf( outfile, "\tstd\n" ); - fprintf( outfile, "\tdec %%esi\n" ); - fprintf( outfile, "\tleal %d(%%esi), %%edi\n", size ); - fprintf( outfile, "\tmovl $%d, %%ecx\n", sizeof(STACK16FRAME) ); - fprintf( outfile, "\trep\n\tmovsb\n" ); - fprintf( outfile, "\tpopf\n" ); - - fprintf( outfile, "\t.byte 0x64\n\taddw $%d,(%d)\n", size, STACKOFFSET ); - /* Return argument size to caller */ if ( isEx ) { - fprintf( outfile, "\tmovl 32(%%esp), %%ebx\n" ); + fprintf( outfile, "\tmovl 36(%%esp), %%ebx\n" ); fprintf( outfile, "\tmovl %%ebp, (%%ebx)\n" ); }
@@ -897,18 +706,11 @@ fprintf( outfile, "\tpopl %%edi\n" ); fprintf( outfile, "\tpopl %%ebp\n" ); fprintf( outfile, "\tret\n" ); - function_footer( outfile, name ); -} + function_footer( outfile, isEx ? "CALL32_CBClientEx" : "CALL32_CBClient" );
-static void BuildCallTo32CBClientRet( FILE *outfile, BOOL isEx ) -{ - const char *name = isEx? "CALL32_CBClientEx_Ret" : "CALL32_CBClient_Ret"; - /* '16-bit' return stub */
- fprintf( outfile, "\n\t.globl %s\n", asm_name(name) ); - fprintf( outfile, "%s:\n", asm_name(name) ); - + function_header( outfile, isEx ? "CALL32_CBClientEx_Ret" : "CALL32_CBClient_Ret" ); if ( !isEx ) { fprintf( outfile, "\tmovzwl %%sp, %%ebx\n" ); @@ -922,12 +724,7 @@ fprintf( outfile, "\tlssl %%ss:-12(%%ebx), %%esp\n" ); } fprintf( outfile, "\tlret\n" ); - function_footer( outfile, name ); - - /* Declare the return address variable */ - - fprintf( outfile, "\n\t.globl %sAddr\n", asm_name(name) ); - fprintf( outfile, "%sAddr:\t.long 0\n", asm_name(name) ); + function_footer( outfile, isEx ? "CALL32_CBClientEx_Ret" : "CALL32_CBClient_Ret" ); }
@@ -1102,13 +899,13 @@
/* Start cleanup. Restore fs register. */
- fprintf( outfile, ".globl %s\n", asm_name("DPMI_PendingEventCheck_Cleanup") ); + fprintf( outfile, "\t.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 %s\n", asm_name("DPMI_PendingEventCheck_Return") ); + fprintf( outfile, "\t.globl %s\n", asm_name("DPMI_PendingEventCheck_Return") ); fprintf( outfile, "%s:\n", asm_name("DPMI_PendingEventCheck_Return") ); fprintf( outfile, "\tiret\n" );
@@ -1136,9 +933,8 @@
fprintf( outfile, "%s:\n\n", asm_name("__wine_spec_thunk_text_16") );
- 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" ); + fprintf( outfile, "\t.globl %s\n", asm_name("__wine_call16_start") ); + fprintf( outfile, "%s:\n", asm_name("__wine_call16_start") );
/* Standard CallFrom16 routine (WORD return) */ BuildCallFrom16Core( outfile, FALSE, FALSE, TRUE ); @@ -1158,38 +954,29 @@ /* Register CallTo16 routine */ BuildCallTo16Core( outfile, 1 );
+ /* Standard CallTo16 return stub */ + BuildRet16Func( outfile ); + /* CBClientThunkSL routine */ BuildCallTo32CBClient( outfile, FALSE );
/* CBClientThunkSLEx routine */ BuildCallTo32CBClient( outfile, TRUE );
- 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, "%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 ); - - /* CBClientThunkSL return stub */ - BuildCallTo32CBClientRet( outfile, FALSE ); - - /* CBClientThunkSLEx return stub */ - BuildCallTo32CBClientRet( outfile, TRUE ); - /* Pending DPMI events check stub */ BuildPendingEventCheck( outfile );
- /* End of Call16_Ret segment */ - 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" ); + fprintf( outfile, "\t.globl %s\n", asm_name("__wine_call16_end") ); + fprintf( outfile, "%s:\n", asm_name("__wine_call16_end") ); + function_footer( outfile, "__wine_spec_thunk_text_16" ); + + /* Declare the return address and data selector variables */ + fprintf( outfile, "\n\t.data\n\t.align %d\n", get_alignment(4) ); + 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") ); + if (UsePIC) fprintf( outfile, "wine_ldt_copy_ptr:\t.long %s\n", asm_name("wine_ldt_copy") ); }
/******************************************************************* _____
Modified: trunk/reactos/tools/winebuild/spec16.c --- trunk/reactos/tools/winebuild/spec16.c 2005-08-10 21:09:05 UTC (rev 17270) +++ trunk/reactos/tools/winebuild/spec16.c 2005-08-10 22:15:12 UTC (rev 17271) @@ -253,7 +253,7 @@
fprintf( outfile, "void" ); fprintf( outfile, " );\n" );
- fprintf( outfile, "static %s __stdcall __wine_%s_CallFrom16_%s( proc_%s_t proc, unsigned char *args%s )\n", + fprintf( outfile, "static %s __wine_%s_CallFrom16_%s( proc_%s_t proc, unsigned char *args%s )\n", ret_type, make_c_identifier(prefix), profile, profile, reg_func? ", void *context" : "" );
@@ -397,7 +397,7 @@ ORDDEF **type, **typelist; int i, nFuncs, nTypes; unsigned char *resdir_buffer, *resdata_buffer, *et_buffer, *data_buffer; - unsigned char string[256]; + char string[256]; unsigned int ne_offset, segtable_offset, impnames_offset; unsigned int entrypoint_size, callfrom_size; unsigned int code_size, code_offset; @@ -780,6 +780,7 @@ } arg_types[j / 10] |= type << (3 * (j % 10)); } + if (typelist[i]->type == TYPE_VARARGS) arg_types[j / 10] |= ARG_VARARG << (3 * (j % 10)); if (typelist[i]->flags & FLAG_REGISTER) arg_types[0] |= ARG_REGISTER; if (typelist[i]->flags & FLAG_RET16) arg_types[0] |= ARG_RET16;
_____
Modified: trunk/reactos/tools/winebuild/spec32.c --- trunk/reactos/tools/winebuild/spec32.c 2005-08-10 21:09:05 UTC (rev 17270) +++ trunk/reactos/tools/winebuild/spec32.c 2005-08-10 22:15:12 UTC (rev 17271) @@ -267,12 +267,12 @@
fprintf( outfile, " "__wine_spec_exp_ordinals:\n"\n" ); for (i = 0; i < spec->nb_names; i++) { - fprintf( outfile, " "\t" __ASM_SHORT " %d\n"\n", - spec->names[i]->ordinal - spec->base ); + fprintf( outfile, " "\t%s %d\n"\n", + get_asm_short_keyword(), spec->names[i]->ordinal - spec->base ); } if (spec->nb_names % 2) { - fprintf( outfile, " "\t" __ASM_SHORT " 0\n"\n" ); + fprintf( outfile, " "\t%s 0\n"\n", get_asm_short_keyword() ); } }
@@ -285,14 +285,15 @@ { ORDDEF *odp = spec->ordinals[i]; if (odp && (odp->flags & FLAG_FORWARD)) - fprintf( outfile, " "\t" __ASM_STRING " \"%s\"\n"\n", odp->link_name ); + fprintf( outfile, " "\t%s \"%s\"\n"\n", get_asm_string_keyword(), odp->link_name ); } fprintf( outfile, " "\t.align %d\n"\n", get_alignment(4) ); }
/* output relays */
- if (debugging) + /* we only support relay debugging on i386 */ + if (target_cpu == CPU_x86) { for (i = spec->base; i <= spec->limit; i++) { @@ -325,7 +326,7 @@ case TYPE_CDECL: 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%s %d\n"\n", get_asm_short_keyword(), args ); fprintf( outfile, " "\t.long %s,0x%08x\n"\n", asm_name(odp->link_name), mask ); break; default: _____
Modified: trunk/reactos/tools/winebuild/utils.c --- trunk/reactos/tools/winebuild/utils.c 2005-08-10 21:09:05 UTC (rev 17270) +++ trunk/reactos/tools/winebuild/utils.c 2005-08-10 22:15:12 UTC (rev 17271) @@ -387,26 +387,74 @@
const char *asm_name( const char *sym ) { static char buffer[256]; - sprintf( buffer, __ASM_NAME("%s"), sym ); - return buffer; + + switch (target_platform) + { + case PLATFORM_APPLE: + case PLATFORM_WINDOWS: + buffer[0] = '_'; + strcpy( buffer + 1, sym ); + return buffer; + default: + return sym; + } }
/* 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 ); + + switch (target_platform) + { + case PLATFORM_APPLE: + return ""; + case PLATFORM_WINDOWS: + sprintf( buffer, ".def _%s; .scl 2; .type 32; .endef", func ); + break; + case PLATFORM_SVR4: + sprintf( buffer, ".type %s,2", func ); + break; + default: + sprintf( buffer, ".type %s,@function", func ); + break; + } 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 - return ""; -#endif + + switch (target_platform) + { + case PLATFORM_APPLE: + case PLATFORM_WINDOWS: + return ""; + default: + sprintf( buffer, ".size %s, .-%s", func, func ); + return buffer; + } } + +const char *get_asm_string_keyword(void) +{ + switch (target_platform) + { + case PLATFORM_APPLE: + case PLATFORM_SVR4: + return ".asciz"; + default: + return ".string"; + } +} + +const char *get_asm_short_keyword(void) +{ + switch (target_platform) + { + case PLATFORM_SVR4: return ".half"; + default: return ".short"; + } +} _____
Modified: trunk/reactos/tools/winebuild/winebuild.man.in --- trunk/reactos/tools/winebuild/winebuild.man.in 2005-08-10 21:09:05 UTC (rev 17270) +++ trunk/reactos/tools/winebuild/winebuild.man.in 2005-08-10 22:15:12 UTC (rev 17271) @@ -191,6 +191,11 @@
Optionally a major and minor subsystem version can also be specified; the default subsystem version is 4.0. .TP +.BI --target= cpu-manufacturer[-kernel]-os +Specify the target CPU and platform on which the generated code will +be built. The target specification is in the standard autoconf format +as returned by config.sub. +.TP .B --version Display the program version and exit. .TP