/*
 *	PDB dumping utility
 *
 * 	Copyright 2006 Eric Pouech
 *
 * 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>

#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "windef.h"
#include "winbase.h"
#include "winedump.h"
#include "wine/mscvpdb.h"

struct pdb_reader
{
    union
    {
        struct
        {
            const struct PDB_JG_HEADER* header;
            const struct PDB_JG_TOC*    toc;
            const struct PDB_JG_ROOT*   root;
        } jg;
        struct
        {
            const struct PDB_DS_HEADER* header;
            const struct PDB_DS_TOC*    toc;
            const struct PDB_DS_ROOT*   root;
        } ds;
    } u;
    void*       (*read_file)(struct pdb_reader*, DWORD);
    DWORD       file_used[1024];
};

static void* pdb_jg_read(const struct PDB_JG_HEADER* pdb, const WORD* block_list, int size)
{
    int                 i, nBlocks;
    BYTE*               buffer;

    if (!size) return NULL;

    nBlocks = (size + pdb->block_size - 1) / pdb->block_size;
    buffer = malloc(nBlocks * pdb->block_size);

    for (i = 0; i < nBlocks; i++)
        memcpy(buffer + i * pdb->block_size,
               (const char*)pdb + block_list[i] * pdb->block_size, pdb->block_size);

    return buffer;
}

static void* pdb_jg_read_file(struct pdb_reader* reader, DWORD file_nr)
{
    const WORD*         block_list;
    DWORD               i;

    if (!reader->u.jg.toc || file_nr >= reader->u.jg.toc->num_files) return NULL;

    reader->file_used[file_nr / 32] |= 1 << (file_nr % 32);
    if (reader->u.jg.toc->file[file_nr].size == 0 ||
        reader->u.jg.toc->file[file_nr].size == 0xFFFFFFFF)
        return NULL;
    block_list = (const WORD*) &reader->u.jg.toc->file[reader->u.jg.toc->num_files];
    for (i = 0; i < file_nr; i++)
        block_list += (reader->u.jg.toc->file[i].size +
                       reader->u.jg.header->block_size - 1) / reader->u.jg.header->block_size;

    return pdb_jg_read(reader->u.jg.header, block_list,
                       reader->u.jg.toc->file[file_nr].size);
}

static void pdb_jg_init(struct pdb_reader* reader)
{
    reader->u.jg.header = PRD(0, sizeof(struct PDB_JG_HEADER));
    reader->read_file = pdb_jg_read_file;
    reader->u.jg.toc = pdb_jg_read(reader->u.jg.header, 
                                   reader->u.jg.header->toc_block,
                                   reader->u.jg.header->toc.size);
    memset(reader->file_used, 0, sizeof(reader->file_used));
}

static DWORD    pdb_get_num_files(const struct pdb_reader* reader)
{
    if (reader->read_file == pdb_jg_read_file)
        return reader->u.jg.toc->num_files;
    else
        return reader->u.ds.toc->num_files;
}

static DWORD    pdb_get_file_size(const struct pdb_reader* reader, unsigned idx)
{
    if (reader->read_file == pdb_jg_read_file)
        return reader->u.jg.toc->file[idx].size;
    else
        return reader->u.ds.toc->file_size[idx];
}

static void pdb_exit(struct pdb_reader* reader)
{
#if 1
    unsigned            i;
    unsigned char*      file;
    DWORD               size;

    for (i = 0; i < pdb_get_num_files(reader); i++)
    {
        if (reader->file_used[i / 32] & (1 << (i % 32))) continue;

        file = reader->read_file(reader, i);
        if (!file) continue;

        size = pdb_get_file_size(reader, i);

        printf("File --unused-- #%d (%x)\n", i, size);
        dump_data(file, size, "    ");
        free(file);
    }
#endif
    if (reader->read_file == pdb_jg_read_file)
    {
        free((char*)reader->u.jg.root);
        free((char*)reader->u.jg.toc);
    }
    else
    {
        free((char*)reader->u.ds.root);
        free((char*)reader->u.ds.toc);
    }
}

static unsigned get_stream_by_name(struct pdb_reader* reader, const char* name)
{
    DWORD*      pdw;
    DWORD*      ok_bits;
    DWORD       cbstr, count;
    DWORD       string_idx, stream_idx;
    unsigned    i;
    const char* str;

    if (reader->read_file == pdb_jg_read_file)
    {
        str = &reader->u.jg.root->names[0];
        cbstr = reader->u.jg.root->cbNames;
    }
    else
    {
        str = &reader->u.ds.root->names[0];
        cbstr = reader->u.ds.root->cbNames;
    }

    pdw = (DWORD*)(str + cbstr);
    pdw++; /* number of ok entries */
    count = *pdw++;

    /* bitfield: first dword is len (in dword), then data */
    ok_bits = pdw;
    pdw += *ok_bits++ + 1;
    if (*pdw++ != 0)
    {
        printf("unexpected value\n");
        return -1;
    }

    for (i = 0; i < count; i++)
    {
        if (ok_bits[i / 32] & (1 << (i % 32)))
        {
            string_idx = *pdw++;
            stream_idx = *pdw++;
            if (!strcmp(name, &str[string_idx])) return stream_idx;
        }
    }
    return -1;
}

static void *read_string_table(struct pdb_reader* reader)
{
    unsigned    stream_idx;
    void*       ret;

    stream_idx = get_stream_by_name(reader, "/names");
    if (stream_idx == -1) return NULL;
    ret = reader->read_file(reader, stream_idx);
    if (ret && *(const DWORD*)ret == 0xeffeeffe) return ret;
    printf("wrong header %x expecting 0xeffeeffe\n", *(const DWORD*)ret);
    free( ret );
    return NULL;
}

static void pdb_dump_symbols(struct pdb_reader* reader, PDB_STREAM_INDEXES* sidx)
{
    PDB_SYMBOLS*    symbols;
    unsigned char*  modimage;
    const char*     file;
    char*           filesimage;
    DWORD           filessize = 0;

    sidx->FPO = sidx->unk0 = sidx->unk1 = sidx->unk2 = sidx->unk3 = sidx->segments =
        sidx->unk4 = sidx->unk5 = sidx->unk6 = sidx->FPO_EXT = sidx->unk7 = -1;

    symbols = reader->read_file(reader, 3);
    if (!symbols) return;

    switch (symbols->version)
    {
    case 0:            /* VC 4.0 */
    case 19960307:     /* VC 5.0 */
    case 19970606:     /* VC 6.0 */
    case 19990903:     /* VC 7.0 */
        break;
    default:
        printf("-Unknown symbol info version %d\n", symbols->version);
    }
    printf("Symbols:\n"
           "\tsignature:       %08x\n"
           "\tversion:         %u\n"
           "\tunknown:         %08x\n"
           "\thash1_file:      %08x\n"
           "\thash2_file:      %08x\n"
           "\tgsym_file:       %04x\n"
           "\tunknown1:        %04x\n"
           "\tmodule_size:     %08x\n"
           "\toffset_size:     %08x\n"
           "\thash_size:       %08x\n"
           "\tsrc_module_size: %08x\n"
           "\tpdbimport_size:  %08x\n"
           "\tresvd0:          %08x\n"
           "\tstream_idx_size: %08x\n"
           "\tunknown2_size:   %08x\n"
           "\tresvd3:          %04x\n"
           "\tmachine:         %s\n"
           "\tresvd[4]         %08x\n",
           symbols->signature,
           symbols->version,
           symbols->unknown,
           symbols->hash1_file,
           symbols->hash2_file,
           symbols->gsym_file,
           symbols->unknown1,
           symbols->module_size,
           symbols->offset_size,
           symbols->hash_size,
           symbols->srcmodule_size,
           symbols->pdbimport_size,
           symbols->resvd0,
           symbols->stream_index_size,
           symbols->unknown2_size,
           symbols->resvd3,
           get_machine_str( symbols->machine ),
           symbols->resvd4);

    if (symbols->offset_size)
    {
        const BYTE*                 src;

        printf("\t----------offsets------------\n");
        src = (const BYTE*)((const char*)symbols + sizeof(PDB_SYMBOLS) + symbols->module_size);
        dump_data(src, symbols->offset_size, "    ");
    }

    if (!(filesimage = read_string_table(reader))) printf("string table not found\n");
    else filessize = *(const DWORD*)(filesimage + 8);

    if (symbols->srcmodule_size)
    {
        const PDB_SYMBOL_SOURCE*src;
        int                     i, j, cfile;
        const WORD*             indx;
        const DWORD*            offset;
        const char*             start_cstr;
        const char*             cstr;

        printf("\t----------src module------------\n");
        src = (const PDB_SYMBOL_SOURCE*)((const char*)symbols + sizeof(PDB_SYMBOLS) + 
                                         symbols->module_size + symbols->offset_size + symbols->hash_size);
        printf("\tSource Modules\n"
               "\t\tnModules:         %u\n"
               "\t\tnSrcFiles:        %u\n",
               src->nModules, src->nSrcFiles);

        /* usage of table seems to be as follows:
         * two arrays of WORD (src->nModules as size)
         *  - first array contains index into files for "module" compilation
         *    (module = compilation unit ??)
         *  - second array contains the number of source files in module
         *    an array of DWORD (src->nSrcFiles as size)
         *  - contains offset (in following string table) of the source file name
         *    a string table
         *  - each string is a pascal string (ie. with its length as first BYTE) or
         *    0-terminated string (depending on version)
         */
        indx = &src->table[src->nModules];
        offset = (const DWORD*)&src->table[2 * src->nModules];
        cstr = (const char*)&src->table[2 * (src->nModules + src->nSrcFiles)];
        start_cstr = cstr;

        for (i = cfile = 0; i < src->nModules; i++)
        {
            printf("\t\tModule[%2d]:\n", i);
            cfile = src->table[i];
            for (j = cfile; j < src->nSrcFiles && j < cfile + indx[i]; j++)
            {
                /* FIXME: in some cases, it's a p_string but WHEN ? */
                if (cstr + offset[j] >= (const char*)start_cstr /* wrap around */ &&
                    cstr + offset[j] < (const char*)src + symbols->srcmodule_size)
                    printf("\t\t\tSource file: %s\n", cstr + offset[j]);
                else
                    printf("\t\t\tSource file: <<out of bounds>>\n");
            }
        }
    }
    if (symbols->pdbimport_size)
    {
        const PDB_SYMBOL_IMPORT*  imp;
        const char* first;
        const char* last;
        const char* ptr;

        printf("\t------------import--------------\n");
        imp = (const PDB_SYMBOL_IMPORT*)((const char*)symbols + sizeof(PDB_SYMBOLS) + 
                                         symbols->module_size + symbols->offset_size + 
                                         symbols->hash_size + symbols->srcmodule_size);
        first = (const char*)imp;
        last = (const char*)imp + symbols->pdbimport_size;
        while (imp < (const PDB_SYMBOL_IMPORT*)last)
        {
            ptr = (const char*)imp + sizeof(*imp) + strlen(imp->filename);
            printf("\tImport: %lx\n"
                   "\t\tUnknown1:      %08x\n"
                   "\t\tUnknown2:      %08x\n"
                   "\t\tTimeDateStamp: %08x\n"
                   "\t\tAge:           %08u\n"
                   "\t\tfile1:         %s\n"
                   "\t\tfile2:         %s\n",
                   (ULONG_PTR)((const char*)imp - (const char*)first),
                   imp->unknown1,
                   imp->unknown2,
                   imp->TimeDateStamp,
                   imp->Age,
                   imp->filename,
                   ptr);
            imp = (const PDB_SYMBOL_IMPORT*)(first + ((ptr - first + strlen(ptr) + 1 + 3) & ~3));
        }
    }
    if (symbols->stream_index_size)
    {
        printf("\t------------stream indexes--------------\n");
        switch (symbols->stream_index_size)
        {
        case sizeof(PDB_STREAM_INDEXES_OLD):
            /* PDB_STREAM_INDEXES is a superset of PDB_STREAM_INDEX_OLD
             * FIXME: to be confirmed when all fields are fully understood
             */
            memcpy(sidx,
                   (const char*)symbols + sizeof(PDB_SYMBOLS) + symbols->module_size +
                   symbols->offset_size + symbols->hash_size + symbols->srcmodule_size +
                   symbols->pdbimport_size + symbols->unknown2_size,
                   sizeof(PDB_STREAM_INDEXES_OLD));
            printf("\tFPO:                  %04x\n"
                   "\t?:                    %04x\n"
                   "\t?:                    %04x\n"
                   "\t?:                    %04x\n"
                   "\t?:                    %04x\n"
                   "\tSegments:             %04x\n",
                   sidx->FPO, sidx->unk0, sidx->unk1, sidx->unk2, sidx->unk3,
                   sidx->segments);
            break;
        case sizeof(PDB_STREAM_INDEXES):
            memcpy(sidx,
                   (const char*)symbols + sizeof(PDB_SYMBOLS) + symbols->module_size +
                   symbols->offset_size + symbols->hash_size + symbols->srcmodule_size +
                   symbols->pdbimport_size + symbols->unknown2_size,
                   sizeof(*sidx));
            printf("\tFPO:                  %04x\n"
                   "\t?:                    %04x\n"
                   "\t?:                    %04x\n"
                   "\t?:                    %04x\n"
                   "\t?:                    %04x\n"
                   "\tSegments:             %04x\n"
                   "\t?:                    %04x\n"
                   "\t?:                    %04x\n"
                   "\t?:                    %04x\n"
                   "\tFPO-ext:              %04x\n"
                   "\t?:                    %04x\n",
                   sidx->FPO, sidx->unk0, sidx->unk1, sidx->unk2, sidx->unk3,
                   sidx->segments, sidx->unk4, sidx->unk5, sidx->unk6, sidx->FPO_EXT,
                   sidx->unk7);
            break;
        default:
            printf("unexpected size for stream index %d\n", symbols->stream_index_size);
            break;
        }
    }

    /* Read global symbol table */
    modimage = reader->read_file(reader, symbols->gsym_file);
    if (modimage)
    {
        printf("\t------------globals-------------\n"); 
        codeview_dump_symbols(modimage, pdb_get_file_size(reader, symbols->gsym_file));
        free(modimage);
    }

    /* Read per-module symbol / linenumber tables */
    file = (const char*)symbols + sizeof(PDB_SYMBOLS);
    while (file - (const char*)symbols < sizeof(PDB_SYMBOLS) + symbols->module_size)
    {
        int file_nr, symbol_size, lineno_size;
        const char* file_name;
            
        if (symbols->version < 19970000)
        {
            const PDB_SYMBOL_FILE*      sym_file = (const PDB_SYMBOL_FILE*) file;
            file_nr     = sym_file->file;
            file_name   = sym_file->filename;
            symbol_size = sym_file->symbol_size;
            lineno_size = sym_file->lineno_size;
            printf("\t--------symbol file----------- %s\n", file_name);
            printf("\tgot symbol_file\n"
                   "\t\tunknown1:   %08x\n"
                   "\t\trange\n"
                   "\t\t\tsegment:         %04x\n"
                   "\t\t\tpad1:            %04x\n"
                   "\t\t\toffset:          %08x\n"
                   "\t\t\tsize:            %08x\n"
                   "\t\t\tcharacteristics: %08x\n"
                   "\t\t\tindex:           %04x\n"
                   "\t\t\tpad2:            %04x\n"
                   "\t\tflag:       %04x\n"
                   "\t\tfile:       %04x\n"
                   "\t\tsymb size:  %08x\n"
                   "\t\tline size:  %08x\n"
                   "\t\tunknown2:   %08x\n"
                   "\t\tnSrcFiles:  %08x\n"
                   "\t\tattribute:  %08x\n",
                   sym_file->unknown1,
                   sym_file->range.segment,
                   sym_file->range.pad1,
                   sym_file->range.offset,
                   sym_file->range.size,
                   sym_file->range.characteristics,
                   sym_file->range.index,
                   sym_file->range.pad2,
                   sym_file->flag,
                   sym_file->file,
                   sym_file->symbol_size,
                   sym_file->lineno_size,
                   sym_file->unknown2,
                   sym_file->nSrcFiles,
                   sym_file->attribute);
        }
        else
        {
            const PDB_SYMBOL_FILE_EX*   sym_file = (const PDB_SYMBOL_FILE_EX*) file;
            file_nr     = sym_file->file;
            file_name   = sym_file->filename;
            symbol_size = sym_file->symbol_size;
            lineno_size = sym_file->lineno_size;
            printf("\t--------symbol file----------- %s\n", file_name);
            printf("\t\tunknown1:   %08x\n"
                   "\t\trange\n"
                   "\t\t\tsegment:         %04x\n"
                   "\t\t\tpad1:            %04x\n"
                   "\t\t\toffset:          %08x\n"
                   "\t\t\tsize:            %08x\n"
                   "\t\t\tcharacteristics: %08x\n"
                   "\t\t\tindex:           %04x\n"
                   "\t\t\tpad2:            %04x\n"
                   "\t\t\ttimestamp:       %08x\n"
                   "\t\t\tunknown:         %08x\n"
                   "\t\tflag:       %04x\n"
                   "\t\tfile:       %04x\n"
                   "\t\tsymb size:  %08x\n"
                   "\t\tline size:  %08x\n"
                   "\t\tunknown2:   %08x\n"
                   "\t\tnSrcFiles:  %08x\n"
                   "\t\tattribute:  %08x\n"
                   "\t\treserved/0: %08x\n"
                   "\t\treserved/1: %08x\n",
                   sym_file->unknown1,
                   sym_file->range.segment,
                   sym_file->range.pad1,
                   sym_file->range.offset,
                   sym_file->range.size,
                   sym_file->range.characteristics,
                   sym_file->range.index,
                   sym_file->range.pad2,
                   sym_file->range.timestamp,
                   sym_file->range.unknown,
                   sym_file->flag,
                   sym_file->file,
                   sym_file->symbol_size,
                   sym_file->lineno_size,
                   sym_file->unknown2,
                   sym_file->nSrcFiles,
                   sym_file->attribute,
                   sym_file->reserved[0],
                   sym_file->reserved[1]);
        }
        modimage = reader->read_file(reader, file_nr);
        if (modimage)
        {
            int total_size = pdb_get_file_size(reader, file_nr);

            if (symbol_size)
                codeview_dump_symbols((const char*)modimage + sizeof(DWORD), symbol_size);

            /* line number info */
            if (lineno_size)
                codeview_dump_linetab((const char*)modimage + symbol_size, TRUE, "        ");
            /* anyway, lineno_size doesn't see to really be the size of the line number information, and
             * it's not clear yet when to call for linetab2...
             */
            codeview_dump_linetab2((const char*)modimage + symbol_size + lineno_size,
                                   total_size - (symbol_size + lineno_size),
                                   filesimage ? filesimage + 12 : NULL, filessize, "        ");
            /* what's that part ??? */
            if (0)
                dump_data(modimage + symbol_size + lineno_size, total_size - (symbol_size + lineno_size), "    ");
            free(modimage);
        }

        file_name += strlen(file_name) + 1;
        file = (char*)((DWORD_PTR)(file_name + strlen(file_name) + 1 + 3) & ~3);
    }
    free(symbols);
    free(filesimage);
}

static void pdb_dump_types(struct pdb_reader* reader)
{
    PDB_TYPES*  types = NULL;

    types = reader->read_file(reader, 2);

    switch (types->version)
    {
    case 19950410:      /* VC 4.0 */
    case 19951122:
    case 19961031:      /* VC 5.0 / 6.0 */
    case 19990903:      /* VC 7.0 */
    case 20040203:      /* VC 8.0 */
        break;
    default:
        printf("-Unknown type info version %d\n", types->version);
    }

    /* Read type table */
    printf("Types:\n"
           "\tversion:        %u\n"
           "\ttype_offset:    %08x\n"
           "\tfirst_index:    %x\n"
           "\tlast_index:     %x\n"
           "\ttype_size:      %x\n"
           "\tfile:           %x\n"
           "\tpad:            %x\n"
           "\thash_size:      %x\n"
           "\thash_base:      %x\n"
           "\thash_offset:    %x\n"
           "\thash_len:       %x\n"
           "\tsearch_offset:  %x\n"
           "\tsearch_len:     %x\n"
           "\tunknown_offset: %x\n"
           "\tunknown_len:    %x\n",
           types->version,
           types->type_offset,
           types->first_index,
           types->last_index,
           types->type_size,
           types->file,
           types->pad,
           types->hash_size,
           types->hash_base,
           types->hash_offset,
           types->hash_len,
           types->search_offset,
           types->search_len,
           types->unknown_offset,
           types->unknown_len);
    codeview_dump_types_from_block((const char*)types + types->type_offset, types->type_size);
    free(types);
}

