From 0c214a7091af8efe39ffdaea7fe9e2de4d8006ba Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 3 Mar 2008 15:19:53 +0100 Subject: [PATCH] winebuild: Add support for 16-bit exe modules. --- tools/winebuild/main.c | 15 ++++----------- tools/winebuild/spec16.c | 39 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/tools/winebuild/main.c b/tools/winebuild/main.c index 3238b2a5013..82ee59dc9bf 100644 --- a/tools/winebuild/main.c +++ b/tools/winebuild/main.c @@ -596,10 +596,12 @@ int main(int argc, char **argv) case MODE_DLL: if (spec->subsystem != IMAGE_SUBSYSTEM_NATIVE) spec->characteristics |= IMAGE_FILE_DLL; + if (!spec_file_name) fatal_error( "missing .spec file\n" ); + /* fall through */ + case MODE_EXE: load_resources( argv, spec ); load_import_libs( argv ); - if (!spec_file_name) fatal_error( "missing .spec file\n" ); - if (!parse_input_file( spec )) break; + if (spec_file_name && !parse_input_file( spec )) break; switch (spec->type) { case SPEC_WIN16: @@ -614,15 +616,6 @@ int main(int argc, char **argv) default: assert(0); } break; - case MODE_EXE: - if (spec->type == SPEC_WIN16) fatal_error( "Cannot build 16-bit exe files\n" ); - if (!spec->file_name) fatal_error( "executable must be named via the -F option\n" ); - load_resources( argv, spec ); - load_import_libs( argv ); - if (spec_file_name && !parse_input_file( spec )) break; - read_undef_symbols( spec, argv ); - BuildSpec32File( spec ); - break; case MODE_DEF: if (argv[0]) fatal_error( "file argument '%s' not allowed in this mode\n", argv[0] ); if (spec->type == SPEC_WIN16) fatal_error( "Cannot yet build .def file for 16-bit dlls\n" ); diff --git a/tools/winebuild/spec16.c b/tools/winebuild/spec16.c index f5be830f9d5..8fda97806a9 100644 --- a/tools/winebuild/spec16.c +++ b/tools/winebuild/spec16.c @@ -435,6 +435,7 @@ static int sort_func_list( ORDDEF **list, int count, { int i, j; + if (!count) return 0; qsort( list, count, sizeof(*list), compare ); for (i = j = 0; i < count; i++) @@ -528,6 +529,7 @@ static void output_init_code( const DLLSPEC *spec, const char *header_name ) void BuildSpec16File( DLLSPEC *spec ) { ORDDEF **typelist; + ORDDEF *entry_point = NULL; int i, j, nb_funcs; char header_name[256]; @@ -535,6 +537,12 @@ void BuildSpec16File( DLLSPEC *spec ) output_standard_file_header(); + if (!spec->file_name) + { + char *p; + spec->file_name = xstrdup( output_file_name ); + if ((p = strrchr( spec->file_name, '.' ))) *p = 0; + } if (!spec->dll_name) /* set default name from file name */ { char *p; @@ -542,6 +550,28 @@ void BuildSpec16File( DLLSPEC *spec ) if ((p = strrchr( spec->dll_name, '.' ))) *p = 0; } + /* store the main entry point as ordinal 0 */ + + if (!spec->ordinals) + { + spec->ordinals = xmalloc( sizeof(spec->ordinals[0]) ); + spec->ordinals[0] = NULL; + } + if (spec->init_func && !(spec->characteristics & IMAGE_FILE_DLL)) + { + entry_point = xmalloc( sizeof(*entry_point) ); + entry_point->type = TYPE_PASCAL; + entry_point->ordinal = 0; + entry_point->lineno = 0; + entry_point->flags = FLAG_REGISTER; + entry_point->name = NULL; + entry_point->link_name = xstrdup( spec->init_func ); + entry_point->export_name = NULL; + entry_point->u.func.arg_types[0] = 0; + assert( !spec->ordinals[0] ); + spec->ordinals[0] = entry_point; + } + /* Build sorted list of all argument types, without duplicates */ typelist = xmalloc( (spec->limit + 1) * sizeof(*typelist) ); @@ -594,12 +624,15 @@ void BuildSpec16File( DLLSPEC *spec ) get_asm_short_keyword() ); output( "\t.long 0\n" ); /* ne_crc */ output( "\t%s 0x%04x\n", get_asm_short_keyword(), /* ne_flags */ - NE_FFLAGS_SINGLEDATA | NE_FFLAGS_LIBMODULE ); + NE_FFLAGS_SINGLEDATA | + ((spec->characteristics & IMAGE_FILE_DLL) ? NE_FFLAGS_LIBMODULE : 0) ); output( "\t%s 2\n", get_asm_short_keyword() ); /* ne_autodata */ output( "\t%s %u\n", get_asm_short_keyword(), spec->heap_size ); /* ne_heap */ output( "\t%s 0\n", get_asm_short_keyword() ); /* ne_stack */ - output( "\t.long 0\n" ); /* ne_csip */ - output( "\t.long 0\n" ); /* ne_sssp */ + if (!entry_point) output( "\t.long 0\n" ); /* ne_csip */ + else output( "\t%s .L__wine_%s_0-.L__wine_spec_code_segment,1\n", + get_asm_short_keyword(), make_c_identifier(spec->dll_name) ); + output( "\t%s 0,2\n", get_asm_short_keyword() ); /* ne_sssp */ output( "\t%s 2\n", get_asm_short_keyword() ); /* ne_cseg */ output( "\t%s 0\n", get_asm_short_keyword() ); /* ne_cmod */ output( "\t%s 0\n", get_asm_short_keyword() ); /* ne_cbnrestab */