winebuild: Add 16-bit support for PE builds.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
1f6681f474
commit
d58953b300
|
@ -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 */
|
".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 )
|
static inline int is_function( const ORDDEF *odp )
|
||||||
{
|
{
|
||||||
if (odp->flags & FLAG_EXPORT32) return 0;
|
if (odp->flags & FLAG_EXPORT32) return 0;
|
||||||
|
@ -565,7 +567,7 @@ static void output_module16( DLLSPEC *spec )
|
||||||
|
|
||||||
output( "\n/* module data */\n\n" );
|
output( "\n/* module data */\n\n" );
|
||||||
output( "\t.data\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( ".L__wine_spec_dos_header:\n" );
|
||||||
output( "\t.short 0x5a4d\n" ); /* e_magic */
|
output( "\t.short 0x5a4d\n" ); /* e_magic */
|
||||||
output( "\t.short 0\n" ); /* e_cblp */
|
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,0,0,0\n" ); /* e_res */
|
||||||
output( "\t.short 0\n" ); /* e_oemid */
|
output( "\t.short 0\n" ); /* e_oemid */
|
||||||
output( "\t.short 0\n" ); /* e_oeminfo */
|
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.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( ".L__wine_spec_ne_header:\n" );
|
||||||
output( "\t.short 0x454e\n" ); /* ne_magic */
|
output( "\t.short 0x454e\n" ); /* ne_magic */
|
||||||
output( "\t.byte 0\n" ); /* ne_ver */
|
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( ".L__wine_%s_%u:\n", spec->c_name, i );
|
||||||
output( "\tpushw %%bp\n" );
|
output( "\tpushw %%bp\n" );
|
||||||
output( "\tpushl $%s\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( "\tcallw .L__wine_spec_callfrom16_%s\n", get_callfrom16_name( odp ) );
|
||||||
}
|
}
|
||||||
output( ".L__wine_spec_code_segment_end:\n" );
|
output( ".L__wine_spec_code_segment_end:\n" );
|
||||||
|
@ -784,6 +789,7 @@ static void output_module16( DLLSPEC *spec )
|
||||||
output_res16_data( 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 */
|
output( "\t.byte 0\n" ); /* make sure the last symbol points to something */
|
||||||
|
|
||||||
/* relay functions */
|
/* relay functions */
|
||||||
|
@ -815,11 +821,11 @@ void output_spec16_file( DLLSPEC *spec16 )
|
||||||
needs_get_pc_thunk = 0;
|
needs_get_pc_thunk = 0;
|
||||||
open_output_file();
|
open_output_file();
|
||||||
output_standard_file_header();
|
output_standard_file_header();
|
||||||
output_module( spec32 );
|
if (target_platform != PLATFORM_WINDOWS) output_module( spec32 );
|
||||||
output_module16( spec16 );
|
output_module16( spec16 );
|
||||||
output_stubs( spec16 );
|
output_stubs( spec16 );
|
||||||
output_exports( spec32 );
|
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 (is_undefined( "__wine_call_from_16" )) output_asm_relays16();
|
||||||
if (needs_get_pc_thunk) output_get_pc_thunk();
|
if (needs_get_pc_thunk) output_get_pc_thunk();
|
||||||
if (spec16->main_module)
|
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 code_segment[] = { 0x90, 0xc3 };
|
||||||
static const unsigned char data_segment[16] = { 0 };
|
static const unsigned char data_segment[16] = { 0 };
|
||||||
static const char fakedll_signature[] = "Wine placeholder DLL";
|
|
||||||
const unsigned int cseg = 2;
|
const unsigned int cseg = 2;
|
||||||
const unsigned int lfanew = (0x40 + sizeof(fakedll_signature) + 15) & ~15;
|
const unsigned int lfanew = (0x40 + sizeof(fakedll_signature) + 15) & ~15;
|
||||||
const unsigned int segtab = lfanew + 0x40;
|
const unsigned int segtab = lfanew + 0x40;
|
||||||
|
|
|
@ -900,8 +900,10 @@ const char *get_link_name( const ORDDEF *odp )
|
||||||
char *ret;
|
char *ret;
|
||||||
|
|
||||||
if (target_cpu != CPU_x86) return odp->link_name;
|
if (target_cpu != CPU_x86) return odp->link_name;
|
||||||
if (odp->type != TYPE_STDCALL) return odp->link_name;
|
|
||||||
|
|
||||||
|
switch (odp->type)
|
||||||
|
{
|
||||||
|
case TYPE_STDCALL:
|
||||||
if (target_platform == PLATFORM_WINDOWS)
|
if (target_platform == PLATFORM_WINDOWS)
|
||||||
{
|
{
|
||||||
if (odp->flags & FLAG_THISCALL) return odp->link_name;
|
if (odp->flags & FLAG_THISCALL) return odp->link_name;
|
||||||
|
@ -915,6 +917,21 @@ const char *get_link_name( const ORDDEF *odp )
|
||||||
else if (odp->flags & FLAG_FASTCALL) ret = strmake( "__fastcall_%s", odp->link_name );
|
else if (odp->flags & FLAG_FASTCALL) ret = strmake( "__fastcall_%s", odp->link_name );
|
||||||
else return 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 );
|
free( buffer );
|
||||||
buffer = ret;
|
buffer = ret;
|
||||||
|
|
Loading…
Reference in New Issue