[2] | 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
|
---|
| 74 | CHAR *ProcessName = "DEBUGGEE.EXE";
|
---|
| 75 | FILE *hTrap;
|
---|
| 76 | static BOOL f32bit = TRUE;
|
---|
| 77 | struct 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 | /*-------------------------------------*/
|
---|
| 130 | APIRET APIENTRY DOSQUERYMODFROMEIP( HMODULE *phMod,
|
---|
| 131 | ULONG *pObjNum,
|
---|
| 132 | ULONG BuffLen,
|
---|
| 133 | PCHAR pBuff,
|
---|
| 134 | ULONG *pOffset,
|
---|
| 135 | PVOID Address );
|
---|
[41] | 136 | /*APIRET APIENTRY DosQueryModFromEIP( HMODULE *phMod,
|
---|
[2] | 137 | ULONG *pObjNum,
|
---|
| 138 | ULONG BuffLen,
|
---|
| 139 | PCHAR pBuff,
|
---|
| 140 | ULONG *pOffset,
|
---|
[41] | 141 | PVOID Address );*/
|
---|
[2] | 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
|
---|
| 150 | RESULTCODES ReturnCodes;
|
---|
| 151 | UCHAR LoadError[40]; /*DosExecPGM buffer */
|
---|
| 152 | USHORT Passes;
|
---|
| 153 | UCHAR Translate[17];
|
---|
| 154 | UCHAR OldStuff[16];
|
---|
| 155 |
|
---|
| 156 | #ifdef USE_DOSDEBUG
|
---|
| 157 | void GetObjects(struct debug_buffer * pDbgBuf,HMODULE hMte,PSZ pName);
|
---|
| 158 | #endif
|
---|
| 159 |
|
---|
| 160 | VOID ListModules(VOID);
|
---|
| 161 | void CheckMem(PVOID Ptr,PSZ MemoryName);
|
---|
| 162 | /* Better New WalkStack From John Currier */
|
---|
| 163 | static void WalkStack(PUSHORT StackBottom,PUSHORT StackTop,PUSHORT Ebp,PUSHORT ExceptionAddress);
|
---|
| 164 | int Read16CodeView(int fh,int TrapSeg,int TrapOff,CHAR * FileName);
|
---|
| 165 | int Read32PmDebug(int fh,int TrapSeg,int TrapOff,CHAR * FileName);
|
---|
| 166 | APIRET GetLineNum(CHAR * FileName, ULONG Object,ULONG TrapOffset);
|
---|
| 167 | void GetSymbol(CHAR * SymFileName, ULONG Object,ULONG TrapOffset);
|
---|
| 168 | void print_vars(ULONG stackofs);
|
---|
| 169 |
|
---|
| 170 | ULONG func_ofs;
|
---|
| 171 | ULONG pubfunc_ofs;
|
---|
| 172 | char func_name[128];
|
---|
| 173 | ULONG var_ofs = 0;
|
---|
| 174 |
|
---|
| 175 | struct {
|
---|
| 176 | BYTE name[128];
|
---|
| 177 | ULONG stack_offset;
|
---|
| 178 | USHORT type_idx;
|
---|
| 179 | } autovar_def[100];
|
---|
| 180 |
|
---|
| 181 | HMODULE hMod;
|
---|
| 182 | ULONG ObjNum;
|
---|
| 183 | ULONG Offset;
|
---|
| 184 |
|
---|
| 185 | /*-------------------------------------*/
|
---|
| 186 | CHAR Buffer[CCHMAXPATH];
|
---|
| 187 |
|
---|
| 188 | typedef ULONG * _Seg16 PULONG16;
|
---|
| 189 | APIRET16 APIENTRY16 DOS16SIZESEG( USHORT Seg , PULONG16 Size);
|
---|
| 190 | typedef APIRET16 (APIENTRY16 _PFN16)();
|
---|
| 191 | ULONG APIENTRY DosSelToFlat(ULONG);
|
---|
| 192 | /*-------------------------------------*/
|
---|
| 193 |
|
---|
| 194 | /*- DosQProcStatus interface ----------*/
|
---|
| 195 | APIRET16 APIENTRY16 DOSQPROCSTATUS( ULONG * _Seg16 pBuf, USHORT cbBuf);
|
---|
| 196 | #define CONVERT(fp,QSsel) MAKEP((QSsel),OFFSETOF(fp))
|
---|
| 197 | #pragma pack(1)
|
---|
| 198 | /* Global Data Section */
|
---|
| 199 | typedef struct qsGrec_s {
|
---|
| 200 | ULONG cThrds; /* number of threads in use */
|
---|
| 201 | ULONG Reserved1;
|
---|
| 202 | ULONG Reserved2;
|
---|
| 203 | }qsGrec_t;
|
---|
| 204 |
|
---|
[41] | 205 | #define PADSHORT USHORT pad_sh
|
---|
| 206 | #define PADCHAR UCHAR pad_ch
|
---|
| 207 |
|
---|
[2] | 208 | /* Thread Record structure * Holds all per thread information. */
|
---|
| 209 | typedef 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 */
|
---|
[41] | 219 | PADCHAR;
|
---|
| 220 | PADSHORT;
|
---|
[2] | 221 | } qsTrec_t;
|
---|
| 222 |
|
---|
| 223 | /* Process and Thread Data Section */
|
---|
| 224 | typedef 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 */
|
---|
| 250 | typedef 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 */
|
---|
| 258 | typedef 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 */
|
---|
| 272 | typedef 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 */
|
---|
| 284 | typedef 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 */
|
---|
| 293 | typedef 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 | /*-------------------------*/
|
---|
| 303 | ULONG * pBuf,*pTemp;
|
---|
| 304 | USHORT Selector;
|
---|
| 305 | qsPtrRec_t * pRec;
|
---|
| 306 | qsLrec_t * pLib;
|
---|
| 307 | qsMrec_t * pShrMemRec; /* ptr to shared mem section */
|
---|
| 308 | qsPrec_t * pProc;
|
---|
| 309 | qsTrec_t * pThread;
|
---|
| 310 | ULONG ListedThreads=0;
|
---|
| 311 | APIRET16 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 |
|
---|
| 316 | typedef 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 |
|
---|
| 327 | RETURN_FROM_DISASM CDECL16 DISASM( CHAR * _Seg16 Source, USHORT IPvalue,USHORT segsize );
|
---|
| 328 | RETURN_FROM_DISASM AsmLine;
|
---|
| 329 |
|
---|
| 330 | char *SourceBuffer=0;
|
---|
| 331 | static USHORT BigSeg;
|
---|
| 332 | static ULONG Version[2];
|
---|
| 333 |
|
---|
| 334 | BYTE *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 |
|
---|
| 431 | typedef _PFN16 * _Seg16 PFN16;
|
---|
| 432 | /*-- --*/
|
---|
| 433 | static BOOL InForceExit =FALSE;
|
---|
| 434 |
|
---|
| 435 | /*-------------------------------------*/
|
---|
| 436 | ULONG 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 |
|
---|
| 450 | ULONG _System excHandler(PEXCEPTIONREPORTRECORD pERepRec,
|
---|
| 451 | PLOCALEXCEPTSTRUCT pRegRec2,
|
---|
| 452 | // PREGREC2 pRegRec2,
|
---|
| 453 | PCONTEXTRECORD pCtxRec,
|
---|
| 454 | PVOID pv)
|
---|
| 455 | {
|
---|
| 456 | ULONG rc = XCPT_CONTINUE_SEARCH;
|
---|
[104] | 457 |
|
---|
[2] | 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
|
---|
| 491 | ULONG APIENTRY myHandler (PEXCEPTIONREPORTRECORD pERepRec,
|
---|
| 492 | PEXCEPTIONREGISTRATIONRECORD pERegRec,
|
---|
| 493 | PCONTEXTRECORD pCtxRec,
|
---|
| 494 | PVOID p)
|
---|
| 495 | {
|
---|
| 496 | ULONG rc = XCPT_CONTINUE_SEARCH;
|
---|
[104] | 497 |
|
---|
[2] | 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);
|
---|
[104] | 504 |
|
---|
[2] | 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 |
|
---|
| 524 | static 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';
|
---|
[104] | 532 | }
|
---|
[2] | 533 |
|
---|
| 534 | ULONG 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];
|
---|
[207] | 553 | CHAR *LogPath;
|
---|
[2] | 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 |
|
---|
[207] | 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);
|
---|
[2] | 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
|
---|
[104] | 648 |
|
---|
[2] | 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 */
|
---|
| 764 | APIRET16 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 | }
|
---|
| 776 | APIRET16 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 |
|
---|
| 785 | VOID 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 |
|
---|
| 852 | void 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 |
|
---|
| 876 | PUSHORT Convert(USHORT * _Seg16 p16) {
|
---|
| 877 | return p16;
|
---|
| 878 | }
|
---|
| 879 |
|
---|
| 880 | /* Better New WalkStack From John Currier */
|
---|
| 881 | static 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 |
|
---|
| 1104 | void 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 |
|
---|
| 1268 | typedef struct _SSLINEENTRY32 {
|
---|
| 1269 | unsigned short LineNum;
|
---|
| 1270 | unsigned short FileNum;
|
---|
| 1271 | unsigned long Offset;
|
---|
| 1272 | } SSLINEENTRY32;
|
---|
| 1273 | typedef 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 |
|
---|
| 1281 | typedef 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 |
|
---|
| 1298 | typedef struct DbugRec DBUG, far * DBUGPTR; /* 013 */
|
---|
| 1299 | char szNrPub[128];
|
---|
| 1300 | char szNrLine[128];
|
---|
| 1301 | char 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;
|
---|
| 1306 | unsigned char *pEntTab;
|
---|
| 1307 | unsigned long lfaBase;
|
---|
| 1308 | #pragma pack()
|
---|
| 1309 | /* ------------------------------------------------------------------ */
|
---|
| 1310 |
|
---|
| 1311 | APIRET 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 | }
|
---|
| 1423 | char fname[128],ModName[80];
|
---|
| 1424 | char ename[128],dummy[128];
|
---|
| 1425 |
|
---|
| 1426 | int 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 |
|
---|
| 1548 | USHORT userdef_count;
|
---|
| 1549 | USHORT pointer_count;
|
---|
| 1550 |
|
---|
| 1551 | struct one_userdef_rec {
|
---|
| 1552 | USHORT idx;
|
---|
| 1553 | USHORT type_index;
|
---|
| 1554 | BYTE name[33];
|
---|
| 1555 | } one_userdef[MAX_USERDEFS];
|
---|
| 1556 |
|
---|
| 1557 | struct one_pointer_rec {
|
---|
| 1558 | USHORT idx;
|
---|
| 1559 | USHORT type_index;
|
---|
| 1560 | BYTE type_qual;
|
---|
| 1561 | BYTE name[33];
|
---|
| 1562 | } one_pointer[MAX_POINTERS];
|
---|
| 1563 |
|
---|
| 1564 | int 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;
|
---|
[108] | 1662 | sprintf(szNrPub,"%s %s (%s) %04X:%08lu\n",
|
---|
[2] | 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));
|
---|
[104] | 1826 |
|
---|
[2] | 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;
|
---|
[104] | 1855 |
|
---|
[2] | 1856 | case 1:
|
---|
| 1857 | lseek(fh, sizeof(struct linlist_rec), SEEK_CUR);
|
---|
| 1858 | break;
|
---|
[104] | 1859 |
|
---|
[2] | 1860 | case 2:
|
---|
| 1861 | lseek(fh, sizeof(struct linsourcelist_rec), SEEK_CUR);
|
---|
| 1862 | break;
|
---|
[104] | 1863 |
|
---|
[2] | 1864 | case 3:
|
---|
| 1865 | lseek(fh, sizeof(struct filenam_rec), SEEK_CUR);
|
---|
| 1866 | break;
|
---|
[104] | 1867 |
|
---|
[2] | 1868 | case 4:
|
---|
| 1869 | lseek(fh, sizeof(struct pathtab_rec), SEEK_CUR);
|
---|
| 1870 | break;
|
---|
[104] | 1871 |
|
---|
[2] | 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 |
|
---|
| 1900 | BYTE *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)
|
---|
[108] | 1908 | sprintf(value, "%hhd", *(signed char *)varptr);
|
---|
[2] | 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)
|
---|
[108] | 1924 | sprintf(value, "%Lf", *(long double *)varptr);
|
---|
[2] | 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)
|
---|
[108] | 1934 | sprintf(value, "%hd", *(short *)varptr);
|
---|
[2] | 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 */
|
---|
| 1967 | BOOL 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 |
|
---|
| 1990 | BOOL 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 |
|
---|
| 2039 | void 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 |
|
---|