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