Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1089 lines
23 KiB

/***********************************************************************
* Microsoft (R) 32-Bit Incremental Linker
*
* Copyright (C) Microsoft Corp 1992-95. All rights reserved.
*
* File: dbinsp.cpp
*
* File Comments:
*
* Inspects & dumps incremental database files.
*
***********************************************************************/
#include "link.h"
#if DBG
// macros
#define FileWarning(file, str) printf("%s : %s\n", file, str)
// statics
static PIMAGE pimage;
static void *pvIncr;
static INT FileHandle;
static DWORD FileLen;
static char *SzDbFile;
static BOOL fSymbols;
static BOOL fHashTable;
static BOOL fSectionMap;
static BOOL fLibMap;
static BOOL fHeaders;
// function prototypes
extern void IncrInitImage(PPIMAGE);
void ProcessDbInspSwitches(void);
void DbInsp(PARGUMENT_LIST);
BOOL FVerifyAndDumpHeader(const char *);
BOOL FReadInFile(void);
void DumpIncrDb(const char *);
BOOL DumpIncrImageHeaders(PIMAGE, const char *);
void DumpIncrImgFileHdr(PIMAGE_FILE_HEADER);
void DumpIncrImgOptHdr(PIMAGE_OPTIONAL_HEADER);
void DumpIncrPGRP(PGRP);
void DumpIncrPSEC(PSEC);
void DumpIncrPLIB(PLIB);
void DumpIncrPMOD(PMOD);
void DumpIncrPCON(PCON);
void DumpIncrSectionMap(PSECS, const char *);
void DumpIncrLibMap(PLIB, const char *);
void DumpIncrHashTable(PHT, void *);
void DumpIncrSymbolTable(PST);
// functions
void
DbInspUsage(void)
{
if (fNeedBanner) {
PrintBanner();
}
puts("usage: DBINSP [options] [files]\n\n"
" options:\n\n"
" /ALL\n"
" /HASH\n"
" /HEADERS\n"
" /LIBMAP\n"
" /NOLOGO\n"
" /OUT:filename\n"
" /SECMAP\n"
" /SYMBOLS");
fflush(stdout);
exit(USAGE);
}
MainFunc DbInspMain(int Argc, char *Argv[])
/*++
Routine Description:
Dumps an incremental database in human readable form.
Arguments:
Argc - Standard C argument count.
Argv - Standard C argument strings.
Return Value:
0 Dump was successful.
!0 Dumper error index.
--*/
{
WORD i;
PARGUMENT_LIST parg;
if (Argc < 2) {
DbInspUsage();
}
ParseCommandLine(Argc, Argv, NULL);
ProcessDbInspSwitches();
if (fNeedBanner) {
PrintBanner();
}
for(i = 0, parg = ObjectFilenameArguments.First;
i < ObjectFilenameArguments.Count;
i++, parg = parg->Next) {
DbInsp(parg);
}
FileCloseAll();
fclose(InfoStream);
return (0);
}
void
ProcessDbInspSwitches (
void
)
/*++
Routine Description:
Process incr db inspector switches.
Arguments:
None.
Return Value:
None.
--*/
{
PARGUMENT_LIST parg;
WORD i;
for (i=0,parg=SwitchArguments.First;
i<SwitchArguments.Count;
parg=parg->Next, i++) {
if (!strcmp(parg->OriginalName, "?")) {
DbInspUsage();
assert(FALSE); // doesn't return
}
if (!_strnicmp(parg->OriginalName, "out:", 4)) {
if (*(parg->OriginalName+4)) {
szInfoFilename = parg->OriginalName+4;
if (!(InfoStream = fopen(szInfoFilename, "wt"))) {
Fatal(NULL, CANTOPENFILE, szInfoFilename);
}
}
continue;
}
if (!_stricmp(parg->OriginalName, "nologo")) {
fNeedBanner = FALSE;
continue;
}
if (!_stricmp(parg->OriginalName, "symbols")) {
fSymbols = TRUE;
continue;
}
if (!_stricmp(parg->OriginalName, "all")) {
fSymbols = TRUE;
fHashTable = TRUE;
fSectionMap = TRUE;
fLibMap = TRUE;
fHeaders = TRUE;
continue;
}
if (!_stricmp(parg->OriginalName, "hash")) {
fHashTable = TRUE;
continue;
}
if (!_stricmp(parg->OriginalName, "secmap")) {
fSectionMap = TRUE;
continue;
}
if (!_stricmp(parg->OriginalName, "libmap")) {
fLibMap = TRUE;
continue;
}
if (!_stricmp(parg->OriginalName, "headers")) {
fHeaders = TRUE;
continue;
}
Warning(NULL, WARN_UNKNOWN_SWITCH, parg->OriginalName);
} // end for
}
void
DbInsp (
PARGUMENT_LIST parg
)
/*++
Routine Description:
Verifies and dumps contents of incremental database.
Arguments:
parg - ptr to argument.
Return Value:
None.
--*/
{
fprintf(InfoStream, "\nInspecting file %s\n", parg->OriginalName);
// Set the incr db filename
szIncrDbFilename = parg->OriginalName;
// Peek at the header
if (!FVerifyAndDumpHeader(parg->OriginalName)) {
return;
}
// Read in the entire file
if (!FReadInFile()) {
return;
}
// verify symbol table (ptrs are valid only after reading it in the entire image)
if (!FValidPtrInfo((DWORD) pvIncr, (DWORD) FileLen, (DWORD) pimage->pst->blkStringTable.pb, pimage->pst->blkStringTable.cb)) {
FileWarning(parg->OriginalName, "invalid pointer to string table");
return;
}
if (Align(sizeof(DWORD), ((DWORD) pimage->pst->blkStringTable.pb + pimage->pst->blkStringTable.cb - (DWORD) pvIncr))
!= FileLen) {
FileWarning(parg->OriginalName, "garbage beyond string table");
return;
}
// Dump the rest of the stuff
DumpIncrDb(parg->OriginalName);
// Close the incr db file
FileClose(FileIncrDbHandle, TRUE);
}
BOOL
FVerifyAndDumpHeader (
const char *szFile
)
/*++
Routine Description:
Reads in just the header and verifies it & dumps interesting info.
Arguments:
szFile - name of the incr db file.
Return Value:
None.
--*/
{
struct _stat statfile;
IMAGE image;
// stat the file
if (_stat(szFile, &statfile) == -1) {
Fatal(NULL, CANTOPENFILE, szFile);
}
FileLen = statfile.st_size;
if (FileLen < sizeof(IMAGE)) {
FileWarning(szFile, "file too small to be incr db");
return(FALSE);
}
FileHandle = FileOpen(szFile, O_RDONLY | O_BINARY, 0);
FileRead(FileHandle, &image, sizeof(IMAGE));
FileClose(FileHandle, TRUE);
// verify the incr db signature
if (strcmp(image.Sig, INCDB_SIGNATURE)) {
FileWarning(szFile, "invalid incr db signature found");
return(FALSE);
}
// verify the version numbers
if (image.MajVersNum != INCDB_MAJVERSNUM) {
FileWarning(szFile, "invalid version number found");
return(FALSE);
}
pvIncr = image.pvBase;
if (!DumpIncrImageHeaders(&image, szFile)) {
return(FALSE);
}
return(TRUE);
}
BOOL FReadInFile(void)
/*++
Routine Description:
Reads in file onto private heap.
Arguments:
szFile - name of file.
Return Value:
None.
--*/
{
DWORD dwErr = 0;
// create a private heap to load the image
if (CreateHeap(pvIncr, FileLen, FALSE, &dwErr) != pvIncr) {
puts("failed to map ILK file");
return(FALSE);
}
pimage = (PIMAGE) pvIncr;
IncrInitImage(&pimage);
return(TRUE);
}
BOOL
DumpIncrImageHeaders (
PIMAGE pimg,
const char *szFile
)
/*++
Routine Description:
Dumps out the various headers.
Arguments:
pimg - pointer to IMAGE struct
szFile - name of file for error reporting
Return Value:
TRUE if everything is valid.
--*/
{
BYTE Sig[32];
BOOL fValid = TRUE;
fprintf(InfoStream, "\nIMAGE HEADER VALUES\n");
strcpy((char *) Sig, pimg->Sig);
Sig[26]='\0';
fprintf(InfoStream, " Signature: %s", Sig);
fprintf(InfoStream, " MajVersNum: 0x%.4x\n", pimg->MajVersNum);
fprintf(InfoStream, " MinVersNum: 0x%.4x\n", pimg->MinVersNum);
fprintf(InfoStream, " Heap Base: 0x%.8lx\n",pvIncr);
fprintf(InfoStream, " secs.psecHead: 0x%.8lx\n", pimg->secs.psecHead);
fprintf(InfoStream, " libs.plibHead: 0x%.8lx\n", pimg->libs.plibHead);
fprintf(InfoStream, " libs.fNoDefaultLibs: %c\n", pimg->libs.fNoDefaultLibs ? '1':'0');
fprintf(InfoStream, " plibCmdLineObjs: 0x%.8lx\n",pimg->plibCmdLineObjs);
fprintf(InfoStream, " pst: 0x%.8lx\n",pimg->pst);
if (!FValidPtrInfo((DWORD) pvIncr, (DWORD)FileLen, (DWORD)pimg->secs.psecHead, 0)) {
FileWarning(szFile, "invalid pointer to section list");
fValid = FALSE;
}
if (!FValidPtrInfo((DWORD) pvIncr, (DWORD)FileLen, (DWORD)pimg->libs.plibHead, 0)) {
FileWarning(szFile, "invalid pointer to lib list");
fValid = FALSE;
}
if (!FValidPtrInfo((DWORD) pvIncr, (DWORD)FileLen, (DWORD)pimg->plibCmdLineObjs, 0)) {
FileWarning(szFile, "invalid pointer to cmdline objs lib");
fValid = FALSE;
}
if (!FValidPtrInfo((DWORD) pvIncr, (DWORD)FileLen, (DWORD)pimg->pst, 0)) {
FileWarning(szFile, "invalid pointer to symbol table");
fValid = FALSE;
}
DumpIncrImgFileHdr(&pimg->ImgFileHdr);
DumpIncrImgOptHdr(&pimg->ImgOptHdr);
return(fValid);
}
void
DumpIncrImgFileHdr (
PIMAGE_FILE_HEADER pImgFileHdr
)
/*++
Routine Description:
Dumps out the IMAGE_FILE_HEADER.
Arguments:
pImgFileHdr - pointer to IMAGE_FILE_HEADER struct
Return Value:
None.
--*/
{
if (!fHeaders) {
return;
}
fprintf(InfoStream, "\nIMAGE FILE HEADER VALUES\n");
fprintf(InfoStream, " Machine: 0x%.4x\n", pImgFileHdr->Machine);
fprintf(InfoStream, " NumOfSec: 0x%.4x\n", pImgFileHdr->NumberOfSections);
fprintf(InfoStream, " TimeStamp: %s", ctime((time_t *)&pImgFileHdr->TimeDateStamp));
fprintf(InfoStream, " PtrToSymTbl: 0x%.8lx\n", pImgFileHdr->PointerToSymbolTable);
fprintf(InfoStream, " NumOfSyms: 0x%.8lx\n", pImgFileHdr->NumberOfSymbols);
fprintf(InfoStream, " SizeOfOptHdr: 0x%.4x\n", pImgFileHdr->SizeOfOptionalHeader);
fprintf(InfoStream, " Character.: 0x%.4x\n", pImgFileHdr->Characteristics);
}
static const char * const SubsystemName[] = {
"Unknown",
"Native",
"Windows GUI",
"Windows CUI",
"Posix CUI",
"MMOSA",
};
static const char * const DirectoryEntryName[] = {
"Export",
"Import",
"Resource",
"Exception",
"Security",
"Base Relocation",
"Debug",
"Description",
"Special",
"Thread Storage",
NULL
};
void
DumpIncrImgOptHdr (
PIMAGE_OPTIONAL_HEADER pImgOptHdr
)
/*++
Routine Description:
Dumps out the IMAGE_OPTIONAL_HEADER. Code taken from dump.c yikes!
Arguments:
pImgFileHdr - pointer to IMAGE_OPTIONAL_HEADER struct
Return Value:
None.
--*/
{
WORD i, j;
char version[30];
if (!fHeaders) {
return;
}
fprintf(InfoStream, "\nIMAGE OPTIONAL FILE HEADER VALUES\n");
fprintf(InfoStream, "% 8hX magic #\n", pImgOptHdr->Magic);
j = (WORD) sprintf(version, "%d.%d", pImgOptHdr->MajorLinkerVersion, pImgOptHdr->MinorLinkerVersion);
if (j > 8) {
j = 8;
}
for (j = (WORD) (8-j); j; j--) {
fputc(' ', InfoStream);
}
fprintf(InfoStream, "%s linker version\n% 8lX size of code\n% 8lX size of initialized data\n% 8lX size of uninitialized data\n% 8lX address of entry point\n% 8lX base of code\n% 8lX base of data\n",
version,
pImgOptHdr->SizeOfCode,
pImgOptHdr->SizeOfInitializedData,
pImgOptHdr->SizeOfUninitializedData,
pImgOptHdr->AddressOfEntryPoint,
pImgOptHdr->BaseOfCode,
pImgOptHdr->BaseOfData);
switch (pImgOptHdr->Subsystem) {
case IMAGE_SUBSYSTEM_MMOSA : i = 5; break;
case IMAGE_SUBSYSTEM_POSIX_CUI : i = 4; break;
case IMAGE_SUBSYSTEM_WINDOWS_CUI : i = 3; break;
case IMAGE_SUBSYSTEM_WINDOWS_GUI : i = 2; break;
case IMAGE_SUBSYSTEM_NATIVE : i = 1; break;
default : i = 0;
}
fprintf(InfoStream, " ----- new -----\n% 8lX image base\n% 8lX section alignment\n% 8lX file alignment\n% 8hX subsystem (%s)\n",
pImgOptHdr->ImageBase,
pImgOptHdr->SectionAlignment,
pImgOptHdr->FileAlignment,
pImgOptHdr->Subsystem,
SubsystemName[i]);
j = (WORD) sprintf(version, "%hX.%hX", pImgOptHdr->MajorOperatingSystemVersion, pImgOptHdr->MinorOperatingSystemVersion);
if (j > 8) {
j = 8;
}
for (j = (WORD) (8-j); j; j--) {
fputc(' ', InfoStream);
}
fprintf(InfoStream, "%s operating system version\n", version);
j = (WORD) sprintf(version, "%hX.%hX", pImgOptHdr->MajorImageVersion, pImgOptHdr->MinorImageVersion);
if (j > 8) {
j = 8;
}
for (j = (WORD) (8-j); j; j--) {
fputc(' ', InfoStream);
}
fprintf(InfoStream, "%s image version\n", version);
j = (WORD) sprintf(version, "%hX.%hX", pImgOptHdr->MajorSubsystemVersion, pImgOptHdr->MinorSubsystemVersion);
if (j > 8) {
j = 8;
}
for (j = (WORD) (8-j); j; j--) {
fputc(' ', InfoStream);
}
fprintf(InfoStream, "%s subsystem version\n% 8lX size of image\n% 8lX size of headers\n% 8lX checksum\n",
version,
pImgOptHdr->SizeOfImage,
pImgOptHdr->SizeOfHeaders,
pImgOptHdr->CheckSum);
fprintf(InfoStream, "% 8lX size of stack reserve\n% 8lX size of stack commit\n% 8lX size of heap reserve\n% 8lX size of heap commit\n%",
pImgOptHdr->SizeOfStackReserve,
pImgOptHdr->SizeOfStackCommit,
pImgOptHdr->SizeOfHeapReserve,
pImgOptHdr->SizeOfHeapCommit);
for (i=0; i<IMAGE_NUMBEROF_DIRECTORY_ENTRIES; i++) {
if (!DirectoryEntryName[i]) {
break;
}
fprintf(InfoStream, "% 8lX [% 8lx] address [size] of %s Directory\n%",
pImgOptHdr->DataDirectory[i].VirtualAddress,
pImgOptHdr->DataDirectory[i].Size,
DirectoryEntryName[i]
);
}
fputc('\n', InfoStream);
}
void
DumpIncrDb (
const char *szFile
)
/*++
Routine Description:
Dumps the contents of the incr db file.
Arguments:
szFile - name of the file to dump.
Return Value:
None.
--*/
{
DumpIncrSymbolTable(pimage->pst);
DumpIncrHashTable(pimage->pst->pht, &pimage->pst->blkStringTable);
DumpIncrSectionMap(&pimage->secs, szFile);
DumpIncrLibMap(pimage->libs.plibHead, szFile);
}
void
DumpIncrSectionMap(
PSECS psecs,
const char *szFile
)
/*++
Routine Description:
Dump the image map.
Arguments:
None.
Return Value:
None.
--*/
{
ENM_SEC enm_sec;
ENM_GRP enm_grp;
ENM_DST enm_dst;
CHAR buf[128];
if (!fSectionMap) {
return;
}
fprintf(InfoStream, "\nSECTION MAP DUMP\n");
InitEnmSec(&enm_sec, psecs);
while (FNextEnmSec(&enm_sec)) {
if (!FValidPtrInfo((DWORD) pvIncr, (DWORD)FileLen, (DWORD)enm_sec.psec, sizeof(SEC))) {
sprintf(buf, "invalid ptr to SEC 0x%lx found\n",enm_sec.psec);
FileWarning(szFile, buf);
goto InvalidSectionMap;
}
DumpIncrPSEC(enm_sec.psec);
InitEnmGrp(&enm_grp, enm_sec.psec);
while (FNextEnmGrp(&enm_grp)) {
if (!FValidPtrInfo((DWORD) pvIncr, (DWORD)FileLen, (DWORD)enm_grp.pgrp, sizeof(GRP))) {
sprintf(buf, "invalid ptr to GRP 0x%lx found\n",enm_grp.pgrp);
FileWarning(szFile, buf);
goto InvalidSectionMap;
}
DumpIncrPGRP(enm_grp.pgrp);
InitEnmDst(&enm_dst, enm_grp.pgrp);
while (FNextEnmDst(&enm_dst)) {
if (!FValidPtrInfo((DWORD) pvIncr, (DWORD)FileLen, (DWORD)enm_dst.pcon, sizeof(CON))) {
sprintf(buf, "invalid ptr to CON 0x%lx found\n",enm_dst.pcon);
FileWarning(szFile, buf);
goto InvalidSectionMap;
}
DumpIncrPCON(enm_dst.pcon);
}
}
}
InvalidSectionMap:
fprintf(InfoStream, "\n");
}
void
DumpIncrLibMap(
PLIB plibHead,
const char *szFile
)
/*++
Routine Description:
Dump the driver map.
Arguments:
None.
Return Value:
None.
--*/
{
ENM_LIB enm_lib;
ENM_MOD enm_mod;
ENM_SRC enm_src;
CHAR buf[128];
if (!fLibMap) {
return;
}
fprintf(InfoStream, "\nLIBRARY MAP OF IMAGE\n");
InitEnmLib(&enm_lib, plibHead);
while (FNextEnmLib(&enm_lib)) {
if (!FValidPtrInfo((DWORD) pvIncr, (DWORD)FileLen, (DWORD)enm_lib.plib, sizeof(LIB))) {
sprintf(buf, "invalid ptr to LIB 0x%lx found\n",enm_lib.plib);
FileWarning(szFile, buf);
goto InvalidLibMap;
}
DumpIncrPLIB(enm_lib.plib);
InitEnmMod(&enm_mod, enm_lib.plib);
while (FNextEnmMod(&enm_mod)) {
if (!FValidPtrInfo((DWORD) pvIncr, (DWORD)FileLen, (DWORD)enm_mod.pmod, sizeof(MOD))) {
sprintf(buf, "invalid ptr to MOD 0x%lx found\n",enm_mod.pmod);
FileWarning(szFile, buf);
goto InvalidLibMap;
}
DumpIncrPMOD(enm_mod.pmod);
InitEnmSrc(&enm_src, enm_mod.pmod);
while (FNextEnmSrc(&enm_src)) {
if (!FValidPtrInfo((DWORD) pvIncr, (DWORD)FileLen, (DWORD)enm_src.pcon, sizeof(CON))) {
sprintf(buf, "invalid ptr to CON 0x%lx found\n",enm_src.pcon);
FileWarning(szFile, buf);
goto InvalidLibMap;
}
DumpIncrPCON(enm_src.pcon);
}
}
}
InvalidLibMap:
fprintf(InfoStream, "\n");
}
void
DumpIncrPSEC(
PSEC psec)
/*++
Routine Description:
Dump an image section.
Arguments:
psec - section to dump.
Return Value:
None.
--*/
{
assert(psec);
fprintf(InfoStream, "\n==========\n");
fprintf(InfoStream, "section=%.8s, isec=%.4x\n", psec->szName, psec->isec);
fprintf(InfoStream, "rva= %.8lX ", psec->rva);
fprintf(InfoStream, "foPad= %.8lx ", psec->foPad);
fprintf(InfoStream, "cbRawData= %.8lx ", psec->cbRawData);
fprintf(InfoStream, "foRawData= %.8lx\n", psec->foRawData);
fprintf(InfoStream, "foLinenum= %.8lx ", psec->foLinenum);
fprintf(InfoStream, "flags= %.8lx ", psec->flags);
fprintf(InfoStream, "cLinenum= %.4x\n", psec->cLinenum);
fflush(InfoStream);
}
void
DumpIncrPGRP(
PGRP pgrp)
/*++
Routine Description:
Dump an image group.
Arguments:
pgrp - group to dump.
Return Value:
None.
--*/
{
fprintf(InfoStream, "\n----------\n");
fprintf(InfoStream, "\n group=%s\n", pgrp->szName);
fflush(InfoStream);
}
void
DumpIncrPLIB(
PLIB plib)
/*++
Routine Description:
Dump a library.
Arguments:
plib - library to dump.
Return Value:
None.
--*/
{
fprintf(InfoStream, "\n==========\n");
fprintf(InfoStream, "library=%s\n", plib->szName);
fprintf(InfoStream, "foIntMemST=%.8lx ", plib->foIntMemSymTab);
fprintf(InfoStream, "csymIntMem=%.8lx ", plib->csymIntMem);
fprintf(InfoStream, "flags= %.8lx\n", plib->flags);
fprintf(InfoStream, "TimeStamp= %s", ctime((time_t *)&plib->TimeStamp));
fflush(InfoStream);
}
void
DumpIncrPMOD(
PMOD pmod)
/*++
Routine Description:
Dump a module.
Arguments:
pmod - module to dump.
Return Value:
None.
--*/
{
fprintf(InfoStream, "\n----------\n");
fprintf(InfoStream, " module=%s, ", SzOrigFilePMOD(pmod));
if (FIsLibPMOD(pmod)) {
fprintf(InfoStream, "foMember=%.8lx\n", pmod->foMember);
} else {
fprintf(InfoStream, "szNameMod=%s\n", pmod->szNameMod);
}
fprintf(InfoStream, "foSymTable=%.8lx ", pmod->foSymbolTable);
fprintf(InfoStream, "csymbols= %.8lx ", pmod->csymbols);
fprintf(InfoStream, "cbOptHdr= %.8lx\n", pmod->cbOptHdr);
fprintf(InfoStream, "flags= %.8lx ", pmod->flags);
fprintf(InfoStream, "ccon= %.8lx ", pmod->ccon);
fprintf(InfoStream, "icon= %.8lx ", pmod->icon);
fprintf(InfoStream, "TimeStamp= (%.8lx) %s", pmod->TimeStamp, ctime((time_t *)&pmod->TimeStamp));
fprintf(InfoStream, "cbFile= %.8lx ", pmod->cbFile);
fprintf(InfoStream, "HdrTime= %.8lx\n", pmod->HdrTimeStamp);
fflush(InfoStream);
}
void
DumpIncrPCON(
PCON pcon)
/*++
Routine Description:
Dump a contribution.
Arguments:
pcon - contribution to dump.
Return Value:
None.
--*/
{
fprintf(InfoStream, "\n contributor: flags=%.8lx, rva=%.8lx, module=%s\n",
pcon->flags, pcon->rva, SzObjNamePCON(pcon));
fprintf(InfoStream, "cbRawData= %.8lx ", pcon->cbRawData);
fprintf(InfoStream, "foRawDataD=%.8lx ", pcon->foRawDataDest);
fprintf(InfoStream, "chksum =%.8lx ", pcon->chksumComdat);
fprintf(InfoStream, "selComdat= %.4x\n", pcon->selComdat);
fprintf(InfoStream, "cbPad = %.4x\n", pcon->cbPad);
fflush(InfoStream);
}
void
DumpIncrHashTable(
PHT pht,
void *pvBlk)
/*++
Routine Description:
Dump a hash table.
Arguments:
pht - hast table
pvBlk - ptr to string table
Return Value:
None.
--*/
{
PELEMENT pelement;
DWORD ibucket;
assert(pht);
if (!fHashTable) {
return;
}
fprintf(InfoStream, "\nHASH TABLE DUMP\n");
for (ibucket = 0; ibucket < pht->cbuckets; ibucket++) {
assert(ibucket / pht->celementInChunk < pht->cchunkInDir);
pelement = pht->rgpchunk[ibucket / pht->celementInChunk]->
rgpelement[ibucket % pht->celementInChunk];
fprintf(InfoStream, "bucket = %u\n", ibucket);
while (pelement) {
fprintf(InfoStream, " %s\n", pht->SzFromPv(pelement->pv, pvBlk));
pelement = pelement->pelementNext;
}
}
fprintf(InfoStream, "\n");
}
void
DumpIncrSymbolTable (
PST pst
)
/*++
Routine Description:
Dump the symbol table.
Arguments:
pst - symbol table
Return Value:
None.
--*/
{
PPEXTERNAL rgpexternal;
DWORD cexternal;
DWORD i;
if (!fSymbols) {
return;
}
fprintf(InfoStream, "\nSYMBOL TABLE DUMP\n");
// put them out sorted by name
rgpexternal = RgpexternalByName(pst);
cexternal = Cexternal(pst);
for (i = 0; i < cexternal; i++) {
PEXTERNAL pext;
char *szSym;
const char *szType;
pext = rgpexternal[i];
szSym = SzOutputSymbolName(SzNamePext(pext, pst), TRUE);
if (!pext->pcon || (pext->Flags & EXTERN_IGNORE)) {
fprintf(InfoStream, "%s off=%.8lx flags=%.8lx %s name=%s\n",
pext->Offset ? "THUNK" : " ",
pext->Offset,
pext->Flags,
"IGNR",
szSym);
continue;
}
if (pext->pcon && !FIsLibPCON(pext->pcon)) {
if (ISFCN(pext->ImageSymbol.Type)) {
szType = "FUNC";
} else {
szType = "DATA";
}
} else {
szType = " ";
}
fprintf(InfoStream, "%s off=%.8lx flags=%.8lx %s name=%s\n",
pext->Offset ? "THUNK" : " ",
pext->Offset,
pext->Flags,
szType,
szSym);
if (szSym != SzNamePext(pext, pst)) {
free(szSym);
}
}
}
#endif // DBG