Changed the Win32 dll descriptor to be in IMAGE_NT_HEADERS format.
Generate the import table directly in PE format. Added gui/cuiexe_no_main modes in EXE spec files, and use this for the main wine binary.
This commit is contained in:
parent
86f4531676
commit
c585a501d9
|
@ -289,9 +289,9 @@ $(SUBDIRS:%=%/__uninstall__): dummy
|
||||||
|
|
||||||
# Misc. rules
|
# Misc. rules
|
||||||
|
|
||||||
$(SPEC_SRCS:.spec=.spec.c): $(BUILD) $(TOPSRCDIR)/include/builtin16.h $(TOPSRCDIR)/include/builtin32.h
|
$(SPEC_SRCS:.spec=.spec.c): $(BUILD) $(TOPSRCDIR)/include/builtin16.h
|
||||||
|
|
||||||
$(GLUE:.c=.glue.c): $(BUILD) $(TOPSRCDIR)/include/builtin16.h $(TOPSRCDIR)/include/builtin32.h
|
$(GLUE:.c=.glue.c): $(BUILD) $(TOPSRCDIR)/include/builtin16.h
|
||||||
|
|
||||||
$(RC_SRCS:.rc=.s): $(WRC)
|
$(RC_SRCS:.rc=.s): $(WRC)
|
||||||
|
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
/*
|
|
||||||
* Win32 built-in DLLs definitions
|
|
||||||
*
|
|
||||||
* Copyright 1997 Alexandre Julliard
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __WINE_BUILTIN32_H
|
|
||||||
#define __WINE_BUILTIN32_H
|
|
||||||
|
|
||||||
/* Warning: this must match the definition in tools/winebuild/spec32.c */
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
const char* filename; /* DLL file name */
|
|
||||||
int nb_imports; /* Number of imported DLLs */
|
|
||||||
void *pe_header; /* Buffer for PE header */
|
|
||||||
void *exports; /* Pointer to export directory */
|
|
||||||
unsigned int exports_size; /* Total size of export directory */
|
|
||||||
const char * const *imports; /* Pointer to imports */
|
|
||||||
void (*dllentrypoint)(); /* Pointer to entry point function */
|
|
||||||
int characteristics;
|
|
||||||
void *rsrc; /* Resource descriptor */
|
|
||||||
} BUILTIN32_DESCRIPTOR;
|
|
||||||
|
|
||||||
extern void BUILTIN32_RegisterDLL( const BUILTIN32_DESCRIPTOR *descr );
|
|
||||||
extern void RELAY_SetupDLL( const char *module );
|
|
||||||
|
|
||||||
#endif /* __WINE_BUILTIN32_H */
|
|
|
@ -1 +1,2 @@
|
||||||
Makefile
|
Makefile
|
||||||
|
wine.spec.c
|
||||||
|
|
|
@ -5,6 +5,8 @@ SRCDIR = @srcdir@
|
||||||
VPATH = @srcdir@
|
VPATH = @srcdir@
|
||||||
MODULE = miscemu
|
MODULE = miscemu
|
||||||
|
|
||||||
|
SPEC_SRCS = wine.spec
|
||||||
|
|
||||||
C_SRCS = \
|
C_SRCS = \
|
||||||
main.c
|
main.c
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
#include "wingdi.h"
|
#include "wingdi.h"
|
||||||
#include "winuser.h"
|
#include "winuser.h"
|
||||||
|
|
||||||
#include "builtin32.h"
|
|
||||||
#include "callback.h"
|
#include "callback.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "process.h"
|
#include "process.h"
|
||||||
|
@ -17,7 +16,7 @@
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* Main loop of initial task
|
* Main loop of initial task
|
||||||
*/
|
*/
|
||||||
static void initial_task(void)
|
void wine_initial_task(void)
|
||||||
{
|
{
|
||||||
MSG msg;
|
MSG msg;
|
||||||
HINSTANCE16 instance;
|
HINSTANCE16 instance;
|
||||||
|
@ -55,13 +54,6 @@ static void initial_task(void)
|
||||||
*/
|
*/
|
||||||
int main( int argc, char *argv[] )
|
int main( int argc, char *argv[] )
|
||||||
{
|
{
|
||||||
BUILTIN32_DESCRIPTOR descriptor;
|
|
||||||
|
|
||||||
memset( &descriptor, 0, sizeof(descriptor) );
|
|
||||||
descriptor.filename = argv[0];
|
|
||||||
descriptor.dllentrypoint = initial_task;
|
|
||||||
BUILTIN32_RegisterDLL( &descriptor );
|
|
||||||
|
|
||||||
PROCESS_InitWine( argc, argv );
|
PROCESS_InitWine( argc, argv );
|
||||||
return 1; /* not reached */
|
return 1; /* not reached */
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
name wine
|
||||||
|
mode cuiexe_no_main
|
||||||
|
type win32
|
||||||
|
init wine_initial_task
|
|
@ -20,7 +20,6 @@
|
||||||
|
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "wine/winbase16.h"
|
#include "wine/winbase16.h"
|
||||||
#include "builtin32.h"
|
|
||||||
#include "elfdll.h"
|
#include "elfdll.h"
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "neexe.h"
|
#include "neexe.h"
|
||||||
|
@ -43,7 +42,15 @@ typedef struct
|
||||||
|
|
||||||
#define MAX_DLLS 100
|
#define MAX_DLLS 100
|
||||||
|
|
||||||
static const BUILTIN32_DESCRIPTOR *builtin_dlls[MAX_DLLS];
|
typedef struct
|
||||||
|
{
|
||||||
|
const IMAGE_NT_HEADERS *nt; /* NT header */
|
||||||
|
const char *filename; /* DLL file name */
|
||||||
|
} BUILTIN32_DESCRIPTOR;
|
||||||
|
|
||||||
|
extern void RELAY_SetupDLL( const char *module );
|
||||||
|
|
||||||
|
static BUILTIN32_DESCRIPTOR builtin_dlls[MAX_DLLS];
|
||||||
static int nb_dlls;
|
static int nb_dlls;
|
||||||
|
|
||||||
|
|
||||||
|
@ -119,8 +126,6 @@ static HMODULE BUILTIN32_DoLoadImage( const BUILTIN32_DESCRIPTOR *descr )
|
||||||
IMAGE_DOS_HEADER *dos;
|
IMAGE_DOS_HEADER *dos;
|
||||||
IMAGE_NT_HEADERS *nt;
|
IMAGE_NT_HEADERS *nt;
|
||||||
IMAGE_SECTION_HEADER *sec;
|
IMAGE_SECTION_HEADER *sec;
|
||||||
IMAGE_IMPORT_DESCRIPTOR *imp;
|
|
||||||
IMAGE_EXPORT_DIRECTORY *exports = descr->exports;
|
|
||||||
INT i, size, nb_sections;
|
INT i, size, nb_sections;
|
||||||
BYTE *addr, *code_start, *data_start;
|
BYTE *addr, *code_start, *data_start;
|
||||||
int page_size = VIRTUAL_GetPageSize();
|
int page_size = VIRTUAL_GetPageSize();
|
||||||
|
@ -131,17 +136,17 @@ static HMODULE BUILTIN32_DoLoadImage( const BUILTIN32_DESCRIPTOR *descr )
|
||||||
|
|
||||||
size = (sizeof(IMAGE_DOS_HEADER)
|
size = (sizeof(IMAGE_DOS_HEADER)
|
||||||
+ sizeof(IMAGE_NT_HEADERS)
|
+ sizeof(IMAGE_NT_HEADERS)
|
||||||
+ nb_sections * sizeof(IMAGE_SECTION_HEADER)
|
+ nb_sections * sizeof(IMAGE_SECTION_HEADER));
|
||||||
+ (descr->nb_imports+1) * sizeof(IMAGE_IMPORT_DESCRIPTOR));
|
|
||||||
|
|
||||||
assert( size <= page_size );
|
assert( size <= page_size );
|
||||||
|
|
||||||
if (descr->pe_header)
|
if (descr->nt->OptionalHeader.ImageBase)
|
||||||
{
|
{
|
||||||
if ((addr = VIRTUAL_mmap( -1, descr->pe_header, page_size, 0,
|
void *base = (void *)descr->nt->OptionalHeader.ImageBase;
|
||||||
PROT_READ|PROT_WRITE, MAP_FIXED )) != descr->pe_header)
|
if ((addr = VIRTUAL_mmap( -1, base, page_size, 0,
|
||||||
|
PROT_READ|PROT_WRITE, MAP_FIXED )) != base)
|
||||||
{
|
{
|
||||||
ERR("failed to map over PE header for %s at %p\n", descr->filename, descr->pe_header );
|
ERR("failed to map over PE header for %s at %p\n", descr->filename, base );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -153,7 +158,6 @@ static HMODULE BUILTIN32_DoLoadImage( const BUILTIN32_DESCRIPTOR *descr )
|
||||||
dos = (IMAGE_DOS_HEADER *)addr;
|
dos = (IMAGE_DOS_HEADER *)addr;
|
||||||
nt = (IMAGE_NT_HEADERS *)(dos + 1);
|
nt = (IMAGE_NT_HEADERS *)(dos + 1);
|
||||||
sec = (IMAGE_SECTION_HEADER *)(nt + 1);
|
sec = (IMAGE_SECTION_HEADER *)(nt + 1);
|
||||||
imp = (IMAGE_IMPORT_DESCRIPTOR *)(sec + nb_sections);
|
|
||||||
code_start = addr + page_size;
|
code_start = addr + page_size;
|
||||||
|
|
||||||
/* HACK! */
|
/* HACK! */
|
||||||
|
@ -164,28 +168,15 @@ static HMODULE BUILTIN32_DoLoadImage( const BUILTIN32_DESCRIPTOR *descr )
|
||||||
dos->e_magic = IMAGE_DOS_SIGNATURE;
|
dos->e_magic = IMAGE_DOS_SIGNATURE;
|
||||||
dos->e_lfanew = sizeof(*dos);
|
dos->e_lfanew = sizeof(*dos);
|
||||||
|
|
||||||
nt->Signature = IMAGE_NT_SIGNATURE;
|
*nt = *descr->nt;
|
||||||
nt->FileHeader.Machine = IMAGE_FILE_MACHINE_I386;
|
|
||||||
nt->FileHeader.NumberOfSections = nb_sections;
|
|
||||||
nt->FileHeader.SizeOfOptionalHeader = sizeof(nt->OptionalHeader);
|
|
||||||
nt->FileHeader.Characteristics = descr->characteristics;
|
|
||||||
|
|
||||||
nt->OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR_MAGIC;
|
nt->FileHeader.NumberOfSections = nb_sections;
|
||||||
nt->OptionalHeader.SizeOfCode = data_start - code_start;
|
nt->OptionalHeader.SizeOfCode = data_start - code_start;
|
||||||
nt->OptionalHeader.SizeOfInitializedData = 0;
|
nt->OptionalHeader.SizeOfInitializedData = 0;
|
||||||
nt->OptionalHeader.SizeOfUninitializedData = 0;
|
nt->OptionalHeader.SizeOfUninitializedData = 0;
|
||||||
nt->OptionalHeader.ImageBase = (DWORD)addr;
|
nt->OptionalHeader.ImageBase = (DWORD)addr;
|
||||||
nt->OptionalHeader.SectionAlignment = page_size;
|
|
||||||
nt->OptionalHeader.FileAlignment = page_size;
|
fixup_rva_ptrs( &nt->OptionalHeader.AddressOfEntryPoint, addr, 1 );
|
||||||
nt->OptionalHeader.MajorOperatingSystemVersion = 1;
|
|
||||||
nt->OptionalHeader.MinorOperatingSystemVersion = 0;
|
|
||||||
nt->OptionalHeader.MajorSubsystemVersion = 4;
|
|
||||||
nt->OptionalHeader.MinorSubsystemVersion = 0;
|
|
||||||
nt->OptionalHeader.SizeOfImage = page_size;
|
|
||||||
nt->OptionalHeader.SizeOfHeaders = page_size;
|
|
||||||
nt->OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
|
|
||||||
if (descr->dllentrypoint)
|
|
||||||
nt->OptionalHeader.AddressOfEntryPoint = (DWORD)descr->dllentrypoint - (DWORD)addr;
|
|
||||||
|
|
||||||
/* Build the code section */
|
/* Build the code section */
|
||||||
|
|
||||||
|
@ -210,44 +201,34 @@ static HMODULE BUILTIN32_DoLoadImage( const BUILTIN32_DESCRIPTOR *descr )
|
||||||
|
|
||||||
/* Build the import directory */
|
/* Build the import directory */
|
||||||
|
|
||||||
if (descr->nb_imports)
|
dir = &nt->OptionalHeader.DataDirectory[IMAGE_FILE_IMPORT_DIRECTORY];
|
||||||
|
if (dir->Size)
|
||||||
{
|
{
|
||||||
dir = &nt->OptionalHeader.DataDirectory[IMAGE_FILE_IMPORT_DIRECTORY];
|
IMAGE_IMPORT_DESCRIPTOR *imports = (void *)dir->VirtualAddress;
|
||||||
dir->VirtualAddress = (BYTE *)imp - addr;
|
fixup_rva_ptrs( &dir->VirtualAddress, addr, 1 );
|
||||||
dir->Size = sizeof(*imp) * (descr->nb_imports + 1);
|
/* we can fixup everything at once since we only have pointers and 0 values */
|
||||||
|
fixup_rva_ptrs( imports, addr, dir->Size / sizeof(void*) );
|
||||||
/* Build the imports */
|
|
||||||
for (i = 0; i < descr->nb_imports; i++)
|
|
||||||
{
|
|
||||||
imp[i].u.Characteristics = 0;
|
|
||||||
imp[i].ForwarderChain = -1;
|
|
||||||
imp[i].Name = (BYTE *)descr->imports[i] - addr;
|
|
||||||
/* hack: make first thunk point to some zero value */
|
|
||||||
imp[i].FirstThunk = (PIMAGE_THUNK_DATA)((BYTE *)&imp[i].u.Characteristics - addr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Build the resource directory */
|
/* Build the resource directory */
|
||||||
|
|
||||||
if (descr->rsrc)
|
dir = &nt->OptionalHeader.DataDirectory[IMAGE_FILE_RESOURCE_DIRECTORY];
|
||||||
|
if (dir->VirtualAddress)
|
||||||
{
|
{
|
||||||
BUILTIN32_RESOURCE *rsrc = descr->rsrc;
|
BUILTIN32_RESOURCE *rsrc = (BUILTIN32_RESOURCE *)dir->VirtualAddress;
|
||||||
IMAGE_RESOURCE_DATA_ENTRY *rdep;
|
IMAGE_RESOURCE_DATA_ENTRY *rdep = rsrc->entries;
|
||||||
dir = &nt->OptionalHeader.DataDirectory[IMAGE_FILE_RESOURCE_DIRECTORY];
|
dir->VirtualAddress = (BYTE *)rsrc->restab - addr;
|
||||||
dir->VirtualAddress = (BYTE *)rsrc->restab - addr;
|
dir->Size = rsrc->restabsize;
|
||||||
dir->Size = rsrc->restabsize;
|
for (i = 0; i < rsrc->nresources; i++) rdep[i].OffsetToData += dir->VirtualAddress;
|
||||||
rdep = rsrc->entries;
|
|
||||||
for (i = 0; i < rsrc->nresources; i++) rdep[i].OffsetToData += dir->VirtualAddress;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Build the export directory */
|
/* Build the export directory */
|
||||||
|
|
||||||
if (exports)
|
dir = &nt->OptionalHeader.DataDirectory[IMAGE_FILE_EXPORT_DIRECTORY];
|
||||||
|
if (dir->Size)
|
||||||
{
|
{
|
||||||
dir = &nt->OptionalHeader.DataDirectory[IMAGE_FILE_EXPORT_DIRECTORY];
|
IMAGE_EXPORT_DIRECTORY *exports = (void *)dir->VirtualAddress;
|
||||||
dir->VirtualAddress = (BYTE *)exports - addr;
|
fixup_rva_ptrs( &dir->VirtualAddress, addr, 1 );
|
||||||
dir->Size = descr->exports_size;
|
|
||||||
|
|
||||||
fixup_rva_ptrs( (void *)exports->AddressOfFunctions, addr, exports->NumberOfFunctions );
|
fixup_rva_ptrs( (void *)exports->AddressOfFunctions, addr, exports->NumberOfFunctions );
|
||||||
fixup_rva_ptrs( (void *)exports->AddressOfNames, addr, exports->NumberOfNames );
|
fixup_rva_ptrs( (void *)exports->AddressOfNames, addr, exports->NumberOfNames );
|
||||||
fixup_rva_ptrs( &exports->Name, addr, 1 );
|
fixup_rva_ptrs( &exports->Name, addr, 1 );
|
||||||
|
@ -290,12 +271,12 @@ WINE_MODREF *BUILTIN32_LoadLibraryExA(LPCSTR path, DWORD flags)
|
||||||
|
|
||||||
/* Search built-in descriptor */
|
/* Search built-in descriptor */
|
||||||
for (i = 0; i < nb_dlls; i++)
|
for (i = 0; i < nb_dlls; i++)
|
||||||
if (!strcasecmp( builtin_dlls[i]->filename, dllname )) goto found;
|
if (!strcasecmp( builtin_dlls[i].filename, dllname )) goto found;
|
||||||
|
|
||||||
if ((handle = BUILTIN32_dlopen( dllname )))
|
if ((handle = BUILTIN32_dlopen( dllname )))
|
||||||
{
|
{
|
||||||
for (i = 0; i < nb_dlls; i++)
|
for (i = 0; i < nb_dlls; i++)
|
||||||
if (!strcasecmp( builtin_dlls[i]->filename, dllname )) goto found;
|
if (!strcasecmp( builtin_dlls[i].filename, dllname )) goto found;
|
||||||
ERR( "loaded .so but dll %s still not found\n", dllname );
|
ERR( "loaded .so but dll %s still not found\n", dllname );
|
||||||
BUILTIN32_dlclose( handle );
|
BUILTIN32_dlclose( handle );
|
||||||
}
|
}
|
||||||
|
@ -306,7 +287,7 @@ WINE_MODREF *BUILTIN32_LoadLibraryExA(LPCSTR path, DWORD flags)
|
||||||
|
|
||||||
found:
|
found:
|
||||||
/* Load built-in module */
|
/* Load built-in module */
|
||||||
if (!(module = BUILTIN32_DoLoadImage( builtin_dlls[i] ))) return NULL;
|
if (!(module = BUILTIN32_DoLoadImage( &builtin_dlls[i] ))) return NULL;
|
||||||
|
|
||||||
/* Create 32-bit MODREF */
|
/* Create 32-bit MODREF */
|
||||||
if ( !(wm = PE_CreateModule( module, path, flags, -1, TRUE )) )
|
if ( !(wm = PE_CreateModule( module, path, flags, -1, TRUE )) )
|
||||||
|
@ -329,7 +310,7 @@ HMODULE BUILTIN32_LoadExeModule(void)
|
||||||
|
|
||||||
/* Search built-in EXE descriptor */
|
/* Search built-in EXE descriptor */
|
||||||
for ( i = 0; i < nb_dlls; i++ )
|
for ( i = 0; i < nb_dlls; i++ )
|
||||||
if ( !(builtin_dlls[i]->characteristics & IMAGE_FILE_DLL) )
|
if ( !(builtin_dlls[i].nt->FileHeader.Characteristics & IMAGE_FILE_DLL) )
|
||||||
{
|
{
|
||||||
if ( exe != -1 )
|
if ( exe != -1 )
|
||||||
{
|
{
|
||||||
|
@ -347,7 +328,7 @@ HMODULE BUILTIN32_LoadExeModule(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load built-in module */
|
/* Load built-in module */
|
||||||
return BUILTIN32_DoLoadImage( builtin_dlls[exe] );
|
return BUILTIN32_DoLoadImage( &builtin_dlls[exe] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -356,10 +337,12 @@ HMODULE BUILTIN32_LoadExeModule(void)
|
||||||
*
|
*
|
||||||
* Register a built-in DLL descriptor.
|
* Register a built-in DLL descriptor.
|
||||||
*/
|
*/
|
||||||
void BUILTIN32_RegisterDLL( const BUILTIN32_DESCRIPTOR *descr )
|
void BUILTIN32_RegisterDLL( const IMAGE_NT_HEADERS *header, const char *filename )
|
||||||
{
|
{
|
||||||
assert( nb_dlls < MAX_DLLS );
|
assert( nb_dlls < MAX_DLLS );
|
||||||
builtin_dlls[nb_dlls++] = descr;
|
builtin_dlls[nb_dlls].nt = header;
|
||||||
|
builtin_dlls[nb_dlls].filename = filename;
|
||||||
|
nb_dlls++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
|
|
@ -8,6 +8,7 @@ PROGRAMS = winebuild
|
||||||
MODULE = none
|
MODULE = none
|
||||||
|
|
||||||
C_SRCS = \
|
C_SRCS = \
|
||||||
|
import.c \
|
||||||
main.c \
|
main.c \
|
||||||
parser.c \
|
parser.c \
|
||||||
relay.c \
|
relay.c \
|
||||||
|
|
|
@ -61,7 +61,9 @@ typedef enum
|
||||||
{
|
{
|
||||||
SPEC_MODE_DLL,
|
SPEC_MODE_DLL,
|
||||||
SPEC_MODE_GUIEXE,
|
SPEC_MODE_GUIEXE,
|
||||||
SPEC_MODE_CUIEXE
|
SPEC_MODE_CUIEXE,
|
||||||
|
SPEC_MODE_GUIEXE_NO_MAIN,
|
||||||
|
SPEC_MODE_CUIEXE_NO_MAIN
|
||||||
} SPEC_MODE;
|
} SPEC_MODE;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -126,7 +128,6 @@ typedef struct
|
||||||
|
|
||||||
|
|
||||||
#define MAX_ORDINALS 2048
|
#define MAX_ORDINALS 2048
|
||||||
#define MAX_IMPORTS 16
|
|
||||||
|
|
||||||
/* global functions */
|
/* global functions */
|
||||||
|
|
||||||
|
@ -135,7 +136,11 @@ extern void *xrealloc (void *ptr, size_t size);
|
||||||
extern char *xstrdup( const char *str );
|
extern char *xstrdup( const char *str );
|
||||||
extern char *strupper(char *s);
|
extern char *strupper(char *s);
|
||||||
extern void fatal_error( const char *msg, ... );
|
extern void fatal_error( const char *msg, ... );
|
||||||
|
extern void warning( const char *msg, ... );
|
||||||
extern void dump_bytes( FILE *outfile, const unsigned char *data, int len, const char *label );
|
extern void dump_bytes( FILE *outfile, const unsigned char *data, int len, const char *label );
|
||||||
|
extern void add_import_dll( const char *name );
|
||||||
|
extern void resolve_imports( FILE *outfile );
|
||||||
|
extern int output_imports( FILE *outfile );
|
||||||
|
|
||||||
extern void BuildGlue( FILE *outfile, FILE *infile );
|
extern void BuildGlue( FILE *outfile, FILE *infile );
|
||||||
extern void BuildRelays( FILE *outfile );
|
extern void BuildRelays( FILE *outfile );
|
||||||
|
@ -148,7 +153,6 @@ extern SPEC_TYPE ParseTopLevel( FILE *file );
|
||||||
extern int current_line;
|
extern int current_line;
|
||||||
extern int nb_entry_points;
|
extern int nb_entry_points;
|
||||||
extern int nb_names;
|
extern int nb_names;
|
||||||
extern int nb_imports;
|
|
||||||
extern int Base;
|
extern int Base;
|
||||||
extern int Limit;
|
extern int Limit;
|
||||||
extern int DLLHeapSize;
|
extern int DLLHeapSize;
|
||||||
|
@ -163,7 +167,6 @@ extern char DLLFileName[80];
|
||||||
extern char DLLInitFunc[80];
|
extern char DLLInitFunc[80];
|
||||||
extern char rsrc_name[80];
|
extern char rsrc_name[80];
|
||||||
extern char owner_name[80];
|
extern char owner_name[80];
|
||||||
extern char *DLLImports[MAX_IMPORTS];
|
|
||||||
extern const char *input_file_name;
|
extern const char *input_file_name;
|
||||||
extern const char *output_file_name;
|
extern const char *output_file_name;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* DLL imports support
|
||||||
|
*
|
||||||
|
* Copyright 2000 Alexandre Julliard
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "winnt.h"
|
||||||
|
#include "build.h"
|
||||||
|
|
||||||
|
struct import
|
||||||
|
{
|
||||||
|
char *dll; /* dll name */
|
||||||
|
char **imports; /* functions we want to import from this dll */
|
||||||
|
int nb_imports; /* number of imported functions */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static struct import **dll_imports = NULL;
|
||||||
|
static int nb_imports = 0; /* number of imported dlls */
|
||||||
|
static int total_imports = 0; /* total number of imported functions */
|
||||||
|
|
||||||
|
|
||||||
|
/* add a dll to the list of imports */
|
||||||
|
void add_import_dll( const char *name )
|
||||||
|
{
|
||||||
|
struct import *imp = xmalloc( sizeof(*imp) );
|
||||||
|
imp->dll = xstrdup( name );
|
||||||
|
imp->imports = NULL;
|
||||||
|
imp->nb_imports = 0;
|
||||||
|
|
||||||
|
dll_imports = xrealloc( dll_imports, (nb_imports+1) * sizeof(*dll_imports) );
|
||||||
|
dll_imports[nb_imports++] = imp;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef notyet
|
||||||
|
/* add a function to the list of imports from a given dll */
|
||||||
|
static void add_import_func( struct import *imp, const char *name )
|
||||||
|
{
|
||||||
|
imp->imports = xrealloc( imp->imports, (imp->nb_imports+1) * sizeof(*imp->imports) );
|
||||||
|
imp->imports[imp->nb_imports++] = xstrdup( name );
|
||||||
|
total_imports++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* output the import table of a Win32 module */
|
||||||
|
int output_imports( FILE *outfile )
|
||||||
|
{
|
||||||
|
int i, j, pos;
|
||||||
|
|
||||||
|
if (!nb_imports) goto done;
|
||||||
|
|
||||||
|
/* main import header */
|
||||||
|
|
||||||
|
fprintf( outfile, "\n\n/* imports */\n\n" );
|
||||||
|
fprintf( outfile, "static struct {\n" );
|
||||||
|
fprintf( outfile, " struct {\n" );
|
||||||
|
fprintf( outfile, " void *OriginalFirstThunk;\n" );
|
||||||
|
fprintf( outfile, " unsigned int TimeDateStamp;\n" );
|
||||||
|
fprintf( outfile, " unsigned int ForwarderChain;\n" );
|
||||||
|
fprintf( outfile, " const char *Name;\n" );
|
||||||
|
fprintf( outfile, " void *FirstThunk;\n" );
|
||||||
|
fprintf( outfile, " } imp[%d];\n", nb_imports+1 );
|
||||||
|
fprintf( outfile, " const char *data[%d];\n", total_imports + nb_imports );
|
||||||
|
fprintf( outfile, "} imports = {\n {\n" );
|
||||||
|
|
||||||
|
/* list of dlls */
|
||||||
|
|
||||||
|
for (i = j = 0; i < nb_imports; i++)
|
||||||
|
{
|
||||||
|
fprintf( outfile, " { 0, 0, 0, \"%s\", &imports.data[%d] },\n",
|
||||||
|
dll_imports[i]->dll, j );
|
||||||
|
j += dll_imports[i]->nb_imports + 1;
|
||||||
|
}
|
||||||
|
fprintf( outfile, " { 0, 0, 0, 0, 0 },\n" );
|
||||||
|
fprintf( outfile, " },\n {\n" );
|
||||||
|
|
||||||
|
/* list of imported functions */
|
||||||
|
|
||||||
|
for (i = 0; i < nb_imports; i++)
|
||||||
|
{
|
||||||
|
fprintf( outfile, " /* %s */\n", dll_imports[i]->dll );
|
||||||
|
for (j = 0; j < dll_imports[i]->nb_imports; j++)
|
||||||
|
fprintf( outfile, " \"\\0\\0%s\",\n", dll_imports[i]->imports[j] );
|
||||||
|
fprintf( outfile, " 0,\n" );
|
||||||
|
}
|
||||||
|
fprintf( outfile, " }\n};\n\n" );
|
||||||
|
|
||||||
|
/* thunks for imported functions */
|
||||||
|
|
||||||
|
fprintf( outfile, "#ifndef __GNUC__\nstatic void __asm__dummy_import(void) {\n#endif\n\n" );
|
||||||
|
pos = 20 * (nb_imports + 1); /* offset of imports.data from start of imports */
|
||||||
|
fprintf( outfile, "asm(\".align 4\");\n" );
|
||||||
|
for (i = 0; i < nb_imports; i++, pos += 4)
|
||||||
|
{
|
||||||
|
for (j = 0; j < dll_imports[i]->nb_imports; j++, pos += 4)
|
||||||
|
{
|
||||||
|
fprintf( outfile,
|
||||||
|
"asm(\".type " PREFIX "%s,@function\\n\\t"
|
||||||
|
".globl " PREFIX "%s\\n"
|
||||||
|
PREFIX "%s:\\tjmp *(imports+%d)\\n\\t"
|
||||||
|
"movl %%esi,%%esi\");\n",
|
||||||
|
dll_imports[i]->imports[j], dll_imports[i]->imports[j],
|
||||||
|
dll_imports[i]->imports[j], pos );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf( outfile, "#ifndef __GNUC__\n}\n#endif\n\n" );
|
||||||
|
|
||||||
|
done:
|
||||||
|
return nb_imports;
|
||||||
|
}
|
|
@ -38,13 +38,11 @@ int DLLHeapSize = 0;
|
||||||
int UsePIC = 0;
|
int UsePIC = 0;
|
||||||
int nb_entry_points = 0;
|
int nb_entry_points = 0;
|
||||||
int nb_names = 0;
|
int nb_names = 0;
|
||||||
int nb_imports = 0;
|
|
||||||
int debugging = 1;
|
int debugging = 1;
|
||||||
|
|
||||||
char DLLName[80];
|
char DLLName[80];
|
||||||
char DLLFileName[80];
|
char DLLFileName[80];
|
||||||
char DLLInitFunc[80];
|
char DLLInitFunc[80];
|
||||||
char *DLLImports[MAX_IMPORTS];
|
|
||||||
char rsrc_name[80];
|
char rsrc_name[80];
|
||||||
char owner_name[80];
|
char owner_name[80];
|
||||||
|
|
||||||
|
|
|
@ -310,6 +310,20 @@ static void ParseForward( ORDDEF *odp )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
* fix_export_name
|
||||||
|
*
|
||||||
|
* Fix an exported function name by removing a possible @xx suffix
|
||||||
|
*/
|
||||||
|
static void fix_export_name( char *name )
|
||||||
|
{
|
||||||
|
char *p, *end = strrchr( name, '@' );
|
||||||
|
if (!end || !end[1] || end == name) return;
|
||||||
|
/* make sure all the rest is digits */
|
||||||
|
for (p = end + 1; *p; p++) if (!isdigit(*p)) return;
|
||||||
|
*end = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
* ParseOrdinal
|
* ParseOrdinal
|
||||||
*
|
*
|
||||||
|
@ -333,6 +347,7 @@ static void ParseOrdinal(int ordinal)
|
||||||
if (!(token = GetToken())) fatal_error( "Expected name after type\n" );
|
if (!(token = GetToken())) fatal_error( "Expected name after type\n" );
|
||||||
|
|
||||||
strcpy( odp->name, token );
|
strcpy( odp->name, token );
|
||||||
|
fix_export_name( odp->name );
|
||||||
odp->lineno = current_line;
|
odp->lineno = current_line;
|
||||||
odp->ordinal = ordinal;
|
odp->ordinal = ordinal;
|
||||||
|
|
||||||
|
@ -436,7 +451,9 @@ SPEC_TYPE ParseTopLevel( FILE *file )
|
||||||
if (!strcmp(token, "dll" )) SpecMode = SPEC_MODE_DLL;
|
if (!strcmp(token, "dll" )) SpecMode = SPEC_MODE_DLL;
|
||||||
else if (!strcmp(token, "guiexe" )) SpecMode = SPEC_MODE_GUIEXE;
|
else if (!strcmp(token, "guiexe" )) SpecMode = SPEC_MODE_GUIEXE;
|
||||||
else if (!strcmp(token, "cuiexe" )) SpecMode = SPEC_MODE_CUIEXE;
|
else if (!strcmp(token, "cuiexe" )) SpecMode = SPEC_MODE_CUIEXE;
|
||||||
else fatal_error( "Mode must be 'dll', 'guiexe' or 'cuiexe'\n" );
|
else if (!strcmp(token, "guiexe_no_main" )) SpecMode = SPEC_MODE_GUIEXE_NO_MAIN;
|
||||||
|
else if (!strcmp(token, "cuiexe_no_main" )) SpecMode = SPEC_MODE_CUIEXE_NO_MAIN;
|
||||||
|
else fatal_error( "Mode must be 'dll', 'guiexe', 'cuiexe', 'guiexe_no_main' or 'cuiexe_no_main'\n" );
|
||||||
}
|
}
|
||||||
else if (strcmp(token, "heap") == 0)
|
else if (strcmp(token, "heap") == 0)
|
||||||
{
|
{
|
||||||
|
@ -456,11 +473,9 @@ SPEC_TYPE ParseTopLevel( FILE *file )
|
||||||
}
|
}
|
||||||
else if (strcmp(token, "import") == 0)
|
else if (strcmp(token, "import") == 0)
|
||||||
{
|
{
|
||||||
if (nb_imports >= MAX_IMPORTS)
|
|
||||||
fatal_error( "Too many imports (limit %d)\n", MAX_IMPORTS );
|
|
||||||
if (SpecType != SPEC_WIN32)
|
if (SpecType != SPEC_WIN32)
|
||||||
fatal_error( "Imports not supported for Win16\n" );
|
fatal_error( "Imports not supported for Win16\n" );
|
||||||
DLLImports[nb_imports++] = xstrdup(GetToken());
|
add_import_dll( GetToken() );
|
||||||
}
|
}
|
||||||
else if (strcmp(token, "rsrc") == 0)
|
else if (strcmp(token, "rsrc") == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -269,7 +269,8 @@ void BuildSpec32File( FILE *outfile )
|
||||||
{
|
{
|
||||||
ORDDEF *odp;
|
ORDDEF *odp;
|
||||||
int i, fwd_size = 0, have_regs = FALSE;
|
int i, fwd_size = 0, have_regs = FALSE;
|
||||||
int nr_exports;
|
int nr_exports, nr_imports;
|
||||||
|
int characteristics, subsystem;
|
||||||
const char *init_func;
|
const char *init_func;
|
||||||
DWORD page_size;
|
DWORD page_size;
|
||||||
|
|
||||||
|
@ -370,24 +371,17 @@ void BuildSpec32File( FILE *outfile )
|
||||||
|
|
||||||
/* Output the DLL imports */
|
/* Output the DLL imports */
|
||||||
|
|
||||||
if (nb_imports)
|
nr_imports = output_imports( outfile );
|
||||||
{
|
|
||||||
fprintf( outfile, "static const char * const Imports[%d] =\n{\n", nb_imports );
|
|
||||||
for (i = 0; i < nb_imports; i++)
|
|
||||||
{
|
|
||||||
fprintf( outfile, " \"%s\"", DLLImports[i] );
|
|
||||||
if (i < nb_imports-1) fprintf( outfile, ",\n" );
|
|
||||||
}
|
|
||||||
fprintf( outfile, "\n};\n\n" );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Output LibMain function */
|
/* Output LibMain function */
|
||||||
|
|
||||||
init_func = DLLInitFunc[0] ? DLLInitFunc : NULL;
|
init_func = DLLInitFunc[0] ? DLLInitFunc : NULL;
|
||||||
|
characteristics = subsystem = 0;
|
||||||
switch(SpecMode)
|
switch(SpecMode)
|
||||||
{
|
{
|
||||||
case SPEC_MODE_DLL:
|
case SPEC_MODE_DLL:
|
||||||
if (init_func) fprintf( outfile, "extern void %s();\n", init_func );
|
if (init_func) fprintf( outfile, "extern void %s();\n", init_func );
|
||||||
|
characteristics = IMAGE_FILE_DLL;
|
||||||
break;
|
break;
|
||||||
case SPEC_MODE_GUIEXE:
|
case SPEC_MODE_GUIEXE:
|
||||||
if (!init_func) init_func = "WinMain";
|
if (!init_func) init_func = "WinMain";
|
||||||
|
@ -412,6 +406,7 @@ void BuildSpec32File( FILE *outfile )
|
||||||
" return 1;\n"
|
" return 1;\n"
|
||||||
"}\n\n" );
|
"}\n\n" );
|
||||||
init_func = "exe_main";
|
init_func = "exe_main";
|
||||||
|
subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
|
||||||
break;
|
break;
|
||||||
case SPEC_MODE_CUIEXE:
|
case SPEC_MODE_CUIEXE:
|
||||||
if (!init_func) init_func = "wine_main";
|
if (!init_func) init_func = "wine_main";
|
||||||
|
@ -432,6 +427,15 @@ void BuildSpec32File( FILE *outfile )
|
||||||
" return 1;\n"
|
" return 1;\n"
|
||||||
"}\n\n" );
|
"}\n\n" );
|
||||||
init_func = "exe_main";
|
init_func = "exe_main";
|
||||||
|
subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI;
|
||||||
|
break;
|
||||||
|
case SPEC_MODE_GUIEXE_NO_MAIN:
|
||||||
|
if (init_func) fprintf( outfile, "extern void %s();\n", init_func );
|
||||||
|
subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
|
||||||
|
break;
|
||||||
|
case SPEC_MODE_CUIEXE_NO_MAIN:
|
||||||
|
if (init_func) fprintf( outfile, "extern void %s();\n", init_func );
|
||||||
|
subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -439,28 +443,87 @@ void BuildSpec32File( FILE *outfile )
|
||||||
|
|
||||||
if (rsrc_name[0]) fprintf( outfile, "extern char %s[];\n\n", rsrc_name );
|
if (rsrc_name[0]) fprintf( outfile, "extern char %s[];\n\n", rsrc_name );
|
||||||
|
|
||||||
/* Warning: this must match the definition in builtin32.h */
|
/* Output the NT header */
|
||||||
fprintf( outfile, "static const struct dll_descriptor\n{\n" );
|
|
||||||
fprintf( outfile, " const char* filename;\n" );
|
/* this is the IMAGE_NT_HEADERS structure, but we cannot include winnt.h here */
|
||||||
fprintf( outfile, " int nb_imports;\n" );
|
fprintf( outfile, "static const struct image_nt_headers\n{\n" );
|
||||||
fprintf( outfile, " void *pe_header;\n" );
|
fprintf( outfile, " int Signature;\n" );
|
||||||
fprintf( outfile, " void *exports;\n" );
|
fprintf( outfile, " struct file_header {\n" );
|
||||||
fprintf( outfile, " unsigned int exports_size;\n" );
|
fprintf( outfile, " short Machine;\n" );
|
||||||
fprintf( outfile, " const char * const *imports;\n" );
|
fprintf( outfile, " short NumberOfSections;\n" );
|
||||||
fprintf( outfile, " void (*dllentrypoint)();\n" );
|
fprintf( outfile, " int TimeDateStamp;\n" );
|
||||||
fprintf( outfile, " int characteristics;\n" );
|
fprintf( outfile, " void *PointerToSymbolTable;\n" );
|
||||||
fprintf( outfile, " void *rsrc;\n" );
|
fprintf( outfile, " int NumberOfSymbols;\n" );
|
||||||
fprintf( outfile, "} descriptor = {\n" );
|
fprintf( outfile, " short SizeOfOptionalHeader;\n" );
|
||||||
fprintf( outfile, " \"%s\",\n", DLLFileName );
|
fprintf( outfile, " short Characteristics;\n" );
|
||||||
fprintf( outfile, " %d,\n", nb_imports );
|
fprintf( outfile, " } FileHeader;\n" );
|
||||||
fprintf( outfile, " pe_header,\n" );
|
fprintf( outfile, " struct opt_header {\n" );
|
||||||
fprintf( outfile, " %s,\n", nr_exports ? "&exports" : "0" );
|
fprintf( outfile, " short Magic;\n" );
|
||||||
fprintf( outfile, " %s,\n", nr_exports ? "sizeof(exports.exp)" : "0" );
|
fprintf( outfile, " char MajorLinkerVersion, MinorLinkerVersion;\n" );
|
||||||
fprintf( outfile, " %s,\n", nb_imports ? "Imports" : "0" );
|
fprintf( outfile, " int SizeOfCode;\n" );
|
||||||
fprintf( outfile, " %s,\n", init_func ? init_func : "0" );
|
fprintf( outfile, " int SizeOfInitializedData;\n" );
|
||||||
fprintf( outfile, " %d,\n", SpecMode == SPEC_MODE_DLL ? IMAGE_FILE_DLL : 0 );
|
fprintf( outfile, " int SizeOfUninitializedData;\n" );
|
||||||
fprintf( outfile, " %s\n", rsrc_name[0] ? rsrc_name : "0" );
|
fprintf( outfile, " void *AddressOfEntryPoint;\n" );
|
||||||
fprintf( outfile, "};\n" );
|
fprintf( outfile, " void *BaseOfCode;\n" );
|
||||||
|
fprintf( outfile, " void *BaseOfData;\n" );
|
||||||
|
fprintf( outfile, " void *ImageBase;\n" );
|
||||||
|
fprintf( outfile, " int SectionAlignment;\n" );
|
||||||
|
fprintf( outfile, " int FileAlignment;\n" );
|
||||||
|
fprintf( outfile, " short MajorOperatingSystemVersion;\n" );
|
||||||
|
fprintf( outfile, " short MinorOperatingSystemVersion;\n" );
|
||||||
|
fprintf( outfile, " short MajorImageVersion;\n" );
|
||||||
|
fprintf( outfile, " short MinorImageVersion;\n" );
|
||||||
|
fprintf( outfile, " short MajorSubsystemVersion;\n" );
|
||||||
|
fprintf( outfile, " short MinorSubsystemVersion;\n" );
|
||||||
|
fprintf( outfile, " int Win32VersionValue;\n" );
|
||||||
|
fprintf( outfile, " int SizeOfImage;\n" );
|
||||||
|
fprintf( outfile, " int SizeOfHeaders;\n" );
|
||||||
|
fprintf( outfile, " int CheckSum;\n" );
|
||||||
|
fprintf( outfile, " short Subsystem;\n" );
|
||||||
|
fprintf( outfile, " short DllCharacteristics;\n" );
|
||||||
|
fprintf( outfile, " int SizeOfStackReserve;\n" );
|
||||||
|
fprintf( outfile, " int SizeOfStackCommit;\n" );
|
||||||
|
fprintf( outfile, " int SizeOfHeapReserve;\n" );
|
||||||
|
fprintf( outfile, " int SizeOfHeapCommit;\n" );
|
||||||
|
fprintf( outfile, " int LoaderFlags;\n" );
|
||||||
|
fprintf( outfile, " int NumberOfRvaAndSizes;\n" );
|
||||||
|
fprintf( outfile, " struct { void *VirtualAddress; int Size; } DataDirectory[%d];\n",
|
||||||
|
IMAGE_NUMBEROF_DIRECTORY_ENTRIES );
|
||||||
|
fprintf( outfile, " } OptionalHeader;\n" );
|
||||||
|
fprintf( outfile, "} nt_header = {\n" );
|
||||||
|
fprintf( outfile, " 0x%04x,\n", IMAGE_NT_SIGNATURE ); /* Signature */
|
||||||
|
|
||||||
|
fprintf( outfile, " { 0x%04x,\n", IMAGE_FILE_MACHINE_I386 ); /* Machine */
|
||||||
|
fprintf( outfile, " 0, 0, 0, 0,\n" );
|
||||||
|
fprintf( outfile, " sizeof(nt_header.OptionalHeader),\n" ); /* SizeOfOptionalHeader */
|
||||||
|
fprintf( outfile, " 0x%04x },\n", characteristics ); /* Characteristics */
|
||||||
|
|
||||||
|
fprintf( outfile, " { 0x%04x,\n", IMAGE_NT_OPTIONAL_HDR_MAGIC ); /* Magic */
|
||||||
|
fprintf( outfile, " 0, 0,\n" ); /* Major/MinorLinkerVersion */
|
||||||
|
fprintf( outfile, " 0, 0, 0,\n" ); /* SizeOfCode/Data */
|
||||||
|
fprintf( outfile, " %s,\n", init_func ? init_func : "0" ); /* AddressOfEntryPoint */
|
||||||
|
fprintf( outfile, " 0, 0,\n" ); /* BaseOfCode/Data */
|
||||||
|
fprintf( outfile, " pe_header,\n" ); /* ImageBase */
|
||||||
|
fprintf( outfile, " %ld,\n", page_size ); /* SectionAlignment */
|
||||||
|
fprintf( outfile, " %ld,\n", page_size ); /* FileAlignment */
|
||||||
|
fprintf( outfile, " 1, 0,\n" ); /* Major/MinorOperatingSystemVersion */
|
||||||
|
fprintf( outfile, " 0, 0,\n" ); /* Major/MinorImageVersion */
|
||||||
|
fprintf( outfile, " 4, 0,\n" ); /* Major/MinorSubsystemVersion */
|
||||||
|
fprintf( outfile, " 0,\n" ); /* Win32VersionValue */
|
||||||
|
fprintf( outfile, " %ld,\n", page_size ); /* SizeOfImage */
|
||||||
|
fprintf( outfile, " %ld,\n", page_size ); /* SizeOfHeaders */
|
||||||
|
fprintf( outfile, " 0,\n" ); /* CheckSum */
|
||||||
|
fprintf( outfile, " 0x%04x,\n", subsystem ); /* Subsystem */
|
||||||
|
fprintf( outfile, " 0, 0, 0, 0, 0, 0,\n" );
|
||||||
|
fprintf( outfile, " %d,\n", IMAGE_NUMBEROF_DIRECTORY_ENTRIES ); /* NumberOfRvaAndSizes */
|
||||||
|
fprintf( outfile, " {\n" );
|
||||||
|
fprintf( outfile, " { %s, %s },\n", /* IMAGE_DIRECTORY_ENTRY_EXPORT */
|
||||||
|
nr_exports ? "&exports" : "0", nr_exports ? "sizeof(exports.exp)" : "0" );
|
||||||
|
fprintf( outfile, " { %s, %s },\n", /* IMAGE_DIRECTORY_ENTRY_IMPORT */
|
||||||
|
nr_imports ? "&imports" : "0", nr_imports ? "sizeof(imports)" : "0" );
|
||||||
|
fprintf( outfile, " { %s, 0 },\n", /* IMAGE_DIRECTORY_ENTRY_RESOURCE */
|
||||||
|
rsrc_name[0] ? rsrc_name : "0" );
|
||||||
|
fprintf( outfile, " }\n }\n};\n\n" );
|
||||||
|
|
||||||
/* Output the DLL constructor */
|
/* Output the DLL constructor */
|
||||||
|
|
||||||
|
@ -474,6 +537,6 @@ void BuildSpec32File( FILE *outfile )
|
||||||
fprintf( outfile, "}\n" );
|
fprintf( outfile, "}\n" );
|
||||||
fprintf( outfile, "#endif /* defined(__GNUC__) */\n" );
|
fprintf( outfile, "#endif /* defined(__GNUC__) */\n" );
|
||||||
fprintf( outfile, "static void %s_init(void)\n{\n", DLLName );
|
fprintf( outfile, "static void %s_init(void)\n{\n", DLLName );
|
||||||
fprintf( outfile, " extern void BUILTIN32_RegisterDLL( const struct dll_descriptor * );\n" );
|
fprintf( outfile, " extern void BUILTIN32_RegisterDLL( const struct image_nt_headers *, const char * );\n" );
|
||||||
fprintf( outfile, " BUILTIN32_RegisterDLL( &descriptor );\n}\n" );
|
fprintf( outfile, " BUILTIN32_RegisterDLL( &nt_header, \"%s\" );\n}\n", DLLFileName );
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,13 +55,34 @@ void fatal_error( const char *msg, ... )
|
||||||
{
|
{
|
||||||
va_list valist;
|
va_list valist;
|
||||||
va_start( valist, msg );
|
va_start( valist, msg );
|
||||||
if (input_file_name && current_line)
|
if (input_file_name)
|
||||||
fprintf( stderr, "%s:%d: ", input_file_name, current_line );
|
{
|
||||||
|
fprintf( stderr, "%s:", input_file_name );
|
||||||
|
if (current_line)
|
||||||
|
fprintf( stderr, "%d:", current_line );
|
||||||
|
fputc( ' ', stderr );
|
||||||
|
}
|
||||||
vfprintf( stderr, msg, valist );
|
vfprintf( stderr, msg, valist );
|
||||||
va_end( valist );
|
va_end( valist );
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void warning( const char *msg, ... )
|
||||||
|
{
|
||||||
|
va_list valist;
|
||||||
|
va_start( valist, msg );
|
||||||
|
if (input_file_name)
|
||||||
|
{
|
||||||
|
fprintf( stderr, "%s:", input_file_name );
|
||||||
|
if (current_line)
|
||||||
|
fprintf( stderr, "%d:", current_line );
|
||||||
|
fputc( ' ', stderr );
|
||||||
|
}
|
||||||
|
fprintf( stderr, "warning: " );
|
||||||
|
vfprintf( stderr, msg, valist );
|
||||||
|
va_end( valist );
|
||||||
|
}
|
||||||
|
|
||||||
/* dump a byte stream into the assembly code */
|
/* dump a byte stream into the assembly code */
|
||||||
void dump_bytes( FILE *outfile, const unsigned char *data, int len, const char *label )
|
void dump_bytes( FILE *outfile, const unsigned char *data, int len, const char *label )
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue