From e4177e67cfa840c40b3610b68b519bf5d61c864a Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 12 May 1999 09:57:37 +0000 Subject: [PATCH] Added import declaration for Win32 built-ins. --- include/builtin32.h | 2 ++ relay32/builtin32.c | 43 +++++++++++++++++++++++++++++++++++++++---- tools/build-spec.txt | 22 ++++++++++++++++------ tools/build.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 100 insertions(+), 10 deletions(-) diff --git a/include/builtin32.h b/include/builtin32.h index 25055dc55b8..4edb4857da3 100644 --- a/include/builtin32.h +++ b/include/builtin32.h @@ -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; diff --git a/relay32/builtin32.c b/relay32/builtin32.c index bd705c19d3a..f32a2498218 100644 --- a/relay32/builtin32.c +++ b/relay32/builtin32.c @@ -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]; diff --git a/tools/build-spec.txt b/tools/build-spec.txt index bb35b6e457f..415fcaa0216 100644 --- a/tools/build-spec.txt +++ b/tools/build-spec.txt @@ -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. .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. .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: diff --git a/tools/build.c b/tools/build.c index 69d1114e694..1971212eb4c 100644 --- a/tools/build.c +++ b/tools/build.c @@ -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;