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
int base; /* Ordinal base */
int nb_funcs; /* Number of functions */
int nb_names; /* Number of function names */
int nb_imports; /* Number of imported DLLs */
int fwd_size; /* Total size of forward names */
const ENTRYPOINT32 *functions; /* Pointer to function table */
const char * const *names; /* Pointer to names table */
const unsigned short *ordinals; /* Pointer to ordinals table */
const unsigned char *args; /* Pointer to argument lengths */
const unsigned int *argtypes; /* Pointer to argument types bitmask */
const char * const *imports; /* Pointer to imports */
const ENTRYPOINT32 dllentrypoint;/* Pointer to LibMain function */
} BUILTIN32_DESCRIPTOR;
......
......@@ -159,18 +159,22 @@ static HMODULE BUILTIN32_DoLoadImage( BUILTIN32_DLL *dll )
IMAGE_NT_HEADERS *nt;
IMAGE_SECTION_HEADER *sec;
IMAGE_EXPORT_DIRECTORY *exp;
IMAGE_IMPORT_DESCRIPTOR *imp;
LPVOID *funcs;
LPSTR *names;
LPSTR pfwd;
DEBUG_ENTRY_POINT *debug;
INT i, size;
INT i, size, nb_sections;
BYTE *addr;
/* Allocate the module */
nb_sections = 2; /* exports + code */
if (dll->descr->nb_imports) nb_sections++;
size = (sizeof(IMAGE_DOS_HEADER)
+ 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)
+ dll->descr->nb_funcs * sizeof(LPVOID)
+ dll->descr->nb_names * sizeof(LPSTR)
......@@ -184,7 +188,8 @@ static HMODULE BUILTIN32_DoLoadImage( BUILTIN32_DLL *dll )
dos = (IMAGE_DOS_HEADER *)addr;
nt = (IMAGE_NT_HEADERS *)(dos + 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);
names = (LPSTR *)(funcs + dll->descr->nb_funcs);
pfwd = (LPSTR)(names + dll->descr->nb_names);
......@@ -197,7 +202,7 @@ static HMODULE BUILTIN32_DoLoadImage( BUILTIN32_DLL *dll )
nt->Signature = IMAGE_NT_SIGNATURE;
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.Characteristics = IMAGE_FILE_DLL;
......@@ -218,6 +223,36 @@ static HMODULE BUILTIN32_DoLoadImage( BUILTIN32_DLL *dll )
if (dll->descr->dllentrypoint)
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 */
dir = &nt->OptionalHeader.DataDirectory[IMAGE_FILE_EXPORT_DIRECTORY];
......
......@@ -3,6 +3,7 @@ type win16|win32
[file WINFILENAME]
[base ORDINAL]
[heap SIZE]
[import DLL]
ORDINAL VARTYPE EXPORTNAME (DATA [DATA [DATA [...]]])
......@@ -26,13 +27,22 @@ General:
"name" and "type" fields are mandatory. Specific ordinal
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
modules); default is no local heap. "file" gives the name of the
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
Windows file KRNL386.EXE). Lines whose first character is a '#' will
be ignored as comments.
modules); default is no local heap.
"file" gives the name of the 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 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:
......
......@@ -78,6 +78,7 @@ static const char * const TypeNames[TYPE_NBTYPES] =
};
#define MAX_ORDINALS 2048
#define MAX_IMPORTS 16
/* Callback function used for stub functions */
#define STUB_CALLBACK \
......@@ -159,6 +160,8 @@ static char *SpecName;
static FILE *SpecFp;
static WORD Code_Selector, Data_Selector;
static char DLLInitFunc[80];
static char *DLLImports[MAX_IMPORTS];
static int nb_imports = 0;
char *ParseBuffer = NULL;
char *ParseNext;
......@@ -202,6 +205,16 @@ static void *xrealloc (void *ptr, size_t size)
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)
{
......@@ -737,6 +750,21 @@ static int ParseTopLevel(void)
if (!DLLInitFunc[0])
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))
{
int ordinal;
......@@ -1198,6 +1226,19 @@ static int BuildSpec32File( char * specfile, FILE *outfile )
}
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 */
fprintf( outfile, "const BUILTIN32_DESCRIPTOR %s_Descriptor =\n{\n",
......@@ -1206,6 +1247,7 @@ static int BuildSpec32File( char * specfile, FILE *outfile )
fprintf( outfile, " %d,\n", Base );
fprintf( outfile, " %d,\n", Limit - Base + 1 );
fprintf( outfile, " %d,\n", nb_names );
fprintf( outfile, " %d,\n", nb_imports );
fprintf( outfile, " %d,\n", (fwd_size + 3) & ~3 );
fprintf( outfile,
" Functions,\n"
......@@ -1213,6 +1255,7 @@ static int BuildSpec32File( char * specfile, FILE *outfile )
" FuncOrdinals,\n"
" FuncArgs,\n"
" ArgTypes,\n");
fprintf( outfile, " %s,\n", nb_imports ? "Imports" : "0" );
fprintf( outfile, " %s\n", DLLInitFunc[0] ? DLLInitFunc : "0" );
fprintf( outfile, "};\n" );
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