Revert 31292, 31294 and 31297.

Every change I try for fixing the build in one component breaks the build for another component.
winebuild wasn't synchronized completely to the Wine version anyway, and the current Wine version removed support for the --pedll option we use, so a full clean sync isn't possible.

svn path=/trunk/; revision=31298
This commit is contained in:
Colin Finck 2007-12-17 23:36:09 +00:00
parent f22e568f90
commit cf6d1c80e6
13 changed files with 1366 additions and 1439 deletions

View file

@ -19,8 +19,6 @@ C_SRCS = \
spec32.c \
utils.c
INSTALLDIRS = $(DESTDIR)$(bindir) $(DESTDIR)$(mandir)/man$(prog_manext)
all: $(PROGRAMS) $(MANPAGES)
@MAKE_RULES@
@ -28,11 +26,12 @@ all: $(PROGRAMS) $(MANPAGES)
winebuild$(EXEEXT): $(OBJS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBPORT) $(LDFLAGS)
install:: $(PROGRAMS) $(MANPAGES) $(INSTALLDIRS)
$(INSTALL_PROGRAM) winebuild$(EXEEXT) $(DESTDIR)$(bindir)/winebuild$(EXEEXT)
$(INSTALL_DATA) winebuild.man $(DESTDIR)$(mandir)/man$(prog_manext)/winebuild.$(prog_manext)
install:: $(PROGRAMS) $(MANPAGES)
$(MKINSTALLDIRS) $(bindir) $(mandir)/man$(prog_manext)
$(INSTALL_PROGRAM) winebuild$(EXEEXT) $(bindir)/winebuild$(EXEEXT)
$(INSTALL_DATA) winebuild.man $(mandir)/man$(prog_manext)/winebuild.$(prog_manext)
uninstall::
$(RM) $(DESTDIR)$(bindir)/winebuild$(EXEEXT) $(DESTDIR)$(mandir)/man$(prog_manext)/winebuild.$(prog_manext)
$(RM) $(bindir)/winebuild$(EXEEXT) $(mandir)/man$(prog_manext)/winebuild.$(prog_manext)
@DEPENDENCIES@ # everything below this line is overwritten by make depend
### Dependencies:

View file

@ -17,7 +17,7 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __WINE_BUILD_H
@ -85,7 +85,6 @@ typedef struct
typedef struct
{
char *src_name; /* file name of the source spec file */
char *file_name; /* file name of the dll */
char *dll_name; /* internal name of the dll */
char *init_func; /* initialization routine */
@ -99,7 +98,6 @@ typedef struct
int nb_names; /* number of entry points with names */
unsigned int nb_resources; /* number of resources */
int characteristics; /* characteristics for the PE header */
int dll_characteristics;/* DLL characteristics for the PE header */
int subsystem; /* subsystem id */
int subsystem_major; /* subsystem version major number */
int subsystem_minor; /* subsystem version minor number */
@ -116,7 +114,7 @@ enum target_cpu
enum target_platform
{
PLATFORM_UNSPECIFIED, PLATFORM_APPLE, PLATFORM_WINDOWS
PLATFORM_UNSPECIFIED, PLATFORM_APPLE, PLATFORM_SVR4, PLATFORM_WINDOWS
};
extern enum target_cpu target_cpu;
@ -124,16 +122,31 @@ extern enum target_platform target_platform;
/* entry point flags */
#define FLAG_NORELAY 0x01 /* don't use relay debugging for this function */
#define FLAG_NONAME 0x02 /* don't export function by name */
#define FLAG_NONAME 0x02 /* don't import function by name */
#define FLAG_RET16 0x04 /* function returns a 16-bit value */
#define FLAG_RET64 0x08 /* function returns a 64-bit value */
#define FLAG_I386 0x10 /* function is i386 only */
#define FLAG_REGISTER 0x20 /* use register calling convention */
#define FLAG_PRIVATE 0x40 /* function is private (cannot be imported) */
#define FLAG_ORDINAL 0x80 /* function should be imported by ordinal */
#define FLAG_FORWARD 0x100 /* function is a forwarded name */
#define FLAG_EXT_LINK 0x200 /* function links to an external symbol */
#define FLAG_FORWARD 0x80 /* function is a forwarded name */
#define FLAG_EXT_LINK 0x100 /* function links to an external symbol */
/* Offset of a structure field relative to the start of the struct */
#define STRUCTOFFSET(type,field) ((int)&((type *)0)->field)
/* Offset of register relative to the start of the CONTEXT struct */
#define CONTEXTOFFSET(reg) STRUCTOFFSET(CONTEXT86,reg)
/* Offset of register relative to the start of the STACK16FRAME struct */
#define STACK16OFFSET(reg) STRUCTOFFSET(STACK16FRAME,reg)
/* Offset of register relative to the start of the STACK32FRAME struct */
#define STACK32OFFSET(reg) STRUCTOFFSET(STACK32FRAME,reg)
/* Offset of the stack pointer relative to %fs:(0) */
#define STACKOFFSET (STRUCTOFFSET(TEB,WOW32Reserved))
#define MAX_ORDINALS 65535
@ -156,13 +169,11 @@ extern void error( const char *msg, ... )
__attribute__ ((__format__ (__printf__, 1, 2)));
extern void warning( const char *msg, ... )
__attribute__ ((__format__ (__printf__, 1, 2)));
extern int output( const char *format, ... )
__attribute__ ((__format__ (__printf__, 1, 2)));
extern char *get_temp_file_name( const char *prefix, const char *suffix );
extern void output_standard_file_header(void);
extern void output_standard_file_header( FILE *outfile );
extern FILE *open_input_file( const char *srcdir, const char *name );
extern void close_input_file( FILE *file );
extern void dump_bytes( const void *buffer, unsigned int size );
extern void dump_bytes( FILE *outfile, const void *buffer, unsigned int size );
extern int remove_stdcall_decoration( char *name );
extern void assemble_file( const char *src_file, const char *obj_file );
extern DLLSPEC *alloc_dll_spec(void);
@ -180,8 +191,7 @@ extern const char *get_asm_string_keyword(void);
extern const char *get_asm_short_keyword(void);
extern const char *get_asm_rodata_section(void);
extern const char *get_asm_string_section(void);
extern void output_function_size( const char *name );
extern void output_gnu_stack_note(void);
extern void output_function_size( FILE *outfile, const char *name );
extern void add_import_dll( const char *name, const char *filename );
extern void add_delayed_import( const char *name );
@ -191,25 +201,27 @@ extern void read_undef_symbols( DLLSPEC *spec, char **argv );
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_stubs( DLLSPEC *spec );
extern void output_imports( DLLSPEC *spec );
extern void output_get_pc_thunk( FILE *outfile );
extern void output_stubs( FILE *outfile, DLLSPEC *spec );
extern void output_imports( FILE *outfile, DLLSPEC *spec );
extern int load_res32_file( const char *name, DLLSPEC *spec );
extern void output_resources( DLLSPEC *spec );
extern void output_resources( FILE *outfile, 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, const char *header_name );
extern void output_res16_data( FILE *outfile, DLLSPEC *spec );
extern void output_res16_directory( FILE *outfile, DLLSPEC *spec, const char *header_name );
extern void BuildRelays16(void);
extern void BuildRelays32(void);
extern void BuildSpec16File( DLLSPEC *spec );
extern void BuildSpec32File( DLLSPEC *spec );
extern void BuildDef32File( DLLSPEC *spec );
extern void BuildPedllFile( DLLSPEC *spec );
extern void BuildRelays16( FILE *outfile );
extern void BuildRelays32( FILE *outfile );
extern void BuildSpec16File( FILE *outfile, DLLSPEC *spec );
extern void BuildSpec32File( FILE *outfile, DLLSPEC *spec );
extern void BuildDef32File( FILE *outfile, DLLSPEC *spec );
extern void BuildPedllFile( FILE *outfile, DLLSPEC *spec );
extern int parse_spec_file( FILE *file, DLLSPEC *spec );
extern int parse_def_file( FILE *file, DLLSPEC *spec );
extern int mkstemps(char *template, int suffix_len);
/* global variables */
extern int current_line;
@ -220,11 +232,9 @@ extern int display_warnings;
extern int kill_at;
extern int verbose;
extern int save_temps;
extern int link_ext_symbols;
extern char *input_file_name;
extern char *spec_file_name;
extern FILE *output_file;
extern const char *output_file_name;
extern char **lib_path;

File diff suppressed because it is too large Load diff

View file

@ -19,14 +19,16 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "wine/port.h"
#include <assert.h>
#include <stdio.h>
#ifdef WIN32
#include <io.h> /* unlink() */
#endif//WIN32
#include <signal.h>
#include <errno.h>
#include <string.h>
@ -46,7 +48,6 @@ int display_warnings = 0;
int kill_at = 0;
int verbose = 0;
int save_temps = 0;
int link_ext_symbols = 0;
#if defined(__i386__) || defined(__x86_64__)
enum target_cpu target_cpu = CPU_x86;
@ -64,6 +65,8 @@ enum target_cpu target_cpu = CPU_POWERPC;
#ifdef __APPLE__
enum target_platform target_platform = PLATFORM_APPLE;
#elif defined(__svr4__)
enum target_platform target_platform = PLATFORM_SVR4;
#elif defined(_WINDOWS)
enum target_platform target_platform = PLATFORM_WINDOWS;
#else
@ -74,7 +77,6 @@ char **lib_path = NULL;
char *input_file_name = NULL;
char *spec_file_name = NULL;
FILE *output_file = NULL;
const char *output_file_name = NULL;
static const char *output_file_source_name;
@ -82,6 +84,7 @@ char *as_command = NULL;
char *ld_command = NULL;
char *nm_command = NULL;
static FILE *output_file;
static int nb_res_files;
static char **res_files;
@ -124,6 +127,7 @@ static const struct
{
{ "macos", PLATFORM_APPLE },
{ "darwin", PLATFORM_APPLE },
{ "sunos", PLATFORM_SVR4 },
{ "windows", PLATFORM_WINDOWS },
{ "winnt", PLATFORM_WINDOWS }
};
@ -244,9 +248,8 @@ static const char usage_str[] =
" --as-cmd=AS Command to use for assembling (default: as)\n"
" -d, --delay-lib=LIB Import the specified library in delayed mode\n"
" -D SYM Ignored for C flags compatibility\n"
" -e, --entry=FUNC Set the DLL entry point function (default: DllMain)\n"
" -E, --export=FILE Export the symbols defined in the .spec or .def file\n"
" --external-symbols Allow linking to external symbols\n"
" -e, --entry=FUNC Set the DLL entry point function (default: DllMain)\n"
" -f FLAGS Compiler flags (only -fPIC is supported)\n"
" -F, --filename=DLLFILE Set the DLL filename (default: from input file name)\n"
" -h, --help Display this help message\n"
@ -260,7 +263,6 @@ static const char usage_str[] =
" -L, --library-path=DIR Look for imports libraries in DIR\n"
" -M, --main-module=MODULE Set the name of the main module for a Win16 dll\n"
" --nm-cmd=NM Command to use to get undefined symbols (default: nm)\n"
" --nxcompat=y|n Set the NX compatibility flag (default: yes)\n"
" -N, --dll-name=DLLNAME Set the DLL name (default: from input file name)\n"
" -o, --output=NAME Set the output file name (default: stdout)\n"
" -r, --res=RSRC.RES Load resources from RSRC.RES\n"
@ -276,7 +278,7 @@ static const char usage_str[] =
" --def Build a .def file from a .spec file\n"
" --exe Build a .c file for an executable\n"
" --relay16 Build the 16-bit relay assembly routines\n"
" --relay32 Build the 32-bit relay assembly routines\n\n"
" --relay32 Build the 32-bit relay assembly routines\n"
" --pedll Build a .c file for PE dll\n\n"
"The mode options are mutually exclusive; you must specify one and only one.\n\n";
@ -286,16 +288,14 @@ enum long_options_values
LONG_OPT_DEF,
LONG_OPT_EXE,
LONG_OPT_ASCMD,
LONG_OPT_EXTERNAL_SYMS,
LONG_OPT_LDCMD,
LONG_OPT_NMCMD,
LONG_OPT_NXCOMPAT,
LONG_OPT_RELAY16,
LONG_OPT_RELAY32,
LONG_OPT_SAVE_TEMPS,
LONG_OPT_SUBSYSTEM,
LONG_OPT_TARGET,
LONG_OPT_VERSION,
LONG_OPT_TARGET,
LONG_OPT_PEDLL
};
@ -303,21 +303,19 @@ static const char short_options[] = "C:D:E:F:H:I:K:L:M:N:d:e:f:hi:kl:m:o:r:u:vw"
static const struct option long_options[] =
{
{ "dll", 0, 0, LONG_OPT_DLL },
{ "def", 0, 0, LONG_OPT_DEF },
{ "exe", 0, 0, LONG_OPT_EXE },
{ "as-cmd", 1, 0, LONG_OPT_ASCMD },
{ "external-symbols", 0, 0, LONG_OPT_EXTERNAL_SYMS },
{ "ld-cmd", 1, 0, LONG_OPT_LDCMD },
{ "nm-cmd", 1, 0, LONG_OPT_NMCMD },
{ "nxcompat", 1, 0, LONG_OPT_NXCOMPAT },
{ "relay16", 0, 0, LONG_OPT_RELAY16 },
{ "relay32", 0, 0, LONG_OPT_RELAY32 },
{ "save-temps", 0, 0, LONG_OPT_SAVE_TEMPS },
{ "subsystem", 1, 0, LONG_OPT_SUBSYSTEM },
{ "target", 1, 0, LONG_OPT_TARGET },
{ "version", 0, 0, LONG_OPT_VERSION },
{ "pedll", 1, 0, LONG_OPT_PEDLL },
{ "dll", 0, 0, LONG_OPT_DLL },
{ "def", 0, 0, LONG_OPT_DEF },
{ "exe", 0, 0, LONG_OPT_EXE },
{ "as-cmd", 1, 0, LONG_OPT_ASCMD },
{ "ld-cmd", 1, 0, LONG_OPT_LDCMD },
{ "nm-cmd", 1, 0, LONG_OPT_NMCMD },
{ "relay16", 0, 0, LONG_OPT_RELAY16 },
{ "relay32", 0, 0, LONG_OPT_RELAY32 },
{ "save-temps",0, 0, LONG_OPT_SAVE_TEMPS },
{ "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 */
{ "delay-lib", 1, 0, 'd' },
{ "export", 1, 0, 'E' },
@ -473,19 +471,12 @@ static char **parse_options( int argc, char **argv, DLLSPEC *spec )
case LONG_OPT_ASCMD:
as_command = xstrdup( optarg );
break;
case LONG_OPT_EXTERNAL_SYMS:
link_ext_symbols = 1;
break;
case LONG_OPT_LDCMD:
ld_command = xstrdup( optarg );
break;
case LONG_OPT_NMCMD:
nm_command = xstrdup( optarg );
break;
case LONG_OPT_NXCOMPAT:
if (optarg[0] == 'n' || optarg[0] == 'N')
spec->dll_characteristics &= ~IMAGE_DLLCHARACTERISTICS_NX_COMPAT;
break;
case LONG_OPT_RELAY16:
set_exec_mode( MODE_RELAY16 );
break;
@ -573,7 +564,6 @@ static int parse_input_file( DLLSPEC *spec )
char *extension = strrchr( spec_file_name, '.' );
int result;
spec->src_name = xstrdup( input_file_name );
if (extension && !strcmp( extension, ".def" ))
result = parse_def_file( input_file, spec );
else
@ -602,8 +592,7 @@ int main(int argc, char **argv)
switch(exec_mode)
{
case MODE_DLL:
if (spec->subsystem != IMAGE_SUBSYSTEM_NATIVE)
spec->characteristics |= IMAGE_FILE_DLL;
spec->characteristics |= IMAGE_FILE_DLL;
load_resources( argv, spec );
load_import_libs( argv );
if (!spec_file_name) fatal_error( "missing .spec file\n" );
@ -615,7 +604,7 @@ int main(int argc, char **argv)
break;
case SPEC_WIN32:
read_undef_symbols( spec, argv );
BuildSpec32File( spec );
BuildSpec32File( output_file, spec );
break;
default: assert(0);
}
@ -627,14 +616,14 @@ int main(int argc, char **argv)
load_import_libs( argv );
if (spec_file_name && !parse_input_file( spec )) break;
read_undef_symbols( spec, argv );
BuildSpec32File( spec );
BuildSpec32File( output_file, 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" );
if (!spec_file_name) fatal_error( "missing .spec file\n" );
if (!parse_input_file( spec )) break;
BuildDef32File( spec );
BuildDef32File( output_file, spec );
break;
case MODE_RELAY16:
fatal_error( "Win16 relays are not supported in ReactOS version of winebuild\n" );
@ -645,7 +634,7 @@ int main(int argc, char **argv)
case MODE_PEDLL:
if (argv[0]) fatal_error( "file argument '%s' not allowed in this mode\n", argv[0] );
if (!parse_input_file( spec )) break;
BuildPedllFile( spec );
BuildPedllFile( output_file, spec );
break;
default:
usage(1);
@ -654,7 +643,7 @@ int main(int argc, char **argv)
if (nb_errors) exit(1);
if (output_file_name)
{
if (fclose( output_file ) < 0) fatal_perror( "fclose" );
fclose( output_file );
if (output_file_source_name) assemble_file( output_file_source_name, output_file_name );
output_file_name = NULL;
}

View file

@ -19,11 +19,10 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "wine/port.h"
#include <assert.h>
#include <ctype.h>
@ -45,9 +44,6 @@ static FILE *input_file;
static const char *separator_chars;
static const char *comment_chars;
/* valid characters in ordinal names */
static const char valid_ordname_chars[] = "/$:-_@?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
static const char * const TypeNames[TYPE_NBTYPES] =
{
"variable", /* TYPE_VARIABLE */
@ -69,7 +65,6 @@ static const char * const FlagNames[] =
"i386", /* FLAG_I386 */
"register", /* FLAG_REGISTER */
"private", /* FLAG_PRIVATE */
"ordinal", /* FLAG_ORDINAL */
NULL
};
@ -79,12 +74,12 @@ static int IsNumberString(const char *s)
return 1;
}
static inline int is_token_separator( char ch )
inline static int is_token_separator( char ch )
{
return strchr( separator_chars, ch ) != NULL;
}
static inline int is_token_comment( char ch )
inline static int is_token_comment( char ch )
{
return strchr( comment_chars, ch ) != NULL;
}
@ -450,7 +445,6 @@ static const char *parse_spec_flags( ORDDEF *odp )
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) );
@ -474,13 +468,6 @@ static int parse_spec_ordinal( int ordinal, DLLSPEC *spec )
odp->lineno = current_line;
odp->ordinal = ordinal;
len = strspn( odp->name, valid_ordname_chars );
if (len < strlen( odp->name ))
{
error( "Character '%c' is not allowed in exported name '%s'\n", odp->name[len], odp->name );
goto error;
}
switch(odp->type)
{
case TYPE_VARIABLE:
@ -545,14 +532,11 @@ static int parse_spec_ordinal( int ordinal, DLLSPEC *spec )
}
}
if (!strcmp( odp->name, "@" ) || odp->flags & (FLAG_NONAME | FLAG_ORDINAL))
if (!strcmp( odp->name, "@" ) || odp->flags & FLAG_NONAME)
{
if (ordinal == -1)
{
if (!strcmp( odp->name, "@" ))
error( "Nameless function needs an explicit ordinal number\n" );
else
error( "Function imported by ordinal needs an explicit ordinal number\n" );
error( "Nameless function needs an explicit ordinal number\n" );
goto error;
}
if (spec->type != SPEC_WIN32)
@ -560,16 +544,9 @@ static int parse_spec_ordinal( int ordinal, DLLSPEC *spec )
error( "Nameless functions not supported for Win16\n" );
goto error;
}
if (!strcmp( odp->name, "@" ))
{
free( odp->name );
odp->name = NULL;
}
else if (!(odp->flags & FLAG_ORDINAL)) /* -ordinal only affects the import library */
{
odp->export_name = odp->name;
odp->name = NULL;
}
if (!strcmp( odp->name, "@" )) free( odp->name );
else odp->export_name = odp->name;
odp->name = NULL;
}
return 1;

