- Implemented proper ("real", compressed) Win16 entry tables.

- Fixed MyAlloc (AKA NE_AllocateSegment).
- Implemented PatchCodeHandle16.
This commit is contained in:
Andreas Mohr 1999-04-16 08:17:17 +00:00 committed by Alexandre Julliard
parent 0a9975242a
commit dca5e56b90
5 changed files with 310 additions and 249 deletions

View File

@ -266,53 +266,33 @@ HMODULE16 BUILTIN_LoadModule( LPCSTR name, BOOL force )
LPCSTR BUILTIN_GetEntryPoint16( WORD cs, WORD ip, WORD *pOrd )
{
static char buffer[80];
WORD ordinal, i, max_offset;
WORD i, max_offset;
register BYTE *p;
NE_MODULE *pModule;
ET_BUNDLE *bundle;
ET_ENTRY *entry;
if (!(pModule = NE_GetPtr( FarGetOwner16( GlobalHandle16(cs) ))))
return NULL;
/* Search for the ordinal */
p = (BYTE *)pModule + pModule->entry_table;
max_offset = 0;
ordinal = 1;
*pOrd = 0;
while (*p)
{
switch(p[1])
{
case 0: /* unused */
ordinal += *p;
p += 2;
break;
case 1: /* code segment */
i = *p;
p += 2;
while (i-- > 0)
bundle = (ET_BUNDLE *)((BYTE *)pModule + pModule->entry_table);
entry = (ET_ENTRY *)((BYTE *)bundle+6);
do {
for (i = bundle->first + 1; i < bundle->last; i++)
{
p++;
if ((*(WORD *)p <= ip) && (*(WORD *)p >= max_offset))
if ((entry->offs <= ip)
&& (entry->type == 1) /* code segment ? */
&& (entry->offs >= max_offset))
{
max_offset = *(WORD *)p;
*pOrd = ordinal;
}
p += 2;
ordinal++;
}
break;
case 0xff: /* moveable (should not happen in built-in modules) */
TRACE( relay, "Built-in module has moveable entry\n" );
ordinal += *p;
p += 2 + *p * 6;
break;
default: /* other segment */
ordinal += *p;
p += 2 + *p * 3;
break;
max_offset = entry->offs;
*pOrd = i;
}
entry++;
}
} while ( (bundle->next)
&& (bundle = (ET_BUNDLE *)((BYTE *)pModule+bundle->next)));
/* Search for the name in the resident names table */
/* (built-in modules have no non-resident table) */

View File

@ -56,6 +56,20 @@ typedef struct _NE_MODULE
} NE_MODULE;
typedef struct {
BYTE type;
BYTE flags;
BYTE segnum;
WORD offs WINE_PACKED;
} ET_ENTRY;
typedef struct {
WORD first; /* ordinal */
WORD last; /* ordinal */
WORD next; /* bundle */
} ET_BUNDLE;
/* In-memory segment table */
typedef struct
{

View File

@ -59,6 +59,8 @@ void NE_DumpModule( HMODULE16 hModule )
BYTE *pstr;
WORD *pword;
NE_MODULE *pModule;
ET_BUNDLE *bundle;
ET_ENTRY *entry;
if (!(pModule = NE_GetPtr( hModule )))
{
@ -143,39 +145,21 @@ void NE_DumpModule( HMODULE16 hModule )
/* Dump the entry table */
DUMP( "---\n" );
DUMP( "Entry table:\n" );
pstr = (char *)pModule + pModule->entry_table;
ordinal = 1;
while (*pstr)
{
DUMP( "Bundle %d-%d: %02x\n", ordinal, ordinal + *pstr - 1, pstr[1]);
if (!pstr[1])
bundle = (ET_BUNDLE *)((BYTE *)pModule+pModule->entry_table);
do {
entry = (ET_ENTRY *)((BYTE *)bundle+6);
DUMP( "Bundle %d-%d: %02x\n", bundle->first, bundle->last, entry->type);
ordinal = bundle->first;
while (ordinal < bundle->last)
{
ordinal += *pstr;
pstr += 2;
}
else if ((BYTE)pstr[1] == 0xff) /* moveable */
{
i = *pstr;
pstr += 2;
while (i--)
{
DUMP( "%d: %02x:%04x (moveable)\n",
ordinal++, pstr[3], *(WORD *)(pstr + 4) );
pstr += 6;
}
}
else /* fixed */
{
i = *pstr;
pstr += 2;
while (i--)
{
DUMP( "%d: %04x (fixed)\n",
ordinal++, *(WORD *)(pstr + 1) );
pstr += 3;
}
}
if (entry->type == 0xff)
DUMP("%d: %02x:%04x (moveable)\n", ordinal++, entry->segnum, entry->offs);
else
DUMP("%d: %02x:%04x (fixed)\n", ordinal++, entry->segnum, entry->offs);
entry++;
}
} while ( (bundle->next)
&& (bundle = ((ET_BUNDLE *)((BYTE *)pModule + bundle->next))) );
/* Dump the non-resident names table */
DUMP( "---\n" );
@ -305,43 +289,29 @@ FARPROC16 NE_GetEntryPoint( HMODULE16 hModule, WORD ordinal )
FARPROC16 NE_GetEntryPointEx( HMODULE16 hModule, WORD ordinal, BOOL16 snoop )
{
NE_MODULE *pModule;
WORD curOrdinal = 1;
BYTE *p;
WORD sel, offset;
WORD sel, offset, i;
ET_ENTRY *entry;
ET_BUNDLE *bundle;
if (!(pModule = NE_GetPtr( hModule ))) return 0;
assert( !(pModule->flags & NE_FFLAGS_WIN32) );
p = (BYTE *)pModule + pModule->entry_table;
while (*p && (curOrdinal + *p <= ordinal))
bundle = (ET_BUNDLE *)((BYTE *)pModule + pModule->entry_table);
while ((ordinal < bundle->first + 1) || (ordinal > bundle->last))
{
/* Skipping this bundle */
curOrdinal += *p;
switch(p[1])
{
case 0: p += 2; break; /* unused */
case 0xff: p += 2 + *p * 6; break; /* moveable */
default: p += 2 + *p * 3; break; /* fixed */
}
}
if (!*p) return 0;
switch(p[1])
{
case 0: /* unused */
if (!(bundle->next))
return 0;
case 0xff: /* moveable */
p += 2 + 6 * (ordinal - curOrdinal);
sel = p[3];
offset = *(WORD *)(p + 4);
break;
default: /* fixed */
sel = p[1];
p += 2 + 3 * (ordinal - curOrdinal);
offset = *(WORD *)(p + 1);
break;
bundle = (ET_BUNDLE *)((BYTE *)pModule + bundle->next);
}
entry = (ET_ENTRY *)((BYTE *)bundle+6);
for (i=0; i < (ordinal - bundle->first - 1); i++)
entry++;
sel = entry->segnum;
offset = entry->offs;
if (sel == 0xfe) sel = 0xffff; /* constant entry */
else sel = GlobalHandleToSel16(NE_SEG_TABLE(pModule)[sel-1].hSeg);
if (sel==0xffff)
@ -362,39 +332,26 @@ FARPROC16 NE_GetEntryPointEx( HMODULE16 hModule, WORD ordinal, BOOL16 snoop )
BOOL16 NE_SetEntryPoint( HMODULE16 hModule, WORD ordinal, WORD offset )
{
NE_MODULE *pModule;
WORD curOrdinal = 1;
BYTE *p;
ET_ENTRY *entry;
ET_BUNDLE *bundle;
int i;
if (!(pModule = NE_GetPtr( hModule ))) return FALSE;
assert( !(pModule->flags & NE_FFLAGS_WIN32) );
p = (BYTE *)pModule + pModule->entry_table;
while (*p && (curOrdinal + *p <= ordinal))
{
/* Skipping this bundle */
curOrdinal += *p;
switch(p[1])
bundle = (ET_BUNDLE *)((BYTE *)pModule + pModule->entry_table);
while ((ordinal < bundle->first + 1) || (ordinal > bundle->last))
{
case 0: p += 2; break; /* unused */
case 0xff: p += 2 + *p * 6; break; /* moveable */
default: p += 2 + *p * 3; break; /* fixed */
}
bundle = (ET_BUNDLE *)((BYTE *)pModule + bundle->next);
if (!(bundle->next))
return 0;
}
if (!*p) return FALSE;
switch(p[1])
{
case 0: /* unused */
return FALSE;
case 0xff: /* moveable */
p += 2 + 6 * (ordinal - curOrdinal);
*(WORD *)(p + 4) = offset;
break;
default: /* fixed */
p += 2 + 3 * (ordinal - curOrdinal);
*(WORD *)(p + 1) = offset;
break;
}
entry = (ET_ENTRY *)((BYTE *)bundle+6);
for (i=0; i < (ordinal - bundle->first - 1); i++)
entry++;
entry->offs = offset;
return TRUE;
}
@ -436,9 +393,11 @@ static HMODULE16 NE_LoadExeHeader( HFILE16 hFile, OFSTRUCT *ofs )
int size;
HMODULE16 hModule;
NE_MODULE *pModule;
BYTE *pData;
BYTE *pData, *pTempEntryTable;
char *buffer, *fastload = NULL;
int fastload_offset = 0, fastload_length = 0;
ET_ENTRY *entry;
ET_BUNDLE *bundle, *oldbundle;
/* Read a block from either the file or the fast-load area. */
#define READ(offset,size,buffer) \
@ -480,6 +439,9 @@ static HMODULE16 NE_LoadExeHeader( HFILE16 hFile, OFSTRUCT *ofs )
ne_header.entry_tab_offset - ne_header.iname_tab_offset +
/* entry table length */
ne_header.entry_tab_length +
/* entry table extra conversion space */
sizeof(ET_BUNDLE) +
2 * (ne_header.entry_tab_length - ne_header.n_mov_entry_points*6) +
/* loaded file info */
sizeof(OFSTRUCT)-sizeof(ofs->szPathName)+strlen(ofs->szPathName)+1;
@ -537,7 +499,8 @@ static HMODULE16 NE_LoadExeHeader( HFILE16 hFile, OFSTRUCT *ofs )
buffer ))
{
HeapFree( SystemHeap, 0, buffer );
if (fastload) HeapFree( SystemHeap, 0, fastload );
if (fastload)
HeapFree( SystemHeap, 0, fastload );
GlobalFree16( hModule );
return (HMODULE16)11; /* invalid exe */
}
@ -551,7 +514,8 @@ static HMODULE16 NE_LoadExeHeader( HFILE16 hFile, OFSTRUCT *ofs )
}
else
{
if (fastload) HeapFree( SystemHeap, 0, fastload );
if (fastload)
HeapFree( SystemHeap, 0, fastload );
GlobalFree16( hModule );
return (HMODULE16)11; /* invalid exe */
}
@ -576,7 +540,8 @@ static HMODULE16 NE_LoadExeHeader( HFILE16 hFile, OFSTRUCT *ofs )
ne_header.moduleref_tab_offset - ne_header.rname_tab_offset,
pData ))
{
if (fastload) HeapFree( SystemHeap, 0, fastload );
if (fastload)
HeapFree( SystemHeap, 0, fastload );
GlobalFree16( hModule );
return (HMODULE16)11; /* invalid exe */
}
@ -591,7 +556,8 @@ static HMODULE16 NE_LoadExeHeader( HFILE16 hFile, OFSTRUCT *ofs )
ne_header.n_mod_ref_tab * sizeof(WORD),
pData ))
{
if (fastload) HeapFree( SystemHeap, 0, fastload );
if (fastload)
HeapFree( SystemHeap, 0, fastload );
GlobalFree16( hModule );
return (HMODULE16)11; /* invalid exe */
}
@ -606,24 +572,101 @@ static HMODULE16 NE_LoadExeHeader( HFILE16 hFile, OFSTRUCT *ofs )
ne_header.entry_tab_offset - ne_header.iname_tab_offset,
pData ))
{
if (fastload) HeapFree( SystemHeap, 0, fastload );
if (fastload)
HeapFree( SystemHeap, 0, fastload );
GlobalFree16( hModule );
return (HMODULE16)11; /* invalid exe */
}
pData += ne_header.entry_tab_offset - ne_header.iname_tab_offset;
/* Get the entry table */
/* Load entry table, convert it to the optimized version used by Windows */
if ((pTempEntryTable = HeapAlloc( SystemHeap, 0, ne_header.entry_tab_length)) != NULL)
{
BYTE nr_entries, type, *s;
TRACE(module, "Converting entry table.\n");
pModule->entry_table = (int)pData - (int)pModule;
if (!READ( mz_header.e_lfanew + ne_header.entry_tab_offset,
ne_header.entry_tab_length,
pData ))
ne_header.entry_tab_length, pTempEntryTable ))
{
if (fastload) HeapFree( SystemHeap, 0, fastload );
HeapFree( SystemHeap, 0, pTempEntryTable );
if (fastload)
HeapFree( SystemHeap, 0, fastload );
GlobalFree16( hModule );
return (HMODULE16)11; /* invalid exe */
}
pData += ne_header.entry_tab_length;
s = pTempEntryTable;
TRACE(module, "entry table: offs %04x, len %04x, entries %d\n", ne_header.entry_tab_offset, ne_header.entry_tab_length, *s);
bundle = (ET_BUNDLE *)pData;
TRACE(module, "first bundle: %p\n", bundle);
memset(bundle, 0, sizeof(ET_BUNDLE)); /* in case no entry table exists */
entry = (ET_ENTRY *)((BYTE *)bundle+6);
while ((nr_entries = *s++))
{
if ((type = *s++))
{
bundle->last += nr_entries;
if (type == 0xff)
while (nr_entries--)
{
entry->type = type;
entry->flags = *s++;
s += 2;
entry->segnum = *s++;
entry->offs = *(WORD *)s; s += 2;
/*TRACE(module, "entry: %p, type: %d, flags: %d, segnum: %d, offs: %04x\n", entry, entry->type, entry->flags, entry->segnum, entry->offs);*/
entry++;
}
else
while (nr_entries--)
{
entry->type = type;
entry->flags = *s++;
entry->segnum = type;
entry->offs = *(WORD *)s; s += 2;
/*TRACE(module, "entry: %p, type: %d, flags: %d, segnum: %d, offs: %04x\n", entry, entry->type, entry->flags, entry->segnum, entry->offs);*/
entry++;
}
}
else
{
if (bundle->first == bundle->last)
{
bundle->first += nr_entries;
bundle->last += nr_entries;
}
else
{
oldbundle = bundle;
oldbundle->next = ((int)entry - (int)pModule);
bundle = (ET_BUNDLE *)entry;
TRACE(module, "new bundle: %p\n", bundle);
bundle->first = bundle->last =
oldbundle->last + nr_entries;
bundle->next = 0;
(BYTE *)entry += sizeof(ET_BUNDLE);
}
}
}
HeapFree( SystemHeap, 0, pTempEntryTable );
}
else
{
if (fastload)
HeapFree( SystemHeap, 0, fastload );
GlobalFree16( hModule );
return (HMODULE16)11; /* invalid exe */
}
pData += ne_header.entry_tab_length + sizeof(ET_BUNDLE) +
2 * (ne_header.entry_tab_length - ne_header.n_mov_entry_points*6);
if ((DWORD)entry > (DWORD)pData)
ERR(module, "converted entry table bigger than reserved space !!!\nentry: %p, pData: %p. Please report !\n", entry, pData);
/* Store the filename information */
@ -636,7 +679,8 @@ static HMODULE16 NE_LoadExeHeader( HFILE16 hFile, OFSTRUCT *ofs )
/* Free the fast-load area */
#undef READ
if (fastload) HeapFree( SystemHeap, 0, fastload );
if (fastload)
HeapFree( SystemHeap, 0, fastload );
/* Get the non-resident names table */
@ -792,7 +836,7 @@ static HINSTANCE16 NE_LoadFileModule( HFILE16 hFile, OFSTRUCT *ofs,
pModule->count = 1;
/* Call initialization rountines for all loaded DLLs. Note that
/* Call initialization routines for all loaded DLLs. Note that
* when we load implicitly linked DLLs this will be done by InitTask().
*/

View File

@ -88,7 +88,7 @@ BOOL NE_LoadSegment( NE_MODULE *pModule, WORD segnum )
mem = GlobalLock16(pSeg->hSeg);
if (pModule->flags & NE_FFLAGS_SELFLOAD && segnum > 1)
{
/* Implement self loading segments */
/* Implement self-loading segments */
SELFLOADHEADER *selfloadheader;
STACK16FRAME *stack16Top;
DWORD oldstack;
@ -396,7 +396,7 @@ BOOL NE_LoadAllSegments( NE_MODULE *pModule )
{
HFILE hf;
HFILE16 hFile16;
/* Handle self loading modules */
/* Handle self-loading modules */
SELFLOADHEADER *selfloadheader;
STACK16FRAME *stack16Top;
THDB *thdb = THREAD_Current();
@ -413,7 +413,7 @@ BOOL NE_LoadAllSegments( NE_MODULE *pModule )
selfloadheader->EntryAddrProc = NE_GetEntryPoint(hselfload,27);
selfloadheader->MyAlloc = NE_GetEntryPoint(hselfload,28);
selfloadheader->SetOwner = NE_GetEntryPoint(GetModuleHandle16("KERNEL"),403);
pModule->self_loading_sel = GlobalHandleToSel16(GLOBAL_Alloc(GMEM_ZEROINIT, 0xFF00, pModule->self, FALSE, FALSE, FALSE));
pModule->self_loading_sel = SEL(GLOBAL_Alloc(GMEM_ZEROINIT, 0xFF00, pModule->self, FALSE, FALSE, FALSE));
oldstack = thdb->cur_stack;
thdb->cur_stack = PTR_SEG_OFF_TO_SEGPTR(pModule->self_loading_sel,
0xff00 - sizeof(*stack16Top) );
@ -452,19 +452,104 @@ BOOL NE_LoadAllSegments( NE_MODULE *pModule )
}
/***********************************************************************
* NE_FixupSegmentPrologs
*
* Fixup exported functions prologs of one segment
*/
void NE_FixupSegmentPrologs(NE_MODULE *pModule, WORD segnum)
{
SEGTABLEENTRY *pSegTable = NE_SEG_TABLE( pModule );
ET_BUNDLE *bundle;
ET_ENTRY *entry;
WORD dgroup, num_entries, sel = SEL(pSegTable[segnum-1].hSeg);
BYTE *pSeg, *pFunc;
TRACE(module, "(%d);\n", segnum);
if (pSegTable[segnum-1].flags & NE_SEGFLAGS_DATA)
{
pSegTable[segnum-1].flags |= NE_SEGFLAGS_LOADED;
return;
}
if (!(dgroup = SEL(pSegTable[pModule->dgroup-1].hSeg)))
return;
pSeg = PTR_SEG_OFF_TO_LIN(sel, 0);
bundle = (ET_BUNDLE *)((BYTE *)pModule+pModule->entry_table);
do {
TRACE(module, "num_entries: %d, bundle: %p, next: %04x, pSeg: %p\n", bundle->last - bundle->first, bundle, bundle->next, pSeg);
if (!(num_entries = bundle->last - bundle->first))
return;
entry = (ET_ENTRY *)((BYTE *)bundle+6);
while (num_entries--)
{
/*TRACE(module, "entry: %p, entry->segnum: %d, entry->offs: %04x\n", entry, entry->segnum, entry->offs);*/
if (entry->segnum == segnum)
{
pFunc = ((BYTE *)pSeg+entry->offs);
TRACE(module, "pFunc: %p, *(DWORD *)pFunc: %08lx, num_entries: %d\n", pFunc, *(DWORD *)pFunc, num_entries);
if (*(pFunc+2) == 0x90)
{
if (*(WORD *)pFunc == 0x581e) /* push ds, pop ax */
{
TRACE(module, "patch %04x:%04x -> mov ax, ds\n", sel, entry->offs);
*(WORD *)pFunc = 0xd88c; /* mov ax, ds */
}
if (*(WORD *)pFunc == 0xd88c)
{
if ((entry->flags & 2)) /* public data ? */
{
TRACE(module, "patch %04x:%04x -> mov ax, dgroup [%04x]\n", sel, entry->offs, dgroup);
*pFunc = 0xb8; /* mov ax, */
*(WORD *)(pFunc+1) = dgroup;
}
else
if ((pModule->flags & NE_FFLAGS_MULTIPLEDATA)
&& (entry->flags & 1)) /* exported ? */
{
TRACE(module, "patch %04x:%04x -> nop, nop\n", sel, entry->offs);
*(WORD *)pFunc = 0x9090; /* nop, nop */
}
}
}
}
entry++;
}
} while ( (bundle->next)
&& (bundle = ((ET_BUNDLE *)((BYTE *)pModule + bundle->next))) );
}
/***********************************************************************
* PatchCodeHandle
*
* Needed for self-loading modules.
*/
/* It does nothing */
DWORD WINAPI PatchCodeHandle16(HANDLE16 hSel)
DWORD WINAPI PatchCodeHandle16(HANDLE16 hSeg)
{
FIXME(module,"(%04x): stub.\n",hSel);
return (DWORD)NULL;
}
WORD segnum;
WORD sel = SEL(hSeg);
NE_MODULE *pModule = NE_GetPtr(FarGetOwner16(sel));
SEGTABLEENTRY *pSegTable = NE_SEG_TABLE(pModule);
TRACE(module, "(%04x);\n", hSeg);
/* find the segment number of the module that belongs to hSeg */
for (segnum = 1; segnum <= pModule->seg_count; segnum++)
{
if (SEL(pSegTable[segnum-1].hSeg) == sel)
{
NE_FixupSegmentPrologs(pModule, segnum);
break;
}
}
return MAKELONG(hSeg, sel);
}
/***********************************************************************
* NE_FixupPrologs
@ -473,91 +558,15 @@ DWORD WINAPI PatchCodeHandle16(HANDLE16 hSel)
*/
void NE_FixupPrologs( NE_MODULE *pModule )
{
SEGTABLEENTRY *pSegTable;
WORD dgroup = 0;
WORD sel;
BYTE *p, *fixup_ptr, count;
dbg_decl_str(module, 512);
pSegTable = NE_SEG_TABLE(pModule);
if (pModule->flags & NE_FFLAGS_SINGLEDATA)
dgroup = SEL(pSegTable[pModule->dgroup-1].hSeg);
WORD segnum;
TRACE(module, "(%04x)\n", pModule->self );
p = (BYTE *)pModule + pModule->entry_table;
while (*p)
{
if (p[1] == 0) /* Unused entry */
{
p += 2; /* Skip it */
continue;
}
if (p[1] == 0xfe) /* Constant entry */
{
p += 2 + *p * 3; /* Skip it */
continue;
}
/* Now fixup the entries of this bundle */
count = *p;
sel = p[1];
p += 2;
while (count-- > 0)
{
dbg_reset_str(module);
dsprintf(module,"Flags: %04x, sel %02x ", *p, sel);
/* According to the output generated by TDUMP, the flags mean:
* 0x0001 function is exported
* 0x0002 Single data (seems to occur only in DLLs)
*/
if (sel == 0xff) { /* moveable */
dsprintf(module, "(%02x) o %04x", p[3], *(WORD *)(p+4) );
fixup_ptr = (char *)GET_SEL_BASE(SEL(pSegTable[p[3]-1].hSeg)) + *(WORD *)(p + 4);
} else { /* fixed */
dsprintf(module, "offset %04x", *(WORD *)(p+1) );
fixup_ptr = (char *)GET_SEL_BASE(SEL(pSegTable[sel-1].hSeg)) +
*(WORD *)(p + 1);
}
TRACE(module, "%s Signature: %02x %02x %02x,ff %x\n",
dbg_str(module), fixup_ptr[0], fixup_ptr[1],
fixup_ptr[2], pModule->flags );
if (*p & 0x0001)
{
/* Verify the signature */
if (((fixup_ptr[0] == 0x1e && fixup_ptr[1] == 0x58)
|| (fixup_ptr[0] == 0x8c && fixup_ptr[1] == 0xd8))
&& fixup_ptr[2] == 0x90)
{
if (*p & 0x0002)
{
if (pModule->flags & NE_FFLAGS_MULTIPLEDATA)
{
/* can this happen? */
ERR(fixup, "FixupPrologs got confused\n" );
}
else if (pModule->flags & NE_FFLAGS_SINGLEDATA)
{
*fixup_ptr = 0xb8; /* MOV AX, */
*(WORD *)(fixup_ptr+1) = dgroup;
}
}
else
{
if (pModule->flags & NE_FFLAGS_MULTIPLEDATA) {
fixup_ptr[0] = 0x90; /* non-library: NOPs */
fixup_ptr[1] = 0x90;
fixup_ptr[2] = 0x90;
}
}
} else {
WARN(fixup, "Unknown signature\n" );
}
}
else
TRACE(module,"\n");
p += (sel == 0xff) ? 6 : 3;
}
}
if (pModule->flags & NE_FFLAGS_SELFLOAD)
NE_FixupSegmentPrologs(pModule, 1);
else
for (segnum=1; segnum <= pModule->seg_count; segnum++)
NE_FixupSegmentPrologs(pModule, segnum);
}
/***********************************************************************
@ -797,23 +806,30 @@ static WORD NE_Ne2MemFlags(WORD flags)
/***********************************************************************
* NE_AllocateSegment (WPROCS.26)
*
* MyAlloc() function for self-loading apps.
*/
DWORD WINAPI NE_AllocateSegment( WORD wFlags, WORD wSize, WORD wElem )
{
WORD size = wSize << wElem;
HANDLE16 hMem = GlobalAlloc16( NE_Ne2MemFlags(wFlags), size);
HANDLE16 hMem = 0;
/* not data == code */
if ( (wFlags & NE_SEGFLAGS_EXECUTEONLY) ||
!(wFlags & NE_SEGFLAGS_DATA)
) {
WORD hSel = GlobalHandleToSel16(hMem);
if (wSize || (wFlags & NE_SEGFLAGS_MOVEABLE))
hMem = GlobalAlloc16( NE_Ne2MemFlags(wFlags), size);
if ( ((wFlags & 0x7) != 0x1) && /* DATA */
((wFlags & 0x7) != 0x7) ) /* DATA|ALLOCATED|LOADED */
{
WORD hSel = SEL(hMem);
WORD access = SelectorAccessRights16(hSel,0,0);
access |= 2<<2; /* SEGMENT_CODE */
SelectorAccessRights16(hSel,1,access);
}
return MAKELONG( hMem, GlobalHandleToSel16(hMem) );
if (size)
return MAKELONG( hMem, SEL(hMem) );
else
return MAKELONG( 0, hMem );
}
@ -823,12 +839,17 @@ DWORD WINAPI NE_AllocateSegment( WORD wFlags, WORD wSize, WORD wElem )
BOOL NE_CreateSegments( NE_MODULE *pModule )
{
SEGTABLEENTRY *pSegment;
int i, minsize;
int i, minsize, seg_count;
assert( !(pModule->flags & NE_FFLAGS_WIN32) );
pSegment = NE_SEG_TABLE( pModule );
for (i = 1; i <= pModule->seg_count; i++, pSegment++)
if (pModule->flags & NE_FFLAGS_SELFLOAD)
seg_count = 1;
else
seg_count = pModule->seg_count;
for (i = 1; i <= seg_count; i++, pSegment++)
{
minsize = pSegment->minsize ? pSegment->minsize : 0x10000;
if (i == pModule->ss) minsize += pModule->stack_size;

View File

@ -796,8 +796,10 @@ static int BuildModule16( FILE *outfile, int max_code_offset,
NE_MODULE *pModule;
SEGTABLEENTRY *pSegment;
OFSTRUCT *pFileInfo;
BYTE *pstr, *bundle;
BYTE *pstr;
WORD *pword;
ET_BUNDLE *bundle = 0;
ET_ENTRY *entry = 0;
/* Module layout:
* NE_MODULE Module
@ -911,7 +913,6 @@ static int BuildModule16( FILE *outfile, int max_code_offset,
/* Entry table */
pModule->entry_table = (int)pstr - (int)pModule;
bundle = NULL;
odp = OrdinalDefinitions + 1;
for (i = 1; i <= Limit; i++, odp++)
{
@ -943,24 +944,25 @@ static int BuildModule16( FILE *outfile, int max_code_offset,
break;
}
/* create a new bundle if necessary */
if (!bundle || (bundle[0] >= 254) || (bundle[1] != selector))
if (!bundle)
{
bundle = pstr;
bundle[0] = 0;
bundle[1] = selector;
pstr += 2;
bundle = (ET_BUNDLE *)pstr;
bundle->first = 0;
pstr += sizeof(ET_BUNDLE);
}
(*bundle)++;
if (selector != 0)
{
*pstr++ = 1;
*(WORD *)pstr = odp->offset;
pstr += sizeof(WORD);
}
/* FIXME: is this really correct ?? */
entry = (ET_ENTRY *)pstr;
entry->type = selector;
entry->flags = 3; /* exported & public data */
entry->segnum = selector;
entry->offs = odp->offset;
pstr += sizeof(ET_ENTRY);
}
*pstr++ = 0;
bundle->last = i;
bundle->next = 0;
/* Dump the module content */