Added import declaration for Win32 built-ins.
This commit is contained in:
parent
3eb441c7c4
commit
e4177e67cf
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue