Generate the 16-bit module header in the standard on-disk format, so
that winebuild doesn't need to know about kernel internal structures.
This commit is contained in:
parent
66b019c1a8
commit
67204137ee
|
@ -70,12 +70,10 @@ struct ne_segment_table_entry_s
|
|||
|
||||
typedef struct
|
||||
{
|
||||
void *module_start; /* 32-bit address of the module data */
|
||||
int module_size; /* Size of the module data */
|
||||
void *code_start; /* 32-bit address of DLL code */
|
||||
void *data_start; /* 32-bit address of DLL data */
|
||||
const char *owner; /* 32-bit dll that contains this dll */
|
||||
const void *rsrc; /* resources data */
|
||||
const char *file_name; /* module file name */
|
||||
const void *module; /* module header */
|
||||
void *code_start; /* 32-bit address of DLL code */
|
||||
const void *rsrc; /* resources data */
|
||||
} BUILTIN16_DESCRIPTOR;
|
||||
|
||||
/* Table of all built-in DLLs */
|
||||
|
@ -157,12 +155,11 @@ static const BUILTIN16_DESCRIPTOR *find_dll_descr( const char *dllname )
|
|||
const BUILTIN16_DESCRIPTOR *descr = builtin_dlls[i];
|
||||
if (descr)
|
||||
{
|
||||
IMAGE_OS2_HEADER *pModule = descr->module_start;
|
||||
OFSTRUCT *pOfs = (OFSTRUCT *)(pModule + 1);
|
||||
const IMAGE_OS2_HEADER *pModule = descr->module;
|
||||
BYTE *name_table = (BYTE *)pModule + pModule->ne_restab;
|
||||
|
||||
/* check the dll file name */
|
||||
if (!NE_strcasecmp( pOfs->szPathName, dllname )) return descr;
|
||||
if (!NE_strcasecmp( descr->file_name, dllname )) return descr;
|
||||
/* check the dll module name (without extension) */
|
||||
if (!NE_strncasecmp( dllname, name_table+1, *name_table ) &&
|
||||
!strcmp( dllname + *name_table, ".dll" ))
|
||||
|
@ -1077,32 +1074,23 @@ static HINSTANCE16 NE_LoadModule( LPCSTR name, BOOL lib_only )
|
|||
*/
|
||||
static HMODULE16 NE_DoLoadBuiltinModule( const BUILTIN16_DESCRIPTOR *descr )
|
||||
{
|
||||
IMAGE_OS2_HEADER *header;
|
||||
NE_MODULE *pModule;
|
||||
OFSTRUCT *ofs;
|
||||
int minsize;
|
||||
SEGTABLEENTRY *pSegTable;
|
||||
HMODULE16 hModule;
|
||||
SEGTABLEENTRY *pSegTable;
|
||||
const IMAGE_DOS_HEADER *mz_header;
|
||||
const IMAGE_OS2_HEADER *ne_header;
|
||||
unsigned int fastload_offset, fastload_length;
|
||||
|
||||
hModule = GLOBAL_CreateBlock( GMEM_MOVEABLE, descr->module_start,
|
||||
descr->module_size, 0, WINE_LDT_FLAGS_DATA );
|
||||
if (!hModule) return ERROR_NOT_ENOUGH_MEMORY;
|
||||
FarSetOwner16( hModule, hModule );
|
||||
|
||||
header = GlobalLock16( hModule );
|
||||
pModule = (NE_MODULE *)header;
|
||||
ofs = (OFSTRUCT *)(header + 1);
|
||||
/* move the fileinfo structure a bit further to make space for the Wine-specific fields */
|
||||
if (sizeof(*header) + sizeof(*ofs) < sizeof(*pModule) + ofs->cBytes + 1)
|
||||
{
|
||||
FIXME( "module name %s too long\n", debugstr_a(ofs->szPathName) );
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
memmove( pModule + 1, ofs, ofs->cBytes + 1 );
|
||||
|
||||
mz_header = descr->module;
|
||||
ne_header = (const IMAGE_OS2_HEADER *)((const BYTE *)mz_header + mz_header->e_lfanew);
|
||||
fastload_offset = ne_header->ne_pretthunks << ne_header->ne_align;
|
||||
fastload_length = ne_header->ne_psegrefbytes << ne_header->ne_align;
|
||||
hModule = build_module( mz_header, ne_header, 0, descr->file_name,
|
||||
descr->module, fastload_offset, fastload_length );
|
||||
if (hModule < 32) return hModule;
|
||||
pModule = GlobalLock16( hModule );
|
||||
pModule->ne_flags |= NE_FFLAGS_BUILTIN;
|
||||
pModule->count = 1;
|
||||
pModule->fileinfo = sizeof(*pModule);
|
||||
pModule->self = hModule;
|
||||
/* NOTE: (Ab)use the rsrc32_map parameter for resource data pointer */
|
||||
pModule->rsrc32_map = (void *)descr->rsrc;
|
||||
|
||||
|
@ -1114,26 +1102,26 @@ static HMODULE16 NE_DoLoadBuiltinModule( const BUILTIN16_DESCRIPTOR *descr )
|
|||
WINE_LDT_FLAGS_CODE|WINE_LDT_FLAGS_32BIT );
|
||||
if (!pSegTable->hSeg) return ERROR_NOT_ENOUGH_MEMORY;
|
||||
patch_code_segment( descr->code_start );
|
||||
pSegTable->flags |= NE_SEGFLAGS_ALLOCATED | NE_SEGFLAGS_LOADED;
|
||||
pSegTable++;
|
||||
|
||||
/* Allocate the data segment */
|
||||
|
||||
minsize = pSegTable->minsize ? pSegTable->minsize : 0x10000;
|
||||
minsize += pModule->ne_heap;
|
||||
if (minsize > 0x10000) minsize = 0x10000;
|
||||
pSegTable->hSeg = GlobalAlloc16( GMEM_FIXED, minsize );
|
||||
if (!pSegTable->hSeg) return ERROR_NOT_ENOUGH_MEMORY;
|
||||
FarSetOwner16( pSegTable->hSeg, hModule );
|
||||
if (!NE_CreateSegment( pModule, 2 )) return ERROR_NOT_ENOUGH_MEMORY;
|
||||
pModule->dgroup_entry = (char *)pSegTable - (char *)pModule;
|
||||
if (pSegTable->minsize) memcpy( GlobalLock16( pSegTable->hSeg ),
|
||||
descr->data_start, pSegTable->minsize);
|
||||
memcpy( GlobalLock16( pSegTable->hSeg ),
|
||||
(const char *)descr->module + (pSegTable->filepos << pModule->ne_align),
|
||||
pSegTable->minsize);
|
||||
pSegTable->flags |= NE_SEGFLAGS_LOADED;
|
||||
|
||||
if (pModule->ne_heap)
|
||||
LocalInit16( GlobalHandleToSel16(pSegTable->hSeg), pSegTable->minsize, minsize );
|
||||
{
|
||||
unsigned int size = pSegTable->minsize + pModule->ne_heap;
|
||||
if (size > 0xfffe) size = 0xfffe;
|
||||
LocalInit16( GlobalHandleToSel16(pSegTable->hSeg), pSegTable->minsize, size );
|
||||
}
|
||||
|
||||
NE_InitResourceHandler( hModule );
|
||||
|
||||
NE_RegisterModule( pModule );
|
||||
|
||||
return hModule;
|
||||
}
|
||||
|
||||
|
|
|
@ -178,7 +178,7 @@ extern int load_res32_file( const char *name, DLLSPEC *spec );
|
|||
extern void output_resources( FILE *outfile, DLLSPEC *spec );
|
||||
extern void load_res16_file( const char *name, DLLSPEC *spec );
|
||||
extern int output_res16_data( FILE *outfile, DLLSPEC *spec );
|
||||
extern int output_res16_directory( unsigned char *buffer, DLLSPEC *spec );
|
||||
extern unsigned int output_res16_directory( unsigned char **ret_buf, DLLSPEC *spec );
|
||||
extern void output_dll_init( FILE *outfile, const char *constructor, const char *destructor );
|
||||
|
||||
extern void BuildRelays16( FILE *outfile );
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -293,21 +294,35 @@ int output_res16_data( FILE *outfile, DLLSPEC *spec )
|
|||
}
|
||||
|
||||
/* output the resource definitions */
|
||||
int output_res16_directory( unsigned char *buffer, DLLSPEC *spec )
|
||||
unsigned int output_res16_directory( unsigned char **ret_buf, DLLSPEC *spec )
|
||||
{
|
||||
int offset, res_offset = 0;
|
||||
unsigned int i, j;
|
||||
unsigned int i, j, total_size;
|
||||
struct res_tree *tree;
|
||||
const struct res_type *type;
|
||||
const struct resource *res;
|
||||
unsigned char *start = buffer;
|
||||
unsigned char *buffer;
|
||||
|
||||
tree = build_resource_tree( spec );
|
||||
|
||||
/* first compute total size */
|
||||
|
||||
offset = 4; /* alignment + terminator */
|
||||
offset += tree->nb_types * 8; /* typeinfo structures */
|
||||
offset += spec->nb_resources * 12; /* nameinfo structures */
|
||||
|
||||
total_size = offset;
|
||||
|
||||
for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
|
||||
{
|
||||
if (type->type->str) total_size += strlen(type->type->str) + 1;
|
||||
for (j = 0, res = type->res; j < type->nb_names; j++, res++)
|
||||
if (res->name.str) total_size += strlen(res->name.str) + 1;
|
||||
}
|
||||
total_size++; /* final terminator */
|
||||
if (total_size & 1) total_size++;
|
||||
*ret_buf = buffer = xmalloc( total_size );
|
||||
|
||||
put_word( &buffer, ALIGNMENT );
|
||||
|
||||
/* type and name structures */
|
||||
|
@ -356,8 +371,9 @@ int output_res16_directory( unsigned char *buffer, DLLSPEC *spec )
|
|||
}
|
||||
}
|
||||
put_byte( &buffer, 0 ); /* names terminator */
|
||||
if ((buffer - start) & 1) put_byte( &buffer, 0 ); /* align on word boundary */
|
||||
if ((buffer - *ret_buf) & 1) put_byte( &buffer, 0 ); /* align on word boundary */
|
||||
assert( buffer - *ret_buf == total_size );
|
||||
|
||||
free_resource_tree( tree );
|
||||
return buffer - start;
|
||||
return total_size;
|
||||
}
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
|
||||
#include "wine/exception.h"
|
||||
#include "wine/winbase16.h"
|
||||
#include "module.h"
|
||||
|
||||
#include "build.h"
|
||||
|
||||
|
@ -104,179 +103,312 @@ static int StoreVariableCode( unsigned char *buffer, int size, ORDDEF *odp )
|
|||
|
||||
|
||||
/*******************************************************************
|
||||
* BuildModule16
|
||||
*
|
||||
* Build the in-memory representation of a 16-bit NE module, and dump it
|
||||
* as a byte stream into the assembly code.
|
||||
* output_entry_table
|
||||
*/
|
||||
static int BuildModule16( FILE *outfile, int max_code_offset,
|
||||
int max_data_offset, DLLSPEC *spec )
|
||||
static int output_entry_table( unsigned char **ret_buff, DLLSPEC *spec )
|
||||
{
|
||||
int i;
|
||||
char *buffer, *pstr;
|
||||
IMAGE_OS2_HEADER *pModule;
|
||||
SEGTABLEENTRY *pSegment;
|
||||
OFSTRUCT *pFileInfo;
|
||||
ET_BUNDLE *bundle = 0;
|
||||
ET_ENTRY entry;
|
||||
int i, prev = 0, prev_sel = -1;
|
||||
unsigned char *pstr, *buffer;
|
||||
unsigned char *bundle = NULL;
|
||||
|
||||
/* Module layout:
|
||||
* IMAGE_OS2_HEADER Module
|
||||
* OFSTRUCT File information
|
||||
* SEGTABLEENTRY Segment 1 (code)
|
||||
* SEGTABLEENTRY Segment 2 (data)
|
||||
* WORD[2] Resource table (empty)
|
||||
* BYTE[2] Imported names (empty)
|
||||
* BYTE[n] Resident names table
|
||||
* BYTE[n] Entry table
|
||||
*/
|
||||
buffer = xmalloc( spec->limit * 5 ); /* we use at most 5 bytes per entry-point */
|
||||
pstr = buffer;
|
||||
|
||||
buffer = xmalloc( 0x10000 );
|
||||
memset( buffer, 0, 0x10000 );
|
||||
|
||||
pModule = (IMAGE_OS2_HEADER *)buffer;
|
||||
pModule->ne_magic = IMAGE_OS2_SIGNATURE;
|
||||
pModule->ne_flags = NE_FFLAGS_SINGLEDATA | NE_FFLAGS_BUILTIN | NE_FFLAGS_LIBMODULE;
|
||||
pModule->ne_autodata = 2;
|
||||
pModule->ne_heap = spec->heap_size;
|
||||
pModule->ne_cseg = 2;
|
||||
pModule->ne_exetyp = NE_OSFLAGS_WINDOWS;
|
||||
|
||||
/* File information */
|
||||
|
||||
pFileInfo = (OFSTRUCT *)(pModule + 1);
|
||||
pFileInfo->cBytes = sizeof(*pFileInfo) - sizeof(pFileInfo->szPathName)
|
||||
+ strlen(spec->file_name);
|
||||
strcpy( pFileInfo->szPathName, spec->file_name );
|
||||
/* note: we allocate the whole OFSTRUCT so that the loader has some extra space to play with */
|
||||
|
||||
/* Segment table */
|
||||
|
||||
pSegment = (SEGTABLEENTRY *)(pFileInfo + 1);
|
||||
pModule->ne_segtab = (char *)pSegment - buffer;
|
||||
pSegment->filepos = 0;
|
||||
pSegment->size = max_code_offset;
|
||||
pSegment->flags = 0;
|
||||
pSegment->minsize = max_code_offset;
|
||||
pSegment->hSeg = 0;
|
||||
pSegment++;
|
||||
|
||||
pSegment->filepos = 0;
|
||||
pSegment->size = max_data_offset;
|
||||
pSegment->flags = NE_SEGFLAGS_DATA;
|
||||
pSegment->minsize = max_data_offset;
|
||||
pSegment->hSeg = 0;
|
||||
pSegment++;
|
||||
|
||||
/* Resource table */
|
||||
|
||||
pstr = (char *)pSegment;
|
||||
pstr = (char *)(((long)pstr + 3) & ~3);
|
||||
pModule->ne_rsrctab = pstr - buffer;
|
||||
pstr += output_res16_directory( pstr, spec );
|
||||
|
||||
/* Imported names table */
|
||||
|
||||
pstr = (char *)(((long)pstr + 3) & ~3);
|
||||
pModule->ne_imptab = pstr - buffer;
|
||||
*pstr++ = 0;
|
||||
*pstr++ = 0;
|
||||
|
||||
/* Resident names table */
|
||||
|
||||
pstr = (char *)(((long)pstr + 3) & ~3);
|
||||
pModule->ne_restab = pstr - buffer;
|
||||
/* First entry is module name */
|
||||
*pstr = strlen( spec->dll_name );
|
||||
strcpy( pstr + 1, spec->dll_name );
|
||||
strupper( pstr + 1 );
|
||||
pstr += *pstr + 1;
|
||||
*pstr++ = 0;
|
||||
*pstr++ = 0;
|
||||
/* Store all ordinals */
|
||||
for (i = 1; i <= spec->limit; i++)
|
||||
{
|
||||
ORDDEF *odp = spec->ordinals[i];
|
||||
WORD ord = i;
|
||||
if (!odp || !odp->name[0]) continue;
|
||||
*pstr = strlen( odp->name );
|
||||
strcpy( pstr + 1, odp->name );
|
||||
strupper( pstr + 1 );
|
||||
pstr += *pstr + 1;
|
||||
memcpy( pstr, &ord, sizeof(WORD) );
|
||||
pstr += sizeof(WORD);
|
||||
}
|
||||
*pstr++ = 0;
|
||||
|
||||
/* Entry table */
|
||||
|
||||
pstr = (char *)(((long)pstr + 3) & ~3);
|
||||
pModule->ne_enttab = pstr - buffer;
|
||||
for (i = 1; i <= spec->limit; i++)
|
||||
{
|
||||
int selector = 0;
|
||||
WORD offset;
|
||||
ORDDEF *odp = spec->ordinals[i];
|
||||
if (!odp) continue;
|
||||
|
||||
switch (odp->type)
|
||||
{
|
||||
switch (odp->type)
|
||||
{
|
||||
case TYPE_CDECL:
|
||||
case TYPE_PASCAL:
|
||||
case TYPE_VARARGS:
|
||||
case TYPE_STUB:
|
||||
selector = 1; /* Code selector */
|
||||
break;
|
||||
|
||||
case TYPE_VARIABLE:
|
||||
selector = 2; /* Data selector */
|
||||
break;
|
||||
|
||||
case TYPE_ABS:
|
||||
selector = 0xfe; /* Constant selector */
|
||||
break;
|
||||
|
||||
default:
|
||||
selector = 0; /* Invalid selector */
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !selector )
|
||||
continue;
|
||||
|
||||
if ( bundle && bundle->last+1 == i )
|
||||
bundle->last++;
|
||||
else
|
||||
if (!bundle || prev + 1 != i || prev_sel != selector || *bundle == 255)
|
||||
{
|
||||
pstr = (char *)(((long)pstr + 1) & ~1);
|
||||
if ( bundle )
|
||||
bundle->next = pstr - buffer;
|
||||
/* need to start a new bundle */
|
||||
|
||||
bundle = (ET_BUNDLE *)pstr;
|
||||
bundle->first = i-1;
|
||||
bundle->last = i;
|
||||
bundle->next = 0;
|
||||
pstr += sizeof(ET_BUNDLE);
|
||||
if (prev + 1 != i)
|
||||
{
|
||||
int skip = i - (prev + 1);
|
||||
while (skip > 255)
|
||||
{
|
||||
*pstr++ = 255;
|
||||
*pstr++ = 0;
|
||||
skip -= 255;
|
||||
}
|
||||
*pstr++ = skip;
|
||||
*pstr++ = 0;
|
||||
}
|
||||
|
||||
bundle = pstr;
|
||||
*pstr++ = 0;
|
||||
*pstr++ = selector;
|
||||
prev_sel = selector;
|
||||
}
|
||||
|
||||
/* FIXME: is this really correct ?? */
|
||||
entry.type = 0xff; /* movable */
|
||||
entry.flags = 3; /* exported & public data */
|
||||
entry.segnum = selector;
|
||||
entry.offs = odp->offset;
|
||||
memcpy( pstr, &entry, sizeof(ET_ENTRY) );
|
||||
pstr += sizeof(ET_ENTRY);
|
||||
/* output the entry */
|
||||
*pstr++ = 3; /* flags: exported & public data */
|
||||
offset = odp->offset;
|
||||
memcpy( pstr, &offset, sizeof(WORD) );
|
||||
pstr += sizeof(WORD);
|
||||
(*bundle)++; /* increment bundle entry count */
|
||||
prev = i;
|
||||
}
|
||||
*pstr++ = 0;
|
||||
|
||||
/* Dump the module content */
|
||||
|
||||
pstr = (char *)(((long)pstr + 3) & ~3);
|
||||
dump_bytes( outfile, buffer, pstr - buffer, "Module", 0 );
|
||||
free( buffer );
|
||||
if ((pstr - buffer) & 1) *pstr++ = 0;
|
||||
*ret_buff = xrealloc( buffer, pstr - buffer );
|
||||
return pstr - buffer;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* output_bytes
|
||||
*/
|
||||
static void output_bytes( FILE *outfile, const void *buffer, unsigned int size )
|
||||
{
|
||||
unsigned int i;
|
||||
const unsigned char *ptr = buffer;
|
||||
|
||||
fprintf( outfile, " {" );
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
if (!(i & 7)) fprintf( outfile, "\n " );
|
||||
fprintf( outfile, " 0x%02x", *ptr++ );
|
||||
if (i < size - 1) fprintf( outfile, "," );
|
||||
}
|
||||
fprintf( outfile, "\n },\n" );
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* output_module_data
|
||||
*
|
||||
* Output the 16-bit NE module structure.
|
||||
*/
|
||||
static void output_module_data( FILE *outfile, int max_code_offset, const void *data_segment,
|
||||
unsigned int data_size, DLLSPEC *spec )
|
||||
{
|
||||
unsigned char *res_buffer, *et_buffer;
|
||||
unsigned char string[256];
|
||||
int i;
|
||||
unsigned int segtable_offset, resdir_offset, impnames_offset, resnames_offset, et_offset, data_offset;
|
||||
unsigned int resnames_size, resdir_size, et_size;
|
||||
|
||||
/* DOS header */
|
||||
|
||||
fprintf( outfile, "static const struct module_data\n{\n" );
|
||||
fprintf( outfile, " struct\n {\n" );
|
||||
fprintf( outfile, " unsigned short e_magic;\n" );
|
||||
fprintf( outfile, " unsigned short e_cblp;\n" );
|
||||
fprintf( outfile, " unsigned short e_cp;\n" );
|
||||
fprintf( outfile, " unsigned short e_crlc;\n" );
|
||||
fprintf( outfile, " unsigned short e_cparhdr;\n" );
|
||||
fprintf( outfile, " unsigned short e_minalloc;\n" );
|
||||
fprintf( outfile, " unsigned short e_maxalloc;\n" );
|
||||
fprintf( outfile, " unsigned short e_ss;\n" );
|
||||
fprintf( outfile, " unsigned short e_sp;\n" );
|
||||
fprintf( outfile, " unsigned short e_csum;\n" );
|
||||
fprintf( outfile, " unsigned short e_ip;\n" );
|
||||
fprintf( outfile, " unsigned short e_cs;\n" );
|
||||
fprintf( outfile, " unsigned short e_lfarlc;\n" );
|
||||
fprintf( outfile, " unsigned short e_ovno;\n" );
|
||||
fprintf( outfile, " unsigned short e_res[4];\n" );
|
||||
fprintf( outfile, " unsigned short e_oemid;\n" );
|
||||
fprintf( outfile, " unsigned short e_oeminfo;\n" );
|
||||
fprintf( outfile, " unsigned short e_res2[10];\n" );
|
||||
fprintf( outfile, " unsigned int e_lfanew;\n" );
|
||||
fprintf( outfile, " } dos_header;\n" );
|
||||
|
||||
/* NE header */
|
||||
|
||||
fprintf( outfile, " struct\n {\n" );
|
||||
fprintf( outfile, " unsigned short ne_magic;\n" );
|
||||
fprintf( outfile, " unsigned char ne_ver;\n" );
|
||||
fprintf( outfile, " unsigned char ne_rev;\n" );
|
||||
fprintf( outfile, " unsigned short ne_enttab;\n" );
|
||||
fprintf( outfile, " unsigned short ne_cbenttab;\n" );
|
||||
fprintf( outfile, " int ne_crc;\n" );
|
||||
fprintf( outfile, " unsigned short ne_flags;\n" );
|
||||
fprintf( outfile, " unsigned short ne_autodata;\n" );
|
||||
fprintf( outfile, " unsigned short ne_heap;\n" );
|
||||
fprintf( outfile, " unsigned short ne_stack;\n" );
|
||||
fprintf( outfile, " unsigned int ne_csip;\n" );
|
||||
fprintf( outfile, " unsigned int ne_sssp;\n" );
|
||||
fprintf( outfile, " unsigned short ne_cseg;\n" );
|
||||
fprintf( outfile, " unsigned short ne_cmod;\n" );
|
||||
fprintf( outfile, " unsigned short ne_cbnrestab;\n" );
|
||||
fprintf( outfile, " unsigned short ne_segtab;\n" );
|
||||
fprintf( outfile, " unsigned short ne_rsrctab;\n" );
|
||||
fprintf( outfile, " unsigned short ne_restab;\n" );
|
||||
fprintf( outfile, " unsigned short ne_modtab;\n" );
|
||||
fprintf( outfile, " unsigned short ne_imptab;\n" );
|
||||
fprintf( outfile, " unsigned int ne_nrestab;\n" );
|
||||
fprintf( outfile, " unsigned short ne_cmovent;\n" );
|
||||
fprintf( outfile, " unsigned short ne_align;\n" );
|
||||
fprintf( outfile, " unsigned short ne_cres;\n" );
|
||||
fprintf( outfile, " unsigned char ne_exetyp;\n" );
|
||||
fprintf( outfile, " unsigned char ne_flagsothers;\n" );
|
||||
fprintf( outfile, " unsigned short ne_pretthunks;\n" );
|
||||
fprintf( outfile, " unsigned short ne_psegrefbytes;\n" );
|
||||
fprintf( outfile, " unsigned short ne_swaparea;\n" );
|
||||
fprintf( outfile, " unsigned short ne_expver;\n" );
|
||||
fprintf( outfile, " } os2_header;\n" );
|
||||
|
||||
/* segment table */
|
||||
|
||||
segtable_offset = 64;
|
||||
fprintf( outfile, " struct\n {\n" );
|
||||
fprintf( outfile, " unsigned short filepos;\n" );
|
||||
fprintf( outfile, " unsigned short size;\n" );
|
||||
fprintf( outfile, " unsigned short flags;\n" );
|
||||
fprintf( outfile, " unsigned short minsize;\n" );
|
||||
fprintf( outfile, " } segtable[2];\n" );
|
||||
|
||||
/* resource directory */
|
||||
|
||||
resdir_offset = segtable_offset + 2 * 8;
|
||||
resdir_size = output_res16_directory( &res_buffer, spec );
|
||||
fprintf( outfile, " unsigned char resdir[%d];\n", resdir_size );
|
||||
|
||||
/* resident names table */
|
||||
|
||||
resnames_offset = resdir_offset + resdir_size;
|
||||
fprintf( outfile, " struct\n {\n" );
|
||||
fprintf( outfile, " struct { unsigned char len; char name[%d]; unsigned short ord; } name_0;\n",
|
||||
strlen( spec->dll_name ) );
|
||||
resnames_size = 3 + strlen( spec->dll_name );
|
||||
for (i = 1; i <= spec->limit; i++)
|
||||
{
|
||||
ORDDEF *odp = spec->ordinals[i];
|
||||
if (!odp || !odp->name[0]) continue;
|
||||
fprintf( outfile, " struct { unsigned char len; char name[%d]; unsigned short ord; } name_%d;\n",
|
||||
strlen(odp->name), i );
|
||||
resnames_size += 3 + strlen( odp->name );
|
||||
}
|
||||
fprintf( outfile, " unsigned char name_last[%d];\n", 2 - (resnames_size & 1) );
|
||||
resnames_size = (resnames_size + 2) & ~1;
|
||||
fprintf( outfile, " } resnames;\n" );
|
||||
|
||||
/* imported names table */
|
||||
|
||||
impnames_offset = resnames_offset + resnames_size;
|
||||
fprintf( outfile, " unsigned char impnames[2];\n" );
|
||||
|
||||
/* entry table */
|
||||
|
||||
et_offset = impnames_offset + 2;
|
||||
et_size = output_entry_table( &et_buffer, spec );
|
||||
fprintf( outfile, " unsigned char entry_table[%d];\n", et_size );
|
||||
|
||||
/* data segment */
|
||||
|
||||
data_offset = et_offset + et_size;
|
||||
fprintf( outfile, " unsigned char data_segment[%d];\n", data_size );
|
||||
if (data_offset + data_size >= 0x10000)
|
||||
fatal_error( "Not supported yet: 16-bit module data larger than 64K\n" );
|
||||
|
||||
/* DOS header */
|
||||
|
||||
fprintf( outfile, "} module =\n{\n {\n" );
|
||||
fprintf( outfile, " 0x%04x,\n", IMAGE_DOS_SIGNATURE ); /* e_magic */
|
||||
fprintf( outfile, " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n" );
|
||||
fprintf( outfile, " { 0, 0, 0, 0, }, 0, 0,\n" );
|
||||
fprintf( outfile, " { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },\n" );
|
||||
fprintf( outfile, " sizeof(module.dos_header)\n" ); /* e_lfanew */
|
||||
|
||||
/* NE header */
|
||||
|
||||
fprintf( outfile, " },\n {\n" );
|
||||
fprintf( outfile, " 0x%04x,\n", IMAGE_OS2_SIGNATURE ); /* ne_magic */
|
||||
fprintf( outfile, " 0, 0,\n" );
|
||||
fprintf( outfile, " %d,\n", et_offset ); /* ne_enttab */
|
||||
fprintf( outfile, " sizeof(module.entry_table),\n" ); /* ne_cbenttab */
|
||||
fprintf( outfile, " 0,\n" ); /* ne_crc */
|
||||
fprintf( outfile, " 0x%04x,\n", /* ne_flags */
|
||||
NE_FFLAGS_SINGLEDATA | NE_FFLAGS_LIBMODULE );
|
||||
fprintf( outfile, " 2,\n" ); /* ne_autodata */
|
||||
fprintf( outfile, " %d,\n", spec->heap_size ); /* ne_heap */
|
||||
fprintf( outfile, " 0, 0, 0,\n" );
|
||||
fprintf( outfile, " 2,\n" ); /* ne_cseg */
|
||||
fprintf( outfile, " 0,\n" ); /* ne_cmod */
|
||||
fprintf( outfile, " 0,\n" ); /* ne_cbnrestab */
|
||||
fprintf( outfile, " %d,\n", segtable_offset ); /* ne_segtab */
|
||||
fprintf( outfile, " %d,\n", resdir_offset ); /* ne_rsrctab */
|
||||
fprintf( outfile, " %d,\n", resnames_offset ); /* ne_restab */
|
||||
fprintf( outfile, " %d,\n", impnames_offset ); /* ne_modtab */
|
||||
fprintf( outfile, " %d,\n", impnames_offset ); /* ne_imptab */
|
||||
fprintf( outfile, " 0,\n" ); /* ne_nrestab */
|
||||
fprintf( outfile, " 0,\n" ); /* ne_cmovent */
|
||||
fprintf( outfile, " 0,\n" ); /* ne_align */
|
||||
fprintf( outfile, " 0,\n" ); /* ne_cres */
|
||||
fprintf( outfile, " 0x%04x,\n", NE_OSFLAGS_WINDOWS ); /* ne_exetyp */
|
||||
fprintf( outfile, " 0x%04x,\n", NE_AFLAGS_FASTLOAD ); /* ne_flagsothers */
|
||||
fprintf( outfile, " 0,\n" ); /* ne_pretthunks */
|
||||
fprintf( outfile, " sizeof(module),\n" ); /* ne_psegrefbytes */
|
||||
fprintf( outfile, " 0,\n" ); /* ne_swaparea */
|
||||
fprintf( outfile, " 0\n" ); /* ne_expver */
|
||||
fprintf( outfile, " },\n" );
|
||||
|
||||
/* segment table */
|
||||
|
||||
fprintf( outfile, " {\n" );
|
||||
fprintf( outfile, " { 0, %d, 0x%04x, %d },\n",
|
||||
max_code_offset, NE_SEGFLAGS_32BIT, max_code_offset );
|
||||
fprintf( outfile, " { %d, %d, 0x%04x, %d },\n",
|
||||
data_offset, data_size, NE_SEGFLAGS_DATA, data_size );
|
||||
fprintf( outfile, " },\n" );
|
||||
|
||||
/* resource directory */
|
||||
|
||||
output_bytes( outfile, res_buffer, resdir_size );
|
||||
free( res_buffer );
|
||||
|
||||
/* resident names table */
|
||||
|
||||
fprintf( outfile, " {\n" );
|
||||
strcpy( string, spec->dll_name );
|
||||
fprintf( outfile, " { %d, \"%s\", 0 },\n", strlen(string), strupper(string) );
|
||||
for (i = 1; i <= spec->limit; i++)
|
||||
{
|
||||
ORDDEF *odp = spec->ordinals[i];
|
||||
if (!odp || !odp->name[0]) continue;
|
||||
strcpy( string, odp->name );
|
||||
fprintf( outfile, " { %d, \"%s\", %d },\n", strlen(string), strupper(string), i );
|
||||
}
|
||||
fprintf( outfile, " { 0 }\n },\n" );
|
||||
|
||||
/* imported names table */
|
||||
|
||||
fprintf( outfile, " { 0, 0 },\n" );
|
||||
|
||||
/* entry table */
|
||||
|
||||
output_bytes( outfile, et_buffer, et_size );
|
||||
free( et_buffer );
|
||||
|
||||
/* data_segment */
|
||||
|
||||
output_bytes( outfile, data_segment, data_size );
|
||||
|
||||
fprintf( outfile, "};\n" );
|
||||
}
|
||||
|
||||
|
||||
#ifdef __i386__
|
||||
/*******************************************************************
|
||||
* BuildCallFrom16Func
|
||||
|
@ -528,7 +660,7 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec )
|
|||
{
|
||||
ORDDEF **type, **typelist;
|
||||
int i, nFuncs, nTypes;
|
||||
int code_offset, data_offset, module_size, res_size;
|
||||
int code_offset, data_offset, res_size;
|
||||
unsigned char *data;
|
||||
char constructor[100], destructor[100];
|
||||
#ifdef __i386__
|
||||
|
@ -756,13 +888,9 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec )
|
|||
|
||||
fprintf( outfile, " }\n};\n" );
|
||||
|
||||
/* Output data segment */
|
||||
|
||||
dump_bytes( outfile, data, data_offset, "Data_Segment", 0 );
|
||||
|
||||
/* Build the module */
|
||||
|
||||
module_size = BuildModule16( outfile, code_offset, data_offset, spec );
|
||||
output_module_data( outfile, code_offset, data, data_offset, spec );
|
||||
res_size = output_res16_data( outfile, spec );
|
||||
|
||||
/* Output the DLL descriptor */
|
||||
|
@ -770,18 +898,14 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec )
|
|||
fprintf( outfile, "#include \"poppack.h\"\n\n" );
|
||||
|
||||
fprintf( outfile, "static const struct dll_descriptor\n{\n" );
|
||||
fprintf( outfile, " unsigned char *module_start;\n" );
|
||||
fprintf( outfile, " int module_size;\n" );
|
||||
fprintf( outfile, " const char *file_name;\n" );
|
||||
fprintf( outfile, " const struct module_data *module;\n" );
|
||||
fprintf( outfile, " struct code_segment *code_start;\n" );
|
||||
fprintf( outfile, " unsigned char *data_start;\n" );
|
||||
fprintf( outfile, " const char *owner;\n" );
|
||||
fprintf( outfile, " const unsigned char *rsrc;\n" );
|
||||
fprintf( outfile, "} descriptor =\n{\n" );
|
||||
fprintf( outfile, " Module,\n" );
|
||||
fprintf( outfile, " sizeof(Module),\n" );
|
||||
fprintf( outfile, " \"%s\",\n", spec->file_name );
|
||||
fprintf( outfile, " &module,\n" );
|
||||
fprintf( outfile, " &code_segment,\n" );
|
||||
fprintf( outfile, " Data_Segment,\n" );
|
||||
fprintf( outfile, " \"%s\",\n", spec->owner_name );
|
||||
fprintf( outfile, " %s\n", res_size ? "resource_data" : "0" );
|
||||
fprintf( outfile, "};\n" );
|
||||
|
||||
|
|
Loading…
Reference in New Issue