/*
 * Made after:
 *	CVDump - Parses through a Visual Studio .DBG file in CodeView 4 format
 * 	and dumps the info to STDOUT in a human-readable format
 *
 * 	Copyright 2000 John R. Sheets
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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 for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"
#include "wine/port.h"

#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <time.h>
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#include <fcntl.h>

#include "windef.h"
#include "winbase.h"
#include "winedump.h"
#include "wine/mscvpdb.h"

/*
 * .DBG File Layout:
 *
 * IMAGE_SEPARATE_DEBUG_HEADER
 * IMAGE_SECTION_HEADER[]
 * IMAGE_DEBUG_DIRECTORY[]
 * OMFSignature
 * debug data (typical example)
 *   - IMAGE_DEBUG_TYPE_MISC
 *   - IMAGE_DEBUG_TYPE_FPO
 *   - IMAGE_DEBUG_TYPE_CODEVIEW
 * OMFDirHeader
 * OMFDirEntry[]
 */

/*
 * Descriptions:
 *
 * (hdr)  IMAGE_SEPARATE_DEBUG_HEADER - .DBG-specific file header; holds info that
 *        applies to the file as a whole, including # of COFF sections, file offsets, etc.
 * (hdr)  IMAGE_SECTION_HEADER - list of COFF sections copied verbatim from .EXE;
 *        although this directory contains file offsets, these offsets are meaningless
 *        in the context of the .DBG file, because only the section headers are copied
 *        to the .DBG file... not the binary data it points to.
 * (hdr)  IMAGE_DEBUG_DIRECTORY - list of different formats of debug info contained in file
 *        (see IMAGE_DEBUG_TYPE_* descriptions below); tells where each section starts
 * (hdr)  OMFSignature (CV) - Contains "NBxx" signature, plus file offset telling how far
 *        into the IMAGE_DEBUG_TYPE_CODEVIEW section the OMFDirHeader and OMFDirEntry's sit
 * (data) IMAGE_DEBUG_TYPE_MISC - usually holds name of original .EXE file
 * (data) IMAGE_DEBUG_TYPE_FPO - Frame Pointer Optimization data; used for dealing with
 *        optimized stack frames (optional)
 * (data) IMAGE_DEBUG_TYPE_CODEVIEW - *** THE GOOD STUFF ***
 *        This block of data contains all the symbol tables, line number info, etc.,
 *        that the Visual C++ debugger needs.
 * (hdr)  OMFDirHeader (CV) -
 * (hdr)  OMFDirEntry (CV) - list of subsections within CodeView debug data section
 */

/*
 * The .DBG file typically has three arrays of directory entries, which tell
 * the OS or debugger where in the file to look for the actual data
 *
 * IMAGE_SECTION_HEADER - number of entries determined by:
 *    (IMAGE_SEPARATE_DEBUG_HEADER.NumberOfSections)
 *
 * IMAGE_DEBUG_DIRECTORY - number of entries determined by:
 *    (IMAGE_SEPARATE_DEBUG_HEADER.DebugDirectorySize / sizeof (IMAGE_DEBUG_DIRECTORY))
 *
 * OMFDirEntry - number of entries determined by:
 *    (OMFDirHeader.cDir)
 */

extern const IMAGE_NT_HEADERS*  PE_nt_headers;
static const void*	        cv_base /* = 0 */;

static int dump_cv_sst_module(const OMFDirEntry* omfde)
{
    const OMFModule*	module;
    const OMFSegDesc*	segDesc;
    int		i;

    module = PRD(Offset(cv_base) + omfde->lfo, sizeof(OMFModule));
    if (!module) {printf("Can't get the OMF-Module, aborting\n"); return FALSE;}

    printf("    olvNumber:          %u\n", module->ovlNumber);
    printf("    iLib:               %u\n", module->iLib);
    printf("    cSeg:               %u\n", module->cSeg);
    printf("    Style:              %c%c\n", module->Style[0], module->Style[1]);
    printf("    Name:               %.*s\n",
	   *(const BYTE*)((const char*)(module + 1) + sizeof(OMFSegDesc) * module->cSeg),
	   (const char*)(module + 1) + sizeof(OMFSegDesc) * module->cSeg + 1);

    segDesc = PRD(Offset(module + 1), sizeof(OMFSegDesc) * module->cSeg);
    if (!segDesc) {printf("Can't get the OMF-SegDesc, aborting\n"); return FALSE;}

    for (i = 0; i < module->cSeg; i++)
    {
	printf ("      segment #%2d: offset = [0x%8x], size = [0x%8x]\n",
		segDesc->Seg, segDesc->Off, segDesc->cbSeg);
	segDesc++;
    }
    return TRUE;
}

