From dca5e56b9054815dd2dcdf20843233f49f6924ea Mon Sep 17 00:00:00 2001 From: Andreas Mohr Date: Fri, 16 Apr 1999 08:17:17 +0000 Subject: [PATCH] - Implemented proper ("real", compressed) Win16 entry tables. - Fixed MyAlloc (AKA NE_AllocateSegment). - Implemented PatchCodeHandle16. --- if1632/builtin.c | 50 +++------ include/module.h | 14 +++ loader/ne/module.c | 242 ++++++++++++++++++++++++++------------------ loader/ne/segment.c | 221 ++++++++++++++++++++++------------------ tools/build.c | 32 +++--- 5 files changed, 310 insertions(+), 249 deletions(-) diff --git a/if1632/builtin.c b/if1632/builtin.c index d5c6444a60b..8cc9fc8ade6 100644 --- a/if1632/builtin.c +++ b/if1632/builtin.c @@ -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) */ diff --git a/include/module.h b/include/module.h index 4ae9d7b612c..ff320b870a3 100644 --- a/include/module.h +++ b/include/module.h @@ -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 { diff --git a/loader/ne/module.c b/loader/ne/module.c index de866c95d59..7856510a67b 100644 --- a/loader/ne/module.c +++ b/loader/ne/module.c @@ -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(). */ diff --git a/loader/ne/segment.c b/loader/ne/segment.c index 89352219509..48585cc9412 100644 --- a/loader/ne/segment.c +++ b/loader/ne/segment.c @@ -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; diff --git a/tools/build.c b/tools/build.c index 31e10896a79..30b1881e280 100644 --- a/tools/build.c +++ b/tools/build.c @@ -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 */