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

Last change on this file was 207, checked in by gyoung, 6 months ago

Move Trap/Debug log to LOGFILES directory

File size: 77.8 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 CHAR *LogPath;
554 struct debug_buffer DbgBuf;
555 static CHAR Name[CCHMAXPATH];
556
557 /* Do not recurse into Trapper (John Currier) */
558 /* Not necessary anymore because nested calls are catched now CW */
559 static BOOL fAlreadyTrapped = FALSE;
560
561 if (InForceExit) {
562 return (XCPT_CONTINUE_SEARCH);
563 } /* endif */
564 if ((pERepRec->ExceptionNum&XCPT_SEVERITY_CODE)==XCPT_FATAL_EXCEPTION)
565 {
566 if ((pERepRec->ExceptionNum!=XCPT_PROCESS_TERMINATE)&&
567 (pERepRec->ExceptionNum!=XCPT_UNWIND)&&
568 (pERepRec->ExceptionNum!=XCPT_SIGNAL)&&
569 (pERepRec->ExceptionNum!=XCPT_ASYNC_PROCESS_TERMINATE)) {
570 DosEnterMustComplete(&Nest);
571
572 LogPath = getenv( "LOGFILES" );
573 if (!LogPath)
574 sprintf(TrapFile,"%c:\\%s",_GetBootDriveLetter(), EXCEPTION_LOGFILE_NAME);
575 else
576 sprintf(TrapFile,"%s\\%s",LogPath, EXCEPTION_LOGFILE_NAME);
577
578 hTrap=fopen(TrapFile,"a");
579 if (hTrap==NULL)
580 hTrap=stdout;
581
582 // rc=DosError(FERR_DISABLEEXCEPTION | FERR_DISABLEHARDERR );
583
584 setbuf( hTrap, NULL);/* Unbuffered stream */
585 // fprintf(hTrap,"A trap occurred in Audio/Data-CD-Creator\n");
586 fprintf(hTrap,"----------------------------------------\n\n");
587 fprintf(hTrap,"Exception %8.8lX Occurred",pERepRec->ExceptionNum);
588 fprintf(hTrap," at %s ",_strtime(Buffer));
589 fprintf(hTrap," %s\n\n",_strdate(Buffer));
590 if ( pERepRec->ExceptionNum == XCPT_ACCESS_VIOLATION)
591 {
592 switch (pERepRec->ExceptionInfo[0]) {
593 case XCPT_READ_ACCESS:
594 fprintf(hTrap,"Invalid read address %8.8lX\n",pERepRec->ExceptionInfo[1]);
595 break;
596 case XCPT_WRITE_ACCESS:
597 fprintf(hTrap,"Invalid write address %8.8lX\n",pERepRec->ExceptionInfo[1]);
598 break;
599 case XCPT_SPACE_ACCESS:
600 /* Thanks to John Currier */
601 /* It looks like this is off by one... */
602 fprintf(hTrap,"Invalid Selector: %8.8p",
603 pERepRec->ExceptionInfo[1] ?
604 pERepRec->ExceptionInfo[1] + 1 : 0);
605 break;
606 case XCPT_LIMIT_ACCESS:
607 fprintf(hTrap,"Limit access fault\n");
608 break;
609 case XCPT_UNKNOWN_ACCESS:
610 fprintf(hTrap,"Unknown access fault\n");
611 break;
612 break;
613 default:
614 fprintf(hTrap,"Other Unknown access fault\n");
615 } /* endswitch */
616 } /* endif XCPT_ACCESS_VIOLATION */
617 else if( pERepRec->ExceptionNum == XCPT_INTEGER_DIVIDE_BY_ZERO)
618 {
619 fprintf(hTrap,"Division by zero.\n");
620 }
621 else if( pERepRec->ExceptionNum == XCPT_ILLEGAL_INSTRUCTION)
622 {
623 fprintf(hTrap,"Illegal instruction.\n");
624 }
625 else if( pERepRec->ExceptionNum == XCPT_PRIVILEGED_INSTRUCTION)
626 {
627 fprintf(hTrap,"Privileged instruction.\n");
628 }
629 else if( pERepRec->ExceptionNum == XCPT_INTEGER_OVERFLOW)
630 {
631 fprintf(hTrap,"Integer overflow.\n");
632 }
633
634 /* John Currier's recursion prevention */
635 fprintf(hTrap,"\n\n");
636#if 0 /* Not necessary anymore because nested calls are catched now CW */
637 if (fAlreadyTrapped)
638 {
639 fprintf(hTrap, "Exception Handler Trapped...aborting evaluation!\n");
640 if (hTrap != stderr)
641 fclose(hTrap);
642 DosExitMustComplete(&Nest);
643
644 /* DosUnsetExceptionHandler(pERegRec); */
645 return (XCPT_CONTINUE_SEARCH);
646 }
647#endif
648
649 fAlreadyTrapped = TRUE;
650 /* end John Currier's recursion prevention */
651 rc = DosQuerySysInfo(QSV_VERSION_MAJOR,QSV_VERSION_MINOR,
652 Version,sizeof(Version));
653 if ((rc==0)&&
654 (Version[0]>=20) &&
655 (Version[1]>=10) ) {
656 /* version must be over 2.1 for DOSQUERYMODFROMEIP */
657 fprintf(hTrap,"OS/2 Version %d.%d\n",Version[0]/10,Version[1]);
658 rc=DOSQUERYMODFROMEIP( &hMod, &ObjNum, CCHMAXPATH,
659 Name, &Offset, pERepRec->ExceptionAddress);
660 if (rc==0) {
661 fprintf(hTrap,"Failing code module internal name : %s\n",Name);
662 rc=DosQueryModuleName(hMod,CCHMAXPATH, Name);
663 fprintf(hTrap,"Failing code module file name : %s\n",Name);
664 fprintf(hTrap,"Failing code Object # %d at Offset %x \n",ObjNum+1,Offset);
665 if (strlen(Name)>3) {
666 fprintf(hTrap," File Line# Public Symbol\n");
667 fprintf(hTrap," ÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄ- ÄÄÄÄÄÄÄÄÄÄÄÄ-\n");
668 rc =GetLineNum(Name,ObjNum,Offset);
669
670 if (rc == 0)
671 print_vars(pCtxRec->ctx_RegEbp);
672
673 /* if no codeview try with symbol files */
674 if (rc!=0) {
675 strcpy(Name+strlen(Name)-3,"SYM"); /* Get Sym File name */
676 GetSymbol(Name,ObjNum,Offset);
677 } /* endif */
678 } /* endif */
679 fprintf(hTrap,"\n");
680 } else {
681 fprintf(hTrap,"Invalid execution address\n");
682 } /* endif */
683 } /* endif */
684 if ( (pCtxRec->ContextFlags) & CONTEXT_CONTROL ) {
685 void * _Seg16 Ptr16;
686 BigSeg=((pCtxRec->ctx_RegEip)>0x00010000);
687 if (BigSeg) {
688 /* Avoid traps in 16:16 Disasm DLL */
689 if (DosAllocMem((PPVOID)&SourceBuffer,0x100,fALLOC)==0) {
690 Size=0x100;
691 rc=DosQueryMem((PVOID)pCtxRec->ctx_RegEip,&Size,&Attr);
692 if (Attr&(PAG_READ|PAG_EXECUTE)) {
693 memcpy(SourceBuffer,(PVOID)pCtxRec->ctx_RegEip,Size);
694#if 0 /*CW*/
695 AsmLine= DISASM( SourceBuffer,
696 (USHORT)pCtxRec->ctx_RegEip, BigSeg );
697 fprintf(hTrap,"\n Failing instruction at CS:EIP : %4.4X:%8.8X is %s\n\n",
698 pCtxRec->ctx_SegCs,
699 pCtxRec->ctx_RegEip,AsmLine->buf);
700#endif
701 } /* endif */
702 }
703 } else {
704 if (CSSize>pCtxRec->ctx_RegEip) {
705#if 0 /*CW*/
706 AsmLine= DISASM(MAKE16P(pCtxRec->ctx_SegCs,
707 pCtxRec->ctx_RegEip),
708 (USHORT)pCtxRec->ctx_RegEip, BigSeg );
709 fprintf(hTrap,"\n Failing instruction at CS:IP : %4.4X:%4.4X is %s\n\n",
710 pCtxRec->ctx_SegCs,
711 pCtxRec->ctx_RegEip,AsmLine->buf);
712#endif
713 } else {
714 fprintf(hTrap,"Invalid execution address\n");
715 } /* endif */
716 } /* endif */
717
718 rc=DosGetInfoBlocks(&ptib,&ppib);
719 if (rc==NO_ERROR) {
720 static CHAR Format[10];
721
722 fprintf(hTrap,"\nThread slot %lu , Id %lu , priority %p\n",
723 ptib->tib_ordinal,
724 ptib->tib_ptib2->tib2_ultid ,
725 ptib->tib_ptib2->tib2_ulpri );
726 Ptr16=ptib->tib_pstack;
727 sprintf(Format,"%8.8lX",Ptr16);
728 fprintf(hTrap,"Stack Bottom : %8.8lX (%4.4s:%4.4s) ;", ptib->tib_pstack ,Format,Format+4);
729 Ptr16=ptib->tib_pstacklimit;
730 sprintf(Format,"%8.8lX",Ptr16);
731 fprintf(hTrap,"Stack Top : %8.8lX (%4.4s:%4.4s) \n",ptib->tib_pstacklimit,Format,Format+4);
732 fprintf(hTrap,"Process Id : %lu ", ppib->pib_ulpid);
733 rc=DosQueryModuleName(ppib->pib_hmte,CCHMAXPATH, Name);
734 if (rc==NO_ERROR) {
735 fprintf(hTrap,".EXE name : %s\n",Name);
736 } else {
737 fprintf(hTrap,".EXE name : ??????\n");
738 } /* endif */
739 /* Better New WalkStack From John Currier */
740 WalkStack((PUSHORT)ptib->tib_pstack,
741 (PUSHORT)ptib->tib_pstacklimit,
742 (PUSHORT)pCtxRec->ctx_RegEbp,
743 (PUSHORT)pERepRec->ExceptionAddress);
744 ListModules();
745 Count=0;
746 } /* endif */
747 } /* endif */
748
749 if (hTrap!=stdout) {
750 fclose(hTrap);
751 }
752 DosExitMustComplete(&Nest);
753
754 /* rc=DosUnsetExceptionHandler(pERegRec); CW */
755 } /* endif */
756 } else {
757 /* printf("Other non fatal exception %8.8lx ",pERepRec->ExceptionNum); */
758 /* printf("At address %8.8lx\n",pERepRec->ExceptionAddress); */
759 } /* endif */
760 return (XCPT_CONTINUE_SEARCH);
761}
762
763#if 0 /*CW */
764APIRET16 APIENTRY16 SETEXCEPT(PEXCEPTIONREGISTRATIONRECORD _Seg16 pxcpthand)
765 {
766 APIRET rc;
767
768 rc=DosError(FERR_DISABLEEXCEPTION | FERR_DISABLEHARDERR );
769 printf("Set error rc %ld\n",rc);
770 pxcpthand->prev_structure=0;
771 pxcpthand->ExceptionHandler=&myHandler;
772 rc=DosSetExceptionHandler(pxcpthand);
773 printf("Set except rc %ld\n",rc);
774 return rc;/* CW */
775}
776APIRET16 APIENTRY16 UNSETEXCEPT(PEXCEPTIONREGISTRATIONRECORD _Seg16 pxcpthand)
777 {
778 APIRET rc;
779 rc=DosUnsetExceptionHandler(pxcpthand);
780 printf("Unset except rc %ld\n",rc);
781 return rc;/* CW */
782}
783#endif
784
785VOID ListModules() {
786 APIRET rc;
787 APIRET16 rc16;
788#ifdef USE_DOSDEBUG
789 /**----------------------------------***/
790#else
791#if MORE_INFO_WANTED
792 PVOID BaseAddress;
793 ULONG RegionSize;
794 ULONG AllocationFlags;
795 HMODULE LastModule;
796 static CHAR Name[CCHMAXPATH];
797 ULONG Size;
798 LastModule=0;
799 BaseAddress=(PVOID)0x10000;
800 RegionSize =0x3FFFFFFF;
801 fprintf(hTrap,"ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\n");
802 fprintf(hTrap,"³ List of currently accessed modules (DLLs) object addresses ³");
803 rc=DosQueryMem(BaseAddress,&RegionSize,&AllocationFlags);
804 while (rc==NO_ERROR) {
805 if ((AllocationFlags&PAG_EXECUTE)&&
806 (AllocationFlags&PAG_BASE)) {
807 rc=DOSQUERYMODFROMEIP( &hMod, &ObjNum, CCHMAXPATH,
808 Name, &Offset, BaseAddress);
809 if (rc==0) {
810 if (hMod!=LastModule) {
811 rc=DosQueryModuleName(hMod,CCHMAXPATH, Name);
812 fprintf(hTrap,"\nÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŽ\n");
813 fprintf(hTrap,"³ Module %-48.48s Handle %8.8d ³\n",Name,hMod);
814 fprintf(hTrap,"³ Object Number Address Length Flags Type ³");
815 LastModule=hMod;
816 } /* endif */
817 fprintf(hTrap,"\n³ % 6.6d %8.8lX %8.8lX %8.8lX ",ObjNum,
818 BaseAddress, RegionSize, AllocationFlags);
819 rc16 =DOS16SIZESEG( SELECTOROF(BaseAddress), &Size);
820 if (rc16==0) {
821 fprintf(hTrap," - 16:16 Selector %4.4hX ³",SELECTOROF((PVOID)BaseAddress));
822 } else {
823 fprintf(hTrap," - 32 Bits ³");
824 } /* endif */
825 }
826 }
827 if (AllocationFlags&PAG_FREE) RegionSize =0x10000;
828 RegionSize +=0x0FFF;
829 RegionSize &=0xFFFFF000;
830 BaseAddress=(PVOID)(((PCHAR)BaseAddress)+RegionSize);
831 RegionSize=((PCHAR)0x3FFFFFFF)-(PCHAR)BaseAddress;
832 rc=DosQueryMem(BaseAddress,&RegionSize,&AllocationFlags);
833 while ((rc==ERROR_INVALID_ADDRESS)||
834 (rc==ERROR_NO_OBJECT)) {
835 BaseAddress=(PVOID)(((PCHAR)BaseAddress)+0x10000);
836 if (BaseAddress>(PVOID)0x3FFFFFFF) {
837 break;
838 } /* endif */
839 RegionSize=((PCHAR)0x3FFFFFFF)-(PCHAR)BaseAddress;
840 rc=DosQueryMem(BaseAddress,&RegionSize,&AllocationFlags);
841 } /* endwhile */
842 if (BaseAddress>(PVOID)0x3FFFFFFF) {
843 break;
844 } /* endif */
845 } /* endwhile */
846 fprintf(hTrap,"\nÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\n");
847#endif
848#endif
849}
850
851
852void CheckMem(PVOID Ptr,PSZ MemoryName) {
853 APIRET rc;
854 ULONG Size,Flags,Attr;
855 Size=1;
856 rc=DosQueryMem(Ptr,&Size,&Attr);
857 if (rc!=NO_ERROR) {
858 fprintf(hTrap, "³ %3.3s does not point to valid memory ³\n",MemoryName);
859 } else {
860 if (Attr&PAG_FREE) {
861 fprintf(hTrap, "³ %3.3s points to unallocated memory ³\n",MemoryName);
862 } else {
863 if ((Attr&PAG_COMMIT)==0x0U) {
864 fprintf(hTrap,"³ %3.3s points to uncommited memory ³\n",MemoryName);
865 } /* endif */
866 if ((Attr&PAG_WRITE)==0x0U) {
867 fprintf(hTrap,"³ %3.3s points to unwritable memory ³\n",MemoryName);
868 } /* endif */
869 if ((Attr&PAG_READ)==0x0U) {
870 fprintf(hTrap,"³ %3.3s points to unreadable memory ³\n",MemoryName);
871 } /* endif */
872 } /* endif */
873 } /* endif */
874}
875
876PUSHORT Convert(USHORT * _Seg16 p16) {
877 return p16;
878}
879
880/* Better New WalkStack From John Currier */
881static void WalkStack(PUSHORT StackBottom, PUSHORT StackTop, PUSHORT Ebp,
882 PUSHORT ExceptionAddress)
883{
884 PUSHORT RetAddr;
885 PUSHORT LastEbp;
886 APIRET rc;
887 ULONG Size,Attr;
888 USHORT Cs,Ip,Bp,Sp;
889 static char Name[CCHMAXPATH];
890 HMODULE hMod;
891 ULONG ObjNum;
892 ULONG Offset;
893 BOOL fExceptionAddress = TRUE; // Use Exception Addr 1st time thru
894
895 // Note: we can't handle stacks bigger than 64K for now...
896 Sp = (USHORT)(((ULONG)StackBottom) >> 16);
897 Bp = (USHORT)(ULONG)Ebp;
898
899 if (!f32bit)
900 Ebp = (PUSHORT)MAKEULONG(Bp, Sp);
901
902 fprintf(hTrap,"\nCall Stack:\n");
903 fprintf(hTrap," Source Line Nearest\n");
904 fprintf(hTrap," EBP Address Module Obj# File Numbr Public Symbol\n");
905 fprintf(hTrap," ÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄ- ÄÄÄÄÄÄÄÄ ÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄ- ÄÄÄÄÄÄÄÄÄÄÄÄ-\n");
906
907 do
908 {
909 Size = 10;
910 rc = DosQueryMem((PVOID)(Ebp+2), &Size, &Attr);
911 if (rc != NO_ERROR || !(Attr & PAG_COMMIT) || (Size<10) )
912 {
913 fprintf(hTrap,"Invalid EBP: %8.8p\n",Ebp);
914 break;
915 }
916
917 if (fExceptionAddress)
918 RetAddr = ExceptionAddress;
919 else
920 RetAddr = (PUSHORT)(*((PULONG)(Ebp+2)));
921
922 if (RetAddr == (PUSHORT)0x00000053)
923 {
924 // For some reason there's a "return address" of 0x53 following
925 // EBP on the stack and we have to adjust EBP by 44 bytes to get
926 // at the real return address. This has something to do with
927 // thunking from 32bits to 16bits...
928 // Serious kludge, and it's probably dependent on versions of C(++)
929 // runtime or OS, but it works for now!
930 Ebp += 22;
931 RetAddr = (PUSHORT)(*((PULONG)(Ebp+2)));
932 }
933
934 // Get the (possibly) 16bit CS and IP
935 if (fExceptionAddress)
936 {
937 Cs = (USHORT)(((ULONG)ExceptionAddress) >> 16);
938 Ip = (USHORT)(ULONG)ExceptionAddress;
939 }
940 else
941 {
942 Cs = *(Ebp+2);
943 Ip = *(Ebp+1);
944 }
945
946 // if the return address points to the stack then it's really just
947 // a pointer to the return address (UGH!).
948 if ((USHORT)(((ULONG)RetAddr) >> 16) == Sp)
949 RetAddr = (PUSHORT)(*((PULONG)RetAddr));
950
951 if (Ip == 0 && *Ebp == 0)
952 {
953 // End of the stack so these are both shifted by 2 bytes:
954 Cs = *(Ebp+3);
955 Ip = *(Ebp+2);
956 }
957
958 // 16bit programs have on the stack:
959 // BP:IP:CS
960 // where CS may be thunked
961 //
962 // in dump swapped
963 // BP IP CS BP CS IP
964 // 4677 53B5 F7D0 7746 D0F7 B553
965 //
966 // 32bit programs have:
967 // EBP:EIP
968 // and you'd have something like this (with SP added) (not
969 // accurate values)
970 //
971 // in dump swapped
972 // EBP EIP EBP EIP
973 // 4677 2900 53B5 F7D0 0029 7746 D0F7 B553
974 //
975 // So the basic difference is that 32bit programs have a 32bit
976 // EBP and we can attempt to determine whether we have a 32bit
977 // EBP by checking to see if its 'selector' is the same as SP.
978 // Note that this technique limits us to checking stacks < 64K.
979 //
980 // Soooo, if IP (which maps into the same USHORT as the swapped
981 // stack page in EBP) doesn't point to the stack (i.e. it could
982 // be a 16bit IP) then see if CS is valid (as is or thunked).
983 //
984 // Note that there's the possibility of a 16bit return address
985 // that has an offset that's the same as SP so we'll think it's
986 // a 32bit return address and won't be able to successfully resolve
987 // its details.
988 if (Ip != Sp)
989 {
990 if (DOS16SIZESEG(Cs, &Size) == NO_ERROR)
991 {
992 RetAddr = (USHORT * _Seg16)MAKEULONG(Ip, Cs);
993 f32bit = FALSE;
994 }
995 else if (DOS16SIZESEG((Cs << 3) + 7, &Size) == NO_ERROR)
996 {
997 Cs = (Cs << 3) + 7;
998 RetAddr = (USHORT * _Seg16)MAKEULONG(Ip, Cs);
999 f32bit = FALSE;
1000 }
1001 else
1002 f32bit = TRUE;
1003 }
1004 else
1005 f32bit = TRUE;
1006
1007
1008 if (fExceptionAddress)
1009 fprintf(hTrap," Trap ->");
1010 else
1011 fprintf(hTrap," %8.8p", Ebp);
1012
1013 if (f32bit)
1014 fprintf(hTrap," :%8.8p", RetAddr);
1015 else
1016 fprintf(hTrap," %04.04X:%04.04X", Cs, Ip);
1017
1018 if (Version[0] >= 20 && Version[1] >= 10)
1019 {
1020 // Make a 'tick' sound to let the user know we're still alive
1021 DosBeep(2000, 1);
1022
1023 Size = 10; /* Inserted by Kim Rasmussen 26/06 1996 to avoid error 87 when Size is 0 */
1024
1025 rc = DosQueryMem((PVOID)RetAddr, &Size, &Attr);
1026 if (rc != NO_ERROR || !(Attr & PAG_COMMIT))
1027 {
1028 fprintf(hTrap,"Invalid RetAddr: %8.8p\n",RetAddr);
1029 break; /* avoid infinite loops */
1030 } else {
1031 rc = DOSQUERYMODFROMEIP(&hMod, &ObjNum, sizeof(Name),
1032 Name, &Offset, (PVOID)RetAddr);
1033 if (rc == NO_ERROR && ObjNum != -1)
1034 {
1035 static char szJunk[_MAX_FNAME];
1036 static char szName[_MAX_FNAME];
1037 DosQueryModuleName(hMod, sizeof(Name), Name);
1038 _splitpath(Name, szJunk, szJunk, szName, szJunk);
1039 fprintf(hTrap," %-8s %04X", szName, ObjNum+1);
1040
1041 if (strlen(Name) > 3)
1042 {
1043 rc = GetLineNum(Name, ObjNum, Offset);
1044 /* if no codeview try with symbol files */
1045 if (rc != NO_ERROR)
1046 {
1047 strcpy(Name+strlen(Name)-3,"SYM");
1048 GetSymbol(Name,ObjNum,Offset);
1049 }
1050 }
1051 }
1052 else
1053 {
1054 fprintf(hTrap," *Unknown*");
1055 }
1056 }
1057 }
1058
1059 fprintf(hTrap,"\n");
1060
1061 Bp = *Ebp;
1062 if (Bp == 0 && (*Ebp+1) == 0)
1063 {
1064 fprintf(hTrap,"End of Call Stack\n");
1065 break;
1066 }
1067
1068 if (!fExceptionAddress)
1069 {
1070 LastEbp = Ebp;
1071#if 0
1072 Ebp = (PUSHORT)MAKEULONG(Bp, Sp);
1073#else /* Inserted by Kim Rasmussen 26/06 1996 to allow big stacks */
1074 if (f32bit)
1075 Ebp = (PUSHORT)*(PULONG)LastEbp;
1076 else
1077 Ebp = (PUSHORT)MAKEULONG(Bp, Sp);
1078#endif
1079 if (f32bit) {
1080 print_vars((ULONG)Ebp);
1081 } /* endif */
1082
1083 if (Ebp < LastEbp)
1084 {
1085 fprintf(hTrap,"Lost Stack chain - new EBP below previous\n");
1086 break;
1087 }
1088 }
1089 else
1090 fExceptionAddress = FALSE;
1091
1092 Size = 4;
1093 rc = DosQueryMem((PVOID)Ebp, &Size, &Attr);
1094 if ((rc != NO_ERROR)||(Size<4))
1095 {
1096 fprintf(hTrap,"Lost Stack chain - invalid EBP: %8.8p\n", Ebp);
1097 break;
1098 }
1099 } while (TRUE);
1100
1101 fprintf(hTrap,"\n");
1102}
1103
1104void GetSymbol(CHAR * SymFileName, ULONG Object,ULONG TrapOffset)
1105{
1106 static FILE * SymFile;
1107 static MAPDEF MapDef;
1108 static SEGDEF SegDef;
1109 static SEGDEF *pSegDef;
1110 static SYMDEF32 SymDef32;
1111 static SYMDEF16 SymDef16;
1112 static char Buffer[256];
1113 static int SegNum,SymNum,LastVal;
1114 static unsigned long int SegOffset,SymOffset,SymPtrOffset;
1115 SymFile=fopen(SymFileName,"rb");
1116 if (SymFile==0) {
1117 /*fprintf(hTrap,"Could not open symbol file %s\n",SymFileName);*/
1118 return;
1119 } /* endif */
1120 fread(&MapDef,sizeof(MAPDEF),1,SymFile);
1121 SegOffset= SEGDEFOFFSET(MapDef);
1122 for (SegNum=0;SegNum<MapDef.cSegs;SegNum++) {
1123 /* printf("Scanning segment #%d Offset %4.4hX\n",SegNum+1,SegOffset); */
1124 if (fseek(SymFile,SegOffset,SEEK_SET)) {
1125 fprintf(hTrap,"Seek error ");
1126 return;
1127 }
1128 fread(&SegDef,sizeof(SEGDEF),1,SymFile);
1129 if (SegNum==Object) {
1130 Buffer[0]=0x00;
1131 LastVal=0;
1132 for (SymNum=0;SymNum<SegDef.cSymbols;SymNum++) {
1133 SymPtrOffset=SYMDEFOFFSET(SegOffset,SegDef,SymNum);
1134 fseek(SymFile,SymPtrOffset,SEEK_SET);
1135 fread(&SymOffset,sizeof(unsigned short int),1,SymFile);
1136 fseek(SymFile,SymOffset+SegOffset,SEEK_SET);
1137 if (SegDef.bFlags&0x01) {
1138 fread(&SymDef32,sizeof(SYMDEF32),1,SymFile);
1139 if (SymDef32.wSymVal>TrapOffset) {
1140 fprintf(hTrap,"between %s + %X ",Buffer,TrapOffset-LastVal);
1141 }
1142 LastVal=SymDef32.wSymVal;
1143 Buffer[0]= SymDef32.achSymName[0];
1144 fread(&Buffer[1],1,SymDef32.cbSymName,SymFile);
1145 Buffer[SymDef32.cbSymName]=0x00;
1146 if (SymDef32.wSymVal>TrapOffset) {
1147 fprintf(hTrap,"and %s - %X\n",Buffer,LastVal-TrapOffset);
1148 break;
1149 }
1150 /*printf("32 Bit Symbol <%s> Address %p\n",Buffer,SymDef32.wSymVal);*/
1151 } else {
1152 fread(&SymDef16,sizeof(SYMDEF16),1,SymFile);
1153 if (SymDef16.wSymVal>TrapOffset) {
1154 fprintf(hTrap,"between %s + %X ",Buffer,TrapOffset-LastVal);
1155 }
1156 LastVal=SymDef16.wSymVal;
1157 Buffer[0]=SymDef16.achSymName[0];
1158 fread(&Buffer[1],1,SymDef16.cbSymName,SymFile);
1159 Buffer[SymDef16.cbSymName]=0x00;
1160 if (SymDef16.wSymVal>TrapOffset) {
1161 fprintf(hTrap,"and %s - %X\n",Buffer,LastVal-TrapOffset);
1162 break;
1163 }
1164 /*printf("16 Bit Symbol <%s> Address %p\n",Buffer,SymDef16.wSymVal);*/
1165 } /* endif */
1166 }
1167 break;
1168 } /* endif */
1169 SegOffset=NEXTSEGDEFOFFSET(SegDef);
1170 } /* endwhile */
1171 fclose(SymFile);
1172}
1173
1174#include <newexe.h>
1175#define FOR_EXEHDR 1 /* avoid define conflicts between newexe.h and exe386.h */
1176#ifndef DWORD
1177#define DWORD long int
1178#endif
1179#ifndef WORD
1180#define WORD short int
1181#endif
1182#include <exe386.h>
1183#include <fcntl.h>
1184#include <sys\stat.h>
1185#include <share.h>
1186#include <io.h>
1187/* ------------------------------------------------------------------ */
1188/* Last 8 bytes of 16:16 file when CODEVIEW debugging info is present */
1189#pragma pack(1)
1190 struct _eodbug
1191 {
1192 unsigned short dbug; /* 'NB' signature */
1193 unsigned short ver; /* version */
1194 unsigned long dfaBase; /* size of codeview info */
1195 } eodbug;
1196
1197#define DBUGSIG 0x424E
1198#define SSTMODULES 0x0101
1199#define SSTPUBLICS 0x0102
1200#define SSTTYPES 0x0103
1201#define SSTSYMBOLS 0x0104
1202#define SSTSRCLINES 0x0105
1203#define SSTLIBRARIES 0x0106
1204#define SSTSRCLINES2 0x0109
1205#define SSTSRCLINES32 0x010B
1206
1207 struct _base
1208 {
1209 unsigned short dbug; /* 'NB' signature */
1210 unsigned short ver; /* version */
1211 unsigned long lfoDir; /* file offset to dir entries */
1212 } base;
1213
1214 struct ssDir
1215 {
1216 unsigned short sst; /* SubSection Type */
1217 unsigned short modindex; /* Module index number */
1218 unsigned long lfoStart; /* Start of section */
1219 unsigned short cb; /* Size of section */
1220 } ;
1221
1222 struct ssDir32
1223 {
1224 unsigned short sst; /* SubSection Type */
1225 unsigned short modindex; /* Module index number */
1226 unsigned long lfoStart; /* Start of section */
1227 unsigned long cb; /* Size of section */
1228 } ;
1229
1230 struct ssModule
1231 {
1232 unsigned short csBase; /* code segment base */
1233 unsigned short csOff; /* code segment offset */
1234 unsigned short csLen; /* code segment length */
1235 unsigned short ovrNum; /* overlay number */
1236 unsigned short indxSS; /* Index into sstLib or 0 */
1237 unsigned short reserved;
1238 char csize; /* size of prefix string */
1239 } ssmod;
1240
1241 struct ssModule32
1242 {
1243 unsigned short csBase; /* code segment base */
1244 unsigned long csOff; /* code segment offset */
1245 unsigned long csLen; /* code segment length */
1246 unsigned long ovrNum; /* overlay number */
1247 unsigned short indxSS; /* Index into sstLib or 0 */
1248 unsigned long reserved;
1249 char csize; /* size of prefix string */
1250 } ssmod32;
1251
1252 struct ssPublic
1253 {
1254 unsigned short offset;
1255 unsigned short segment;
1256 unsigned short type;
1257 char csize;
1258 } sspub;
1259
1260 struct ssPublic32
1261 {
1262 unsigned long offset;
1263 unsigned short segment;
1264 unsigned short type;
1265 char csize;
1266 } sspub32;
1267
1268typedef struct _SSLINEENTRY32 {
1269 unsigned short LineNum;
1270 unsigned short FileNum;
1271 unsigned long Offset;
1272} SSLINEENTRY32;
1273typedef struct _FIRSTLINEENTRY32 {
1274 unsigned short LineNum;
1275 unsigned char entry_type;
1276 unsigned char reserved;
1277 unsigned short numlines;
1278 unsigned short segnum;
1279} FIRSTLINEENTRY32;
1280
1281typedef struct _SSFILENUM32 {
1282 unsigned long first_displayable; /* Not used */
1283 unsigned long number_displayable; /* Not used */
1284 unsigned long file_count; /* number of source files */
1285} SSFILENUM32;
1286
1287 struct DbugRec { /* debug info struct ure used in linked * list */
1288 struct DbugRec far *pnext; /* next node *//* 013 */
1289 char far *SourceFile; /* source file name *013 */
1290 unsigned short TypeOfProgram; /* dll or exe *014* */
1291 unsigned short LineNumber; /* line number in source file */
1292 unsigned short OffSet; /* offset into loaded module */
1293 unsigned short Selector; /* code segment 014 */
1294 unsigned short OpCode; /* Opcode replaced with BreakPt */
1295 unsigned long Count; /* count over Break Point */
1296};
1297
1298typedef struct DbugRec DBUG, far * DBUGPTR; /* 013 */
1299char szNrPub[128];
1300char szNrLine[128];
1301char szNrFile[128];
1302 struct new_seg *pseg;
1303 struct o32_obj *pobj; /* Flat .EXE object table entry */
1304 struct ssDir *pDirTab;
1305 struct ssDir32 *pDirTab32;
1306unsigned char *pEntTab;
1307unsigned long lfaBase;
1308#pragma pack()
1309/* ------------------------------------------------------------------ */
1310
1311APIRET GetLineNum(CHAR * FileName, ULONG Object,ULONG TrapOffset) {
1312 APIRET rc;
1313 int ModuleFile;
1314 static struct exe_hdr old;
1315 static struct new_exe new1;
1316 static struct e32_exe e32;
1317 strcpy(szNrPub," N/A ");
1318 strcpy(szNrLine," N/A ");
1319 strcpy(szNrFile," ");
1320 ModuleFile =sopen(FileName,O_RDONLY|O_BINARY,SH_DENYNO);
1321 if (ModuleFile!=-1) {
1322 /* Read old Exe header */
1323 if (read( ModuleFile ,(void *)&old,64)==-1L) {
1324 fprintf(hTrap,"Could Not Read old exe header %d\n",errno);
1325 close(ModuleFile);
1326 return 2;
1327 }
1328 /* Seek to new Exe header */
1329 if (lseek(ModuleFile,(long)E_LFANEW(old),SEEK_SET)==-1L) {
1330 fprintf(hTrap,"Could Not seek to new exe header %d\n",errno);
1331 close(ModuleFile);
1332 return 3;
1333 }
1334 if (read( ModuleFile ,(void *)&new1,64)==-1L) {
1335 fprintf(hTrap,"Could Not read new exe header %d\n",errno);
1336 close(ModuleFile);
1337 return 4;
1338 }
1339 /* Check EXE signature */
1340 if (NE_MAGIC(new1)==E32MAGIC) {
1341 /* Flat 32 executable */
1342 rc=Read32PmDebug(ModuleFile,Object+1,TrapOffset,FileName);
1343 if (rc==0) {
1344 fprintf(hTrap,"%s",szNrFile);
1345 fprintf(hTrap,"%s",szNrLine);
1346 fprintf(hTrap,"%s",szNrPub);
1347 } /* endif */
1348 close(ModuleFile);
1349 /* rc !=0 try with DBG file */
1350 if (rc!=0) {
1351 strcpy(FileName+strlen(FileName)-3,"DBG"); /* Build DBG File name */
1352 ModuleFile =sopen(FileName,O_RDONLY|O_BINARY,SH_DENYNO);
1353 if (ModuleFile!=-1) {
1354 rc=Read32PmDebug(ModuleFile,Object+1,TrapOffset,FileName);
1355 if (rc==0) {
1356 fprintf(hTrap,"%s",szNrFile);
1357 fprintf(hTrap,"%s",szNrLine);
1358 fprintf(hTrap,"%s",szNrPub);
1359 } /* endif */
1360 close(ModuleFile);
1361 }
1362 } /* endif */
1363 return rc;
1364 } else {
1365 if (NE_MAGIC(new1)==NEMAGIC) {
1366 /* 16:16 executable */
1367 if ((pseg = ( struct new_seg *) calloc(NE_CSEG(new1),sizeof( struct new_seg)))==NULL) {
1368 fprintf(hTrap,"Out of memory!");
1369 close(ModuleFile);
1370 return -1;
1371 }
1372 if (lseek(ModuleFile,E_LFANEW(old)+NE_SEGTAB(new1),SEEK_SET)==-1L) {
1373 fprintf(hTrap,"Error %u seeking segment table in %s\n",errno,FileName);
1374 free(pseg);
1375 close(ModuleFile);
1376 return 9;
1377 }
1378
1379 if (read(ModuleFile,(void *)pseg,NE_CSEG(new1)*sizeof( struct new_seg))==-1) {
1380 fprintf(hTrap,"Error %u reading segment table from %s\n",errno,FileName);
1381 free(pseg);
1382 close(ModuleFile);
1383 return 10;
1384 }
1385 rc=Read16CodeView(ModuleFile,Object+1,TrapOffset,FileName);
1386 if (rc==0) {
1387 fprintf(hTrap,"%s",szNrFile);
1388 fprintf(hTrap,"%s",szNrLine);
1389 fprintf(hTrap,"%s",szNrPub);
1390 } /* endif */
1391 free(pseg);
1392 close(ModuleFile);
1393 /* rc !=0 try with DBG file */
1394 if (rc!=0) {
1395 strcpy(FileName+strlen(FileName)-3,"DBG"); /* Build DBG File name */
1396 ModuleFile =sopen(FileName,O_RDONLY|O_BINARY,SH_DENYNO);
1397 if (ModuleFile!=-1) {
1398 rc=Read16CodeView(ModuleFile,Object+1,TrapOffset,FileName);
1399 if (rc==0) {
1400 fprintf(hTrap,"%s",szNrFile);
1401 fprintf(hTrap,"%s",szNrLine);
1402 fprintf(hTrap,"%s",szNrPub);
1403 } /* endif */
1404 close(ModuleFile);
1405 }
1406 } /* endif */
1407 return rc;
1408
1409 } else {
1410 /* Unknown executable */
1411 fprintf(hTrap,"Could Not find exe signature");
1412 close(ModuleFile);
1413 return 11;
1414 }
1415 }
1416 /* Read new Exe header */
1417 } else {
1418 fprintf(hTrap,"Could Not open Module File %d",errno);
1419 return 1;
1420 } /* endif */
1421 return 0;
1422}
1423char fname[128],ModName[80];
1424char ename[128],dummy[128];
1425
1426int Read16CodeView(int fh,int TrapSeg,int TrapOff,CHAR * FileName) {
1427 static unsigned short int offset,NrPublic,NrLine,NrEntry,numdir,namelen,numlines,line;
1428 static int ModIndex;
1429 static int bytesread,i,j;
1430 ModIndex=0;
1431 /* See if any CODEVIEW info */
1432 if (lseek(fh,-8L,SEEK_END)==-1) {
1433 fprintf(hTrap,"Error %u seeking CodeView table in %s\n",errno,FileName);
1434 return(18);
1435 }
1436
1437 if (read(fh,(void *)&eodbug,8)==-1) {
1438 fprintf(hTrap,"Error %u reading debug info from %s\n",errno,FileName);
1439 return(19);
1440 }
1441 if (eodbug.dbug!=DBUGSIG) {
1442 /* fprintf(hTrap,"\nNo CodeView information stored.\n"); */
1443 return(100);
1444 }
1445
1446 if ((lfaBase=lseek(fh,-eodbug.dfaBase,SEEK_END))==-1L) {
1447 fprintf(hTrap,"Error %u seeking base codeview data in %s\n",errno,FileName);
1448 return(20);
1449 }
1450
1451 if (read(fh,(void *)&base,8)==-1) {
1452 fprintf(hTrap,"Error %u reading base codeview data in %s\n",errno,FileName);
1453 return(21);
1454 }
1455
1456 if (lseek(fh,base.lfoDir-8,SEEK_CUR)==-1) {
1457 fprintf(hTrap,"Error %u seeking dir codeview data in %s\n",errno,FileName);
1458 return(22);
1459 }
1460
1461 if (read(fh,(void *)&numdir,2)==-1) {
1462 fprintf(hTrap,"Error %u reading dir codeview data in %s\n",errno,FileName);
1463 return(23);
1464 }
1465
1466 /* Read dir table into buffer */
1467 if (( pDirTab = ( struct ssDir *) calloc(numdir,sizeof( struct ssDir)))==NULL) {
1468 fprintf(hTrap,"Out of memory!");
1469 return(-1);
1470 }
1471
1472 if (read(fh,(void *)pDirTab,numdir*sizeof( struct ssDir))==-1) {
1473 fprintf(hTrap,"Error %u reading codeview dir table from %s\n",errno,FileName);
1474 free(pDirTab);
1475 return(24);
1476 }
1477
1478 i=0;
1479 while (i<numdir) {
1480 if (pDirTab[i].sst!=SSTMODULES) {
1481 i++;
1482 continue;
1483 }
1484 NrPublic=0x0;
1485 NrLine=0x0;
1486 /* point to subsection */
1487 lseek(fh, pDirTab[i].lfoStart + lfaBase, SEEK_SET);
1488 read(fh,(void *)&ssmod.csBase,sizeof(ssmod));
1489 read(fh,(void *)ModName,(unsigned)ssmod.csize);
1490 ModIndex=pDirTab[i].modindex;
1491 ModName[ssmod.csize]='\0';
1492 i++;
1493 while (pDirTab[i].modindex ==ModIndex && i<numdir) {
1494 /* point to subsection */
1495 lseek(fh, pDirTab[i].lfoStart + lfaBase, SEEK_SET);
1496 switch(pDirTab[i].sst) {
1497 case SSTPUBLICS:
1498 bytesread=0;
1499 while (bytesread < pDirTab[i].cb) {
1500 bytesread += read(fh,(void *)&sspub.offset,sizeof(sspub));
1501 bytesread += read(fh,(void *)ename,(unsigned)sspub.csize);
1502 ename[sspub.csize]='\0';
1503 if ((sspub.segment==TrapSeg) &&
1504 (sspub.offset<=TrapOff) &&
1505 (sspub.offset>=NrPublic)) {
1506 NrPublic=sspub.offset;
1507 sprintf(szNrPub,"%s %s (%s) %04hX:%04hX\n",
1508 (sspub.type==1) ? " Abs" : " ",ename,ModName,
1509 sspub.segment, sspub.offset
1510 );
1511 }
1512 }
1513 break;
1514
1515 case SSTSRCLINES2:
1516 case SSTSRCLINES:
1517 if (TrapSeg!=ssmod.csBase) break;
1518 namelen=0;
1519 read(fh,(void *)&namelen,1);
1520 read(fh,(void *)ename,namelen);
1521 ename[namelen]='\0';
1522 /* skip 2 zero bytes */
1523 if (pDirTab[i].sst==SSTSRCLINES2) read(fh,(void *)&numlines,2);
1524 read(fh,(void *)&numlines,2);
1525 for (j=0;j<numlines;j++) {
1526 read(fh,(void *)&line,2);
1527 read(fh,(void *)&offset,2);
1528 if (offset<=TrapOff && offset>=NrLine) {
1529 NrLine=offset;
1530 sprintf(szNrLine,"% 6hu", line);
1531 sprintf(szNrFile,"% 13.13s ", ename);
1532 /*sprintf(szNrLine,"%04hX:%04hX line #%hu (%s) (%s)\n",
1533 ssmod.csBase,offset,line,ModName,ename); */
1534 }
1535 }
1536 break;
1537 } /* end switch */
1538 i++;
1539 } /* end while modindex */
1540 } /* End While i < numdir */
1541 free(pDirTab);
1542 return(0);
1543}
1544
1545#define MAX_USERDEFS 150
1546#define MAX_POINTERS 150
1547
1548USHORT userdef_count;
1549USHORT pointer_count;
1550
1551struct one_userdef_rec {
1552 USHORT idx;
1553 USHORT type_index;
1554 BYTE name[33];
1555} one_userdef[MAX_USERDEFS];
1556
1557struct one_pointer_rec {
1558 USHORT idx;
1559 USHORT type_index;
1560 BYTE type_qual;
1561 BYTE name[33];
1562} one_pointer[MAX_POINTERS];
1563
1564int Read32PmDebug(int fh,int TrapSeg,int TrapOff,CHAR * FileName) {
1565 static unsigned int CurrSymSeg, NrSymbol,offset,NrPublic,NrFile,NrLine,NrEntry,numdir,namelen,numlines,line;
1566 static int ModIndex;
1567 static int bytesread,i,j;
1568 static int pOffset;
1569 static SSLINEENTRY32 LineEntry;
1570 static SSFILENUM32 FileInfo;
1571 static FIRSTLINEENTRY32 FirstLine;
1572 static BYTE dump_vars = FALSE;
1573 static USHORT idx;
1574 static BOOL read_types;
1575 static LONG lSize;
1576 static BOOL is_new_debug;
1577
1578 ModIndex=0;
1579 /* See if any CODEVIEW info */
1580 if (lseek(fh,-8L,SEEK_END)==-1) {
1581 fprintf(hTrap,"Error %u seeking CodeView table in %s\n",errno,FileName);
1582 return(18);
1583 }
1584
1585 if (read(fh,(void *)&eodbug,8)==-1) {
1586 fprintf(hTrap,"Error %u reading debug info from %s\n",errno,FileName);
1587 return(19);
1588 }
1589 if (eodbug.dbug!=DBUGSIG) {
1590 /*fprintf(hTrap,"\nNo CodeView information stored.\n");*/
1591 return(100);
1592 }
1593
1594 if ((lfaBase=lseek(fh,-eodbug.dfaBase,SEEK_END))==-1L) {
1595 fprintf(hTrap,"Error %u seeking base codeview data in %s\n",errno,FileName);
1596 return(20);
1597 }
1598
1599 if (read(fh,(void *)&base,8)==-1) {
1600 fprintf(hTrap,"Error %u reading base codeview data in %s\n",errno,FileName);
1601 return(21);
1602 }
1603
1604 if (lseek(fh,base.lfoDir-8+4,SEEK_CUR)==-1) {
1605 fprintf(hTrap,"Error %u seeking dir codeview data in %s\n",errno,FileName);
1606 return(22);
1607 }
1608
1609 if (read(fh,(void *)&numdir,4)==-1) {
1610 fprintf(hTrap,"Error %u reading dir codeview data in %s\n",errno,FileName);
1611 return(23);
1612 }
1613
1614 /* Read dir table into buffer */
1615 if (( pDirTab32 = ( struct ssDir32 *) calloc(numdir,sizeof( struct ssDir32)))==NULL) {
1616 fprintf(hTrap,"Out of memory!");
1617 return(-1);
1618 }
1619
1620 if (read(fh,(void *)pDirTab32,numdir*sizeof( struct ssDir32))==-1) {
1621 fprintf(hTrap,"Error %u reading codeview dir table from %s\n",errno,FileName);
1622 free(pDirTab32);
1623 return(24);
1624 }
1625
1626 i=0;
1627 while (i<numdir) {
1628 if ( pDirTab32[i].sst !=SSTMODULES) {
1629 i++;
1630 continue;
1631 }
1632 NrPublic=0x0;
1633 NrSymbol=0;
1634 NrLine=0x0;
1635 NrFile=0x0;
1636 CurrSymSeg = 0;
1637 /* point to subsection */
1638 lseek(fh, pDirTab32[i].lfoStart + lfaBase, SEEK_SET);
1639 read(fh,(void *)&ssmod32.csBase,sizeof(ssmod32));
1640 read(fh,(void *)ModName,(unsigned)ssmod32.csize);
1641 ModIndex=pDirTab32[i].modindex;
1642 ModName[ssmod32.csize]='\0';
1643 i++;
1644
1645 read_types = FALSE;
1646
1647 while (pDirTab32[i].modindex ==ModIndex && i<numdir) {
1648 /* point to subsection */
1649 lseek(fh, pDirTab32[i].lfoStart + lfaBase, SEEK_SET);
1650 switch(pDirTab32[i].sst) {
1651 case SSTPUBLICS:
1652 bytesread=0;
1653 while (bytesread < pDirTab32[i].cb) {
1654 bytesread += read(fh,(void *)&sspub32.offset,sizeof(sspub32));
1655 bytesread += read(fh,(void *)ename,(unsigned)sspub32.csize);
1656 ename[sspub32.csize]='\0';
1657 if ((sspub32.segment==TrapSeg) &&
1658 (sspub32.offset<=TrapOff) &&
1659 (sspub32.offset>=NrPublic)) {
1660 NrPublic = pubfunc_ofs = sspub32.offset;
1661 read_types = TRUE;
1662 sprintf(szNrPub,"%s %s (%s) %04X:%08lu\n",
1663 (sspub32.type==1) ? " Abs" : " ",ename,ModName,
1664 sspub32.segment, sspub32.offset
1665 );
1666 }
1667 }
1668 break;
1669
1670 /* Read symbols, so we can dump the variables on the stack */
1671 case SSTSYMBOLS:
1672 if (TrapSeg!=ssmod32.csBase) break;
1673
1674 bytesread=0;
1675 while (bytesread < pDirTab32[i].cb) {
1676 static USHORT usLength;
1677 static BYTE b1, b2;
1678 static BYTE bType, *ptr;
1679 static ULONG ofs;
1680 static ULONG last_addr = 0;
1681 static BYTE str[256];
1682 static struct symseg_rec symseg;
1683 static struct symauto_rec symauto;
1684 static struct symproc_rec symproc;
1685
1686 /* Read the length of this subentry */
1687 bytesread += read(fh, &b1, 1);
1688 if (b1 & 0x80) {
1689 bytesread += read(fh, &b2, 1);
1690 usLength = ((b1 & 0x7F) << 8) + b2;
1691 }
1692 else
1693 usLength = b1;
1694
1695 ofs = tell(fh);
1696
1697 bytesread += read(fh, &bType, 1);
1698
1699 switch(bType) {
1700 case SYM_CHANGESEG:
1701 read(fh, &symseg, sizeof(symseg));
1702 CurrSymSeg = symseg.seg_no;
1703 break;
1704
1705 case SYM_PROC:
1706 case SYM_CPPPROC:
1707 read(fh, &symproc, sizeof(symproc));
1708 read(fh, str, symproc.name_len);
1709 str[symproc.name_len] = 0;
1710
1711 if ((CurrSymSeg == TrapSeg) &&
1712 (symproc.offset<=TrapOff) &&
1713 (symproc.offset>=NrSymbol)) {
1714
1715 dump_vars = TRUE;
1716 var_ofs = 0;
1717 NrSymbol = symproc.offset;
1718 func_ofs = symproc.offset;
1719
1720 strcpy(func_name, str);
1721 }
1722 else {
1723 dump_vars = FALSE;
1724 }
1725 break;
1726
1727 case SYM_AUTO:
1728 if (!dump_vars)
1729 break;
1730
1731 read(fh, &symauto, sizeof(symauto));
1732 read(fh, str, symauto.name_len);
1733 str[symauto.name_len] = 0;
1734
1735 strcpy(autovar_def[var_ofs].name, str);
1736 autovar_def[var_ofs].stack_offset = symauto.stack_offset;
1737 autovar_def[var_ofs].type_idx = symauto.type_idx;
1738 var_ofs++;
1739 break;
1740
1741 }
1742
1743 bytesread += usLength;
1744
1745 lseek(fh, ofs+usLength, SEEK_SET);
1746 }
1747 break;
1748
1749 case SSTTYPES:
1750// if (ModIndex != TrapSeg)
1751 if (!read_types)
1752 break;
1753
1754 bytesread=0;
1755 idx = 0x200;
1756 userdef_count = 0;
1757 pointer_count = 0;
1758 while (bytesread < pDirTab32[i].cb) {
1759 static struct type_rec type;
1760 static struct type_userdefrec udef;
1761 static struct type_pointerrec point;
1762 static struct type_funcrec func;
1763 static struct type_structrec struc;
1764 static struct type_list1 list1;
1765 static struct type_list2 list2;
1766 static struct type_list2_1 list2_1;
1767 static ULONG ofs;
1768 static BYTE str[256], b1, b2;
1769 static USHORT n;
1770
1771 /* Read the length of this subentry */
1772 ofs = tell(fh);
1773
1774 read(fh, &type, sizeof(type));
1775 bytesread += sizeof(type);
1776
1777 switch(type.type) {
1778 case TYPE_USERDEF:
1779 if (userdef_count > MAX_USERDEFS)
1780 break;
1781
1782 read(fh, &udef, sizeof(udef));
1783 read(fh, str, udef.name_len);
1784 str[udef.name_len] = 0;
1785
1786 // Insert userdef in table
1787 one_userdef[userdef_count].idx = idx;
1788 one_userdef[userdef_count].type_index = udef.type_index;
1789 memcpy(one_userdef[userdef_count].name, str, min(udef.name_len+1, 32));
1790 one_userdef[userdef_count].name[32] = 0;
1791 userdef_count++;
1792 break;
1793
1794 case TYPE_POINTER:
1795 if (pointer_count > MAX_POINTERS)
1796 break;
1797
1798 read(fh, &point, sizeof(point));
1799 read(fh, str, point.name_len);
1800 str[point.name_len] = 0;
1801
1802 // Insert userdef in table
1803 one_pointer[pointer_count].idx = idx;
1804 one_pointer[pointer_count].type_index = point.type_index;
1805 memcpy(one_pointer[pointer_count].name, str, min(point.name_len+1, 32));
1806 one_pointer[pointer_count].name[32] = 0;
1807 one_pointer[pointer_count].type_qual = type.type_qual;
1808 pointer_count++;
1809 break;
1810 }
1811
1812 ++idx;
1813
1814 bytesread += type.length;
1815
1816 lseek(fh, ofs+type.length+2, SEEK_SET);
1817 }
1818 break;
1819
1820 case SSTSRCLINES32:
1821 if (TrapSeg!=ssmod32.csBase) break;
1822
1823 /* read first line */
1824 do {
1825 read(fh,(void *)&FirstLine,sizeof(FirstLine));
1826
1827 if (FirstLine.LineNum!=0) {
1828 fprintf(hTrap,"Missing Line table information\n");
1829 break;
1830 } /* endif */
1831 numlines= FirstLine.numlines;
1832 /* Other type of data skip 4 more bytes */
1833 if (FirstLine.entry_type < 4) {
1834 read(fh, (void *)&lSize, 4);
1835 if (FirstLine.entry_type == 3)
1836 lseek(fh,lSize,SEEK_CUR);
1837 }
1838 } while(FirstLine.entry_type == 3);
1839
1840 for (j=0;j<numlines;j++) {
1841 switch (FirstLine.entry_type) {
1842 case 0:
1843 read(fh,(void *)&LineEntry,sizeof(LineEntry));
1844 /* Changed by Kim Rasmussen 26/06 1996 to ignore linenumber 0 */
1845 /* if (LineEntry.Offset+ssmod32.csOff<=TrapOff && LineEntry.Offset+ssmod32.csOff>=NrLine) { */
1846 if (LineEntry.LineNum && LineEntry.Offset+ssmod32.csOff<=TrapOff && LineEntry.Offset+ssmod32.csOff>=NrLine) {
1847 NrLine=LineEntry.Offset;
1848 NrFile=LineEntry.FileNum;
1849 /*pOffset =sprintf(szNrLine,"%04X:%08X line #%hu ",
1850 ssmod32.csBase,LineEntry.Offset,
1851 LineEntry.LineNum);*/
1852 sprintf(szNrLine,"% 6hu", LineEntry.LineNum);
1853 }
1854 break;
1855
1856 case 1:
1857 lseek(fh, sizeof(struct linlist_rec), SEEK_CUR);
1858 break;
1859
1860 case 2:
1861 lseek(fh, sizeof(struct linsourcelist_rec), SEEK_CUR);
1862 break;
1863
1864 case 3:
1865 lseek(fh, sizeof(struct filenam_rec), SEEK_CUR);
1866 break;
1867
1868 case 4:
1869 lseek(fh, sizeof(struct pathtab_rec), SEEK_CUR);
1870 break;
1871
1872 }
1873 }
1874 if (NrFile!=0) {
1875 read(fh,(void *)&FileInfo,sizeof(FileInfo));
1876 namelen=0;
1877 for (j=1;j<=FileInfo.file_count;j++) {
1878 namelen=0;
1879 read(fh,(void *)&namelen,1);
1880 read(fh,(void *)ename,namelen);
1881 if (j==NrFile) break;
1882 }
1883 ename[namelen]='\0';
1884 /* pOffset=sprintf(szNrLine+pOffset," (%s) (%s)\n",ename,ModName);*/
1885 sprintf(szNrFile,"% 13.13s ",ename);
1886 } else {
1887 /* strcat(szNrLine,"\n"); avoid new line for empty name fill */
1888 strcpy(szNrFile," ");
1889 } /* endif */
1890 break;
1891 } /* end switch */
1892
1893 i++;
1894 } /* end while modindex */
1895 } /* End While i < numdir */
1896 free(pDirTab32);
1897 return(0);
1898}
1899
1900BYTE *var_value(void *varptr, BYTE type)
1901{
1902 static BYTE value[128];
1903 APIRET rc;
1904
1905 strcpy(value, "Unknown");
1906
1907 if (type == 0)
1908 sprintf(value, "%hhd", *(signed char *)varptr);
1909 else if (type == 1)
1910 sprintf(value, "%hd", *(signed short *)varptr);
1911 else if (type == 2)
1912 sprintf(value, "%ld", *(signed long *)varptr);
1913 else if (type == 4)
1914 sprintf(value, "%hu", *(BYTE *)varptr);
1915 else if (type == 5)
1916 sprintf(value, "%hu", *(USHORT *)varptr);
1917 else if (type == 6)
1918 sprintf(value, "%lu", *(ULONG *)varptr);
1919 else if (type == 8)
1920 sprintf(value, "%f", *(float *)varptr);
1921 else if (type == 9)
1922 sprintf(value, "%f", *(double *)varptr);
1923 else if (type == 10)
1924 sprintf(value, "%Lf", *(long double *)varptr);
1925 else if (type == 16)
1926 sprintf(value, "%s", *(char *)varptr ? "TRUE" : "FALSE");
1927 else if (type == 17)
1928 sprintf(value, "%s", *(short *)varptr ? "TRUE" : "FALSE");
1929 else if (type == 18)
1930 sprintf(value, "%s", *(long *)varptr ? "TRUE" : "FALSE");
1931 else if (type == 20)
1932 sprintf(value, "%c", *(char *)varptr);
1933 else if (type == 21)
1934 sprintf(value, "%hd", *(short *)varptr);
1935 else if (type == 22)
1936 sprintf(value, "%lc", *(long *)varptr);
1937 else if (type == 23)
1938 sprintf(value, "void");
1939 else if (type >= 32) {
1940 ULONG Size,Attr;
1941 Size=1;
1942 rc=DosQueryMem((void*)*(ULONG *)varptr,&Size,&Attr);
1943 if (rc) {
1944 sprintf(value, "0x%p invalid", *(ULONG *)varptr);
1945 } else {
1946 sprintf(value, "0x%p", *(ULONG *)varptr);
1947 if (Attr&PAG_FREE) {
1948 strcat(value," unallocated memory");
1949 } else {
1950 if ((Attr&PAG_COMMIT)==0x0U) {
1951 strcat(value," uncommited");
1952 } /* endif */
1953 if ((Attr&PAG_WRITE)==0x0U) {
1954 strcat(value," unwritable");
1955 } /* endif */
1956 if ((Attr&PAG_READ)==0x0U) {
1957 strcat(value," unreadable");
1958 } /* endif */
1959 } /* endif */
1960 } /* endif */
1961 }
1962
1963 return value;
1964}
1965
1966/* Search the table of userdef's - return TRUE if found */
1967BOOL search_userdefs(ULONG stackofs, USHORT var_no)
1968{
1969 USHORT pos;
1970
1971 for(pos = 0; pos < userdef_count && one_userdef[pos].idx != autovar_def[var_no].type_idx; pos++);
1972
1973 if (pos < userdef_count) {
1974 if (one_userdef[pos].type_index >= 0x80 && one_userdef[pos].type_index <= 0xDA) {
1975 fprintf(hTrap, "%- 6d %- 20.20s %- 33.33s %s\n",
1976 autovar_def[var_no].stack_offset,
1977 autovar_def[var_no].name,
1978 one_userdef[pos].name,
1979 var_value((void *)(stackofs+autovar_def[var_no].stack_offset),
1980 one_userdef[pos].type_index-0x80));
1981 return TRUE;
1982 }
1983 else /* If the result isn't a simple type, let's act as we didn't find it */
1984 return FALSE;
1985 }
1986
1987 return FALSE;
1988}
1989
1990BOOL search_pointers(ULONG stackofs, USHORT var_no)
1991{
1992 USHORT pos, upos;
1993 static BYTE str[35];
1994 BYTE type_index;
1995
1996 for(pos = 0; pos < pointer_count && one_pointer[pos].idx != autovar_def[var_no].type_idx; pos++);
1997
1998 if (pos < pointer_count) {
1999 if (one_pointer[pos].type_index >= 0x80 && one_pointer[pos].type_index <= 0xDA) {
2000 strcpy(str, type_name[one_pointer[pos].type_index-0x80]);
2001 strcat(str, " *");
2002 fprintf(hTrap, "%- 6d %- 20.20s %- 33.33s %s\n",
2003 autovar_def[var_no].stack_offset,
2004 autovar_def[var_no].name,
2005 str,
2006 var_value((void *)(stackofs+autovar_def[var_no].stack_offset), 32));
2007 return TRUE;
2008 }
2009 else { /* If the result isn't a simple type, look for it in the other lists */
2010 for(upos = 0; upos < userdef_count && one_userdef[upos].idx != one_pointer[pos].type_index; upos++);
2011
2012 if (upos < userdef_count) {
2013 strcpy(str, one_userdef[upos].name);
2014 strcat(str, " *");
2015 fprintf(hTrap, "%- 6d %- 20.20s %- 33.33s %s\n",
2016 autovar_def[var_no].stack_offset,
2017 autovar_def[var_no].name,
2018 str,
2019 var_value((void *)(stackofs+autovar_def[var_no].stack_offset), 32));
2020 return TRUE;
2021 }
2022 else { /* If it isn't a userdef, for now give up and just print as much as we know */
2023 sprintf(str, "Pointer to type 0x%X", one_pointer[pos].type_index);
2024
2025 fprintf(hTrap, "%- 6d %- 20.20s %- 33.33s %s\n",
2026 autovar_def[var_no].stack_offset,
2027 autovar_def[var_no].name,
2028 str,
2029 var_value((void *)(stackofs+autovar_def[var_no].stack_offset), 32));
2030
2031 return TRUE;
2032 }
2033 }
2034 }
2035
2036 return FALSE;
2037}
2038
2039void print_vars(ULONG stackofs)
2040{
2041 USHORT n, pos;
2042 BOOL AutoVarsFound=FALSE;
2043
2044/* stackofs += stack_ebp; */
2045 if (1 || func_ofs == pubfunc_ofs) {
2046 for(n = 0; n < var_ofs; n++) {
2047 if (AutoVarsFound==FALSE) {
2048 AutoVarsFound=TRUE;
2049 fprintf(hTrap, "List of auto variables at EBP %p in %s:\n",stackofs, func_name);
2050 fprintf(hTrap,"Offset Name Type Value \n");
2051 fprintf(hTrap,"ÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\n");
2052 }
2053
2054 /* If it's one of the simple types */
2055 if (autovar_def[n].type_idx >= 0x80 && autovar_def[n].type_idx <= 0xDA)
2056 {
2057 fprintf(hTrap, "%- 6d %- 20.20s %- 33.33s %s\n",
2058 autovar_def[n].stack_offset,
2059 autovar_def[n].name,
2060 type_name[autovar_def[n].type_idx-0x80],
2061 var_value((void *)(stackofs+autovar_def[n].stack_offset),
2062 autovar_def[n].type_idx-0x80));
2063 }
2064 else { /* Complex type, check if we know what it is */
2065 if (!search_userdefs(stackofs, n)) {
2066 if (!search_pointers(stackofs, n)) {
2067 fprintf(hTrap, "%- 6d %-20.20s 0x%X\n",
2068 autovar_def[n].stack_offset,
2069 autovar_def[n].name,
2070 autovar_def[n].type_idx);
2071 }
2072 }
2073 }
2074 }
2075 if (AutoVarsFound==FALSE) {
2076 fprintf(hTrap, " No auto variables found in %s.\n", func_name);
2077 }
2078 fprintf(hTrap, "\n");
2079 }
2080}
2081
2082
2083
Note: See TracBrowser for help on using the repository browser.