static int dump_cv_sst_global_pub(const OMFDirEntry* omfde)
{
    long	        fileoffset;
    const OMFSymHash*   header;
    const BYTE*	        symbols;

    fileoffset = Offset(cv_base) + omfde->lfo;
    printf ("    GlobalPub section starts at file offset 0x%lx\n", fileoffset);
    printf ("    Symbol table starts at 0x%lx\n", fileoffset + sizeof (OMFSymHash));

    printf ("\n                           ----- Begin Symbol Table -----\n");

    header = PRD(fileoffset, sizeof(OMFSymHash));
    if (!header) {printf("Can't get OMF-SymHash, aborting\n");return FALSE;}

    symbols = PRD(fileoffset + sizeof(OMFSymHash), header->cbSymbol);
    if (!symbols) {printf("Can't OMF-SymHash details, aborting\n"); return FALSE;}

    codeview_dump_symbols(symbols, header->cbSymbol);

    return TRUE;
}

static int dump_cv_sst_global_sym(const OMFDirEntry* omfde)
{
    /*** NOT YET IMPLEMENTED ***/
    return TRUE;
}

static int dump_cv_sst_static_sym(const OMFDirEntry* omfde)
{
    /*** NOT YET IMPLEMENTED ***/
    return TRUE;
}

static int dump_cv_sst_libraries(const OMFDirEntry* omfde)
{
    /*** NOT YET IMPLEMENTED ***/
    return TRUE;
}

static int dump_cv_sst_global_types(const OMFDirEntry* omfde)
{
    long	        fileoffset;
    const OMFGlobalTypes*types;
    const BYTE*         data;
    unsigned            sz;

    fileoffset = Offset(cv_base) + omfde->lfo;
    printf ("    GlobalTypes section starts at file offset 0x%lx\n", fileoffset);

    printf ("\n                           ----- Begin Global Types Table -----\n");

    types = PRD(fileoffset, sizeof(OMFGlobalTypes));
    if (!types) {printf("Can't get OMF-GlobalTypes, aborting\n");return FALSE;}

    sz = omfde->cb - sizeof(OMFGlobalTypes) - sizeof(DWORD) * types->cTypes;
    data = PRD(fileoffset + sizeof(OMFGlobalTypes) + sizeof(DWORD) * types->cTypes, sz);
    if (!data) {printf("Can't OMF-SymHash details, aborting\n"); return FALSE;}

    /* doc says:
     * - for NB07 & NB08 (that we don't support yet), offsets are from types
     * - for NB09, offsets are from data
     * For now, we only support the latter
     */
    codeview_dump_types_from_offsets(data, (const DWORD*)(types + 1), types->cTypes);

    return TRUE;
}

static int dump_cv_sst_seg_map(const OMFDirEntry* omfde)
{
    const OMFSegMap*		segMap;
    const OMFSegMapDesc*	segMapDesc;
    int		i;

    segMap = PRD(Offset(cv_base) + omfde->lfo, sizeof(OMFSegMap));
    if (!segMap) {printf("Can't get SegMap, aborting\n");return FALSE;}

    printf("    cSeg:          %u\n", segMap->cSeg);
    printf("    cSegLog:       %u\n", segMap->cSegLog);

    segMapDesc = PRD(Offset(segMap + 1), segMap->cSeg * sizeof(OMFSegDesc));
    if (!segMapDesc) {printf("Can't get SegDescr array, aborting\n");return FALSE;}

    for (i = 0; i < segMap->cSeg; i++)
    {
	printf("    SegDescr #%2d\n", i + 1);
	printf("      flags:         %04X\n", segMapDesc[i].flags);
	printf("      ovl:           %u\n", segMapDesc[i].ovl);
	printf("      group:         %u\n", segMapDesc[i].group);
	printf("      frame:         %u\n", segMapDesc[i].frame);
	printf("      iSegName:      %u\n", segMapDesc[i].iSegName);
	printf("      iClassName:    %u\n", segMapDesc[i].iClassName);
	printf("      offset:        %lu\n", segMapDesc[i].offset);
	printf("      cbSeg:         %lu\n", segMapDesc[i].cbSeg);
    }

    return TRUE;
}

