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.
 
 
 
 
 
 

292 lines
8.7 KiB

//////////////////////////////////////////////////////////////////////////////
// MLI: Mod linenumber information API implementation
//
// Contributed by Amit Mital of VCE, 8/3/93, subsequently C++ized and
// modified to use DBI buffers and heaps. (Actually, Jan apologizes for
// largely rewriting, but it seemed the best way to learn the code.)
#include "pdbimpl.h"
#include "dbiimpl.h"
inline int adjustLineNumber(LINE lineStart, DWORD line)
{
return (line == 0x7fff) ? lineStart : (lineStart + line);
}
BOOL MLI::AddLines(SZ_CONST szSrc, ISECT isect, OFF offCon, CB cbCon, OFF doff,
LINE lineStart, IMAGE_LINENUMBER *plnumCoff, CB cb)
// szSrc the source file name
// isect section index
// offMin starting offset
// offMax ending offset
// lineStart starting line number
// plnumCoff pointer to linenumber coff info ??
// cb byte count
{
assert(cb % sizeof(IMAGE_LINENUMBER) == 0);
int clnum = cb / sizeof(IMAGE_LINENUMBER);
pSrcFile pSrcFile = AddSrcFile(szSrc);
if (!pSrcFile)
return FALSE;
OFF offMac = offCon + cbCon;
// If this contribution does not start a function (linenumber != 0),
// offCon is passed in the first lnum entry.
if (plnumCoff[0].Linenumber)
offCon = plnumCoff[0].Type.VirtualAddress + doff;
pSectInfo pSectInfo = pSrcFile->AddSectInfo(isect, offCon, offMac, pool);
if (!pSectInfo)
return FALSE;
if (!pSectInfo->AddLineNumbers(adjustLineNumber(lineStart, plnumCoff[0].Linenumber), offCon, pool))
return FALSE;
for (IMAGE_LINENUMBER* pln = &plnumCoff[1]; pln < &plnumCoff[clnum]; pln++)
if (!pSectInfo->AddLineNumbers(adjustLineNumber(lineStart, pln->Linenumber), pln->Type.VirtualAddress + doff, pool))
return FALSE;
return TRUE;
}
// Find a pointer to the source file linked list structure - add it if it isn't there
pSrcFile MLI::AddSrcFile(SZ_CONST szFile)
{
for (pSrcFile* ppFile = &pSrcFiles; *ppFile; ppFile = &(*ppFile)->pNext)
if (strcmp((*ppFile)->szFile, szFile) == 0)
return *ppFile;
SZ szName = szCopyPool(szFile, pool);
if (!szName || !(*ppFile = new (pool) SrcFile(szName)))
return 0;
cfiles++;
return *ppFile;
}
// Find the section structure within the source file structure - add it if it is not there
pSectInfo SrcFile::AddSectInfo(ISECT isect, OFF offMin, OFF offMax, POOL& pool)
{
for (pSectInfo* ppSI = &pSectInfos; *ppSI; ppSI = &(*ppSI)->pNext) {
if ((*ppSI)->isect == isect && (*ppSI)->offMax + 1 == offMin) { // see if the new start is close enough to the old end
(*ppSI)->offMax = offMax;
return *ppSI;
}
}
if (!(*ppSI = new (pool) SectInfo(isect, offMin, offMax)))
return 0;
csect++;
return *ppSI;
}
// Add linenumber information to the record
BOOL SectInfo::AddLineNumbers(int linenumber, int offset, POOL& pool)
{
if (!(*ppTail = new (pool) Lines(offset, linenumber)))
return FALSE;
ppTail = &(*ppTail)->pNext;
cPair++;
return TRUE;
}
BOOL MLI::Emit(Buffer& buffer)
{
if (!CollectSections())
return FALSE;
// emit header information
if (!buffer.AppendFmt("ss", cfiles, csect))
return FALSE;
// emit base src file offsets
OFF off = cbAlign(2*sizeof(USHORT) + cfiles*sizeof(ULONG) + csect*(2*sizeof(ULONG) + sizeof(USHORT)));
OFF offFiles = off;
for (pSrcFile pFile = pSrcFiles; pFile; pFile = pFile->pNext) {
if (!buffer.AppendFmt("l", off))
return FALSE;
off += pFile->Size();
}
// emit section info
for (pSectInfo pSI = pSectInfos; pSI; pSI = pSI->pNext)
if (!buffer.AppendFmt("ll", pSI->offMin, pSI->offMax))
return FALSE;
for (pSI = pSectInfos; pSI; pSI = pSI->pNext)
if (!buffer.AppendFmt("s", pSI->isect))
return FALSE;
if (!buffer.AppendFmt("f", (int)dcbAlign(buffer.Size())))
return FALSE;
// emit each source file's info
off = offFiles;
for (pFile = pSrcFiles; pFile; pFile = pFile->pNext) {
if (!pFile->Emit(buffer, off))
return FALSE;
off += pFile->Size();
}
return TRUE;
}
// Given the module's per-file, per-section information, collect
// section information across files, into a flattened, per-module
// per-section information summary.
//
BOOL MLI::CollectSections()
{
pSectInfo* ppsiTail = &pSectInfos;
for (pSrcFile pFile = pSrcFiles; pFile; pFile = pFile->pNext) {
for (pSectInfo psiFile = pFile->pSectInfos; psiFile; psiFile = psiFile->pNext) {
// search the module's section infos for existing info on this section
for (pSectInfo psi = pSectInfos; psi; psi = psi->pNext)
if (psi->isect == psiFile->isect) {
// found: update extent of section
psi->offMin = __min(psi->offMin, psiFile->offMin);
psi->offMax = __max(psi->offMax, psiFile->offMax);
goto nextSIFile;
}
// not found: add new section info to module's section info
if (!(*ppsiTail = new (pool) SectInfo(psiFile->isect, psiFile->offMin, psiFile->offMax)))
return FALSE;
++csect;
ppsiTail = &(*ppsiTail)->pNext;
nextSIFile:;
}
}
return TRUE;
}
// calculate the size of the data for the file pointed to; return it's size
OFF SrcFile::Size()
{
// check memoization
if (size)
return size;
// header size
size = 2*sizeof(USHORT); // csect, pad
size += cbName + 1 + dcbAlign(cbName + 1); // cbname
// file table size
size += csect * 3*sizeof(ULONG); // baseSrcLn, start, end
// line table size
for (pSectInfo pSI = pSectInfos; pSI; pSI = pSI->pNext) {
pSI->size = sizeof(ULONG);
pSI->size += pSI->cPair * (sizeof(ULONG) + sizeof(USHORT)); // offset, line number
if (pSI->cPair & 1)
pSI->size += sizeof(USHORT); // maintain alignment
size += pSI->size;
}
return size;
}
BOOL SrcFile::Emit(Buffer& buffer, OFF off) const
{
if (!buffer.AppendFmt("ss", csect, (USHORT)0 /*pad*/))
return FALSE;
off += csect*3*sizeof(ULONG); // space for baseSrcLine offset and start/end
off += 2*sizeof(USHORT) + cbName + 1 + dcbAlign(cbName + 1);
for (pSectInfo pSI = pSectInfos; pSI; pSI = pSI->pNext) {
if (!buffer.AppendFmt("l", off))
return FALSE;
off += pSI->size;
}
for (pSI = pSectInfos; pSI; pSI = pSI->pNext)
if (!buffer.AppendFmt("ll", pSI->offMin, pSI->offMax))
return FALSE;
if (!buffer.AppendFmt("bzf", (BYTE)cbName, szFile, (int)dcbAlign(cbName + 1)))
return FALSE;
for (pSI = pSectInfos; pSI; pSI = pSI->pNext)
if (!pSI->Emit(buffer))
return FALSE;
return TRUE;
}
BOOL SectInfo::Emit(Buffer& buffer) const
{
if (!buffer.AppendFmt("ss", isect, cPair))
return FALSE;
for (pLines plines = pHead; plines; plines = plines->pNext)
if (!buffer.AppendFmt("l", plines->off))
return FALSE;
for (plines = pHead; plines; plines = plines->pNext)
if (!buffer.AppendFmt("s", plines->line))
return FALSE;
if (cPair & 1)
if (!buffer.AppendFmt("s", 0)) \
return FALSE;
return TRUE;
}
BOOL MLI::EmitFileInfo(Mod1* pmod1)
{
if (!pmod1->initFileInfo(cfiles))
return FALSE;
int ifile = 0;
for (pSrcFile pFile = pSrcFiles; pFile; pFile = pFile->pNext)
if (!pmod1->addFileInfo(ifile++, pFile->szFile))
return FALSE;
return TRUE;
}
BOOL MLI::Dump(const Buffer& buffer) const
{
PB pb = buffer.Start();
struct FSB { short cFile; short cSeg; long baseSrcFile[]; };
FSB* pfsb = (FSB*)pb;
pb += sizeof(FSB) + sizeof(long)*pfsb->cFile;
struct SE { long start, end; };
SE* pse = (SE*)pb;
pb += sizeof(SE)*pfsb->cSeg;
short* seg = (short*)pb;
pb += sizeof(short)*pfsb->cSeg;
printf("HDR: cFile=%u cSeg=%u\n", pfsb->cFile, pfsb->cSeg);
for (int ifile = 0; ifile < pfsb->cFile; ifile++)
printf("baseSrcFile[%d]=%04lx\n", ifile, pfsb->baseSrcFile[ifile]);
for (int iseg = 0; iseg < pfsb->cSeg; iseg++)
printf("%d: start=%04lx end=%04lx seg=%02x\n",
iseg, pse[iseg].start, pse[iseg].end, seg[iseg]);
for (ifile = 0; ifile < pfsb->cFile; ifile++) {
PB pb = buffer.Start() + pfsb->baseSrcFile[ifile];
struct SPB { short cSeg; short pad; long baseSrcLn[]; };
SPB* pspb = (SPB*)pb;
pb += sizeof SPB + sizeof(long)*pspb->cSeg;
SE* pse = (SE*)pb;
pb += sizeof(SE)*pspb->cSeg;
unsigned char cbName = *pb++;
unsigned char* Name = pb;
printf(" file[%d]: cSeg=%u pad=%02x cbName=%u, Name=%s\n",
ifile, pspb->cSeg, pspb->pad, cbName, Name);
for (int iseg = 0; iseg < pspb->cSeg; iseg++)
printf(" %d: baseSrcLn=%04lx start=%04lx end=%04lx\n",
iseg, pspb->baseSrcLn[iseg], pse[iseg].start, pse[iseg].end);
for (iseg = 0; iseg < pspb->cSeg; iseg++) {
PB pb = buffer.Start() + pspb->baseSrcLn[iseg];
struct SPO { short Seg; short cPair; long offset[]; };
SPO* pspo = (SPO*)pb;
pb += sizeof(SPO) + sizeof(long)*pspo->cPair;
short* linenumber = (short*)pb;
printf(" seg[%d]: Seg=%02x cPair=%u\n", iseg, pspo->Seg, pspo->cPair);
printf(" ");
for (int ipair = 0; ipair < pspo->cPair; ipair++) {
printf(" %4u:%04lx", linenumber[ipair], pspo->offset[ipair]);
if (ipair < pspo->cPair - 1 && (ipair & 3) == 3)
printf("\n ");
}
printf("\n");
}
}
fflush(stdout);
return TRUE;
}