From d58953b3002a749eeb584531319afb02011cd16a Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Sat, 18 May 2019 09:21:49 +0200 Subject: [PATCH] winebuild: Add 16-bit support for PE builds. Signed-off-by: Alexandre Julliard --- tools/winebuild/spec16.c | 17 +++++++++++------ tools/winebuild/utils.c | 39 ++++++++++++++++++++++++++++----------- 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/tools/winebuild/spec16.c b/tools/winebuild/spec16.c index 9dce748dd49..b21f472772b 100644 --- a/tools/winebuild/spec16.c +++ b/tools/winebuild/spec16.c @@ -55,6 +55,8 @@ static const char * const nop_sequence[4] = ".byte 0x8d,0x74,0x26,0x00,0x8d,0x74,0x26,0x00" /* lea 0x00(%esi),%esi; lea 0x00(%esi),%esi */ }; +static const char fakedll_signature[] = "Wine placeholder DLL"; + static inline int is_function( const ORDDEF *odp ) { if (odp->flags & FLAG_EXPORT32) return 0; @@ -565,7 +567,7 @@ static void output_module16( DLLSPEC *spec ) output( "\n/* module data */\n\n" ); output( "\t.data\n" ); - output( "\t.align %d\n", get_alignment(4) ); + output( "\t.align %d\n", get_alignment(16) ); output( ".L__wine_spec_dos_header:\n" ); output( "\t.short 0x5a4d\n" ); /* e_magic */ output( "\t.short 0\n" ); /* e_cblp */ @@ -584,9 +586,12 @@ static void output_module16( DLLSPEC *spec ) output( "\t.short 0,0,0,0\n" ); /* e_res */ output( "\t.short 0\n" ); /* e_oemid */ output( "\t.short 0\n" ); /* e_oeminfo */ - output( ".Lwine_ldt_copy_ptr:\t.long 0,0,0,0,0\n" ); /* e_res2, used for ldt_copy */ + output( ".Lwine_ldt_copy_ptr:\n" ); /* e_res2, used for private data */ + output( "\t.long .L__wine_spec_ne_header_end-.L__wine_spec_dos_header,0,0,0,0\n" ); output( "\t.long .L__wine_spec_ne_header-.L__wine_spec_dos_header\n" );/* e_lfanew */ + output( "\t%s \"%s\"\n", get_asm_string_keyword(), fakedll_signature ); + output( "\t.align %d\n", get_alignment(16) ); output( ".L__wine_spec_ne_header:\n" ); output( "\t.short 0x454e\n" ); /* ne_magic */ output( "\t.byte 0\n" ); /* ne_ver */ @@ -755,7 +760,7 @@ static void output_module16( DLLSPEC *spec ) output( ".L__wine_%s_%u:\n", spec->c_name, i ); output( "\tpushw %%bp\n" ); output( "\tpushl $%s\n", - asm_name( odp->type == TYPE_STUB ? get_stub_name( odp, spec ) : odp->link_name )); + asm_name( odp->type == TYPE_STUB ? get_stub_name( odp, spec ) : get_link_name( odp ))); output( "\tcallw .L__wine_spec_callfrom16_%s\n", get_callfrom16_name( odp ) ); } output( ".L__wine_spec_code_segment_end:\n" ); @@ -784,6 +789,7 @@ static void output_module16( DLLSPEC *spec ) output_res16_data( spec ); } + output( ".L__wine_spec_ne_header_end:\n" ); output( "\t.byte 0\n" ); /* make sure the last symbol points to something */ /* relay functions */ @@ -815,11 +821,11 @@ void output_spec16_file( DLLSPEC *spec16 ) needs_get_pc_thunk = 0; open_output_file(); output_standard_file_header(); - output_module( spec32 ); + if (target_platform != PLATFORM_WINDOWS) output_module( spec32 ); output_module16( spec16 ); output_stubs( spec16 ); output_exports( spec32 ); - output_imports( spec16 ); + if (target_platform != PLATFORM_WINDOWS) output_imports( spec16 ); if (is_undefined( "__wine_call_from_16" )) output_asm_relays16(); if (needs_get_pc_thunk) output_get_pc_thunk(); if (spec16->main_module) @@ -842,7 +848,6 @@ void output_fake_module16( DLLSPEC *spec ) { static const unsigned char code_segment[] = { 0x90, 0xc3 }; static const unsigned char data_segment[16] = { 0 }; - static const char fakedll_signature[] = "Wine placeholder DLL"; const unsigned int cseg = 2; const unsigned int lfanew = (0x40 + sizeof(fakedll_signature) + 15) & ~15; const unsigned int segtab = lfanew + 0x40; diff --git a/tools/winebuild/utils.c b/tools/winebuild/utils.c index 315643cf7dd..dbfe7a4ba74 100644 --- a/tools/winebuild/utils.c +++ b/tools/winebuild/utils.c @@ -900,20 +900,37 @@ const char *get_link_name( const ORDDEF *odp ) char *ret; if (target_cpu != CPU_x86) return odp->link_name; - if (odp->type != TYPE_STDCALL) return odp->link_name; - if (target_platform == PLATFORM_WINDOWS) + switch (odp->type) { - if (odp->flags & FLAG_THISCALL) return odp->link_name; - if (odp->flags & FLAG_FASTCALL) ret = strmake( "@%s@%u", odp->link_name, get_args_size( odp )); - else if (!kill_at) ret = strmake( "%s@%u", odp->link_name, get_args_size( odp )); - else return odp->link_name; - } - else - { - if (odp->flags & FLAG_THISCALL) ret = strmake( "__thiscall_%s", odp->link_name ); - else if (odp->flags & FLAG_FASTCALL) ret = strmake( "__fastcall_%s", odp->link_name ); + case TYPE_STDCALL: + if (target_platform == PLATFORM_WINDOWS) + { + if (odp->flags & FLAG_THISCALL) return odp->link_name; + if (odp->flags & FLAG_FASTCALL) ret = strmake( "@%s@%u", odp->link_name, get_args_size( odp )); + else if (!kill_at) ret = strmake( "%s@%u", odp->link_name, get_args_size( odp )); + else return odp->link_name; + } + else + { + if (odp->flags & FLAG_THISCALL) ret = strmake( "__thiscall_%s", odp->link_name ); + else if (odp->flags & FLAG_FASTCALL) ret = strmake( "__fastcall_%s", odp->link_name ); + else return odp->link_name; + } + break; + + case TYPE_PASCAL: + if (target_platform == PLATFORM_WINDOWS && !kill_at) + { + int args = get_args_size( odp ); + if (odp->flags & FLAG_REGISTER) args += get_ptr_size(); /* context argument */ + ret = strmake( "%s@%u", odp->link_name, args ); + } else return odp->link_name; + break; + + default: + return odp->link_name; } free( buffer );