static int dump_cv_sst_file_index(const OMFDirEntry* omfde)
{
    /*** NOT YET IMPLEMENTED ***/
    return TRUE;
}

static int dump_cv_sst_src_module(const OMFDirEntry* omfde)
{
    int 		        i, j;
    const BYTE*		        rawdata;
    const unsigned long*	seg_info_dw;
    const unsigned short*	seg_info_w;
    unsigned		        ofs;
    const OMFSourceModule*	sourceModule;
    const OMFSourceFile*	sourceFile;
    const OMFSourceLine*	sourceLine;

    rawdata = PRD(Offset(cv_base) + omfde->lfo, omfde->cb);
    if (!rawdata) {printf("Can't get srcModule subsection details, aborting\n");return FALSE;}

    /* FIXME: check ptr validity */
    sourceModule = (const void*)rawdata;
    printf ("    Module table: Found %d file(s) and %d segment(s)\n",
	    sourceModule->cFile, sourceModule->cSeg);
    for (i = 0; i < sourceModule->cFile; i++)
    {
	printf ("      File #%2d begins at an offset of 0x%lx in this section\n",
		i + 1, sourceModule->baseSrcFile[i]);
    }

    /* FIXME: check ptr validity */
    seg_info_dw = (const void*)((const char*)(sourceModule + 1) +
			  sizeof(unsigned long) * (sourceModule->cFile - 1));
    seg_info_w = (const unsigned short*)(&seg_info_dw[sourceModule->cSeg * 2]);
    for (i = 0; i <  sourceModule->cSeg; i++)
    {
	printf ("      Segment #%2d start = 0x%lx, end = 0x%lx, seg index = %u\n",
		i + 1, seg_info_dw[i * 2], seg_info_dw[(i * 2) + 1],
		seg_info_w[i]);
    }
    ofs = sizeof(OMFSourceModule) + sizeof(unsigned long) * (sourceModule->cFile - 1) +
	sourceModule->cSeg * (2 * sizeof(unsigned long) + sizeof(unsigned short));
    ofs = (ofs + 3) & ~3;

    /* the OMFSourceFile is quite unpleasant to use:
     * we have first:
     * 	unsigned short	number of segments
     *	unsigned short	reserved
     *	unsigned long	baseSrcLn[# segments]
     *  unsigned long	offset[2 * #segments]
     *				odd indices are start offsets
     *				even indices are end offsets
     * 	unsigned char	string length for file name
     *	char		file name (length is previous field)
     */
    /* FIXME: check ptr validity */
    sourceFile = (const void*)(rawdata + ofs);
    seg_info_dw = (const void*)((const char*)sourceFile + 2 * sizeof(unsigned short) +
			  sourceFile->cSeg * sizeof(unsigned long));

    ofs += 2 * sizeof(unsigned short) + 3 * sourceFile->cSeg * sizeof(unsigned long);

    printf("    File table: %.*s\n",
	   *(const BYTE*)((const char*)sourceModule + ofs), (const char*)sourceModule + ofs + 1);

    for (i = 0; i < sourceFile->cSeg; i++)
    {
	printf ("      Segment #%2d start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
		i + 1, seg_info_dw[i * 2], seg_info_dw[(i * 2) + 1], sourceFile->baseSrcLn[i]);
    }
    /* add file name length */
    ofs += *(const BYTE*)((const char*)sourceModule + ofs) + 1;
    ofs = (ofs + 3) & ~3;

    for (i = 0; i < sourceModule->cSeg; i++)
    {
        sourceLine = (const void*)(rawdata + ofs);
        seg_info_dw = (const void*)((const char*)sourceLine + 2 * sizeof(unsigned short));
        seg_info_w = (const void*)(&seg_info_dw[sourceLine->cLnOff]);

	printf ("    Line table #%2d: Found %d line numbers for segment index %d\n",
		i, sourceLine->cLnOff, sourceLine->Seg);

	for (j = 0; j < sourceLine->cLnOff; j++)
	{
	    printf ("      Pair #%2d: offset = [0x%8lx], linenumber = %d\n",
		    j + 1, seg_info_dw[j], seg_info_w[j]);
	}
	ofs += 2 * sizeof(unsigned short) +
	    sourceLine->cLnOff * (sizeof(unsigned long) + sizeof(unsigned short));
	ofs = (ofs + 3) & ~3;
    }

    return TRUE;
}

static int dump_cv_sst_align_sym(const OMFDirEntry* omfde)
{
    const char* rawdata = PRD(Offset(cv_base) + omfde->lfo, omfde->cb);

    if (!rawdata) {printf("Can't get srcAlignSym subsection details, aborting\n");return FALSE;}
    if (omfde->cb < sizeof(DWORD)) return TRUE;
    codeview_dump_symbols(rawdata + sizeof(DWORD), omfde->cb - sizeof(DWORD));

    return TRUE;
}

static void dump_codeview_all_modules(const OMFDirHeader *omfdh)
{
    unsigned 		i;
    const OMFDirEntry*  dirEntry;
    const char*		str;

    if (!omfdh || !omfdh->cDir) return;

    dirEntry = PRD(Offset(omfdh + 1), omfdh->cDir * sizeof(OMFDirEntry));
    if (!dirEntry) {printf("Can't read DirEntry array, aborting\n"); return;}

    for (i = 0; i < omfdh->cDir; i++)
    {
	switch (dirEntry[i].SubSection)
	{
	case sstModule:		str = "sstModule";	break;
	case sstAlignSym:	str = "sstAlignSym";	break;
	case sstSrcModule:	str = "sstSrcModule";	break;
	case sstLibraries:	str = "sstLibraries";	break;
	case sstGlobalSym:	str = "sstGlobalSym";	break;
	case sstGlobalPub:	str = "sstGlobalPub";	break;
	case sstGlobalTypes:	str = "sstGlobalTypes";	break;
	case sstSegMap:		str = "sstSegMap";	break;
	case sstFileIndex:	str = "sstFileIndex";	break;
	case sstStaticSym:	str = "sstStaticSym";	break;
	default:		str = "<undefined>";	break;
	}
	printf("Module #%2d (%p)\n", i + 1, &dirEntry[i]);
	printf("  SubSection:            %04X (%s)\n", dirEntry[i].SubSection, str);
	printf("  iMod:                  %d\n", dirEntry[i].iMod);
	printf("  lfo:                   %d\n", dirEntry[i].lfo);
	printf("  cb:                    %u\n", dirEntry[i].cb);

	switch (dirEntry[i].SubSection)
	{
	case sstModule:		dump_cv_sst_module(&dirEntry[i]);	break;
	case sstAlignSym:	dump_cv_sst_align_sym(&dirEntry[i]);	break;
	case sstSrcModule:	dump_cv_sst_src_module(&dirEntry[i]);	break;
	case sstLibraries:	dump_cv_sst_libraries(&dirEntry[i]);	break;
	case sstGlobalSym:	dump_cv_sst_global_sym(&dirEntry[i]);	break;
	case sstGlobalPub:	dump_cv_sst_global_pub(&dirEntry[i]);	break;
	case sstGlobalTypes:	dump_cv_sst_global_types(&dirEntry[i]);	break;
	case sstSegMap:		dump_cv_sst_seg_map(&dirEntry[i]);	break;
	case sstFileIndex:	dump_cv_sst_file_index(&dirEntry[i]);	break;
	case sstStaticSym:	dump_cv_sst_static_sym(&dirEntry[i]);	break;
	default:		printf("unsupported type %x\n", dirEntry[i].SubSection); break;
	}
	printf("\n");
    }

    return;
}

static void dump_codeview_headers(unsigned long base, unsigned long len)
{
    const OMFDirHeader* dirHeader;
    const char*         signature;
    const OMFDirEntry*  dirEntry;
    const OMFSignature* sig;
    unsigned		i;
    int modulecount = 0, alignsymcount = 0, srcmodulecount = 0, librariescount = 0;
    int globalsymcount = 0, globalpubcount = 0, globaltypescount = 0;
    int segmapcount = 0, fileindexcount = 0, staticsymcount = 0;

    cv_base = PRD(base, len);
    if (!cv_base) {printf("Can't get full debug content, aborting\n");return;}

    signature = cv_base;

    printf("    CodeView Data\n");
    printf("      Signature:         %.4s\n", signature);

    if (memcmp(signature, "NB10", 4) == 0)
    {
	const CODEVIEW_PDB_DATA* pdb_data;
	pdb_data = (const void *)cv_base;

        printf("      Filepos:           0x%08lX\n", pdb_data->filepos);
	printf("      TimeStamp:         %08X (%s)\n",
	       pdb_data->timestamp, get_time_str(pdb_data->timestamp));
	printf("      Age:               %08X\n", pdb_data->age);
	printf("      Filename:          %s\n", pdb_data->name);
	return;
    }
    if (memcmp(signature, "RSDS", 4) == 0)
    {
	const OMFSignatureRSDS* rsds_data;

	rsds_data = (const void *)cv_base;
	printf("      Guid:              %s\n", get_guid_str(&rsds_data->guid));
	printf("      Age:               %08X\n", rsds_data->age);
	printf("      Filename:          %s\n", rsds_data->name);
	return;
    }

    if (memcmp(signature, "NB09", 4) != 0 && memcmp(signature, "NB11", 4) != 0)
    {
	printf("Unsupported signature (%.4s), aborting\n", signature);
	return;
    }

    sig = cv_base;

    printf("      Filepos:           0x%08lX\n", sig->filepos);

    dirHeader = PRD(Offset(cv_base) + sig->filepos, sizeof(OMFDirHeader));
    if (!dirHeader) {printf("Can't get debug header, aborting\n"); return;}

    printf("      Size of header:    0x%4X\n", dirHeader->cbDirHeader);
    printf("      Size per entry:    0x%4X\n", dirHeader->cbDirEntry);
    printf("      # of entries:      0x%8X (%d)\n", dirHeader->cDir, dirHeader->cDir);
    printf("      Offset to NextDir: 0x%8X\n", dirHeader->lfoNextDir);
    printf("      Flags:             0x%8X\n", dirHeader->flags);

    if (!dirHeader->cDir) return;

    dirEntry = PRD(Offset(dirHeader + 1), sizeof(OMFDirEntry) * dirHeader->cDir);
    if (!dirEntry) {printf("Can't get DirEntry array, aborting\n");return;}

    for (i = 0; i < dirHeader->cDir; i++)
    {
	switch (dirEntry[i].SubSection)
	{
	case sstModule:		modulecount++;		break;
	case sstAlignSym:	alignsymcount++;	break;
	case sstSrcModule:	srcmodulecount++;	break;
	case sstLibraries:	librariescount++;	break;
	case sstGlobalSym:	globalsymcount++;	break;
	case sstGlobalPub:	globalpubcount++;	break;
	case sstGlobalTypes:	globaltypescount++;	break;
	case sstSegMap:		segmapcount++;		break;
	case sstFileIndex:	fileindexcount++;	break;
	case sstStaticSym:	staticsymcount++;	break;
	}
    }

    /* This one has to be > 0
     */
    printf ("\nFound: %d sstModule subsections\n", modulecount);

    if (alignsymcount > 0)    printf ("       %d sstAlignSym subsections\n", alignsymcount);
    if (srcmodulecount > 0)   printf ("       %d sstSrcModule subsections\n", srcmodulecount);
    if (librariescount > 0)   printf ("       %d sstLibraries subsections\n", librariescount);
    if (globalsymcount > 0)   printf ("       %d sstGlobalSym subsections\n", globalsymcount);
    if (globalpubcount > 0)   printf ("       %d sstGlobalPub subsections\n", globalpubcount);
    if (globaltypescount > 0) printf ("       %d sstGlobalTypes subsections\n", globaltypescount);
    if (segmapcount > 0)      printf ("       %d sstSegMap subsections\n", segmapcount);
    if (fileindexcount > 0)   printf ("       %d sstFileIndex subsections\n", fileindexcount);
    if (staticsymcount > 0)   printf ("       %d sstStaticSym subsections\n", staticsymcount);

    dump_codeview_all_modules(dirHeader);
}

static const char *get_coff_name( const IMAGE_SYMBOL *coff_sym, const char *coff_strtab )
{
   static       char    namebuff[9];
   const char*          nampnt;

   if( coff_sym->N.Name.Short )
      {
         memcpy(namebuff, coff_sym->N.ShortName, 8);
         namebuff[8] = '\0';
         nampnt = &namebuff[0];
      }
   else
      {
         nampnt = coff_strtab + coff_sym->N.Name.Long;
      }

   if( nampnt[0] == '_' )
      nampnt++;
   return nampnt;
}

static const char* storage_class(BYTE sc)
{
    static char tmp[7];
    switch (sc)
    {
    case IMAGE_SYM_CLASS_STATIC:        return "static";
    case IMAGE_SYM_CLASS_EXTERNAL:      return "extrnl";
    case IMAGE_SYM_CLASS_LABEL:         return "label ";
    }
    sprintf(tmp, "#%d", sc);
    return tmp;
}

