1 /**
2  * @namespace   biew_plugins_auto
3  * @file        plugins/bin/lx.c
4  * @brief       This file contains implementation of LX (Linear eXecutable) file
5  *              format decoder.
6  * @version     -
7  * @remark      this source file is part of Binary vIEW project (BIEW).
8  *              The Binary vIEW (BIEW) is copyright (C) 1995 Nickols_K.
9  *              All rights reserved. This software is redistributable under the
10  *              licence given in the file "Licence.en" ("Licence.ru" in russian
11  *              translation) distributed in the BIEW archive.
12  * @note        Requires POSIX compatible development system
13  *
14  * @author      Nickols_K
15  * @since       1995
16  * @note        Development, fixes and improvements
17 **/
18 #include <limits.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 
23 #include "colorset.h"
24 #include "plugins/disasm.h"
25 #include "plugins/bin/lx_le.h"
26 #include "plugins/bin/ne.h"
27 #include "bin_util.h"
28 #include "bmfile.h"
29 #include "biewhelp.h"
30 #include "tstrings.h"
31 #include "biewutil.h"
32 #include "bconsole.h"
33 #include "reg_form.h"
34 #include "biewlib/kbd_code.h"
35 #include "biewlib/biewlib.h"
36 #include "biewlib/pmalloc.h"
37 
38 union LX_LE lxe;
39 int LXType;
40 
41 BGLOBAL lx_cache = &bNull;
42 
43 static __filesize_t __NEAR__ __FASTCALL__ CalcEntryPointLX(unsigned long objnum,__filesize_t _offset);
44 
45 static const char * LXordering[] =
46 {
47  "little endian",
48  "big endian"
49 };
50 
51 const char * LXcputype[] =
52 {
53  "Unknown",
54  "80286",
55  "80386",
56  "80486",
57  "80586",
58  "80686",
59  "80787",
60  "80887"
61 };
62 
63 const char * LXostype[] =
64 {
65   "Unknown",
66   "OS/2",
67   "Windows",
68   "DOS 4.x",
69   "Windows/386",
70   "Unknown",
71   "Unknown",
72   "Unknown"
73 };
74 
75 const char * __osModType[] =
76 {
77   "PROGRAM",
78   "LIBRARY",
79   "PROT. MODE PROGRAM",
80   "PROT. MODE LIBRARY",
81   "PHYSICAL DEVICE DRIVER",
82   "VIRTUAL DEVICE DRIVER",
83   "PROT. MODE PHYSICAL DEVICE DRIVER",
84   "PROT. MODE VIRTUAL DEVICE DRIVER"
85 };
86 
87 static __filesize_t LXEntryPoint = 0;
88 
GetOrderingLX(unsigned char type)89 static const char * __NEAR__ __FASTCALL__ GetOrderingLX(unsigned char type)
90 {
91  if(type < 2) return LXordering[type];
92  else         return "";
93 }
94 
GetCPUTypeLX(int num)95 static const char * __NEAR__ __FASTCALL__ GetCPUTypeLX(int num)
96 {
97  if(num > 5) num = 0;
98  return LXcputype[num];
99 }
100 
GetOSTypeLX(int num)101 static const char * __NEAR__ __FASTCALL__ GetOSTypeLX(int num)
102 {
103   if(num > 4) num = 0;
104   return LXostype[num];
105 }
106 
__getOSModType(char type)107 static const char * __NEAR__ __FASTCALL__ __getOSModType(char type)
108 {
109   return __osModType[type & 0x07];
110 }
111 
PaintNewHeaderLX_1(void)112 static void __NEAR__ PaintNewHeaderLX_1(void)
113 {
114   twPrintF("Signature                        = '%c%c'\n"
115            "Byte order                       = %02XH (%s)\n"
116            "Word order                       = %02XH (%s)\n"
117            "Format level                     = %08lXH\n"
118            "OS Type                          = %s\n"
119            "CPU Type                         = %s\n"
120            "Module version                   = %hu.%04X\n"
121            "Linear flags :                     [%08lXH]\n"
122            "  Contest DATA in EXE: %s\n"
123            "  [%c] Per-process library initializtion\n"
124            "  [%c] Internal fixups have been applied\n"
125            "  [%c] External fixups have been applied\n"
126            "  %s\n"
127            "  [%c] Module is not loadable (contains errors)\n"
128            "  Module type is : %s\n"
129            "  [%c] Symmetric Multi Processor mode disabled\n"
130            "  [%c] Per-process library termination\n"
131            "Number of pages                  = %08lXH\n"
132            "EIP objects number               = %08lXH\n"
133            "EIP                              = %08lXH\n"
134            "ESP objects number               = %08lXH\n"
135            "ESP                              = %08lXH"
136            ,lxe.lx.lxSignature[0],lxe.lx.lxSignature[1]
137            ,(int)lxe.lx.lxByteOrdering,GetOrderingLX(lxe.lx.lxByteOrdering)
138            ,(int)lxe.lx.lxWordOrdering,GetOrderingLX(lxe.lx.lxWordOrdering)
139            ,lxe.lx.lxFormatLevel
140            ,GetOSTypeLX(lxe.lx.lxOSType)
141            ,GetCPUTypeLX(lxe.lx.lxCPUType)
142            ,(unsigned short)(lxe.lx.lxModuleVersion >> 16),(unsigned)(unsigned short)(lxe.lx.lxModuleVersion)
143            ,lxe.lx.lxModuleFlags
144            ,__nedata[lxe.lx.lxModuleFlags & 0x0000003]
145            ,GetBool((lxe.lx.lxModuleFlags & 0x00000004L) == 0x00000004L)
146            ,GetBool((lxe.lx.lxModuleFlags & 0x00000010L) == 0x00000010L)
147            ,GetBool((lxe.lx.lxModuleFlags & 0x00000020L) == 0x00000020L)
148            ,GetPMWinAPI((unsigned)(lxe.lx.lxModuleFlags))
149            ,GetBool((lxe.lx.lxModuleFlags & 0x00002000L) == 0x00002000L)
150            ,__getOSModType(((lxe.lx.lxModuleFlags & 0x00038000L) >> 15) & 0x07)
151            ,GetBool((lxe.lx.lxModuleFlags & 0x00080000L) == 0x00080000L)
152            ,GetBool((lxe.lx.lxModuleFlags & 0x40000000L) == 0x40000000L)
153            ,lxe.lx.lxPageCount
154            ,lxe.lx.lxEIPObjectNumbers
155            ,lxe.lx.lxEIP
156            ,lxe.lx.lxESPObjectNumbers
157            ,lxe.lx.lxESP);
158 }
159 
PaintNewHeaderLX_2(void)160 static void __NEAR__ PaintNewHeaderLX_2( void )
161 {
162   twPrintF("Page size                        = %08lXH\n"
163            "Page offset shift                = %08lXH\n"
164            "Fixup section size               = %08lXH\n"
165            ,lxe.lx.lxPageSize
166            ,lxe.lx.lxPageOffsetShift
167            ,lxe.lx.lxFixupSectionSize);
168   if(LXType == FILE_LX) twPrintF("Fixup section checksum           = %08lXH\n",lxe.lx.lxFixupSectionChecksum);
169   else                  twPrintF("Page checksum                    = %08lXH\n",lxe.lx.lxFixupSectionChecksum);
170   twPrintF("Loader section size              = %08lXH\n"
171            "Loader section checksum          = %08lXH\n"
172            "Object table offset              = %08lXH\n"
173            "Number of objects in module      = %08lXH\n"
174            "Object page table offset         = %08lXH\n"
175            "Object iter page  offset         = %08lXH\n"
176            "Resource table offset            = %08lXH\n"
177            "Number of resource table entries = %08lXH\n"
178            "Resident name table offset       = %08lXH\n"
179            "Entry table table offset         = %08lXH\n"
180            "Module directives offset         = %08lXH\n"
181            "Number module directives         = %08lXH\n"
182            "Fixup page table offset          = %08lXH\n"
183            "Fixup record table offset        = %08lXH\n"
184            "Import module table offset       = %08lXH\n"
185            "Import module table entries      = %08lXH\n"
186            "Import procedure table offset    = %08lXH"
187            ,lxe.lx.lxLoaderSectionSize
188            ,lxe.lx.lxLoaderSectionChecksum
189            ,lxe.lx.lxObjectTableOffset
190            ,lxe.lx.lxObjectCount
191            ,lxe.lx.lxObjectPageTableOffset
192            ,lxe.lx.lxObjectIterPageOffset
193            ,lxe.lx.lxResourceTableOffset
194            ,lxe.lx.lxNumberResourceTableEntries
195            ,lxe.lx.lxResidentNameTableOffset
196            ,lxe.lx.lxEntryTableOffset
197            ,lxe.lx.lxModuleDirectivesOffset
198            ,lxe.lx.lxNumberModuleDirectives
199            ,lxe.lx.lxFixupPageTableOffset
200            ,lxe.lx.lxFixupRecordTableOffset
201            ,lxe.lx.lxImportModuleTableOffset
202            ,lxe.lx.lxImportModuleTableEntries
203            ,lxe.lx.lxImportProcedureTableOffset);
204 }
205 
PaintNewHeaderLX_3(void)206 static void __NEAR__ PaintNewHeaderLX_3( void )
207 {
208   twPrintF("Per - page checksum  offset      = %08lXH\n"
209            "Data pages offset                = %08lXH\n"
210            "Number of preload pages          = %08lXH\n"
211            "Non resident name table offset   = %08lXH\n"
212            "Non resident name table length   = %08lXH\n"
213            "Non resident name table checksum = %08lXH\n"
214            ,lxe.lx.lxPerPageChecksumOffset
215            ,lxe.lx.lxDataPagesOffset
216            ,lxe.lx.lxNumberPreloadPages
217            ,lxe.lx.lxNonResidentNameTableOffset
218            ,lxe.lx.lxNonResidentNameTableLength
219            ,lxe.lx.lxNonResidentNameTableChecksum);
220   if(LXType == FILE_LX)
221   {
222     twPrintF("Auto DS objects number           = %08lXH\n"
223              "Debug info offset                = %08lXH\n"
224              "Debug info length                = %08lXH\n"
225              "Number instance preload          = %08lXH\n"
226              "Number instance demand           = %08lXH\n"
227              "Heap size                        = %08lXH\n"
228              "Stack size                       = %08lXH\n"
229              ,lxe.lx.lxAutoDSObjectNumber
230              ,lxe.lx.lxDebugInfoOffset
231              ,lxe.lx.lxDebugInfoLength
232              ,lxe.lx.lxNumberInstancePreload
233              ,lxe.lx.lxNumberInstanceDemand
234              ,lxe.lx.lxHeapSize
235              ,lxe.lx.lxStackSize);
236   }
237   else
238   {
239     twPrintF("Debug info offset                = %08lXH\n"
240              "Debug info length                = %08lXH\n"
241              ,lxe.lx.lxAutoDSObjectNumber
242              ,lxe.lx.lxDebugInfoOffset);
243   }
244   twSetColorAttr(dialog_cset.entry);
245   twPrintF(">Entry Point                     = %08lXH",LXEntryPoint);
246   twClrEOL();
247   twSetColorAttr(dialog_cset.main);
248 }
249 
250 static void (__NEAR__ * lxphead[])( void ) =
251 {
252   PaintNewHeaderLX_1,
253   PaintNewHeaderLX_2,
254   PaintNewHeaderLX_3
255 };
256 
PaintNewHeaderLX(TWindow * win,const void ** ptr,unsigned npage,unsigned tpage)257 static void __FASTCALL__ PaintNewHeaderLX(TWindow * win,const void **ptr,unsigned npage,unsigned tpage)
258 {
259   char text[80];
260   UNUSED(ptr);
261   twUseWin(win);
262   twFreezeWin(win);
263   twClearWin();
264   sprintf(text," Linear eXecutable Header [%d/%d] ",npage + 1,tpage);
265   twSetTitleAttr(win,text,TW_TMODE_CENTER,dialog_cset.title);
266   twSetFooterAttr(win,PAGEBOX_SUB,TW_TMODE_RIGHT,dialog_cset.selfooter);
267   if(npage < 3)
268   {
269     twGotoXY(1,1);
270     (*(lxphead[npage]))();
271   }
272   twRefreshFullWin(win);
273 }
274 
ShowNewHeaderLX(void)275 __filesize_t __FASTCALL__ ShowNewHeaderLX( void )
276 {
277   __filesize_t fpos;
278   LXEntryPoint = LXType == FILE_LX ? CalcEntryPointLX(lxe.lx.lxEIPObjectNumbers,lxe.lx.lxEIP) : CalcEntryPointLE(lxe.lx.lxEIPObjectNumbers,lxe.lx.lxEIP);
279   if(LXEntryPoint == FILESIZE_MAX) LXEntryPoint = 0;
280   fpos = BMGetCurrFilePos();
281   if(PageBox(70,21,NULL,3,PaintNewHeaderLX) != -1)
282   {
283     if(LXEntryPoint) fpos = LXEntryPoint;
284   }
285   return fpos;
286 }
287 
LXModRefNumItems(BGLOBAL handle)288 static unsigned __FASTCALL__ LXModRefNumItems(BGLOBAL handle)
289 {
290   UNUSED(handle);
291   return (unsigned)lxe.lx.lxImportModuleTableEntries;
292 }
293 
LXRNamesNumItems(BGLOBAL handle)294 unsigned __FASTCALL__ LXRNamesNumItems(BGLOBAL handle)
295 {
296   return GetNamCountNE(handle,headshift + lxe.lx.lxResidentNameTableOffset);
297 }
298 
LXNRNamesNumItems(BGLOBAL handle)299 unsigned __FASTCALL__ LXNRNamesNumItems(BGLOBAL handle)
300 {
301   return GetNamCountNE(handle,lxe.lx.lxNonResidentNameTableOffset);
302 }
303 
LXRNamesReadItems(BGLOBAL handle,memArray * obj,unsigned nnames)304 tBool __FASTCALL__ LXRNamesReadItems(BGLOBAL handle,memArray * obj,unsigned nnames)
305 {
306    return RNamesReadItems(handle,obj,nnames,lxe.lx.lxResidentNameTableOffset + headshift);
307 }
308 
LXImpNamesNumItems(BGLOBAL handle)309 static unsigned __FASTCALL__ LXImpNamesNumItems(BGLOBAL handle)
310 {
311   __filesize_t fpos;
312   unsigned char len;
313   unsigned count;
314   bioSeek(handle,lxe.lx.lxImportProcedureTableOffset + headshift,SEEKF_START);
315   fpos = bioTell(handle);
316   count = 0;
317   while(fpos < lxe.lx.lxFixupSectionSize + lxe.lx.lxFixupPageTableOffset + headshift)
318   {
319     len = bioReadByte(handle);
320     bioSeek(handle,len,SEEKF_CUR);
321     fpos = bioTell(handle);
322     if(bioEOF(handle)) break;
323     count++;
324   }
325   return count;
326 }
327 
LXImpNamesReadItems(BGLOBAL handle,memArray * obj,unsigned nnames)328 static tBool __FASTCALL__ LXImpNamesReadItems(BGLOBAL handle,memArray * obj,unsigned nnames)
329 {
330  unsigned i;
331  unsigned char byte;
332  bioSeek(handle,lxe.lx.lxImportProcedureTableOffset + headshift,SEEKF_START);
333  for(i = 0;i < nnames;i++)
334  {
335    char nam[256];
336    byte = bioReadByte(handle);
337    if(IsKbdTerminate() || bioEOF(handle)) break;
338    bioReadBuffer(handle,nam,byte);
339    nam[byte] = 0;
340    if(!ma_AddString(obj,nam,True)) break;
341  }
342  return True;
343 }
344 
345 
LXNRNamesReadItems(BGLOBAL handle,memArray * obj,unsigned nnames)346 tBool __FASTCALL__ LXNRNamesReadItems(BGLOBAL handle,memArray * obj,unsigned nnames)
347 {
348    return RNamesReadItems(handle,obj,nnames,lxe.lx.lxNonResidentNameTableOffset);
349 }
350 
351 #if 0
352 extern unsigned __FASTCALL__ RNameReadFull(BGLOBAL handle,char * names,unsigned nindex,__filesize_t _offset);
353 static unsigned __FASTCALL__ LXRNamesReadFullName(BGLOBAL handle,char * names,unsigned index)
354 {
355    return RNameReadFull(handle,names,index,lxe.lx.lxResidentNameTableOffset + headshift);
356 }
357 
358 static unsigned __FASTCALL__ LXNRNamesReadFullName(BGLOBAL handle,char * names,unsigned index)
359 {
360    return RNameReadFull(handle,names,index,lxe.lx.lxNonResidentNameTableOffset);
361 }
362 #endif
__ReadModRefNamesLX(BGLOBAL handle,memArray * obj,unsigned nnames)363 static tBool __FASTCALL__  __ReadModRefNamesLX(BGLOBAL handle,memArray * obj,unsigned nnames)
364 {
365  unsigned i;
366  unsigned char byte;
367  bioSeek(handle,lxe.lx.lxImportModuleTableOffset + headshift,SEEKF_START);
368  for(i = 0;i < nnames;i++)
369  {
370    char nam[256];
371    byte = bioReadByte(handle);
372    if(IsKbdTerminate() || bioEOF(handle)) break;
373    bioReadBuffer(handle,nam,byte);
374    nam[byte] = 0;
375    if(!ma_AddString(obj,nam,True)) break;
376  }
377  return True;
378 }
379 
objpaintLX(const LX_OBJECT * nam)380 static void __NEAR__ __FASTCALL__ objpaintLX(const LX_OBJECT *nam)
381 {
382  twGotoXY(1,1);
383  twPrintF("Virtual Size                         = %lX bytes\n"
384           "BVA (base virtual address)           = %08lX\n"
385           "FLAGS: %lX\n"
386           "   [%c] Readable object\n"
387           "   [%c] Writable object\n"
388           "   [%c] Executable object\n"
389           "   [%c] Resource object\n"
390           "   [%c] Object is discardable\n"
391           "   [%c] Object is shared\n"
392           "   [%c] Object has preload pages\n"
393           "   [%c] Object has invalid pages\n"
394           "   [%c] Object is permanent and swappable\n"
395           "   [%c] Object is permanent and resident\n"
396           "   [%c] Object is permanent and long lockable\n"
397           "   [%c] 16:16 alias required (80x86 specific)\n"
398           "   [%c] Big/Default bit setting (80x86 specific)\n"
399           "   [%c] Object is conforming for code (80x86 specific)\n"
400           "   [%c] Object I/O privilege level (80x86 specific)\n"
401           "   [%c] Object is loadable to High Memory (>512MiB)\n"
402           "Object page map index                = %lu\n"
403           "Number of entries in object page map = %lu"
404           ,nam->o32_size
405           ,nam->o32_base
406           ,nam->o32_flags
407           ,GetBool((nam->o32_flags & 0x00000001L) == 0x00000001L)
408           ,GetBool((nam->o32_flags & 0x00000002L) == 0x00000002L)
409           ,GetBool((nam->o32_flags & 0x00000004L) == 0x00000004L)
410           ,GetBool((nam->o32_flags & 0x00000008L) == 0x00000008L)
411           ,GetBool((nam->o32_flags & 0x00000010L) == 0x00000010L)
412           ,GetBool((nam->o32_flags & 0x00000020L) == 0x00000020L)
413           ,GetBool((nam->o32_flags & 0x00000040L) == 0x00000040L)
414           ,GetBool((nam->o32_flags & 0x00000080L) == 0x00000080L)
415           ,GetBool((nam->o32_flags & 0x00000100L) == 0x00000100L)
416           ,GetBool((nam->o32_flags & 0x00000200L) == 0x00000200L)
417           ,GetBool((nam->o32_flags & 0x00000400L) == 0x00000400L)
418           ,GetBool((nam->o32_flags & 0x00001000L) == 0x00001000L)
419           ,GetBool((nam->o32_flags & 0x00002000L) == 0x00002000L)
420           ,GetBool((nam->o32_flags & 0x00004000L) == 0x00004000L)
421           ,GetBool((nam->o32_flags & 0x00008000L) == 0x00008000L)
422           ,GetBool((nam->o32_flags & 0x00010000L) == 0x00010000L)
423           ,nam->o32_pagemap
424           ,nam->o32_mapsize);
425 }
426 
ObjPaintLX(TWindow * win,const void ** names,unsigned start,unsigned nlist)427 static void __FASTCALL__ ObjPaintLX(TWindow * win,const void ** names,unsigned start,unsigned nlist)
428 {
429  char buffer[81];
430  const LX_OBJECT ** nam = (const LX_OBJECT **)names;
431  twUseWin(win);
432  twFreezeWin(win);
433  twClearWin();
434  sprintf(buffer," Object Table [ %u / %u ] ",start + 1,nlist);
435  twSetTitleAttr(win,buffer,TW_TMODE_CENTER,dialog_cset.title);
436  twSetFooterAttr(win,PAGEBOX_SUB,TW_TMODE_RIGHT,dialog_cset.selfooter);
437  objpaintLX(nam[start]);
438  twRefreshFullWin(win);
439 }
440 
__ReadObjectsLX(BGLOBAL handle,memArray * obj,unsigned n)441 static tBool __NEAR__ __FASTCALL__ __ReadObjectsLX(BGLOBAL handle,memArray * obj,unsigned n)
442 {
443  size_t i;
444   for(i = 0;i < n;i++)
445   {
446     LX_OBJECT lxo;
447     if(IsKbdTerminate() || bioEOF(handle)) break;
448     bioReadBuffer(handle,&lxo,sizeof(LX_OBJECT));
449     if(!ma_AddData(obj,&lxo,sizeof(LX_OBJECT),True)) break;
450   }
451   return True;
452 }
453 
__ReadEntriesLX(BGLOBAL handle,memArray * obj)454 static tBool __NEAR__ __FASTCALL__ __ReadEntriesLX(BGLOBAL handle,memArray *obj)
455 {
456  unsigned i;
457  unsigned char j;
458  unsigned char cnt,type;
459  tUIntFast16 numobj = 0;
460  LX_ENTRY _lxe;
461  i = 0;
462  while(1)
463  {
464    tBool is_eof;
465    is_eof = False;
466    cnt = bioReadByte(handle);
467    type = bioReadByte(handle);
468    if(!cnt) break;
469    if(type) numobj = bioReadWord(handle);
470    for(j = 0;j < cnt;j++,i++)
471    {
472      char size;
473      switch(type)
474      {
475        case 0: size = 0; break;
476        case 1: size = 2; break;
477        case 2:
478        case 0x80:
479        case 3: size = 4; break;
480        default:
481        case 4: size = 6; break;
482      }
483      is_eof = bioEOF(handle);
484      if(IsKbdTerminate() || is_eof) goto exit;
485      _lxe.b32_type = type;
486      if(size)
487      {
488        _lxe.b32_obj = numobj;
489        _lxe.entry.e32_flags = bioReadByte(handle);
490        bioReadBuffer(handle,&_lxe.entry.e32_variant,size);
491      }
492      if(!ma_AddData(obj,&_lxe,sizeof(LX_ENTRY),True)) goto exit;
493    }
494    if(is_eof) break;
495  }
496  exit:
497  return True;
498 }
499 
lxReadPageDesc(BGLOBAL handle,LX_MAP_TABLE * mt,unsigned long pageidx)500 static void __FASTCALL__ lxReadPageDesc(BGLOBAL handle,LX_MAP_TABLE *mt,unsigned long pageidx)
501 {
502   bioSeek(handle,headshift+lxe.lx.lxObjectPageTableOffset+
503           sizeof(LX_MAP_TABLE)*(pageidx - 1),SEEK_SET);
504   bioReadBuffer(handle,(void *)mt,sizeof(LX_MAP_TABLE));
505 }
506 
__calcPageEntry(LX_MAP_TABLE * mt)507 static __filesize_t __NEAR__ __FASTCALL__ __calcPageEntry(LX_MAP_TABLE *mt)
508 {
509   __filesize_t dataoff;
510   __filesize_t ret;
511   dataoff = mt->o32_pagedataoffset << lxe.lx.lxPageOffsetShift;
512   switch(mt->o32_pageflags)
513   {
514     default:
515     case PAGE_VALID: ret = lxe.lx.lxDataPagesOffset;
516                      break;
517     case PAGE_ITERDATA2: /* This is very undocumented type.
518                             I do not know - how handle it !!!*/
519     case PAGE_ITERDATA: ret = lxe.lx.lxObjectIterPageOffset;
520                         break;
521     case PAGE_RANGE:
522     case PAGE_INVALID:
523     case PAGE_ZEROED:  ret = 0; break;
524   }
525   return ret + dataoff;
526 }
527 
CalcPageEntry(unsigned long pageidx)528 static __filesize_t __NEAR__ __FASTCALL__ CalcPageEntry(unsigned long pageidx)
529 {
530   BGLOBAL handle;
531   LX_MAP_TABLE mt;
532   if(!pageidx) return -1;
533   handle = lx_cache;
534   lxReadPageDesc(handle,&mt,pageidx);
535   return __calcPageEntry((void *)&mt);
536 }
537 
CalcEntryPointLX(unsigned long objnum,__filesize_t _offset)538 static __filesize_t __NEAR__ __FASTCALL__ CalcEntryPointLX(unsigned long objnum,__filesize_t _offset)
539 {
540   BGLOBAL handle;
541   unsigned long i,diff;
542   LX_OBJECT lo;
543   LX_MAP_TABLE mt;
544   if(!objnum) return BMGetCurrFilePos();
545   handle = lx_cache;
546   bioSeek(handle,lxe.lx.lxObjectTableOffset + headshift,SEEK_SET);
547   bioSeek(handle,sizeof(LX_OBJECT)*(objnum - 1),SEEKF_CUR);
548   bioReadBuffer(handle,(void *)&lo,sizeof(LX_OBJECT));
549   i = _offset / lxe.lx.lxPageSize;
550   diff = _offset - i*lxe.lx.lxPageSize;
551   lxReadPageDesc(handle,&mt,i+lo.o32_pagemap);
552   return __calcPageEntry((void *)&mt) + diff;
553 }
554 
ReadLXLEImpMod(__filesize_t offtable,unsigned num,char * str)555 static void __FASTCALL__ ReadLXLEImpMod(__filesize_t offtable,unsigned num,char *str)
556 {
557   BGLOBAL handle;
558   unsigned i;
559   unsigned char len;
560   char buff[256];
561   handle = lx_cache;
562   bioSeek(handle,offtable,SEEK_SET);
563   for(i = 1;i < num;i++)
564   {
565     len = bioReadByte(handle);
566     bioSeek(handle,len,SEEKF_CUR);
567   }
568   len = bioReadByte(handle);
569   bioReadBuffer(handle,(void *)buff,len);
570   buff[len] = 0;
571   strcat(str,buff);
572 }
573 
ReadLXLEImpName(__filesize_t offtable,unsigned num,char * str)574 static void __FASTCALL__ ReadLXLEImpName(__filesize_t offtable,unsigned num,char *str)
575 {
576   BGLOBAL handle;
577   unsigned char len;
578   char buff[256];
579   handle = lx_cache;
580   bioSeek(handle,offtable+num,SEEK_SET);
581   len = bioReadByte(handle);
582   bioReadBuffer(handle,(void *)buff,len);
583   buff[len] = 0;
584   strcat(str,buff);
585 }
586 
ShowFwdModOrdLX(const LX_ENTRY * lxent)587 void __FASTCALL__ ShowFwdModOrdLX(const LX_ENTRY *lxent)
588 {
589   char buff[513];
590   buff[0] = 0;
591   ReadLXLEImpMod(lxe.lx.lxImportModuleTableOffset + headshift,lxent->entry.e32_variant.e32_fwd.modord,buff);
592   strcat(buff,".");
593   if((lxent->entry.e32_flags & 0x01) == 0x01)
594   {
595     sprintf(&buff[strlen(buff)],"@%u",(unsigned)lxent->entry.e32_variant.e32_fwd.value);
596   }
597   else ReadLXLEImpName(lxe.lx.lxImportProcedureTableOffset + headshift,(unsigned)lxent->entry.e32_variant.e32_fwd.value,buff);
598   TMessageBox(buff," Forwarder entry point ");
599 }
600 
CalcEntryLX(const LX_ENTRY * lxent)601 static __filesize_t __NEAR__ __FASTCALL__ CalcEntryLX(const LX_ENTRY *lxent)
602 {
603   __filesize_t ret;
604   ret = BMGetCurrFilePos();
605       switch(lxent->b32_type)
606       {
607         case 1: ret = CalcEntryPointLX(lxent->b32_obj,lxent->entry.e32_variant.e32_offset.offset16);
608                       break;
609         case 2: ret = CalcEntryPointLX(lxent->b32_obj,lxent->entry.e32_variant.e32_callgate.offset);
610                       break;
611         case 3: ret = CalcEntryPointLX(lxent->b32_obj,lxent->entry.e32_variant.e32_offset.offset32);
612                       break;
613         case 4: ShowFwdModOrdLX(lxent);
614         case 5:
615         default: break;
616       }
617   return ret;
618 }
619 
CalcEntryBungleLX(unsigned ordinal,tBool dispmsg)620 static __filesize_t __NEAR__ __FASTCALL__ CalcEntryBungleLX(unsigned ordinal,tBool dispmsg)
621 {
622   BGLOBAL handle;
623   tBool found;
624   unsigned i;
625   unsigned char j;
626   unsigned char cnt,type;
627   tUIntFast16 numobj = 0;
628   LX_ENTRY lxent;
629   __filesize_t ret;
630   ret = BMGetCurrFilePos();
631   handle = lx_cache;
632   bioSeek(handle,lxe.lx.lxEntryTableOffset + headshift,SEEK_SET);
633   i = 0;
634   found = False;
635   while(1)
636   {
637    tBool is_eof;
638    is_eof = False;
639    cnt = bioReadByte(handle);
640    type = bioReadByte(handle);
641    if(!cnt) break;
642    if(type) numobj = bioReadWord(handle);
643    if(bioEOF(handle)) break;
644    for(j = 0;j < cnt;j++,i++)
645    {
646      char size;
647      switch(type)
648      {
649        case 0: size = 0; break;
650        case 1: size = 2; break;
651        case 2:
652        case 0x80:
653        case 3: size = 4; break;
654        default:
655        case 4: size = 6; break;
656      }
657      if(i == ordinal - 1)
658      {
659        lxent.b32_type = type;
660        found = True;
661        if(size)
662        {
663          lxent.b32_obj = numobj;
664          lxent.entry.e32_flags = bioReadByte(handle);
665          bioReadBuffer(handle,(void *)&lxent.entry.e32_variant,size);
666          is_eof = bioEOF(handle);
667        }
668        break;
669      }
670      else
671        if(size) bioSeek(handle,size + sizeof(char),SEEKF_CUR);
672      if(is_eof) break;
673    }
674    if(found || is_eof) break;
675  }
676  if(found) ret = CalcEntryLX((LX_ENTRY *)&lxent);
677  else      if(dispmsg) ErrMessageBox(NOT_ENTRY,NULL);
678  return ret;
679 }
680 
ShowObjectsLX(void)681 __filesize_t __FASTCALL__ ShowObjectsLX( void )
682 {
683  BGLOBAL handle;
684  __filesize_t fpos;
685  unsigned nnames;
686  memArray * obj;
687  fpos = BMGetCurrFilePos();
688  nnames = (unsigned)lxe.lx.lxObjectCount;
689  if(!nnames) { NotifyBox(NOT_ENTRY," Objects Table "); return fpos; }
690  if(!(obj = ma_Build(nnames,True))) return fpos;
691  handle = lx_cache;
692  bioSeek(handle,lxe.lx.lxObjectTableOffset + headshift,SEEK_SET);
693  if(__ReadObjectsLX(handle,obj,nnames))
694  {
695   int ret;
696     ret = PageBox(70,20,(const void **)obj->data,obj->nItems,ObjPaintLX);
697     if(ret != -1)  fpos = LXType == FILE_LX ? CalcPageEntry(((LX_OBJECT *)obj->data[ret])->o32_pagemap) : CalcPageEntryLE(((const LX_OBJECT *)obj->data[ret])->o32_pagemap);
698  }
699  ma_Destroy(obj);
700  return fpos;
701 }
702 
703 const char * mapattr[] =
704 {
705 "Valid Physical Page In .EXE",
706 "Iterated Data Page",
707 "Invalid Page",
708 "Zero Filled Page",
709 "Range Of Pages",
710 "Iterated Data Page Type II"
711 };
712 
lxeGetMapAttr(unsigned long attr)713 const char * __FASTCALL__ lxeGetMapAttr(unsigned long attr)
714 {
715   if (attr > 5) return "Unknown";
716   else  return mapattr[attr];
717 }
718 #if 0
719 static void __NEAR__ __FASTCALL__ iterpaintLX(const LX_ITER *nam)
720 {
721  twGotoXY(1,1);
722  twPrintF("Number of iteration                  = %hu\n"
723           "Number of bytes                      = %hu\n"
724           "Iterated data bytes                  = %hu"
725           ,nam->LX_nIter
726           ,nam->LX_nBytes
727           ,(int)nam->LX_Iterdata);
728 }
729 #endif
730 const char *__e32type[] =
731 {
732   "Empty",
733   "Entry16",
734   "Gate16",
735   "Entry32",
736   "EntryForwarder",
737   "TypeInfo"
738 };
739 
entryTypeLX(unsigned char type)740 static const char * __NEAR__ __FASTCALL__ entryTypeLX(unsigned char type)
741 {
742    if(type < 6) return __e32type[type];
743    else         return "Unknown";
744 }
745 
entrypaintLX(const LX_ENTRY * nam)746 static void __NEAR__ __FASTCALL__ entrypaintLX(const LX_ENTRY *nam)
747 {
748  if(!nam->b32_type)
749  {
750    twGotoXY(35,4);
751    twPrintF("Unused");
752  }
753  else
754  {
755    twGotoXY(1,1);
756    twPrintF("Entry type: %s\n"
757             "Object number : %hd\n"
758             "Flags: %02XH\n"
759             ,entryTypeLX(nam->b32_type)
760             ,nam->b32_obj
761             ,(int)nam->entry.e32_flags);
762    if(nam->b32_type != 4)
763    {
764      twPrintF("   [%c] Exported Entry\n"
765               "   [%c] Used Shared Data\n"
766               "   %02XH - parameter word count mask\n"
767               ,GetBool((nam->entry.e32_flags & 0x01) == 0x01)
768               ,GetBool((nam->entry.e32_flags & 0x02) == 0x02)
769               ,(int)(nam->entry.e32_flags >> 2));
770    }
771    else
772    {
773      twPrintF("\n"
774               "   [%c] Import by ordinal\n"
775               "\n"
776               ,GetBool((nam->entry.e32_flags & 0x01) == 0x01));
777    }
778    if(nam->b32_type == 1)
779    {
780      twPrintF("Entry offset : %04hXH\n"
781               "\n"
782               ,nam->entry.e32_variant.e32_offset.offset16);
783    }
784    else
785       if(nam->b32_type == 3)
786       {
787         twPrintF("Entry offset : %08XH\n"
788                  "\n"
789                  ,nam->entry.e32_variant.e32_offset.offset32);
790       }
791       else
792       if(nam->b32_type == 2)
793       {
794        twPrintF("Callgate offset : %04hXH\n"
795                 "Callgate selector : %04hXH\n"
796                 ,nam->entry.e32_variant.e32_callgate.offset
797                 ,nam->entry.e32_variant.e32_callgate.callgate);
798       }
799       else
800        if(nam->b32_type == 4)
801        {
802          twPrintF("Module ordinal number : %04hXH\n"
803                   "Proc name offset or ordinal : %04hXH\n"
804                   ,nam->entry.e32_variant.e32_fwd.modord
805                   ,nam->entry.e32_variant.e32_fwd.value);
806        }
807    }
808 }
809 #if 0
810 static void __FASTCALL__ IterPaintLX(TWindow * win,const void ** names,unsigned start,unsigned nlist)
811 {
812  char buffer[81];
813  const LX_ITER ** nam = (const LX_ITER **)names;
814  twUseWin(win);
815  twFreezeWin(win);
816  twClearWin();
817  sprintf(buffer," Iter Table [ %u / %u ] ",start + 1,nlist);
818  twSetTitleAttr(win,buffer,TW_TMODE_CENTER,dialog_cset.title);
819  iterpaintLX(nam[start]);
820  twRefreshFullWin(win);
821 }
822 #endif
PaintEntriesLX(TWindow * win,const void ** names,unsigned start,unsigned nlist)823 static void __FASTCALL__ PaintEntriesLX(TWindow * win,const void ** names,unsigned start,unsigned nlist)
824 {
825  char buffer[81];
826  const LX_ENTRY ** nam = (const LX_ENTRY **)names;
827  twUseWin(win);
828  twFreezeWin(win);
829  twClearWin();
830  sprintf(buffer," Entries Table [ %u / %u ] ",start + 1,nlist);
831  twSetTitleAttr(win,buffer,TW_TMODE_CENTER,dialog_cset.title);
832  twSetFooterAttr(win,PAGEBOX_SUB,TW_TMODE_RIGHT,dialog_cset.selfooter);
833  entrypaintLX(nam[start]);
834  twRefreshFullWin(win);
835 }
836 
__ReadMapTblLX(BGLOBAL handle,memArray * obj,unsigned n)837 static tBool __FASTCALL__ __ReadMapTblLX(BGLOBAL handle,memArray * obj,unsigned n)
838 {
839   size_t i;
840   for(i = 0;i < n;i++)
841   {
842     LX_MAP_TABLE mt;
843     char stmp[80];
844     if(IsKbdTerminate() || bioEOF(handle)) break;
845     lxReadPageDesc(handle,&mt,i+1);
846     sprintf(stmp,"Off=%08lXH Siz=%04hXH Flg:%04hXH=%s",
847                  (unsigned long)mt.o32_pagedataoffset,
848                  mt.o32_pagesize,
849                  mt.o32_pageflags,
850                  (const char *)lxeGetMapAttr(mt.o32_pageflags));
851     if(!ma_AddString(obj,(const char *)stmp,True)) break;
852   }
853   return True;
854 }
855 #if 0
856 static tBool __NEAR__ __FASTCALL__ __ReadIterTblLX(BGLOBAL handle,memArray * obj,unsigned n)
857 {
858  int i;
859   for(i = 0;i < n;i++)
860   {
861     LX_ITER lxi;
862     if(IsKbdTerminate() || bioEOF(handle)) break;
863     bioReadBuffer(handle,&lxi,sizeof(LX_ITER));
864     if(!ma_AddData(obj,&lxi,sizeof(LX_ITER),True)) break;
865   }
866   return True;
867 }
868 #endif
lxGetPageCount(BGLOBAL handle)869 static unsigned __FASTCALL__ lxGetPageCount(BGLOBAL handle)
870 {
871   UNUSED(handle);
872   return (unsigned)lxe.lx.lxPageCount;
873 }
874 
ShowMapTableLX(void)875 static __filesize_t __FASTCALL__ ShowMapTableLX( void )
876 {
877  __filesize_t fpos;
878  int ret;
879  fpos = BMGetCurrFilePos();
880  ret = fmtShowList(lxGetPageCount,__ReadMapTblLX," Map of pages ",
881                    LB_SELECTIVE,NULL);
882  if(ret != -1)
883  {
884    fpos = CalcPageEntry(ret + 1);
885  }
886  return fpos;
887 }
888 
ShowEntriesLX(void)889 __filesize_t __FASTCALL__ ShowEntriesLX( void )
890 {
891  BGLOBAL handle;
892  __filesize_t fpos;
893  memArray * obj;
894  fpos = BMGetCurrFilePos();
895  if(!lxe.lx.lxEntryTableOffset) { NotifyBox(NOT_ENTRY," Entry Table "); return fpos; }
896  handle = lx_cache;
897  bioSeek(handle,lxe.lx.lxEntryTableOffset + headshift,SEEK_SET);
898  if(!(obj = ma_Build(0,True))) goto exit;
899  if(__ReadEntriesLX(handle,obj))
900  {
901     int ret;
902     if(!obj->nItems) { NotifyBox(NOT_ENTRY," Entry Table "); goto bye; }
903     ret = PageBox(70,8,(const void **)obj->data,obj->nItems,PaintEntriesLX);
904     if(ret != -1)  fpos = LXType == FILE_LX ? CalcEntryLX(obj->data[ret]) : CalcEntryLE(obj->data[ret]);
905  }
906  bye:
907  ma_Destroy(obj);
908  exit:
909  return fpos;
910 }
911 
912 const char * ResourceGrNamesLX[] =
913 {
914   "RESERVED 0",
915   "Mouse pointer share",
916   "BITMAP",
917   "MENU",
918   "DIALOG",
919   "STRINGTABLE",
920   "FONTDIR",
921   "FONT",
922   "ACCELTABLE",
923   "RCDATA",
924   "Err msg table",
925   "DlgInclude",
926   "VKey table",
927   "Key to UGL table",
928   "Glyph to char table",
929   "Display info",
930   "FKA short",
931   "FKA long",
932   "Help table",
933   "Help subtable",
934   "DBCS font drive dir",
935   "DBCS font drive"
936 };
937 
__ReadResourceGroupLX(BGLOBAL handle,memArray * obj,unsigned nitems,long * addr)938 static tBool __NEAR__ __FASTCALL__ __ReadResourceGroupLX(BGLOBAL handle,memArray *obj,unsigned nitems,long * addr)
939 {
940  unsigned i;
941  LXResource lxr;
942  for(i = 0;i < nitems;i++)
943  {
944     char stmp[81];
945     bioReadBuffer(handle,&lxr,sizeof(LXResource));
946     addr[i] = lxr.offset;
947     if(IsKbdTerminate() || bioEOF(handle)) break;
948     sprintf(stmp,"%6hu = ",lxr.nameID);
949     if(lxr.typeID < sizeof(ResourceGrNamesLX)/sizeof(char *)) strcat(stmp,ResourceGrNamesLX[lxr.typeID]);
950     else  sprintf(&stmp[strlen(stmp)],"Unknown < %04hXH >",lxr.typeID);
951     sprintf(&stmp[strlen(stmp)]," obj=%04hXH.%08lXH"
952                                ,lxr.object
953                                ,(unsigned long)lxr.offset);
954     if(!ma_AddString(obj,stmp,True)) break;
955  }
956  return True;
957 }
958 
ShowResourceLX(void)959 static __filesize_t __FASTCALL__ ShowResourceLX( void )
960 {
961  __filesize_t fpos;
962  BGLOBAL handle;
963  memArray * obj;
964  long * raddr;
965  unsigned nrgroup;
966  fpos = BMGetCurrFilePos();
967  handle = lx_cache;
968  bioSeek(handle,(__fileoff_t)headshift + lxe.lx.lxResourceTableOffset,SEEK_SET);
969  nrgroup = (unsigned)lxe.lx.lxNumberResourceTableEntries;
970  if(!nrgroup) { NotifyBox(NOT_ENTRY," Resources "); return fpos; }
971  if(!(obj = ma_Build(nrgroup,True))) goto exit;
972  if(!(raddr  = PMalloc(nrgroup*sizeof(long)))) return fpos;
973  if(__ReadResourceGroupLX(handle,obj,nrgroup,raddr))
974  {
975    ma_Display(obj," Resource groups : ",LB_SORTABLE,-1);
976  }
977  ma_Destroy(obj);
978  free(raddr);
979  exit:
980  return fpos;
981 }
982 
ShowModRefLX(void)983 __filesize_t __FASTCALL__ ShowModRefLX( void )
984 {
985   fmtShowList(LXModRefNumItems,
986               __ReadModRefNamesLX,
987               MOD_REFER,
988               LB_SORTABLE,
989               NULL);
990   return BMGetCurrFilePos();
991 }
992 
ShowResNamLX(void)993 static __filesize_t __FASTCALL__ ShowResNamLX( void )
994 {
995   __filesize_t fpos = BMGetCurrFilePos();
996   int ret;
997   unsigned ordinal;
998   ret = fmtShowList(LXRNamesNumItems,LXRNamesReadItems,
999                     RES_NAMES,
1000                     LB_SELECTIVE | LB_SORTABLE,&ordinal);
1001   if(ret != -1)
1002   {
1003     fpos = CalcEntryBungleLX(ordinal,True);
1004   }
1005   return fpos;
1006 }
1007 
ShowNResNmLX(void)1008 static __filesize_t __FASTCALL__ ShowNResNmLX( void )
1009 {
1010   __filesize_t fpos;
1011   fpos = BMGetCurrFilePos();
1012   {
1013     int ret;
1014     unsigned ordinal;
1015     ret = fmtShowList(LXNRNamesNumItems,LXNRNamesReadItems,
1016                       NORES_NAMES,
1017                       LB_SELECTIVE | LB_SORTABLE,&ordinal);
1018     if(ret != -1)
1019     {
1020       fpos = CalcEntryBungleLX(ordinal,True);
1021     }
1022   }
1023   return fpos;
1024 }
1025 
ShowImpProcLXLE(void)1026 __filesize_t __FASTCALL__ ShowImpProcLXLE( void )
1027 {
1028   fmtShowList(LXImpNamesNumItems,LXImpNamesReadItems,
1029               IMPPROC_TABLE,0,NULL);
1030   return BMGetCurrFilePos();
1031 }
1032 
isLX(void)1033 static tBool __FASTCALL__ isLX( void )
1034 {
1035    char id[4];
1036    headshift = IsNewExe();
1037    bmReadBufferEx(id,sizeof(id),headshift,SEEKF_START);
1038    if(id[0] == 'L' && id[1] == 'X' && id[2] == 0 && id[3] == 0) return True;
1039    return False;
1040 }
1041 
LXinit(void)1042 static void __FASTCALL__ LXinit( void )
1043 {
1044    BGLOBAL main_handle;
1045    LXType = FILE_LX;
1046    bmReadBufferEx(&lxe.lx,sizeof(LXHEADER),headshift,SEEKF_START);
1047    main_handle = bmbioHandle();
1048    if((lx_cache = bioDupEx(main_handle,BBIO_SMALL_CACHE_SIZE)) == &bNull) lx_cache = main_handle;
1049 }
1050 
LXdestroy(void)1051 static void __FASTCALL__ LXdestroy( void )
1052 {
1053    BGLOBAL main_handle;
1054    main_handle = bmbioHandle();
1055    if(lx_cache != &bNull && lx_cache != main_handle) bioClose(lx_cache);
1056 }
1057 
LXHelp(void)1058 static __filesize_t __FASTCALL__ LXHelp( void )
1059 {
1060   hlpDisplay(10005);
1061   return BMGetCurrFilePos();
1062 }
1063 
lxVA2PA(__filesize_t va)1064 static __filesize_t __FASTCALL__ lxVA2PA(__filesize_t va)
1065 {
1066  /* First we must determine object number for given virtual address */
1067   BGLOBAL handle;
1068   unsigned long i,diff,oidx;
1069   __filesize_t rva,pa;
1070   LX_OBJECT lo;
1071   LX_MAP_TABLE mt;
1072   handle = lx_cache;
1073   bioSeek(handle,lxe.lx.lxObjectTableOffset + headshift,SEEK_SET);
1074   pa = oidx = 0; /* means: error */
1075   for(i = 0;i < lxe.lx.lxObjectCount;i++)
1076   {
1077     bioReadBuffer(handle,(void *)&lo,sizeof(LX_OBJECT));
1078     if(lo.o32_base <= va && va < lo.o32_base + lo.o32_size)
1079     {
1080       oidx = i+1;
1081       break;
1082     }
1083   }
1084   /* Secondly we must determine page within object */
1085   if(oidx)
1086   {
1087     rva = va - lo.o32_base;
1088     i = rva / lxe.lx.lxPageSize;
1089     diff = rva - i*lxe.lx.lxPageSize;
1090     lxReadPageDesc(handle,&mt,i+lo.o32_pagemap);
1091     pa = __calcPageEntry((void *)&mt) + diff;
1092   }
1093   return pa;
1094 }
1095 
lxPA2VA(__filesize_t pa)1096 static __filesize_t __FASTCALL__ lxPA2VA(__filesize_t pa)
1097 {
1098  /* First we must determine page for given physical address */
1099   BGLOBAL handle;
1100   unsigned long i,pidx,pagentry;
1101   __filesize_t rva,va;
1102   LX_OBJECT lo;
1103   LX_MAP_TABLE mt;
1104   handle = lx_cache;
1105   pagentry = va = pidx = 0;
1106   for(i = 0;i < lxe.lx.lxPageCount;i++)
1107   {
1108     lxReadPageDesc(handle,&mt,i+1);
1109     pagentry = __calcPageEntry(&mt);
1110     if(pagentry <= pa && pa < pagentry + mt.o32_pagesize)
1111     {
1112       pidx = i+1;
1113       break;
1114     }
1115   }
1116   /* Secondly we must determine object number for given physical address */
1117   if(pidx)
1118   {
1119     rva = pa - pagentry + (pidx-1)*lxe.lx.lxPageSize;
1120     bioSeek(handle,lxe.lx.lxObjectTableOffset + headshift,SEEK_SET);
1121     for(i = 0;i < lxe.lx.lxObjectCount;i++)
1122     {
1123       bioReadBuffer(handle,(void *)&lo,sizeof(LX_OBJECT));
1124       if(lo.o32_pagemap <= pidx && pidx < lo.o32_pagemap + lo.o32_mapsize)
1125       {
1126         va = lo.o32_base + rva;
1127         break;
1128       }
1129     }
1130   }
1131   return va;
1132 }
1133 
lxBitness(__filesize_t pa)1134 static int __FASTCALL__ lxBitness(__filesize_t pa)
1135 {
1136  /* First we must determine page for given physical address */
1137   BGLOBAL handle;
1138   unsigned long i,pidx,pagentry;
1139   int ret;
1140   LX_OBJECT lo;
1141   LX_MAP_TABLE mt;
1142   handle = lx_cache;
1143   pagentry = pidx = 0;
1144   ret = DAB_USE16;
1145   for(i = 0;i < lxe.lx.lxPageCount;i++)
1146   {
1147     lxReadPageDesc(handle,&mt,i+1);
1148     pagentry = __calcPageEntry(&mt);
1149     if(pagentry <= pa && pa < pagentry + mt.o32_pagesize)
1150     {
1151       pidx = i+1;
1152       break;
1153     }
1154   }
1155   /* Secondly we must determine object number for given physical address */
1156   if(pidx)
1157   {
1158     bioSeek(handle,lxe.lx.lxObjectTableOffset + headshift,SEEK_SET);
1159     for(i = 0;i < lxe.lx.lxObjectCount;i++)
1160     {
1161       bioReadBuffer(handle,(void *)&lo,sizeof(LX_OBJECT));
1162       if(lo.o32_pagemap <= pidx && pidx < lo.o32_pagemap + lo.o32_mapsize)
1163       {
1164         ret = (lo.o32_flags & 0x00002000L) == 0x00002000L ? DAB_USE32 : DAB_USE16;
1165         break;
1166       }
1167     }
1168   }
1169   return ret;
1170 }
1171 
lxAddressResolv(char * addr,__filesize_t cfpos)1172 static tBool __FASTCALL__ lxAddressResolv(char *addr,__filesize_t cfpos)
1173 {
1174  /* Since this function is used in references resolving of disassembler
1175     it must be seriously optimized for speed. */
1176   tBool bret = True;
1177   tUInt32 res;
1178   if(cfpos >= headshift && cfpos < headshift + sizeof(LXHEADER))
1179   {
1180     strcpy(addr,"LXH :");
1181     strcpy(&addr[5],Get4Digit(cfpos - headshift));
1182   }
1183   else
1184   if(cfpos >= headshift + lxe.lx.lxObjectTableOffset &&
1185      cfpos <  headshift + lxe.lx.lxObjectTableOffset + sizeof(LX_OBJECT)*lxe.lx.lxObjectCount)
1186   {
1187     strcpy(addr,"LXOD:");
1188     strcpy(&addr[5],Get4Digit(cfpos - headshift - lxe.lx.lxObjectTableOffset));
1189   }
1190   else
1191   if(cfpos >= headshift + lxe.lx.lxObjectPageTableOffset &&
1192      cfpos <  headshift + lxe.lx.lxObjectPageTableOffset + sizeof(LX_MAP_TABLE)*lxe.lx.lxPageCount)
1193   {
1194     strcpy(addr,"LXPD:");
1195     strcpy(&addr[5],Get4Digit(cfpos - headshift - lxe.lx.lxObjectPageTableOffset));
1196   }
1197   else
1198    if((res=lxPA2VA(cfpos))!=0)
1199    {
1200      addr[0] = '.';
1201      strcpy(&addr[1],Get8Digit(res));
1202    }
1203    else bret = False;
1204   return bret;
1205 }
1206 
lxPlatform(void)1207 static int __FASTCALL__ lxPlatform( void ) { return DISASM_CPU_IX86; }
1208 
1209 REGISTRY_BIN lxTable =
1210 {
1211   "LX (Linear eXecutable)",
1212   { "LXhelp", "Import", "ResNam", "NRsNam", "ImpNam", "Entry ", "ResTbl", "LXHead", "MapTbl", "Object" },
1213   { LXHelp, ShowModRefLX, ShowResNamLX, ShowNResNmLX, ShowImpProcLXLE, ShowEntriesLX, ShowResourceLX, ShowNewHeaderLX, ShowMapTableLX, ShowObjectsLX },
1214   isLX, LXinit, LXdestroy,
1215   NULL,
1216   NULL,
1217   NULL,
1218   lxPlatform,
1219   lxBitness,
1220   NULL,
1221   lxAddressResolv,
1222   lxVA2PA,
1223   lxPA2VA,
1224   NULL,
1225   NULL,
1226   NULL,
1227   NULL
1228 };
1229