source: trunk/mediafolder/c/helper/except.cpp@ 133

Last change on this file since 133 was 108, checked in by gyoung, 23 months ago

Fix all the warnings and errors reported by CPPCheck.

File size: 77.6 KB
Line 
1/**********************************************************************/
2/* */
3/* EXCEPTQ */
4/* */
5/* DLL containing an exception handler for gathering trap information */
6/* This DLL dumps all important debugging Data and is accessible */
7/* from both 16 bit and 32 bits programs */
8/**********************************************************************/
9/* Version: 2.2 | Marc Fiammante (FIAMMANT at LGEPROFS) */
10/* | La Gaude FRANCE */
11/* | Internet: fiammante@vnet.ibm.com */
12/* Version: 5.0 | John Currier (JCURRIER at CLTVM1) */
13/* | Internet: currier@vnet.ibm.com */
14/* Version: 6.0 | Kim Rasmussen (krasmus@ibm.net) */
15/* | Denmark */
16/* Version: 6.1 | Anthony Cruise (CRUISE at YKTVMH) */
17/* | Watson Research */
18/* Version: 6.2 | John Currier (JCURRIER at CLTVM1) */
19/* | Internet: currier@vnet.ibm.com */
20/* Version: 6.3 | Kim Rasmussen (kr@belle.dk) */
21/* | Denmark */
22/* | Marc Fiammante (FIAMMANT at LGEPROFS) */
23/* | La Gaude FRANCE */
24/* | Internet: fiammante@vnet.ibm.com */
25/* Version: 6.4 | Kim Rasmussen (kr@belle.dk) */
26/* | Denmark - http://www.belle.dk/kr/ */
27/**********************************************************************/
28/* */
29/**********************************************************************/
30/* History: */
31/* -------- */
32/* */
33/* created: Marc Fiammante December 1992 */
34/* changed: John Currier August 1994 */
35/* changed: Kim Rasmussen, May 1995 */
36/* Dump of auto-variables added (32-bit only) */
37/* changed: Anthony Cruise, May 1995 */
38/* Do not dump duplicate lines (32-bit only) */
39/* fixed : Marc Fiammante thanks to Bill Siddall */
40/* Dump of auto-variables wrong values */
41/* fixed : John Currier fix stack thunk on non fatal exceptions */
42/* fixed DosQueryMem Size test on return */
43/* fixed : Marc Fiammante find stack bottom from top to bottom */
44/* avoid traps on disassemble. */
45/* changed: Support for VisualAge C added (new debug format) */
46/* */
47/**********************************************************************/
48/**********************************************************************/
49/* */
50/* Modified by Chris Wohlgemuth 2002 for use with Audio/Data-CD- */
51/* Creator. */
52/* */
53/**********************************************************************/
54#define INCL_BASE
55#define INCL_DOSEXCEPTIONS
56#define INCL_DOSSEMAPHORES /* Semaphore values */
57#include <os2.h>
58#include <ctype.h>
59#include <stdlib.h>
60#include <stdio.h>
61#include <string.h>
62#include <time.h>
63#include "sym.h"
64#include "omf.h"
65
66#ifndef DWORD
67#define DWORD unsigned long
68#endif
69#ifndef WORD
70#define WORD unsigned short
71#endif
72#pragma stack16(512)
73#define HF_STDERR 2
74CHAR *ProcessName = "DEBUGGEE.EXE";
75FILE *hTrap;
76static BOOL f32bit = TRUE;
77struct debug_buffer
78 {
79 ULONG Pid; /* Debuggee Process ID */
80 ULONG Tid; /* Debuggee Thread ID */
81 LONG Cmd; /* Command or Notification */
82 LONG Value; /* Generic Data Value */
83 ULONG Addr; /* Debuggee Address */
84 ULONG Buffer; /* Debugger Buffer Address */
85 ULONG Len; /* Length of Range */
86 ULONG Index; /* Generic Identifier Index */
87 ULONG MTE; /* Module Handle */
88 ULONG EAX; /* Register Set */
89 ULONG ECX;
90 ULONG EDX;
91 ULONG EBX;
92 ULONG ESP;
93 ULONG EBP;
94 ULONG ESI;
95 ULONG EDI;
96 ULONG EFlags;
97 ULONG EIP;
98 ULONG CSLim; /* Byte Granular Limits */
99 ULONG CSBase; /* Byte Granular Base */
100 UCHAR CSAcc; /* Access Bytes */
101 UCHAR CSAtr; /* Attribute Bytes */
102 USHORT CS;
103 ULONG DSLim;
104 ULONG DSBase;
105 UCHAR DSAcc;
106 UCHAR DSAtr;
107 USHORT DS;
108 ULONG ESLim;
109 ULONG ESBase;
110 UCHAR ESAcc;
111 UCHAR ESAtr;
112 USHORT ES;
113 ULONG FSLim;
114 ULONG FSBase;
115 UCHAR FSAcc;
116 UCHAR FSAtr;
117 USHORT FS;
118 ULONG GSLim;
119 ULONG GSBase;
120 UCHAR GSAcc;
121 UCHAR GSAtr;
122 USHORT GS;
123 ULONG SSLim;
124 ULONG SSBase;
125 UCHAR SSAcc;
126 UCHAR SSAtr;
127 USHORT SS;
128} DbgBuf;
129/*-------------------------------------*/
130APIRET APIENTRY DOSQUERYMODFROMEIP( HMODULE *phMod,
131 ULONG *pObjNum,
132 ULONG BuffLen,
133 PCHAR pBuff,
134 ULONG *pOffset,
135 PVOID Address );
136/*APIRET APIENTRY DosQueryModFromEIP( HMODULE *phMod,
137 ULONG *pObjNum,
138 ULONG BuffLen,
139 PCHAR pBuff,
140 ULONG *pOffset,
141 PVOID Address );*/
142
143/*-------------------------------------*/
144/* CW
145#define DBG_O_OBJMTE 0x10000000L*/
146#define DBG_C_NumToAddr 13
147#define DBG_C_AddrToObject 28
148#define DBG_C_Connect 21
149#define DBG_L_386 1
150RESULTCODES ReturnCodes;
151UCHAR LoadError[40]; /*DosExecPGM buffer */
152USHORT Passes;
153UCHAR Translate[17];
154UCHAR OldStuff[16];
155
156#ifdef USE_DOSDEBUG
157void GetObjects(struct debug_buffer * pDbgBuf,HMODULE hMte,PSZ pName);
158#endif
159
160VOID ListModules(VOID);
161void CheckMem(PVOID Ptr,PSZ MemoryName);
162/* Better New WalkStack From John Currier */
163static void WalkStack(PUSHORT StackBottom,PUSHORT StackTop,PUSHORT Ebp,PUSHORT ExceptionAddress);
164int Read16CodeView(int fh,int TrapSeg,int TrapOff,CHAR * FileName);
165int Read32PmDebug(int fh,int TrapSeg,int TrapOff,CHAR * FileName);
166APIRET GetLineNum(CHAR * FileName, ULONG Object,ULONG TrapOffset);
167void GetSymbol(CHAR * SymFileName, ULONG Object,ULONG TrapOffset);
168void print_vars(ULONG stackofs);
169
170ULONG func_ofs;
171ULONG pubfunc_ofs;
172char func_name[128];
173ULONG var_ofs = 0;
174
175struct {
176 BYTE name[128];
177 ULONG stack_offset;
178 USHORT type_idx;
179} autovar_def[100];
180
181HMODULE hMod;
182ULONG ObjNum;
183ULONG Offset;
184
185/*-------------------------------------*/
186CHAR Buffer[CCHMAXPATH];
187
188typedef ULONG * _Seg16 PULONG16;
189APIRET16 APIENTRY16 DOS16SIZESEG( USHORT Seg , PULONG16 Size);
190typedef APIRET16 (APIENTRY16 _PFN16)();
191ULONG APIENTRY DosSelToFlat(ULONG);
192/*-------------------------------------*/
193
194/*- DosQProcStatus interface ----------*/
195APIRET16 APIENTRY16 DOSQPROCSTATUS( ULONG * _Seg16 pBuf, USHORT cbBuf);
196#define CONVERT(fp,QSsel) MAKEP((QSsel),OFFSETOF(fp))
197#pragma pack(1)
198/* Global Data Section */
199typedef struct qsGrec_s {
200 ULONG cThrds; /* number of threads in use */
201 ULONG Reserved1;
202 ULONG Reserved2;
203}qsGrec_t;
204
205#define PADSHORT USHORT pad_sh
206#define PADCHAR UCHAR pad_ch
207
208/* Thread Record structure * Holds all per thread information. */
209typedef struct qsTrec_s {
210 ULONG RecType; /* Record Type */
211 /* Thread rectype = 100 */
212 USHORT tid; /* thread ID */
213 USHORT slot; /* "unique" thread slot number */
214 ULONG sleepid; /* sleep id thread is sleeping on */
215 ULONG priority; /* thread priority */
216 ULONG systime; /* thread system time */
217 ULONG usertime; /* thread user time */
218 UCHAR state; /* thread state */
219 PADCHAR;
220 PADSHORT;
221} qsTrec_t;
222
223/* Process and Thread Data Section */
224typedef struct qsPrec_s {
225 ULONG RecType; /* type of record being processed */
226 /* process rectype = 1 */
227 qsTrec_t * pThrdRec; /* ptr to 1st thread rec for this prc*/
228 USHORT pid; /* process ID */
229 USHORT ppid; /* parent process ID */
230 ULONG type; /* process type */
231 ULONG stat; /* process status */
232 ULONG sgid; /* process screen group */
233 USHORT hMte; /* program module handle for process */
234 USHORT cTCB; /* # of TCBs in use in process */
235 ULONG Reserved1;
236 void * Reserved2;
237 USHORT c16Sem; /*# of 16 bit system sems in use by proc*/
238 USHORT cLib; /* number of runtime linked libraries */
239 USHORT cShrMem; /* number of shared memory handles */
240 USHORT Reserved3;
241 USHORT * p16SemRec; /*ptr to head of 16 bit sem inf for proc*/
242 USHORT * pLibRec; /*ptr to list of runtime lib in use by */
243 /*process*/
244 USHORT * pShrMemRec; /*ptr to list of shared mem handles in */
245 /*use by process*/
246 USHORT * Reserved4;
247} qsPrec_t;
248
249/* 16 Bit System Semaphore Section */
250typedef struct qsS16Headrec_s {
251 ULONG RecType; /* semaphore rectype = 3 */
252 ULONG Reserved1; /* overlays NextRec of 1st qsS16rec_t */
253 ULONG Reserved2;
254 ULONG S16TblOff; /* index of first semaphore,SEE PSTAT OUTPUT*/
255 /* System Semaphore Information Section */
256} qsS16Headrec_t;
257/* 16 bit System Semaphore Header Record Structure */
258typedef struct qsS16rec_s {
259 ULONG NextRec; /* offset to next record in buffer */
260 UINT s_SysSemOwner ; /* thread owning this semaphore */
261 UCHAR s_SysSemFlag ; /* system semaphore flag bit field */
262 UCHAR s_SysSemRefCnt ; /* number of references to this */
263 /* system semaphore */
264 UCHAR s_SysSemProcCnt ; /*number of requests by sem owner */
265 UCHAR Reserved1;
266 ULONG Reserved2;
267 UINT Reserved3;
268 CHAR SemName[1]; /* start of semaphore name string */
269} qsS16rec_t;
270
271/* Executable Module Section */
272typedef struct qsLrec_s {
273 void * pNextRec; /* pointer to next record in buffer */
274 USHORT hmte; /* handle for this mte */
275 USHORT Reserved1; /* Reserved */
276 ULONG ctImpMod; /* # of imported modules in table */
277 ULONG Reserved2; /* Reserved */
278/* qsLObjrec_t * Reserved3; Reserved */
279 ULONG * Reserved3; /* Reserved */
280 UCHAR * pName; /* ptr to name string following stru*/
281} qsLrec_t;
282
283/* Shared Memory Segment Section */
284typedef struct qsMrec_s {
285 struct qsMrec_s *MemNextRec; /* offset to next record in buffer */
286 USHORT hmem; /* handle for shared memory */
287 USHORT sel; /* shared memory selector */
288 USHORT refcnt; /* reference count */
289 CHAR Memname[1]; /* start of shared memory name string */
290} qsMrec_t;
291
292/* Pointer Record Section */
293typedef struct qsPtrRec_s {
294 qsGrec_t * pGlobalRec; /* ptr to the global data section */
295 qsPrec_t * pProcRec; /* ptr to process record section */
296 qsS16Headrec_t * p16SemRec; /* ptr to 16 bit sem section */
297 void * Reserved; /* a reserved area */
298 qsMrec_t * pShrMemRec; /* ptr to shared mem section */
299 qsLrec_t * pLibRec; /*ptr to exe module record section*/
300} qsPtrRec_t;
301
302/*-------------------------*/
303ULONG * pBuf,*pTemp;
304USHORT Selector;
305qsPtrRec_t * pRec;
306qsLrec_t * pLib;
307qsMrec_t * pShrMemRec; /* ptr to shared mem section */
308qsPrec_t * pProc;
309qsTrec_t * pThread;
310ULONG ListedThreads=0;
311APIRET16 APIENTRY16 DOS16ALLOCSEG(
312 USHORT cbSize, /* number of bytes requested */
313 USHORT * _Seg16 pSel, /* sector allocated (returned) */
314 USHORT fsAlloc); /* sharing attributes of the allocated segment */
315
316typedef struct
317 {
318 short int ilen; /* Instruction length */
319 long rref; /* Value of any IP relative storage reference */
320 unsigned short sel; /* Selector of any CS:eIP storage reference. */
321 long poff; /* eIP value of any CS:eIP storage reference. */
322 char longoper; /* YES/NO value. Is instr in 32 bit operand mode? **/
323 char longaddr; /* YES/NO value. Is instr in 32 bit address mode? **/
324 char buf[40]; /* String holding disassembled instruction **/
325 } * _Seg16 RETURN_FROM_DISASM;
326
327RETURN_FROM_DISASM CDECL16 DISASM( CHAR * _Seg16 Source, USHORT IPvalue,USHORT segsize );
328RETURN_FROM_DISASM AsmLine;
329
330char *SourceBuffer=0;
331static USHORT BigSeg;
332static ULONG Version[2];
333
334BYTE *type_name[] = {
335 "8 bit signed ",
336 "16 bit signed ",
337 "32 bit signed ",
338 "Unknown (0x83) ",
339 "8 bit unsigned ",
340 "16 bit unsigned ",
341 "32 bit unsigned ",
342 "Unknown (0x87) ",
343 "32 bit real ",
344 "64 bit real ",
345 "80 bit real ",
346 "Unknown (0x8B) ",
347 "64 bit complex ",
348 "128 bit complex ",
349 "160 bit complex ",
350 "Unknown (0x8F) ",
351 "8 bit boolean ",
352 "16 bit boolean ",
353 "32 bit boolean ",
354 "Unknown (0x93) ",
355 "8 bit character ",
356 "16 bit characters ",
357 "32 bit characters ",
358 "void ",
359 "15 bit unsigned ",
360 "24 bit unsigned ",
361 "31 bit unsigned ",
362 "Unknown (0x9B) ",
363 "Unknown (0x9C) ",
364 "Unknown (0x9D) ",
365 "Unknown (0x9E) ",
366 "Unknown (0x9F) ",
367 "near pointer to 8 bit signed ",
368 "near pointer to 16 bit signed ",
369 "near pointer to 32 bit signed ",
370 "Unknown (0xA3) ",
371 "near pointer to 8 bit unsigned ",
372 "near pointer to 16 bit unsigned ",
373 "near pointer to 32 bit unsigned ",
374 "Unknown (0xA7) ",
375 "near pointer to 32 bit real ",
376 "near pointer to 64 bit real ",
377 "near pointer to 80 bit real ",
378 "Unknown (0xAB) ",
379 "near pointer to 64 bit complex ",
380 "near pointer to 128 bit complex ",
381 "near pointer to 160 bit complex ",
382 "Unknown (0xAF) ",
383 "near pointer to 8 bit boolean ",
384 "near pointer to 16 bit boolean ",
385 "near pointer to 32 bit boolean ",
386 "Unknown (0xB3) ",
387 "near pointer to 8 bit character ",
388 "near pointer to 16 bit characters",
389 "near pointer to 32 bit characters",
390 "near pointer to void ",
391 "near pointer to 15 bit unsigned ",
392 "near pointer to 24 bit unsigned ",
393 "near pointer to 31 bit unsigned ",
394 "Unknown (0xBB) ",
395 "Unknown (0xBC) ",
396 "Unknown (0xBD) ",
397 "Unknown (0xBE) ",
398 "Unknown (0xBF) ",
399 "far pointer to 8 bit signed ",
400 "far pointer to 16 bit signed ",
401 "far pointer to 32 bit signed ",
402 "Unknown (0xC3) ",
403 "far pointer to 8 bit unsigned ",
404 "far pointer to 16 bit unsigned ",
405 "far pointer to 32 bit unsigned ",
406 "Unknown (0xC7) ",
407 "far pointer to 32 bit real ",
408 "far pointer to 64 bit real ",
409 "far pointer to 80 bit real ",
410 "Unknown (0xCB) ",
411 "far pointer to 64 bit complex ",
412 "far pointer to 128 bit complex ",
413 "far pointer to 160 bit complex ",
414 "Unknown (0xCF) ",
415 "far pointer to 8 bit boolean ",
416 "far pointer to 16 bit boolean ",
417 "far pointer to 32 bit boolean ",
418 "Unknown (0xD3) ",
419 "far pointer to 8 bit character ",
420 "far pointer to 16 bit characters ",
421 "far pointer to 32 bit characters ",
422 "far pointer to void ",
423 "far pointer to 15 bit unsigned ",
424 "far pointer to 24 bit unsigned ",
425 "far pointer to 31 bit unsigned ",
426};
427
428/*-- --*/
429/*-------------------------------------*/
430
431typedef _PFN16 * _Seg16 PFN16;
432/*-- --*/
433static BOOL InForceExit =FALSE;
434
435/*-------------------------------------*/
436ULONG APIENTRY HandleFatalException (PEXCEPTIONREPORTRECORD pERepRec,
437 PEXCEPTIONREGISTRATIONRECORD pERegRec,
438 PCONTEXTRECORD pCtxRec,
439 PVOID p);
440
441// Thanks to John Currier :
442// Do not call 16 bit code in myHandler function to prevent call
443// to __EDCThunkProlog and problems is guard page exception handling
444// Also reduce the stack size to 1K for true 16 bit calls.
445// 16 bit calls thunk will now only occur on fatal exceptions
446#pragma stack16(1024)
447
448#include "except.h"
449
450ULONG _System excHandler(PEXCEPTIONREPORTRECORD pERepRec,
451 PLOCALEXCEPTSTRUCT pRegRec2,
452 // PREGREC2 pRegRec2,
453 PCONTEXTRECORD pCtxRec,
454 PVOID pv)
455{
456 ULONG rc = XCPT_CONTINUE_SEARCH;
457
458 if (pERepRec->fHandlerFlags & EH_EXIT_UNWIND)
459 return (XCPT_CONTINUE_SEARCH);
460 if (pERepRec->fHandlerFlags & EH_UNWINDING)
461 return (XCPT_CONTINUE_SEARCH);
462 if (pERepRec->fHandlerFlags & EH_NESTED_CALL)
463 return (XCPT_CONTINUE_SEARCH);
464
465
466 if ((pERepRec->ExceptionNum & XCPT_SEVERITY_CODE) == XCPT_FATAL_EXCEPTION)
467 {
468 DosBeep(5000,30);
469 DosBeep(4000,30);
470 DosBeep(3000,30);
471 DosBeep(4000,30);
472 DosBeep(5000,30);
473
474 if (pERepRec->ExceptionNum != XCPT_PROCESS_TERMINATE &&
475 pERepRec->ExceptionNum != XCPT_UNWIND &&
476 pERepRec->ExceptionNum != XCPT_SIGNAL &&
477 pERepRec->ExceptionNum != XCPT_BREAKPOINT &&
478 pERepRec->ExceptionNum != XCPT_SINGLE_STEP &&
479 pERepRec->ExceptionNum != XCPT_ASYNC_PROCESS_TERMINATE)
480 {
481 // If any of the above conditionals fail then we have to handle
482 // the fatal trap.
483 rc = HandleFatalException(pERepRec, (PEXCEPTIONREGISTRATIONRECORD) pRegRec2, pCtxRec, pv);
484 longjmp(pRegRec2->jmpThread, pERepRec->ExceptionNum);
485 // longjmp(pERegRec->jmpThread, pERepRec->ExceptionNum);
486 }
487 }
488 return rc;
489}
490#if 0
491ULONG APIENTRY myHandler (PEXCEPTIONREPORTRECORD pERepRec,
492 PEXCEPTIONREGISTRATIONRECORD pERegRec,
493 PCONTEXTRECORD pCtxRec,
494 PVOID p)
495{
496 ULONG rc = XCPT_CONTINUE_SEARCH;
497
498 if (pERepRec->fHandlerFlags & EH_EXIT_UNWIND)
499 return (XCPT_CONTINUE_SEARCH);
500 if (pERepRec->fHandlerFlags & EH_UNWINDING)
501 return (XCPT_CONTINUE_SEARCH);
502 if (pERepRec->fHandlerFlags & EH_NESTED_CALL)
503 return (XCPT_CONTINUE_SEARCH);
504
505 if ((pERepRec->ExceptionNum & XCPT_SEVERITY_CODE) == XCPT_FATAL_EXCEPTION)
506 {
507 if (pERepRec->ExceptionNum != XCPT_PROCESS_TERMINATE &&
508 pERepRec->ExceptionNum != XCPT_UNWIND &&
509 pERepRec->ExceptionNum != XCPT_SIGNAL &&
510 pERepRec->ExceptionNum != XCPT_BREAKPOINT &&
511 pERepRec->ExceptionNum != XCPT_SINGLE_STEP &&
512 pERepRec->ExceptionNum != XCPT_ASYNC_PROCESS_TERMINATE)
513 {
514 // If any of the above conditionals fail then we have to handle
515 // the fatal trap.
516 rc = HandleFatalException(pERepRec, pERegRec, pCtxRec, p);
517 longjmp(pERegRec->jmpThread, pERepRec->ExceptionNum);
518 }
519 }
520 return rc;
521}
522#endif
523
524static char _GetBootDriveLetter(void)
525{
526 ULONG ulSysValue;
527
528 if(!DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,&ulSysValue,sizeof(ulSysValue)))
529 return 'a'+ulSysValue-1;
530
531 return 'c';
532}
533
534ULONG APIENTRY HandleFatalException (PEXCEPTIONREPORTRECORD pERepRec,
535 PEXCEPTIONREGISTRATIONRECORD pERegRec,
536 PCONTEXTRECORD pCtxRec,
537 PVOID p)
538{
539 PCHAR SegPtr;
540 PUSHORT StackPtr;
541 PUSHORT ValidStackBottom;
542 PUCHAR TestStackBottom;
543 PUCHAR cStackPtr;
544 ULONG Size,Flags,Attr,CSSize;
545 APIRET rc;
546 APIRET semrc;
547 APIRET16 rc16;
548 PTIB ptib;
549 PPIB ppib;
550 USHORT Count;
551 ULONG Nest;
552 CHAR TrapFile[20];
553 struct debug_buffer DbgBuf;
554 static CHAR Name[CCHMAXPATH];
555
556 /* Do not recurse into Trapper (John Currier) */
557 /* Not necessary anymore because nested calls are catched now CW */
558 static BOOL fAlreadyTrapped = FALSE;
559
560 if (InForceExit) {
561 return (XCPT_CONTINUE_SEARCH);
562 } /* endif */
563 if ((pERepRec->ExceptionNum&XCPT_SEVERITY_CODE)==XCPT_FATAL_EXCEPTION)
564 {
565 if ((pERepRec->ExceptionNum!=XCPT_PROCESS_TERMINATE)&&
566 (pERepRec->ExceptionNum!=XCPT_UNWIND)&&
567 (pERepRec->ExceptionNum!=XCPT_SIGNAL)&&
568 (pERepRec->ExceptionNum!=XCPT_ASYNC_PROCESS_TERMINATE)) {
569 DosEnterMustComplete(&Nest);
570
571 sprintf(TrapFile,"%c:\\%s",_GetBootDriveLetter(), EXCEPTION_LOGFILE_NAME);
572
573 hTrap=fopen(TrapFile,"a");
574 if (hTrap==NULL)
575 hTrap=stdout;
576
577 // rc=DosError(FERR_DISABLEEXCEPTION | FERR_DISABLEHARDERR );
578
579 setbuf( hTrap, NULL);/* Unbuffered stream */
580 // fprintf(hTrap,"A trap occurred in Audio/Data-CD-Creator\n");
581 fprintf(hTrap,"----------------------------------------\n\n");
582 fprintf(hTrap,"Exception %8.8lX Occurred",pERepRec->ExceptionNum);
583 fprintf(hTrap," at %s ",_strtime(Buffer));
584 fprintf(hTrap," %s\n\n",_strdate(Buffer));
585 if ( pERepRec->ExceptionNum == XCPT_ACCESS_VIOLATION)
586 {
587 switch (pERepRec->ExceptionInfo[0]) {
588 case XCPT_READ_ACCESS:
589 fprintf(hTrap,"Invalid read address %8.8lX\n",pERepRec->ExceptionInfo[1]);
590 break;
591 case XCPT_WRITE_ACCESS:
592 fprintf(hTrap,"Invalid write address %8.8lX\n",pERepRec->ExceptionInfo[1]);
593 break;
594 case XCPT_SPACE_ACCESS:
595 /* Thanks to John Currier */
596 /* It looks like this is off by one... */
597 fprintf(hTrap,"Invalid Selector: %8.8p",
598 pERepRec->ExceptionInfo[1] ?
599 pERepRec->ExceptionInfo[1] + 1 : 0);
600 break;
601 case XCPT_LIMIT_ACCESS:
602 fprintf(hTrap,"Limit access fault\n");
603 break;
604 case XCPT_UNKNOWN_ACCESS:
605 fprintf(hTrap,"Unknown access fault\n");
606 break;
607 break;
608 default:
609 fprintf(hTrap,"Other Unknown access fault\n");
610 } /* endswitch */
611 } /* endif XCPT_ACCESS_VIOLATION */
612 else if( pERepRec->ExceptionNum == XCPT_INTEGER_DIVIDE_BY_ZERO)
613 {
614 fprintf(hTrap,"Division by zero.\n");
615 }
616 else if( pERepRec->ExceptionNum == XCPT_ILLEGAL_INSTRUCTION)
617 {
618 fprintf(hTrap,"Illegal instruction.\n");
619 }
620 else if( pERepRec->ExceptionNum == XCPT_PRIVILEGED_INSTRUCTION)
621 {
622 fprintf(hTrap,"Privileged instruction.\n");
623 }
624 else if( pERepRec->ExceptionNum == XCPT_INTEGER_OVERFLOW)
625 {
626 fprintf(hTrap,"Integer overflow.\n");
627 }
628
629 /* John Currier's recursion prevention */
630 fprintf(hTrap,"\n\n");
631#if 0 /* Not necessary anymore because nested calls are catched now CW */
632 if (fAlreadyTrapped)
633 {
634 fprintf(hTrap, "Exception Handler Trapped...aborting evaluation!\n");
635 if (hTrap != stderr)
636 fclose(hTrap);
637 DosExitMustComplete(&Nest);
638
639 /* DosUnsetExceptionHandler(pERegRec); */
640 return (XCPT_CONTINUE_SEARCH);
641 }
642#endif
643
644 fAlreadyTrapped = TRUE;
645 /* end John Currier's recursion prevention */
646 rc = DosQuerySysInfo(QSV_VERSION_MAJOR,QSV_VERSION_MINOR,
647 Version,sizeof(Version));
648 if ((rc==0)&&
649 (Version[0]>=20) &&
650 (Version[1]>=10) ) {
651 /* version must be over 2.1 for DOSQUERYMODFROMEIP */
652 fprintf(hTrap,"OS/2 Version %d.%d\n",Version[0]/10,Version[1]);
653 rc=DOSQUERYMODFROMEIP( &hMod, &ObjNum, CCHMAXPATH,
654 Name, &Offset, pERepRec->ExceptionAddress);
655 if (rc==0) {
656 fprintf(hTrap,"Failing code module internal name : %s\n",Name);
657 rc=DosQueryModuleName(hMod,CCHMAXPATH, Name);
658 fprintf(hTrap,"Failing code module file name : %s\n",Name);
659 fprintf(hTrap,"Failing code Object # %d at Offset %x \n",ObjNum+1,Offset);
660 if (strlen(Name)>3) {
661 fprintf(hTrap," File Line# Public Symbol\n");
662 fprintf(hTrap," ÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄ- ÄÄÄÄÄÄÄÄÄÄÄÄ-\n");
663 rc =GetLineNum(Name,ObjNum,Offset);
664
665 if (rc == 0)
666 print_vars(pCtxRec->ctx_RegEbp);
667
668 /* if no codeview try with symbol files */
669 if (rc!=0) {
670 strcpy(Name+strlen(Name)-3,"SYM"); /* Get Sym File name */
671 GetSymbol(Name,ObjNum,Offset);
672 } /* endif */
673 } /* endif */
674 fprintf(hTrap,"\n");
675 } else {
676 fprintf(hTrap,"Invalid execution address\n");
677 } /* endif */
678 } /* endif */
679 if ( (pCtxRec->ContextFlags) & CONTEXT_CONTROL ) {
680 void * _Seg16 Ptr16;
681 BigSeg=((pCtxRec->ctx_RegEip)>0x00010000);
682 if (BigSeg) {
683 /* Avoid traps in 16:16 Disasm DLL */
684 if (DosAllocMem((PPVOID)&SourceBuffer,0x100,fALLOC)==0) {
685 Size=0x100;
686 rc=DosQueryMem((PVOID)pCtxRec->ctx_RegEip,&Size,&Attr);
687 if (Attr&(PAG_READ|PAG_EXECUTE)) {
688 memcpy(SourceBuffer,(PVOID)pCtxRec->ctx_RegEip,Size);
689#if 0 /*CW*/
690 AsmLine= DISASM( SourceBuffer,
691 (USHORT)pCtxRec->ctx_RegEip, BigSeg );
692 fprintf(hTrap,"\n Failing instruction at CS:EIP : %4.4X:%8.8X is %s\n\n",
693 pCtxRec->ctx_SegCs,
694 pCtxRec->ctx_RegEip,AsmLine->buf);
695#endif
696 } /* endif */
697 }
698 } else {
699 if (CSSize>pCtxRec->ctx_RegEip) {
700#if 0 /*CW*/
701 AsmLine= DISASM(MAKE16P(pCtxRec->ctx_SegCs,
702 pCtxRec->ctx_RegEip),
703 (USHORT)pCtxRec->ctx_RegEip, BigSeg );
704 fprintf(hTrap,"\n Failing instruction at CS:IP : %4.4X:%4.4X is %s\n\n",
705 pCtxRec->ctx_SegCs,
706 pCtxRec->ctx_RegEip,AsmLine->buf);
707#endif
708 } else {
709 fprintf(hTrap,"Invalid execution address\n");
710 } /* endif */
711 } /* endif */
712
713 rc=DosGetInfoBlocks(&ptib,&ppib);
714 if (rc==NO_ERROR) {
715 static CHAR Format[10];
716
717 fprintf(hTrap,"\nThread slot %lu , Id %lu , priority %p\n",
718 ptib->tib_ordinal,
719 ptib->tib_ptib2->tib2_ultid ,
720 ptib->tib_ptib2->tib2_ulpri );
721 Ptr16=ptib->tib_pstack;
722 sprintf(Format,"%8.8lX",Ptr16);
723 fprintf(hTrap,"Stack Bottom : %8.8lX (%4.4s:%4.4s) ;", ptib->tib_pstack ,Format,Format+4);
724 Ptr16=ptib->tib_pstacklimit;
725 sprintf(Format,"%8.8lX",Ptr16);
726 fprintf(hTrap,"Stack Top : %8.8lX (%4.4s:%4.4s) \n",ptib->tib_pstacklimit,Format,Format+4);
727 fprintf(hTrap,"Process Id : %lu ", ppib->pib_ulpid);
728 rc=DosQueryModuleName(ppib->pib_hmte,CCHMAXPATH, Name);
729 if (rc==NO_ERROR) {
730 fprintf(hTrap,".EXE name : %s\n",Name);
731 } else {
732 fprintf(hTrap,".EXE name : ??????\n");
733 } /* endif */
734 /* Better New WalkStack From John Currier */
735 WalkStack((PUSHORT)ptib->tib_pstack,
736 (PUSHORT)ptib->tib_pstacklimit,
737 (PUSHORT)pCtxRec->ctx_RegEbp,
738 (PUSHORT)pERepRec->ExceptionAddress);
739 ListModules();
740 Count=0;
741 } /* endif */
742 } /* endif */
743
744 if (hTrap!=stdout) {
745 fclose(hTrap);
746 }
747 DosExitMustComplete(&Nest);
748
749 /* rc=DosUnsetExceptionHandler(pERegRec); CW */
750 } /* endif */
751 } else {
752 /* printf("Other non fatal exception %8.8lx ",pERepRec->ExceptionNum); */
753 /* printf("At address %8.8lx\n",pERepRec->ExceptionAddress); */
754 } /* endif */
755 return (XCPT_CONTINUE_SEARCH);
756}
757
758#if 0 /*CW */
759APIRET16 APIENTRY16 SETEXCEPT(PEXCEPTIONREGISTRATIONRECORD _Seg16 pxcpthand)
760 {
761 APIRET rc;
762
763 rc=DosError(FERR_DISABLEEXCEPTION | FERR_DISABLEHARDERR );
764 printf("Set error rc %ld\n",rc);
765 pxcpthand->prev_structure=0;
766 pxcpthand->ExceptionHandler=&myHandler;
767 rc=DosSetExceptionHandler(pxcpthand);
768 printf("Set except rc %ld\n",rc);
769 return rc;/* CW */
770}
771APIRET16 APIENTRY16 UNSETEXCEPT(PEXCEPTIONREGISTRATIONRECORD _Seg16 pxcpthand)
772 {
773 APIRET rc;
774 rc=DosUnsetExceptionHandler(pxcpthand);
775 printf("Unset except rc %ld\n",rc);
776 return rc;/* CW */
777}
778#endif
779
780VOID ListModules() {
781 APIRET rc;
782 APIRET16 rc16;
783#ifdef USE_DOSDEBUG
784 /**----------------------------------***/
785#else
786#if MORE_INFO_WANTED
787 PVOID BaseAddress;
788 ULONG RegionSize;
789 ULONG AllocationFlags;
790 HMODULE LastModule;
791 static CHAR Name[CCHMAXPATH];
792 ULONG Size;
793 LastModule=0;
794 BaseAddress=(PVOID)0x10000;
795 RegionSize =0x3FFFFFFF;
796 fprintf(hTrap,"ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\n");
797 fprintf(hTrap,"³ List of currently accessed modules (DLLs) object addresses ³");
798 rc=DosQueryMem(BaseAddress,&RegionSize,&AllocationFlags);
799 while (rc==NO_ERROR) {
800 if ((AllocationFlags&PAG_EXECUTE)&&
801 (AllocationFlags&PAG_BASE)) {
802 rc=DOSQUERYMODFROMEIP( &hMod, &ObjNum, CCHMAXPATH,
803 Name, &Offset, BaseAddress);
804 if (rc==0) {
805 if (hMod!=LastModule) {
806 rc=DosQueryModuleName(hMod,CCHMAXPATH, Name);
807 fprintf(hTrap,"\nÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŽ\n");
808 fprintf(hTrap,"³ Module %-48.48s Handle %8.8d ³\n",Name,hMod);
809 fprintf(hTrap,"³ Object Number Address Length Flags Type ³");
810 LastModule=hMod;
811 } /* endif */
812 fprintf(hTrap,"\n³ % 6.6d %8.8lX %8.8lX %8.8lX ",ObjNum,
813 BaseAddress, RegionSize, AllocationFlags);
814 rc16 =DOS16SIZESEG( SELECTOROF(BaseAddress), &Size);
815 if (rc16==0) {
816 fprintf(hTrap," - 16:16 Selector %4.4hX ³",SELECTOROF((PVOID)BaseAddress));
817 } else {
818 fprintf(hTrap," - 32 Bits ³");
819 } /* endif */
820 }
821 }
822 if (AllocationFlags&PAG_FREE) RegionSize =0x10000;
823 RegionSize +=0x0FFF;
824 RegionSize &=0xFFFFF000;
825 BaseAddress=(PVOID)(((PCHAR)BaseAddress)+RegionSize);
826 RegionSize=((PCHAR)0x3FFFFFFF)-(PCHAR)BaseAddress;
827 rc=DosQueryMem(BaseAddress,&RegionSize,&AllocationFlags);
828 while ((rc==ERROR_INVALID_ADDRESS)||
829 (rc==ERROR_NO_OBJECT)) {
830 BaseAddress=(PVOID)(((PCHAR)BaseAddress)+0x10000);
831 if (BaseAddress>(PVOID)0x3FFFFFFF) {
832 break;
833 } /* endif */
834 RegionSize=((PCHAR)0x3FFFFFFF)-(PCHAR)BaseAddress;
835 rc=DosQueryMem(BaseAddress,&RegionSize,&AllocationFlags);
836 } /* endwhile */
837 if (BaseAddress>(PVOID)0x3FFFFFFF) {
838 break;
839 } /* endif */
840 } /* endwhile */
841 fprintf(hTrap,"\nÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\n");
842#endif
843#endif
844}
845
846
847void CheckMem(PVOID Ptr,PSZ MemoryName) {
848 APIRET rc;
849 ULONG Size,Flags,Attr;
850 Size=1;
851 rc=DosQueryMem(Ptr,&Size,&Attr);
852 if (rc!=NO_ERROR) {
853 fprintf(hTrap, "³ %3.3s does not point to valid memory ³\n",MemoryName);
854 } else {
855 if (Attr&PAG_FREE) {
856 fprintf(hTrap, "³ %3.3s points to unallocated memory ³\n",MemoryName);
857 } else {
858 if ((Attr&PAG_COMMIT)==0x0U) {
859 fprintf(hTrap,"³ %3.3s points to uncommited memory ³\n",MemoryName);
860 } /* endif */
861 if ((Attr&PAG_WRITE)==0x0U) {
862 fprintf(hTrap,"³ %3.3s points to unwritable memory ³\n",MemoryName);
863 } /* endif */
864 if ((Attr&PAG_READ)==0x0U) {
865 fprintf(hTrap,"³ %3.3s points to unreadable memory ³\n",MemoryName);
866 } /* endif */
867 } /* endif */
868 } /* endif */
869}
870
871PUSHORT Convert(USHORT * _Seg16 p16) {
872 return p16;
873}
874
875/* Better New WalkStack From John Currier */
876static void WalkStack(PUSHORT StackBottom, PUSHORT StackTop, PUSHORT Ebp,
877 PUSHORT ExceptionAddress)
878{
879 PUSHORT RetAddr;
880 PUSHORT LastEbp;
881 APIRET rc;
882 ULONG Size,Attr;
883 USHORT Cs,Ip,Bp,Sp;
884 static char Name[CCHMAXPATH];
885 HMODULE hMod;
886 ULONG ObjNum;
887 ULONG Offset;
888 BOOL fExceptionAddress = TRUE; // Use Exception Addr 1st time thru
889
890 // Note: we can't handle stacks bigger than 64K for now...
891 Sp = (USHORT)(((ULONG)StackBottom) >> 16);
892 Bp = (USHORT)(ULONG)Ebp;
893
894 if (!f32bit)
895 Ebp = (PUSHORT)MAKEULONG(Bp, Sp);
896
897 fprintf(hTrap,"\nCall Stack:\n");
898 fprintf(hTrap," Source Line Nearest\n");
899 fprintf(hTrap," EBP Address Module Obj# File Numbr Public Symbol\n");
900 fprintf(hTrap," ÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄ- ÄÄÄÄÄÄÄÄ ÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄ- ÄÄÄÄÄÄÄÄÄÄÄÄ-\n");
901
902 do
903 {
904 Size = 10;
905 rc = DosQueryMem((PVOID)(Ebp+2), &Size, &Attr);
906 if (rc != NO_ERROR || !(Attr & PAG_COMMIT) || (Size<10) )
907 {
908 fprintf(hTrap,"Invalid EBP: %8.8p\n",Ebp);
909 break;
910 }
911
912 if (fExceptionAddress)
913 RetAddr = ExceptionAddress;
914 else
915 RetAddr = (PUSHORT)(*((PULONG)(Ebp+2)));
916
917 if (RetAddr == (PUSHORT)0x00000053)
918 {
919 // For some reason there's a "return address" of 0x53 following
920 // EBP on the stack and we have to adjust EBP by 44 bytes to get
921 // at the real return address. This has something to do with
922 // thunking from 32bits to 16bits...
923 // Serious kludge, and it's probably dependent on versions of C(++)
924 // runtime or OS, but it works for now!
925 Ebp += 22;
926 RetAddr = (PUSHORT)(*((PULONG)(Ebp+2)));
927 }
928
929 // Get the (possibly) 16bit CS and IP
930 if (fExceptionAddress)
931 {
932 Cs = (USHORT)(((ULONG)ExceptionAddress) >> 16);
933 Ip = (USHORT)(ULONG)ExceptionAddress;
934 }
935 else
936 {
937 Cs = *(Ebp+2);
938 Ip = *(Ebp+1);
939 }
940
941 // if the return address points to the stack then it's really just
942 // a pointer to the return address (UGH!).
943 if ((USHORT)(((ULONG)RetAddr) >> 16) == Sp)
944 RetAddr = (PUSHORT)(*((PULONG)RetAddr));
945
946 if (Ip == 0 && *Ebp == 0)
947 {
948 // End of the stack so these are both shifted by 2 bytes:
949 Cs = *(Ebp+3);
950 Ip = *(Ebp+2);
951 }
952
953 // 16bit programs have on the stack:
954 // BP:IP:CS
955 // where CS may be thunked
956 //
957 // in dump swapped
958 // BP IP CS BP CS IP
959 // 4677 53B5 F7D0 7746 D0F7 B553
960 //
961 // 32bit programs have:
962 // EBP:EIP
963 // and you'd have something like this (with SP added) (not
964 // accurate values)
965 //
966 // in dump swapped
967 // EBP EIP EBP EIP
968 // 4677 2900 53B5 F7D0 0029 7746 D0F7 B553
969 //
970 // So the basic difference is that 32bit programs have a 32bit
971 // EBP and we can attempt to determine whether we have a 32bit
972 // EBP by checking to see if its 'selector' is the same as SP.
973 // Note that this technique limits us to checking stacks < 64K.
974 //
975 // Soooo, if IP (which maps into the same USHORT as the swapped
976 // stack page in EBP) doesn't point to the stack (i.e. it could
977 // be a 16bit IP) then see if CS is valid (as is or thunked).
978 //
979 // Note that there's the possibility of a 16bit return address
980 // that has an offset that's the same as SP so we'll think it's
981 // a 32bit return address and won't be able to successfully resolve
982 // its details.
983 if (Ip != Sp)
984 {
985 if (DOS16SIZESEG(Cs, &Size) == NO_ERROR)
986 {
987 RetAddr = (USHORT * _Seg16)MAKEULONG(Ip, Cs);
988 f32bit = FALSE;
989 }
990 else if (DOS16SIZESEG((Cs << 3) + 7, &Size) == NO_ERROR)
991 {
992 Cs = (Cs << 3) + 7;
993 RetAddr = (USHORT * _Seg16)MAKEULONG(Ip, Cs);
994 f32bit = FALSE;
995 }
996 else
997 f32bit = TRUE;
998 }
999 else
1000 f32bit = TRUE;
1001
1002
1003 if (fExceptionAddress)
1004 fprintf(hTrap," Trap ->");
1005 else
1006 fprintf(hTrap," %8.8p", Ebp);
1007
1008 if (f32bit)
1009 fprintf(hTrap," :%8.8p", RetAddr);
1010 else
1011 fprintf(hTrap," %04.04X:%04.04X", Cs, Ip);
1012
1013 if (Version[0] >= 20 && Version[1] >= 10)
1014 {
1015 // Make a 'tick' sound to let the user know we're still alive
1016 DosBeep(2000, 1);
1017
1018 Size = 10; /* Inserted by Kim Rasmussen 26/06 1996 to avoid error 87 when Size is 0 */
1019
1020 rc = DosQueryMem((PVOID)RetAddr, &Size, &Attr);
1021 if (rc != NO_ERROR || !(Attr & PAG_COMMIT))
1022 {
1023 fprintf(hTrap,"Invalid RetAddr: %8.8p\n",RetAddr);
1024 break; /* avoid infinite loops */
1025 } else {
1026 rc = DOSQUERYMODFROMEIP(&hMod, &ObjNum, sizeof(Name),
1027 Name, &Offset, (PVOID)RetAddr);
1028 if (rc == NO_ERROR && ObjNum != -1)
1029 {
1030 static char szJunk[_MAX_FNAME];
1031 static char szName[_MAX_FNAME];
1032 DosQueryModuleName(hMod, sizeof(Name), Name);
1033 _splitpath(Name, szJunk, szJunk, szName, szJunk);
1034 fprintf(hTrap," %-8s %04X", szName, ObjNum+1);
1035
1036 if (strlen(Name) > 3)
1037 {
1038 rc = GetLineNum(Name, ObjNum, Offset);
1039 /* if no codeview try with symbol files */
1040 if (rc != NO_ERROR)
1041 {
1042 strcpy(Name+strlen(Name)-3,"SYM");
1043 GetSymbol(Name,ObjNum,Offset);
1044 }
1045 }
1046 }
1047 else
1048 {
1049 fprintf(hTrap," *Unknown*");
1050 }
1051 }
1052 }
1053
1054 fprintf(hTrap,"\n");
1055
1056 Bp = *Ebp;
1057 if (Bp == 0 && (*Ebp+1) == 0)
1058 {
1059 fprintf(hTrap,"End of Call Stack\n");
1060 break;
1061 }
1062
1063 if (!fExceptionAddress)
1064 {
1065 LastEbp = Ebp;
1066#if 0
1067 Ebp = (PUSHORT)MAKEULONG(Bp, Sp);
1068#else /* Inserted by Kim Rasmussen 26/06 1996 to allow big stacks */
1069 if (f32bit)
1070 Ebp = (PUSHORT)*(PULONG)LastEbp;
1071 else
1072 Ebp = (PUSHORT)MAKEULONG(Bp, Sp);
1073#endif
1074 if (f32bit) {
1075 print_vars((ULONG)Ebp);
1076 } /* endif */
1077
1078 if (Ebp < LastEbp)
1079 {
1080 fprintf(hTrap,"Lost Stack chain - new EBP below previous\n");
1081 break;
1082 }
1083 }
1084 else
1085 fExceptionAddress = FALSE;
1086
1087 Size = 4;
1088 rc = DosQueryMem((PVOID)Ebp, &Size, &Attr);
1089 if ((rc != NO_ERROR)||(Size<4))
1090 {
1091 fprintf(hTrap,"Lost Stack chain - invalid EBP: %8.8p\n", Ebp);
1092 break;
1093 }
1094 } while (TRUE);
1095
1096 fprintf(hTrap,"\n");
1097}
1098
1099void GetSymbol(CHAR * SymFileName, ULONG Object,ULONG TrapOffset)
1100{
1101 static FILE * SymFile;
1102 static MAPDEF MapDef;
1103 static SEGDEF SegDef;
1104 static SEGDEF *pSegDef;
1105 static SYMDEF32 SymDef32;
1106 static SYMDEF16 SymDef16;
1107 static char Buffer[256];
1108 static int SegNum,SymNum,LastVal;
1109 static unsigned long int SegOffset,SymOffset,SymPtrOffset;
1110 SymFile=fopen(SymFileName,"rb");
1111 if (SymFile==0) {
1112 /*fprintf(hTrap,"Could not open symbol file %s\n",SymFileName);*/
1113 return;
1114 } /* endif */
1115 fread(&MapDef,sizeof(MAPDEF),1,SymFile);
1116 SegOffset= SEGDEFOFFSET(MapDef);
1117 for (SegNum=0;SegNum<MapDef.cSegs;SegNum++) {
1118 /* printf("Scanning segment #%d Offset %4.4hX\n",SegNum+1,SegOffset); */
1119 if (fseek(SymFile,SegOffset,SEEK_SET)) {
1120 fprintf(hTrap,"Seek error ");
1121 return;
1122 }
1123 fread(&SegDef,sizeof(SEGDEF),1,SymFile);
1124 if (SegNum==Object) {
1125 Buffer[0]=0x00;
1126 LastVal=0;
1127 for (SymNum=0;SymNum<SegDef.cSymbols;SymNum++) {
1128 SymPtrOffset=SYMDEFOFFSET(SegOffset,SegDef,SymNum);
1129 fseek(SymFile,SymPtrOffset,SEEK_SET);
1130 fread(&SymOffset,sizeof(unsigned short int),1,SymFile);
1131 fseek(SymFile,SymOffset+SegOffset,SEEK_SET);
1132 if (SegDef.bFlags&0x01) {
1133 fread(&SymDef32,sizeof(SYMDEF32),1,SymFile);
1134 if (SymDef32.wSymVal>TrapOffset) {
1135 fprintf(hTrap,"between %s + %X ",Buffer,TrapOffset-LastVal);
1136 }
1137 LastVal=SymDef32.wSymVal;
1138 Buffer[0]= SymDef32.achSymName[0];
1139 fread(&Buffer[1],1,SymDef32.cbSymName,SymFile);
1140 Buffer[SymDef32.cbSymName]=0x00;
1141 if (SymDef32.wSymVal>TrapOffset) {
1142 fprintf(hTrap,"and %s - %X\n",Buffer,LastVal-TrapOffset);
1143 break;
1144 }
1145 /*printf("32 Bit Symbol <%s> Address %p\n",Buffer,SymDef32.wSymVal);*/
1146 } else {
1147 fread(&SymDef16,sizeof(SYMDEF16),1,SymFile);
1148 if (SymDef16.wSymVal>TrapOffset) {
1149 fprintf(hTrap,"between %s + %X ",Buffer,TrapOffset-LastVal);
1150 }
1151 LastVal=SymDef16.wSymVal;
1152 Buffer[0]=SymDef16.achSymName[0];
1153 fread(&Buffer[1],1,SymDef16.cbSymName,SymFile);
1154 Buffer[SymDef16.cbSymName]=0x00;
1155 if (SymDef16.wSymVal>TrapOffset) {
1156 fprintf(hTrap,"and %s - %X\n",Buffer,LastVal-TrapOffset);
1157 break;
1158 }
1159 /*printf("16 Bit Symbol <%s> Address %p\n",Buffer,SymDef16.wSymVal);*/
1160 } /* endif */
1161 }
1162 break;
1163 } /* endif */
1164 SegOffset=NEXTSEGDEFOFFSET(SegDef);
1165 } /* endwhile */
1166 fclose(SymFile);
1167}
1168
1169#include <newexe.h>
1170#define FOR_EXEHDR 1 /* avoid define conflicts between newexe.h and exe386.h */
1171#ifndef DWORD
1172#define DWORD long int
1173#endif
1174#ifndef WORD
1175#define WORD short int
1176#endif
1177#include <exe386.h>
1178#include <fcntl.h>
1179#include <sys\stat.h>
1180#include <share.h>
1181#include <io.h>
1182/* ------------------------------------------------------------------ */
1183/* Last 8 bytes of 16:16 file when CODEVIEW debugging info is present */
1184#pragma pack(1)
1185 struct _eodbug
1186 {
1187 unsigned short dbug; /* 'NB' signature */
1188 unsigned short ver; /* version */
1189 unsigned long dfaBase; /* size of codeview info */
1190 } eodbug;
1191
1192#define DBUGSIG 0x424E
1193#define SSTMODULES 0x0101
1194#define SSTPUBLICS 0x0102
1195#define SSTTYPES 0x0103
1196#define SSTSYMBOLS 0x0104
1197#define SSTSRCLINES 0x0105
1198#define SSTLIBRARIES 0x0106
1199#define SSTSRCLINES2 0x0109
1200#define SSTSRCLINES32 0x010B
1201
1202 struct _base
1203 {
1204 unsigned short dbug; /* 'NB' signature */
1205 unsigned short ver; /* version */
1206 unsigned long lfoDir; /* file offset to dir entries */
1207 } base;
1208
1209 struct ssDir
1210 {
1211 unsigned short sst; /* SubSection Type */
1212 unsigned short modindex; /* Module index number */
1213 unsigned long lfoStart; /* Start of section */
1214 unsigned short cb; /* Size of section */
1215 } ;
1216
1217 struct ssDir32
1218 {
1219 unsigned short sst; /* SubSection Type */
1220 unsigned short modindex; /* Module index number */
1221 unsigned long lfoStart; /* Start of section */
1222 unsigned long cb; /* Size of section */
1223 } ;
1224
1225 struct ssModule
1226 {
1227 unsigned short csBase; /* code segment base */
1228 unsigned short csOff; /* code segment offset */
1229 unsigned short csLen; /* code segment length */
1230 unsigned short ovrNum; /* overlay number */
1231 unsigned short indxSS; /* Index into sstLib or 0 */
1232 unsigned short reserved;
1233 char csize; /* size of prefix string */
1234 } ssmod;
1235
1236 struct ssModule32
1237 {
1238 unsigned short csBase; /* code segment base */
1239 unsigned long csOff; /* code segment offset */
1240 unsigned long csLen; /* code segment length */
1241 unsigned long ovrNum; /* overlay number */
1242 unsigned short indxSS; /* Index into sstLib or 0 */
1243 unsigned long reserved;
1244 char csize; /* size of prefix string */
1245 } ssmod32;
1246
1247 struct ssPublic
1248 {
1249 unsigned short offset;
1250 unsigned short segment;
1251 unsigned short type;
1252 char csize;
1253 } sspub;
1254
1255 struct ssPublic32
1256 {
1257 unsigned long offset;
1258 unsigned short segment;
1259 unsigned short type;
1260 char csize;
1261 } sspub32;
1262
1263typedef struct _SSLINEENTRY32 {
1264 unsigned short LineNum;
1265 unsigned short FileNum;
1266 unsigned long Offset;
1267} SSLINEENTRY32;
1268typedef struct _FIRSTLINEENTRY32 {
1269 unsigned short LineNum;
1270 unsigned char entry_type;
1271 unsigned char reserved;
1272 unsigned short numlines;
1273 unsigned short segnum;
1274} FIRSTLINEENTRY32;
1275
1276typedef struct _SSFILENUM32 {
1277 unsigned long first_displayable; /* Not used */
1278 unsigned long number_displayable; /* Not used */
1279 unsigned long file_count; /* number of source files */
1280} SSFILENUM32;
1281
1282 struct DbugRec { /* debug info struct ure used in linked * list */
1283 struct DbugRec far *pnext; /* next node *//* 013 */
1284 char far *SourceFile; /* source file name *013 */
1285 unsigned short TypeOfProgram; /* dll or exe *014* */
1286 unsigned short LineNumber; /* line number in source file */
1287 unsigned short OffSet; /* offset into loaded module */
1288 unsigned short Selector; /* code segment 014 */
1289 unsigned short OpCode; /* Opcode replaced with BreakPt */
1290 unsigned long Count; /* count over Break Point */
1291};
1292
1293typedef struct DbugRec DBUG, far * DBUGPTR; /* 013 */
1294char szNrPub[128];
1295char szNrLine[128];
1296char szNrFile[128];
1297 struct new_seg *pseg;
1298 struct o32_obj *pobj; /* Flat .EXE object table entry */
1299 struct ssDir *pDirTab;
1300 struct ssDir32 *pDirTab32;
1301unsigned char *pEntTab;
1302unsigned long lfaBase;
1303#pragma pack()
1304/* ------------------------------------------------------------------ */
1305
1306APIRET GetLineNum(CHAR * FileName, ULONG Object,ULONG TrapOffset) {
1307 APIRET rc;
1308 int ModuleFile;
1309 static struct exe_hdr old;
1310 static struct new_exe new1;
1311 static struct e32_exe e32;
1312 strcpy(szNrPub," N/A ");
1313 strcpy(szNrLine," N/A ");
1314 strcpy(szNrFile," ");
1315 ModuleFile =sopen(FileName,O_RDONLY|O_BINARY,SH_DENYNO);
1316 if (ModuleFile!=-1) {
1317 /* Read old Exe header */
1318 if (read( ModuleFile ,(void *)&old,64)==-1L) {
1319 fprintf(hTrap,"Could Not Read old exe header %d\n",errno);
1320 close(ModuleFile);
1321 return 2;
1322 }
1323 /* Seek to new Exe header */
1324 if (lseek(ModuleFile,(long)E_LFANEW(old),SEEK_SET)==-1L) {
1325 fprintf(hTrap,"Could Not seek to new exe header %d\n",errno);
1326 close(ModuleFile);
1327 return 3;
1328 }
1329 if (read( ModuleFile ,(void *)&new1,64)==-1L) {
1330 fprintf(hTrap,"Could Not read new exe header %d\n",errno);
1331 close(ModuleFile);
1332 return 4;
1333 }
1334 /* Check EXE signature */
1335 if (NE_MAGIC(new1)==E32MAGIC) {
1336 /* Flat 32 executable */
1337 rc=Read32PmDebug(ModuleFile,Object+1,TrapOffset,FileName);
1338 if (rc==0) {
1339 fprintf(hTrap,"%s",szNrFile);
1340 fprintf(hTrap,"%s",szNrLine);
1341 fprintf(hTrap,"%s",szNrPub);
1342 } /* endif */
1343 close(ModuleFile);
1344 /* rc !=0 try with DBG file */
1345 if (rc!=0) {
1346 strcpy(FileName+strlen(FileName)-3,"DBG"); /* Build DBG File name */
1347 ModuleFile =sopen(FileName,O_RDONLY|O_BINARY,SH_DENYNO);
1348 if (ModuleFile!=-1) {
1349 rc=Read32PmDebug(ModuleFile,Object+1,TrapOffset,FileName);
1350 if (rc==0) {
1351 fprintf(hTrap,"%s",szNrFile);
1352 fprintf(hTrap,"%s",szNrLine);
1353 fprintf(hTrap,"%s",szNrPub);
1354 } /* endif */
1355 close(ModuleFile);
1356 }
1357 } /* endif */
1358 return rc;
1359 } else {
1360 if (NE_MAGIC(new1)==NEMAGIC) {
1361 /* 16:16 executable */
1362 if ((pseg = ( struct new_seg *) calloc(NE_CSEG(new1),sizeof( struct new_seg)))==NULL) {
1363 fprintf(hTrap,"Out of memory!");
1364 close(ModuleFile);
1365 return -1;
1366 }
1367 if (lseek(ModuleFile,E_LFANEW(old)+NE_SEGTAB(new1),SEEK_SET)==-1L) {
1368 fprintf(hTrap,"Error %u seeking segment table in %s\n",errno,FileName);
1369 free(pseg);
1370 close(ModuleFile);
1371 return 9;
1372 }
1373
1374 if (read(ModuleFile,(void *)pseg,NE_CSEG(new1)*sizeof( struct new_seg))==-1) {
1375 fprintf(hTrap,"Error %u reading segment table from %s\n",errno,FileName);
1376 free(pseg);
1377 close(ModuleFile);
1378 return 10;
1379 }
1380 rc=Read16CodeView(ModuleFile,Object+1,TrapOffset,FileName);
1381 if (rc==0) {
1382 fprintf(hTrap,"%s",szNrFile);
1383 fprintf(hTrap,"%s",szNrLine);
1384 fprintf(hTrap,"%s",szNrPub);
1385 } /* endif */
1386 free(pseg);
1387 close(ModuleFile);
1388 /* rc !=0 try with DBG file */
1389 if (rc!=0) {
1390 strcpy(FileName+strlen(FileName)-3,"DBG"); /* Build DBG File name */
1391 ModuleFile =sopen(FileName,O_RDONLY|O_BINARY,SH_DENYNO);
1392 if (ModuleFile!=-1) {
1393 rc=Read16CodeView(ModuleFile,Object+1,TrapOffset,FileName);
1394 if (rc==0) {
1395 fprintf(hTrap,"%s",szNrFile);
1396 fprintf(hTrap,"%s",szNrLine);
1397 fprintf(hTrap,"%s",szNrPub);
1398 } /* endif */
1399 close(ModuleFile);
1400 }
1401 } /* endif */
1402 return rc;
1403
1404 } else {
1405 /* Unknown executable */
1406 fprintf(hTrap,"Could Not find exe signature");
1407 close(ModuleFile);
1408 return 11;
1409 }
1410 }
1411 /* Read new Exe header */
1412 } else {
1413 fprintf(hTrap,"Could Not open Module File %d",errno);
1414 return 1;
1415 } /* endif */
1416 return 0;
1417}
1418char fname[128],ModName[80];
1419char ename[128],dummy[128];
1420
1421int Read16CodeView(int fh,int TrapSeg,int TrapOff,CHAR * FileName) {
1422 static unsigned short int offset,NrPublic,NrLine,NrEntry,numdir,namelen,numlines,line;
1423 static int ModIndex;
1424 static int bytesread,i,j;
1425 ModIndex=0;
1426 /* See if any CODEVIEW info */
1427 if (lseek(fh,-8L,SEEK_END)==-1) {
1428 fprintf(hTrap,"Error %u seeking CodeView table in %s\n",errno,FileName);
1429 return(18);
1430 }
1431
1432 if (read(fh,(void *)&eodbug,8)==-1) {
1433 fprintf(hTrap,"Error %u reading debug info from %s\n",errno,FileName);
1434 return(19);
1435 }
1436 if (eodbug.dbug!=DBUGSIG) {
1437 /* fprintf(hTrap,"\nNo CodeView information stored.\n"); */
1438 return(100);
1439 }
1440
1441 if ((lfaBase=lseek(fh,-eodbug.dfaBase,SEEK_END))==-1L) {
1442 fprintf(hTrap,"Error %u seeking base codeview data in %s\n",errno,FileName);
1443 return(20);
1444 }
1445
1446 if (read(fh,(void *)&base,8)==-1) {
1447 fprintf(hTrap,"Error %u reading base codeview data in %s\n",errno,FileName);
1448 return(21);
1449 }
1450
1451 if (lseek(fh,base.lfoDir-8,SEEK_CUR)==-1) {
1452 fprintf(hTrap,"Error %u seeking dir codeview data in %s\n",errno,FileName);
1453 return(22);
1454 }
1455
1456 if (read(fh,(void *)&numdir,2)==-1) {
1457 fprintf(hTrap,"Error %u reading dir codeview data in %s\n",errno,FileName);
1458 return(23);
1459 }
1460
1461 /* Read dir table into buffer */
1462 if (( pDirTab = ( struct ssDir *) calloc(numdir,sizeof( struct ssDir)))==NULL) {
1463 fprintf(hTrap,"Out of memory!");
1464 return(-1);
1465 }
1466
1467 if (read(fh,(void *)pDirTab,numdir*sizeof( struct ssDir))==-1) {
1468 fprintf(hTrap,"Error %u reading codeview dir table from %s\n",errno,FileName);
1469 free(pDirTab);
1470 return(24);
1471 }
1472
1473 i=0;
1474 while (i<numdir) {
1475 if (pDirTab[i].sst!=SSTMODULES) {
1476 i++;
1477 continue;
1478 }
1479 NrPublic=0x0;
1480 NrLine=0x0;
1481 /* point to subsection */
1482 lseek(fh, pDirTab[i].lfoStart + lfaBase, SEEK_SET);
1483 read(fh,(void *)&ssmod.csBase,sizeof(ssmod));
1484 read(fh,(void *)ModName,(unsigned)ssmod.csize);
1485 ModIndex=pDirTab[i].modindex;
1486 ModName[ssmod.csize]='\0';
1487 i++;
1488 while (pDirTab[i].modindex ==ModIndex && i<numdir) {
1489 /* point to subsection */
1490 lseek(fh, pDirTab[i].lfoStart + lfaBase, SEEK_SET);
1491 switch(pDirTab[i].sst) {
1492 case SSTPUBLICS:
1493 bytesread=0;
1494 while (bytesread < pDirTab[i].cb) {
1495 bytesread += read(fh,(void *)&sspub.offset,sizeof(sspub));
1496 bytesread += read(fh,(void *)ename,(unsigned)sspub.csize);
1497 ename[sspub.csize]='\0';
1498 if ((sspub.segment==TrapSeg) &&
1499 (sspub.offset<=TrapOff) &&
1500 (sspub.offset>=NrPublic)) {
1501 NrPublic=sspub.offset;
1502 sprintf(szNrPub,"%s %s (%s) %04hX:%04hX\n",
1503 (sspub.type==1) ? " Abs" : " ",ename,ModName,
1504 sspub.segment, sspub.offset
1505 );
1506 }
1507 }
1508 break;
1509
1510 case SSTSRCLINES2:
1511 case SSTSRCLINES:
1512 if (TrapSeg!=ssmod.csBase) break;
1513 namelen=0;
1514 read(fh,(void *)&namelen,1);
1515 read(fh,(void *)ename,namelen);
1516 ename[namelen]='\0';
1517 /* skip 2 zero bytes */
1518 if (pDirTab[i].sst==SSTSRCLINES2) read(fh,(void *)&numlines,2);
1519 read(fh,(void *)&numlines,2);
1520 for (j=0;j<numlines;j++) {
1521 read(fh,(void *)&line,2);
1522 read(fh,(void *)&offset,2);
1523 if (offset<=TrapOff && offset>=NrLine) {
1524 NrLine=offset;
1525 sprintf(szNrLine,"% 6hu", line);
1526 sprintf(szNrFile,"% 13.13s ", ename);
1527 /*sprintf(szNrLine,"%04hX:%04hX line #%hu (%s) (%s)\n",
1528 ssmod.csBase,offset,line,ModName,ename); */
1529 }
1530 }
1531 break;
1532 } /* end switch */
1533 i++;
1534 } /* end while modindex */
1535 } /* End While i < numdir */
1536 free(pDirTab);
1537 return(0);
1538}
1539
1540#define MAX_USERDEFS 150
1541#define MAX_POINTERS 150
1542
1543USHORT userdef_count;
1544USHORT pointer_count;
1545
1546struct one_userdef_rec {
1547 USHORT idx;
1548 USHORT type_index;
1549 BYTE name[33];
1550} one_userdef[MAX_USERDEFS];
1551
1552struct one_pointer_rec {
1553 USHORT idx;
1554 USHORT type_index;
1555 BYTE type_qual;
1556 BYTE name[33];
1557} one_pointer[MAX_POINTERS];
1558
1559int Read32PmDebug(int fh,int TrapSeg,int TrapOff,CHAR * FileName) {
1560 static unsigned int CurrSymSeg, NrSymbol,offset,NrPublic,NrFile,NrLine,NrEntry,numdir,namelen,numlines,line;
1561 static int ModIndex;
1562 static int bytesread,i,j;
1563 static int pOffset;
1564 static SSLINEENTRY32 LineEntry;
1565 static SSFILENUM32 FileInfo;
1566 static FIRSTLINEENTRY32 FirstLine;
1567 static BYTE dump_vars = FALSE;
1568 static USHORT idx;
1569 static BOOL read_types;
1570 static LONG lSize;
1571 static BOOL is_new_debug;
1572
1573 ModIndex=0;
1574 /* See if any CODEVIEW info */
1575 if (lseek(fh,-8L,SEEK_END)==-1) {
1576 fprintf(hTrap,"Error %u seeking CodeView table in %s\n",errno,FileName);
1577 return(18);
1578 }
1579
1580 if (read(fh,(void *)&eodbug,8)==-1) {
1581 fprintf(hTrap,"Error %u reading debug info from %s\n",errno,FileName);
1582 return(19);
1583 }
1584 if (eodbug.dbug!=DBUGSIG) {
1585 /*fprintf(hTrap,"\nNo CodeView information stored.\n");*/
1586 return(100);
1587 }
1588
1589 if ((lfaBase=lseek(fh,-eodbug.dfaBase,SEEK_END))==-1L) {
1590 fprintf(hTrap,"Error %u seeking base codeview data in %s\n",errno,FileName);
1591 return(20);
1592 }
1593
1594 if (read(fh,(void *)&base,8)==-1) {
1595 fprintf(hTrap,"Error %u reading base codeview data in %s\n",errno,FileName);
1596 return(21);
1597 }
1598
1599 if (lseek(fh,base.lfoDir-8+4,SEEK_CUR)==-1) {
1600 fprintf(hTrap,"Error %u seeking dir codeview data in %s\n",errno,FileName);
1601 return(22);
1602 }
1603
1604 if (read(fh,(void *)&numdir,4)==-1) {
1605 fprintf(hTrap,"Error %u reading dir codeview data in %s\n",errno,FileName);
1606 return(23);
1607 }
1608
1609 /* Read dir table into buffer */
1610 if (( pDirTab32 = ( struct ssDir32 *) calloc(numdir,sizeof( struct ssDir32)))==NULL) {
1611 fprintf(hTrap,"Out of memory!");
1612 return(-1);
1613 }
1614
1615 if (read(fh,(void *)pDirTab32,numdir*sizeof( struct ssDir32))==-1) {
1616 fprintf(hTrap,"Error %u reading codeview dir table from %s\n",errno,FileName);
1617 free(pDirTab32);
1618 return(24);
1619 }
1620
1621 i=0;
1622 while (i<numdir) {
1623 if ( pDirTab32[i].sst !=SSTMODULES) {
1624 i++;
1625 continue;
1626 }
1627 NrPublic=0x0;
1628 NrSymbol=0;
1629 NrLine=0x0;
1630 NrFile=0x0;
1631 CurrSymSeg = 0;
1632 /* point to subsection */
1633 lseek(fh, pDirTab32[i].lfoStart + lfaBase, SEEK_SET);
1634 read(fh,(void *)&ssmod32.csBase,sizeof(ssmod32));
1635 read(fh,(void *)ModName,(unsigned)ssmod32.csize);
1636 ModIndex=pDirTab32[i].modindex;
1637 ModName[ssmod32.csize]='\0';
1638 i++;
1639
1640 read_types = FALSE;
1641
1642 while (pDirTab32[i].modindex ==ModIndex && i<numdir) {
1643 /* point to subsection */
1644 lseek(fh, pDirTab32[i].lfoStart + lfaBase, SEEK_SET);
1645 switch(pDirTab32[i].sst) {
1646 case SSTPUBLICS:
1647 bytesread=0;
1648 while (bytesread < pDirTab32[i].cb) {
1649 bytesread += read(fh,(void *)&sspub32.offset,sizeof(sspub32));
1650 bytesread += read(fh,(void *)ename,(unsigned)sspub32.csize);
1651 ename[sspub32.csize]='\0';
1652 if ((sspub32.segment==TrapSeg) &&
1653 (sspub32.offset<=TrapOff) &&
1654 (sspub32.offset>=NrPublic)) {
1655 NrPublic = pubfunc_ofs = sspub32.offset;
1656 read_types = TRUE;
1657 sprintf(szNrPub,"%s %s (%s) %04X:%08lu\n",
1658 (sspub32.type==1) ? " Abs" : " ",ename,ModName,
1659 sspub32.segment, sspub32.offset
1660 );
1661 }
1662 }
1663 break;
1664
1665 /* Read symbols, so we can dump the variables on the stack */
1666 case SSTSYMBOLS:
1667 if (TrapSeg!=ssmod32.csBase) break;
1668
1669 bytesread=0;
1670 while (bytesread < pDirTab32[i].cb) {
1671 static USHORT usLength;
1672 static BYTE b1, b2;
1673 static BYTE bType, *ptr;
1674 static ULONG ofs;
1675 static ULONG last_addr = 0;
1676 static BYTE str[256];
1677 static struct symseg_rec symseg;
1678 static struct symauto_rec symauto;
1679 static struct symproc_rec symproc;
1680
1681 /* Read the length of this subentry */
1682 bytesread += read(fh, &b1, 1);
1683 if (b1 & 0x80) {
1684 bytesread += read(fh, &b2, 1);
1685 usLength = ((b1 & 0x7F) << 8) + b2;
1686 }
1687 else
1688 usLength = b1;
1689
1690 ofs = tell(fh);
1691
1692 bytesread += read(fh, &bType, 1);
1693
1694 switch(bType) {
1695 case SYM_CHANGESEG:
1696 read(fh, &symseg, sizeof(symseg));
1697 CurrSymSeg = symseg.seg_no;
1698 break;
1699
1700 case SYM_PROC:
1701 case SYM_CPPPROC:
1702 read(fh, &symproc, sizeof(symproc));
1703 read(fh, str, symproc.name_len);
1704 str[symproc.name_len] = 0;
1705
1706 if ((CurrSymSeg == TrapSeg) &&
1707 (symproc.offset<=TrapOff) &&
1708 (symproc.offset>=NrSymbol)) {
1709
1710 dump_vars = TRUE;
1711 var_ofs = 0;
1712 NrSymbol = symproc.offset;
1713 func_ofs = symproc.offset;
1714
1715 strcpy(func_name, str);
1716 }
1717 else {
1718 dump_vars = FALSE;
1719 }
1720 break;
1721
1722 case SYM_AUTO:
1723 if (!dump_vars)
1724 break;
1725
1726 read(fh, &symauto, sizeof(symauto));
1727 read(fh, str, symauto.name_len);
1728 str[symauto.name_len] = 0;
1729
1730 strcpy(autovar_def[var_ofs].name, str);
1731 autovar_def[var_ofs].stack_offset = symauto.stack_offset;
1732 autovar_def[var_ofs].type_idx = symauto.type_idx;
1733 var_ofs++;
1734 break;
1735
1736 }
1737
1738 bytesread += usLength;
1739
1740 lseek(fh, ofs+usLength, SEEK_SET);
1741 }
1742 break;
1743
1744 case SSTTYPES:
1745// if (ModIndex != TrapSeg)
1746 if (!read_types)
1747 break;
1748
1749 bytesread=0;
1750 idx = 0x200;
1751 userdef_count = 0;
1752 pointer_count = 0;
1753 while (bytesread < pDirTab32[i].cb) {
1754 static struct type_rec type;
1755 static struct type_userdefrec udef;
1756 static struct type_pointerrec point;
1757 static struct type_funcrec func;
1758 static struct type_structrec struc;
1759 static struct type_list1 list1;
1760 static struct type_list2 list2;
1761 static struct type_list2_1 list2_1;
1762 static ULONG ofs;
1763 static BYTE str[256], b1, b2;
1764 static USHORT n;
1765
1766 /* Read the length of this subentry */
1767 ofs = tell(fh);
1768
1769 read(fh, &type, sizeof(type));
1770 bytesread += sizeof(type);
1771
1772 switch(type.type) {
1773 case TYPE_USERDEF:
1774 if (userdef_count > MAX_USERDEFS)
1775 break;
1776
1777 read(fh, &udef, sizeof(udef));
1778 read(fh, str, udef.name_len);
1779 str[udef.name_len] = 0;
1780
1781 // Insert userdef in table
1782 one_userdef[userdef_count].idx = idx;
1783 one_userdef[userdef_count].type_index = udef.type_index;
1784 memcpy(one_userdef[userdef_count].name, str, min(udef.name_len+1, 32));
1785 one_userdef[userdef_count].name[32] = 0;
1786 userdef_count++;
1787 break;
1788
1789 case TYPE_POINTER:
1790 if (pointer_count > MAX_POINTERS)
1791 break;
1792
1793 read(fh, &point, sizeof(point));
1794 read(fh, str, point.name_len);
1795 str[point.name_len] = 0;
1796
1797 // Insert userdef in table
1798 one_pointer[pointer_count].idx = idx;
1799 one_pointer[pointer_count].type_index = point.type_index;
1800 memcpy(one_pointer[pointer_count].name, str, min(point.name_len+1, 32));
1801 one_pointer[pointer_count].name[32] = 0;
1802 one_pointer[pointer_count].type_qual = type.type_qual;
1803 pointer_count++;
1804 break;
1805 }
1806
1807 ++idx;
1808
1809 bytesread += type.length;
1810
1811 lseek(fh, ofs+type.length+2, SEEK_SET);
1812 }
1813 break;
1814
1815 case SSTSRCLINES32:
1816 if (TrapSeg!=ssmod32.csBase) break;
1817
1818 /* read first line */
1819 do {
1820 read(fh,(void *)&FirstLine,sizeof(FirstLine));
1821
1822 if (FirstLine.LineNum!=0) {
1823 fprintf(hTrap,"Missing Line table information\n");
1824 break;
1825 } /* endif */
1826 numlines= FirstLine.numlines;
1827 /* Other type of data skip 4 more bytes */
1828 if (FirstLine.entry_type < 4) {
1829 read(fh, (void *)&lSize, 4);
1830 if (FirstLine.entry_type == 3)
1831 lseek(fh,lSize,SEEK_CUR);
1832 }
1833 } while(FirstLine.entry_type == 3);
1834
1835 for (j=0;j<numlines;j++) {
1836 switch (FirstLine.entry_type) {
1837 case 0:
1838 read(fh,(void *)&LineEntry,sizeof(LineEntry));
1839 /* Changed by Kim Rasmussen 26/06 1996 to ignore linenumber 0 */
1840 /* if (LineEntry.Offset+ssmod32.csOff<=TrapOff && LineEntry.Offset+ssmod32.csOff>=NrLine) { */
1841 if (LineEntry.LineNum && LineEntry.Offset+ssmod32.csOff<=TrapOff && LineEntry.Offset+ssmod32.csOff>=NrLine) {
1842 NrLine=LineEntry.Offset;
1843 NrFile=LineEntry.FileNum;
1844 /*pOffset =sprintf(szNrLine,"%04X:%08X line #%hu ",
1845 ssmod32.csBase,LineEntry.Offset,
1846 LineEntry.LineNum);*/
1847 sprintf(szNrLine,"% 6hu", LineEntry.LineNum);
1848 }
1849 break;
1850
1851 case 1:
1852 lseek(fh, sizeof(struct linlist_rec), SEEK_CUR);
1853 break;
1854
1855 case 2:
1856 lseek(fh, sizeof(struct linsourcelist_rec), SEEK_CUR);
1857 break;
1858
1859 case 3:
1860 lseek(fh, sizeof(struct filenam_rec), SEEK_CUR);
1861 break;
1862
1863 case 4:
1864 lseek(fh, sizeof(struct pathtab_rec), SEEK_CUR);
1865 break;
1866
1867 }
1868 }
1869 if (NrFile!=0) {
1870 read(fh,(void *)&FileInfo,sizeof(FileInfo));
1871 namelen=0;
1872 for (j=1;j<=FileInfo.file_count;j++) {
1873 namelen=0;
1874 read(fh,(void *)&namelen,1);
1875 read(fh,(void *)ename,namelen);
1876 if (j==NrFile) break;
1877 }
1878 ename[namelen]='\0';
1879 /* pOffset=sprintf(szNrLine+pOffset," (%s) (%s)\n",ename,ModName);*/
1880 sprintf(szNrFile,"% 13.13s ",ename);
1881 } else {
1882 /* strcat(szNrLine,"\n"); avoid new line for empty name fill */
1883 strcpy(szNrFile," ");
1884 } /* endif */
1885 break;
1886 } /* end switch */
1887
1888 i++;
1889 } /* end while modindex */
1890 } /* End While i < numdir */
1891 free(pDirTab32);
1892 return(0);
1893}
1894
1895BYTE *var_value(void *varptr, BYTE type)
1896{
1897 static BYTE value[128];
1898 APIRET rc;
1899
1900 strcpy(value, "Unknown");
1901
1902 if (type == 0)
1903 sprintf(value, "%hhd", *(signed char *)varptr);
1904 else if (type == 1)
1905 sprintf(value, "%hd", *(signed short *)varptr);
1906 else if (type == 2)
1907 sprintf(value, "%ld", *(signed long *)varptr);
1908 else if (type == 4)
1909 sprintf(value, "%hu", *(BYTE *)varptr);
1910 else if (type == 5)
1911 sprintf(value, "%hu", *(USHORT *)varptr);
1912 else if (type == 6)
1913 sprintf(value, "%lu", *(ULONG *)varptr);
1914 else if (type == 8)
1915 sprintf(value, "%f", *(float *)varptr);
1916 else if (type == 9)
1917 sprintf(value, "%f", *(double *)varptr);
1918 else if (type == 10)
1919 sprintf(value, "%Lf", *(long double *)varptr);
1920 else if (type == 16)
1921 sprintf(value, "%s", *(char *)varptr ? "TRUE" : "FALSE");
1922 else if (type == 17)
1923 sprintf(value, "%s", *(short *)varptr ? "TRUE" : "FALSE");
1924 else if (type == 18)
1925 sprintf(value, "%s", *(long *)varptr ? "TRUE" : "FALSE");
1926 else if (type == 20)
1927 sprintf(value, "%c", *(char *)varptr);
1928 else if (type == 21)
1929 sprintf(value, "%hd", *(short *)varptr);
1930 else if (type == 22)
1931 sprintf(value, "%lc", *(long *)varptr);
1932 else if (type == 23)
1933 sprintf(value, "void");
1934 else if (type >= 32) {
1935 ULONG Size,Attr;
1936 Size=1;
1937 rc=DosQueryMem((void*)*(ULONG *)varptr,&Size,&Attr);
1938 if (rc) {
1939 sprintf(value, "0x%p invalid", *(ULONG *)varptr);
1940 } else {
1941 sprintf(value, "0x%p", *(ULONG *)varptr);
1942 if (Attr&PAG_FREE) {
1943 strcat(value," unallocated memory");
1944 } else {
1945 if ((Attr&PAG_COMMIT)==0x0U) {
1946 strcat(value," uncommited");
1947 } /* endif */
1948 if ((Attr&PAG_WRITE)==0x0U) {
1949 strcat(value," unwritable");
1950 } /* endif */
1951 if ((Attr&PAG_READ)==0x0U) {
1952 strcat(value," unreadable");
1953 } /* endif */
1954 } /* endif */
1955 } /* endif */
1956 }
1957
1958 return value;
1959}
1960
1961/* Search the table of userdef's - return TRUE if found */
1962BOOL search_userdefs(ULONG stackofs, USHORT var_no)
1963{
1964 USHORT pos;
1965
1966 for(pos = 0; pos < userdef_count && one_userdef[pos].idx != autovar_def[var_no].type_idx; pos++);
1967
1968 if (pos < userdef_count) {
1969 if (one_userdef[pos].type_index >= 0x80 && one_userdef[pos].type_index <= 0xDA) {
1970 fprintf(hTrap, "%- 6d %- 20.20s %- 33.33s %s\n",
1971 autovar_def[var_no].stack_offset,
1972 autovar_def[var_no].name,
1973 one_userdef[pos].name,
1974 var_value((void *)(stackofs+autovar_def[var_no].stack_offset),
1975 one_userdef[pos].type_index-0x80));
1976 return TRUE;
1977 }
1978 else /* If the result isn't a simple type, let's act as we didn't find it */
1979 return FALSE;
1980 }
1981
1982 return FALSE;
1983}
1984
1985BOOL search_pointers(ULONG stackofs, USHORT var_no)
1986{
1987 USHORT pos, upos;
1988 static BYTE str[35];
1989 BYTE type_index;
1990
1991 for(pos = 0; pos < pointer_count && one_pointer[pos].idx != autovar_def[var_no].type_idx; pos++);
1992
1993 if (pos < pointer_count) {
1994 if (one_pointer[pos].type_index >= 0x80 && one_pointer[pos].type_index <= 0xDA) {
1995 strcpy(str, type_name[one_pointer[pos].type_index-0x80]);
1996 strcat(str, " *");
1997 fprintf(hTrap, "%- 6d %- 20.20s %- 33.33s %s\n",
1998 autovar_def[var_no].stack_offset,
1999 autovar_def[var_no].name,
2000 str,
2001 var_value((void *)(stackofs+autovar_def[var_no].stack_offset), 32));
2002 return TRUE;
2003 }
2004 else { /* If the result isn't a simple type, look for it in the other lists */
2005 for(upos = 0; upos < userdef_count && one_userdef[upos].idx != one_pointer[pos].type_index; upos++);
2006
2007 if (upos < userdef_count) {
2008 strcpy(str, one_userdef[upos].name);
2009 strcat(str, " *");
2010 fprintf(hTrap, "%- 6d %- 20.20s %- 33.33s %s\n",
2011 autovar_def[var_no].stack_offset,
2012 autovar_def[var_no].name,
2013 str,
2014 var_value((void *)(stackofs+autovar_def[var_no].stack_offset), 32));
2015 return TRUE;
2016 }
2017 else { /* If it isn't a userdef, for now give up and just print as much as we know */
2018 sprintf(str, "Pointer to type 0x%X", one_pointer[pos].type_index);
2019
2020 fprintf(hTrap, "%- 6d %- 20.20s %- 33.33s %s\n",
2021 autovar_def[var_no].stack_offset,
2022 autovar_def[var_no].name,
2023 str,
2024 var_value((void *)(stackofs+autovar_def[var_no].stack_offset), 32));
2025
2026 return TRUE;
2027 }
2028 }
2029 }
2030
2031 return FALSE;
2032}
2033
2034void print_vars(ULONG stackofs)
2035{
2036 USHORT n, pos;
2037 BOOL AutoVarsFound=FALSE;
2038
2039/* stackofs += stack_ebp; */
2040 if (1 || func_ofs == pubfunc_ofs) {
2041 for(n = 0; n < var_ofs; n++) {
2042 if (AutoVarsFound==FALSE) {
2043 AutoVarsFound=TRUE;
2044 fprintf(hTrap, "List of auto variables at EBP %p in %s:\n",stackofs, func_name);
2045 fprintf(hTrap,"Offset Name Type Value \n");
2046 fprintf(hTrap,"ÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\n");
2047 }
2048
2049 /* If it's one of the simple types */
2050 if (autovar_def[n].type_idx >= 0x80 && autovar_def[n].type_idx <= 0xDA)
2051 {
2052 fprintf(hTrap, "%- 6d %- 20.20s %- 33.33s %s\n",
2053 autovar_def[n].stack_offset,
2054 autovar_def[n].name,
2055 type_name[autovar_def[n].type_idx-0x80],
2056 var_value((void *)(stackofs+autovar_def[n].stack_offset),
2057 autovar_def[n].type_idx-0x80));
2058 }
2059 else { /* Complex type, check if we know what it is */
2060 if (!search_userdefs(stackofs, n)) {
2061 if (!search_pointers(stackofs, n)) {
2062 fprintf(hTrap, "%- 6d %-20.20s 0x%X\n",
2063 autovar_def[n].stack_offset,
2064 autovar_def[n].name,
2065 autovar_def[n].type_idx);
2066 }
2067 }
2068 }
2069 }
2070 if (AutoVarsFound==FALSE) {
2071 fprintf(hTrap, " No auto variables found in %s.\n", func_name);
2072 }
2073 fprintf(hTrap, "\n");
2074 }
2075}
2076
2077
2078
Note: See TracBrowser for help on using the repository browser.