void    dump_coff_symbol_table(const IMAGE_SYMBOL *coff_symbols, unsigned num_sym,
                               const IMAGE_SECTION_HEADER *sectHead)
{
    const IMAGE_SYMBOL              *coff_sym;
    const char                      *coff_strtab = (const char *) (coff_symbols + num_sym);
    unsigned int                    i;
    const char                      *nampnt;
    int                             naux;

    printf("\nDebug table: COFF format.\n");
    printf("  ID  | seg:offs    [  abs   ] |  Kind  | symbol/function name\n");
    for (i=0; i < num_sym; i++)
    {
        coff_sym = coff_symbols + i;
        naux = coff_sym->NumberOfAuxSymbols;

        switch (coff_sym->StorageClass)
        {
        case IMAGE_SYM_CLASS_FILE:
            printf("file %s\n", (const char *) (coff_sym + 1));
            break;
        case IMAGE_SYM_CLASS_STATIC:
        case IMAGE_SYM_CLASS_EXTERNAL:
        case IMAGE_SYM_CLASS_LABEL:
            if (coff_sym->SectionNumber > 0)
            {
                DWORD base = sectHead[coff_sym->SectionNumber - 1].VirtualAddress;
                nampnt = get_coff_name( coff_sym, coff_strtab );

                printf("%05d | %02d:%08x [%08x] | %s | %s\n",
                       i, coff_sym->SectionNumber - 1, coff_sym->Value,
                       base + coff_sym->Value,
                       storage_class(coff_sym->StorageClass), nampnt);
            }
            break;
        default:
            printf("%05d | %s\n", i, storage_class(coff_sym->StorageClass));
        }
        /*
         * For now, skip past the aux entries.
         */
        i += naux;
    }
}

void	dump_coff(unsigned long coffbase, unsigned long len, const IMAGE_SECTION_HEADER* sectHead)
{
    const IMAGE_COFF_SYMBOLS_HEADER *coff = PRD(coffbase, len);
    const IMAGE_SYMBOL              *coff_symbols =
                                        (const IMAGE_SYMBOL *) ((const char *)coff + coff->LvaToFirstSymbol);

    dump_coff_symbol_table(coff_symbols, coff->NumberOfSymbols, sectHead);
}

void	dump_codeview(unsigned long base, unsigned long len)
{
    dump_codeview_headers(base, len);
}

void	dump_frame_pointer_omission(unsigned long base, unsigned long len)
{
    const FPO_DATA*     fpo;
    const FPO_DATA*     last;
    const char*         x;
    /* FPO is used to describe nonstandard stack frames */
    printf("Range             #loc #pmt Prlg #reg Info\n"
           "-----------------+----+----+----+----+------------\n");

    fpo = PRD(base, len);
    if (!fpo) {printf("Couldn't get FPO blob\n"); return;}
    last = (const FPO_DATA*)((const char*)fpo + len);

    while (fpo < last && fpo->ulOffStart)
    {
        switch (fpo->cbFrame)
        {
        case FRAME_FPO: x = "FRAME_FPO"; break;
        case FRAME_NONFPO: x = "FRAME_NONFPO"; break;
        case FRAME_TRAP: x = "FRAME_TRAP"; break;
        case FRAME_TSS: x = "case FRAME_TSS"; break;
        default: x = NULL; break;
        }
        printf("%08x-%08x %4u %4u %4u %4u %s%s%s\n",
               fpo->ulOffStart, fpo->ulOffStart + fpo->cbProcSize,
               fpo->cdwLocals, fpo->cdwParams, fpo->cbProlog, fpo->cbRegs,
               x, fpo->fHasSEH ? " SEH" : "", fpo->fUseBP ? " UseBP" : "");
        fpo++;
    }
}

struct stab_nlist
{
    union
    {
        char*                   n_name;
        struct stab_nlist*      n_next;
        long                    n_strx;
    } n_un;
    unsigned char       n_type;
    char                n_other;
    short               n_desc;
    unsigned long       n_value;
};

