summaryrefslogtreecommitdiffstats
path: root/sal/osl/os2/debug.c
diff options
context:
space:
mode:
Diffstat (limited to 'sal/osl/os2/debug.c')
-rw-r--r--sal/osl/os2/debug.c2153
1 files changed, 0 insertions, 2153 deletions
diff --git a/sal/osl/os2/debug.c b/sal/osl/os2/debug.c
deleted file mode 100644
index 3de1ae22ecea..000000000000
--- a/sal/osl/os2/debug.c
+++ /dev/null
@@ -1,2153 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2000, 2010 Oracle and/or its affiliates.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org. If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-/*
- *@@sourcefile debug.c:
- * this file contains debugging functions for the
- * exception handlers in except.c.
- *
- * This code is capable of unwinding the stack from
- * a given address and trying to get function names
- * and source line numbers, either from the respective
- * module's debug code (if present) or from a SYM file,
- * which is searched for in the directory of the module
- * or in ?:\OS2\PDPSI\PMDF\WARP4.
- *
- * This file incorporates code from the following:
- * -- Marc Fiammante, John Currier, Kim Rasmussen,
- * Anthony Cruise (EXCEPT3.ZIP package for a generic
- * exception handling DLL, available at Hobbes).
- *
- * Usage: All OS/2 programs.
- *
- * Note: Version numbering in this file relates to XWorkplace version
- * numbering.
- *
- *@@changed V0.9.0 [umoeller]: made some declarations C++-compatible
- *@@changed V0.9.1 (2000-01-30) [umoeller]: greatly cleaned up this file
- *
- *@@header "helpers\debug.h"
- */
-
-/*
- * This file Copyright (C) 1992-99 Ulrich M�ller,
- * Kim Rasmussen,
- * Marc Fiammante,
- * John Currier,
- * Anthony Cruise.
- * This file is part of the "XWorkplace helpers" source package.
- *
- * 2009-06-15 published under LGPL3 with Ulrich M�ller permission.
- *
- */
-
-//#define DEBUG_SYMDUMP // enable to dump sym file to log
-
-//YD commented, since we need unsigned char BYTE!
-//#define OS2EMX_PLAIN_CHAR
-//Also gcc char is signed, while most structures requires unsigned data!
-//Raised limits for all fields!
-
- // this is needed for "os2emx.h"; if this is defined,
- // emx will define PSZ as _signed_ char, otherwise
- // as unsigned char
-
-#define INCL_DOSPROCESS
-#define INCL_DOSMODULEMGR
-#define INCL_DOSMISC
-#define INCL_DOSERRORS
-#include <os2.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#define DONT_REPLACE_MALLOC
-#include "helpers\setup.h" // code generation and debugging options
-
-#include "helpers\debug.h"
-#include "helpers\dosh.h"
-
-#pragma hdrstop
-
-#include <fcntl.h>
-#ifdef __EMX__
- #include <sys\types.h> // required for sys\stat.h; UM 99-10-22
-#endif
-#include <sys\stat.h>
-#include <share.h>
-#include <io.h>
-
-#ifndef DWORD
-#define DWORD unsigned long
-#endif
-#ifndef WORD
-#define WORD unsigned short
-#endif
-
-#pragma stack16(512)
-#define HF_STDERR 2
-
-/*
- *@@category: Helpers\Control program helpers\Exceptions/debugging
- * See except.c and debug.c.
- */
-
-/* ******************************************************************
- *
- * Global variables
- *
- ********************************************************************/
-
-// this specifies whether we're dealing with 32-bit code;
-// this gets changed whenever 16-bit count is detected
-static BOOL f32bit = TRUE;
-
-/*
- * Global variables for Read32PmDebug:
- *
- */
-
-ULONG func_ofs;
-ULONG pubfunc_ofs;
-//YD 17/07/06 c++ namespace can generate really long
-//YD names, use a large buffer!
-char func_name[16*1024];
-ULONG var_ofs = 0;
-
-struct {
- BYTE name[128];
- ULONG stack_offset;
- USHORT type_idx;
-} autovar_def[1024];
-
-#pragma pack(1)
-
-BYTE *type_name[] =
-{
- "8 bit signed ",
- "16 bit signed ",
- "32 bit signed ",
- "Unknown (0x83) ",
- "8 bit unsigned ",
- "16 bit unsigned ",
- "32 bit unsigned ",
- "Unknown (0x87) ",
- "32 bit real ",
- "64 bit real ",
- "80 bit real ",
- "Unknown (0x8B) ",
- "64 bit complex ",
- "128 bit complex ",
- "160 bit complex ",
- "Unknown (0x8F) ",
- "8 bit boolean ",
- "16 bit boolean ",
- "32 bit boolean ",
- "Unknown (0x93) ",
- "8 bit character ",
- "16 bit characters ",
- "32 bit characters ",
- "void ",
- "15 bit unsigned ",
- "24 bit unsigned ",
- "31 bit unsigned ",
- "Unknown (0x9B) ",
- "Unknown (0x9C) ",
- "Unknown (0x9D) ",
- "Unknown (0x9E) ",
- "Unknown (0x9F) ",
- "near pointer to 8 bit signed ",
- "near pointer to 16 bit signed ",
- "near pointer to 32 bit signed ",
- "Unknown (0xA3) ",
- "near pointer to 8 bit unsigned ",
- "near pointer to 16 bit unsigned ",
- "near pointer to 32 bit unsigned ",
- "Unknown (0xA7) ",
- "near pointer to 32 bit real ",
- "near pointer to 64 bit real ",
- "near pointer to 80 bit real ",
- "Unknown (0xAB) ",
- "near pointer to 64 bit complex ",
- "near pointer to 128 bit complex ",
- "near pointer to 160 bit complex ",
- "Unknown (0xAF) ",
- "near pointer to 8 bit boolean ",
- "near pointer to 16 bit boolean ",
- "near pointer to 32 bit boolean ",
- "Unknown (0xB3) ",
- "near pointer to 8 bit character ",
- "near pointer to 16 bit characters",
- "near pointer to 32 bit characters",
- "near pointer to void ",
- "near pointer to 15 bit unsigned ",
- "near pointer to 24 bit unsigned ",
- "near pointer to 31 bit unsigned ",
- "Unknown (0xBB) ",
- "Unknown (0xBC) ",
- "Unknown (0xBD) ",
- "Unknown (0xBE) ",
- "Unknown (0xBF) ",
- "far pointer to 8 bit signed ",
- "far pointer to 16 bit signed ",
- "far pointer to 32 bit signed ",
- "Unknown (0xC3) ",
- "far pointer to 8 bit unsigned ",
- "far pointer to 16 bit unsigned ",
- "far pointer to 32 bit unsigned ",
- "Unknown (0xC7) ",
- "far pointer to 32 bit real ",
- "far pointer to 64 bit real ",
- "far pointer to 80 bit real ",
- "Unknown (0xCB) ",
- "far pointer to 64 bit complex ",
- "far pointer to 128 bit complex ",
- "far pointer to 160 bit complex ",
- "Unknown (0xCF) ",
- "far pointer to 8 bit boolean ",
- "far pointer to 16 bit boolean ",
- "far pointer to 32 bit boolean ",
- "Unknown (0xD3) ",
- "far pointer to 8 bit character ",
- "far pointer to 16 bit characters ",
- "far pointer to 32 bit characters ",
- "far pointer to void ",
- "far pointer to 15 bit unsigned ",
- "far pointer to 24 bit unsigned ",
- "far pointer to 31 bit unsigned ",
-};
-
-// Thanks to John Currier:
-// Do not call 16 bit code in myHandler function to prevent call
-// to __EDCThunkProlog and problems is guard page exception handling
-// Also reduce the stack size to 1K for true 16 bit calls.
-// 16 bit calls thunk will now only occur on fatal exceptions
-#pragma stack16(1024)
-
-// ------------------------------------------------------------------
-// Last 8 bytes of 16:16 file when CODEVIEW debugging info is present
-#pragma pack(1)
-struct _eodbug
-{
- unsigned short dbug; // 'NB' signature
- unsigned short ver; // version
- unsigned long dfaBase; // size of codeview info
-} G_eodbug;
-
-#define DBUGSIG 0x424E
-#define SSTMODULES 0x0101
-#define SSTPUBLICS 0x0102
-#define SSTTYPES 0x0103
-#define SSTSYMBOLS 0x0104
-#define SSTSRCLINES 0x0105
-#define SSTLIBRARIES 0x0106
-#define SSTSRCLINES2 0x0109
-#define SSTSRCLINES32 0x010B
-
-typedef struct _SYMBASE
-{
- unsigned short dbug; // 'NB' signature
- unsigned short ver; // version
- unsigned long lfoDir; // file offset to dir entries
-} SYMBASE;
-
-typedef struct _SSDIR
-{
- unsigned short sst; // SubSection Type
- unsigned short modindex; // Module index number
- unsigned long lfoStart; // Start of section
- unsigned short cb; // Size of section
-} SSDIR;
-
-typedef struct _SSDIR32
-{
- unsigned short sst; // SubSection Type
- unsigned short modindex; // Module index number
- unsigned long lfoStart; // Start of section
- unsigned long cb; // Size of section
-} SSDIR32;
-
-typedef struct _SSMODULE
-{
- unsigned short csBase; // code segment base
- unsigned short csOff; // code segment offset
- unsigned short csLen; // code segment length
- unsigned short ovrNum; // overlay number
- unsigned short indxSS; // Index into sstLib or 0
- unsigned short reserved;
- BYTE csize; // size of prefix string
-} SSMODULE;
-
-typedef struct _SSMOD32
-{
- unsigned short csBase; // code segment base
- unsigned long csOff; // code segment offset
- unsigned long csLen; // code segment length
- unsigned long ovrNum; // overlay number
- unsigned short indxSS; // Index into sstLib or 0
- unsigned long reserved;
- BYTE csize; // size of prefix string
-} SSMOD32;
-
-typedef struct _SSPUBLIC
-{
- unsigned short offset;
- unsigned short segment;
- unsigned short type;
- BYTE csize;
-} SSPUBLIC;
-
-typedef struct _SSPUBLIC32
-{
- unsigned long offset;
- unsigned short segment;
- unsigned short type;
- BYTE csize;
-} SSPUBLIC32;
-
-typedef struct _SSLINEENTRY32
-{
- unsigned short LineNum;
- unsigned short FileNum;
- unsigned long Offset;
-} SSLINEENTRY32;
-
-typedef struct _FIRSTLINEENTRY32
-{
- unsigned short LineNum;
- unsigned char entry_type;
- unsigned char reserved;
- unsigned short numlines;
- unsigned short segnum;
-} FIRSTLINEENTRY32;
-
-typedef struct _SSFILENUM32
-{
- unsigned long first_displayable; // Not used
- unsigned long number_displayable; // Not used
- unsigned long file_count; // number of source files
-} SSFILENUM32;
-
-/*
- *@@ XDEBUGINFO:
- * buffers for Read... funcs.
- *
- *@@added V0.9.4 (2000-06-15) [umoeller]
- */
-
-typedef struct _XDEBUGINFO
-{
- char szNrFile[300]; // receives source file
- char szNrLine[300]; // receives line number
- //YD 17/07/06 c++ namespace can generate really long
- //YD names, use a large buffer!
- char szNrPub[16*1024]; // receives function name
-
- struct new_seg *pseg;
- struct o32_obj *pobj; // flat .EXE object table entry
-
- SYMBASE base;
-
- SSDIR *pDirTab;
- SSDIR32 *pDirTab32;
- unsigned char *pEntTab;
- unsigned long lfaBase;
- SSMOD32 ssmod32;
- SSPUBLIC32 sspub32;
-
- SSMODULE ssmod;
- SSPUBLIC sspub;
-} XDEBUGINFO, *PXDEBUGINFO;
-
-
-USHORT _THUNK_FUNCTION (Dos16SizeSeg) ();
-//APIRET16 APIENTRY16 DOS16SIZESEG(USHORT Seg, PULONG16 Size);
-USHORT DosSizeSeg (USHORT Seg, PULONG16 Size)
-{
- return ((USHORT)
- (_THUNK_PROLOG (2+4);
- _THUNK_SHORT (Seg);
- _THUNK_FLAT (Size);
- _THUNK_CALL (Dos16SizeSeg)));
-}
-
-#pragma pack()
-
-/* ******************************************************************
- *
- * PART 1: ANALYZE DEBUG CODE
- *
- ********************************************************************/
-
-static int Read16CodeView(FILE *LogFile, PXDEBUGINFO pxdi, int fh, int TrapSeg, int TrapOff, CHAR *FileName);
-static int Read32PmDebug(FILE *LogFile, PXDEBUGINFO pxdi, int fh, int TrapSeg, int TrapOff, CHAR *FileName);
-
-/*
- *@@ WriteAddressInfo:
- * formats and writes a line into the trap log
- * file.
- *
- * This gets called for each line from the
- * stack dump. At this point, the line in the
- * trap log already has:
- *
- + CS:EIP : 000109FF XMLVIEW :0
- + ^^^ and we write here
- * After this call, we have.
- *
- + CS:EIP : 000109FF XMLVIEW :0 xxx.c 123 ConfirmCreate__Fv
- + ^^^ and we write here
- *
- *@@added V0.9.12 (2001-05-12) [umoeller]
- */
-
-static VOID WriteDebugInfo(FILE *LogFile, // in: open log file
- PXDEBUGINFO pxdi) // in: debug info
-{
- fprintf(LogFile,
- "%s%s%s",
- pxdi->szNrFile,
- pxdi->szNrLine,
- pxdi->szNrPub);
-}
-
-/*
- *@@ dbgPrintDebugInfo:
- * this is the main entry point into analyzing debug
- * code.
- *
- * This analyzes a given address and tries to find
- * debug code descriptions for this address. If found,
- * the information is written to the given log file.
- *
- * Gets called from dbgPrintStack.
- *
- * This returns NO_ERROR if the could was successfully
- * analyzed or something != 0 if we failed.
- *
- * New with V0.84.
- */
-
-APIRET dbgPrintDebugInfo(FILE *LogFile, // out: log file to write to
- CHAR *FileName, // in: EXE/DLL module file name
- ULONG Object, // in: trapping object (from DosQueryModFromEIP)
- ULONG TrapOffset) // in: trapping address (from DosQueryModFromEIP)
-{
- APIRET rc = 0;
- int ModuleFile = 0;
- static struct exe_hdr OldExeHeader;
- static struct new_exe NewExeHeader;
-
- ULONG ulSegment = Object + 1; // segment no. is object no. + 1
-
- XDEBUGINFO xdi;
- memset(&xdi, 0, sizeof(xdi));
-
- // open the module file for reading to analyze the code
- ModuleFile = sopen(FileName, O_RDONLY | O_BINARY, SH_DENYNO);
-
- if (ModuleFile != -1)
- {
- // file found:
- // read old Exe header
- if (read(ModuleFile, (void*)&OldExeHeader, 64) == -1L)
- {
- fprintf(LogFile, "errno %d reading old exe header\n", errno);
- close(ModuleFile);
- return 2;
- }
- // seek to new Exe header
- if (lseek(ModuleFile, (long)E_LFANEW(OldExeHeader), SEEK_SET) == -1L)
- {
- fprintf(LogFile, "errno %d seeking to new exe header\n", errno);
- close(ModuleFile);
- return 3;
- }
- if (read(ModuleFile, (void *)&NewExeHeader, 64) == -1L)
- {
- fprintf(LogFile, "errno %d reading new exe header\n", errno);
- close(ModuleFile);
- return 4;
- }
-
- // check EXE signature
- if (NE_MAGIC(NewExeHeader) == E32MAGIC)
- {
- /*
- * flat 32 executable:
- *
- */
-
- // do analysis for 32-bit code
- if (!(rc = Read32PmDebug(LogFile,
- &xdi, // output
- ModuleFile,
- ulSegment,
- TrapOffset,
- FileName)))
- WriteDebugInfo(LogFile, &xdi);
-
- close(ModuleFile);
-
- // rc !=0 try with DBG file
- if (rc != 0)
- {
- strcpy(FileName + strlen(FileName) - 3, "DBG"); // Build DBG File name
- ModuleFile = sopen(FileName, O_RDONLY | O_BINARY, SH_DENYNO);
- if (ModuleFile != -1)
- {
- if (!(rc = Read32PmDebug(LogFile,
- &xdi,
- ModuleFile,
- ulSegment,
- TrapOffset,
- FileName)))
- WriteDebugInfo(LogFile, &xdi);
-
- close(ModuleFile);
- }
- }
-
- return rc;
- }
- else
- {
- if (NE_MAGIC(NewExeHeader) == NEMAGIC)
- {
- /*
- * 16:16 executable:
- *
- */
-
- if ((xdi.pseg = (struct new_seg *)calloc(NE_CSEG(NewExeHeader),
- sizeof(struct new_seg)))
- == NULL)
- {
- fprintf(LogFile, "Out of memory!");
- close(ModuleFile);
- return -1;
- }
- if ( lseek(ModuleFile,
- E_LFANEW(OldExeHeader) + NE_SEGTAB(NewExeHeader),
- SEEK_SET) == -1L)
- {
- fprintf(LogFile, "Error %u seeking segment table in %s\n", errno, FileName);
- free(xdi.pseg);
- close(ModuleFile);
- return 9;
- }
-
- if (read(ModuleFile,
- (void *)xdi.pseg,
- NE_CSEG(NewExeHeader) * sizeof(struct new_seg))
- == -1)
- {
- fprintf(LogFile, "Error %u reading segment table from %s\n", errno, FileName);
- free(xdi.pseg);
- close(ModuleFile);
- return 10;
- }
-
- if (!(rc = Read16CodeView(LogFile,
- &xdi,
- ModuleFile,
- ulSegment,
- TrapOffset,
- FileName)))
- WriteDebugInfo(LogFile, &xdi);
-
- free(xdi.pseg);
- close(ModuleFile);
-
- // rc !=0 try with DBG file
- if (rc != 0)
- {
- strcpy(FileName + strlen(FileName) - 3, "DBG"); // Build DBG File name
- ModuleFile = sopen(FileName,
- O_RDONLY | O_BINARY, SH_DENYNO);
- if (ModuleFile != -1)
- {
- if (!(rc = Read16CodeView(LogFile,
- &xdi,
- ModuleFile,
- ulSegment,
- TrapOffset,
- FileName)))
- WriteDebugInfo(LogFile, &xdi);
-
- close(ModuleFile);
- }
- }
- return rc;
- }
- else
- {
- /*
- * Unknown executable:
- *
- */
-
- fprintf(LogFile, "Error, could not find exe signature");
- close(ModuleFile);
- return 11;
- }
- }
- } // end if (ModuleFile != -1)
- else
- {
- fprintf(LogFile, "Error %d opening module file %s", errno, FileName);
- return 1;
- } // endif
-
- // return 0; we never get here
-}
-
-char fname[256],
- ModName[80];
-char ename[256],
- dummy[256];
-
-#define MAX_USERDEFS 300 // raised from 150 V0.9.1 (2000-01-30) [umoeller]
-#define MAX_POINTERS 300 // raised from 150 V0.9.1 (2000-01-30) [umoeller]
-
-USHORT userdef_count;
-USHORT pointer_count;
-
-struct one_userdef_rec
-{
- USHORT idx;
- USHORT type_index;
- BYTE name[33];
-} one_userdef[MAX_USERDEFS];
-
-struct one_pointer_rec
-{
- USHORT idx;
- USHORT type_index;
- BYTE type_qual;
- BYTE name[33];
-} one_pointer[MAX_POINTERS];
-
-/*
- * Read32PmDebug:
- * parses 32-bit debug code.
- * Called from dbgPrintDebugInfo for 32-bit modules.
- */
-
-static int Read32PmDebug(FILE *LogFile, // in: text log file to write to
- PXDEBUGINFO pxdi,
- int ModuleFile, // in: module file opened with sopen()
- int TrapSeg,
- int TrapOff,
- CHAR *FileName)
-{
- static unsigned int CurrSymSeg, NrSymbol,
- /* offset, */ NrPublic,
- NrFile, NrLine, /* NrEntry */
- numdir, namelen,
- numlines /* , line */;
- static int ModIndex;
- static int bytesread, i, j;
- static SSLINEENTRY32 LineEntry;
- static SSFILENUM32 FileInfo;
- static FIRSTLINEENTRY32 FirstLine;
- static BYTE dump_vars = FALSE;
- static USHORT idx;
- static BOOL read_types;
- static LONG lSize;
-
- ModIndex = 0;
- // See if any CODEVIEW info
- if (lseek(ModuleFile, -8L, SEEK_END) == -1)
- {
- fprintf(LogFile, "Error %u seeking CodeView table in %s\n", errno, FileName);
- return (18);
- }
-
- if (read(ModuleFile,
- (void *)&G_eodbug, 8)
- == -1)
- {
- fprintf(LogFile, "Error %u reading debug info from %s\n", errno, FileName);
- return (19);
- }
- if (G_eodbug.dbug != DBUGSIG)
- {
- // fprintf(LogFile,"\nNo CodeView information stored.\n");
- return (100);
- }
-
- if ( (pxdi->lfaBase = lseek(ModuleFile,
- -(LONG)G_eodbug.dfaBase,
- SEEK_END))
- == -1L)
- {
- fprintf(LogFile, "Error %u seeking base codeview data in %s\n", errno, FileName);
- return (20);
- }
-
- if (read(ModuleFile,
- (void *)&pxdi->base, 8)
- == -1)
- {
- fprintf(LogFile, "Error %u reading base codeview data in %s\n", errno, FileName);
- return (21);
- }
-
- if (lseek(ModuleFile,
- pxdi->base.lfoDir - 8 + 4,
- SEEK_CUR)
- == -1)
- {
- fprintf(LogFile, "Error %u seeking dir codeview data in %s\n", errno, FileName);
- return (22);
- }
-
- if (read(ModuleFile,
- (void *)&numdir, 4)
- == -1)
- {
- fprintf(LogFile, "Error %u reading dir codeview data in %s\n", errno, FileName);
- return (23);
- }
-
- // Read dir table into buffer
- if ( (pxdi->pDirTab32 = (SSDIR32*)calloc(numdir,
- sizeof(SSDIR32)))
- == NULL)
- {
- fprintf(LogFile, "Out of memory!");
- return (-1);
- }
-
- if (read(ModuleFile,
- (void*)pxdi->pDirTab32,
- numdir * sizeof(SSDIR32))
- == -1)
- {
- fprintf(LogFile, "Error %u reading codeview dir table from %s\n", errno, FileName);
- free(pxdi->pDirTab32);
- return (24);
- }
-
- i = 0;
- while (i < numdir)
- {
- if (pxdi->pDirTab32[i].sst != SSTMODULES)
- {
- i++;
- continue;
- }
-
- NrPublic = 0x0;
- NrSymbol = 0;
- NrLine = 0x0;
- NrFile = 0x0;
- CurrSymSeg = 0;
- // point to subsection
- lseek(ModuleFile,
- pxdi->pDirTab32[i].lfoStart + pxdi->lfaBase,
- SEEK_SET);
- read(ModuleFile,
- (void*)&pxdi->ssmod32.csBase,
- sizeof(SSMOD32));
- read(ModuleFile,
- (void*)ModName,
- (unsigned)pxdi->ssmod32.csize);
- ModIndex = pxdi->pDirTab32[i].modindex;
- ModName[pxdi->ssmod32.csize] = '\0';
- i++;
-
- read_types = FALSE;
-
- while ( (pxdi->pDirTab32[i].modindex == ModIndex)
- && (i < numdir)
- )
- {
- // point to subsection
- lseek(ModuleFile,
- pxdi->pDirTab32[i].lfoStart + pxdi->lfaBase,
- SEEK_SET);
-
- switch (pxdi->pDirTab32[i].sst)
- {
- case SSTPUBLICS:
- bytesread = 0;
- while (bytesread < pxdi->pDirTab32[i].cb)
- {
- bytesread += read(ModuleFile,
- (void *)&pxdi->sspub32.offset,
- sizeof(pxdi->sspub32));
- bytesread += read(ModuleFile,
- (void*)ename,
- (unsigned)pxdi->sspub32.csize);
- ename[pxdi->sspub32.csize] = '\0';
- if ( (pxdi->sspub32.segment == TrapSeg)
- && (pxdi->sspub32.offset <= TrapOff)
- && (pxdi->sspub32.offset >= NrPublic)
- )
- {
- NrPublic = pubfunc_ofs = pxdi->sspub32.offset;
- read_types = TRUE;
- sprintf(pxdi->szNrPub,
- "%s %s (%s)\n",
- (pxdi->sspub32.type == 1)
- ? " Abs"
- : " ",
- ename,
- ModName
- );
- // but continue, because there might be a
- // symbol that comes closer
- }
- }
- break;
-
- // Read symbols, so we can dump the variables on the stack
- case SSTSYMBOLS:
- if (TrapSeg != pxdi->ssmod32.csBase)
- break;
-
- bytesread = 0;
- while (bytesread < pxdi->pDirTab32[i].cb)
- {
- static USHORT usLength;
- static USHORT usLengthSym;
- static BYTE b1,
- b2;
- static BYTE bType;
- // *ptr;
- static ULONG ofs;
- // static ULONG last_addr = 0;
- //YD 17/07/06 c++ namespace can generate really long
- //YD names, use a large buffer!
- static BYTE str[16*1024];
- static struct symseg_rec symseg;
- static struct symauto_rec symauto;
- static struct symproc_rec symproc;
-
- // Read the length of this subentry
- bytesread += read(ModuleFile, &b1, 1);
- if (b1 & 0x80)
- {
- bytesread += read(ModuleFile, &b2, 1);
- usLength = ((b1 & 0x7F) << 8) + b2;
- }
- else
- usLength = b1;
-
- ofs = tell(ModuleFile);
-
- bytesread += read(ModuleFile, &bType, 1);
-
- switch (bType)
- {
- case SYM_CHANGESEG:
- read(ModuleFile, &symseg, sizeof(symseg));
- CurrSymSeg = symseg.seg_no;
- break;
-
- case SYM_PROC:
- case SYM_CPPPROC:
- read(ModuleFile, &symproc, sizeof(symproc));
- if (symproc.name_len & 0x80)
- {
- read(ModuleFile, &b2, 1);
- usLengthSym = ((symproc.name_len & 0x7F) << 8) + b2;
- }
- else
- {
- usLengthSym = symproc.name_len;
- }
- read(ModuleFile, str, usLengthSym);
- str[usLengthSym] = 0;
-
- if ((CurrSymSeg == TrapSeg) &&
- (symproc.offset <= TrapOff) &&
- (symproc.offset >= NrSymbol))
- {
-
- dump_vars = TRUE;
- var_ofs = 0;
- NrSymbol = symproc.offset;
- func_ofs = symproc.offset;
-
- strcpy(func_name, str);
- }
- else
- {
- dump_vars = FALSE;
- }
- break;
-
- case SYM_AUTO:
- if (!dump_vars)
- break;
-
- read(ModuleFile, &symauto, sizeof(symauto));
- read(ModuleFile, str, symauto.name_len);
- if (symauto.name_len==0x80)
- printf("symauto.name_len==0x80\n");
- str[symauto.name_len] = 0;
-
- strcpy(autovar_def[var_ofs].name, str);
- autovar_def[var_ofs].stack_offset = symauto.stack_offset;
- autovar_def[var_ofs].type_idx = symauto.type_idx;
- var_ofs++;
- break;
-
- }
-
- bytesread += usLength;
-
- lseek(ModuleFile, ofs + usLength, SEEK_SET);
- }
- break;
-
- case SSTTYPES:
- // if (ModIndex != TrapSeg)
- if (!read_types)
- break;
-
- bytesread = 0;
- idx = 0x200;
- userdef_count = 0;
- pointer_count = 0;
- while (bytesread < pxdi->pDirTab32[i].cb)
- {
- static struct type_rec type;
- static struct type_userdefrec udef;
- static struct type_pointerrec point;
- static ULONG ofs;
- static BYTE str[256];
-
- // Read the length of this subentry
- ofs = tell(ModuleFile);
-
- read(ModuleFile, &type, sizeof(type));
- bytesread += sizeof(type);
-
- switch (type.type)
- {
- case TYPE_USERDEF:
- if (userdef_count >= MAX_USERDEFS)
- break;
-
- read(ModuleFile, &udef, sizeof(udef));
- read(ModuleFile, str, udef.name_len);
- str[udef.name_len] = 0;
-
- // Insert userdef in table
- one_userdef[userdef_count].idx = idx;
- one_userdef[userdef_count].type_index = udef.type_index;
- memcpy(one_userdef[userdef_count].name,
- str,
- _min(udef.name_len + 1, 32));
- one_userdef[userdef_count].name[32] = 0;
- userdef_count++;
- break;
-
- case TYPE_POINTER:
- if (pointer_count >= MAX_POINTERS)
- break;
-
- read(ModuleFile, &point, sizeof(point));
- read(ModuleFile, str, point.name_len);
- str[point.name_len] = 0;
-
- // Insert userdef in table
- one_pointer[pointer_count].idx = idx;
- one_pointer[pointer_count].type_index = point.type_index;
- memcpy(one_pointer[pointer_count].name,
- str,
- _min(point.name_len + 1, 32));
- one_pointer[pointer_count].name[32] = 0;
- one_pointer[pointer_count].type_qual = type.type_qual;
- pointer_count++;
- break;
- }
-
- ++idx;
-
- bytesread += type.length;
-
- lseek(ModuleFile, ofs + type.length + 2, SEEK_SET);
- }
- break;
-
- case SSTSRCLINES32:
- if (TrapSeg != pxdi->ssmod32.csBase)
- break;
-
- // read first line
- do
- {
- read(ModuleFile, (void *)&FirstLine, sizeof(FirstLine));
-
- if (FirstLine.LineNum != 0)
- {
- fprintf(LogFile, "Missing Line table information\n");
- break;
- } // endif
- numlines = FirstLine.numlines;
- // Other type of data skip 4 more bytes
- if (FirstLine.entry_type < 4)
- {
- read(ModuleFile, (void *)&lSize, 4);
- if (FirstLine.entry_type == 3)
- lseek(ModuleFile, lSize, SEEK_CUR);
- }
- }
- while (FirstLine.entry_type == 3);
-
- for (j = 0; j < numlines; j++)
- {
- switch (FirstLine.entry_type)
- {
- case 0:
- read(ModuleFile, (void *)&LineEntry, sizeof(LineEntry));
- // Changed by Kim Rasmussen 26/06 1996 to ignore linenumber 0
- // if (LineEntry.Offset+ssmod32.csOff<=TrapOff && LineEntry.Offset+ssmod32.csOff>=NrLine) {
- if ( (LineEntry.LineNum)
- && (LineEntry.Offset + pxdi->ssmod32.csOff
- <= TrapOff)
- && (LineEntry.Offset + pxdi->ssmod32.csOff >= NrLine)
- )
- {
- NrLine = LineEntry.Offset;
- NrFile = LineEntry.FileNum;
- /*pOffset =sprintf(szNrLine,"%04X:%08X line #%hu ",
- * ssmod32.csBase,LineEntry.Offset,
- * LineEntry.LineNum); */
- sprintf(pxdi->szNrLine, "% 6hu", LineEntry.LineNum);
- }
- break;
-
- case 1:
- lseek(ModuleFile, sizeof(struct linlist_rec), SEEK_CUR);
- break;
-
- case 2:
- lseek(ModuleFile, sizeof(struct linsourcelist_rec), SEEK_CUR);
- break;
-
- case 3:
- lseek(ModuleFile, sizeof(struct filenam_rec), SEEK_CUR);
- break;
-
- case 4:
- lseek(ModuleFile, sizeof(struct pathtab_rec), SEEK_CUR);
- break;
-
- }
- }
-
- if (NrFile != 0)
- {
- // file found:
- read(ModuleFile, (void*)&FileInfo, sizeof(FileInfo));
- namelen = 0;
- for (j = 1; j <= FileInfo.file_count; j++)
- {
- namelen = 0;
- read(ModuleFile, (void *)&namelen, 1);
- read(ModuleFile, (void *)ename, namelen);
- if (j == NrFile)
- break;
- }
- ename[namelen] = '\0';
- // pOffset=sprintf(szNrLine+pOffset," (%s) (%s)\n",ename,ModName);
- sprintf(pxdi->szNrFile, "%11.11s ", ename);
- }
- else
- {
- // strcat(szNrLine,"\n"); avoid new line for empty name fill
- strcpy(pxdi->szNrFile, "file? ");
- } // endif
- break;
- } // end switch
-
- i++;
- } // end while modindex
- } // End While i < numdir
- free(pxdi->pDirTab32);
- return (0);
-}
-
-/*
- * Read16CodeView:
- * parses 16-bit debug code.
- * Called from dbgPrintDebugInfo for 16-bit modules.
- */
-
-static int Read16CodeView(FILE *LogFile, // in: text log file to write to
- PXDEBUGINFO pxdi,
- int fh,
- int TrapSeg,
- int TrapOff,
- CHAR *FileName)
-{
- static unsigned short int offset,
- NrPublic, NrLine,
- numdir,
- namelen, numlines,
- line;
- static int ModIndex;
- static int bytesread, i, j;
-
- ModIndex = 0;
- // See if any CODEVIEW info
- if (lseek(fh, -8L, SEEK_END) == -1)
- {
- fprintf(LogFile, "Error %u seeking CodeView table in %s\n", errno, FileName);
- return (18);
- }
-
- if (read(fh, (void *)&G_eodbug, 8) == -1)
- {
- fprintf(LogFile, "Error %u reading debug info from %s\n", errno, FileName);
- return (19);
- }
- if (G_eodbug.dbug != DBUGSIG)
- {
- // fprintf(LogFile,"\nNo CodeView information stored.\n");
- return (100);
- }
-
- if ((pxdi->lfaBase = lseek(fh, -(LONG)G_eodbug.dfaBase, SEEK_END)) == -1L)
- {
- fprintf(LogFile, "Error %u seeking base codeview data in %s\n", errno, FileName);
- return (20);
- }
-
- if (read(fh, (void *)&pxdi->base, 8) == -1)
- {
- fprintf(LogFile, "Error %u reading base codeview data in %s\n", errno, FileName);
- return (21);
- }
-
- if (lseek(fh, pxdi->base.lfoDir - 8, SEEK_CUR) == -1)
- {
- fprintf(LogFile, "Error %u seeking dir codeview data in %s\n", errno, FileName);
- return (22);
- }
-
- if (read(fh, (void *)&numdir, 2) == -1)
- {
- fprintf(LogFile, "Error %u reading dir codeview data in %s\n", errno, FileName);
- return (23);
- }
-
- // Read dir table into buffer
- if ((pxdi->pDirTab = (SSDIR*)calloc(numdir, sizeof(SSDIR))) == NULL)
- {
- fprintf(LogFile, "Out of memory!");
- return (-1);
- }
-
- if (read(fh, (void*)pxdi->pDirTab, numdir * sizeof(SSDIR)) == -1)
- {
- fprintf(LogFile, "Error %u reading codeview dir table from %s\n", errno, FileName);
- free(pxdi->pDirTab);
- return (24);
- }
-
- i = 0;
- while (i < numdir)
- {
- if (pxdi->pDirTab[i].sst != SSTMODULES)
- {
- i++;
- continue;
- }
- NrPublic = 0x0;
- NrLine = 0x0;
- // point to subsection
- lseek(fh, pxdi->pDirTab[i].lfoStart + pxdi->lfaBase, SEEK_SET);
- read(fh, (void *)&pxdi->ssmod.csBase, sizeof(SSMODULE));
- read(fh, (void *)ModName, (unsigned)pxdi->ssmod.csize);
- ModIndex = pxdi->pDirTab[i].modindex;
- ModName[pxdi->ssmod.csize] = '\0';
- i++;
- while (pxdi->pDirTab[i].modindex == ModIndex && i < numdir)
- {
- // point to subsection
- lseek(fh, pxdi->pDirTab[i].lfoStart + pxdi->lfaBase, SEEK_SET);
- switch (pxdi->pDirTab[i].sst)
- {
- case SSTPUBLICS:
- bytesread = 0;
- while (bytesread < pxdi->pDirTab[i].cb)
- {
- bytesread += read(fh, (void *)&pxdi->sspub.offset, sizeof(pxdi->sspub));
- bytesread += read(fh, (void *)ename, (unsigned)pxdi->sspub.csize);
- ename[pxdi->sspub.csize] = '\0';
- if ((pxdi->sspub.segment == TrapSeg) &&
- (pxdi->sspub.offset <= TrapOff) &&
- (pxdi->sspub.offset >= NrPublic))
- {
- NrPublic = pxdi->sspub.offset;
- sprintf(pxdi->szNrPub, "%s %s (%s) %04hX:%04hX\n",
- (pxdi->sspub.type == 1) ? " Abs" : " ", ename,
- ModName, // ()
- pxdi->sspub.segment,
- pxdi->sspub.offset
- );
- }
- }
- break;
-
- case SSTSRCLINES2:
- case SSTSRCLINES:
- if (TrapSeg != pxdi->ssmod.csBase)
- break;
- namelen = 0;
- read(fh, (void *)&namelen, 1);
- read(fh, (void *)ename, namelen);
- ename[namelen] = '\0';
- // skip 2 zero bytes
- if (pxdi->pDirTab[i].sst == SSTSRCLINES2)
- read(fh, (void *)&numlines, 2);
- read(fh, (void *)&numlines, 2);
- for (j = 0; j < numlines; j++)
- {
- read(fh, (void *)&line, 2);
- read(fh, (void *)&offset, 2);
- if (offset <= TrapOff && offset >= NrLine)
- {
- NrLine = offset;
- sprintf(pxdi->szNrFile, "% 12.12s ", ename);
- sprintf(pxdi->szNrLine, "% 6hu", line);
- /*sprintf(szNrLine,"%04hX:%04hX line #%hu (%s) (%s)\n",
- * ssmod.csBase,offset,line,ModName,ename); */
- }
- }
- break;
- } // end switch
- i++;
- } // end while modindex
- } // End While i < numdir
- free(pxdi->pDirTab);
- return (0);
-}
-
-/* ******************************************************************
- *
- * PART 2: ANALYZE VARIABLES
- *
- ********************************************************************/
-
-/*
- * var_value:
- * writes a description of a variable type to
- * the specified buffer, depending on "type".
- *
- *@@changed V0.9.1 (2000-01-30) [umoeller]: changed prototype to use external buffer
- */
-
-static VOID var_value(void *varptr, // in: address of the variable on the stack
- char *pszBuf, // out: information
- BYTE type) // in: type; if >= 32, we'll call DosQueryMem
-{
- ULONG Size = 1,
- Attr = 0;
-
- if (DosQueryMem(varptr, &Size, &Attr) != NO_ERROR)
- {
- sprintf(pszBuf, "type %d, DosQueryMem failed", type);
- return;
- }
-
- if ((Attr & PAG_READ) == 0)
- {
- sprintf(pszBuf, "type %d, read-access to value denied", type);
- return;
- }
-
- if (type == 0)
- sprintf(pszBuf, "%hd", *(signed char*)varptr);
- else if (type == 1)
- sprintf(pszBuf, "%hd", *(signed short*)varptr);
- else if (type == 2)
- sprintf(pszBuf, "%ld", *(signed long*)varptr);
- else if (type == 4)
- sprintf(pszBuf, "%hu", *(BYTE*) varptr);
- else if (type == 5)
- sprintf(pszBuf, "%hu", *(USHORT*)varptr);
- else if (type == 6)
- sprintf(pszBuf, "0x%lX (%lu)", *((ULONG*)varptr), *((ULONG*)varptr));
- else if (type == 8)
- sprintf(pszBuf, "%f", *(float*)varptr);
- else if (type == 9)
- sprintf(pszBuf, "%f", *(double*)varptr);
- else if (type == 10)
- sprintf(pszBuf, "%f", (double)(*(long double*)varptr));
- else if (type == 16)
- sprintf(pszBuf, "%s", *(char*)varptr ? "TRUE" : "FALSE");
- else if (type == 17)
- sprintf(pszBuf, "%s", *(short*)varptr ? "TRUE" : "FALSE");
- else if (type == 18)
- sprintf(pszBuf, "%s", *(long*)varptr ? "TRUE" : "FALSE");
- else if (type == 20)
- sprintf(pszBuf, "%c", *(char*)varptr);
- else if (type == 21)
- sprintf(pszBuf, "%hd", (*(short*)varptr));
- else if (type == 22)
- sprintf(pszBuf, "%ld", *(long*)varptr);
- else if (type == 23)
- sprintf(pszBuf, "void");
- else if (type >= 32)
- {
- sprintf(pszBuf, "0x%p", (void*)(*(ULONG*)varptr));
- if (Attr & PAG_FREE)
- {
- strcat(pszBuf, " unallocated memory");
- }
- else
- {
- if ((Attr & PAG_COMMIT) == 0x0U)
- {
- strcat(pszBuf, " uncommitted");
- } // endif
- if ((Attr & PAG_WRITE) == 0x0U)
- {
- strcat(pszBuf, " unwritable");
- } // endif
- if ((Attr & PAG_READ) == 0x0U)
- {
- strcat(pszBuf, " unreadable");
- } // endif
- } // endif
- } // endif
- else
- sprintf(pszBuf, "Unknown type %d", type);
-}
-
-/*
- * search_userdefs:
- * searches the table of userdef's-
- * Return TRUE if found.
- */
-
-static BOOL search_userdefs(FILE *LogFile, // in: text log file to write to
- ULONG stackofs,
- USHORT var_no)
-{
- USHORT pos;
-
- for (pos = 0;
- pos < userdef_count;
- pos++)
- {
- if (one_userdef[pos].idx == autovar_def[var_no].type_idx)
- {
- if ( (one_userdef[pos].type_index >= 0x80)
- // && (one_userdef[pos].type_index <= 0xDA)
- )
- {
- static char sszVar3[500] = "complex";
- if (one_userdef[pos].type_index <= 0xDA)
- var_value((void*)(stackofs + autovar_def[var_no].stack_offset),
- sszVar3,
- one_userdef[pos].type_index - 0x80);
-
- fprintf(LogFile,
- " %- 6ld %- 20.20s %- 33.33s %s (user)\n",
- autovar_def[var_no].stack_offset, // stack offset
- autovar_def[var_no].name, // identifier
- one_userdef[pos].name, // type name
- sszVar3 // composed by var_value
- );
- return TRUE;
- }
- else
- return FALSE;
- }
- }
-
- return FALSE;
-}
-
-/*
- * search_pointers:
- *
- */
-
-static BOOL search_pointers(FILE *LogFile, // in: text log file to write to
- ULONG stackofs,
- USHORT var_no)
-{
- USHORT pos, upos;
- static BYTE str[35];
- static char sszVar[500];
-
- // BYTE type_index;
-
- for (pos = 0;
- ( (pos < pointer_count)
- && (one_pointer[pos].idx != autovar_def[var_no].type_idx)
- );
- pos++);
-
- if (pos < pointer_count)
- {
- if ( (one_pointer[pos].type_index >= 0x80)
- && (one_pointer[pos].type_index <= 0xDA)
- )
- {
- strcpy(str, type_name[one_pointer[pos].type_index - 0x80]);
- strcat(str, " *");
- var_value((void*)(stackofs + autovar_def[var_no].stack_offset),
- sszVar,
- 32);
- fprintf(LogFile, " %- 6ld %- 20.20s %- 33.33s %s (ptr1)\n",
- autovar_def[var_no].stack_offset,
- autovar_def[var_no].name,
- str,
- sszVar);
- return TRUE;
- }
- else
- {
- // If the result isn't a simple type, look for it in the other lists
- for (upos = 0;
- ( (upos < userdef_count)
- && (one_userdef[upos].idx != one_pointer[pos].type_index)
- );
- upos++)
- ;
-
- if (upos < userdef_count)
- {
- strcpy(str, one_userdef[upos].name);
- strcat(str, " *");
- var_value((void *)(stackofs + autovar_def[var_no].stack_offset),
- sszVar,
- 32);
- fprintf(LogFile, " %- 6ld %- 20.20s %- 33.33s %s (ptr2)\n",
- autovar_def[var_no].stack_offset,
- autovar_def[var_no].name,
- str,
- sszVar);
- return TRUE;
- }
- else
- {
- // if it isn't a userdef, for now give up and just print
- // as much as we know
- sprintf(str, "Pointer to type 0x%X", one_pointer[pos].type_index);
-
- var_value((void *)(stackofs + autovar_def[var_no].stack_offset),
- sszVar,
- 32);
- fprintf(LogFile, " %- 6ld %- 20.20s %- 33.33s %s (ptr3)\n",
- autovar_def[var_no].stack_offset,
- autovar_def[var_no].name,
- str,
- sszVar);
-
- return TRUE;
- }
- }
- }
-
- return FALSE;
-}
-
-/*
- *@@ dbgPrintVariables:
- * Dumps variables for the specified stack offset
- * to the specified log file.
- *
- * New with V0.84.
- */
-
-void dbgPrintVariables(FILE *LogFile, // in: text log file to write to
- ULONG stackofs)
-{
- USHORT n; // , pos;
- BOOL AutoVarsFound = FALSE;
-
- if (/* 1 || */ func_ofs == pubfunc_ofs)
- {
- for (n = 0;
- n < var_ofs;
- n++)
- {
- if (AutoVarsFound == FALSE)
- {
- AutoVarsFound = TRUE;
- fprintf(LogFile, " List of auto variables at EBP %p in %s:\n",
- (PVOID)stackofs,
- func_name);
- fprintf(LogFile, " Offset Name Type Value \n");
- fprintf(LogFile, " ������ �������������������� ��������������������������������� �����������������\n");
- }
-
- // If it's one of the simple types
- if ( (autovar_def[n].type_idx >= 0x80)
- && (autovar_def[n].type_idx <= 0xDA)
- )
- {
- static char sszVar2[500];
-
- var_value((void *)(stackofs + autovar_def[n].stack_offset),
- sszVar2,
- autovar_def[n].type_idx - 0x80);
-
- fprintf(LogFile, " %- 6ld %- 20.20s %- 33.33s %s (simple)\n",
- autovar_def[n].stack_offset,
- autovar_def[n].name,
- type_name[autovar_def[n].type_idx - 0x80],
- sszVar2);
- }
- else
- { // Complex type, check if we know what it is
- if (!search_userdefs(LogFile, stackofs, n))
- {
- if (!search_pointers(LogFile, stackofs, n))
- {
- fprintf(LogFile, " %- 6ld %-20.20s 0x%X (unknown)\n",
- autovar_def[n].stack_offset,
- autovar_def[n].name,
- autovar_def[n].type_idx);
- }
- }
- }
- }
- /* if (AutoVarsFound == FALSE)
- {
- fprintf(LogFile, " No auto variables found in %s.\n", func_name);
- } */
- fprintf(LogFile, "\n");
- }
-}
-
-/* ******************************************************************
- *
- * PART 3: ANALYZE SYMBOL (.SYM) FILE
- *
- ********************************************************************/
-
-/*
- *@@ dbgPrintSYMInfo:
- * this gets called by dbgPrintStack if dbgPrintDebugInfo
- * failed (because no debug code was found) to check if
- * maybe a SYM file with the same filename exists and try
- * to get the info from there.
- *
- * This gets called for every line of the stack
- * walk, but only if getting the information from
- * the debug code failed, e.g. because no debug code
- * was available for an address.
- *
- * The file pointer is in the "Source file" column
- * every time this gets called.
- *
- * New with V0.84.
- *
- * Returns 0 if reading the SYM file was successful.
- *
- *@@changed V0.9.1 (2000-01-30) [umoeller]: added return code; this used to be VOID
- */
-
-int dbgPrintSYMInfo(FILE *LogFile, // in: text log file to write to
- CHAR *SymFileName, // in: SYM file name (can be fully q'fied)
- ULONG Object,
- ULONG TrapOffset)
-{
- static FILE *SymFile;
- static MAPDEF MapDef;
- static SEGDEF SegDef;
- static SYMDEF32 SymDef32;
- static SYMDEF16 SymDef16;
- static char Buffer[256];
- static int SegNum, SymNum, LastVal;
- static unsigned long int SegOffset,
- SymOffset, SymPtrOffset;
-
- // open .SYM file
-#ifdef DEBUG_SYMDUMP
- fprintf(LogFile,"Dump of '%s' for object %d\n",SymFileName,Object);
-#endif
- SymFile = fopen(SymFileName, "rb");
- if (SymFile == 0)
- return (2);
-
- // read in first map definition
- fread(&MapDef, sizeof(MAPDEF), 1, SymFile);
-#ifdef DEBUG_SYMDUMP
- Buffer[0] = MapDef.achModName[0];
- fread(&Buffer[1], 1, MapDef.cbModName-1, SymFile);
- Buffer[MapDef.cbModName] = 0x00;
- fprintf(LogFile,"Module name '%s'\n",Buffer);
-#endif
-
- SegOffset = SEGDEFOFFSET(MapDef);
-#ifdef DEBUG_SYMDUMP
- fprintf(LogFile,"SegOffset %0x\n",SegOffset);
-#endif
-
- // go thru all segments
- for (SegNum = 0;
- SegNum < MapDef.cSegs;
- SegNum++)
- {
-#ifdef DEBUG_SYMDUMP
- fprintf(LogFile,"Scanning segment #%d Offset %08X\n",SegNum,SegOffset);
-#endif
- if (fseek(SymFile, SegOffset, SEEK_SET))
- // seek error
- return (3);
-
- // read in segment definition
- fread(&SegDef, sizeof(SEGDEF), 1, SymFile);
-#ifdef DEBUG_SYMDUMP
- Buffer[0] = 0x00;
- if (SegDef.cbSegName>0) {
- Buffer[0] = SegDef.achSegName[0];
- fread(&Buffer[1], 1, SegDef.cbSegName-1, SymFile);
- Buffer[SegDef.cbSegName] = 0x00;
- }
- fprintf(LogFile,"Segment name '%s', number %d, flags %02x\n",Buffer,SegNum,SegDef.bFlags);
-#endif
-
- if (SegNum == Object)
- {
- // stack object found:
- Buffer[0] = 0x00;
- LastVal = 0;
-
- // go thru all symbols in this object
-#ifdef DEBUG_SYMDUMP
- fprintf(LogFile,"Scanning #%d symbols\n",SegDef.cSymbols);
-#endif
- for (SymNum = 0; SymNum < SegDef.cSymbols; SymNum++)
- {
- SymPtrOffset=SYMDEFOFFSET(SegOffset,SegDef,SymNum);
- fseek(SymFile,SymPtrOffset,SEEK_SET);
- fread(&SymOffset,sizeof(unsigned short int),1,SymFile);
- fseek(SymFile,SymOffset+SegOffset,SEEK_SET);
- if (SegDef.bFlags & 0x01)
- {
- // 32-bit symbol:
- fread(&SymDef32, sizeof(SYMDEF32), 1, SymFile);
- if (SymDef32.wSymVal > TrapOffset)
- {
- // symbol found
- fprintf(LogFile,
- "between %s + 0x%lX ",
- Buffer,
- TrapOffset - LastVal);
- /* fprintf(LogFile, "(ppLineDef: 0x%lX) ",
- LINEDEFOFFSET(SegDef)
- ); */
- fprintf(LogFile, "\n");
- }
-
- LastVal = SymDef32.wSymVal;
- Buffer[0] = SymDef32.achSymName[0];
- fread(&Buffer[1], 1, SymDef32.cbSymName-1, SymFile);
- Buffer[SymDef32.cbSymName] = 0x00;
-#ifdef DEBUG_SYMDUMP
- fprintf(LogFile,"32 Bit Symbol Address %08p <%s> \n",SymDef32.wSymVal,Buffer);
-#endif
-
- if (SymDef32.wSymVal > TrapOffset)
- {
- // symbol found, as above
- fprintf(LogFile,
- " "
- "and %s - 0x%lX ",
- Buffer,
- LastVal - TrapOffset);
- fprintf(LogFile, "\n");
- break;
- }
- }
- else
- {
- // 16-bit symbol:
- fread(&SymDef16, sizeof(SYMDEF16), 1, SymFile);
- if (SymDef16.wSymVal > TrapOffset)
- {
- fprintf(LogFile,
- "between %s + %lX\n",
- Buffer,
- TrapOffset - LastVal);
- }
- LastVal = SymDef16.wSymVal;
- Buffer[0] = SymDef16.achSymName[0];
- fread(&Buffer[1], 1, SymDef16.cbSymName-1, SymFile);
- Buffer[SymDef16.cbSymName] = 0x00;
- if (SymDef16.wSymVal > TrapOffset)
- {
- fprintf(LogFile,
- " "
- "and %s - %lX\n",
- Buffer,
- LastVal - TrapOffset);
- break;
- }
-#ifdef DEBUG_SYMDUMP
- fprintf(LogFile,"16 Bit Symbol <%s> Address %p\n",Buffer,SymDef16.wSymVal);
-#endif
- } // endif
- }
- break;
- } // endif
- SegOffset = NEXTSEGDEFOFFSET(SegDef);
- } // endwhile
- fclose(SymFile);
- return (0); // no error
-}
-
-/* ******************************************************************
- *
- * PART 4: dbgPrintStack
- *
- ********************************************************************/
-
-/*
- *@@ dbgPrintStackFrame:
- * parses and dumps one stack frame.
- * Called from excPrintStackFrame.
- *
- * This calls dbgPrintDebugInfo and, if
- * that fails, dbgPrintSYMInfo.
- *
- *@@added V0.9.2 (2000-03-10) [umoeller]
- *@@changed V0.9.3 (2000-04-10) [umoeller]: added support for non-Warp 4 SYM files
- *@@changed V0.9.3 (2000-04-26) [umoeller]: this broke Warp 4 FP 13, fixed
- */
-
-BOOL dbgPrintStackFrame(FILE *LogFile,
- PSZ pszModuleName, // in: module name (fully q'fied)
- ULONG ulObject,
- ULONG ulOffset)
-{
- APIRET arc = 0;
- // "Source file"... columns
-
-//YD do not use debug info
-#define ENABLE_DEBUG_INFO
-#ifdef ENABLE_DEBUG_INFO
- // first attempt to analyze the debug code
- arc = dbgPrintDebugInfo(LogFile,
- pszModuleName,
- ulObject,
- ulOffset);
-#else
- arc = 1;
-#endif
-
- // if no debug code is available, analyze
- // the SYM file instead
- if (arc != NO_ERROR)
- {
- CHAR szSymName[CCHMAXPATH];
- strcpy(szSymName, pszModuleName);
- strcpy(szSymName + strlen(szSymName) - 3, "SYM");
- arc = dbgPrintSYMInfo(LogFile,
- szSymName,
- ulObject,
- ulOffset);
- if (arc != 0)
- {
- // SYM file not found in current directory:
- // check the SYM files in the \OS2 directory,
- // depending on the OS/2 version level:
- CHAR szSymFile2[CCHMAXPATH];
- PSZ pszFilename = strrchr(szSymName, '\\');
- if (pszFilename)
- {
- PSZ pszVersionDir = "WARP4";
- ULONG aulBuf[3];
-
- DosQuerySysInfo(QSV_VERSION_MAJOR, // 11
- QSV_VERSION_MINOR, // 12
- &aulBuf, sizeof(aulBuf));
- // Warp 3 is reported as 20.30
- // Warp 4 is reported as 20.40
- // Aurora is reported as 20.45
-
- if (aulBuf[0] == 20)
- {
- if (aulBuf[1] == 30)
- // Warp 3:
- pszVersionDir = "WARP3";
- else if (aulBuf[1] >= 40)
- // Warp 4 or higher:
- // (NOTE: Warp 4 FP 13 now returns 45 also,
- // but the SYM files are still in the WARP4 directory...)
- // V0.9.3 (2000-04-26) [umoeller]
- pszVersionDir = "WARP4";
- }
-
- pszFilename++;
- sprintf(szSymFile2,
- "%c:\\OS2\\PDPSI\\PMDF\\%s\\%s",
- doshQueryBootDrive(),
- pszVersionDir,
- pszFilename);
- arc = dbgPrintSYMInfo(LogFile,
- szSymFile2,
- ulObject,
- ulOffset);
-
- // V0.9.3 (2000-04-26) [umoeller]
- if ( (arc != 0) // still not found
- && (aulBuf[1] == 45) // and running Aurora or Warp 4 FP13?
- )
- {
- // Warp Server for e-Business (aka Warp 4.5):
- // we use the SYM files for the UNI kernel,
- // I have found no way to find out whether
- // we're running on an SMP kernel
- sprintf(szSymFile2,
- "%c:\\OS2\\PDPSI\\PMDF\\%s\\%s",
- doshQueryBootDrive(),
- "WARP45_U",
- pszFilename);
- arc = dbgPrintSYMInfo(LogFile,
- szSymFile2,
- ulObject,
- ulOffset);
- }
- }
- }
-
- if (arc == 2) // file not found
- fprintf(LogFile,
- "Cannot find symbol file %s\n",
- szSymName);
- else if (arc != 0)
- fprintf(LogFile,
- "Error %lu reading symbol file %s\n",
- arc,
- szSymName);
- }
-
- return (arc == NO_ERROR);
-}
-
-/*
- *@@ dbgPrintStack:
- * this takes stack data from the TIB and
- * context record data structures and tries
- * to analyse what the different stack frames
- * point to.
- *
- * For each stack frame, this calls dbgPrintDebugInfo,
- * and, if that fails, dbgPrintSYMInfo.
- *
- * New with V0.84.
- *
- *@@changed V0.9.2 (2000-03-08) [umoeller]: now searching OS2\PDPSI\PMDF for SYM files also
- */
-
-VOID dbgPrintStack(FILE *LogFile, // in: text log file to write to
- PUSHORT StackBottom,
- PUSHORT StackTop,
- PUSHORT Ebp,
- PUSHORT ExceptionAddress)
-{
- PUSHORT RetAddr = 0;
- PUSHORT LastEbp = 0;
- APIRET rc = 0;
- ULONG Size = 0,
- Attr = 0;
- USHORT Cs = 0,
- Ip = 0,
- // Bp,
- Sp = 0;
- static char Name[CCHMAXPATH];
- HMODULE hMod = 0;
- ULONG ObjNum = 0;
- ULONG Offset = 0;
- BOOL fExceptionAddress = TRUE; // Use Exception Addr 1st time thru
-
- // Note: we can't handle stacks bigger than 64K for now...
- Sp = (USHORT) (((ULONG) StackBottom) >> 16);
- // Bp = ;
-
- if (!f32bit)
- Ebp = (PUSHORT) MAKEULONG(((USHORT)(ULONG)Ebp), Sp);
-
- fprintf(LogFile, "\n\nCall stack:\n");
- fprintf(LogFile, " Source Line Nearest\n");
- fprintf(LogFile, " EBP Address Module Obj# File Numbr Public Symbol\n");
- fprintf(LogFile, " �������� ��������- �������� ���� ������������ ����� ������������-\n");
-
- do
- {
- Size = 10;
- rc = DosQueryMem((PVOID) (Ebp + 2), &Size, &Attr);
- if (rc != NO_ERROR)
- {
- fprintf(LogFile, "Invalid EBP %8.8lX (DosQueryMem returned %lu)\n", (ULONG)Ebp, rc);
- break;
- }
- if (!(Attr & PAG_COMMIT))
- {
- fprintf(LogFile, "Invalid EBP %8.8lX (not committed)\n", (ULONG)Ebp);
- break;
- }
- if (Size < 10)
- {
- fprintf(LogFile, "Invalid EBP %8.8lX (mem block size < 10)\n", (ULONG)Ebp);
- break;
- }
-
- if (fExceptionAddress)
- RetAddr = ExceptionAddress;
- else
- RetAddr = (PUSHORT) (*((PULONG) (Ebp + 2)));
-
- if (RetAddr == (PUSHORT) 0x00000053)
- {
- // For some reason there's a "return address" of 0x53 following
- // EBP on the stack and we have to adjust EBP by 44 bytes to get
- // at the real return address. This has something to do with
- // thunking from 32bits to 16bits...
- // Serious kludge, and it's probably dependent on versions of C(++)
- // runtime or OS, but it works for now!
- Ebp += 22;
- RetAddr = (PUSHORT) (*((PULONG) (Ebp + 2)));
- }
-
- // Get the (possibly) 16bit CS and IP
- if (fExceptionAddress)
- {
- Cs = (USHORT) (((ULONG) ExceptionAddress) >> 16);
- Ip = (USHORT) (ULONG) ExceptionAddress;
- }
- else
- {
- Cs = *(Ebp + 2);
- Ip = *(Ebp + 1);
- }
-
- // if the return address points to the stack then it's really just
- // a pointer to the return address (UGH!).
- if ( (USHORT) (((ULONG) RetAddr) >> 16) == Sp
- )
- RetAddr = (PUSHORT) (*((PULONG) RetAddr));
-
- if (Ip == 0 && *Ebp == 0)
- {
- // End of the stack so these are both shifted by 2 bytes:
- Cs = *(Ebp + 3);
- Ip = *(Ebp + 2);
- }
-
- // 16bit programs have on the stack:
- // BP:IP:CS
- // where CS may be thunked
- //
- // in dump swapped
- // BP IP CS BP CS IP
- // 4677 53B5 F7D0 7746 D0F7 B553
- //
- // 32bit programs have:
- // EBP:EIP
- // and you'd have something like this (with SP added) (not
- // accurate values)
- //
- // in dump swapped
- // EBP EIP EBP EIP
- // 4677 2900 53B5 F7D0 0029 7746 D0F7 B553
- //
- // So the basic difference is that 32bit programs have a 32bit
- // EBP and we can attempt to determine whether we have a 32bit
- // EBP by checking to see if its 'selector' is the same as SP.
- // Note that this technique limits us to checking stacks < 64K.
- //
- // Soooo, if IP (which maps into the same USHORT as the swapped
- // stack page in EBP) doesn't point to the stack (i.e. it could
- // be a 16bit IP) then see if CS is valid (as is or thunked).
- //
- // Note that there's the possibility of a 16bit return address
- // that has an offset that's the same as SP so we'll think it's
- // a 32bit return address and won't be able to successfully resolve
- // its details.
- if (Ip != Sp)
- {
- if (DosSizeSeg(Cs, &Size) == NO_ERROR)
- {
- RetAddr = (USHORT * _Seg16) MAKEULONG(Ip, Cs);
- f32bit = FALSE;
- }
- else if (DosSizeSeg((Cs << 3) + 7, &Size) == NO_ERROR)
- {
- Cs = (Cs << 3) + 7;
- RetAddr = (USHORT * _Seg16) MAKEULONG(Ip, Cs);
- f32bit = FALSE;
- }
- else
- f32bit = TRUE;
- }
- else
- f32bit = TRUE;
-
-
- // "EBP" column
- if (fExceptionAddress)
- fprintf(LogFile, " Trap -> ");
- else
- fprintf(LogFile, " %8.8lX ", (ULONG)Ebp);
-
- // "Address" column
- if (f32bit)
- fprintf(LogFile, ":%8.8lX ", (ULONG)RetAddr);
- else
- fprintf(LogFile, "%04.04X:%04.04X ", Cs, Ip);
-
- // Version check omitted; the following requires
- // OS/2 2.10 or later (*UM)
- // if (Version[0] >= 20 && Version[1] >= 10)
- {
- // Make a 'tick' sound to let the user know we're still alive
- DosBeep(2000, 10);
-
- Size = 10; // Inserted by Kim Rasmussen 26/06 1996 to avoid error 87 when Size is 0
-
- // "Module"/"Object" columns
- rc = DosQueryMem((PVOID) RetAddr, &Size, &Attr);
- if (rc != NO_ERROR || !(Attr & PAG_COMMIT))
- {
- fprintf(LogFile, "Invalid RetAddr: %8.8lX\n", (ULONG)RetAddr);
- break; // avoid infinite loops
- }
- else
- {
- rc = DosQueryModFromEIP(&hMod,
- &ObjNum,
- sizeof(Name), Name,
- &Offset,
- (PVOID)RetAddr);
- if ( (rc == NO_ERROR)
- // && (ObjNum != -1)
- )
- {
- // static char szJunk[_MAX_FNAME];
- static char szName[_MAX_FNAME];
-
- DosQueryModuleName(hMod, sizeof(Name), Name);
- // _splitpath(Name, szJunk, szJunk, szName, szJunk);
-
- // print module and object
- fprintf(LogFile, "%-8s %04lX ", szName, ObjNum + 1);
-
- if (strlen(Name) > 3)
- {
- dbgPrintStackFrame(LogFile,
- Name,
- ObjNum,
- Offset);
- }
- }
- else
- fprintf(LogFile,
- "DosQueryModFromEIP failed, returned %lu\n",
- rc);
- }
- }
-
- if ( ((*Ebp) == 0)
- && ((*Ebp + 1) == 0)
- )
- {
- fprintf(LogFile, "End of call stack\n");
- break;
- }
-
- if (!fExceptionAddress)
- {
- LastEbp = Ebp;
-
- if (f32bit)
- Ebp = (PUSHORT) *(PULONG) LastEbp;
- else
- Ebp = (PUSHORT) MAKEULONG((*Ebp), Sp);
-
- if (f32bit)
- {
- dbgPrintVariables(LogFile, (ULONG) Ebp);
- } // endif
-
- if (Ebp < LastEbp)
- {
- fprintf(LogFile, "... lost stack chain - new EBP below previous\n");
- break;
- }
- }
- else
- fExceptionAddress = FALSE;
-
- Size = 4;
- rc = DosQueryMem((PVOID) Ebp, &Size, &Attr);
- if ((rc != NO_ERROR) || (Size < 4))
- {
- fprintf(LogFile, "... lost stack chain - invalid EBP: %8.8lX\n", (ULONG)Ebp);
- break;
- }
- } while (TRUE);
-
- fprintf(LogFile, "\n");
-}
-
-/*
- *@@ doshQueryBootDrive:
- * returns the letter of the boot drive as a
- * single (capital) character, which is useful for
- * constructing file names using sprintf and such.
- *
- *@@changed V0.9.16 (2002-01-13) [umoeller]: optimized
- */
-
-CHAR doshQueryBootDrive(VOID)
-{
- // this can never change, so query this only once
- // V0.9.16 (2002-01-13) [umoeller]
- static CHAR cBootDrive = '\0';
-
- if (!cBootDrive)
- {
- ULONG ulBootDrive;
- DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
- &ulBootDrive,
- sizeof(ulBootDrive));
- cBootDrive = (CHAR)ulBootDrive + 'A' - 1;
- }
-
- return (cBootDrive);
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */