/sal/osl/os2/debug.c
C | 2152 lines | 1530 code | 218 blank | 404 comment | 292 complexity | b5606fbc9395bd94677640a1ebee7552 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-3.0, AGPL-1.0, BSD-3-Clause-No-Nuclear-License-2014, GPL-3.0, GPL-2.0, BSD-3-Clause, LGPL-2.1
Large files files are truncated, but you can click here to view the full file
- /*************************************************************************
- *
- * 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++)
- ;
- …
Large files files are truncated, but you can click here to view the full file