static const char * const stabs_defs[] = {
    NULL,NULL,NULL,NULL,                /* 00 */
    NULL,NULL,NULL,NULL,                /* 08 */
    NULL,NULL,NULL,NULL,                /* 10 */
    NULL,NULL,NULL,NULL,                /* 18 */
    "GSYM","FNAME","FUN","STSYM",       /* 20 */
    "LCSYM","MAIN","ROSYM","PC",        /* 28 */
    NULL,"NSYMS","NOMAP",NULL,          /* 30 */
    "OBJ",NULL,"OPT",NULL,              /* 38 */
    "RSYM","M2C","SLINE","DSLINE",      /* 40 */
    "BSLINE","DEFD","FLINE",NULL,       /* 48 */
    "EHDECL",NULL,"CATCH",NULL,         /* 50 */
    NULL,NULL,NULL,NULL,                /* 58 */
    "SSYM","ENDM","SO",NULL,            /* 60 */
    NULL,NULL,NULL,NULL,                /* 68 */
    NULL,NULL,NULL,NULL,                /* 70 */
    NULL,NULL,NULL,NULL,                /* 78 */
    "LSYM","BINCL","SOL",NULL,          /* 80 */
    NULL,NULL,NULL,NULL,                /* 88 */
    NULL,NULL,NULL,NULL,                /* 90 */
    NULL,NULL,NULL,NULL,                /* 98 */
    "PSYM","EINCL","ENTRY",NULL,        /* a0 */
    NULL,NULL,NULL,NULL,                /* a8 */
    NULL,NULL,NULL,NULL,                /* b0 */
    NULL,NULL,NULL,NULL,                /* b8 */
    "LBRAC","EXCL","SCOPE",NULL,        /* c0 */
    NULL,NULL,NULL,NULL,                /* c8 */
    NULL,NULL,NULL,NULL,                /* d0 */
    NULL,NULL,NULL,NULL,                /* d8 */
    "RBRAC","BCOMM","ECOMM",NULL,       /* e0 */
    "ECOML","WITH",NULL,NULL,           /* e8 */
    "NBTEXT","NBDATA","NBBSS","NBSTS",  /* f0 */
    "NBLCS",NULL,NULL,NULL              /* f8 */
};

void    dump_stabs(const void* pv_stabs, unsigned szstabs, const char* stabstr, unsigned szstr)
{
    int                         i;
    int                         nstab;
    const char*                 ptr;
    char*                       stabbuff;
    unsigned int                stabbufflen;
    const struct stab_nlist*    stab_ptr = pv_stabs;
    const char*                 strs_end;
    char                        n_buffer[16];

    nstab = szstabs / sizeof(struct stab_nlist);
    strs_end = stabstr + szstr;

    /*
     * Allocate a buffer into which we can build stab strings for cases
     * where the stab is continued over multiple lines.
     */
    stabbufflen = 65536;
    stabbuff = malloc(stabbufflen);

    stabbuff[0] = '\0';

    printf("#Sym n_type n_othr   n_desc n_value  n_strx String\n");

    for (i = 0; i < nstab; i++, stab_ptr++)
    {
        ptr = stabstr + stab_ptr->n_un.n_strx;
        if ((ptr > strs_end) || (ptr + strlen(ptr) > strs_end))
        {
            ptr = "[[*** bad string ***]]";
        }
        else if (ptr[strlen(ptr) - 1] == '\\')
        {
            /*
             * Indicates continuation.  Append this to the buffer, and go onto the
             * next record.  Repeat the process until we find a stab without the
             * '/' character, as this indicates we have the whole thing.
             */
            unsigned    len = strlen(ptr);
            if (strlen(stabbuff) + len > stabbufflen)
            {
                stabbufflen += 65536;
                stabbuff = realloc(stabbuff, stabbufflen);
            }
            strncat(stabbuff, ptr, len - 1);
            continue;
        }
        else if (stabbuff[0] != '\0')
        {
            strcat(stabbuff, ptr);
            ptr = stabbuff;
        }
        if ((stab_ptr->n_type & 1) || !stabs_defs[stab_ptr->n_type / 2])
            sprintf(n_buffer, "<0x%02x>", stab_ptr->n_type);
        else
            sprintf(n_buffer, "%-6s", stabs_defs[stab_ptr->n_type / 2]);
        printf("%4d %s %-8x % 6d %-8lx %-6lx %s\n", 
               i, n_buffer, stab_ptr->n_other, stab_ptr->n_desc, stab_ptr->n_value,
               stab_ptr->n_un.n_strx, ptr);
    }
    free(stabbuff);
}
