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

Last change on this file since 41 was 41, checked in by gyoung, 2 years ago

REM out function redefinition (it is defined in BSEDOS.H). Fix a struct declaration.

File size: 77.7 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 <exe.h>
1170#include <newexe.h>
1171#define FOR_EXEHDR 1 /* avoid define conflicts between newexe.h and exe386.h */
1172#ifndef DWORD
1173#define DWORD long int
1174#endif
1175#ifndef WORD
1176#define WORD short int
1177#endif
1178#include <exe386.h>
1179#include <fcntl.h>
1180#include <sys\stat.h>
1181#include <share.h>
1182#include <io.h>
1183/* ------------------------------------------------------------------ */
1184/* Last 8 bytes of 16:16 file when CODEVIEW debugging info is present */
1185#pragma pack(1)
1186 struct _eodbug
1187 {
1188 unsigned short dbug; /* 'NB' signature */
1189 unsigned short ver; /* version */
1190 unsigned long dfaBase; /* size of codeview info */
1191 } eodbug;
1192
1193#define DBUGSIG 0x424E
1194#define SSTMODULES 0x0101
1195#define SSTPUBLICS 0x0102
1196#define SSTTYPES 0x0103
1197#define SSTSYMBOLS 0x0104
1198#define SSTSRCLINES 0x0105
1199#define SSTLIBRARIES 0x0106
1200#define SSTSRCLINES2 0x0109
1201#define SSTSRCLINES32 0x010B
1202
1203 struct _base
1204 {
1205 unsigned short dbug; /* 'NB' signature */
1206 unsigned short ver; /* version */
1207 unsigned long lfoDir; /* file offset to dir entries */
1208 } base;
1209
1210 struct ssDir
1211 {
1212 unsigned short sst; /* SubSection Type */
1213 unsigned short modindex; /* Module index number */
1214 unsigned long lfoStart; /* Start of section */
1215 unsigned short cb; /* Size of section */
1216 } ;
1217
1218 struct ssDir32
1219 {
1220 unsigned short sst; /* SubSection Type */
1221 unsigned short modindex; /* Module index number */
1222 unsigned long lfoStart; /* Start of section */
1223 unsigned long cb; /* Size of section */
1224 } ;
1225
1226 struct ssModule
1227 {
1228 unsigned short csBase; /* code segment base */
1229 unsigned short csOff; /* code segment offset */
1230 unsigned short csLen; /* code segment length */
1231 unsigned short ovrNum; /* overlay number */
1232 unsigned short indxSS; /* Index into sstLib or 0 */
1233 unsigned short reserved;
1234 char csize; /* size of prefix string */
1235 } ssmod;
1236
1237 struct ssModule32
1238 {
1239 unsigned short csBase; /* code segment base */
1240 unsigned long csOff; /* code segment offset */
1241 unsigned long csLen; /* code segment length */
1242 unsigned long ovrNum; /* overlay number */
1243 unsigned short indxSS; /* Index into sstLib or 0 */
1244 unsigned long reserved;
1245 char csize; /* size of prefix string */
1246 } ssmod32;
1247
1248 struct ssPublic
1249 {
1250 unsigned short offset;
1251 unsigned short segment;
1252 unsigned short type;
1253 char csize;
1254 } sspub;
1255
1256 struct ssPublic32
1257 {
1258 unsigned long offset;
1259 unsigned short segment;
1260 unsigned short type;
1261 char csize;
1262 } sspub32;
1263
1264typedef struct _SSLINEENTRY32 {
1265 unsigned short LineNum;
1266 unsigned short FileNum;
1267 unsigned long Offset;
1268} SSLINEENTRY32;
1269typedef struct _FIRSTLINEENTRY32 {
1270 unsigned short LineNum;
1271 unsigned char entry_type;
1272 unsigned char reserved;
1273 unsigned short numlines;
1274 unsigned short segnum;
1275} FIRSTLINEENTRY32;
1276
1277typedef struct _SSFILENUM32 {
1278 unsigned long first_displayable; /* Not used */
1279 unsigned long number_displayable; /* Not used */
1280 unsigned long file_count; /* number of source files */
1281} SSFILENUM32;
1282
1283 struct DbugRec { /* debug info struct ure used in linked * list */
1284 struct DbugRec far *pnext; /* next node *//* 013 */
1285 char far *SourceFile; /* source file name *013 */
1286 unsigned short TypeOfProgram; /* dll or exe *014* */
1287 unsigned short LineNumber; /* line number in source file */
1288 unsigned short OffSet; /* offset into loaded module */
1289 unsigned short Selector; /* code segment 014 */
1290 unsigned short OpCode; /* Opcode replaced with BreakPt */
1291 unsigned long Count; /* count over Break Point */
1292};
1293
1294typedef struct DbugRec DBUG, far * DBUGPTR; /* 013 */
1295char szNrPub[128];
1296char szNrLine[128];
1297char szNrFile[128];
1298 struct new_seg *pseg;
1299 struct o32_obj *pobj; /* Flat .EXE object table entry */
1300 struct ssDir *pDirTab;
1301 struct ssDir32 *pDirTab32;
1302unsigned char *pEntTab;
1303unsigned long lfaBase;
1304#pragma pack()
1305/* ------------------------------------------------------------------ */
1306
1307APIRET GetLineNum(CHAR * FileName, ULONG Object,ULONG TrapOffset) {
1308 APIRET rc;
1309 int ModuleFile;
1310 static struct exe_hdr old;
1311 static struct new_exe new1;
1312 static struct e32_exe e32;
1313 strcpy(szNrPub," N/A ");
1314 strcpy(szNrLine," N/A ");
1315 strcpy(szNrFile," ");
1316 ModuleFile =sopen(FileName,O_RDONLY|O_BINARY,SH_DENYNO);
1317 if (ModuleFile!=-1) {
1318 /* Read old Exe header */
1319 if (read( ModuleFile ,(void *)&old,64)==-1L) {
1320 fprintf(hTrap,"Could Not Read old exe header %d\n",errno);
1321 close(ModuleFile);
1322 return 2;
1323 }
1324 /* Seek to new Exe header */
1325 if (lseek(ModuleFile,(long)E_LFANEW(old),SEEK_SET)==-1L) {
1326 fprintf(hTrap,"Could Not seek to new exe header %d\n",errno);
1327 close(ModuleFile);
1328 return 3;
1329 }
1330 if (read( ModuleFile ,(void *)&new1,64)==-1L) {
1331 fprintf(hTrap,"Could Not read new exe header %d\n",errno);
1332 close(ModuleFile);
1333 return 4;
1334 }
1335 /* Check EXE signature */
1336 if (NE_MAGIC(new1)==E32MAGIC) {
1337 /* Flat 32 executable */
1338 rc=Read32PmDebug(ModuleFile,Object+1,TrapOffset,FileName);
1339 if (rc==0) {
1340 fprintf(hTrap,"%s",szNrFile);
1341 fprintf(hTrap,"%s",szNrLine);
1342 fprintf(hTrap,"%s",szNrPub);
1343 } /* endif */
1344 close(ModuleFile);
1345 /* rc !=0 try with DBG file */
1346 if (rc!=0) {
1347 strcpy(FileName+strlen(FileName)-3,"DBG"); /* Build DBG File name */
1348 ModuleFile =sopen(FileName,O_RDONLY|O_BINARY,SH_DENYNO);
1349 if (ModuleFile!=-1) {
1350 rc=Read32PmDebug(ModuleFile,Object+1,TrapOffset,FileName);
1351 if (rc==0) {
1352 fprintf(hTrap,"%s",szNrFile);
1353 fprintf(hTrap,"%s",szNrLine);
1354 fprintf(hTrap,"%s",szNrPub);
1355 } /* endif */
1356 close(ModuleFile);
1357 }
1358 } /* endif */
1359 return rc;
1360 } else {
1361 if (NE_MAGIC(new1)==NEMAGIC) {
1362 /* 16:16 executable */
1363 if ((pseg = ( struct new_seg *) calloc(NE_CSEG(new1),sizeof( struct new_seg)))==NULL) {
1364 fprintf(hTrap,"Out of memory!");
1365 close(ModuleFile);
1366 return -1;
1367 }
1368 if (lseek(ModuleFile,E_LFANEW(old)+NE_SEGTAB(new1),SEEK_SET)==-1L) {
1369 fprintf(hTrap,"Error %u seeking segment table in %s\n",errno,FileName);
1370 free(pseg);
1371 close(ModuleFile);
1372 return 9;
1373 }
1374
1375 if (read(ModuleFile,(void *)pseg,NE_CSEG(new1)*sizeof( struct new_seg))==-1) {
1376 fprintf(hTrap,"Error %u reading segment table from %s\n",errno,FileName);
1377 free(pseg);
1378 close(ModuleFile);
1379 return 10;
1380 }
1381 rc=Read16CodeView(ModuleFile,Object+1,TrapOffset,FileName);
1382 if (rc==0) {
1383 fprintf(hTrap,"%s",szNrFile);
1384 fprintf(hTrap,"%s",szNrLine);
1385 fprintf(hTrap,"%s",szNrPub);
1386 } /* endif */
1387 free(pseg);
1388 close(ModuleFile);
1389 /* rc !=0 try with DBG file */
1390 if (rc!=0) {
1391 strcpy(FileName+strlen(FileName)-3,"DBG"); /* Build DBG File name */
1392 ModuleFile =sopen(FileName,O_RDONLY|O_BINARY,SH_DENYNO);
1393 if (ModuleFile!=-1) {
1394 rc=Read16CodeView(ModuleFile,Object+1,TrapOffset,FileName);
1395 if (rc==0) {
1396 fprintf(hTrap,"%s",szNrFile);
1397 fprintf(hTrap,"%s",szNrLine);
1398 fprintf(hTrap,"%s",szNrPub);
1399 } /* endif */
1400 close(ModuleFile);
1401 }
1402 } /* endif */
1403 return rc;
1404
1405 } else {
1406 /* Unknown executable */
1407 fprintf(hTrap,"Could Not find exe signature");
1408 close(ModuleFile);
1409 return 11;
1410 }
1411 }
1412 /* Read new Exe header */
1413 } else {
1414 fprintf(hTrap,"Could Not open Module File %d",errno);
1415 return 1;
1416 } /* endif */
1417 return 0;
1418}
1419char fname[128],ModName[80];
1420char ename[128],dummy[128];
1421
1422int Read16CodeView(int fh,int TrapSeg,int TrapOff,CHAR * FileName) {
1423 static unsigned short int offset,NrPublic,NrLine,NrEntry,numdir,namelen,numlines,line;
1424 static int ModIndex;
1425 static int bytesread,i,j;
1426 ModIndex=0;
1427 /* See if any CODEVIEW info */
1428 if (lseek(fh,-8L,SEEK_END)==-1) {
1429 fprintf(hTrap,"Error %u seeking CodeView table in %s\n",errno,FileName);
1430 return(18);
1431 }
1432
1433 if (read(fh,(void *)&eodbug,8)==-1) {
1434 fprintf(hTrap,"Error %u reading debug info from %s\n",errno,FileName);
1435 return(19);
1436 }
1437 if (eodbug.dbug!=DBUGSIG) {
1438 /* fprintf(hTrap,"\nNo CodeView information stored.\n"); */
1439 return(100);
1440 }
1441
1442 if ((lfaBase=lseek(fh,-eodbug.dfaBase,SEEK_END))==-1L) {
1443 fprintf(hTrap,"Error %u seeking base codeview data in %s\n",errno,FileName);
1444 return(20);
1445 }
1446
1447 if (read(fh,(void *)&base,8)==-1) {
1448 fprintf(hTrap,"Error %u reading base codeview data in %s\n",errno,FileName);
1449 return(21);
1450 }
1451
1452 if (lseek(fh,base.lfoDir-8,SEEK_CUR)==-1) {
1453 fprintf(hTrap,"Error %u seeking dir codeview data in %s\n",errno,FileName);
1454 return(22);
1455 }
1456
1457 if (read(fh,(void *)&numdir,2)==-1) {
1458 fprintf(hTrap,"Error %u reading dir codeview data in %s\n",errno,FileName);
1459 return(23);
1460 }
1461
1462 /* Read dir table into buffer */
1463 if (( pDirTab = ( struct ssDir *) calloc(numdir,sizeof( struct ssDir)))==NULL) {
1464 fprintf(hTrap,"Out of memory!");
1465 return(-1);
1466 }
1467
1468 if (read(fh,(void *)pDirTab,numdir*sizeof( struct ssDir))==-1) {
1469 fprintf(hTrap,"Error %u reading codeview dir table from %s\n",errno,FileName);
1470 free(pDirTab);
1471 return(24);
1472 }
1473
1474 i=0;
1475 while (i<numdir) {
1476 if (pDirTab[i].sst!=SSTMODULES) {
1477 i++;
1478 continue;
1479 }
1480 NrPublic=0x0;
1481 NrLine=0x0;
1482 /* point to subsection */
1483 lseek(fh, pDirTab[i].lfoStart + lfaBase, SEEK_SET);
1484 read(fh,(void *)&ssmod.csBase,sizeof(ssmod));
1485 read(fh,(void *)ModName,(unsigned)ssmod.csize);
1486 ModIndex=pDirTab[i].modindex;
1487 ModName[ssmod.csize]='\0';
1488 i++;
1489 while (pDirTab[i].modindex ==ModIndex && i<numdir) {
1490 /* point to subsection */
1491 lseek(fh, pDirTab[i].lfoStart + lfaBase, SEEK_SET);
1492 switch(pDirTab[i].sst) {
1493 case SSTPUBLICS:
1494 bytesread=0;
1495 while (bytesread < pDirTab[i].cb) {
1496 bytesread += read(fh,(void *)&sspub.offset,sizeof(sspub));
1497 bytesread += read(fh,(void *)ename,(unsigned)sspub.csize);
1498 ename[sspub.csize]='\0';
1499 if ((sspub.segment==TrapSeg) &&
1500 (sspub.offset<=TrapOff) &&
1501 (sspub.offset>=NrPublic)) {
1502 NrPublic=sspub.offset;
1503 sprintf(szNrPub,"%s %s (%s) %04hX:%04hX\n",
1504 (sspub.type==1) ? " Abs" : " ",ename,ModName,
1505 sspub.segment, sspub.offset
1506 );
1507 }
1508 }
1509 break;
1510
1511 case SSTSRCLINES2:
1512 case SSTSRCLINES:
1513 if (TrapSeg!=ssmod.csBase) break;
1514 namelen=0;
1515 read(fh,(void *)&namelen,1);
1516 read(fh,(void *)ename,namelen);
1517 ename[namelen]='\0';
1518 /* skip 2 zero bytes */
1519 if (pDirTab[i].sst==SSTSRCLINES2) read(fh,(void *)&numlines,2);
1520 read(fh,(void *)&numlines,2);
1521 for (j=0;j<numlines;j++) {
1522 read(fh,(void *)&line,2);
1523 read(fh,(void *)&offset,2);
1524 if (offset<=TrapOff && offset>=NrLine) {
1525 NrLine=offset;
1526 sprintf(szNrLine,"% 6hu", line);
1527 sprintf(szNrFile,"% 13.13s ", ename);
1528 /*sprintf(szNrLine,"%04hX:%04hX line #%hu (%s) (%s)\n",
1529 ssmod.csBase,offset,line,ModName,ename); */
1530 }
1531 }
1532 break;
1533 } /* end switch */
1534 i++;
1535 } /* end while modindex */
1536 } /* End While i < numdir */
1537 free(pDirTab);
1538 return(0);
1539}
1540
1541#define MAX_USERDEFS 150
1542#define MAX_POINTERS 150
1543
1544USHORT userdef_count;
1545USHORT pointer_count;
1546
1547struct one_userdef_rec {
1548 USHORT idx;
1549 USHORT type_index;
1550 BYTE name[33];
1551} one_userdef[MAX_USERDEFS];
1552
1553struct one_pointer_rec {
1554 USHORT idx;
1555 USHORT type_index;
1556 BYTE type_qual;
1557 BYTE name[33];
1558} one_pointer[MAX_POINTERS];
1559
1560int Read32PmDebug(int fh,int TrapSeg,int TrapOff,CHAR * FileName) {
1561 static unsigned int CurrSymSeg, NrSymbol,offset,NrPublic,NrFile,NrLine,NrEntry,numdir,namelen,numlines,line;
1562 static int ModIndex;
1563 static int bytesread,i,j;
1564 static int pOffset;
1565 static SSLINEENTRY32 LineEntry;
1566 static SSFILENUM32 FileInfo;
1567 static FIRSTLINEENTRY32 FirstLine;
1568 static BYTE dump_vars = FALSE;
1569 static USHORT idx;
1570 static BOOL read_types;
1571 static LONG lSize;
1572 static BOOL is_new_debug;
1573
1574 ModIndex=0;
1575 /* See if any CODEVIEW info */
1576 if (lseek(fh,-8L,SEEK_END)==-1) {
1577 fprintf(hTrap,"Error %u seeking CodeView table in %s\n",errno,FileName);
1578 return(18);
1579 }
1580
1581 if (read(fh,(void *)&eodbug,8)==-1) {
1582 fprintf(hTrap,"Error %u reading debug info from %s\n",errno,FileName);
1583 return(19);
1584 }
1585 if (eodbug.dbug!=DBUGSIG) {
1586 /*fprintf(hTrap,"\nNo CodeView information stored.\n");*/
1587 return(100);
1588 }
1589
1590 if ((lfaBase=lseek(fh,-eodbug.dfaBase,SEEK_END))==-1L) {
1591 fprintf(hTrap,"Error %u seeking base codeview data in %s\n",errno,FileName);
1592 return(20);
1593 }
1594
1595 if (read(fh,(void *)&base,8)==-1) {
1596 fprintf(hTrap,"Error %u reading base codeview data in %s\n",errno,FileName);
1597 return(21);
1598 }
1599
1600 if (lseek(fh,base.lfoDir-8+4,SEEK_CUR)==-1) {
1601 fprintf(hTrap,"Error %u seeking dir codeview data in %s\n",errno,FileName);
1602 return(22);
1603 }
1604
1605 if (read(fh,(void *)&numdir,4)==-1) {
1606 fprintf(hTrap,"Error %u reading dir codeview data in %s\n",errno,FileName);
1607 return(23);
1608 }
1609
1610 /* Read dir table into buffer */
1611 if (( pDirTab32 = ( struct ssDir32 *) calloc(numdir,sizeof( struct ssDir32)))==NULL) {
1612 fprintf(hTrap,"Out of memory!");
1613 return(-1);
1614 }
1615
1616 if (read(fh,(void *)pDirTab32,numdir*sizeof( struct ssDir32))==-1) {
1617 fprintf(hTrap,"Error %u reading codeview dir table from %s\n",errno,FileName);
1618 free(pDirTab32);
1619 return(24);
1620 }
1621
1622 i=0;
1623 while (i<numdir) {
1624 if ( pDirTab32[i].sst !=SSTMODULES) {
1625 i++;
1626 continue;
1627 }
1628 NrPublic=0x0;
1629 NrSymbol=0;
1630 NrLine=0x0;
1631 NrFile=0x0;
1632 CurrSymSeg = 0;
1633 /* point to subsection */
1634 lseek(fh, pDirTab32[i].lfoStart + lfaBase, SEEK_SET);
1635 read(fh,(void *)&ssmod32.csBase,sizeof(ssmod32));
1636 read(fh,(void *)ModName,(unsigned)ssmod32.csize);
1637 ModIndex=pDirTab32[i].modindex;
1638 ModName[ssmod32.csize]='\0';
1639 i++;
1640
1641 read_types = FALSE;
1642
1643 while (pDirTab32[i].modindex ==ModIndex && i<numdir) {
1644 /* point to subsection */
1645 lseek(fh, pDirTab32[i].lfoStart + lfaBase, SEEK_SET);
1646 switch(pDirTab32[i].sst) {
1647 case SSTPUBLICS:
1648 bytesread=0;
1649 while (bytesread < pDirTab32[i].cb) {
1650 bytesread += read(fh,(void *)&sspub32.offset,sizeof(sspub32));
1651 bytesread += read(fh,(void *)ename,(unsigned)sspub32.csize);
1652 ename[sspub32.csize]='\0';
1653 if ((sspub32.segment==TrapSeg) &&
1654 (sspub32.offset<=TrapOff) &&
1655 (sspub32.offset>=NrPublic)) {
1656 NrPublic = pubfunc_ofs = sspub32.offset;
1657 read_types = TRUE;
1658 sprintf(szNrPub,"%s %s (%s) %04X:%08X\n",
1659 (sspub32.type==1) ? " Abs" : " ",ename,ModName,
1660 sspub32.segment, sspub32.offset
1661 );
1662 }
1663 }
1664 break;
1665
1666 /* Read symbols, so we can dump the variables on the stack */
1667 case SSTSYMBOLS:
1668 if (TrapSeg!=ssmod32.csBase) break;
1669
1670 bytesread=0;
1671 while (bytesread < pDirTab32[i].cb) {
1672 static USHORT usLength;
1673 static BYTE b1, b2;
1674 static BYTE bType, *ptr;
1675 static ULONG ofs;
1676 static ULONG last_addr = 0;
1677 static BYTE str[256];
1678 static struct symseg_rec symseg;
1679 static struct symauto_rec symauto;
1680 static struct symproc_rec symproc;
1681
1682 /* Read the length of this subentry */
1683 bytesread += read(fh, &b1, 1);
1684 if (b1 & 0x80) {
1685 bytesread += read(fh, &b2, 1);
1686 usLength = ((b1 & 0x7F) << 8) + b2;
1687 }
1688 else
1689 usLength = b1;
1690
1691 ofs = tell(fh);
1692
1693 bytesread += read(fh, &bType, 1);
1694
1695 switch(bType) {
1696 case SYM_CHANGESEG:
1697 read(fh, &symseg, sizeof(symseg));
1698 CurrSymSeg = symseg.seg_no;
1699 break;
1700
1701 case SYM_PROC:
1702 case SYM_CPPPROC:
1703 read(fh, &symproc, sizeof(symproc));
1704 read(fh, str, symproc.name_len);
1705 str[symproc.name_len] = 0;
1706
1707 if ((CurrSymSeg == TrapSeg) &&
1708 (symproc.offset<=TrapOff) &&
1709 (symproc.offset>=NrSymbol)) {
1710
1711 dump_vars = TRUE;
1712 var_ofs = 0;
1713 NrSymbol = symproc.offset;
1714 func_ofs = symproc.offset;
1715
1716 strcpy(func_name, str);
1717 }
1718 else {
1719 dump_vars = FALSE;
1720 }
1721 break;
1722
1723 case SYM_AUTO:
1724 if (!dump_vars)
1725 break;
1726
1727 read(fh, &symauto, sizeof(symauto));
1728 read(fh, str, symauto.name_len);
1729 str[symauto.name_len] = 0;
1730
1731 strcpy(autovar_def[var_ofs].name, str);
1732 autovar_def[var_ofs].stack_offset = symauto.stack_offset;
1733 autovar_def[var_ofs].type_idx = symauto.type_idx;
1734 var_ofs++;
1735 break;
1736
1737 }
1738
1739 bytesread += usLength;
1740
1741 lseek(fh, ofs+usLength, SEEK_SET);
1742 }
1743 break;
1744
1745 case SSTTYPES:
1746// if (ModIndex != TrapSeg)
1747 if (!read_types)
1748 break;
1749
1750 bytesread=0;
1751 idx = 0x200;
1752 userdef_count = 0;
1753 pointer_count = 0;
1754 while (bytesread < pDirTab32[i].cb) {
1755 static struct type_rec type;
1756 static struct type_userdefrec udef;
1757 static struct type_pointerrec point;
1758 static struct type_funcrec func;
1759 static struct type_structrec struc;
1760 static struct type_list1 list1;
1761 static struct type_list2 list2;
1762 static struct type_list2_1 list2_1;
1763 static ULONG ofs;
1764 static BYTE str[256], b1, b2;
1765 static USHORT n;
1766
1767 /* Read the length of this subentry */
1768 ofs = tell(fh);
1769
1770 read(fh, &type, sizeof(type));
1771 bytesread += sizeof(type);
1772
1773 switch(type.type) {
1774 case TYPE_USERDEF:
1775 if (userdef_count > MAX_USERDEFS)
1776 break;
1777
1778 read(fh, &udef, sizeof(udef));
1779 read(fh, str, udef.name_len);
1780 str[udef.name_len] = 0;
1781
1782 // Insert userdef in table
1783 one_userdef[userdef_count].idx = idx;
1784 one_userdef[userdef_count].type_index = udef.type_index;
1785 memcpy(one_userdef[userdef_count].name, str, min(udef.name_len+1, 32));
1786 one_userdef[userdef_count].name[32] = 0;
1787 userdef_count++;
1788 break;
1789
1790 case TYPE_POINTER:
1791 if (pointer_count > MAX_POINTERS)
1792 break;
1793
1794 read(fh, &point, sizeof(point));
1795 read(fh, str, point.name_len);
1796 str[point.name_len] = 0;
1797
1798 // Insert userdef in table
1799 one_pointer[pointer_count].idx = idx;
1800 one_pointer[pointer_count].type_index = point.type_index;
1801 memcpy(one_pointer[pointer_count].name, str, min(point.name_len+1, 32));
1802 one_pointer[pointer_count].name[32] = 0;
1803 one_pointer[pointer_count].type_qual = type.type_qual;
1804 pointer_count++;
1805 break;
1806 }
1807
1808 ++idx;
1809
1810 bytesread += type.length;
1811
1812 lseek(fh, ofs+type.length+2, SEEK_SET);
1813 }
1814 break;
1815
1816 case SSTSRCLINES32:
1817 if (TrapSeg!=ssmod32.csBase) break;
1818
1819 /* read first line */
1820 do {
1821 read(fh,(void *)&FirstLine,sizeof(FirstLine));
1822
1823 if (FirstLine.LineNum!=0) {
1824 fprintf(hTrap,"Missing Line table information\n");
1825 break;
1826 } /* endif */
1827 numlines= FirstLine.numlines;
1828 /* Other type of data skip 4 more bytes */
1829 if (FirstLine.entry_type < 4) {
1830 read(fh, (void *)&lSize, 4);
1831 if (FirstLine.entry_type == 3)
1832 lseek(fh,lSize,SEEK_CUR);
1833 }
1834 } while(FirstLine.entry_type == 3);
1835
1836 for (j=0;j<numlines;j++) {
1837 switch (FirstLine.entry_type) {
1838 case 0:
1839 read(fh,(void *)&LineEntry,sizeof(LineEntry));
1840 /* Changed by Kim Rasmussen 26/06 1996 to ignore linenumber 0 */
1841 /* if (LineEntry.Offset+ssmod32.csOff<=TrapOff && LineEntry.Offset+ssmod32.csOff>=NrLine) { */
1842 if (LineEntry.LineNum && LineEntry.Offset+ssmod32.csOff<=TrapOff && LineEntry.Offset+ssmod32.csOff>=NrLine) {
1843 NrLine=LineEntry.Offset;
1844 NrFile=LineEntry.FileNum;
1845 /*pOffset =sprintf(szNrLine,"%04X:%08X line #%hu ",
1846 ssmod32.csBase,LineEntry.Offset,
1847 LineEntry.LineNum);*/
1848 sprintf(szNrLine,"% 6hu", LineEntry.LineNum);
1849 }
1850 break;
1851
1852 case 1:
1853 lseek(fh, sizeof(struct linlist_rec), SEEK_CUR);
1854 break;
1855
1856 case 2:
1857 lseek(fh, sizeof(struct linsourcelist_rec), SEEK_CUR);
1858 break;
1859
1860 case 3:
1861 lseek(fh, sizeof(struct filenam_rec), SEEK_CUR);
1862 break;
1863
1864 case 4:
1865 lseek(fh, sizeof(struct pathtab_rec), SEEK_CUR);
1866 break;
1867
1868 }
1869 }
1870 if (NrFile!=0) {
1871 read(fh,(void *)&FileInfo,sizeof(FileInfo));
1872 namelen=0;
1873 for (j=1;j<=FileInfo.file_count;j++) {
1874 namelen=0;
1875 read(fh,(void *)&namelen,1);
1876 read(fh,(void *)ename,namelen);
1877 if (j==NrFile) break;
1878 }
1879 ename[namelen]='\0';
1880 /* pOffset=sprintf(szNrLine+pOffset," (%s) (%s)\n",ename,ModName);*/
1881 sprintf(szNrFile,"% 13.13s ",ename);
1882 } else {
1883 /* strcat(szNrLine,"\n"); avoid new line for empty name fill */
1884 strcpy(szNrFile," ");
1885 } /* endif */
1886 break;
1887 } /* end switch */
1888
1889 i++;
1890 } /* end while modindex */
1891 } /* End While i < numdir */
1892 free(pDirTab32);
1893 return(0);
1894}
1895
1896BYTE *var_value(void *varptr, BYTE type)
1897{
1898 static BYTE value[128];
1899 APIRET rc;
1900
1901 strcpy(value, "Unknown");
1902
1903 if (type == 0)
1904 sprintf(value, "%hd", *(signed char *)varptr);
1905 else if (type == 1)
1906 sprintf(value, "%hd", *(signed short *)varptr);
1907 else if (type == 2)
1908 sprintf(value, "%ld", *(signed long *)varptr);
1909 else if (type == 4)
1910 sprintf(value, "%hu", *(BYTE *)varptr);
1911 else if (type == 5)
1912 sprintf(value, "%hu", *(USHORT *)varptr);
1913 else if (type == 6)
1914 sprintf(value, "%lu", *(ULONG *)varptr);
1915 else if (type == 8)
1916 sprintf(value, "%f", *(float *)varptr);
1917 else if (type == 9)
1918 sprintf(value, "%f", *(double *)varptr);
1919 else if (type == 10)
1920 sprintf(value, "%f", *(long double *)varptr);
1921 else if (type == 16)
1922 sprintf(value, "%s", *(char *)varptr ? "TRUE" : "FALSE");
1923 else if (type == 17)
1924 sprintf(value, "%s", *(short *)varptr ? "TRUE" : "FALSE");
1925 else if (type == 18)
1926 sprintf(value, "%s", *(long *)varptr ? "TRUE" : "FALSE");
1927 else if (type == 20)
1928 sprintf(value, "%c", *(char *)varptr);
1929 else if (type == 21)
1930 sprintf(value, "%lc", *(short *)varptr);
1931 else if (type == 22)
1932 sprintf(value, "%lc", *(long *)varptr);
1933 else if (type == 23)
1934 sprintf(value, "void");
1935 else if (type >= 32) {
1936 ULONG Size,Attr;
1937 Size=1;
1938 rc=DosQueryMem((void*)*(ULONG *)varptr,&Size,&Attr);
1939 if (rc) {
1940 sprintf(value, "0x%p invalid", *(ULONG *)varptr);
1941 } else {
1942 sprintf(value, "0x%p", *(ULONG *)varptr);
1943 if (Attr&PAG_FREE) {
1944 strcat(value," unallocated memory");
1945 } else {
1946 if ((Attr&PAG_COMMIT)==0x0U) {
1947 strcat(value," uncommited");
1948 } /* endif */
1949 if ((Attr&PAG_WRITE)==0x0U) {
1950 strcat(value," unwritable");
1951 } /* endif */
1952 if ((Attr&PAG_READ)==0x0U) {
1953 strcat(value," unreadable");
1954 } /* endif */
1955 } /* endif */
1956 } /* endif */
1957 }
1958
1959 return value;
1960}
1961
1962/* Search the table of userdef's - return TRUE if found */
1963BOOL search_userdefs(ULONG stackofs, USHORT var_no)
1964{
1965 USHORT pos;
1966
1967 for(pos = 0; pos < userdef_count && one_userdef[pos].idx != autovar_def[var_no].type_idx; pos++);
1968
1969 if (pos < userdef_count) {
1970 if (one_userdef[pos].type_index >= 0x80 && one_userdef[pos].type_index <= 0xDA) {
1971 fprintf(hTrap, "%- 6d %- 20.20s %- 33.33s %s\n",
1972 autovar_def[var_no].stack_offset,
1973 autovar_def[var_no].name,
1974 one_userdef[pos].name,
1975 var_value((void *)(stackofs+autovar_def[var_no].stack_offset),
1976 one_userdef[pos].type_index-0x80));
1977 return TRUE;
1978 }
1979 else /* If the result isn't a simple type, let's act as we didn't find it */
1980 return FALSE;
1981 }
1982
1983 return FALSE;
1984}
1985
1986BOOL search_pointers(ULONG stackofs, USHORT var_no)
1987{
1988 USHORT pos, upos;
1989 static BYTE str[35];
1990 BYTE type_index;
1991
1992 for(pos = 0; pos < pointer_count && one_pointer[pos].idx != autovar_def[var_no].type_idx; pos++);
1993
1994 if (pos < pointer_count) {
1995 if (one_pointer[pos].type_index >= 0x80 && one_pointer[pos].type_index <= 0xDA) {
1996 strcpy(str, type_name[one_pointer[pos].type_index-0x80]);
1997 strcat(str, " *");
1998 fprintf(hTrap, "%- 6d %- 20.20s %- 33.33s %s\n",
1999 autovar_def[var_no].stack_offset,
2000 autovar_def[var_no].name,
2001 str,
2002 var_value((void *)(stackofs+autovar_def[var_no].stack_offset), 32));
2003 return TRUE;
2004 }
2005 else { /* If the result isn't a simple type, look for it in the other lists */
2006 for(upos = 0; upos < userdef_count && one_userdef[upos].idx != one_pointer[pos].type_index; upos++);
2007
2008 if (upos < userdef_count) {
2009 strcpy(str, one_userdef[upos].name);
2010 strcat(str, " *");
2011 fprintf(hTrap, "%- 6d %- 20.20s %- 33.33s %s\n",
2012 autovar_def[var_no].stack_offset,
2013 autovar_def[var_no].name,
2014 str,
2015 var_value((void *)(stackofs+autovar_def[var_no].stack_offset), 32));
2016 return TRUE;
2017 }
2018 else { /* If it isn't a userdef, for now give up and just print as much as we know */
2019 sprintf(str, "Pointer to type 0x%X", one_pointer[pos].type_index);
2020
2021 fprintf(hTrap, "%- 6d %- 20.20s %- 33.33s %s\n",
2022 autovar_def[var_no].stack_offset,
2023 autovar_def[var_no].name,
2024 str,
2025 var_value((void *)(stackofs+autovar_def[var_no].stack_offset), 32));
2026
2027 return TRUE;
2028 }
2029 }
2030 }
2031
2032 return FALSE;
2033}
2034
2035void print_vars(ULONG stackofs)
2036{
2037 USHORT n, pos;
2038 BOOL AutoVarsFound=FALSE;
2039
2040/* stackofs += stack_ebp; */
2041 if (1 || func_ofs == pubfunc_ofs) {
2042 for(n = 0; n < var_ofs; n++) {
2043 if (AutoVarsFound==FALSE) {
2044 AutoVarsFound=TRUE;
2045 fprintf(hTrap, "List of auto variables at EBP %p in %s:\n",stackofs, func_name);
2046 fprintf(hTrap,"Offset Name Type Value \n");
2047 fprintf(hTrap,"ÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\n");
2048 }
2049
2050 /* If it's one of the simple types */
2051 if (autovar_def[n].type_idx >= 0x80 && autovar_def[n].type_idx <= 0xDA)
2052 {
2053 fprintf(hTrap, "%- 6d %- 20.20s %- 33.33s %s\n",
2054 autovar_def[n].stack_offset,
2055 autovar_def[n].name,
2056 type_name[autovar_def[n].type_idx-0x80],
2057 var_value((void *)(stackofs+autovar_def[n].stack_offset),
2058 autovar_def[n].type_idx-0x80));
2059 }
2060 else { /* Complex type, check if we know what it is */
2061 if (!search_userdefs(stackofs, n)) {
2062 if (!search_pointers(stackofs, n)) {
2063 fprintf(hTrap, "%- 6d %-20.20s 0x%X\n",
2064 autovar_def[n].stack_offset,
2065 autovar_def[n].name,
2066 autovar_def[n].type_idx);
2067 }
2068 }
2069 }
2070 }
2071 if (AutoVarsFound==FALSE) {
2072 fprintf(hTrap, " No auto variables found in %s.\n", func_name);
2073 }
2074 fprintf(hTrap, "\n");
2075 }
2076}
2077
2078
2079
Note: See TracBrowser for help on using the repository browser.