Commit e4177e67 authored by Alexandre Julliard's avatar Alexandre Julliard

Added import declaration for Win32 built-ins.

parent 3eb441c7
...@@ -15,12 +15,14 @@ typedef struct ...@@ -15,12 +15,14 @@ typedef struct
int base; /* Ordinal base */ int base; /* Ordinal base */
int nb_funcs; /* Number of functions */ int nb_funcs; /* Number of functions */
int nb_names; /* Number of function names */ int nb_names; /* Number of function names */
int nb_imports; /* Number of imported DLLs */
int fwd_size; /* Total size of forward names */ int fwd_size; /* Total size of forward names */
const ENTRYPOINT32 *functions; /* Pointer to function table */ const ENTRYPOINT32 *functions; /* Pointer to function table */
const char * const *names; /* Pointer to names table */ const char * const *names; /* Pointer to names table */
const unsigned short *ordinals; /* Pointer to ordinals table */ const unsigned short *ordinals; /* Pointer to ordinals table */
const unsigned char *args; /* Pointer to argument lengths */ const unsigned char *args; /* Pointer to argument lengths */
const unsigned int *argtypes; /* Pointer to argument types bitmask */ const unsigned int *argtypes; /* Pointer to argument types bitmask */
const char * const *imports; /* Pointer to imports */
const ENTRYPOINT32 dllentrypoint;/* Pointer to LibMain function */ const ENTRYPOINT32 dllentrypoint;/* Pointer to LibMain function */
} BUILTIN32_DESCRIPTOR; } BUILTIN32_DESCRIPTOR;
......
...@@ -159,18 +159,22 @@ static HMODULE BUILTIN32_DoLoadImage( BUILTIN32_DLL *dll ) ...@@ -159,18 +159,22 @@ static HMODULE BUILTIN32_DoLoadImage( BUILTIN32_DLL *dll )
IMAGE_NT_HEADERS *nt; IMAGE_NT_HEADERS *nt;
IMAGE_SECTION_HEADER *sec; IMAGE_SECTION_HEADER *sec;
IMAGE_EXPORT_DIRECTORY *exp; IMAGE_EXPORT_DIRECTORY *exp;
IMAGE_IMPORT_DESCRIPTOR *imp;
LPVOID *funcs; LPVOID *funcs;
LPSTR *names; LPSTR *names;
LPSTR pfwd; LPSTR pfwd;
DEBUG_ENTRY_POINT *debug; DEBUG_ENTRY_POINT *debug;
INT i, size; INT i, size, nb_sections;
BYTE *addr; BYTE *addr;
/* Allocate the module */ /* Allocate the module */
nb_sections = 2; /* exports + code */
if (dll->descr->nb_imports) nb_sections++;
size = (sizeof(IMAGE_DOS_HEADER) size = (sizeof(IMAGE_DOS_HEADER)
+ sizeof(IMAGE_NT_HEADERS) + sizeof(IMAGE_NT_HEADERS)
+ 2 * sizeof(IMAGE_SECTION_HEADER) + nb_sections * sizeof(IMAGE_SECTION_HEADER)
+ (dll->descr->nb_imports+1) * sizeof(IMAGE_IMPORT_DESCRIPTOR)
+ sizeof(IMAGE_EXPORT_DIRECTORY) + sizeof(IMAGE_EXPORT_DIRECTORY)
+ dll->descr->nb_funcs * sizeof(LPVOID) + dll->descr->nb_funcs * sizeof(LPVOID)
+ dll->descr->nb_names * sizeof(LPSTR) + dll->descr->nb_names * sizeof(LPSTR)
...@@ -184,7 +188,8 @@ static HMODULE BUILTIN32_DoLoadImage( BUILTIN32_DLL *dll ) ...@@ -184,7 +188,8 @@ static HMODULE BUILTIN32_DoLoadImage( BUILTIN32_DLL *dll )
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);
exp = (IMAGE_EXPORT_DIRECTORY *)(sec + 2); imp = (IMAGE_IMPORT_DESCRIPTOR *)(sec + nb_sections);
exp = (IMAGE_EXPORT_DIRECTORY *)(imp + dll->descr->nb_imports + 1);
funcs = (LPVOID *)(exp + 1); funcs = (LPVOID *)(exp + 1);
names = (LPSTR *)(funcs + dll->descr->nb_funcs); names = (LPSTR *)(funcs + dll->descr->nb_funcs);
pfwd = (LPSTR)(names + dll->descr->nb_names); pfwd = (LPSTR)(names + dll->descr->nb_names);
...@@ -197,7 +202,7 @@ static HMODULE BUILTIN32_DoLoadImage( BUILTIN32_DLL *dll ) ...@@ -197,7 +202,7 @@ static HMODULE BUILTIN32_DoLoadImage( BUILTIN32_DLL *dll )
nt->Signature = IMAGE_NT_SIGNATURE; nt->Signature = IMAGE_NT_SIGNATURE;
nt->FileHeader.Machine = IMAGE_FILE_MACHINE_I386; nt->FileHeader.Machine = IMAGE_FILE_MACHINE_I386;
nt->FileHeader.NumberOfSections = 2; /* exports + code */ nt->FileHeader.NumberOfSections = nb_sections;
nt->FileHeader.SizeOfOptionalHeader = sizeof(nt->OptionalHeader); nt->FileHeader.SizeOfOptionalHeader = sizeof(nt->OptionalHeader);
nt->FileHeader.Characteristics = IMAGE_FILE_DLL; nt->FileHeader.Characteristics = IMAGE_FILE_DLL;
...@@ -218,6 +223,36 @@ static HMODULE BUILTIN32_DoLoadImage( BUILTIN32_DLL *dll ) ...@@ -218,6 +223,36 @@ static HMODULE BUILTIN32_DoLoadImage( BUILTIN32_DLL *dll )
if (dll->descr->dllentrypoint) if (dll->descr->dllentrypoint)
nt->OptionalHeader.AddressOfEntryPoint = (DWORD)dll->descr->dllentrypoint - (DWORD)addr; nt->OptionalHeader.AddressOfEntryPoint = (DWORD)dll->descr->dllentrypoint - (DWORD)addr;
/* Build the import directory */
if (dll->descr->nb_imports)
{
dir = &nt->OptionalHeader.DataDirectory[IMAGE_FILE_IMPORT_DIRECTORY];
dir->VirtualAddress = (BYTE *)imp - addr;
dir->Size = sizeof(*imp) * (dll->descr->nb_imports + 1);
/* Build the imports section */
strcpy( sec->Name, ".idata" );
sec->Misc.VirtualSize = dir->Size;
sec->VirtualAddress = (BYTE *)imp - addr;
sec->SizeOfRawData = dir->Size;
sec->PointerToRawData = (BYTE *)imp - addr;
sec->Characteristics = (IMAGE_SCN_CNT_INITIALIZED_DATA |
IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ |
IMAGE_SCN_MEM_WRITE);
sec++;
/* Build the imports */
for (i = 0; i < dll->descr->nb_imports; i++)
{
imp[i].u.Characteristics = 0;
imp[i].ForwarderChain = -1;
imp[i].Name = (BYTE *)dll->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 export directory */ /* Build the export directory */
dir = &nt->OptionalHeader.DataDirectory[IMAGE_FILE_EXPORT_DIRECTORY]; dir = &nt->OptionalHeader.DataDirectory[IMAGE_FILE_EXPORT_DIRECTORY];
......
...@@ -3,6 +3,7 @@ type win16|win32 ...@@ -3,6 +3,7 @@ type win16|win32
[file WINFILENAME] [file WINFILENAME]
[base ORDINAL] [base ORDINAL]
[heap SIZE] [heap SIZE]
[import DLL]
ORDINAL VARTYPE EXPORTNAME (DATA [DATA [DATA [...]]]) ORDINAL VARTYPE EXPORTNAME (DATA [DATA [DATA [...]]])
...@@ -26,13 +27,22 @@ General: ...@@ -26,13 +27,22 @@ General:
"name" and "type" fields are mandatory. Specific ordinal "name" and "type" fields are mandatory. Specific ordinal
declarations are optional, but the default handler will print an error declarations are optional, but the default handler will print an error
message. "base" gives the offset of the first ordinal; default is 0. message.
"base" gives the offset of the first ordinal; default is 0.
"heap" is the size of the module local heap (only valid for Win16 "heap" is the size of the module local heap (only valid for Win16
modules); default is no local heap. "file" gives the name of the modules); default is no local heap.
Windows file that is replaced by the builtin. <name>.DLL is assumed if
none is given. (This is important for kernel, which lives in the "file" gives the name of the Windows file that is replaced by the
Windows file KRNL386.EXE). Lines whose first character is a '#' will builtin. <name>.DLL is assumed if none is given. (This is important
be ignored as comments. for kernel, which lives in the Windows file KRNL386.EXE).
"import" names a module that this one depends on (only for Win32
modules at the present). The import declaration can be present several
times.
Lines whose first character is a '#' will be ignored as comments.
Variable ordinals: Variable ordinals:
......
...@@ -78,6 +78,7 @@ static const char * const TypeNames[TYPE_NBTYPES] = ...@@ -78,6 +78,7 @@ static const char * const TypeNames[TYPE_NBTYPES] =
}; };
#define MAX_ORDINALS 2048 #define MAX_ORDINALS 2048
#define MAX_IMPORTS 16
/* Callback function used for stub functions */ /* Callback function used for stub functions */
#define STUB_CALLBACK \ #define STUB_CALLBACK \
...@@ -159,6 +160,8 @@ static char *SpecName; ...@@ -159,6 +160,8 @@ static char *SpecName;
static FILE *SpecFp; static FILE *SpecFp;
static WORD Code_Selector, Data_Selector; static WORD Code_Selector, Data_Selector;
static char DLLInitFunc[80]; static char DLLInitFunc[80];
static char *DLLImports[MAX_IMPORTS];
static int nb_imports = 0;
char *ParseBuffer = NULL; char *ParseBuffer = NULL;
char *ParseNext; char *ParseNext;
...@@ -202,6 +205,16 @@ static void *xrealloc (void *ptr, size_t size) ...@@ -202,6 +205,16 @@ static void *xrealloc (void *ptr, size_t size)
return res; return res;
} }
static char *xstrdup( const char *str )
{
char *res = strdup( str );
if (!res)
{
fprintf (stderr, "Virtual memory exhausted.\n");
exit (1);
}
return res;
}
static int IsNumberString(char *s) static int IsNumberString(char *s)
{ {
...@@ -737,6 +750,21 @@ static int ParseTopLevel(void) ...@@ -737,6 +750,21 @@ static int ParseTopLevel(void)
if (!DLLInitFunc[0]) if (!DLLInitFunc[0])
fprintf(stderr, "%s:%d: Expected function name after init\n", SpecName, Line); fprintf(stderr, "%s:%d: Expected function name after init\n", SpecName, Line);
} }
else if (strcmp(token, "import") == 0)
{
if (nb_imports >= MAX_IMPORTS)
{
fprintf( stderr, "%s:%d: Too many imports (limit %d)\n",
SpecName, Line, MAX_IMPORTS );
return -1;
}
if (SpecType != SPEC_WIN32)
{
fprintf( stderr, "%s:%d: Imports not supported for Win16\n", SpecName, Line );
return -1;
}
DLLImports[nb_imports++] = xstrdup(GetToken());
}
else if (IsNumberString(token)) else if (IsNumberString(token))
{ {
int ordinal; int ordinal;
...@@ -1198,6 +1226,19 @@ static int BuildSpec32File( char * specfile, FILE *outfile ) ...@@ -1198,6 +1226,19 @@ static int BuildSpec32File( char * specfile, FILE *outfile )
} }
fprintf( outfile, "\n};\n\n" ); fprintf( outfile, "\n};\n\n" );
/* Output the DLL imports */
if (nb_imports)
{
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 the DLL descriptor */ /* Output the DLL descriptor */
fprintf( outfile, "const BUILTIN32_DESCRIPTOR %s_Descriptor =\n{\n", fprintf( outfile, "const BUILTIN32_DESCRIPTOR %s_Descriptor =\n{\n",
...@@ -1206,6 +1247,7 @@ static int BuildSpec32File( char * specfile, FILE *outfile ) ...@@ -1206,6 +1247,7 @@ static int BuildSpec32File( char * specfile, FILE *outfile )
fprintf( outfile, " %d,\n", Base ); fprintf( outfile, " %d,\n", Base );
fprintf( outfile, " %d,\n", Limit - Base + 1 ); fprintf( outfile, " %d,\n", Limit - Base + 1 );
fprintf( outfile, " %d,\n", nb_names ); fprintf( outfile, " %d,\n", nb_names );
fprintf( outfile, " %d,\n", nb_imports );
fprintf( outfile, " %d,\n", (fwd_size + 3) & ~3 ); fprintf( outfile, " %d,\n", (fwd_size + 3) & ~3 );
fprintf( outfile, fprintf( outfile,
" Functions,\n" " Functions,\n"
...@@ -1213,6 +1255,7 @@ static int BuildSpec32File( char * specfile, FILE *outfile ) ...@@ -1213,6 +1255,7 @@ static int BuildSpec32File( char * specfile, FILE *outfile )
" FuncOrdinals,\n" " FuncOrdinals,\n"
" FuncArgs,\n" " FuncArgs,\n"
" ArgTypes,\n"); " ArgTypes,\n");
fprintf( outfile, " %s,\n", nb_imports ? "Imports" : "0" );
fprintf( outfile, " %s\n", DLLInitFunc[0] ? DLLInitFunc : "0" ); fprintf( outfile, " %s\n", DLLInitFunc[0] ? DLLInitFunc : "0" );
fprintf( outfile, "};\n" ); fprintf( outfile, "};\n" );
return 0; return 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment