mirror of
https://github.com/reactos/wine.git
synced 2024-11-28 06:00:45 +00:00
winebuild: Add support for generating stand-alone 16-bit modules.
This is done by wrapping them inside an empty 32-bit module.
This commit is contained in:
parent
ddc8941d1c
commit
5599ac22c7
@ -207,13 +207,16 @@ extern int resolve_imports( DLLSPEC *spec );
|
||||
extern int has_imports(void);
|
||||
extern int has_relays( DLLSPEC *spec );
|
||||
extern void output_get_pc_thunk(void);
|
||||
extern void output_module( DLLSPEC *spec );
|
||||
extern void output_stubs( DLLSPEC *spec );
|
||||
extern void output_imports( DLLSPEC *spec );
|
||||
extern void output_exports( DLLSPEC *spec );
|
||||
extern int load_res32_file( const char *name, DLLSPEC *spec );
|
||||
extern void output_resources( DLLSPEC *spec );
|
||||
extern void load_res16_file( const char *name, DLLSPEC *spec );
|
||||
extern void output_res16_data( DLLSPEC *spec );
|
||||
extern void output_res16_directory( DLLSPEC *spec );
|
||||
extern void output_spec16_file( DLLSPEC *spec );
|
||||
|
||||
extern void BuildRelays16(void);
|
||||
extern void BuildRelays32(void);
|
||||
@ -221,6 +224,7 @@ extern void BuildSpec16File( DLLSPEC *spec );
|
||||
extern void BuildSpec32File( DLLSPEC *spec );
|
||||
extern void BuildDef32File( DLLSPEC *spec );
|
||||
|
||||
extern void add_16bit_exports( DLLSPEC *spec32, DLLSPEC *spec16 );
|
||||
extern int parse_spec_file( FILE *file, DLLSPEC *spec );
|
||||
extern int parse_def_file( FILE *file, DLLSPEC *spec );
|
||||
|
||||
|
@ -379,6 +379,7 @@ static const char *get_default_entry_point( const DLLSPEC *spec )
|
||||
{
|
||||
if (spec->characteristics & IMAGE_FILE_DLL) return "__wine_spec_dll_entry";
|
||||
if (spec->subsystem == IMAGE_SUBSYSTEM_NATIVE) return "__wine_spec_drv_entry";
|
||||
if (spec->type == SPEC_WIN16) return "__wine_spec_exe16_entry";
|
||||
return "__wine_spec_exe_entry";
|
||||
}
|
||||
|
||||
|
@ -82,6 +82,7 @@ char *spec_file_name = NULL;
|
||||
FILE *output_file = NULL;
|
||||
const char *output_file_name = NULL;
|
||||
static const char *output_file_source_name;
|
||||
static char *main_module; /* FIXME: to be removed */
|
||||
|
||||
char *as_command = NULL;
|
||||
char *ld_command = NULL;
|
||||
@ -142,6 +143,7 @@ static void set_subsystem( const char *subsystem, DLLSPEC *spec )
|
||||
if (!strcmp( str, "native" )) spec->subsystem = IMAGE_SUBSYSTEM_NATIVE;
|
||||
else if (!strcmp( str, "windows" )) spec->subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
|
||||
else if (!strcmp( str, "console" )) spec->subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI;
|
||||
else if (!strcmp( str, "win16" )) spec->type = SPEC_WIN16;
|
||||
else fatal_error( "Invalid subsystem name '%s'\n", subsystem );
|
||||
if (major)
|
||||
{
|
||||
@ -359,6 +361,7 @@ static char **parse_options( int argc, char **argv, DLLSPEC *spec )
|
||||
break;
|
||||
case 'M':
|
||||
spec->type = SPEC_WIN16;
|
||||
main_module = xstrdup( optarg );
|
||||
break;
|
||||
case 'N':
|
||||
spec->dll_name = xstrdup( optarg );
|
||||
@ -591,9 +594,13 @@ int main(int argc, char **argv)
|
||||
switch (spec->type)
|
||||
{
|
||||
case SPEC_WIN16:
|
||||
if (argv[0])
|
||||
fatal_error( "file argument '%s' not allowed in this mode\n", argv[0] );
|
||||
BuildSpec16File( spec );
|
||||
if (!main_module)
|
||||
{
|
||||
read_undef_symbols( spec, argv );
|
||||
output_spec16_file( spec );
|
||||
}
|
||||
else
|
||||
BuildSpec16File( spec );
|
||||
break;
|
||||
case SPEC_WIN32:
|
||||
read_undef_symbols( spec, argv );
|
||||
|
@ -146,13 +146,17 @@ static const char * GetToken( int allow_eol )
|
||||
|
||||
static ORDDEF *add_entry_point( DLLSPEC *spec )
|
||||
{
|
||||
ORDDEF *ret;
|
||||
|
||||
if (spec->nb_entry_points == spec->alloc_entry_points)
|
||||
{
|
||||
spec->alloc_entry_points += 128;
|
||||
spec->entry_points = xrealloc( spec->entry_points,
|
||||
spec->alloc_entry_points * sizeof(*spec->entry_points) );
|
||||
}
|
||||
return &spec->entry_points[spec->nb_entry_points++];
|
||||
ret = &spec->entry_points[spec->nb_entry_points++];
|
||||
memset( ret, 0, sizeof(*ret) );
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
@ -475,9 +479,7 @@ static int parse_spec_ordinal( int ordinal, DLLSPEC *spec )
|
||||
{
|
||||
const char *token;
|
||||
size_t len;
|
||||
|
||||
ORDDEF *odp = add_entry_point( spec );
|
||||
memset( odp, 0, sizeof(*odp) );
|
||||
|
||||
if (!(token = GetToken(0))) goto error;
|
||||
|
||||
@ -723,6 +725,29 @@ static void assign_ordinals( DLLSPEC *spec )
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* add_16bit_exports
|
||||
*
|
||||
* Add the necessary exports to the 32-bit counterpart of a 16-bit module.
|
||||
*/
|
||||
void add_16bit_exports( DLLSPEC *spec32, DLLSPEC *spec16 )
|
||||
{
|
||||
ORDDEF *odp;
|
||||
|
||||
/* add an export for the NE module */
|
||||
|
||||
odp = add_entry_point( spec32 );
|
||||
odp->type = TYPE_EXTERN;
|
||||
odp->name = xstrdup( "__wine_spec_dos_header" );
|
||||
odp->lineno = 0;
|
||||
odp->ordinal = 1;
|
||||
odp->link_name = xstrdup( ".L__wine_spec_dos_header" );
|
||||
|
||||
assign_names( spec32 );
|
||||
assign_ordinals( spec32 );
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* parse_spec_file
|
||||
*
|
||||
@ -844,9 +869,7 @@ static int parse_def_export( char *name, DLLSPEC *spec )
|
||||
{
|
||||
int i, args;
|
||||
const char *token = GetToken(1);
|
||||
|
||||
ORDDEF *odp = add_entry_point( spec );
|
||||
memset( odp, 0, sizeof(*odp) );
|
||||
|
||||
odp->lineno = current_line;
|
||||
odp->ordinal = -1;
|
||||
|
@ -522,20 +522,16 @@ static void output_init_code( const DLLSPEC *spec )
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* BuildSpec16File
|
||||
* output_module16
|
||||
*
|
||||
* Build a Win16 assembly file from a spec file.
|
||||
* Output code for a 16-bit module.
|
||||
*/
|
||||
void BuildSpec16File( DLLSPEC *spec )
|
||||
static void output_module16( DLLSPEC *spec )
|
||||
{
|
||||
ORDDEF **typelist;
|
||||
ORDDEF *entry_point = NULL;
|
||||
int i, j, nb_funcs;
|
||||
|
||||
/* File header */
|
||||
|
||||
output_standard_file_header();
|
||||
|
||||
if (!spec->file_name)
|
||||
{
|
||||
char *p;
|
||||
@ -827,14 +823,58 @@ void BuildSpec16File( DLLSPEC *spec )
|
||||
output( "\t.long %s\n", asm_name("wine_ldt_copy") );
|
||||
}
|
||||
|
||||
free( typelist );
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* BuildSpec16File
|
||||
*
|
||||
* Build a Win16 assembly file from a spec file.
|
||||
*/
|
||||
void BuildSpec16File( DLLSPEC *spec )
|
||||
{
|
||||
output_standard_file_header();
|
||||
output_module16( spec );
|
||||
output_init_code( spec );
|
||||
|
||||
output( "\n\t%s\n", get_asm_string_section() );
|
||||
output( ".L__wine_spec_file_name:\n" );
|
||||
output( "\t%s \"%s\"\n", get_asm_string_keyword(), spec->file_name );
|
||||
|
||||
output_stubs( spec );
|
||||
output_get_pc_thunk();
|
||||
output_init_code( spec );
|
||||
output_gnu_stack_note();
|
||||
|
||||
free( typelist );
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* output_spec16_file
|
||||
*
|
||||
* Output the complete data for a spec 16-bit file.
|
||||
*/
|
||||
void output_spec16_file( DLLSPEC *spec16 )
|
||||
{
|
||||
DLLSPEC *spec32 = alloc_dll_spec();
|
||||
|
||||
spec32->file_name = xstrdup( spec16->file_name );
|
||||
|
||||
if (spec16->characteristics & IMAGE_FILE_DLL)
|
||||
{
|
||||
spec32->characteristics = IMAGE_FILE_DLL;
|
||||
spec32->init_func = xstrdup( "__wine_spec_dll_entry" );
|
||||
}
|
||||
|
||||
resolve_imports( spec16 );
|
||||
add_16bit_exports( spec32, spec16 );
|
||||
|
||||
output_standard_file_header();
|
||||
output_module( spec32 );
|
||||
output_module16( spec16 );
|
||||
output_stubs( spec16 );
|
||||
output_exports( spec32 );
|
||||
output_imports( spec16 );
|
||||
output_resources( spec16 );
|
||||
output_gnu_stack_note();
|
||||
free_dll_spec( spec32 );
|
||||
}
|
||||
|
@ -186,7 +186,7 @@ static void output_relay_debug( DLLSPEC *spec )
|
||||
*
|
||||
* Output the export table for a Win32 module.
|
||||
*/
|
||||
static void output_exports( DLLSPEC *spec )
|
||||
void output_exports( DLLSPEC *spec )
|
||||
{
|
||||
int i, fwd_size = 0;
|
||||
int nr_exports = spec->base <= spec->limit ? spec->limit - spec->base + 1 : 0;
|
||||
@ -366,18 +366,15 @@ static void output_asm_constructor( const char *constructor )
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* BuildSpec32File
|
||||
* output_module
|
||||
*
|
||||
* Build a Win32 C file from a spec file.
|
||||
* Output the module data.
|
||||
*/
|
||||
void BuildSpec32File( DLLSPEC *spec )
|
||||
void output_module( DLLSPEC *spec )
|
||||
{
|
||||
int machine = 0;
|
||||
unsigned int page_size = get_page_size();
|
||||
|
||||
resolve_imports( spec );
|
||||
output_standard_file_header();
|
||||
|
||||
/* Reserve some space for the PE header */
|
||||
|
||||
switch (target_platform)
|
||||
@ -522,11 +519,24 @@ void BuildSpec32File( DLLSPEC *spec )
|
||||
if (target_platform == PLATFORM_APPLE)
|
||||
output( "\t.lcomm %s,4\n", asm_name("_end") );
|
||||
|
||||
output_asm_constructor( "__wine_spec_init_ctor" );
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* BuildSpec32File
|
||||
*
|
||||
* Build a Win32 C file from a spec file.
|
||||
*/
|
||||
void BuildSpec32File( DLLSPEC *spec )
|
||||
{
|
||||
resolve_imports( spec );
|
||||
output_standard_file_header();
|
||||
output_module( spec );
|
||||
output_stubs( spec );
|
||||
output_exports( spec );
|
||||
output_imports( spec );
|
||||
output_resources( spec );
|
||||
output_asm_constructor( "__wine_spec_init_ctor" );
|
||||
output_gnu_stack_note();
|
||||
}
|
||||
|
||||
|
@ -197,7 +197,10 @@ for a command line executable,
|
||||
for a graphical executable,
|
||||
.br
|
||||
.B native
|
||||
for a native-mode dll.
|
||||
for a native-mode dll,
|
||||
.br
|
||||
.B win16
|
||||
for a 16-bit module.
|
||||
.br
|
||||
The entry point of a command line executable is a normal C \fBmain\fR
|
||||
function. A \fBwmain\fR function can be used instead if you need the
|
||||
|
Loading…
Reference in New Issue
Block a user