static void pdb_dump_fpo(struct pdb_reader* reader, unsigned stream_idx)
{
    FPO_DATA*           fpo;
    unsigned            i, size;
    const char*         frame_type[4] = {"Fpo", "Trap", "Tss", "NonFpo"};

    if (stream_idx == (WORD)-1) return;
    fpo = reader->read_file(reader, stream_idx);
    size = pdb_get_file_size(reader, stream_idx);
    if (fpo && (size % sizeof(*fpo)) == 0)
    {
        size /= sizeof(*fpo);
        printf("FPO data:\n\t   Start   Length #loc #pmt #prolog #reg frame  SEH /BP\n");
        for (i = 0; i < size; i++)
        {
            printf("\t%08x %08x %4d %4d %7d %4d %6s  %c   %c\n",
                   fpo[i].ulOffStart, fpo[i].cbProcSize, fpo[i].cdwLocals, fpo[i].cdwParams,
                   fpo[i].cbProlog, fpo[i].cbRegs, frame_type[fpo[i].cbFrame],
                   fpo[i].fHasSEH ? 'Y' : 'N', fpo[i].fUseBP ? 'Y' : 'N');
        }
    }
    free(fpo);
}

static void pdb_dump_fpo_ext(struct pdb_reader* reader, unsigned stream_idx)
{
    PDB_FPO_DATA*       fpoext;
    unsigned            i, size, strsize;
    char*               strbase;

    if (stream_idx == (WORD)-1) return;
    strbase = read_string_table(reader);
    if (!strbase) return;

    strsize = *(const DWORD*)(strbase + 8);
    fpoext = reader->read_file(reader, stream_idx);
    size = pdb_get_file_size(reader, stream_idx);
    if (fpoext && (size % sizeof(*fpoext)) == 0)
    {
        size /= sizeof(*fpoext);
        printf("FPO data (extended):\n"
               "\t   Start   Length   Locals   Params MaxStack Prolog #SavedRegs    Flags Command\n");
        for (i = 0; i < size; i++)
        {
            printf("\t%08x %08x %8x %8x %8x %6x   %8x %08x %s\n",
                   fpoext[i].start, fpoext[i].func_size, fpoext[i].locals_size, fpoext[i].params_size,
                   fpoext[i].maxstack_size, fpoext[i].prolog_size, fpoext[i].savedregs_size, fpoext[i].flags,
                   fpoext[i].str_offset < strsize ? strbase + 12 + fpoext[i].str_offset : "<out of bounds>");
        }
    }
    free(fpoext);
    free(strbase);
}

static void pdb_dump_segments(struct pdb_reader* reader, unsigned stream_idx)
{
    const char* segs;
    DWORD       size;
    const char* ptr;

    if (stream_idx == (WORD)-1) return;
    segs = reader->read_file(reader, stream_idx);

    if (segs)
    {
        size = pdb_get_file_size(reader, stream_idx);
        for (ptr = segs; ptr < segs + size; )
        {
            printf("Segment %s\n", ptr);
            ptr += (strlen(ptr) + 1 + 3) & ~3;
            printf("\tdword[0]: %08x\n", *(DWORD*)ptr); ptr += 4;
            printf("\tdword[1]: %08x\n", *(DWORD*)ptr); ptr += 4;
            printf("\tdword[2]: %08x\n", *(DWORD*)ptr); ptr += 4;
            printf("\tdword[3]: %08x\n", *(DWORD*)ptr); ptr += 4;
            printf("\tdword[4]: %08x\n", *(DWORD*)ptr); ptr += 4;
            printf("\tdword[5]: %08x\n", *(DWORD*)ptr); ptr += 4;
            printf("\tdword[6]: %08x\n", *(DWORD*)ptr); ptr += 4;
            printf("\tdword[7]: %08x\n", *(DWORD*)ptr); ptr += 4;
        }
        free((char*)segs);
    } else printf("nosdfsdffd\n");
}

static const char       pdb2[] = "Microsoft C/C++ program database 2.00";

static void pdb_jg_dump(void)
{
    struct pdb_reader   reader;

    /*
     * Read in TOC and well-known files
     */
    pdb_jg_init(&reader);
    printf("Header (JG):\n"
           "\tident:      %.*s\n"
           "\tsignature:  %08x\n"
           "\tblock_size: %08x\n"
           "\tfree_list:  %04x\n"
           "\ttotal_alloc:%04x\n",
           (int)sizeof(pdb2) - 1, reader.u.jg.header->ident,
           reader.u.jg.header->signature,
           reader.u.jg.header->block_size,
           reader.u.jg.header->free_list,
           reader.u.jg.header->total_alloc);

    reader.u.jg.root = reader.read_file(&reader, 1);
    if (reader.u.jg.root)
    {
        DWORD*          pdw;
        DWORD*          ok_bits;
        DWORD           numok, count;
        unsigned        i;
        PDB_STREAM_INDEXES sidx;

        printf("Root:\n"
               "\tVersion:       %u\n"
               "\tTimeDateStamp: %08x\n"
               "\tAge:           %08x\n"
               "\tnames:         %d\n",
               reader.u.jg.root->Version,
               reader.u.jg.root->TimeDateStamp,
               reader.u.jg.root->Age,
               (unsigned)reader.u.jg.root->cbNames);

        pdw = (DWORD*)(&reader.u.jg.root->names[0] + reader.u.jg.root->cbNames);
        numok = *pdw++;
        count = *pdw++;
        printf("\tStreams directory:\n"
               "\t\tok:        %08x\n"
               "\t\tcount:     %08x\n"
               "\t\ttable:\n",
               numok, count);

        /* bitfield: first dword is len (in dword), then data */
        ok_bits = pdw;
        pdw += *ok_bits++ + 1;
        if (*pdw++ != 0)
        {
            printf("unexpected value\n");
            return;
        }

        for (i = 0; i < count; i++)
        {
            if (ok_bits[i / 32] & (1 << (i % 32)))
            {
                DWORD string_idx, stream_idx;
                string_idx = *pdw++;
                stream_idx = *pdw++;
                printf("\t\t\t%2d) %-20s => %x\n", i, &reader.u.jg.root->names[string_idx], stream_idx);
                numok--;
            }
        }
        if (numok) printf(">>> unmatched present field with found\n");

        /* Check for unknown versions */
        switch (reader.u.jg.root->Version)
        {
        case 19950623:      /* VC 4.0 */
        case 19950814:
        case 19960307:      /* VC 5.0 */
        case 19970604:      /* VC 6.0 */
            break;
        default:
            printf("-Unknown root block version %d\n", reader.u.jg.root->Version);
        }
        pdb_dump_types(&reader);
        pdb_dump_symbols(&reader, &sidx);
        pdb_dump_fpo(&reader, sidx.FPO);
        pdb_dump_segments(&reader, sidx.segments);
    }
    else printf("-Unable to get root\n");

    pdb_exit(&reader);
}

static void* pdb_ds_read(const struct PDB_DS_HEADER* header, const DWORD* block_list, int size)
{
    int                 i, nBlocks;
    BYTE*               buffer;

    if (!size) return NULL;

    nBlocks = (size + header->block_size - 1) / header->block_size;
    buffer = malloc(nBlocks * header->block_size);

    for (i = 0; i < nBlocks; i++)
        memcpy(buffer + i * header->block_size,
               (const char*)header + block_list[i] * header->block_size, header->block_size);

    return buffer;
}

static void* pdb_ds_read_file(struct pdb_reader* reader, DWORD file_number)
{
    const DWORD*        block_list;
    DWORD               i;

    if (!reader->u.ds.toc || file_number >= reader->u.ds.toc->num_files) return NULL;

    reader->file_used[file_number / 32] |= 1 << (file_number % 32);
    if (reader->u.ds.toc->file_size[file_number] == 0 ||
        reader->u.ds.toc->file_size[file_number] == 0xFFFFFFFF)
        return NULL;
    block_list = reader->u.ds.toc->file_size + reader->u.ds.toc->num_files;
    for (i = 0; i < file_number; i++)
        block_list += (reader->u.ds.toc->file_size[i] + reader->u.ds.header->block_size - 1) /
            reader->u.ds.header->block_size;

    return pdb_ds_read(reader->u.ds.header, block_list, reader->u.ds.toc->file_size[file_number]);
}

static BOOL pdb_ds_init(struct pdb_reader* reader)
{
    reader->u.ds.header = PRD(0, sizeof(*reader->u.ds.header));
    if (!reader->u.ds.header) return FALSE;
    reader->read_file = pdb_ds_read_file;
    reader->u.ds.toc = pdb_ds_read(reader->u.ds.header, 
                                   (const DWORD*)((const char*)reader->u.ds.header + reader->u.ds.header->toc_page * reader->u.ds.header->block_size),
                                   reader->u.ds.header->toc_size);
    memset(reader->file_used, 0, sizeof(reader->file_used));
    return TRUE;
}