File diff suppressed because it is too large Load diff

View file

@ -15,11 +15,10 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "wine/port.h"
#include <assert.h>
#include <ctype.h>
@ -78,7 +77,7 @@ static const unsigned char *file_end; /* end of resource file */
static const char *file_name; /* current resource file name */
static inline struct resource *add_resource( DLLSPEC *spec )
inline static struct resource *add_resource( DLLSPEC *spec )
{
spec->resources = xrealloc( spec->resources, (spec->nb_resources + 1) * sizeof(*spec->resources) );
return &spec->resources[spec->nb_resources++];
@ -141,7 +140,7 @@ static void get_string( struct string_id *str )
}
else
{
char *p = xmalloc(strlen((const char *)file_pos) + 1);
char *p = xmalloc( (strlen((char*)file_pos) + 1) );
str->str = p;
str->id = 0;
while ((*p++ = get_byte()));
@ -241,16 +240,16 @@ static void free_resource_tree( struct res_tree *tree )
}
/* output a string preceded by its length */
static void output_string( const char *str )
static void output_string( FILE *outfile, const char *str )
{
unsigned int i, len = strlen(str);
output( "\t.byte 0x%02x", len );
for (i = 0; i < len; i++) output( ",0x%02x", (unsigned char)str[i] );
output( " /* %s */\n", str );
fprintf( outfile, "\t.byte 0x%02x", len );
for (i = 0; i < len; i++) fprintf( outfile, ",0x%02x", (unsigned char)str[i] );
fprintf( outfile, " /* %s */\n", str );
}
/* output the resource data */
void output_res16_data( DLLSPEC *spec )
void output_res16_data( FILE *outfile, DLLSPEC *spec )
{
const struct resource *res;
unsigned int i;
@ -259,14 +258,14 @@ void output_res16_data( DLLSPEC *spec )
for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++)
{
output( ".L__wine_spec_resource_%u:\n", i );
dump_bytes( res->data, res->data_size );
output( ".L__wine_spec_resource_%u_end:\n", i );
fprintf( outfile, ".L__wine_spec_resource_%u:\n", i );
dump_bytes( outfile, res->data, res->data_size );
fprintf( outfile, ".L__wine_spec_resource_%u_end:\n", i );
}
}
/* output the resource definitions */
void output_res16_directory( DLLSPEC *spec, const char *header_name )
void output_res16_directory( FILE *outfile, DLLSPEC *spec, const char *header_name )
{
unsigned int i, j;
struct res_tree *tree;
@ -275,39 +274,38 @@ void output_res16_directory( DLLSPEC *spec, const char *header_name )
tree = build_resource_tree( spec );
output( "\n.L__wine_spec_ne_rsrctab:\n" );
output( "\t%s 0\n", get_asm_short_keyword() ); /* alignment */
fprintf( outfile, "\n.L__wine_spec_ne_rsrctab:\n" );
fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* alignment */
/* type and name structures */
for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
{
if (type->type->str)
output( "\t%s .L__wine_spec_restype_%u-.L__wine_spec_ne_rsrctab\n",
fprintf( outfile, "\t%s .L__wine_spec_restype_%u-.L__wine_spec_ne_rsrctab\n",
get_asm_short_keyword(), i );
else
output( "\t%s 0x%04x\n", get_asm_short_keyword(), type->type->id | 0x8000 );
fprintf( outfile, "\t%s 0x%04x\n", get_asm_short_keyword(), type->type->id | 0x8000 );
output( "\t%s %u,0,0\n", get_asm_short_keyword(), type->nb_names );
fprintf( outfile, "\t%s %u,0,0\n", get_asm_short_keyword(), type->nb_names );
for (j = 0, res = type->res; j < type->nb_names; j++, res++)
{
output( "\t%s .L__wine_spec_resource_%lu-%s\n",
get_asm_short_keyword(), (unsigned long)(res - spec->resources), header_name );
output( "\t%s .L__wine_spec_resource_%lu_end-.L__wine_spec_resource_%lu\n",
get_asm_short_keyword(), (unsigned long)(res - spec->resources),
(unsigned long)(res - spec->resources) );
output( "\t%s 0x%04x\n", get_asm_short_keyword(), res->memopt );
fprintf( outfile, "\t%s .L__wine_spec_resource_%u-%s\n",
get_asm_short_keyword(), res - spec->resources, header_name );
fprintf( outfile, "\t%s .L__wine_spec_resource_%u_end-.L__wine_spec_resource_%u\n",
get_asm_short_keyword(), res - spec->resources, res - spec->resources );
fprintf( outfile, "\t%s 0x%04x\n", get_asm_short_keyword(), res->memopt );
if (res->name.str)
output( "\t%s .L__wine_spec_resname_%u_%u-.L__wine_spec_ne_rsrctab\n",
fprintf( outfile, "\t%s .L__wine_spec_resname_%u_%u-.L__wine_spec_ne_rsrctab\n",
get_asm_short_keyword(), i, j );
else
output( "\t%s 0x%04x\n", get_asm_short_keyword(), res->name.id | 0x8000 );
fprintf( outfile, "\t%s 0x%04x\n", get_asm_short_keyword(), res->name.id | 0x8000 );
output( "\t%s 0,0\n", get_asm_short_keyword() );
fprintf( outfile, "\t%s 0,0\n", get_asm_short_keyword() );
}
}
output( "\t%s 0\n", get_asm_short_keyword() ); /* terminator */
fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* terminator */
/* name strings */
@ -315,19 +313,19 @@ void output_res16_directory( DLLSPEC *spec, const char *header_name )
{
if (type->type->str)
{
output( ".L__wine_spec_restype_%u:\n", i );
output_string( type->type->str );
fprintf( outfile, ".L__wine_spec_restype_%u:\n", i );
output_string( outfile, type->type->str );
}
for (j = 0, res = type->res; j < type->nb_names; j++, res++)
{
if (res->name.str)
{
output( ".L__wine_spec_resname_%u_%u:\n", i, j );
output_string( res->name.str );
fprintf( outfile, ".L__wine_spec_resname_%u_%u:\n", i, j );
output_string( outfile, res->name.str );
}
}
}
output( "\t.byte 0\n" ); /* names terminator */
fprintf( outfile, "\t.byte 0\n" ); /* names terminator */
free_resource_tree( tree );
}

View file

@ -15,11 +15,10 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "wine/port.h"
#include <ctype.h>
#include <stdlib.h>
@ -92,7 +91,7 @@ static const char *file_name; /* current resource file name */
#define RESDIR_SIZE(n) (sizeof(IMAGE_RESOURCE_DIRECTORY) + (n) * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY))
static inline struct resource *add_resource( DLLSPEC *spec )
inline static struct resource *add_resource( DLLSPEC *spec )
{
spec->resources = xrealloc( spec->resources, (spec->nb_resources + 1) * sizeof(spec->resources[0]) );
return &spec->resources[spec->nb_resources++];
@ -315,29 +314,29 @@ static void free_resource_tree( struct res_tree *tree )
}
/* output a Unicode string */
static void output_string( const WCHAR *name )
static void output_string( FILE *outfile, const WCHAR *name )
{
int i, len = strlenW(name);
output( "\t%s 0x%04x", get_asm_short_keyword(), len );
for (i = 0; i < len; i++) output( ",0x%04x", name[i] );
output( " /* " );
for (i = 0; i < len; i++) output( "%c", isprint((char)name[i]) ? (char)name[i] : '?' );
output( " */\n" );
fprintf( outfile, "\t%s 0x%04x", get_asm_short_keyword(), len );
for (i = 0; i < len; i++) fprintf( outfile, ",0x%04x", name[i] );
fprintf( outfile, " /* " );
for (i = 0; i < len; i++) fprintf( outfile, "%c", isprint((char)name[i]) ? (char)name[i] : '?' );
fprintf( outfile, " */\n" );
}
/* output a resource directory */
static inline void output_res_dir( unsigned int nb_names, unsigned int nb_ids )
static inline void output_res_dir( FILE *outfile, unsigned int nb_names, unsigned int nb_ids )
{
output( "\t.long 0\n" ); /* Characteristics */
output( "\t.long 0\n" ); /* TimeDateStamp */
output( "\t%s 0,0\n", /* Major/MinorVersion */
fprintf( outfile, "\t.long 0\n" ); /* Characteristics */
fprintf( outfile, "\t.long 0\n" ); /* TimeDateStamp */
fprintf( outfile, "\t%s 0,0\n", /* Major/MinorVersion */
get_asm_short_keyword() );
output( "\t%s %u,%u\n", /* NumberOfNamed/IdEntries */
fprintf( outfile, "\t%s %u,%u\n", /* NumberOfNamed/IdEntries */
get_asm_short_keyword(), nb_names, nb_ids );
}
/* output the resource definitions */
void output_resources( DLLSPEC *spec )
void output_resources( FILE *outfile, DLLSPEC *spec )
{
int k, nb_id_types;
unsigned int i, n, offset, data_offset;
@ -387,19 +386,19 @@ void output_resources( DLLSPEC *spec )
/* output the resource directories */
output( "\n/* resources */\n\n" );
output( "\t.data\n" );
output( "\t.align %d\n", get_alignment(get_ptr_size()) );
output( ".L__wine_spec_resources:\n" );
fprintf( outfile, "\n/* resources */\n\n" );
fprintf( outfile, "\t.data\n" );
fprintf( outfile, "\t.align %d\n", get_alignment(get_ptr_size()) );
fprintf( outfile, ".L__wine_spec_resources:\n" );
output_res_dir( tree->nb_types - nb_id_types, nb_id_types );
output_res_dir( outfile, tree->nb_types - nb_id_types, nb_id_types );
/* dump the type directory */
offset = RESDIR_SIZE( tree->nb_types );
for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
{
output( "\t.long 0x%08x,0x%08x\n",
fprintf( outfile, "\t.long 0x%08x,0x%08x\n",
type->name_offset, offset | 0x80000000 );
offset += RESDIR_SIZE( type->nb_names );
for (n = 0, name = type->names; n < type->nb_names; n++, name++)
@ -413,22 +412,22 @@ void output_resources( DLLSPEC *spec )
for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
{
output_res_dir( type->nb_names - type->nb_id_names, type->nb_id_names );
output_res_dir( outfile, type->nb_names - type->nb_id_names, type->nb_id_names );
offset += RESDIR_SIZE( type->nb_names );
for (n = 0, name = type->names; n < type->nb_names; n++, name++)
{
output( "\t.long 0x%08x,0x%08x\n",
fprintf( outfile, "\t.long 0x%08x,0x%08x\n",
name->name_offset, offset | 0x80000000 );
offset += RESDIR_SIZE( name->nb_languages );
}
for (n = 0, name = type->names; n < type->nb_names; n++, name++)
{
output_res_dir( 0, name->nb_languages );
output_res_dir( outfile, 0, name->nb_languages );
for (k = 0, res = name->res; k < name->nb_languages; k++, res++)
{
unsigned int entry_offset = (res - spec->resources) * sizeof(IMAGE_RESOURCE_DATA_ENTRY);
output( "\t.long 0x%08x,0x%08x\n", res->lang, data_offset + entry_offset );
fprintf( outfile, "\t.long 0x%08x,0x%08x\n", res->lang,
data_offset + (res - spec->resources) * sizeof(IMAGE_RESOURCE_DATA_ENTRY) );
}
}
}
@ -436,28 +435,28 @@ void output_resources( DLLSPEC *spec )
/* dump the resource data entries */
for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++)
output( "\t.long .L__wine_spec_res_%d-.L__wine_spec_rva_base,%u,0,0\n",
fprintf( outfile, "\t.long .L__wine_spec_res_%d-.L__wine_spec_rva_base,%u,0,0\n",
i, res->data_size );
/* dump the name strings */
for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
{
if (type->type->str) output_string( type->type->str );
if (type->type->str) output_string( outfile, type->type->str );
for (n = 0, name = type->names; n < type->nb_names; n++, name++)
if (name->name->str) output_string( name->name->str );
if (name->name->str) output_string( outfile, name->name->str );
}
/* resource data */
for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++)
{
output( "\n\t.align %d\n", get_alignment(get_ptr_size()) );
output( ".L__wine_spec_res_%d:\n", i );
dump_bytes( res->data, res->data_size );
fprintf( outfile, "\n\t.align %d\n", get_alignment(get_ptr_size()) );
fprintf( outfile, ".L__wine_spec_res_%d:\n", i );
dump_bytes( outfile, res->data, res->data_size );
}
output( ".L__wine_spec_resources_end:\n" );
output( "\t.byte 0\n" );
fprintf( outfile, ".L__wine_spec_resources_end:\n" );
fprintf( outfile, "\t.byte 0\n" );
free_resource_tree( tree );
}

View file

@ -19,11 +19,10 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "wine/port.h"
#include <assert.h>
#include <ctype.h>
@ -54,31 +53,31 @@ static inline int is_function( const ORDDEF *odp )
*
* Output entries for individual symbols in the entry table.
*/
static void output_entries( DLLSPEC *spec, int first, int count )
static void output_entries( FILE *outfile, DLLSPEC *spec, int first, int count )
{
int i;
for (i = 0; i < count; i++)
{
ORDDEF *odp = spec->ordinals[first + i];
output( "\t.byte 0x03\n" ); /* flags: exported & public data */
fprintf( outfile, "\t.byte 0x03\n" ); /* flags: exported & public data */
switch (odp->type)
{
case TYPE_CDECL:
case TYPE_PASCAL:
case TYPE_VARARGS:
case TYPE_STUB:
output( "\t%s .L__wine_%s_%u-.L__wine_spec_code_segment\n",
fprintf( outfile, "\t%s .L__wine_%s_%u-.L__wine_spec_code_segment\n",
get_asm_short_keyword(),
make_c_identifier(spec->dll_name), first + i );
break;
case TYPE_VARIABLE:
output( "\t%s .L__wine_%s_%u-.L__wine_spec_data_segment\n",
fprintf( outfile, "\t%s .L__wine_%s_%u-.L__wine_spec_data_segment\n",
get_asm_short_keyword(),
make_c_identifier(spec->dll_name), first + i );
break;
case TYPE_ABS:
output( "\t%s 0x%04x /* %s */\n",
fprintf( outfile, "\t%s 0x%04x /* %s */\n",
get_asm_short_keyword(), odp->u.abs.value, odp->name );
break;
default:
@ -91,7 +90,7 @@ static void output_entries( DLLSPEC *spec, int first, int count )
/*******************************************************************
* output_entry_table
*/
static void output_entry_table( DLLSPEC *spec )
static void output_entry_table( FILE *outfile, DLLSPEC *spec )
{
int i, prev = 0, prev_sel = -1, bundle_count = 0;
@ -126,10 +125,10 @@ static void output_entry_table( DLLSPEC *spec )
/* flush previous bundle */
if (bundle_count)
{
output( "\t/* %s.%d - %s.%d */\n",
fprintf( outfile, "\t/* %s.%d - %s.%d */\n",
spec->dll_name, prev - bundle_count + 1, spec->dll_name, prev );
output( "\t.byte 0x%02x,0x%02x\n", bundle_count, prev_sel );
output_entries( spec, prev - bundle_count + 1, bundle_count );
fprintf( outfile, "\t.byte 0x%02x,0x%02x\n", bundle_count, prev_sel );
output_entries( outfile, spec, prev - bundle_count + 1, bundle_count );
}
if (prev + 1 != i)
@ -137,10 +136,10 @@ static void output_entry_table( DLLSPEC *spec )
int skip = i - (prev + 1);
while (skip > 255)
{
output( "\t.byte 0xff,0x00\n" );
fprintf( outfile, "\t.byte 0xff,0x00\n" );
skip -= 255;
}
output( "\t.byte 0x%02x,0x00\n", skip );
fprintf( outfile, "\t.byte 0x%02x,0x00\n", skip );
}
bundle_count = 0;
@ -153,24 +152,24 @@ static void output_entry_table( DLLSPEC *spec )
/* flush last bundle */
if (bundle_count)
{
output( "\t.byte 0x%02x,0x%02x\n", bundle_count, prev_sel );
output_entries( spec, prev - bundle_count + 1, bundle_count );
fprintf( outfile, "\t.byte 0x%02x,0x%02x\n", bundle_count, prev_sel );
output_entries( outfile, spec, prev - bundle_count + 1, bundle_count );
}
output( "\t.byte 0x00\n" );
fprintf( outfile, "\t.byte 0x00\n" );
}
/*******************************************************************
* output_resident_name
*/
static void output_resident_name( const char *string, int ordinal )
static void output_resident_name( FILE *outfile, const char *string, int ordinal )
{
unsigned int i, len = strlen(string);
output( "\t.byte 0x%02x", len );
for (i = 0; i < len; i++) output( ",0x%02x", (unsigned char)toupper(string[i]) );
output( " /* %s */\n", string );
output( "\t%s %u\n", get_asm_short_keyword(), ordinal );
fprintf( outfile, "\t.byte 0x%02x", len );
for (i = 0; i < len; i++) fprintf( outfile, ",0x%02x", (unsigned char)toupper(string[i]) );
fprintf( outfile, " /* %s */\n", string );
fprintf( outfile, "\t%s %u\n", get_asm_short_keyword(), ordinal );
}
@ -283,7 +282,7 @@ static int get_function_argsize( const ORDDEF *odp )
* the same as for normal functions, but in addition the CONTEXT86 pointer
* filled with the current register values is passed to the 32-bit routine.
*/
static void output_call16_function( ORDDEF *odp )
static void output_call16_function( FILE *outfile, ORDDEF *odp )
{
char name[256];
int i, pos, stack_words;
@ -293,41 +292,41 @@ static void output_call16_function( ORDDEF *odp )
sprintf( name, ".L__wine_spec_call16_%s", get_relay_name(odp) );
output( "\t.align %d\n", get_alignment(4) );
output( "\t%s\n", func_declaration(name) );
output( "%s:\n", name );
output( "\tpushl %%ebp\n" );
output( "\tmovl %%esp,%%ebp\n" );
fprintf( outfile, "\t.align %d\n", get_alignment(4) );
fprintf( outfile, "\t%s\n", func_declaration(name) );
fprintf( outfile, "%s:\n", name );
fprintf( outfile, "\tpushl %%ebp\n" );
fprintf( outfile, "\tmovl %%esp,%%ebp\n" );
stack_words = 2;
if (needs_ldt)
{
output( "\tpushl %%esi\n" );
fprintf( outfile, "\tpushl %%esi\n" );
stack_words++;
if (UsePIC)
{
output( "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") );
output( "1:\tmovl wine_ldt_copy_ptr-1b(%%eax),%%esi\n" );
fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") );
fprintf( outfile, "1:\tmovl wine_ldt_copy_ptr-1b(%%eax),%%esi\n" );
}
else
output( "\tmovl $%s,%%esi\n", asm_name("wine_ldt_copy") );
fprintf( outfile, "\tmovl $%s,%%esi\n", asm_name("wine_ldt_copy") );
}
/* preserve 16-byte stack alignment */
stack_words += strlen(args);
if ((odp->flags & FLAG_REGISTER) || (odp->type == TYPE_VARARGS)) stack_words++;
if (stack_words % 4) output( "\tsubl $%d,%%esp\n", 16 - 4 * (stack_words % 4) );
if (stack_words % 4) fprintf( outfile, "\tsubl $%d,%%esp\n", 16 - 4 * (stack_words % 4) );
if (args[0] || odp->type == TYPE_VARARGS)
output( "\tmovl 12(%%ebp),%%ecx\n" ); /* args */
fprintf( outfile, "\tmovl 12(%%ebp),%%ecx\n" ); /* args */
if (odp->flags & FLAG_REGISTER)
{
output( "\tpushl 16(%%ebp)\n" ); /* context */
fprintf( outfile, "\tpushl 16(%%ebp)\n" ); /* context */
}
else if (odp->type == TYPE_VARARGS)
{
output( "\tleal %d(%%ecx),%%eax\n", argsize );
output( "\tpushl %%eax\n" ); /* va_list16 */
fprintf( outfile, "\tleal %d(%%ecx),%%eax\n", argsize );
fprintf( outfile, "\tpushl %%eax\n" ); /* va_list16 */
}
pos = (odp->type == TYPE_PASCAL) ? 0 : argsize;
@ -337,33 +336,33 @@ static void output_call16_function( ORDDEF *odp )
{
case 'w': /* word */
if (odp->type != TYPE_PASCAL) pos -= 2;
output( "\tmovzwl %d(%%ecx),%%eax\n", pos );
output( "\tpushl %%eax\n" );
fprintf( outfile, "\tmovzwl %d(%%ecx),%%eax\n", pos );
fprintf( outfile, "\tpushl %%eax\n" );
if (odp->type == TYPE_PASCAL) pos += 2;
break;
case 's': /* s_word */
if (odp->type != TYPE_PASCAL) pos -= 2;
output( "\tmovswl %d(%%ecx),%%eax\n", pos );
output( "\tpushl %%eax\n" );
fprintf( outfile, "\tmovswl %d(%%ecx),%%eax\n", pos );
fprintf( outfile, "\tpushl %%eax\n" );
if (odp->type == TYPE_PASCAL) pos += 2;
break;
case 'l': /* long or segmented pointer */
case 'T': /* segmented pointer to null-terminated string */
if (odp->type != TYPE_PASCAL) pos -= 4;
output( "\tpushl %d(%%ecx)\n", pos );
fprintf( outfile, "\tpushl %d(%%ecx)\n", pos );
if (odp->type == TYPE_PASCAL) pos += 4;
break;
case 'p': /* linear pointer */
case 't': /* linear pointer to null-terminated string */
if (odp->type != TYPE_PASCAL) pos -= 4;
output( "\tmovzwl %d(%%ecx),%%edx\n", pos + 2 ); /* sel */
output( "\tshr $3,%%edx\n" );
output( "\tmovzwl %d(%%ecx),%%eax\n", pos ); /* offset */
output( "\taddl (%%esi,%%edx,4),%%eax\n" );
output( "\tpushl %%eax\n" );
fprintf( outfile, "\tmovzwl %d(%%ecx),%%edx\n", pos + 2 ); /* sel */
fprintf( outfile, "\tshr $3,%%edx\n" );
fprintf( outfile, "\tmovzwl %d(%%ecx),%%eax\n", pos ); /* offset */
fprintf( outfile, "\taddl (%%esi,%%edx,4),%%eax\n" );
fprintf( outfile, "\tpushl %%eax\n" );
if (odp->type == TYPE_PASCAL) pos += 4;
break;
@ -372,13 +371,14 @@ static void output_call16_function( ORDDEF *odp )
}
}
output( "\tcall *8(%%ebp)\n" );
fprintf( outfile, "\tcall *8(%%ebp)\n" );
if (needs_ldt) output( "\tmovl -4(%%ebp),%%esi\n" );
if (needs_ldt) fprintf( outfile, "\tmovl -4(%%ebp),%%esi\n" );
if (odp->flags & FLAG_RET16) fprintf( outfile, "\tmovzwl %%ax,%%eax\n" );
output( "\tleave\n" );
output( "\tret\n" );
output_function_size( name );
fprintf( outfile, "\tleave\n" );
fprintf( outfile, "\tret\n" );
output_function_size( outfile, name );
}
@ -450,72 +450,72 @@ static int sort_func_list( ORDDEF **list, int count,
*
* Output the dll initialization code.
*/
static void output_init_code( const DLLSPEC *spec, const char *header_name )
static void output_init_code( FILE *outfile, const DLLSPEC *spec, const char *header_name )
{
char name[80];
sprintf( name, ".L__wine_spec_%s_init", make_c_identifier(spec->dll_name) );
output( "\n/* dll initialization code */\n\n" );
output( "\t.text\n" );
output( "\t.align 4\n" );
output( "\t%s\n", func_declaration(name) );
output( "%s:\n", name );
output( "subl $4,%%esp\n" );
fprintf( outfile, "\n/* dll initialization code */\n\n" );
fprintf( outfile, "\t.text\n" );
fprintf( outfile, "\t.align 4\n" );
fprintf( outfile, "\t%s\n", func_declaration(name) );
fprintf( outfile, "%s:\n", name );
fprintf( outfile, "subl $4,%%esp\n" );
if (UsePIC)
{
output( "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") );
output( "1:\tleal .L__wine_spec_file_name-1b(%%eax),%%ecx\n" );
output( "\tpushl %%ecx\n" );
output( "\tleal %s-1b(%%eax),%%ecx\n", header_name );
output( "\tpushl %%ecx\n" );
fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") );
fprintf( outfile, "1:\tleal .L__wine_spec_file_name-1b(%%eax),%%ecx\n" );
fprintf( outfile, "\tpushl %%ecx\n" );
fprintf( outfile, "\tleal %s-1b(%%eax),%%ecx\n", header_name );
fprintf( outfile, "\tpushl %%ecx\n" );
}
else
{
output( "\tpushl $.L__wine_spec_file_name\n" );
output( "\tpushl $%s\n", header_name );
fprintf( outfile, "\tpushl $.L__wine_spec_file_name\n" );
fprintf( outfile, "\tpushl $%s\n", header_name );
}
output( "\tcall %s\n", asm_name("__wine_dll_register_16") );
output( "\taddl $12,%%esp\n" );
output( "\tret\n" );
output_function_size( name );
fprintf( outfile, "\tcall %s\n", asm_name("__wine_dll_register_16") );
fprintf( outfile, "\taddl $12,%%esp\n" );
fprintf( outfile, "\tret\n" );
output_function_size( outfile, name );
sprintf( name, ".L__wine_spec_%s_fini", make_c_identifier(spec->dll_name) );
output( "\t.align 4\n" );
output( "\t%s\n", func_declaration(name) );
output( "%s:\n", name );
output( "subl $8,%%esp\n" );
fprintf( outfile, "\t.align 4\n" );
fprintf( outfile, "\t%s\n", func_declaration(name) );
fprintf( outfile, "%s:\n", name );
fprintf( outfile, "subl $8,%%esp\n" );
if (UsePIC)
{
output( "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") );
output( "1:\tleal %s-1b(%%eax),%%ecx\n", header_name );
output( "\tpushl %%ecx\n" );
fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") );
fprintf( outfile, "1:\tleal %s-1b(%%eax),%%ecx\n", header_name );
fprintf( outfile, "\tpushl %%ecx\n" );
}
else
{
output( "\tpushl $%s\n", header_name );
fprintf( outfile, "\tpushl $%s\n", header_name );
}
output( "\tcall %s\n", asm_name("__wine_dll_unregister_16") );
output( "\taddl $12,%%esp\n" );
output( "\tret\n" );
output_function_size( name );
fprintf( outfile, "\tcall %s\n", asm_name("__wine_dll_unregister_16") );
fprintf( outfile, "\taddl $12,%%esp\n" );
fprintf( outfile, "\tret\n" );
output_function_size( outfile, name );
if (target_platform == PLATFORM_APPLE)
{
output( "\t.mod_init_func\n" );
output( "\t.align %d\n", get_alignment(4) );
output( "\t.long .L__wine_spec_%s_init\n", make_c_identifier(spec->dll_name) );
output( "\t.mod_term_func\n" );
output( "\t.align %d\n", get_alignment(4) );
output( "\t.long .L__wine_spec_%s_fini\n", make_c_identifier(spec->dll_name) );
fprintf( outfile, "\t.mod_init_func\n" );
fprintf( outfile, "\t.align %d\n", get_alignment(4) );
fprintf( outfile, "\t.long .L__wine_spec_%s_init\n", make_c_identifier(spec->dll_name) );
fprintf( outfile, "\t.mod_term_func\n" );
fprintf( outfile, "\t.align %d\n", get_alignment(4) );
fprintf( outfile, "\t.long .L__wine_spec_%s_fini\n", make_c_identifier(spec->dll_name) );
}
else
{
output( "\t.section \".init\",\"ax\"\n" );
output( "\tcall .L__wine_spec_%s_init\n", make_c_identifier(spec->dll_name) );
output( "\t.section \".fini\",\"ax\"\n" );
output( "\tcall .L__wine_spec_%s_fini\n", make_c_identifier(spec->dll_name) );
fprintf( outfile, "\t.section \".init\",\"ax\"\n" );
fprintf( outfile, "\tcall .L__wine_spec_%s_init\n", make_c_identifier(spec->dll_name) );
fprintf( outfile, "\t.section \".fini\",\"ax\"\n" );
fprintf( outfile, "\tcall .L__wine_spec_%s_fini\n", make_c_identifier(spec->dll_name) );
}
}
@ -525,7 +525,7 @@ static void output_init_code( const DLLSPEC *spec, const char *header_name )
*
* Build a Win16 assembly file from a spec file.
*/
void BuildSpec16File( DLLSPEC *spec )
void BuildSpec16File( FILE *outfile, DLLSPEC *spec )
{
ORDDEF **typelist;
int i, j, nb_funcs;
@ -533,7 +533,7 @@ void BuildSpec16File( DLLSPEC *spec )
/* File header */
output_standard_file_header();
output_standard_file_header( outfile );
if (!spec->dll_name) /* set default name from file name */
{
@ -558,135 +558,135 @@ void BuildSpec16File( DLLSPEC *spec )
/* Output the module structure */
sprintf( header_name, "__wine_spec_%s_dos_header", make_c_identifier(spec->dll_name) );
output( "\n/* module data */\n\n" );
output( "\t.data\n" );
output( "\t.align %d\n", get_alignment(4) );
output( "%s:\n", header_name );
output( "\t%s 0x%04x\n", get_asm_short_keyword(), /* e_magic */
fprintf( outfile, "\n/* module data */\n\n" );
fprintf( outfile, "\t.data\n" );
fprintf( outfile, "\t.align %d\n", get_alignment(4) );
fprintf( outfile, "%s:\n", header_name );
fprintf( outfile, "\t%s 0x%04x\n", get_asm_short_keyword(), /* e_magic */
IMAGE_DOS_SIGNATURE );
output( "\t%s 0\n", get_asm_short_keyword() ); /* e_cblp */
output( "\t%s 0\n", get_asm_short_keyword() ); /* e_cp */
output( "\t%s 0\n", get_asm_short_keyword() ); /* e_crlc */
output( "\t%s 0\n", get_asm_short_keyword() ); /* e_cparhdr */
output( "\t%s 0\n", get_asm_short_keyword() ); /* e_minalloc */
output( "\t%s 0\n", get_asm_short_keyword() ); /* e_maxalloc */
output( "\t%s 0\n", get_asm_short_keyword() ); /* e_ss */
output( "\t%s 0\n", get_asm_short_keyword() ); /* e_sp */
output( "\t%s 0\n", get_asm_short_keyword() ); /* e_csum */
output( "\t%s 0\n", get_asm_short_keyword() ); /* e_ip */
output( "\t%s 0\n", get_asm_short_keyword() ); /* e_cs */
output( "\t%s 0\n", get_asm_short_keyword() ); /* e_lfarlc */
output( "\t%s 0\n", get_asm_short_keyword() ); /* e_ovno */
output( "\t%s 0,0,0,0\n", get_asm_short_keyword() ); /* e_res */
output( "\t%s 0\n", get_asm_short_keyword() ); /* e_oemid */
output( "\t%s 0\n", get_asm_short_keyword() ); /* e_oeminfo */
output( "\t%s 0,0,0,0,0,0,0,0,0,0\n", get_asm_short_keyword() ); /* e_res2 */
output( "\t.long .L__wine_spec_ne_header-%s\n", header_name ); /* e_lfanew */
fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* e_cblp */
fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* e_cp */
fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* e_crlc */
fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* e_cparhdr */
fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* e_minalloc */
fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* e_maxalloc */
fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* e_ss */
fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* e_sp */
fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* e_csum */
fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* e_ip */
fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* e_cs */
fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* e_lfarlc */
fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* e_ovno */
fprintf( outfile, "\t%s 0,0,0,0\n", get_asm_short_keyword() ); /* e_res */
fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* e_oemid */
fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* e_oeminfo */
fprintf( outfile, "\t%s 0,0,0,0,0,0,0,0,0,0\n", get_asm_short_keyword() ); /* e_res2 */
fprintf( outfile, "\t.long .L__wine_spec_ne_header-%s\n", header_name ); /* e_lfanew */
output( ".L__wine_spec_ne_header:\n" );
output( "\t%s 0x%04x\n", get_asm_short_keyword(), /* ne_magic */
fprintf( outfile, ".L__wine_spec_ne_header:\n" );
fprintf( outfile, "\t%s 0x%04x\n", get_asm_short_keyword(), /* ne_magic */
IMAGE_OS2_SIGNATURE );
output( "\t.byte 0\n" ); /* ne_ver */
output( "\t.byte 0\n" ); /* ne_rev */
output( "\t%s .L__wine_spec_ne_enttab-.L__wine_spec_ne_header\n", /* ne_enttab */
fprintf( outfile, "\t.byte 0\n" ); /* ne_ver */
fprintf( outfile, "\t.byte 0\n" ); /* ne_rev */
fprintf( outfile, "\t%s .L__wine_spec_ne_enttab-.L__wine_spec_ne_header\n", /* ne_enttab */
get_asm_short_keyword() );
output( "\t%s .L__wine_spec_ne_enttab_end-.L__wine_spec_ne_enttab\n", /* ne_cbenttab */
fprintf( outfile, "\t%s .L__wine_spec_ne_enttab_end-.L__wine_spec_ne_enttab\n", /* ne_cbenttab */
get_asm_short_keyword() );
output( "\t.long 0\n" ); /* ne_crc */
output( "\t%s 0x%04x\n", get_asm_short_keyword(), /* ne_flags */
fprintf( outfile, "\t.long 0\n" ); /* ne_crc */
fprintf( outfile, "\t%s 0x%04x\n", get_asm_short_keyword(), /* ne_flags */
NE_FFLAGS_SINGLEDATA | NE_FFLAGS_LIBMODULE );
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 */
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 */
output( "\t%s .L__wine_spec_ne_segtab-.L__wine_spec_ne_header\n", /* ne_segtab */
fprintf( outfile, "\t%s 2\n", get_asm_short_keyword() ); /* ne_autodata */
fprintf( outfile, "\t%s %u\n", get_asm_short_keyword(), spec->heap_size ); /* ne_heap */
fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* ne_stack */
fprintf( outfile, "\t.long 0\n" ); /* ne_csip */
fprintf( outfile, "\t.long 0\n" ); /* ne_sssp */
fprintf( outfile, "\t%s 2\n", get_asm_short_keyword() ); /* ne_cseg */
fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* ne_cmod */
fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* ne_cbnrestab */
fprintf( outfile, "\t%s .L__wine_spec_ne_segtab-.L__wine_spec_ne_header\n", /* ne_segtab */
get_asm_short_keyword() );
output( "\t%s .L__wine_spec_ne_rsrctab-.L__wine_spec_ne_header\n", /* ne_rsrctab */
fprintf( outfile, "\t%s .L__wine_spec_ne_rsrctab-.L__wine_spec_ne_header\n", /* ne_rsrctab */
get_asm_short_keyword() );
output( "\t%s .L__wine_spec_ne_restab-.L__wine_spec_ne_header\n", /* ne_restab */
fprintf( outfile, "\t%s .L__wine_spec_ne_restab-.L__wine_spec_ne_header\n", /* ne_restab */
get_asm_short_keyword() );
output( "\t%s .L__wine_spec_ne_modtab-.L__wine_spec_ne_header\n", /* ne_modtab */
fprintf( outfile, "\t%s .L__wine_spec_ne_modtab-.L__wine_spec_ne_header\n", /* ne_modtab */
get_asm_short_keyword() );
output( "\t%s .L__wine_spec_ne_imptab-.L__wine_spec_ne_header\n", /* ne_imptab */
fprintf( outfile, "\t%s .L__wine_spec_ne_imptab-.L__wine_spec_ne_header\n", /* ne_imptab */
get_asm_short_keyword() );
output( "\t.long 0\n" ); /* ne_nrestab */
output( "\t%s 0\n", get_asm_short_keyword() ); /* ne_cmovent */
output( "\t%s 0\n", get_asm_short_keyword() ); /* ne_align */
output( "\t%s 0\n", get_asm_short_keyword() ); /* ne_cres */
output( "\t.byte 0x%02x\n", NE_OSFLAGS_WINDOWS ); /* ne_exetyp */
output( "\t.byte 0x%02x\n", NE_AFLAGS_FASTLOAD ); /* ne_flagsothers */
output( "\t%s 0\n", get_asm_short_keyword() ); /* ne_pretthunks */
output( "\t%s 0\n", get_asm_short_keyword() ); /* ne_psegrefbytes */
output( "\t%s 0\n", get_asm_short_keyword() ); /* ne_swaparea */
output( "\t%s 0\n", get_asm_short_keyword() ); /* ne_expver */
fprintf( outfile, "\t.long 0\n" ); /* ne_nrestab */
fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* ne_cmovent */
fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* ne_align */
fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* ne_cres */
fprintf( outfile, "\t.byte 0x%02x\n", NE_OSFLAGS_WINDOWS ); /* ne_exetyp */
fprintf( outfile, "\t.byte 0x%02x\n", NE_AFLAGS_FASTLOAD ); /* ne_flagsothers */
fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* ne_pretthunks */
fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* ne_psegrefbytes */
fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* ne_swaparea */
fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* ne_expver */
/* segment table */
output( "\n.L__wine_spec_ne_segtab:\n" );
fprintf( outfile, "\n.L__wine_spec_ne_segtab:\n" );
/* code segment entry */
output( "\t%s .L__wine_spec_code_segment-%s\n", /* filepos */
fprintf( outfile, "\t%s .L__wine_spec_code_segment-%s\n", /* filepos */
get_asm_short_keyword(), header_name );
output( "\t%s .L__wine_spec_code_segment_end-.L__wine_spec_code_segment\n", /* size */
fprintf( outfile, "\t%s .L__wine_spec_code_segment_end-.L__wine_spec_code_segment\n", /* size */
get_asm_short_keyword() );
output( "\t%s 0x%04x\n", get_asm_short_keyword(), NE_SEGFLAGS_32BIT ); /* flags */
output( "\t%s .L__wine_spec_code_segment_end-.L__wine_spec_code_segment\n", /* minsize */
fprintf( outfile, "\t%s 0x%04x\n", get_asm_short_keyword(), NE_SEGFLAGS_32BIT ); /* flags */
fprintf( outfile, "\t%s .L__wine_spec_code_segment_end-.L__wine_spec_code_segment\n", /* minsize */
get_asm_short_keyword() );
/* data segment entry */
output( "\t%s .L__wine_spec_data_segment-%s\n", /* filepos */
fprintf( outfile, "\t%s .L__wine_spec_data_segment-%s\n", /* filepos */
get_asm_short_keyword(), header_name );
output( "\t%s .L__wine_spec_data_segment_end-.L__wine_spec_data_segment\n", /* size */
fprintf( outfile, "\t%s .L__wine_spec_data_segment_end-.L__wine_spec_data_segment\n", /* size */
get_asm_short_keyword() );
output( "\t%s 0x%04x\n", get_asm_short_keyword(), NE_SEGFLAGS_DATA ); /* flags */
output( "\t%s .L__wine_spec_data_segment_end-.L__wine_spec_data_segment\n", /* minsize */
fprintf( outfile, "\t%s 0x%04x\n", get_asm_short_keyword(), NE_SEGFLAGS_DATA ); /* flags */
fprintf( outfile, "\t%s .L__wine_spec_data_segment_end-.L__wine_spec_data_segment\n", /* minsize */
get_asm_short_keyword() );
/* resource directory */
output_res16_directory( spec, header_name );
output_res16_directory( outfile, spec, header_name );
/* resident names table */
output( "\n\t.align %d\n", get_alignment(2) );
output( ".L__wine_spec_ne_restab:\n" );
output_resident_name( spec->dll_name, 0 );
fprintf( outfile, "\n\t.align %d\n", get_alignment(2) );
fprintf( outfile, ".L__wine_spec_ne_restab:\n" );
output_resident_name( outfile, spec->dll_name, 0 );
for (i = 1; i <= spec->limit; i++)
{
ORDDEF *odp = spec->ordinals[i];
if (!odp || !odp->name[0]) continue;
output_resident_name( odp->name, i );
output_resident_name( outfile, odp->name, i );
}
output( "\t.byte 0\n" );
fprintf( outfile, "\t.byte 0\n" );
/* imported names table */
output( "\n\t.align %d\n", get_alignment(2) );
output( ".L__wine_spec_ne_modtab:\n" );
output( ".L__wine_spec_ne_imptab:\n" );
output( "\t.byte 0,0\n" );
fprintf( outfile, "\n\t.align %d\n", get_alignment(2) );
fprintf( outfile, ".L__wine_spec_ne_modtab:\n" );
fprintf( outfile, ".L__wine_spec_ne_imptab:\n" );
fprintf( outfile, "\t.byte 0,0\n" );
/* entry table */
output( "\n.L__wine_spec_ne_enttab:\n" );
output_entry_table( spec );
output( ".L__wine_spec_ne_enttab_end:\n" );
fprintf( outfile, "\n.L__wine_spec_ne_enttab:\n" );
output_entry_table( outfile, spec );
fprintf( outfile, ".L__wine_spec_ne_enttab_end:\n" );
/* code segment */
output( "\n\t.align %d\n", get_alignment(2) );
output( ".L__wine_spec_code_segment:\n" );
fprintf( outfile, "\n\t.align %d\n", get_alignment(2) );
fprintf( outfile, ".L__wine_spec_code_segment:\n" );
for ( i = 0; i < nb_funcs; i++ )
{
unsigned int arg_types[2];
int nop_words, argsize = 0;
int j, nop_words, argsize = 0;
if ( typelist[i]->type == TYPE_PASCAL )
argsize = get_function_argsize( typelist[i] );
@ -709,9 +709,9 @@ void BuildSpec16File( DLLSPEC *spec )
}
if (typelist[i]->type == TYPE_VARARGS) arg_types[j / 10] |= ARG_VARARG << (3 * (j % 10));
output( ".L__wine_spec_callfrom16_%s:\n", get_callfrom16_name(typelist[i]) );
output( "\tpushl $.L__wine_spec_call16_%s\n", get_relay_name(typelist[i]) );
output( "\tlcall $0,$0\n" );
fprintf( outfile, ".L__wine_spec_callfrom16_%s:\n", get_callfrom16_name(typelist[i]) );
fprintf( outfile, "\tpushl $.L__wine_spec_call16_%s\n", get_relay_name(typelist[i]) );
fprintf( outfile, "\tlcall $0,$0\n" );
if (typelist[i]->flags & FLAG_REGISTER)
{
@ -719,91 +719,90 @@ void BuildSpec16File( DLLSPEC *spec )
}
else if (typelist[i]->flags & FLAG_RET16)
{
output( "\torw %%ax,%%ax\n" );
output( "\tnop\n" ); /* so that the lretw is aligned */
fprintf( outfile, "\torw %%ax,%%ax\n" );
fprintf( outfile, "\tnop\n" ); /* so that the lretw is aligned */
nop_words = 2;
}
else
{
output( "\tshld $16,%%eax,%%edx\n" );
output( "\torl %%eax,%%eax\n" );
fprintf( outfile, "shld $16,%%eax,%%edx\n" );
fprintf( outfile, "orl %%eax,%%eax\n" );
nop_words = 1;
}
if (argsize)
{
output( "\tlretw $%u\n", argsize );
fprintf( outfile, "lretw $%u\n", argsize );
nop_words--;
}
else output( "\tlretw\n" );
else fprintf( outfile, "lretw\n" );
if (nop_words) output( "\t%s\n", nop_sequence[nop_words-1] );
if (nop_words) fprintf( outfile, "\t%s\n", nop_sequence[nop_words-1] );
/* the movl is here so that the code contains only valid instructions, */
/* it's never actually executed, we only care about the arg_types[] values */
output( "\t%s 0x86c7\n", get_asm_short_keyword() );
output( "\t.long 0x%08x,0x%08x\n", arg_types[0], arg_types[1] );
fprintf( outfile, "\t%s 0x86c7\n", get_asm_short_keyword() );
fprintf( outfile, "\t.long 0x%08x,0x%08x\n", arg_types[0], arg_types[1] );
}
for (i = 0; i <= spec->limit; i++)
{
ORDDEF *odp = spec->ordinals[i];
if (!odp || !is_function( odp )) continue;
output( ".L__wine_%s_%u:\n", make_c_identifier(spec->dll_name), i );
output( "\tpushw %%bp\n" );
output( "\tpushl $%s\n",
fprintf( outfile, ".L__wine_%s_%u:\n", make_c_identifier(spec->dll_name), i );
fprintf( outfile, "\tpushw %%bp\n" );
fprintf( outfile, "\tpushl $%s\n",
asm_name( odp->type == TYPE_STUB ? get_stub_name( odp, spec ) : odp->link_name ));
output( "\tcallw .L__wine_spec_callfrom16_%s\n", get_callfrom16_name( odp ) );
fprintf( outfile, "\tcallw .L__wine_spec_callfrom16_%s\n", get_callfrom16_name( odp ) );
}
output( ".L__wine_spec_code_segment_end:\n" );
fprintf( outfile, ".L__wine_spec_code_segment_end:\n" );
/* data segment */
output( "\n.L__wine_spec_data_segment:\n" );
output( "\t.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n" ); /* instance data */
fprintf( outfile, "\n.L__wine_spec_data_segment:\n" );
fprintf( outfile, "\t.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n" ); /* instance data */
for (i = 0; i <= spec->limit; i++)
{
ORDDEF *odp = spec->ordinals[i];
if (!odp || odp->type != TYPE_VARIABLE) continue;
output( ".L__wine_%s_%u:\n", make_c_identifier(spec->dll_name), i );
output( "\t.long " );
fprintf( outfile, ".L__wine_%s_%u:\n", make_c_identifier(spec->dll_name), i );
fprintf( outfile, "\t.long " );
for (j = 0; j < odp->u.var.n_values-1; j++)
output( "0x%08x,", odp->u.var.values[j] );
output( "0x%08x\n", odp->u.var.values[j] );
fprintf( outfile, "0x%08x,", odp->u.var.values[j] );
fprintf( outfile, "0x%08x\n", odp->u.var.values[j] );
}
output( ".L__wine_spec_data_segment_end:\n" );
fprintf( outfile, ".L__wine_spec_data_segment_end:\n" );
/* resource data */
if (spec->nb_resources)
{
output( "\n.L__wine_spec_resource_data:\n" );
output_res16_data( spec );
fprintf( outfile, "\n.L__wine_spec_resource_data:\n" );
output_res16_data( outfile, spec );
}
output( "\t.byte 0\n" ); /* make sure the last symbol points to something */
fprintf( outfile, "\t.byte 0\n" ); /* make sure the last symbol points to something */
/* relay functions */
nb_funcs = sort_func_list( typelist, nb_funcs, relay_type_compare );
if (nb_funcs)
{
output( "\n/* relay functions */\n\n" );
output( "\t.text\n" );
for ( i = 0; i < nb_funcs; i++ ) output_call16_function( typelist[i] );
output( "\t.data\n" );
output( "wine_ldt_copy_ptr:\n" );
output( "\t.long %s\n", asm_name("wine_ldt_copy") );
fprintf( outfile, "\n/* relay functions */\n\n" );
fprintf( outfile, "\t.text\n" );
for ( i = 0; i < nb_funcs; i++ ) output_call16_function( outfile, typelist[i] );
fprintf( outfile, "\t.data\n" );
fprintf( outfile, "wine_ldt_copy_ptr:\n" );
fprintf( outfile, "\t.long %s\n", asm_name("wine_ldt_copy") );
}
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 );
fprintf( outfile, "\n\t%s\n", get_asm_string_section() );
fprintf( outfile, ".L__wine_spec_file_name:\n" );
fprintf( outfile, "\t%s \"%s\"\n", get_asm_string_keyword(), spec->file_name );
output_stubs( spec );
output_get_pc_thunk();
output_init_code( spec, header_name );
output_gnu_stack_note();
output_stubs( outfile, spec );
output_get_pc_thunk( outfile );
output_init_code( outfile, spec, header_name );
free( typelist );
}

View file

@ -19,11 +19,10 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "wine/port.h"
#include <assert.h>
#include <ctype.h>
@ -31,7 +30,10 @@
#include <string.h>
#include "winglue.h"
//#include "wine/exception.h"
#define EXCEPTION_WINE_STUB 0x80000100 /* stub entry point called */
#define EH_NONCONTINUABLE 0x01
#include "build.h"
@ -50,7 +52,7 @@ static inline int needs_relay( const ORDDEF *odp )
/* check if dll will output relay thunks */
int has_relays( DLLSPEC *spec )
{
int i;
unsigned int i;
if (target_cpu != CPU_x86) return 0;
@ -62,36 +64,57 @@ int has_relays( DLLSPEC *spec )
return 0;
}
/*******************************************************************
* make_internal_name
*
* Generate an internal name for an entry point. Used for stubs etc.
*/
static const char *make_internal_name( const ORDDEF *odp, DLLSPEC *spec, const char *prefix )
{
static char buffer[256];
if (odp->name || odp->export_name)
{
char *p;
sprintf( buffer, "__wine_%s_%s_%s", prefix, spec->file_name,
odp->name ? odp->name : odp->export_name );
/* make sure name is a legal C identifier */
for (p = buffer; *p; p++) if (!isalnum(*p) && *p != '_') break;
if (!*p) return buffer;
}
sprintf( buffer, "__wine_%s_%s_%d", prefix, make_c_identifier(spec->file_name), odp->ordinal );
return buffer;
}
/*******************************************************************
* output_relay_debug
*
* Output entry points for relay debugging
*/
static void output_relay_debug( DLLSPEC *spec )
static void output_relay_debug( FILE *outfile, DLLSPEC *spec )
{
int i;
unsigned int j, args, flags;
unsigned int i, j, args, flags;
/* first the table of entry point offsets */
output( "\t%s\n", get_asm_rodata_section() );
output( "\t.align %d\n", get_alignment(4) );
output( ".L__wine_spec_relay_entry_point_offsets:\n" );
fprintf( outfile, "\t%s\n", get_asm_rodata_section() );
fprintf( outfile, "\t.align %d\n", get_alignment(4) );
fprintf( outfile, ".L__wine_spec_relay_entry_point_offsets:\n" );
for (i = spec->base; i <= spec->limit; i++)
{
ORDDEF *odp = spec->ordinals[i];
if (needs_relay( odp ))
output( "\t.long .L__wine_spec_relay_entry_point_%d-__wine_spec_relay_entry_points\n", i );
fprintf( outfile, "\t.long .L__wine_spec_relay_entry_point_%d-__wine_spec_relay_entry_points\n", i );
else
output( "\t.long 0\n" );
fprintf( outfile, "\t.long 0\n" );
}
/* then the table of argument types */
output( "\t.align %d\n", get_alignment(4) );
output( ".L__wine_spec_relay_arg_types:\n" );
fprintf( outfile, "\t.align %d\n", get_alignment(4) );
fprintf( outfile, ".L__wine_spec_relay_arg_types:\n" );
for (i = spec->base; i <= spec->limit; i++)
{
@ -106,14 +129,14 @@ static void output_relay_debug( DLLSPEC *spec )
if (odp->u.func.arg_types[j] == 'W') mask |= 2<< (j*2);
}
}
output( "\t.long 0x%08x\n", mask );
fprintf( outfile, "\t.long 0x%08x\n", mask );
}
/* then the relay thunks */
output( "\t.text\n" );
output( "__wine_spec_relay_entry_points:\n" );
output( "\tnop\n" ); /* to avoid 0 offset */
fprintf( outfile, "\t.text\n" );
fprintf( outfile, "__wine_spec_relay_entry_points:\n" );
fprintf( outfile, "\tnop\n" ); /* to avoid 0 offset */
for (i = spec->base; i <= spec->limit; i++)
{
@ -121,39 +144,39 @@ static void output_relay_debug( DLLSPEC *spec )
if (!needs_relay( odp )) continue;
output( "\t.align %d\n", get_alignment(4) );
output( ".L__wine_spec_relay_entry_point_%d:\n", i );
fprintf( outfile, "\t.align %d\n", get_alignment(4) );
fprintf( outfile, ".L__wine_spec_relay_entry_point_%d:\n", i );
if (odp->flags & FLAG_REGISTER)
output( "\tpushl %%eax\n" );
fprintf( outfile, "\tpushl %%eax\n" );
else
output( "\tpushl %%esp\n" );
fprintf( outfile, "\tpushl %%esp\n" );
args = strlen(odp->u.func.arg_types);
flags = 0;
if (odp->flags & FLAG_RET64) flags |= 1;
if (odp->type == TYPE_STDCALL) flags |= 2;
output( "\tpushl $%u\n", (flags << 24) | (args << 16) | (i - spec->base) );
fprintf( outfile, "\tpushl $%u\n", (flags << 24) | (args << 16) | (i - spec->base) );
if (UsePIC)
{
output( "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") );
output( "1:\tleal .L__wine_spec_relay_descr-1b(%%eax),%%eax\n" );
fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") );
fprintf( outfile, "1:\tleal .L__wine_spec_relay_descr-1b(%%eax),%%eax\n" );
}
else output( "\tmovl $.L__wine_spec_relay_descr,%%eax\n" );
output( "\tpushl %%eax\n" );
else fprintf( outfile, "\tmovl $.L__wine_spec_relay_descr,%%eax\n" );
fprintf( outfile, "\tpushl %%eax\n" );
if (odp->flags & FLAG_REGISTER)
{
output( "\tcall *8(%%eax)\n" );
fprintf( outfile, "\tcall *8(%%eax)\n" );
}
else
{
output( "\tcall *4(%%eax)\n" );
fprintf( outfile, "\tcall *4(%%eax)\n" );
if (odp->type == TYPE_STDCALL)
output( "\tret $%u\n", args * get_ptr_size() );
fprintf( outfile, "\tret $%u\n", args * get_ptr_size() );
else
output( "\tret\n" );
fprintf( outfile, "\tret\n" );
}
}
}
@ -163,46 +186,46 @@ static void output_relay_debug( DLLSPEC *spec )
*
* Output the export table for a Win32 module.
*/
static void output_exports( DLLSPEC *spec )
static void output_exports( FILE *outfile, DLLSPEC *spec )
{
int i, fwd_size = 0;
int nr_exports = spec->base <= spec->limit ? spec->limit - spec->base + 1 : 0;
if (!nr_exports) return;
output( "\n/* export table */\n\n" );
output( "\t.data\n" );
output( "\t.align %d\n", get_alignment(4) );
output( ".L__wine_spec_exports:\n" );
fprintf( outfile, "\n/* export table */\n\n" );
fprintf( outfile, "\t.data\n" );
fprintf( outfile, "\t.align %d\n", get_alignment(4) );
fprintf( outfile, ".L__wine_spec_exports:\n" );
/* export directory header */
output( "\t.long 0\n" ); /* Characteristics */
output( "\t.long 0\n" ); /* TimeDateStamp */
output( "\t.long 0\n" ); /* MajorVersion/MinorVersion */
output( "\t.long .L__wine_spec_exp_names-.L__wine_spec_rva_base\n" ); /* Name */
output( "\t.long %u\n", spec->base ); /* Base */
output( "\t.long %u\n", nr_exports ); /* NumberOfFunctions */
output( "\t.long %u\n", spec->nb_names ); /* NumberOfNames */
output( "\t.long .L__wine_spec_exports_funcs-.L__wine_spec_rva_base\n" ); /* AddressOfFunctions */
fprintf( outfile, "\t.long 0\n" ); /* Characteristics */
fprintf( outfile, "\t.long 0\n" ); /* TimeDateStamp */
fprintf( outfile, "\t.long 0\n" ); /* MajorVersion/MinorVersion */
fprintf( outfile, "\t.long .L__wine_spec_exp_names-.L__wine_spec_rva_base\n" ); /* Name */
fprintf( outfile, "\t.long %u\n", spec->base ); /* Base */
fprintf( outfile, "\t.long %u\n", nr_exports ); /* NumberOfFunctions */
fprintf( outfile, "\t.long %u\n", spec->nb_names ); /* NumberOfNames */
fprintf( outfile, "\t.long .L__wine_spec_exports_funcs-.L__wine_spec_rva_base\n" ); /* AddressOfFunctions */
if (spec->nb_names)
{
output( "\t.long .L__wine_spec_exp_name_ptrs-.L__wine_spec_rva_base\n" ); /* AddressOfNames */
output( "\t.long .L__wine_spec_exp_ordinals-.L__wine_spec_rva_base\n" ); /* AddressOfNameOrdinals */
fprintf( outfile, "\t.long .L__wine_spec_exp_name_ptrs-.L__wine_spec_rva_base\n" ); /* AddressOfNames */
fprintf( outfile, "\t.long .L__wine_spec_exp_ordinals-.L__wine_spec_rva_base\n" ); /* AddressOfNameOrdinals */
}
else
{
output( "\t.long 0\n" ); /* AddressOfNames */
output( "\t.long 0\n" ); /* AddressOfNameOrdinals */
fprintf( outfile, "\t.long 0\n" ); /* AddressOfNames */
fprintf( outfile, "\t.long 0\n" ); /* AddressOfNameOrdinals */
}
/* output the function pointers */
output( "\n.L__wine_spec_exports_funcs:\n" );
fprintf( outfile, "\n.L__wine_spec_exports_funcs:\n" );
for (i = spec->base; i <= spec->limit; i++)
{
ORDDEF *odp = spec->ordinals[i];
if (!odp) output( "\t%s 0\n", get_asm_ptr_keyword() );
if (!odp) fprintf( outfile, "\t.long 0\n" );
else switch(odp->type)
{
case TYPE_EXTERN:
@ -211,21 +234,21 @@ static void output_exports( DLLSPEC *spec )
case TYPE_CDECL:
if (odp->flags & FLAG_FORWARD)
{
output( "\t%s .L__wine_spec_forwards+%u\n", get_asm_ptr_keyword(), fwd_size );
fprintf( outfile, "\t%s .L__wine_spec_forwards+%u\n", get_asm_ptr_keyword(), fwd_size );
fwd_size += strlen(odp->link_name) + 1;
}
else if (odp->flags & FLAG_EXT_LINK)
{
output( "\t%s %s_%s\n",
fprintf( outfile, "\t%s %s_%s\n",
get_asm_ptr_keyword(), asm_name("__wine_spec_ext_link"), odp->link_name );
}
else
{
output( "\t%s %s\n", get_asm_ptr_keyword(), asm_name(odp->link_name) );
fprintf( outfile, "\t%s %s\n", get_asm_ptr_keyword(), asm_name(odp->link_name) );
}
break;
case TYPE_STUB:
output( "\t%s %s\n", get_asm_ptr_keyword(),
fprintf( outfile, "\t%s %s\n", get_asm_ptr_keyword(),
asm_name( get_stub_name( odp, spec )) );
break;
default:
@ -239,68 +262,68 @@ static void output_exports( DLLSPEC *spec )
int namepos = strlen(spec->file_name) + 1;
output( "\n.L__wine_spec_exp_name_ptrs:\n" );
fprintf( outfile, "\n.L__wine_spec_exp_name_ptrs:\n" );
for (i = 0; i < spec->nb_names; i++)
{
output( "\t.long .L__wine_spec_exp_names+%u-.L__wine_spec_rva_base\n", namepos );
fprintf( outfile, "\t.long .L__wine_spec_exp_names+%u-.L__wine_spec_rva_base\n", namepos );
namepos += strlen(spec->names[i]->name) + 1;
}
/* output the function ordinals */
output( "\n.L__wine_spec_exp_ordinals:\n" );
fprintf( outfile, "\n.L__wine_spec_exp_ordinals:\n" );
for (i = 0; i < spec->nb_names; i++)
{
output( "\t%s %d\n",
fprintf( outfile, "\t%s %d\n",
get_asm_short_keyword(), spec->names[i]->ordinal - spec->base );
}
if (spec->nb_names % 2)
{
output( "\t%s 0\n", get_asm_short_keyword() );
fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() );
}
}
/* output the export name strings */
output( "\n.L__wine_spec_exp_names:\n" );
output( "\t%s \"%s\"\n", get_asm_string_keyword(), spec->file_name );
fprintf( outfile, "\n.L__wine_spec_exp_names:\n" );
fprintf( outfile, "\t%s \"%s\"\n", get_asm_string_keyword(), spec->file_name );
for (i = 0; i < spec->nb_names; i++)
output( "\t%s \"%s\"\n",
fprintf( outfile, "\t%s \"%s\"\n",
get_asm_string_keyword(), spec->names[i]->name );
/* output forward strings */
if (fwd_size)
{
output( "\n.L__wine_spec_forwards:\n" );
fprintf( outfile, "\n.L__wine_spec_forwards:\n" );
for (i = spec->base; i <= spec->limit; i++)
{
ORDDEF *odp = spec->ordinals[i];
if (odp && (odp->flags & FLAG_FORWARD))
output( "\t%s \"%s\"\n", get_asm_string_keyword(), odp->link_name );
fprintf( outfile, "\t%s \"%s\"\n", get_asm_string_keyword(), odp->link_name );
}
}
output( "\t.align %d\n", get_alignment(get_ptr_size()) );
output( ".L__wine_spec_exports_end:\n" );
fprintf( outfile, "\t.align %d\n", get_alignment(get_ptr_size()) );
fprintf( outfile, ".L__wine_spec_exports_end:\n" );
/* output relays */
/* we only support relay debugging on i386 */
if (target_cpu != CPU_x86)
{
output( "\t%s 0\n", get_asm_ptr_keyword() );
fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() );
return;
}
output( ".L__wine_spec_relay_descr:\n" );
output( "\t%s 0xdeb90001\n", get_asm_ptr_keyword() ); /* magic */
output( "\t%s 0,0\n", get_asm_ptr_keyword() ); /* relay funcs */
output( "\t%s 0\n", get_asm_ptr_keyword() ); /* private data */
output( "\t%s __wine_spec_relay_entry_points\n", get_asm_ptr_keyword() );
output( "\t%s .L__wine_spec_relay_entry_point_offsets\n", get_asm_ptr_keyword() );
output( "\t%s .L__wine_spec_relay_arg_types\n", get_asm_ptr_keyword() );
fprintf( outfile, ".L__wine_spec_relay_descr:\n" );
fprintf( outfile, "\t%s 0xdeb90001\n", get_asm_ptr_keyword() ); /* magic */
fprintf( outfile, "\t%s 0,0\n", get_asm_ptr_keyword() ); /* relay funcs */
fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() ); /* private data */
fprintf( outfile, "\t%s __wine_spec_relay_entry_points\n", get_asm_ptr_keyword() );
fprintf( outfile, "\t%s .L__wine_spec_relay_entry_point_offsets\n", get_asm_ptr_keyword() );
fprintf( outfile, "\t%s .L__wine_spec_relay_arg_types\n", get_asm_ptr_keyword() );
output_relay_debug( spec );
output_relay_debug( outfile, spec );
}
@ -309,7 +332,7 @@ static void output_exports( DLLSPEC *spec )
*
* Output the functions for stub entry points
*/
static void output_stub_funcs( DLLSPEC *spec )
static void output_stub_funcs( FILE *outfile, DLLSPEC *spec )
{
int i;
@ -331,13 +354,13 @@ static void output_stub_funcs( DLLSPEC *spec )
{
const ORDDEF *odp = &spec->entry_points[i];
if (odp->type != TYPE_STUB) continue;
output( "void %s(void) ", (odp->name ? odp->name : odp->export_name) );
fprintf( outfile, "void %s(void) ", make_internal_name( odp, spec, "stub" ) );
if (odp->name)
output( "{ __wine_spec_unimplemented_stub(__wine_spec_file_name, \"%s\"); }\n", odp->name );
fprintf( outfile, "{ __wine_spec_unimplemented_stub(__wine_spec_file_name, \"%s\"); }\n", odp->name );
else if (odp->export_name)
output( "{ __wine_spec_unimplemented_stub(__wine_spec_file_name, \"%s\"); }\n", odp->export_name );
fprintf( outfile, "{ __wine_spec_unimplemented_stub(__wine_spec_file_name, \"%s\"); }\n", odp->export_name );
else
output( "{ __wine_spec_unimplemented_stub(__wine_spec_file_name, \"%d\"); }\n", odp->ordinal );
fprintf( outfile, "{ __wine_spec_unimplemented_stub(__wine_spec_file_name, \"%d\"); }\n", odp->ordinal );
}
}
@ -347,33 +370,33 @@ static void output_stub_funcs( DLLSPEC *spec )
*
* Output code for calling a dll constructor.
*/
static void output_asm_constructor( const char *constructor )
static void output_asm_constructor( FILE *outfile, const char *constructor )
{
if (target_platform == PLATFORM_APPLE)
{
/* Mach-O doesn't have an init section */
output( "\n\t.mod_init_func\n" );
output( "\t.align %d\n", get_alignment(4) );
output( "\t.long %s\n", asm_name(constructor) );
fprintf( outfile, "\n\t.mod_init_func\n" );
fprintf( outfile, "\t.align %d\n", get_alignment(4) );
fprintf( outfile, "\t.long %s\n", asm_name(constructor) );
}
else
{
output( "\n\t.section \".init\",\"ax\"\n" );
fprintf( outfile, "\n\t.section \".init\",\"ax\"\n" );
switch(target_cpu)
{
case CPU_x86:
case CPU_x86_64:
output( "\tcall %s\n", asm_name(constructor) );
fprintf( outfile, "\tcall %s\n", asm_name(constructor) );
break;
case CPU_SPARC:
output( "\tcall %s\n", asm_name(constructor) );
output( "\tnop\n" );
fprintf( outfile, "\tcall %s\n", asm_name(constructor) );
fprintf( outfile, "\tnop\n" );
break;
case CPU_ALPHA:
output( "\tjsr $26,%s\n", asm_name(constructor) );
fprintf( outfile, "\tjsr $26,%s\n", asm_name(constructor) );
break;
case CPU_POWERPC:
output( "\tbl %s\n", asm_name(constructor) );
fprintf( outfile, "\tbl %s\n", asm_name(constructor) );
break;
}
}
@ -385,32 +408,32 @@ static void output_asm_constructor( const char *constructor )
*
* Build a Win32 C file from a spec file.
*/
void BuildSpec32File( DLLSPEC *spec )
void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
{
int machine = 0;
unsigned int page_size = get_page_size();
resolve_imports( spec );
output_standard_file_header();
output_standard_file_header( outfile );
/* Reserve some space for the PE header */
output( "\t.text\n" );
output( "\t.align %d\n", get_alignment(page_size) );
output( "__wine_spec_pe_header:\n" );
fprintf( outfile, "\t.text\n" );
fprintf( outfile, "\t.align %d\n", get_alignment(page_size) );
fprintf( outfile, "__wine_spec_pe_header:\n" );
if (target_platform == PLATFORM_APPLE)
output( "\t.space 65536\n" );
fprintf( outfile, "\t.space 65536\n" );
else
output( "\t.skip 65536\n" );
fprintf( outfile, "\t.skip 65536\n" );
/* Output the NT header */
output( "\n\t.data\n" );
output( "\t.align %d\n", get_alignment(get_ptr_size()) );
output( "%s\n", asm_globl("__wine_spec_nt_header") );
output( ".L__wine_spec_rva_base:\n" );
fprintf( outfile, "\n\t.data\n" );
fprintf( outfile, "\t.align %d\n", get_alignment(get_ptr_size()) );
fprintf( outfile, "%s\n", asm_globl("__wine_spec_nt_header") );
fprintf( outfile, ".L__wine_spec_rva_base:\n" );
output( "\t.long 0x%04x\n", IMAGE_NT_SIGNATURE ); /* Signature */
fprintf( outfile, "\t.long 0x%04x\n", IMAGE_NT_SIGNATURE ); /* Signature */
switch(target_cpu)
{
case CPU_x86: machine = IMAGE_FILE_MACHINE_I386; break;
@ -419,105 +442,104 @@ void BuildSpec32File( DLLSPEC *spec )
case CPU_ALPHA: machine = IMAGE_FILE_MACHINE_ALPHA; break;
case CPU_SPARC: machine = IMAGE_FILE_MACHINE_UNKNOWN; break;
}
output( "\t%s 0x%04x\n", /* Machine */
fprintf( outfile, "\t%s 0x%04x\n", /* Machine */
get_asm_short_keyword(), machine );
output( "\t%s 0\n", /* NumberOfSections */
fprintf( outfile, "\t%s 0\n", /* NumberOfSections */
get_asm_short_keyword() );
output( "\t.long 0\n" ); /* TimeDateStamp */
output( "\t.long 0\n" ); /* PointerToSymbolTable */
output( "\t.long 0\n" ); /* NumberOfSymbols */
output( "\t%s %d\n", /* SizeOfOptionalHeader */
fprintf( outfile, "\t.long 0\n" ); /* TimeDateStamp */
fprintf( outfile, "\t.long 0\n" ); /* PointerToSymbolTable */
fprintf( outfile, "\t.long 0\n" ); /* NumberOfSymbols */
fprintf( outfile, "\t%s %d\n", /* SizeOfOptionalHeader */
get_asm_short_keyword(),
get_ptr_size() == 8 ? IMAGE_SIZEOF_NT_OPTIONAL64_HEADER : IMAGE_SIZEOF_NT_OPTIONAL32_HEADER );
output( "\t%s 0x%04x\n", /* Characteristics */
fprintf( outfile, "\t%s 0x%04x\n", /* Characteristics */
get_asm_short_keyword(), spec->characteristics );
output( "\t%s 0x%04x\n", /* Magic */
fprintf( outfile, "\t%s 0x%04x\n", /* Magic */
get_asm_short_keyword(),
get_ptr_size() == 8 ? IMAGE_NT_OPTIONAL_HDR64_MAGIC : IMAGE_NT_OPTIONAL_HDR32_MAGIC );
output( "\t.byte 0\n" ); /* MajorLinkerVersion */
output( "\t.byte 0\n" ); /* MinorLinkerVersion */
output( "\t.long 0\n" ); /* SizeOfCode */
output( "\t.long 0\n" ); /* SizeOfInitializedData */
output( "\t.long 0\n" ); /* SizeOfUninitializedData */
fprintf( outfile, "\t.byte 0\n" ); /* MajorLinkerVersion */
fprintf( outfile, "\t.byte 0\n" ); /* MinorLinkerVersion */
fprintf( outfile, "\t.long 0\n" ); /* SizeOfCode */
fprintf( outfile, "\t.long 0\n" ); /* SizeOfInitializedData */
fprintf( outfile, "\t.long 0\n" ); /* SizeOfUninitializedData */
/* note: we expand the AddressOfEntryPoint field on 64-bit by overwriting the BaseOfCode field */
output( "\t%s %s\n", /* AddressOfEntryPoint */
fprintf( outfile, "\t%s %s\n", /* AddressOfEntryPoint */
get_asm_ptr_keyword(), asm_name(spec->init_func) );
if (get_ptr_size() == 4)
{
output( "\t.long 0\n" ); /* BaseOfCode */
output( "\t.long 0\n" ); /* BaseOfData */
fprintf( outfile, "\t.long 0\n" ); /* BaseOfCode */
fprintf( outfile, "\t.long 0\n" ); /* BaseOfData */
}
output( "\t%s __wine_spec_pe_header\n", /* ImageBase */
fprintf( outfile, "\t%s __wine_spec_pe_header\n", /* ImageBase */
get_asm_ptr_keyword() );
output( "\t.long %u\n", page_size ); /* SectionAlignment */
output( "\t.long %u\n", page_size ); /* FileAlignment */
output( "\t%s 1,0\n", /* Major/MinorOperatingSystemVersion */
fprintf( outfile, "\t.long %u\n", page_size ); /* SectionAlignment */
fprintf( outfile, "\t.long %u\n", page_size ); /* FileAlignment */
fprintf( outfile, "\t%s 1,0\n", /* Major/MinorOperatingSystemVersion */
get_asm_short_keyword() );
output( "\t%s 0,0\n", /* Major/MinorImageVersion */
fprintf( outfile, "\t%s 0,0\n", /* Major/MinorImageVersion */
get_asm_short_keyword() );
output( "\t%s %u,%u\n", /* Major/MinorSubsystemVersion */
fprintf( outfile, "\t%s %u,%u\n", /* Major/MinorSubsystemVersion */
get_asm_short_keyword(), spec->subsystem_major, spec->subsystem_minor );
output( "\t.long 0\n" ); /* Win32VersionValue */
output( "\t.long %s-.L__wine_spec_rva_base\n", /* SizeOfImage */
fprintf( outfile, "\t.long 0\n" ); /* Win32VersionValue */
fprintf( outfile, "\t.long %s-.L__wine_spec_rva_base\n", /* SizeOfImage */
asm_name("_end") );
output( "\t.long %u\n", page_size ); /* SizeOfHeaders */
output( "\t.long 0\n" ); /* CheckSum */
output( "\t%s 0x%04x\n", /* Subsystem */
fprintf( outfile, "\t.long %u\n", page_size ); /* SizeOfHeaders */
fprintf( outfile, "\t.long 0\n" ); /* CheckSum */
fprintf( outfile, "\t%s 0x%04x\n", /* Subsystem */
get_asm_short_keyword(), spec->subsystem );
output( "\t%s 0x%04x\n", /* DllCharacteristics */
get_asm_short_keyword(), spec->dll_characteristics );
output( "\t%s %u,%u\n", /* SizeOfStackReserve/Commit */
fprintf( outfile, "\t%s 0\n", /* DllCharacteristics */
get_asm_short_keyword() );
fprintf( outfile, "\t%s %u,%u\n", /* SizeOfStackReserve/Commit */
get_asm_ptr_keyword(), (spec->stack_size ? spec->stack_size : 1024) * 1024, page_size );
output( "\t%s %u,%u\n", /* SizeOfHeapReserve/Commit */
fprintf( outfile, "\t%s %u,%u\n", /* SizeOfHeapReserve/Commit */
get_asm_ptr_keyword(), (spec->heap_size ? spec->heap_size : 1024) * 1024, page_size );
output( "\t.long 0\n" ); /* LoaderFlags */
output( "\t.long 16\n" ); /* NumberOfRvaAndSizes */
fprintf( outfile, "\t.long 0\n" ); /* LoaderFlags */
fprintf( outfile, "\t.long 16\n" ); /* NumberOfRvaAndSizes */
if (spec->base <= spec->limit) /* DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT] */
output( "\t.long .L__wine_spec_exports-.L__wine_spec_rva_base,"
fprintf( outfile, "\t.long .L__wine_spec_exports-.L__wine_spec_rva_base,"
".L__wine_spec_exports_end-.L__wine_spec_exports\n" );
else
output( "\t.long 0,0\n" );
fprintf( outfile, "\t.long 0,0\n" );
if (has_imports()) /* DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] */
output( "\t.long .L__wine_spec_imports-.L__wine_spec_rva_base,"
fprintf( outfile, "\t.long .L__wine_spec_imports-.L__wine_spec_rva_base,"
".L__wine_spec_imports_end-.L__wine_spec_imports\n" );
else
output( "\t.long 0,0\n" );
fprintf( outfile, "\t.long 0,0\n" );
if (spec->nb_resources) /* DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE] */
output( "\t.long .L__wine_spec_resources-.L__wine_spec_rva_base,"
fprintf( outfile, "\t.long .L__wine_spec_resources-.L__wine_spec_rva_base,"
".L__wine_spec_resources_end-.L__wine_spec_resources\n" );
else
output( "\t.long 0,0\n" );
fprintf( outfile, "\t.long 0,0\n" );
output( "\t.long 0,0\n" ); /* DataDirectory[3] */
output( "\t.long 0,0\n" ); /* DataDirectory[4] */
output( "\t.long 0,0\n" ); /* DataDirectory[5] */
output( "\t.long 0,0\n" ); /* DataDirectory[6] */
output( "\t.long 0,0\n" ); /* DataDirectory[7] */
output( "\t.long 0,0\n" ); /* DataDirectory[8] */
output( "\t.long 0,0\n" ); /* DataDirectory[9] */
output( "\t.long 0,0\n" ); /* DataDirectory[10] */
output( "\t.long 0,0\n" ); /* DataDirectory[11] */
output( "\t.long 0,0\n" ); /* DataDirectory[12] */
output( "\t.long 0,0\n" ); /* DataDirectory[13] */
output( "\t.long 0,0\n" ); /* DataDirectory[14] */
output( "\t.long 0,0\n" ); /* DataDirectory[15] */
fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[3] */
fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[4] */
fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[5] */
fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[6] */
fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[7] */
fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[8] */
fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[9] */
fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[10] */
fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[11] */
fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[12] */
fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[13] */
fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[14] */
fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[15] */
output( "\n\t%s\n", get_asm_string_section() );
output( "%s\n", asm_globl("__wine_spec_file_name") );
output( ".L__wine_spec_file_name:\n" );
output( "\t%s \"%s\"\n", get_asm_string_keyword(), spec->file_name );
fprintf( outfile, "\n\t%s\n", get_asm_string_section() );
fprintf( outfile, "%s\n", asm_globl("__wine_spec_file_name") );
fprintf( outfile, ".L__wine_spec_file_name:\n" );
fprintf( outfile, "\t%s \"%s\"\n", get_asm_string_keyword(), spec->file_name );
if (target_platform == PLATFORM_APPLE)
output( "\t.lcomm %s,4\n", asm_name("_end") );
fprintf( outfile, "\t.lcomm %s,4\n", asm_name("_end") );
output_stubs( spec );
output_exports( spec );
output_imports( spec );
output_resources( spec );
output_asm_constructor( "__wine_spec_init_ctor" );
output_gnu_stack_note();
output_stubs( outfile, spec );
output_exports( outfile, spec );
output_imports( outfile, spec );
output_resources( outfile, spec );
output_asm_constructor( outfile, "__wine_spec_init_ctor" );
}
@ -526,19 +548,20 @@ void BuildSpec32File( DLLSPEC *spec )
*
* Build a Win32 def file from a spec file.
*/
void BuildDef32File( DLLSPEC *spec )
void BuildDef32File( FILE *outfile, DLLSPEC *spec )
{
const char *name;
int i, total;
if (spec_file_name)
output( "; File generated automatically from %s; do not edit!\n\n",
fprintf( outfile, "; File generated automatically from %s; do not edit!\n\n",
spec_file_name );
else
output( "; File generated automatically; do not edit!\n\n" );
fprintf( outfile, "; File generated automatically; do not edit!\n\n" );
output( "LIBRARY %s\n\n", spec->file_name);
output( "EXPORTS\n");
fprintf(outfile, "LIBRARY %s\n\n", spec->file_name);
fprintf(outfile, "EXPORTS\n");
/* Output the exports and relay entry points */
@ -550,13 +573,13 @@ void BuildDef32File( DLLSPEC *spec )
if (!odp) continue;
if (odp->name) name = odp->name;
else if (odp->type == TYPE_STUB) name = make_internal_name( odp, spec, "stub" );
else if (odp->export_name) name = odp->export_name;
else continue;
else name = make_internal_name( odp, spec, "noname_export" );
if (!(odp->flags & FLAG_PRIVATE)) total++;
output( " %s", name );
fprintf(outfile, " %s", name);
switch(odp->type)
{
@ -567,20 +590,20 @@ void BuildDef32File( DLLSPEC *spec )
case TYPE_CDECL:
/* try to reduce output */
if(strcmp(name, odp->link_name) || (odp->flags & FLAG_FORWARD))
output( "=%s", odp->link_name );
fprintf(outfile, "=%s", odp->link_name);
break;
case TYPE_STDCALL:
{
int at_param = strlen(odp->u.func.arg_types) * get_ptr_size();
if (!kill_at) output( "@%d", at_param );
if (!kill_at) fprintf(outfile, "@%d", at_param);
if (odp->flags & FLAG_FORWARD)
{
output( "=%s", odp->link_name );
fprintf(outfile, "=%s", odp->link_name);
}
else if (strcmp(name, odp->link_name)) /* try to reduce output */
{
output( "=%s", odp->link_name );
if (!kill_at) output( "@%d", at_param );
fprintf(outfile, "=%s", odp->link_name);
if (!kill_at) fprintf(outfile, "@%d", at_param);
}
break;
}
@ -597,23 +620,30 @@ void BuildDef32File( DLLSPEC *spec )
if (name != check && check != name + strlen(name) &&
'@' == check[-1])
{
output("%s", check - 1);
fprintf(outfile, "%s", check - 1);
}
}
if (NULL != odp->name)
{
output("=%s", odp->name);
fprintf(outfile, "=%s", make_internal_name( odp, spec, "stub" ));
}
break;
}
default:
assert(0);
}
output( " @%d", odp->ordinal );
if (!odp->name || (odp->flags & FLAG_ORDINAL)) output( " NONAME" );
if (is_data) output( " DATA" );
if (odp->flags & FLAG_PRIVATE) output( " PRIVATE" );
output( "\n" );
fprintf( outfile, " @%d", odp->ordinal );
#if 0 /* MinGW binutils cannot handle this correctly */
if (!odp->name) fprintf( outfile, " NONAME" );
#else
if (!odp->name && (odp->type == TYPE_STUB || odp->export_name)) fprintf( outfile, " NONAME" );
#endif
if (is_data) fprintf( outfile, " DATA" );
#if 0
/* MinGW binutils cannot handle this correctly */
if (odp->flags & FLAG_PRIVATE) fprintf( outfile, " PRIVATE" );
#endif
fprintf( outfile, "\n" );
}
if (!total) warning( "%s: Import library doesn't export anything\n", spec->file_name );
}
@ -624,34 +654,34 @@ void BuildDef32File( DLLSPEC *spec )
*
* Build a PE DLL C file from a spec file.
*/
void BuildPedllFile( DLLSPEC *spec )
void BuildPedllFile( FILE *outfile, DLLSPEC *spec )
{
int nr_exports;
nr_exports = spec->base <= spec->limit ? spec->limit - spec->base + 1 : 0;
output_standard_file_header();
output_standard_file_header( outfile );
output( "#include <stdarg.h>\n");
output( "#include \"windef.h\"\n");
output( "#include \"winbase.h\"\n");
output( "#include \"wine/config.h\"\n");
output( "#include \"wine/exception.h\"\n\n");
fprintf( outfile, "#include <stdarg.h>\n");
fprintf( outfile, "#include \"windef.h\"\n");
fprintf( outfile, "#include \"winbase.h\"\n");
fprintf( outfile, "#include \"wine/config.h\"\n");
fprintf( outfile, "#include \"wine/exception.h\"\n\n");
output( "void __wine_spec_unimplemented_stub( const char *module, const char *function )\n");
output( "{\n");
output( " ULONG_PTR args[2];\n");
output( "\n");
output( " args[0] = (ULONG_PTR)module;\n");
output( " args[1] = (ULONG_PTR)function;\n");
output( " RaiseException( EXCEPTION_WINE_STUB, EH_NONCONTINUABLE, 2, args );\n");
output( "}\n\n");
fprintf( outfile, "void __wine_spec_unimplemented_stub( const char *module, const char *function )\n");
fprintf( outfile, "{\n");
fprintf( outfile, " ULONG_PTR args[2];\n");
fprintf( outfile, "\n");
fprintf( outfile, " args[0] = (ULONG_PTR)module;\n");
fprintf( outfile, " args[1] = (ULONG_PTR)function;\n");
fprintf( outfile, " RaiseException( EXCEPTION_WINE_STUB, EH_NONCONTINUABLE, 2, args );\n");
fprintf( outfile, "}\n\n");
output( "static const char __wine_spec_file_name[] = \"%s\";\n\n", spec->file_name );
fprintf( outfile, "static const char __wine_spec_file_name[] = \"%s\";\n\n", spec->file_name );
if (nr_exports)
{
/* Output the stub functions */
output_stub_funcs( spec );
output_stub_funcs( outfile, spec );
}
}

View file

@ -15,11 +15,14 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "wine/port.h"
#if !defined(WIN32)
#undef strdup
#endif
#include <assert.h>
#include <ctype.h>
@ -31,7 +34,6 @@
# include <unistd.h>
#endif
#include "winglue.h"
#include "build.h"
#define MAX_TMP_FILES 8
@ -163,18 +165,6 @@ void warning( const char *msg, ... )
va_end( valist );
}
int output( const char *format, ... )
{
int ret;
va_list valist;
va_start( valist, format );
ret = vfprintf( output_file, format, valist );
va_end( valist );
if (ret < 0) fatal_perror( "Output error" );
return ret;
}
/* get a name for a temp file, automatically cleaned up on exit */
char *get_temp_file_name( const char *prefix, const char *suffix )
{
@ -206,29 +196,31 @@ char *get_temp_file_name( const char *prefix, const char *suffix )
}
/* output a standard header for generated files */
void output_standard_file_header(void)
void output_standard_file_header( FILE *outfile )
{
if (spec_file_name)
output( "/* File generated automatically from %s; do not edit! */\n", spec_file_name );
fprintf( outfile, "/* File generated automatically from %s; do not edit! */\n",
spec_file_name );
else
output( "/* File generated automatically; do not edit! */\n" );
output( "/* This file can be copied, modified and distributed without restriction. */\n\n" );
fprintf( outfile, "/* File generated automatically; do not edit! */\n" );
fprintf( outfile,
"/* This file can be copied, modified and distributed without restriction. */\n\n" );
}
/* dump a byte stream into the assembly code */
void dump_bytes( const void *buffer, unsigned int size )
void dump_bytes( FILE *outfile, const void *buffer, unsigned int size )
{
unsigned int i;
const unsigned char *ptr = buffer;
if (!size) return;
output( "\t.byte " );
fprintf( outfile, "\t.byte " );
for (i = 0; i < size - 1; i++, ptr++)
{
if ((i % 16) == 15) output( "0x%02x\n\t.byte ", *ptr );
else output( "0x%02x,", *ptr );
if ((i % 16) == 15) fprintf( outfile, "0x%02x\n\t.byte ", *ptr );
else fprintf( outfile, "0x%02x,", *ptr );
}
output( "0x%02x\n", *ptr );
fprintf( outfile, "0x%02x\n", *ptr );
}
@ -332,12 +324,7 @@ DLLSPEC *alloc_dll_spec(void)
spec->alloc_entry_points = 0;
spec->nb_names = 0;
spec->nb_resources = 0;
spec->characteristics = IMAGE_FILE_EXECUTABLE_IMAGE;
if (get_ptr_size() > 4)
spec->characteristics |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
else
spec->characteristics |= IMAGE_FILE_32BIT_MACHINE;
spec->dll_characteristics = IMAGE_DLLCHARACTERISTICS_NX_COMPAT;
spec->characteristics = 0;
spec->subsystem = 0;
spec->subsystem_major = 4;
spec->subsystem_minor = 0;
@ -457,7 +444,7 @@ unsigned int get_alignment(unsigned int align)
case CPU_POWERPC:
case CPU_ALPHA:
n = 0;
while ((1u << n) != align) n++;
while ((1 << n) != align) n++;
return n;
}
/* unreached */
@ -536,7 +523,7 @@ const char *func_declaration( const char *func )
}
/* output a size declaration for an assembly function */
void output_function_size( const char *name )
void output_function_size( FILE *outfile, const char *name )
{
switch (target_platform)
{
@ -544,21 +531,7 @@ void output_function_size( const char *name )
case PLATFORM_WINDOWS:
break;
default:
output( "\t.size %s, .-%s\n", name, name );
break;
}
}
/* output the GNU note for non-exec stack */
void output_gnu_stack_note(void)
{
switch (target_platform)
{
case PLATFORM_WINDOWS:
case PLATFORM_APPLE:
break;
default:
output( "\t.section .note.GNU-stack,\"\",@progbits\n" );
fprintf( outfile, "\t.size %s, .-%s\n", name, name );
break;
}
}

View file

@ -73,11 +73,11 @@ Specify the module entry point function; if not specified, the default
is
.B DllMain
for dlls, and
.B main
for executables (if the standard C
.B main
is not defined,
.B WinMain
for executables (if
.B WinMain
is not defined, the standard C
.B main
is used instead). This is only valid for Win32 modules.
.TP
.BI \-E,\ --export= filename
@ -85,14 +85,6 @@ Specify a .spec file (see \fBSPEC FILE SYNTAX\fR for details),
or a standard Windows .def file that defines the exports
of the DLL or executable that is being built.
.TP
.B \--external-symbols
Allow linking to external symbols directly from the spec
file. Normally symbols exported by a dll have to be defined in the dll
itself; this option makes it possible to use symbols defined in
another Unix library (for symbols defined in another dll, a
.I forward
specification must be used instead).
.TP
.BI \-f\ flags
Ignored for compatibility with the C compiler.
.TP
@ -153,10 +145,6 @@ KRNL386.EXE. It shouldn't be needed otherwise.
Specify the command to use to get the list of undefined symbols; the
default is \fBnm\fR.
.TP
.BI --nxcompat= yes|no
Specify whether the module is compatible with no-exec support. The
default is yes.
.TP
.BI \-o,\ --output= file
Set the name of the output file (default is standard output). If the
output file name end in \fB.o\fR, the text output is sent to a
@ -260,8 +248,7 @@ The entry point is not displayed in relay debugging traces (Win32
only).
.TP
.B -noname
The entry point will be exported by ordinal instead of by name. The
name is still available for importing.
The entry point will be imported by ordinal instead of by name.
.TP
.B -ret16
The function returns a 16-bit value (Win16 only).
@ -278,10 +265,6 @@ The function uses CPU register to pass arguments.
.B -private
The function cannot be imported from other dlls, it can only be
accessed through GetProcAddress.
.TP
.B -ordinal
The entry point will be imported by ordinal instead of by name. The
name is still exported.
.SS "Function ordinals"
Syntax:
.br

View file

@ -17,9 +17,6 @@ typedef unsigned int UINT_PTR;
#define DLL_PROCESS_ATTACH 1
#define DLL_PROCESS_DETACH 0
#define IMAGE_FILE_EXECUTABLE_IMAGE 2
#define IMAGE_FILE_LARGE_ADDRESS_AWARE 32
#define IMAGE_FILE_32BIT_MACHINE 256
#define IMAGE_FILE_DLL 8192
#define IMAGE_SUBSYSTEM_NATIVE 1
#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2
@ -31,7 +28,6 @@ typedef unsigned int UINT_PTR;
#define IMAGE_FILE_MACHINE_POWERPC 0x01f0
#define IMAGE_FILE_MACHINE_AMD64 0x8664
#define IMAGE_NT_SIGNATURE 0x00004550
#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT 0x0100
#define IMAGE_SIZEOF_NT_OPTIONAL32_HEADER 224
#define IMAGE_SIZEOF_NT_OPTIONAL64_HEADER 240
#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b