mirror of
https://github.com/reactos/reactos.git
synced 2025-04-05 21:21:33 +00:00
Sync winebuild (keeping ReactOS-specific changes).
3 days ago Michael Stefaniuc winebuild: Remove duplicate declaration of variable ... 6 days ago Alexandre Julliard winebuild: Don't set the IMAGE_FILE_DLL flag on native ... 10 days ago Alexandre Julliard winebuild: Also optimize out imports that are only ... 10 days ago Alexandre Julliard winebuild: Improved checks for missing forward entry ... 10 days ago Alexandre Julliard winebuild: Print a warning when failing to import a ... 2007-11-07 Alexandre Julliard winebuild: Add a few nops to stub entry points to make ... 2007-10-26 Alexandre Julliard winebuild: Add a -ordinal flag for entry points that ... 2007-09-10 Dmitry Timoshkov winebuild: Add IMAGE_FILE_32BIT_MACHINE flag for a ... 2007-07-19 Alexandre Julliard ntdll: Move private data to make room in the TEB for ... 2007-05-29 Dmitry Timoshkov winebuild: Mark builtin DLLs as IMAGE_FILE_LARGE_ADDRES ... 2007-05-24 Alexandre Julliard winebuild: Set the IMAGE_FILE_EXECUTABLE_IMAGE flag ... 2007-05-21 Dmitry Timoshkov winebuild: Fix compilation warnings in 64-bit mode. 2007-04-25 Rob Shearman winebuild: Refer to strings used in generated stubs ... 2007-04-09 Dmitry Timoshkov winebuild: Check if a given forward does exist in one ... 2007-03-17 Andrew Talbot winebuild: Replace inline static with static inline. 2007-03-05 Joris Huizer winebuild: sign-compare fixes. 2006-12-27 Alexandre Julliard make_makefiles: Generate the top-level .gitignore file. 2006-12-07 Alexandre Julliard winebuild: Added --nxcompat option, and mark all module ... 2006-12-04 Alexandre Julliard winebuild: Check for illegal characters in entry point ... 2006-10-12 Andrew Talbot winebuild: Cast-qual warning fix. 2006-09-14 Alexandre Julliard makefiles: Generate the dependencies line to avoid ... 2006-08-23 Andrew Talbot winebuild: Cast-qual warnings fix. 2006-08-11 Alexandre Julliard winebuild: Added output() function to properly deal ... 2006-08-07 Alexandre Julliard makefiles: Use make dependencies to create installation ... 2006-07-11 Ge van Geldorp winebuild: Save registers which might contain parameter ... 2006-07-11 Ge van Geldorp winebuild: Reserve enough space for null function pointer. 2006-07-10 Alexandre Julliard Take advantage of the recursive nature of .gitignore ... 2006-06-19 Alexandre Julliard winebuild: Get rid of the data16 prefix, it shouldn't ... 2006-06-13 Alexandre Julliard winebuild: Fix a few printf format warnings by casting ... 2006-05-23 Jonathan Ernst Update the address of the Free Software Foundation. 2006-04-18 Alexandre Julliard winebuild: Disable linking to external symbols by default. 2006-04-18 Alexandre Julliard winebuild: Fixed index in module table for delayed ... 2006-04-05 Alexandre Julliard winebuild: Remove a no longer necessary movzwl instruction. 2006-02-16 Robert Shearman winebuild: Correction for manpage. 2006-02-14 Mike Frysinger Add support for 'make install DESTDIR'. 2006-01-24 Alexandre Julliard winebuild: Get rid of the default ignored symbols list. 2006-01-23 Alexandre Julliard winebuild: Always import atof, the MS version is different. 2006-01-21 Marcus Meissner winebuild: Output a .note.GNU-stack section to allow ... 2006-01-20 Alexandre Julliard winebuild: Moved offset definitions to relay.c since ... 2006-01-20 Alexandre Julliard ntdll: Move the %gs register to the ntdll_thread_regs ... svn path=/trunk/; revision=31292
This commit is contained in:
parent
1e284d22a4
commit
26c115dc6a
14 changed files with 1455 additions and 1477 deletions
|
@ -24,8 +24,8 @@ The following build tools are shared with Wine.
|
|||
reactos/tools/unicode # Synced to Wine-0_9_5
|
||||
reactos/tools/wpp # Synced to Wine-0_9_5
|
||||
reactos/tools/bin2res # Resource to binary converter
|
||||
reactos/tools/winebuild # Synced to Wine-0_9_5
|
||||
reactos/tools/wmc # Synced to Wine-0_9_5
|
||||
reactos/tools/winebuild # Synced to Wine-20071217
|
||||
reactos/tools/wmc # Synced to Wine-20071201
|
||||
reactos/tools/wrc # Synced to Wine-0_9_5
|
||||
reactos/tools/widl # Synced to Wine-20060729
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@ C_SRCS = \
|
|||
spec32.c \
|
||||
utils.c
|
||||
|
||||
INSTALLDIRS = $(DESTDIR)$(bindir) $(DESTDIR)$(mandir)/man$(prog_manext)
|
||||
|
||||
all: $(PROGRAMS) $(MANPAGES)
|
||||
|
||||
@MAKE_RULES@
|
||||
|
@ -26,12 +28,11 @@ all: $(PROGRAMS) $(MANPAGES)
|
|||
winebuild$(EXEEXT): $(OBJS)
|
||||
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBPORT) $(LDFLAGS)
|
||||
|
||||
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)
|
||||
install:: $(PROGRAMS) $(MANPAGES) $(INSTALLDIRS)
|
||||
$(INSTALL_PROGRAM) winebuild$(EXEEXT) $(DESTDIR)$(bindir)/winebuild$(EXEEXT)
|
||||
$(INSTALL_DATA) winebuild.man $(DESTDIR)$(mandir)/man$(prog_manext)/winebuild.$(prog_manext)
|
||||
|
||||
uninstall::
|
||||
$(RM) $(bindir)/winebuild$(EXEEXT) $(mandir)/man$(prog_manext)/winebuild.$(prog_manext)
|
||||
$(RM) $(DESTDIR)$(bindir)/winebuild$(EXEEXT) $(DESTDIR)$(mandir)/man$(prog_manext)/winebuild.$(prog_manext)
|
||||
|
||||
### Dependencies:
|
||||
@DEPENDENCIES@ # everything below this line is overwritten by make depend
|
||||
|
|
|
@ -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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_BUILD_H
|
||||
|
@ -31,6 +31,8 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "winglue.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TYPE_VARIABLE, /* variable */
|
||||
|
@ -85,6 +87,7 @@ 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 */
|
||||
|
@ -98,6 +101,7 @@ 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 */
|
||||
|
@ -114,7 +118,7 @@ enum target_cpu
|
|||
|
||||
enum target_platform
|
||||
{
|
||||
PLATFORM_UNSPECIFIED, PLATFORM_APPLE, PLATFORM_SVR4, PLATFORM_WINDOWS
|
||||
PLATFORM_UNSPECIFIED, PLATFORM_APPLE, PLATFORM_WINDOWS
|
||||
};
|
||||
|
||||
extern enum target_cpu target_cpu;
|
||||
|
@ -122,31 +126,16 @@ 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 import function by name */
|
||||
#define FLAG_NONAME 0x02 /* don't export 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 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 FLAG_FORWARD 0x100 /* function is a forwarded name */
|
||||
#define FLAG_EXT_LINK 0x200 /* function links to an external symbol */
|
||||
|
||||
#define MAX_ORDINALS 65535
|
||||
|
||||
|
@ -169,11 +158,13 @@ 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( FILE *outfile );
|
||||
extern void output_standard_file_header(void);
|
||||
extern FILE *open_input_file( const char *srcdir, const char *name );
|
||||
extern void close_input_file( FILE *file );
|
||||
extern void dump_bytes( FILE *outfile, const void *buffer, unsigned int size );
|
||||
extern void dump_bytes( 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);
|
||||
|
@ -191,7 +182,8 @@ 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( FILE *outfile, const char *name );
|
||||
extern void output_function_size( const char *name );
|
||||
extern void output_gnu_stack_note(void);
|
||||
|
||||
extern void add_import_dll( const char *name, const char *filename );
|
||||
extern void add_delayed_import( const char *name );
|
||||
|
@ -201,27 +193,25 @@ 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( FILE *outfile );
|
||||
extern void output_stubs( FILE *outfile, DLLSPEC *spec );
|
||||
extern void output_imports( FILE *outfile, DLLSPEC *spec );
|
||||
extern void output_get_pc_thunk(void);
|
||||
extern void output_stubs( DLLSPEC *spec );
|
||||
extern void output_imports( DLLSPEC *spec );
|
||||
extern int load_res32_file( const char *name, DLLSPEC *spec );
|
||||
extern void output_resources( FILE *outfile, DLLSPEC *spec );
|
||||
extern void output_resources( DLLSPEC *spec );
|
||||
extern void load_res16_file( const char *name, DLLSPEC *spec );
|
||||
extern void output_res16_data( FILE *outfile, DLLSPEC *spec );
|
||||
extern void output_res16_directory( FILE *outfile, DLLSPEC *spec, const char *header_name );
|
||||
extern void output_res16_data( DLLSPEC *spec );
|
||||
extern void output_res16_directory( DLLSPEC *spec, const char *header_name );
|
||||
|
||||
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 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 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;
|
||||
|
@ -232,9 +222,11 @@ 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
|
@ -19,16 +19,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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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>
|
||||
|
@ -38,7 +36,8 @@
|
|||
# include <getopt.h>
|
||||
#endif
|
||||
|
||||
#include "winglue.h"
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "build.h"
|
||||
|
||||
int UsePIC = 0;
|
||||
|
@ -48,8 +47,9 @@ 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__)
|
||||
#ifdef __i386__
|
||||
enum target_cpu target_cpu = CPU_x86;
|
||||
#elif defined(__x86_64__)
|
||||
enum target_cpu target_cpu = CPU_x86_64;
|
||||
|
@ -65,8 +65,6 @@ 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
|
||||
|
@ -77,6 +75,7 @@ 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;
|
||||
|
||||
|
@ -84,7 +83,6 @@ 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;
|
||||
|
||||
|
@ -127,7 +125,6 @@ static const struct
|
|||
{
|
||||
{ "macos", PLATFORM_APPLE },
|
||||
{ "darwin", PLATFORM_APPLE },
|
||||
{ "sunos", PLATFORM_SVR4 },
|
||||
{ "windows", PLATFORM_WINDOWS },
|
||||
{ "winnt", PLATFORM_WINDOWS }
|
||||
};
|
||||
|
@ -248,8 +245,9 @@ 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, --export=FILE Export the symbols defined in the .spec or .def file\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"
|
||||
" -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"
|
||||
|
@ -263,6 +261,7 @@ 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"
|
||||
|
@ -278,7 +277,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"
|
||||
" --relay32 Build the 32-bit relay assembly routines\n\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";
|
||||
|
||||
|
@ -288,14 +287,16 @@ 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_VERSION,
|
||||
LONG_OPT_TARGET,
|
||||
LONG_OPT_VERSION,
|
||||
LONG_OPT_PEDLL
|
||||
};
|
||||
|
||||
|
@ -303,19 +304,21 @@ 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 },
|
||||
{ "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 },
|
||||
{ "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 },
|
||||
/* aliases for short options */
|
||||
{ "delay-lib", 1, 0, 'd' },
|
||||
{ "export", 1, 0, 'E' },
|
||||
|
@ -471,12 +474,19 @@ 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;
|
||||
|
@ -564,6 +574,7 @@ 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
|
||||
|
@ -592,7 +603,8 @@ int main(int argc, char **argv)
|
|||
switch(exec_mode)
|
||||
{
|
||||
case MODE_DLL:
|
||||
spec->characteristics |= IMAGE_FILE_DLL;
|
||||
if (spec->subsystem != IMAGE_SUBSYSTEM_NATIVE)
|
||||
spec->characteristics |= IMAGE_FILE_DLL;
|
||||
load_resources( argv, spec );
|
||||
load_import_libs( argv );
|
||||
if (!spec_file_name) fatal_error( "missing .spec file\n" );
|
||||
|
@ -604,7 +616,7 @@ int main(int argc, char **argv)
|
|||
break;
|
||||
case SPEC_WIN32:
|
||||
read_undef_symbols( spec, argv );
|
||||
BuildSpec32File( output_file, spec );
|
||||
BuildSpec32File( spec );
|
||||
break;
|
||||
default: assert(0);
|
||||
}
|
||||
|
@ -616,14 +628,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( output_file, spec );
|
||||
BuildSpec32File( spec );
|
||||
break;
|
||||
case MODE_DEF:
|
||||
if (argv[0]) fatal_error( "file argument '%s' not allowed in this mode\n", argv[0] );
|
||||
if (spec->type == SPEC_WIN16) fatal_error( "Cannot yet build .def file for 16-bit dlls\n" );
|
||||
if (!spec_file_name) fatal_error( "missing .spec file\n" );
|
||||
if (!parse_input_file( spec )) break;
|
||||
BuildDef32File( output_file, spec );
|
||||
BuildDef32File( spec );
|
||||
break;
|
||||
case MODE_RELAY16:
|
||||
fatal_error( "Win16 relays are not supported in ReactOS version of winebuild\n" );
|
||||
|
@ -634,7 +646,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( output_file, spec );
|
||||
BuildPedllFile( spec );
|
||||
break;
|
||||
default:
|
||||
usage(1);
|
||||
|
@ -643,7 +655,7 @@ int main(int argc, char **argv)
|
|||
if (nb_errors) exit(1);
|
||||
if (output_file_name)
|
||||
{
|
||||
fclose( output_file );
|
||||
if (fclose( output_file ) < 0) fatal_perror( "fclose" );
|
||||
if (output_file_source_name) assemble_file( output_file_source_name, output_file_name );
|
||||
output_file_name = NULL;
|
||||
}
|
||||
|
|
|
@ -19,10 +19,11 @@
|
|||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
@ -31,7 +32,8 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "winglue.h"
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "build.h"
|
||||
|
||||
int current_line = 0;
|
||||
|
@ -44,6 +46,9 @@ 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 */
|
||||
|
@ -65,6 +70,7 @@ static const char * const FlagNames[] =
|
|||
"i386", /* FLAG_I386 */
|
||||
"register", /* FLAG_REGISTER */
|
||||
"private", /* FLAG_PRIVATE */
|
||||
"ordinal", /* FLAG_ORDINAL */
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -74,12 +80,12 @@ static int IsNumberString(const char *s)
|
|||
return 1;
|
||||
}
|
||||
|
||||
inline static int is_token_separator( char ch )
|
||||
static inline int is_token_separator( char ch )
|
||||
{
|
||||
return strchr( separator_chars, ch ) != NULL;
|
||||
}
|
||||
|
||||
inline static int is_token_comment( char ch )
|
||||
static inline int is_token_comment( char ch )
|
||||
{
|
||||
return strchr( comment_chars, ch ) != NULL;
|
||||
}
|
||||
|
@ -445,6 +451,7 @@ 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) );
|
||||
|
@ -468,6 +475,13 @@ 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:
|
||||
|
@ -532,11 +546,14 @@ static int parse_spec_ordinal( int ordinal, DLLSPEC *spec )
|
|||
}
|
||||
}
|
||||
|
||||
if (!strcmp( odp->name, "@" ) || odp->flags & FLAG_NONAME)
|
||||
if (!strcmp( odp->name, "@" ) || odp->flags & (FLAG_NONAME | FLAG_ORDINAL))
|
||||
{
|
||||
if (ordinal == -1)
|
||||
{
|
||||
error( "Nameless function needs an explicit ordinal number\n" );
|
||||
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" );
|
||||
goto error;
|
||||
}
|
||||
if (spec->type != SPEC_WIN32)
|
||||
|
@ -544,9 +561,16 @@ 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 );
|
||||
else odp->export_name = odp->name;
|
||||
odp->name = NULL;
|
||||
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;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -15,10 +15,11 @@
|
|||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
@ -37,7 +38,8 @@
|
|||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#include "winglue.h"
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "build.h"
|
||||
|
||||
/* Unicode string or integer id */
|
||||
|
@ -77,7 +79,7 @@ static const unsigned char *file_end; /* end of resource file */
|
|||
static const char *file_name; /* current resource file name */
|
||||
|
||||
|
||||
inline static struct resource *add_resource( DLLSPEC *spec )
|
||||
static inline struct resource *add_resource( DLLSPEC *spec )
|
||||
{
|
||||
spec->resources = xrealloc( spec->resources, (spec->nb_resources + 1) * sizeof(*spec->resources) );
|
||||
return &spec->resources[spec->nb_resources++];
|
||||
|
@ -140,7 +142,7 @@ static void get_string( struct string_id *str )
|
|||
}
|
||||
else
|
||||
{
|
||||
char *p = xmalloc( (strlen((char*)file_pos) + 1) );
|
||||
char *p = xmalloc(strlen((const char *)file_pos) + 1);
|
||||
str->str = p;
|
||||
str->id = 0;
|
||||
while ((*p++ = get_byte()));
|
||||
|
@ -240,16 +242,16 @@ static void free_resource_tree( struct res_tree *tree )
|
|||
}
|
||||
|
||||
/* output a string preceded by its length */
|
||||
static void output_string( FILE *outfile, const char *str )
|
||||
static void output_string( const char *str )
|
||||
{
|
||||
unsigned int i, len = strlen(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( "\t.byte 0x%02x", len );
|
||||
for (i = 0; i < len; i++) output( ",0x%02x", (unsigned char)str[i] );
|
||||
output( " /* %s */\n", str );
|
||||
}
|
||||
|
||||
/* output the resource data */
|
||||
void output_res16_data( FILE *outfile, DLLSPEC *spec )
|
||||
void output_res16_data( DLLSPEC *spec )
|
||||
{
|
||||
const struct resource *res;
|
||||
unsigned int i;
|
||||
|
@ -258,14 +260,14 @@ void output_res16_data( FILE *outfile, DLLSPEC *spec )
|
|||
|
||||
for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++)
|
||||
{
|
||||
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( ".L__wine_spec_resource_%u:\n", i );
|
||||
dump_bytes( res->data, res->data_size );
|
||||
output( ".L__wine_spec_resource_%u_end:\n", i );
|
||||
}
|
||||
}
|
||||
|
||||
/* output the resource definitions */
|
||||
void output_res16_directory( FILE *outfile, DLLSPEC *spec, const char *header_name )
|
||||
void output_res16_directory( DLLSPEC *spec, const char *header_name )
|
||||
{
|
||||
unsigned int i, j;
|
||||
struct res_tree *tree;
|
||||
|
@ -274,38 +276,39 @@ void output_res16_directory( FILE *outfile, DLLSPEC *spec, const char *header_na
|
|||
|
||||
tree = build_resource_tree( spec );
|
||||
|
||||
fprintf( outfile, "\n.L__wine_spec_ne_rsrctab:\n" );
|
||||
fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* alignment */
|
||||
output( "\n.L__wine_spec_ne_rsrctab:\n" );
|
||||
output( "\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)
|
||||
fprintf( outfile, "\t%s .L__wine_spec_restype_%u-.L__wine_spec_ne_rsrctab\n",
|
||||
output( "\t%s .L__wine_spec_restype_%u-.L__wine_spec_ne_rsrctab\n",
|
||||
get_asm_short_keyword(), i );
|
||||
else
|
||||
fprintf( outfile, "\t%s 0x%04x\n", get_asm_short_keyword(), type->type->id | 0x8000 );
|
||||
output( "\t%s 0x%04x\n", get_asm_short_keyword(), type->type->id | 0x8000 );
|
||||
|
||||
fprintf( outfile, "\t%s %u,0,0\n", get_asm_short_keyword(), type->nb_names );
|
||||
output( "\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++)
|
||||
{
|
||||
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 );
|
||||
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 );
|
||||
if (res->name.str)
|
||||
fprintf( outfile, "\t%s .L__wine_spec_resname_%u_%u-.L__wine_spec_ne_rsrctab\n",
|
||||
output( "\t%s .L__wine_spec_resname_%u_%u-.L__wine_spec_ne_rsrctab\n",
|
||||
get_asm_short_keyword(), i, j );
|
||||
else
|
||||
fprintf( outfile, "\t%s 0x%04x\n", get_asm_short_keyword(), res->name.id | 0x8000 );
|
||||
output( "\t%s 0x%04x\n", get_asm_short_keyword(), res->name.id | 0x8000 );
|
||||
|
||||
fprintf( outfile, "\t%s 0,0\n", get_asm_short_keyword() );
|
||||
output( "\t%s 0,0\n", get_asm_short_keyword() );
|
||||
}
|
||||
}
|
||||
fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* terminator */
|
||||
output( "\t%s 0\n", get_asm_short_keyword() ); /* terminator */
|
||||
|
||||
/* name strings */
|
||||
|
||||
|
@ -313,19 +316,19 @@ void output_res16_directory( FILE *outfile, DLLSPEC *spec, const char *header_na
|
|||
{
|
||||
if (type->type->str)
|
||||
{
|
||||
fprintf( outfile, ".L__wine_spec_restype_%u:\n", i );
|
||||
output_string( outfile, type->type->str );
|
||||
output( ".L__wine_spec_restype_%u:\n", i );
|
||||
output_string( type->type->str );
|
||||
}
|
||||
for (j = 0, res = type->res; j < type->nb_names; j++, res++)
|
||||
{
|
||||
if (res->name.str)
|
||||
{
|
||||
fprintf( outfile, ".L__wine_spec_resname_%u_%u:\n", i, j );
|
||||
output_string( outfile, res->name.str );
|
||||
output( ".L__wine_spec_resname_%u_%u:\n", i, j );
|
||||
output_string( res->name.str );
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf( outfile, "\t.byte 0\n" ); /* names terminator */
|
||||
output( "\t.byte 0\n" ); /* names terminator */
|
||||
|
||||
free_resource_tree( tree );
|
||||
}
|
||||
|
|
|
@ -15,10 +15,11 @@
|
|||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -36,7 +37,8 @@
|
|||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#include "winglue.h"
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "build.h"
|
||||
|
||||
/* Unicode string or integer id */
|
||||
|
@ -91,7 +93,7 @@ static const char *file_name; /* current resource file name */
|
|||
#define RESDIR_SIZE(n) (sizeof(IMAGE_RESOURCE_DIRECTORY) + (n) * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY))
|
||||
|
||||
|
||||
inline static struct resource *add_resource( DLLSPEC *spec )
|
||||
static inline 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++];
|
||||
|
@ -314,29 +316,29 @@ static void free_resource_tree( struct res_tree *tree )
|
|||
}
|
||||
|
||||
/* output a Unicode string */
|
||||
static void output_string( FILE *outfile, const WCHAR *name )
|
||||
static void output_string( const WCHAR *name )
|
||||
{
|
||||
int i, len = strlenW(name);
|
||||
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( "\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" );
|
||||
}
|
||||
|
||||
/* output a resource directory */
|
||||
static inline void output_res_dir( FILE *outfile, unsigned int nb_names, unsigned int nb_ids )
|
||||
static inline void output_res_dir( unsigned int nb_names, unsigned int nb_ids )
|
||||
{
|
||||
fprintf( outfile, "\t.long 0\n" ); /* Characteristics */
|
||||
fprintf( outfile, "\t.long 0\n" ); /* TimeDateStamp */
|
||||
fprintf( outfile, "\t%s 0,0\n", /* Major/MinorVersion */
|
||||
output( "\t.long 0\n" ); /* Characteristics */
|
||||
output( "\t.long 0\n" ); /* TimeDateStamp */
|
||||
output( "\t%s 0,0\n", /* Major/MinorVersion */
|
||||
get_asm_short_keyword() );
|
||||
fprintf( outfile, "\t%s %u,%u\n", /* NumberOfNamed/IdEntries */
|
||||
output( "\t%s %u,%u\n", /* NumberOfNamed/IdEntries */
|
||||
get_asm_short_keyword(), nb_names, nb_ids );
|
||||
}
|
||||
|
||||
/* output the resource definitions */
|
||||
void output_resources( FILE *outfile, DLLSPEC *spec )
|
||||
void output_resources( DLLSPEC *spec )
|
||||
{
|
||||
int k, nb_id_types;
|
||||
unsigned int i, n, offset, data_offset;
|
||||
|
@ -386,19 +388,19 @@ void output_resources( FILE *outfile, DLLSPEC *spec )
|
|||
|
||||
/* output the resource directories */
|
||||
|
||||
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( "\n/* resources */\n\n" );
|
||||
output( "\t.data\n" );
|
||||
output( "\t.align %d\n", get_alignment(get_ptr_size()) );
|
||||
output( ".L__wine_spec_resources:\n" );
|
||||
|
||||
output_res_dir( outfile, tree->nb_types - nb_id_types, nb_id_types );
|
||||
output_res_dir( 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++)
|
||||
{
|
||||
fprintf( outfile, "\t.long 0x%08x,0x%08x\n",
|
||||
output( "\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++)
|
||||
|
@ -412,22 +414,22 @@ void output_resources( FILE *outfile, DLLSPEC *spec )
|
|||
|
||||
for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
|
||||
{
|
||||
output_res_dir( outfile, type->nb_names - type->nb_id_names, type->nb_id_names );
|
||||
output_res_dir( 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++)
|
||||
{
|
||||
fprintf( outfile, "\t.long 0x%08x,0x%08x\n",
|
||||
output( "\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( outfile, 0, name->nb_languages );
|
||||
output_res_dir( 0, name->nb_languages );
|
||||
for (k = 0, res = name->res; k < name->nb_languages; k++, res++)
|
||||
{
|
||||
fprintf( outfile, "\t.long 0x%08x,0x%08x\n", res->lang,
|
||||
data_offset + (res - spec->resources) * sizeof(IMAGE_RESOURCE_DATA_ENTRY) );
|
||||
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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -435,28 +437,28 @@ void output_resources( FILE *outfile, DLLSPEC *spec )
|
|||
/* dump the resource data entries */
|
||||
|
||||
for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++)
|
||||
fprintf( outfile, "\t.long .L__wine_spec_res_%d-.L__wine_spec_rva_base,%u,0,0\n",
|
||||
output( "\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( outfile, type->type->str );
|
||||
if (type->type->str) output_string( type->type->str );
|
||||
for (n = 0, name = type->names; n < type->nb_names; n++, name++)
|
||||
if (name->name->str) output_string( outfile, name->name->str );
|
||||
if (name->name->str) output_string( name->name->str );
|
||||
}
|
||||
|
||||
/* resource data */
|
||||
|
||||
for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++)
|
||||
{
|
||||
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( "\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, ".L__wine_spec_resources_end:\n" );
|
||||
fprintf( outfile, "\t.byte 0\n" );
|
||||
output( ".L__wine_spec_resources_end:\n" );
|
||||
output( "\t.byte 0\n" );
|
||||
|
||||
free_resource_tree( tree );
|
||||
}
|
||||
|
|
|
@ -19,10 +19,11 @@
|
|||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
@ -53,31 +54,31 @@ static inline int is_function( const ORDDEF *odp )
|
|||
*
|
||||
* Output entries for individual symbols in the entry table.
|
||||
*/
|
||||
static void output_entries( FILE *outfile, DLLSPEC *spec, int first, int count )
|
||||
static void output_entries( DLLSPEC *spec, int first, int count )
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
ORDDEF *odp = spec->ordinals[first + i];
|
||||
fprintf( outfile, "\t.byte 0x03\n" ); /* flags: exported & public data */
|
||||
output( "\t.byte 0x03\n" ); /* flags: exported & public data */
|
||||
switch (odp->type)
|
||||
{
|
||||
case TYPE_CDECL:
|
||||
case TYPE_PASCAL:
|
||||
case TYPE_VARARGS:
|
||||
case TYPE_STUB:
|
||||
fprintf( outfile, "\t%s .L__wine_%s_%u-.L__wine_spec_code_segment\n",
|
||||
output( "\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:
|
||||
fprintf( outfile, "\t%s .L__wine_%s_%u-.L__wine_spec_data_segment\n",
|
||||
output( "\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:
|
||||
fprintf( outfile, "\t%s 0x%04x /* %s */\n",
|
||||
output( "\t%s 0x%04x /* %s */\n",
|
||||
get_asm_short_keyword(), odp->u.abs.value, odp->name );
|
||||
break;
|
||||
default:
|
||||
|
@ -90,7 +91,7 @@ static void output_entries( FILE *outfile, DLLSPEC *spec, int first, int count )
|
|||
/*******************************************************************
|
||||
* output_entry_table
|
||||
*/
|
||||
static void output_entry_table( FILE *outfile, DLLSPEC *spec )
|
||||
static void output_entry_table( DLLSPEC *spec )
|
||||
{
|
||||
int i, prev = 0, prev_sel = -1, bundle_count = 0;
|
||||
|
||||
|
@ -125,10 +126,10 @@ static void output_entry_table( FILE *outfile, DLLSPEC *spec )
|
|||
/* flush previous bundle */
|
||||
if (bundle_count)
|
||||
{
|
||||
fprintf( outfile, "\t/* %s.%d - %s.%d */\n",
|
||||
output( "\t/* %s.%d - %s.%d */\n",
|
||||
spec->dll_name, prev - bundle_count + 1, spec->dll_name, prev );
|
||||
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 0x%02x,0x%02x\n", bundle_count, prev_sel );
|
||||
output_entries( spec, prev - bundle_count + 1, bundle_count );
|
||||
}
|
||||
|
||||
if (prev + 1 != i)
|
||||
|
@ -136,10 +137,10 @@ static void output_entry_table( FILE *outfile, DLLSPEC *spec )
|
|||
int skip = i - (prev + 1);
|
||||
while (skip > 255)
|
||||
{
|
||||
fprintf( outfile, "\t.byte 0xff,0x00\n" );
|
||||
output( "\t.byte 0xff,0x00\n" );
|
||||
skip -= 255;
|
||||
}
|
||||
fprintf( outfile, "\t.byte 0x%02x,0x00\n", skip );
|
||||
output( "\t.byte 0x%02x,0x00\n", skip );
|
||||
}
|
||||
|
||||
bundle_count = 0;
|
||||
|
@ -152,24 +153,24 @@ static void output_entry_table( FILE *outfile, DLLSPEC *spec )
|
|||
/* flush last bundle */
|
||||
if (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 0x%02x,0x%02x\n", bundle_count, prev_sel );
|
||||
output_entries( spec, prev - bundle_count + 1, bundle_count );
|
||||
}
|
||||
fprintf( outfile, "\t.byte 0x00\n" );
|
||||
output( "\t.byte 0x00\n" );
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* output_resident_name
|
||||
*/
|
||||
static void output_resident_name( FILE *outfile, const char *string, int ordinal )
|
||||
static void output_resident_name( const char *string, int ordinal )
|
||||
{
|
||||
unsigned int i, len = strlen(string);
|
||||
|
||||
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 );
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
|
@ -282,7 +283,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( FILE *outfile, ORDDEF *odp )
|
||||
static void output_call16_function( ORDDEF *odp )
|
||||
{
|
||||
char name[256];
|
||||
int i, pos, stack_words;
|
||||
|
@ -292,41 +293,41 @@ static void output_call16_function( FILE *outfile, ORDDEF *odp )
|
|||
|
||||
sprintf( name, ".L__wine_spec_call16_%s", get_relay_name(odp) );
|
||||
|
||||
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" );
|
||||
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" );
|
||||
stack_words = 2;
|
||||
if (needs_ldt)
|
||||
{
|
||||
fprintf( outfile, "\tpushl %%esi\n" );
|
||||
output( "\tpushl %%esi\n" );
|
||||
stack_words++;
|
||||
if (UsePIC)
|
||||
{
|
||||
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" );
|
||||
output( "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") );
|
||||
output( "1:\tmovl wine_ldt_copy_ptr-1b(%%eax),%%esi\n" );
|
||||
}
|
||||
else
|
||||
fprintf( outfile, "\tmovl $%s,%%esi\n", asm_name("wine_ldt_copy") );
|
||||
output( "\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) fprintf( outfile, "\tsubl $%d,%%esp\n", 16 - 4 * (stack_words % 4) );
|
||||
if (stack_words % 4) output( "\tsubl $%d,%%esp\n", 16 - 4 * (stack_words % 4) );
|
||||
|
||||
if (args[0] || odp->type == TYPE_VARARGS)
|
||||
fprintf( outfile, "\tmovl 12(%%ebp),%%ecx\n" ); /* args */
|
||||
output( "\tmovl 12(%%ebp),%%ecx\n" ); /* args */
|
||||
|
||||
if (odp->flags & FLAG_REGISTER)
|
||||
{
|
||||
fprintf( outfile, "\tpushl 16(%%ebp)\n" ); /* context */
|
||||
output( "\tpushl 16(%%ebp)\n" ); /* context */
|
||||
}
|
||||
else if (odp->type == TYPE_VARARGS)
|
||||
{
|
||||
fprintf( outfile, "\tleal %d(%%ecx),%%eax\n", argsize );
|
||||
fprintf( outfile, "\tpushl %%eax\n" ); /* va_list16 */
|
||||
output( "\tleal %d(%%ecx),%%eax\n", argsize );
|
||||
output( "\tpushl %%eax\n" ); /* va_list16 */
|
||||
}
|
||||
|
||||
pos = (odp->type == TYPE_PASCAL) ? 0 : argsize;
|
||||
|
@ -336,33 +337,33 @@ static void output_call16_function( FILE *outfile, ORDDEF *odp )
|
|||
{
|
||||
case 'w': /* word */
|
||||
if (odp->type != TYPE_PASCAL) pos -= 2;
|
||||
fprintf( outfile, "\tmovzwl %d(%%ecx),%%eax\n", pos );
|
||||
fprintf( outfile, "\tpushl %%eax\n" );
|
||||
output( "\tmovzwl %d(%%ecx),%%eax\n", pos );
|
||||
output( "\tpushl %%eax\n" );
|
||||
if (odp->type == TYPE_PASCAL) pos += 2;
|
||||
break;
|
||||
|
||||
case 's': /* s_word */
|
||||
if (odp->type != TYPE_PASCAL) pos -= 2;
|
||||
fprintf( outfile, "\tmovswl %d(%%ecx),%%eax\n", pos );
|
||||
fprintf( outfile, "\tpushl %%eax\n" );
|
||||
output( "\tmovswl %d(%%ecx),%%eax\n", pos );
|
||||
output( "\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;
|
||||
fprintf( outfile, "\tpushl %d(%%ecx)\n", pos );
|
||||
output( "\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;
|
||||
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" );
|
||||
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" );
|
||||
if (odp->type == TYPE_PASCAL) pos += 4;
|
||||
break;
|
||||
|
||||
|
@ -371,14 +372,13 @@ static void output_call16_function( FILE *outfile, ORDDEF *odp )
|
|||
}
|
||||
}
|
||||
|
||||
fprintf( outfile, "\tcall *8(%%ebp)\n" );
|
||||
output( "\tcall *8(%%ebp)\n" );
|
||||
|
||||
if (needs_ldt) fprintf( outfile, "\tmovl -4(%%ebp),%%esi\n" );
|
||||
if (odp->flags & FLAG_RET16) fprintf( outfile, "\tmovzwl %%ax,%%eax\n" );
|
||||
if (needs_ldt) output( "\tmovl -4(%%ebp),%%esi\n" );
|
||||
|
||||
fprintf( outfile, "\tleave\n" );
|
||||
fprintf( outfile, "\tret\n" );
|
||||
output_function_size( outfile, name );
|
||||
output( "\tleave\n" );
|
||||
output( "\tret\n" );
|
||||
output_function_size( name );
|
||||
}
|
||||
|
||||
|
||||
|
@ -450,72 +450,72 @@ static int sort_func_list( ORDDEF **list, int count,
|
|||
*
|
||||
* Output the dll initialization code.
|
||||
*/
|
||||
static void output_init_code( FILE *outfile, const DLLSPEC *spec, const char *header_name )
|
||||
static void output_init_code( const DLLSPEC *spec, const char *header_name )
|
||||
{
|
||||
char name[80];
|
||||
|
||||
sprintf( name, ".L__wine_spec_%s_init", make_c_identifier(spec->dll_name) );
|
||||
|
||||
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" );
|
||||
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" );
|
||||
if (UsePIC)
|
||||
{
|
||||
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" );
|
||||
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" );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( outfile, "\tpushl $.L__wine_spec_file_name\n" );
|
||||
fprintf( outfile, "\tpushl $%s\n", header_name );
|
||||
output( "\tpushl $.L__wine_spec_file_name\n" );
|
||||
output( "\tpushl $%s\n", header_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 );
|
||||
output( "\tcall %s\n", asm_name("__wine_dll_register_16") );
|
||||
output( "\taddl $12,%%esp\n" );
|
||||
output( "\tret\n" );
|
||||
output_function_size( name );
|
||||
|
||||
sprintf( name, ".L__wine_spec_%s_fini", make_c_identifier(spec->dll_name) );
|
||||
|
||||
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" );
|
||||
output( "\t.align 4\n" );
|
||||
output( "\t%s\n", func_declaration(name) );
|
||||
output( "%s:\n", name );
|
||||
output( "subl $8,%%esp\n" );
|
||||
if (UsePIC)
|
||||
{
|
||||
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" );
|
||||
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" );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( outfile, "\tpushl $%s\n", header_name );
|
||||
output( "\tpushl $%s\n", header_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 );
|
||||
output( "\tcall %s\n", asm_name("__wine_dll_unregister_16") );
|
||||
output( "\taddl $12,%%esp\n" );
|
||||
output( "\tret\n" );
|
||||
output_function_size( name );
|
||||
|
||||
if (target_platform == PLATFORM_APPLE)
|
||||
{
|
||||
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) );
|
||||
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) );
|
||||
}
|
||||
else
|
||||
{
|
||||
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) );
|
||||
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) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -525,7 +525,7 @@ static void output_init_code( FILE *outfile, const DLLSPEC *spec, const char *he
|
|||
*
|
||||
* Build a Win16 assembly file from a spec file.
|
||||
*/
|
||||
void BuildSpec16File( FILE *outfile, DLLSPEC *spec )
|
||||
void BuildSpec16File( DLLSPEC *spec )
|
||||
{
|
||||
ORDDEF **typelist;
|
||||
int i, j, nb_funcs;
|
||||
|
@ -533,7 +533,7 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec )
|
|||
|
||||
/* File header */
|
||||
|
||||
output_standard_file_header( outfile );
|
||||
output_standard_file_header();
|
||||
|
||||
if (!spec->dll_name) /* set default name from file name */
|
||||
{
|
||||
|
@ -558,135 +558,135 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec )
|
|||
/* Output the module structure */
|
||||
|
||||
sprintf( header_name, "__wine_spec_%s_dos_header", make_c_identifier(spec->dll_name) );
|
||||
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 */
|
||||
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 */
|
||||
IMAGE_DOS_SIGNATURE );
|
||||
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( "\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, ".L__wine_spec_ne_header:\n" );
|
||||
fprintf( outfile, "\t%s 0x%04x\n", get_asm_short_keyword(), /* ne_magic */
|
||||
output( ".L__wine_spec_ne_header:\n" );
|
||||
output( "\t%s 0x%04x\n", get_asm_short_keyword(), /* ne_magic */
|
||||
IMAGE_OS2_SIGNATURE );
|
||||
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 */
|
||||
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 */
|
||||
get_asm_short_keyword() );
|
||||
fprintf( outfile, "\t%s .L__wine_spec_ne_enttab_end-.L__wine_spec_ne_enttab\n", /* ne_cbenttab */
|
||||
output( "\t%s .L__wine_spec_ne_enttab_end-.L__wine_spec_ne_enttab\n", /* ne_cbenttab */
|
||||
get_asm_short_keyword() );
|
||||
fprintf( outfile, "\t.long 0\n" ); /* ne_crc */
|
||||
fprintf( outfile, "\t%s 0x%04x\n", get_asm_short_keyword(), /* ne_flags */
|
||||
output( "\t.long 0\n" ); /* ne_crc */
|
||||
output( "\t%s 0x%04x\n", get_asm_short_keyword(), /* ne_flags */
|
||||
NE_FFLAGS_SINGLEDATA | NE_FFLAGS_LIBMODULE );
|
||||
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 */
|
||||
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 */
|
||||
get_asm_short_keyword() );
|
||||
fprintf( outfile, "\t%s .L__wine_spec_ne_rsrctab-.L__wine_spec_ne_header\n", /* ne_rsrctab */
|
||||
output( "\t%s .L__wine_spec_ne_rsrctab-.L__wine_spec_ne_header\n", /* ne_rsrctab */
|
||||
get_asm_short_keyword() );
|
||||
fprintf( outfile, "\t%s .L__wine_spec_ne_restab-.L__wine_spec_ne_header\n", /* ne_restab */
|
||||
output( "\t%s .L__wine_spec_ne_restab-.L__wine_spec_ne_header\n", /* ne_restab */
|
||||
get_asm_short_keyword() );
|
||||
fprintf( outfile, "\t%s .L__wine_spec_ne_modtab-.L__wine_spec_ne_header\n", /* ne_modtab */
|
||||
output( "\t%s .L__wine_spec_ne_modtab-.L__wine_spec_ne_header\n", /* ne_modtab */
|
||||
get_asm_short_keyword() );
|
||||
fprintf( outfile, "\t%s .L__wine_spec_ne_imptab-.L__wine_spec_ne_header\n", /* ne_imptab */
|
||||
output( "\t%s .L__wine_spec_ne_imptab-.L__wine_spec_ne_header\n", /* ne_imptab */
|
||||
get_asm_short_keyword() );
|
||||
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 */
|
||||
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 */
|
||||
|
||||
/* segment table */
|
||||
|
||||
fprintf( outfile, "\n.L__wine_spec_ne_segtab:\n" );
|
||||
output( "\n.L__wine_spec_ne_segtab:\n" );
|
||||
|
||||
/* code segment entry */
|
||||
|
||||
fprintf( outfile, "\t%s .L__wine_spec_code_segment-%s\n", /* filepos */
|
||||
output( "\t%s .L__wine_spec_code_segment-%s\n", /* filepos */
|
||||
get_asm_short_keyword(), header_name );
|
||||
fprintf( outfile, "\t%s .L__wine_spec_code_segment_end-.L__wine_spec_code_segment\n", /* size */
|
||||
output( "\t%s .L__wine_spec_code_segment_end-.L__wine_spec_code_segment\n", /* size */
|
||||
get_asm_short_keyword() );
|
||||
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 */
|
||||
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 */
|
||||
get_asm_short_keyword() );
|
||||
|
||||
/* data segment entry */
|
||||
|
||||
fprintf( outfile, "\t%s .L__wine_spec_data_segment-%s\n", /* filepos */
|
||||
output( "\t%s .L__wine_spec_data_segment-%s\n", /* filepos */
|
||||
get_asm_short_keyword(), header_name );
|
||||
fprintf( outfile, "\t%s .L__wine_spec_data_segment_end-.L__wine_spec_data_segment\n", /* size */
|
||||
output( "\t%s .L__wine_spec_data_segment_end-.L__wine_spec_data_segment\n", /* size */
|
||||
get_asm_short_keyword() );
|
||||
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 */
|
||||
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 */
|
||||
get_asm_short_keyword() );
|
||||
|
||||
/* resource directory */
|
||||
|
||||
output_res16_directory( outfile, spec, header_name );
|
||||
output_res16_directory( spec, header_name );
|
||||
|
||||
/* resident names table */
|
||||
|
||||
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 );
|
||||
output( "\n\t.align %d\n", get_alignment(2) );
|
||||
output( ".L__wine_spec_ne_restab:\n" );
|
||||
output_resident_name( 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( outfile, odp->name, i );
|
||||
output_resident_name( odp->name, i );
|
||||
}
|
||||
fprintf( outfile, "\t.byte 0\n" );
|
||||
output( "\t.byte 0\n" );
|
||||
|
||||
/* imported names table */
|
||||
|
||||
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" );
|
||||
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" );
|
||||
|
||||
/* entry table */
|
||||
|
||||
fprintf( outfile, "\n.L__wine_spec_ne_enttab:\n" );
|
||||
output_entry_table( outfile, spec );
|
||||
fprintf( outfile, ".L__wine_spec_ne_enttab_end:\n" );
|
||||
output( "\n.L__wine_spec_ne_enttab:\n" );
|
||||
output_entry_table( spec );
|
||||
output( ".L__wine_spec_ne_enttab_end:\n" );
|
||||
|
||||
/* code segment */
|
||||
|
||||
fprintf( outfile, "\n\t.align %d\n", get_alignment(2) );
|
||||
fprintf( outfile, ".L__wine_spec_code_segment:\n" );
|
||||
output( "\n\t.align %d\n", get_alignment(2) );
|
||||
output( ".L__wine_spec_code_segment:\n" );
|
||||
|
||||
for ( i = 0; i < nb_funcs; i++ )
|
||||
{
|
||||
unsigned int arg_types[2];
|
||||
int j, nop_words, argsize = 0;
|
||||
int nop_words, argsize = 0;
|
||||
|
||||
if ( typelist[i]->type == TYPE_PASCAL )
|
||||
argsize = get_function_argsize( typelist[i] );
|
||||
|
@ -709,9 +709,9 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec )
|
|||
}
|
||||
if (typelist[i]->type == TYPE_VARARGS) arg_types[j / 10] |= ARG_VARARG << (3 * (j % 10));
|
||||
|
||||
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" );
|
||||
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" );
|
||||
|
||||
if (typelist[i]->flags & FLAG_REGISTER)
|
||||
{
|
||||
|
@ -719,90 +719,91 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec )
|
|||
}
|
||||
else if (typelist[i]->flags & FLAG_RET16)
|
||||
{
|
||||
fprintf( outfile, "\torw %%ax,%%ax\n" );
|
||||
fprintf( outfile, "\tnop\n" ); /* so that the lretw is aligned */
|
||||
output( "\torw %%ax,%%ax\n" );
|
||||
output( "\tnop\n" ); /* so that the lretw is aligned */
|
||||
nop_words = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( outfile, "shld $16,%%eax,%%edx\n" );
|
||||
fprintf( outfile, "orl %%eax,%%eax\n" );
|
||||
output( "\tshld $16,%%eax,%%edx\n" );
|
||||
output( "\torl %%eax,%%eax\n" );
|
||||
nop_words = 1;
|
||||
}
|
||||
|
||||
if (argsize)
|
||||
{
|
||||
fprintf( outfile, "lretw $%u\n", argsize );
|
||||
output( "\tlretw $%u\n", argsize );
|
||||
nop_words--;
|
||||
}
|
||||
else fprintf( outfile, "lretw\n" );
|
||||
else output( "\tlretw\n" );
|
||||
|
||||
if (nop_words) fprintf( outfile, "\t%s\n", nop_sequence[nop_words-1] );
|
||||
if (nop_words) output( "\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 */
|
||||
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] );
|
||||
output( "\t%s 0x86c7\n", get_asm_short_keyword() );
|
||||
output( "\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;
|
||||
fprintf( outfile, ".L__wine_%s_%u:\n", make_c_identifier(spec->dll_name), i );
|
||||
fprintf( outfile, "\tpushw %%bp\n" );
|
||||
fprintf( outfile, "\tpushl $%s\n",
|
||||
output( ".L__wine_%s_%u:\n", make_c_identifier(spec->dll_name), i );
|
||||
output( "\tpushw %%bp\n" );
|
||||
output( "\tpushl $%s\n",
|
||||
asm_name( odp->type == TYPE_STUB ? get_stub_name( odp, spec ) : odp->link_name ));
|
||||
fprintf( outfile, "\tcallw .L__wine_spec_callfrom16_%s\n", get_callfrom16_name( odp ) );
|
||||
output( "\tcallw .L__wine_spec_callfrom16_%s\n", get_callfrom16_name( odp ) );
|
||||
}
|
||||
fprintf( outfile, ".L__wine_spec_code_segment_end:\n" );
|
||||
output( ".L__wine_spec_code_segment_end:\n" );
|
||||
|
||||
/* data segment */
|
||||
|
||||
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 */
|
||||
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 */
|
||||
for (i = 0; i <= spec->limit; i++)
|
||||
{
|
||||
ORDDEF *odp = spec->ordinals[i];
|
||||
if (!odp || odp->type != TYPE_VARIABLE) continue;
|
||||
fprintf( outfile, ".L__wine_%s_%u:\n", make_c_identifier(spec->dll_name), i );
|
||||
fprintf( outfile, "\t.long " );
|
||||
output( ".L__wine_%s_%u:\n", make_c_identifier(spec->dll_name), i );
|
||||
output( "\t.long " );
|
||||
for (j = 0; j < odp->u.var.n_values-1; j++)
|
||||
fprintf( outfile, "0x%08x,", odp->u.var.values[j] );
|
||||
fprintf( outfile, "0x%08x\n", odp->u.var.values[j] );
|
||||
output( "0x%08x,", odp->u.var.values[j] );
|
||||
output( "0x%08x\n", odp->u.var.values[j] );
|
||||
}
|
||||
fprintf( outfile, ".L__wine_spec_data_segment_end:\n" );
|
||||
output( ".L__wine_spec_data_segment_end:\n" );
|
||||
|
||||
/* resource data */
|
||||
|
||||
if (spec->nb_resources)
|
||||
{
|
||||
fprintf( outfile, "\n.L__wine_spec_resource_data:\n" );
|
||||
output_res16_data( outfile, spec );
|
||||
output( "\n.L__wine_spec_resource_data:\n" );
|
||||
output_res16_data( spec );
|
||||
}
|
||||
|
||||
fprintf( outfile, "\t.byte 0\n" ); /* make sure the last symbol points to something */
|
||||
output( "\t.byte 0\n" ); /* make sure the last symbol points to something */
|
||||
|
||||
/* relay functions */
|
||||
|
||||
nb_funcs = sort_func_list( typelist, nb_funcs, relay_type_compare );
|
||||
if (nb_funcs)
|
||||
{
|
||||
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/* 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\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( "\n\t%s\n", get_asm_string_section() );
|
||||
output( ".L__wine_spec_file_name:\n" );
|
||||
output( "\t%s \"%s\"\n", get_asm_string_keyword(), spec->file_name );
|
||||
|
||||
output_stubs( outfile, spec );
|
||||
output_get_pc_thunk( outfile );
|
||||
output_init_code( outfile, spec, header_name );
|
||||
output_stubs( spec );
|
||||
output_get_pc_thunk();
|
||||
output_init_code( spec, header_name );
|
||||
output_gnu_stack_note();
|
||||
|
||||
free( typelist );
|
||||
}
|
||||
|
|
|
@ -19,21 +19,20 @@
|
|||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "winglue.h"
|
||||
|
||||
#define EXCEPTION_WINE_STUB 0x80000100 /* stub entry point called */
|
||||
#define EH_NONCONTINUABLE 0x01
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
//#include "wine/exception.h"
|
||||
#include "build.h"
|
||||
|
||||
|
||||
|
@ -52,7 +51,7 @@ static inline int needs_relay( const ORDDEF *odp )
|
|||
/* check if dll will output relay thunks */
|
||||
int has_relays( DLLSPEC *spec )
|
||||
{
|
||||
unsigned int i;
|
||||
int i;
|
||||
|
||||
if (target_cpu != CPU_x86) return 0;
|
||||
|
||||
|
@ -91,30 +90,31 @@ static const char *make_internal_name( const ORDDEF *odp, DLLSPEC *spec, const c
|
|||
*
|
||||
* Output entry points for relay debugging
|
||||
*/
|
||||
static void output_relay_debug( FILE *outfile, DLLSPEC *spec )
|
||||
static void output_relay_debug( DLLSPEC *spec )
|
||||
{
|
||||
unsigned int i, j, args, flags;
|
||||
int i;
|
||||
unsigned int j, args, flags;
|
||||
|
||||
/* first the table of entry point offsets */
|
||||
|
||||
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" );
|
||||
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" );
|
||||
|
||||
for (i = spec->base; i <= spec->limit; i++)
|
||||
{
|
||||
ORDDEF *odp = spec->ordinals[i];
|
||||
|
||||
if (needs_relay( odp ))
|
||||
fprintf( outfile, "\t.long .L__wine_spec_relay_entry_point_%d-__wine_spec_relay_entry_points\n", i );
|
||||
output( "\t.long .L__wine_spec_relay_entry_point_%d-__wine_spec_relay_entry_points\n", i );
|
||||
else
|
||||
fprintf( outfile, "\t.long 0\n" );
|
||||
output( "\t.long 0\n" );
|
||||
}
|
||||
|
||||
/* then the table of argument types */
|
||||
|
||||
fprintf( outfile, "\t.align %d\n", get_alignment(4) );
|
||||
fprintf( outfile, ".L__wine_spec_relay_arg_types:\n" );
|
||||
output( "\t.align %d\n", get_alignment(4) );
|
||||
output( ".L__wine_spec_relay_arg_types:\n" );
|
||||
|
||||
for (i = spec->base; i <= spec->limit; i++)
|
||||
{
|
||||
|
@ -129,14 +129,14 @@ static void output_relay_debug( FILE *outfile, DLLSPEC *spec )
|
|||
if (odp->u.func.arg_types[j] == 'W') mask |= 2<< (j*2);
|
||||
}
|
||||
}
|
||||
fprintf( outfile, "\t.long 0x%08x\n", mask );
|
||||
output( "\t.long 0x%08x\n", mask );
|
||||
}
|
||||
|
||||
/* then the relay thunks */
|
||||
|
||||
fprintf( outfile, "\t.text\n" );
|
||||
fprintf( outfile, "__wine_spec_relay_entry_points:\n" );
|
||||
fprintf( outfile, "\tnop\n" ); /* to avoid 0 offset */
|
||||
output( "\t.text\n" );
|
||||
output( "__wine_spec_relay_entry_points:\n" );
|
||||
output( "\tnop\n" ); /* to avoid 0 offset */
|
||||
|
||||
for (i = spec->base; i <= spec->limit; i++)
|
||||
{
|
||||
|
@ -144,39 +144,39 @@ static void output_relay_debug( FILE *outfile, DLLSPEC *spec )
|
|||
|
||||
if (!needs_relay( odp )) continue;
|
||||
|
||||
fprintf( outfile, "\t.align %d\n", get_alignment(4) );
|
||||
fprintf( outfile, ".L__wine_spec_relay_entry_point_%d:\n", i );
|
||||
output( "\t.align %d\n", get_alignment(4) );
|
||||
output( ".L__wine_spec_relay_entry_point_%d:\n", i );
|
||||
|
||||
if (odp->flags & FLAG_REGISTER)
|
||||
fprintf( outfile, "\tpushl %%eax\n" );
|
||||
output( "\tpushl %%eax\n" );
|
||||
else
|
||||
fprintf( outfile, "\tpushl %%esp\n" );
|
||||
output( "\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;
|
||||
fprintf( outfile, "\tpushl $%u\n", (flags << 24) | (args << 16) | (i - spec->base) );
|
||||
output( "\tpushl $%u\n", (flags << 24) | (args << 16) | (i - spec->base) );
|
||||
|
||||
if (UsePIC)
|
||||
{
|
||||
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" );
|
||||
output( "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") );
|
||||
output( "1:\tleal .L__wine_spec_relay_descr-1b(%%eax),%%eax\n" );
|
||||
}
|
||||
else fprintf( outfile, "\tmovl $.L__wine_spec_relay_descr,%%eax\n" );
|
||||
fprintf( outfile, "\tpushl %%eax\n" );
|
||||
else output( "\tmovl $.L__wine_spec_relay_descr,%%eax\n" );
|
||||
output( "\tpushl %%eax\n" );
|
||||
|
||||
if (odp->flags & FLAG_REGISTER)
|
||||
{
|
||||
fprintf( outfile, "\tcall *8(%%eax)\n" );
|
||||
output( "\tcall *8(%%eax)\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( outfile, "\tcall *4(%%eax)\n" );
|
||||
output( "\tcall *4(%%eax)\n" );
|
||||
if (odp->type == TYPE_STDCALL)
|
||||
fprintf( outfile, "\tret $%u\n", args * get_ptr_size() );
|
||||
output( "\tret $%u\n", args * get_ptr_size() );
|
||||
else
|
||||
fprintf( outfile, "\tret\n" );
|
||||
output( "\tret\n" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -186,46 +186,46 @@ static void output_relay_debug( FILE *outfile, DLLSPEC *spec )
|
|||
*
|
||||
* Output the export table for a Win32 module.
|
||||
*/
|
||||
static void output_exports( FILE *outfile, DLLSPEC *spec )
|
||||
static void output_exports( DLLSPEC *spec )
|
||||
{
|
||||
int i, fwd_size = 0;
|
||||
int nr_exports = spec->base <= spec->limit ? spec->limit - spec->base + 1 : 0;
|
||||
|
||||
if (!nr_exports) return;
|
||||
|
||||
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" );
|
||||
output( "\n/* export table */\n\n" );
|
||||
output( "\t.data\n" );
|
||||
output( "\t.align %d\n", get_alignment(4) );
|
||||
output( ".L__wine_spec_exports:\n" );
|
||||
|
||||
/* export directory header */
|
||||
|
||||
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 */
|
||||
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 */
|
||||
if (spec->nb_names)
|
||||
{
|
||||
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 */
|
||||
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 */
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( outfile, "\t.long 0\n" ); /* AddressOfNames */
|
||||
fprintf( outfile, "\t.long 0\n" ); /* AddressOfNameOrdinals */
|
||||
output( "\t.long 0\n" ); /* AddressOfNames */
|
||||
output( "\t.long 0\n" ); /* AddressOfNameOrdinals */
|
||||
}
|
||||
|
||||
/* output the function pointers */
|
||||
|
||||
fprintf( outfile, "\n.L__wine_spec_exports_funcs:\n" );
|
||||
output( "\n.L__wine_spec_exports_funcs:\n" );
|
||||
for (i = spec->base; i <= spec->limit; i++)
|
||||
{
|
||||
ORDDEF *odp = spec->ordinals[i];
|
||||
if (!odp) fprintf( outfile, "\t.long 0\n" );
|
||||
if (!odp) output( "\t%s 0\n", get_asm_ptr_keyword() );
|
||||
else switch(odp->type)
|
||||
{
|
||||
case TYPE_EXTERN:
|
||||
|
@ -234,21 +234,21 @@ static void output_exports( FILE *outfile, DLLSPEC *spec )
|
|||
case TYPE_CDECL:
|
||||
if (odp->flags & FLAG_FORWARD)
|
||||
{
|
||||
fprintf( outfile, "\t%s .L__wine_spec_forwards+%u\n", get_asm_ptr_keyword(), fwd_size );
|
||||
output( "\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)
|
||||
{
|
||||
fprintf( outfile, "\t%s %s_%s\n",
|
||||
output( "\t%s %s_%s\n",
|
||||
get_asm_ptr_keyword(), asm_name("__wine_spec_ext_link"), odp->link_name );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( outfile, "\t%s %s\n", get_asm_ptr_keyword(), asm_name(odp->link_name) );
|
||||
output( "\t%s %s\n", get_asm_ptr_keyword(), asm_name(odp->link_name) );
|
||||
}
|
||||
break;
|
||||
case TYPE_STUB:
|
||||
fprintf( outfile, "\t%s %s\n", get_asm_ptr_keyword(),
|
||||
output( "\t%s %s\n", get_asm_ptr_keyword(),
|
||||
asm_name( get_stub_name( odp, spec )) );
|
||||
break;
|
||||
default:
|
||||
|
@ -262,68 +262,68 @@ static void output_exports( FILE *outfile, DLLSPEC *spec )
|
|||
|
||||
int namepos = strlen(spec->file_name) + 1;
|
||||
|
||||
fprintf( outfile, "\n.L__wine_spec_exp_name_ptrs:\n" );
|
||||
output( "\n.L__wine_spec_exp_name_ptrs:\n" );
|
||||
for (i = 0; i < spec->nb_names; i++)
|
||||
{
|
||||
fprintf( outfile, "\t.long .L__wine_spec_exp_names+%u-.L__wine_spec_rva_base\n", namepos );
|
||||
output( "\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 */
|
||||
|
||||
fprintf( outfile, "\n.L__wine_spec_exp_ordinals:\n" );
|
||||
output( "\n.L__wine_spec_exp_ordinals:\n" );
|
||||
for (i = 0; i < spec->nb_names; i++)
|
||||
{
|
||||
fprintf( outfile, "\t%s %d\n",
|
||||
output( "\t%s %d\n",
|
||||
get_asm_short_keyword(), spec->names[i]->ordinal - spec->base );
|
||||
}
|
||||
if (spec->nb_names % 2)
|
||||
{
|
||||
fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() );
|
||||
output( "\t%s 0\n", get_asm_short_keyword() );
|
||||
}
|
||||
}
|
||||
|
||||
/* output the export name strings */
|
||||
|
||||
fprintf( outfile, "\n.L__wine_spec_exp_names:\n" );
|
||||
fprintf( outfile, "\t%s \"%s\"\n", get_asm_string_keyword(), spec->file_name );
|
||||
output( "\n.L__wine_spec_exp_names:\n" );
|
||||
output( "\t%s \"%s\"\n", get_asm_string_keyword(), spec->file_name );
|
||||
for (i = 0; i < spec->nb_names; i++)
|
||||
fprintf( outfile, "\t%s \"%s\"\n",
|
||||
output( "\t%s \"%s\"\n",
|
||||
get_asm_string_keyword(), spec->names[i]->name );
|
||||
|
||||
/* output forward strings */
|
||||
|
||||
if (fwd_size)
|
||||
{
|
||||
fprintf( outfile, "\n.L__wine_spec_forwards:\n" );
|
||||
output( "\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))
|
||||
fprintf( outfile, "\t%s \"%s\"\n", get_asm_string_keyword(), odp->link_name );
|
||||
output( "\t%s \"%s\"\n", get_asm_string_keyword(), odp->link_name );
|
||||
}
|
||||
}
|
||||
fprintf( outfile, "\t.align %d\n", get_alignment(get_ptr_size()) );
|
||||
fprintf( outfile, ".L__wine_spec_exports_end:\n" );
|
||||
output( "\t.align %d\n", get_alignment(get_ptr_size()) );
|
||||
output( ".L__wine_spec_exports_end:\n" );
|
||||
|
||||
/* output relays */
|
||||
|
||||
/* we only support relay debugging on i386 */
|
||||
if (target_cpu != CPU_x86)
|
||||
{
|
||||
fprintf( outfile, "\t%s 0\n", get_asm_ptr_keyword() );
|
||||
output( "\t%s 0\n", get_asm_ptr_keyword() );
|
||||
return;
|
||||
}
|
||||
|
||||
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( ".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() );
|
||||
|
||||
output_relay_debug( outfile, spec );
|
||||
output_relay_debug( spec );
|
||||
}
|
||||
|
||||
|
||||
|
@ -332,7 +332,7 @@ static void output_exports( FILE *outfile, DLLSPEC *spec )
|
|||
*
|
||||
* Output the functions for stub entry points
|
||||
*/
|
||||
static void output_stub_funcs( FILE *outfile, DLLSPEC *spec )
|
||||
static void output_stub_funcs( DLLSPEC *spec )
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -354,13 +354,13 @@ static void output_stub_funcs( FILE *outfile, DLLSPEC *spec )
|
|||
{
|
||||
const ORDDEF *odp = &spec->entry_points[i];
|
||||
if (odp->type != TYPE_STUB) continue;
|
||||
fprintf( outfile, "void %s(void) ", make_internal_name( odp, spec, "stub" ) );
|
||||
output( "void %s(void) ", make_internal_name( odp, spec, "stub" ) );
|
||||
if (odp->name)
|
||||
fprintf( outfile, "{ __wine_spec_unimplemented_stub(__wine_spec_file_name, \"%s\"); }\n", odp->name );
|
||||
output( "{ __wine_spec_unimplemented_stub(__wine_spec_file_name, \"%s\"); }\n", odp->name );
|
||||
else if (odp->export_name)
|
||||
fprintf( outfile, "{ __wine_spec_unimplemented_stub(__wine_spec_file_name, \"%s\"); }\n", odp->export_name );
|
||||
output( "{ __wine_spec_unimplemented_stub(__wine_spec_file_name, \"%s\"); }\n", odp->export_name );
|
||||
else
|
||||
fprintf( outfile, "{ __wine_spec_unimplemented_stub(__wine_spec_file_name, \"%d\"); }\n", odp->ordinal );
|
||||
output( "{ __wine_spec_unimplemented_stub(__wine_spec_file_name, \"%d\"); }\n", odp->ordinal );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -370,33 +370,33 @@ static void output_stub_funcs( FILE *outfile, DLLSPEC *spec )
|
|||
*
|
||||
* Output code for calling a dll constructor.
|
||||
*/
|
||||
static void output_asm_constructor( FILE *outfile, const char *constructor )
|
||||
static void output_asm_constructor( const char *constructor )
|
||||
{
|
||||
if (target_platform == PLATFORM_APPLE)
|
||||
{
|
||||
/* Mach-O doesn't have an init section */
|
||||
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) );
|
||||
output( "\n\t.mod_init_func\n" );
|
||||
output( "\t.align %d\n", get_alignment(4) );
|
||||
output( "\t.long %s\n", asm_name(constructor) );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( outfile, "\n\t.section \".init\",\"ax\"\n" );
|
||||
output( "\n\t.section \".init\",\"ax\"\n" );
|
||||
switch(target_cpu)
|
||||
{
|
||||
case CPU_x86:
|
||||
case CPU_x86_64:
|
||||
fprintf( outfile, "\tcall %s\n", asm_name(constructor) );
|
||||
output( "\tcall %s\n", asm_name(constructor) );
|
||||
break;
|
||||
case CPU_SPARC:
|
||||
fprintf( outfile, "\tcall %s\n", asm_name(constructor) );
|
||||
fprintf( outfile, "\tnop\n" );
|
||||
output( "\tcall %s\n", asm_name(constructor) );
|
||||
output( "\tnop\n" );
|
||||
break;
|
||||
case CPU_ALPHA:
|
||||
fprintf( outfile, "\tjsr $26,%s\n", asm_name(constructor) );
|
||||
output( "\tjsr $26,%s\n", asm_name(constructor) );
|
||||
break;
|
||||
case CPU_POWERPC:
|
||||
fprintf( outfile, "\tbl %s\n", asm_name(constructor) );
|
||||
output( "\tbl %s\n", asm_name(constructor) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -408,32 +408,32 @@ static void output_asm_constructor( FILE *outfile, const char *constructor )
|
|||
*
|
||||
* Build a Win32 C file from a spec file.
|
||||
*/
|
||||
void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
|
||||
void BuildSpec32File( DLLSPEC *spec )
|
||||
{
|
||||
int machine = 0;
|
||||
unsigned int page_size = get_page_size();
|
||||
|
||||
resolve_imports( spec );
|
||||
output_standard_file_header( outfile );
|
||||
output_standard_file_header();
|
||||
|
||||
/* Reserve some space for the PE header */
|
||||
|
||||
fprintf( outfile, "\t.text\n" );
|
||||
fprintf( outfile, "\t.align %d\n", get_alignment(page_size) );
|
||||
fprintf( outfile, "__wine_spec_pe_header:\n" );
|
||||
output( "\t.text\n" );
|
||||
output( "\t.align %d\n", get_alignment(page_size) );
|
||||
output( "__wine_spec_pe_header:\n" );
|
||||
if (target_platform == PLATFORM_APPLE)
|
||||
fprintf( outfile, "\t.space 65536\n" );
|
||||
output( "\t.space 65536\n" );
|
||||
else
|
||||
fprintf( outfile, "\t.skip 65536\n" );
|
||||
output( "\t.skip 65536\n" );
|
||||
|
||||
/* Output the NT header */
|
||||
|
||||
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( "\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, "\t.long 0x%04x\n", IMAGE_NT_SIGNATURE ); /* Signature */
|
||||
output( "\t.long 0x%04x\n", IMAGE_NT_SIGNATURE ); /* Signature */
|
||||
switch(target_cpu)
|
||||
{
|
||||
case CPU_x86: machine = IMAGE_FILE_MACHINE_I386; break;
|
||||
|
@ -442,104 +442,105 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
|
|||
case CPU_ALPHA: machine = IMAGE_FILE_MACHINE_ALPHA; break;
|
||||
case CPU_SPARC: machine = IMAGE_FILE_MACHINE_UNKNOWN; break;
|
||||
}
|
||||
fprintf( outfile, "\t%s 0x%04x\n", /* Machine */
|
||||
output( "\t%s 0x%04x\n", /* Machine */
|
||||
get_asm_short_keyword(), machine );
|
||||
fprintf( outfile, "\t%s 0\n", /* NumberOfSections */
|
||||
output( "\t%s 0\n", /* NumberOfSections */
|
||||
get_asm_short_keyword() );
|
||||
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 */
|
||||
output( "\t.long 0\n" ); /* TimeDateStamp */
|
||||
output( "\t.long 0\n" ); /* PointerToSymbolTable */
|
||||
output( "\t.long 0\n" ); /* NumberOfSymbols */
|
||||
output( "\t%s %d\n", /* SizeOfOptionalHeader */
|
||||
get_asm_short_keyword(),
|
||||
get_ptr_size() == 8 ? IMAGE_SIZEOF_NT_OPTIONAL64_HEADER : IMAGE_SIZEOF_NT_OPTIONAL32_HEADER );
|
||||
fprintf( outfile, "\t%s 0x%04x\n", /* Characteristics */
|
||||
output( "\t%s 0x%04x\n", /* Characteristics */
|
||||
get_asm_short_keyword(), spec->characteristics );
|
||||
fprintf( outfile, "\t%s 0x%04x\n", /* Magic */
|
||||
output( "\t%s 0x%04x\n", /* Magic */
|
||||
get_asm_short_keyword(),
|
||||
get_ptr_size() == 8 ? IMAGE_NT_OPTIONAL_HDR64_MAGIC : IMAGE_NT_OPTIONAL_HDR32_MAGIC );
|
||||
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 */
|
||||
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 */
|
||||
/* note: we expand the AddressOfEntryPoint field on 64-bit by overwriting the BaseOfCode field */
|
||||
fprintf( outfile, "\t%s %s\n", /* AddressOfEntryPoint */
|
||||
output( "\t%s %s\n", /* AddressOfEntryPoint */
|
||||
get_asm_ptr_keyword(), asm_name(spec->init_func) );
|
||||
if (get_ptr_size() == 4)
|
||||
{
|
||||
fprintf( outfile, "\t.long 0\n" ); /* BaseOfCode */
|
||||
fprintf( outfile, "\t.long 0\n" ); /* BaseOfData */
|
||||
output( "\t.long 0\n" ); /* BaseOfCode */
|
||||
output( "\t.long 0\n" ); /* BaseOfData */
|
||||
}
|
||||
fprintf( outfile, "\t%s __wine_spec_pe_header\n", /* ImageBase */
|
||||
output( "\t%s __wine_spec_pe_header\n", /* ImageBase */
|
||||
get_asm_ptr_keyword() );
|
||||
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 */
|
||||
output( "\t.long %u\n", page_size ); /* SectionAlignment */
|
||||
output( "\t.long %u\n", page_size ); /* FileAlignment */
|
||||
output( "\t%s 1,0\n", /* Major/MinorOperatingSystemVersion */
|
||||
get_asm_short_keyword() );
|
||||
fprintf( outfile, "\t%s 0,0\n", /* Major/MinorImageVersion */
|
||||
output( "\t%s 0,0\n", /* Major/MinorImageVersion */
|
||||
get_asm_short_keyword() );
|
||||
fprintf( outfile, "\t%s %u,%u\n", /* Major/MinorSubsystemVersion */
|
||||
output( "\t%s %u,%u\n", /* Major/MinorSubsystemVersion */
|
||||
get_asm_short_keyword(), spec->subsystem_major, spec->subsystem_minor );
|
||||
fprintf( outfile, "\t.long 0\n" ); /* Win32VersionValue */
|
||||
fprintf( outfile, "\t.long %s-.L__wine_spec_rva_base\n", /* SizeOfImage */
|
||||
output( "\t.long 0\n" ); /* Win32VersionValue */
|
||||
output( "\t.long %s-.L__wine_spec_rva_base\n", /* SizeOfImage */
|
||||
asm_name("_end") );
|
||||
fprintf( outfile, "\t.long %u\n", page_size ); /* SizeOfHeaders */
|
||||
fprintf( outfile, "\t.long 0\n" ); /* CheckSum */
|
||||
fprintf( outfile, "\t%s 0x%04x\n", /* Subsystem */
|
||||
output( "\t.long %u\n", page_size ); /* SizeOfHeaders */
|
||||
output( "\t.long 0\n" ); /* CheckSum */
|
||||
output( "\t%s 0x%04x\n", /* Subsystem */
|
||||
get_asm_short_keyword(), spec->subsystem );
|
||||
fprintf( outfile, "\t%s 0\n", /* DllCharacteristics */
|
||||
get_asm_short_keyword() );
|
||||
fprintf( outfile, "\t%s %u,%u\n", /* SizeOfStackReserve/Commit */
|
||||
output( "\t%s 0x%04x\n", /* DllCharacteristics */
|
||||
get_asm_short_keyword(), spec->dll_characteristics );
|
||||
output( "\t%s %u,%u\n", /* SizeOfStackReserve/Commit */
|
||||
get_asm_ptr_keyword(), (spec->stack_size ? spec->stack_size : 1024) * 1024, page_size );
|
||||
fprintf( outfile, "\t%s %u,%u\n", /* SizeOfHeapReserve/Commit */
|
||||
output( "\t%s %u,%u\n", /* SizeOfHeapReserve/Commit */
|
||||
get_asm_ptr_keyword(), (spec->heap_size ? spec->heap_size : 1024) * 1024, page_size );
|
||||
fprintf( outfile, "\t.long 0\n" ); /* LoaderFlags */
|
||||
fprintf( outfile, "\t.long 16\n" ); /* NumberOfRvaAndSizes */
|
||||
output( "\t.long 0\n" ); /* LoaderFlags */
|
||||
output( "\t.long 16\n" ); /* NumberOfRvaAndSizes */
|
||||
|
||||
if (spec->base <= spec->limit) /* DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT] */
|
||||
fprintf( outfile, "\t.long .L__wine_spec_exports-.L__wine_spec_rva_base,"
|
||||
output( "\t.long .L__wine_spec_exports-.L__wine_spec_rva_base,"
|
||||
".L__wine_spec_exports_end-.L__wine_spec_exports\n" );
|
||||
else
|
||||
fprintf( outfile, "\t.long 0,0\n" );
|
||||
output( "\t.long 0,0\n" );
|
||||
|
||||
if (has_imports()) /* DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] */
|
||||
fprintf( outfile, "\t.long .L__wine_spec_imports-.L__wine_spec_rva_base,"
|
||||
output( "\t.long .L__wine_spec_imports-.L__wine_spec_rva_base,"
|
||||
".L__wine_spec_imports_end-.L__wine_spec_imports\n" );
|
||||
else
|
||||
fprintf( outfile, "\t.long 0,0\n" );
|
||||
output( "\t.long 0,0\n" );
|
||||
|
||||
if (spec->nb_resources) /* DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE] */
|
||||
fprintf( outfile, "\t.long .L__wine_spec_resources-.L__wine_spec_rva_base,"
|
||||
output( "\t.long .L__wine_spec_resources-.L__wine_spec_rva_base,"
|
||||
".L__wine_spec_resources_end-.L__wine_spec_resources\n" );
|
||||
else
|
||||
fprintf( outfile, "\t.long 0,0\n" );
|
||||
output( "\t.long 0,0\n" );
|
||||
|
||||
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( "\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, "\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 );
|
||||
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 );
|
||||
if (target_platform == PLATFORM_APPLE)
|
||||
fprintf( outfile, "\t.lcomm %s,4\n", asm_name("_end") );
|
||||
output( "\t.lcomm %s,4\n", asm_name("_end") );
|
||||
|
||||
output_stubs( outfile, spec );
|
||||
output_exports( outfile, spec );
|
||||
output_imports( outfile, spec );
|
||||
output_resources( outfile, spec );
|
||||
output_asm_constructor( outfile, "__wine_spec_init_ctor" );
|
||||
output_stubs( spec );
|
||||
output_exports( spec );
|
||||
output_imports( spec );
|
||||
output_resources( spec );
|
||||
output_asm_constructor( "__wine_spec_init_ctor" );
|
||||
output_gnu_stack_note();
|
||||
}
|
||||
|
||||
|
||||
|
@ -548,20 +549,19 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
|
|||
*
|
||||
* Build a Win32 def file from a spec file.
|
||||
*/
|
||||
void BuildDef32File( FILE *outfile, DLLSPEC *spec )
|
||||
void BuildDef32File( DLLSPEC *spec )
|
||||
{
|
||||
const char *name;
|
||||
int i, total;
|
||||
|
||||
if (spec_file_name)
|
||||
fprintf( outfile, "; File generated automatically from %s; do not edit!\n\n",
|
||||
output( "; File generated automatically from %s; do not edit!\n\n",
|
||||
spec_file_name );
|
||||
else
|
||||
fprintf( outfile, "; File generated automatically; do not edit!\n\n" );
|
||||
output( "; File generated automatically; do not edit!\n\n" );
|
||||
|
||||
fprintf(outfile, "LIBRARY %s\n\n", spec->file_name);
|
||||
|
||||
fprintf(outfile, "EXPORTS\n");
|
||||
output( "LIBRARY %s\n\n", spec->file_name);
|
||||
output( "EXPORTS\n");
|
||||
|
||||
/* Output the exports and relay entry points */
|
||||
|
||||
|
@ -573,13 +573,13 @@ void BuildDef32File( FILE *outfile, 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 name = make_internal_name( odp, spec, "noname_export" );
|
||||
else continue;
|
||||
|
||||
if (!(odp->flags & FLAG_PRIVATE)) total++;
|
||||
|
||||
fprintf(outfile, " %s", name);
|
||||
|
||||
output( " %s", name );
|
||||
|
||||
switch(odp->type)
|
||||
{
|
||||
|
@ -590,20 +590,20 @@ void BuildDef32File( FILE *outfile, DLLSPEC *spec )
|
|||
case TYPE_CDECL:
|
||||
/* try to reduce output */
|
||||
if(strcmp(name, odp->link_name) || (odp->flags & FLAG_FORWARD))
|
||||
fprintf(outfile, "=%s", odp->link_name);
|
||||
output( "=%s", odp->link_name );
|
||||
break;
|
||||
case TYPE_STDCALL:
|
||||
{
|
||||
int at_param = strlen(odp->u.func.arg_types) * get_ptr_size();
|
||||
if (!kill_at) fprintf(outfile, "@%d", at_param);
|
||||
if (!kill_at) output( "@%d", at_param );
|
||||
if (odp->flags & FLAG_FORWARD)
|
||||
{
|
||||
fprintf(outfile, "=%s", odp->link_name);
|
||||
output( "=%s", odp->link_name );
|
||||
}
|
||||
else if (strcmp(name, odp->link_name)) /* try to reduce output */
|
||||
{
|
||||
fprintf(outfile, "=%s", odp->link_name);
|
||||
if (!kill_at) fprintf(outfile, "@%d", at_param);
|
||||
output( "=%s", odp->link_name );
|
||||
if (!kill_at) output( "@%d", at_param );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -620,30 +620,23 @@ void BuildDef32File( FILE *outfile, DLLSPEC *spec )
|
|||
if (name != check && check != name + strlen(name) &&
|
||||
'@' == check[-1])
|
||||
{
|
||||
fprintf(outfile, "%s", check - 1);
|
||||
output("%s", check - 1);
|
||||
}
|
||||
}
|
||||
if (NULL != odp->name)
|
||||
{
|
||||
fprintf(outfile, "=%s", make_internal_name( odp, spec, "stub" ));
|
||||
output("=%s", make_internal_name( odp, spec, "stub" ));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
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" );
|
||||
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" );
|
||||
}
|
||||
if (!total) warning( "%s: Import library doesn't export anything\n", spec->file_name );
|
||||
}
|
||||
|
@ -654,34 +647,34 @@ void BuildDef32File( FILE *outfile, DLLSPEC *spec )
|
|||
*
|
||||
* Build a PE DLL C file from a spec file.
|
||||
*/
|
||||
void BuildPedllFile( FILE *outfile, DLLSPEC *spec )
|
||||
void BuildPedllFile( DLLSPEC *spec )
|
||||
{
|
||||
int nr_exports;
|
||||
|
||||
nr_exports = spec->base <= spec->limit ? spec->limit - spec->base + 1 : 0;
|
||||
output_standard_file_header( outfile );
|
||||
output_standard_file_header();
|
||||
|
||||
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( "#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, "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( "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, "static const char __wine_spec_file_name[] = \"%s\";\n\n", spec->file_name );
|
||||
output( "static const char __wine_spec_file_name[] = \"%s\";\n\n", spec->file_name );
|
||||
|
||||
if (nr_exports)
|
||||
{
|
||||
/* Output the stub functions */
|
||||
|
||||
output_stub_funcs( outfile, spec );
|
||||
output_stub_funcs( spec );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,14 +15,11 @@
|
|||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#if !defined(WIN32)
|
||||
#undef strdup
|
||||
#endif
|
||||
#include "wine/port.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
@ -34,6 +31,8 @@
|
|||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "windef.h"
|
||||
#include "winnt.h"
|
||||
#include "build.h"
|
||||
|
||||
#define MAX_TMP_FILES 8
|
||||
|
@ -165,6 +164,18 @@ 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 )
|
||||
{
|
||||
|
@ -196,31 +207,29 @@ char *get_temp_file_name( const char *prefix, const char *suffix )
|
|||
}
|
||||
|
||||
/* output a standard header for generated files */
|
||||
void output_standard_file_header( FILE *outfile )
|
||||
void output_standard_file_header(void)
|
||||
{
|
||||
if (spec_file_name)
|
||||
fprintf( outfile, "/* File generated automatically from %s; do not edit! */\n",
|
||||
spec_file_name );
|
||||
output( "/* File generated automatically from %s; do not edit! */\n", spec_file_name );
|
||||
else
|
||||
fprintf( outfile, "/* File generated automatically; do not edit! */\n" );
|
||||
fprintf( outfile,
|
||||
"/* This file can be copied, modified and distributed without restriction. */\n\n" );
|
||||
output( "/* File generated automatically; do not edit! */\n" );
|
||||
output( "/* This file can be copied, modified and distributed without restriction. */\n\n" );
|
||||
}
|
||||
|
||||
/* dump a byte stream into the assembly code */
|
||||
void dump_bytes( FILE *outfile, const void *buffer, unsigned int size )
|
||||
void dump_bytes( const void *buffer, unsigned int size )
|
||||
{
|
||||
unsigned int i;
|
||||
const unsigned char *ptr = buffer;
|
||||
|
||||
if (!size) return;
|
||||
fprintf( outfile, "\t.byte " );
|
||||
output( "\t.byte " );
|
||||
for (i = 0; i < size - 1; i++, ptr++)
|
||||
{
|
||||
if ((i % 16) == 15) fprintf( outfile, "0x%02x\n\t.byte ", *ptr );
|
||||
else fprintf( outfile, "0x%02x,", *ptr );
|
||||
if ((i % 16) == 15) output( "0x%02x\n\t.byte ", *ptr );
|
||||
else output( "0x%02x,", *ptr );
|
||||
}
|
||||
fprintf( outfile, "0x%02x\n", *ptr );
|
||||
output( "0x%02x\n", *ptr );
|
||||
}
|
||||
|
||||
|
||||
|
@ -324,7 +333,12 @@ DLLSPEC *alloc_dll_spec(void)
|
|||
spec->alloc_entry_points = 0;
|
||||
spec->nb_names = 0;
|
||||
spec->nb_resources = 0;
|
||||
spec->characteristics = 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->subsystem = 0;
|
||||
spec->subsystem_major = 4;
|
||||
spec->subsystem_minor = 0;
|
||||
|
@ -444,7 +458,7 @@ unsigned int get_alignment(unsigned int align)
|
|||
case CPU_POWERPC:
|
||||
case CPU_ALPHA:
|
||||
n = 0;
|
||||
while ((1 << n) != align) n++;
|
||||
while ((1u << n) != align) n++;
|
||||
return n;
|
||||
}
|
||||
/* unreached */
|
||||
|
@ -523,7 +537,7 @@ const char *func_declaration( const char *func )
|
|||
}
|
||||
|
||||
/* output a size declaration for an assembly function */
|
||||
void output_function_size( FILE *outfile, const char *name )
|
||||
void output_function_size( const char *name )
|
||||
{
|
||||
switch (target_platform)
|
||||
{
|
||||
|
@ -531,7 +545,21 @@ void output_function_size( FILE *outfile, const char *name )
|
|||
case PLATFORM_WINDOWS:
|
||||
break;
|
||||
default:
|
||||
fprintf( outfile, "\t.size %s, .-%s\n", name, name );
|
||||
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" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,11 +73,11 @@ Specify the module entry point function; if not specified, the default
|
|||
is
|
||||
.B DllMain
|
||||
for dlls, and
|
||||
.B WinMain
|
||||
for executables (if
|
||||
.B WinMain
|
||||
is not defined, the standard C
|
||||
.B main
|
||||
for executables (if the standard C
|
||||
.B main
|
||||
is not defined,
|
||||
.B WinMain
|
||||
is used instead). This is only valid for Win32 modules.
|
||||
.TP
|
||||
.BI \-E,\ --export= filename
|
||||
|
@ -85,6 +85,14 @@ 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
|
||||
|
@ -145,6 +153,10 @@ 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
|
||||
|
@ -248,7 +260,8 @@ The entry point is not displayed in relay debugging traces (Win32
|
|||
only).
|
||||
.TP
|
||||
.B -noname
|
||||
The entry point will be imported by ordinal instead of by name.
|
||||
The entry point will be exported by ordinal instead of by name. The
|
||||
name is still available for importing.
|
||||
.TP
|
||||
.B -ret16
|
||||
The function returns a 16-bit value (Win16 only).
|
||||
|
@ -265,6 +278,10 @@ 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
|
||||
|
|
|
@ -1,132 +1,10 @@
|
|||
#ifndef _WINGLUE_H
|
||||
#define _WINGLUE_H
|
||||
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned long DWORD;
|
||||
typedef unsigned short WCHAR;
|
||||
#if defined(_WIN64)
|
||||
typedef unsigned __int64 UINT_PTR;
|
||||
#else
|
||||
typedef unsigned int UINT_PTR;
|
||||
#endif
|
||||
|
||||
#define LOBYTE(w) ((BYTE)(w))
|
||||
#define HIBYTE(w) ((BYTE)(((WORD)(w)>>8)&0xFF))
|
||||
|
||||
#define DLL_PROCESS_ATTACH 1
|
||||
#define DLL_PROCESS_DETACH 0
|
||||
|
||||
#define IMAGE_FILE_DLL 8192
|
||||
#define IMAGE_SUBSYSTEM_NATIVE 1
|
||||
#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2
|
||||
#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3
|
||||
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
|
||||
#define IMAGE_FILE_MACHINE_UNKNOWN 0
|
||||
#define IMAGE_FILE_MACHINE_I386 0x014c
|
||||
/* Stuff missing in the host's PSDK */
|
||||
#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT 0x0100
|
||||
#define IMAGE_FILE_MACHINE_ALPHA 0x0184
|
||||
#define IMAGE_FILE_MACHINE_POWERPC 0x01f0
|
||||
#define IMAGE_FILE_MACHINE_AMD64 0x8664
|
||||
#define IMAGE_NT_SIGNATURE 0x00004550
|
||||
#define IMAGE_SIZEOF_NT_OPTIONAL32_HEADER 224
|
||||
#define IMAGE_SIZEOF_NT_OPTIONAL64_HEADER 240
|
||||
#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b
|
||||
#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b
|
||||
#if defined(_WIN64)
|
||||
#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER IMAGE_SIZEOF_NT_OPTIONAL64_HEADER
|
||||
#define IMAGE_NT_OPTIONAL_HDR_MAGIC IMAGE_NT_OPTIONAL_HDR64_MAGIC
|
||||
#else
|
||||
#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER IMAGE_SIZEOF_NT_OPTIONAL32_HEADER
|
||||
#define IMAGE_NT_OPTIONAL_HDR_MAGIC IMAGE_NT_OPTIONAL_HDR32_MAGIC
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#ifndef NONAMELESSUNION
|
||||
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95)
|
||||
#define _ANONYMOUS_UNION __extension__
|
||||
#define _ANONYMOUS_STRUCT __extension__
|
||||
#else
|
||||
#if defined(__cplusplus)
|
||||
#define _ANONYMOUS_UNION __extension__
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) */
|
||||
#endif /* NONAMELESSUNION */
|
||||
#elif defined(__WATCOMC__) || defined(_MSC_VER)
|
||||
#define _ANONYMOUS_UNION
|
||||
#define _ANONYMOUS_STRUCT
|
||||
#endif /* __GNUC__/__WATCOMC__ */
|
||||
#ifndef _ANONYMOUS_UNION
|
||||
#define _ANONYMOUS_UNION
|
||||
#define _UNION_NAME(x) x
|
||||
#define DUMMYUNIONNAME u
|
||||
#define DUMMYUNIONNAME2 u2
|
||||
#define DUMMYUNIONNAME3 u3
|
||||
#define DUMMYUNIONNAME4 u4
|
||||
#define DUMMYUNIONNAME5 u5
|
||||
#define DUMMYUNIONNAME6 u6
|
||||
#define DUMMYUNIONNAME7 u7
|
||||
#define DUMMYUNIONNAME8 u8
|
||||
#else
|
||||
#define _UNION_NAME(x)
|
||||
#define DUMMYUNIONNAME
|
||||
#define DUMMYUNIONNAME2
|
||||
#define DUMMYUNIONNAME3
|
||||
#define DUMMYUNIONNAME4
|
||||
#define DUMMYUNIONNAME5
|
||||
#define DUMMYUNIONNAME6
|
||||
#define DUMMYUNIONNAME7
|
||||
#define DUMMYUNIONNAME8
|
||||
#endif
|
||||
#ifndef _ANONYMOUS_STRUCT
|
||||
#define _ANONYMOUS_STRUCT
|
||||
#define _STRUCT_NAME(x) x
|
||||
#define DUMMYSTRUCTNAME s
|
||||
#define DUMMYSTRUCTNAME2 s2
|
||||
#define DUMMYSTRUCTNAME3 s3
|
||||
#else
|
||||
#define _STRUCT_NAME(x)
|
||||
#define DUMMYSTRUCTNAME
|
||||
#define DUMMYSTRUCTNAME2
|
||||
#define DUMMYSTRUCTNAME3
|
||||
#endif
|
||||
|
||||
typedef struct _IMAGE_RESOURCE_DIRECTORY {
|
||||
DWORD Characteristics;
|
||||
DWORD TimeDateStamp;
|
||||
WORD MajorVersion;
|
||||
WORD MinorVersion;
|
||||
WORD NumberOfNamedEntries;
|
||||
WORD NumberOfIdEntries;
|
||||
} IMAGE_RESOURCE_DIRECTORY,*PIMAGE_RESOURCE_DIRECTORY;
|
||||
_ANONYMOUS_STRUCT typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY {
|
||||
_ANONYMOUS_UNION union {
|
||||
_ANONYMOUS_STRUCT struct {
|
||||
DWORD NameOffset:31;
|
||||
DWORD NameIsString:1;
|
||||
}DUMMYSTRUCTNAME;
|
||||
DWORD Name;
|
||||
WORD Id;
|
||||
} DUMMYUNIONNAME;
|
||||
_ANONYMOUS_UNION union {
|
||||
DWORD OffsetToData;
|
||||
_ANONYMOUS_STRUCT struct {
|
||||
DWORD OffsetToDirectory:31;
|
||||
DWORD DataIsDirectory:1;
|
||||
} DUMMYSTRUCTNAME2;
|
||||
} DUMMYUNIONNAME2;
|
||||
} IMAGE_RESOURCE_DIRECTORY_ENTRY,*PIMAGE_RESOURCE_DIRECTORY_ENTRY;
|
||||
typedef struct _IMAGE_RESOURCE_DATA_ENTRY {
|
||||
DWORD OffsetToData;
|
||||
DWORD Size;
|
||||
DWORD CodePage;
|
||||
DWORD Reserved;
|
||||
} IMAGE_RESOURCE_DATA_ENTRY,*PIMAGE_RESOURCE_DATA_ENTRY;
|
||||
|
||||
#ifndef max
|
||||
#define max(a,b) ((a)>(b)?(a):(b))
|
||||
#endif
|
||||
#ifndef min
|
||||
#define min(a,b) ((a)<(b)?(a):(b))
|
||||
#endif
|
||||
|
||||
#endif /* _WINGLUE_H */
|
||||
|
|
Loading…
Reference in a new issue