static const char       pdb7[] = "Microsoft C/C++ MSF 7.00";

static void pdb_ds_dump(void)
{
    struct pdb_reader   reader;

    pdb_ds_init(&reader);
    printf("Header (DS)\n"
           "\tsignature:        %.*s\n"
           "\tblock_size:       %08x\n"
           "\tunknown1:         %08x\n"
           "\tnum_pages:        %08x\n"
           "\ttoc_size:         %08x\n"
           "\tunknown2:         %08x\n"
           "\ttoc_page:         %08x\n",
           (int)sizeof(pdb7) - 1, reader.u.ds.header->signature,
           reader.u.ds.header->block_size,
           reader.u.ds.header->unknown1,
           reader.u.ds.header->num_pages,
           reader.u.ds.header->toc_size,
           reader.u.ds.header->unknown2,
           reader.u.ds.header->toc_page);

    /* files:
     *  0: JG says old toc pages, I'd say free pages (tbc, low prio)
     *  1: root structure
     *  2: types
     *  3: modules
     * other known streams:
     * - string table: it's index is in the stream table from ROOT object under "/names"
     * those streams get their indexes out of the PDB_STREAM_INDEXES object
     * - FPO data
     * - segments
     * - extended FPO data
     */
    reader.u.ds.root = reader.read_file(&reader, 1);
    if (reader.u.ds.root)
    {
        DWORD*          pdw;
        DWORD*          ok_bits;
        DWORD           numok, count;
        unsigned        i;
        PDB_STREAM_INDEXES sidx;

        printf("Root:\n"
               "\tVersion:              %u\n"
               "\tTimeDateStamp:        %08x\n"
               "\tAge:                  %08x\n"
               "\tguid                  %s\n"
               "\tcbNames:              %08x\n",
               reader.u.ds.root->Version,
               reader.u.ds.root->TimeDateStamp,
               reader.u.ds.root->Age,
               get_guid_str(&reader.u.ds.root->guid),
               reader.u.ds.root->cbNames);
        pdw = (DWORD*)(&reader.u.ds.root->names[0] + reader.u.ds.root->cbNames);
        numok = *pdw++;
        count = *pdw++;
        printf("\tStreams directory:\n"
               "\t\tok:        %08x\n"
               "\t\tcount:     %08x\n"
               "\t\ttable:\n",
               numok, count);

        /* bitfield: first dword is len (in dword), then data */
        ok_bits = pdw;
        pdw += *ok_bits++ + 1;
        if (*pdw++ != 0)
        {
            printf("unexpected value\n");
            return;
        }

        for (i = 0; i < count; i++)
        {
            if (ok_bits[i / 32] & (1 << (i % 32)))
            {
                DWORD string_idx, stream_idx;
                string_idx = *pdw++;
                stream_idx = *pdw++;
                printf("\t\t\t%2d) %-20s => %x\n", i, &reader.u.ds.root->names[string_idx], stream_idx);
                numok--;
            }
        }
        if (numok) printf(">>> unmatched present field with found\n");

        pdb_dump_types(&reader);
        pdb_dump_symbols(&reader, &sidx);
        pdb_dump_fpo(&reader, sidx.FPO);
        pdb_dump_fpo_ext(&reader, sidx.FPO_EXT);
        pdb_dump_segments(&reader, sidx.segments);
    }
    else printf("-Unable to get root\n");

    pdb_exit(&reader);
}

enum FileSig get_kind_pdb(void)
{
    const char* head;

    head = PRD(0, sizeof(pdb2) - 1);
    if (head && !memcmp(head, pdb2, sizeof(pdb2) - 1))
        return SIG_PDB;
    head = PRD(0, sizeof(pdb7) - 1);
    if (head && !memcmp(head, pdb7, sizeof(pdb7) - 1))
        return SIG_PDB;
    return SIG_UNKNOWN;
}

void pdb_dump(void)
{
    const char* head;

/*    init_types(); */
    head = PRD(0, sizeof(pdb2) - 1);
    if (head && !memcmp(head, pdb2, sizeof(pdb2) - 1))
    {
        pdb_jg_dump();
        return;
    }
    head = PRD(0, sizeof(pdb7) - 1);
    if (head && !memcmp(head, pdb7, sizeof(pdb7) - 1))
    {
        pdb_ds_dump();
        return;
    }
    printf("Unrecognized header %s\n", head);
}
