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.
 
 
 
 
 
 

338 lines
12 KiB

//////////////////////////////////////////////////////////////////////////////
// DBI implementation declarations
// header of the DBI Stream
// section contribution structure
struct SC {
ISECT isect;
OFF off;
CB cb;
DWORD dwCharacteristics;
IMOD imod;
SC() : isect(isectNil), off(0), cb(cbNil), dwCharacteristics(0), imod(imodNil) { expect(fAlign(this)); }
inline int IsAddrInSC(ISECT isect_, OFF off_);
};
struct SC20 {
ISECT isect;
OFF off;
CB cb;
IMOD imod;
};
class EnumSC : public EnumContrib {
public:
EnumSC(const Buffer& buf) : bufSC(buf) {
reset();
}
void release() {
delete this;
}
void reset() {
i = (unsigned)-1;
}
BOOL next() {
if (++i * sizeof(SC) < (unsigned) bufSC.Size())
return TRUE;
return FALSE;
}
void get(OUT USHORT* pimod, OUT USHORT* pisect, OUT long* poff, OUT long* pcb, OUT ULONG* pdwCharacteristics) {
const SC* psc = (SC *) bufSC.Start() + i;
*pimod = ximodForImod(psc->imod);
*pisect = psc->isect;
*poff = psc->off;
*pcb = psc->cb;
*pdwCharacteristics = psc->dwCharacteristics;
}
private:
const Buffer& bufSC;
unsigned i;
};
// Support for bit vector operations
#ifndef BITSPERBYTE
#define BITSPERBYTE (8)
#endif /* BITSPERBYTE */
struct BITVEC {
public:
BITVEC() {
cbits = 0;
bv = 0;
}
~BITVEC() {
if (bv)
delete [] bv;
}
BOOL fAlloc(unsigned int _cbits) {
cbits = _cbits;
bv = (unsigned char *) new (zeroed) CHAR[(cbits + BITSPERBYTE - 1) / BITSPERBYTE];
return (bv ? TRUE : FALSE);
}
BOOL fTestBit(unsigned int index) {
assert(bv);
if (index >= cbits)
return FALSE;
else
return ((bv[index / BITSPERBYTE] >> (index % BITSPERBYTE)) & 1);
}
BOOL fSetBit(unsigned int index) {
assert(bv);
if (index >= cbits)
return FALSE;
else
bv[index / BITSPERBYTE] |= (1 << (index % BITSPERBYTE));
return TRUE;
}
private:
unsigned char *bv;
unsigned int cbits;
};
// header of the DBI Stream
struct DBIHdr {
SN snGSSyms;
SN snPSSyms;
SN snSymRecs;
CB cbGpModi; // size of rgmodi substream
CB cbSC; // size of Section Contribution substream
CB cbSecMap;
CB cbFileInfo;
DBIHdr()
{
snGSSyms = snNil;
snPSSyms = snNil;
snSymRecs = snNil;
cbGpModi = 0;
cbSC = 0;
cbSecMap = 0;
cbFileInfo = 0;
}
};
struct DBI1 : public DBI { // DBI (debug information) implemenation
public:
INTV QueryInterfaceVersion();
IMPV QueryImplementationVersion();
BOOL OpenMod(SZ_CONST szModule, SZ_CONST szObjFile, OUT Mod** ppmod);
BOOL DeleteMod(SZ_CONST szModule);
#if 0 // NYI
BOOL QueryCountMod(long *pcMod);
#endif
BOOL QueryNextMod(Mod* pmod, Mod** ppmodNext);
BOOL OpenGlobals(OUT GSI** ppgsi);
BOOL OpenPublics(OUT GSI** ppgsi);
BOOL AddSec(ISECT isect, USHORT flags, OFF off, CB cb);
BOOL AddPublic(SZ_CONST szPublic, ISECT isect, OFF off);
BOOL QueryModFromAddr(ISECT isect, OFF off, OUT Mod** ppmod,
OUT ISECT* pisect, OUT OFF* poff, OUT CB* pcb);
BOOL QuerySecMap(OUT PB pb, CB* pcb);
BOOL QueryFileInfo(OUT PB pb, CB* pcb);
void DumpMods();
void DumpSecContribs();
void DumpSecMap();
BOOL Close();
BOOL AddThunkMap(OFF* poffThunkMap, UINT nThunks, CB cbSizeOfThunk,
SO* psoSectMap, UINT nSects, ISECT isectThunkTable, OFF offThunkTable);
BOOL getEnumContrib(OUT Enum** ppenum)
{
return !!(*ppenum = new EnumSC(bufSC));
}
OFF offForSym(PSYM psym)
{
assert(psym);
assert(fWrite);
return (OFF) ((PB) psym - bufSymRecs.Start());
}
BOOL fGetTmts(lfTypeServer* pts, SZ_CONST szObjFile, TM** pptm);
BOOL fOpenTmts(lfTypeServer* pts, SZ_CONST szObjFile, TM** pptm);
BOOL fGetTmpct(lfPreComp* ppc, TMPCT** pptmpct);
BOOL fAddTmpct(lfEndPreComp* pepc, SZ_CONST szModule, TMPCT* ptmpct);
BOOL fAddTmpct(SZ_CONST szModule, SZ_CONST szInternalName, TM* ptm);
BOOL fFindTm(OTM* potm, ST stName, SIG signature, TM** pptm, BOOL fCanonName = FALSE);
static void fixSymRecs (void* pdbi, void* pOld, void* pNew);
BOOL fReadSymRecs();
BOOL fReadSymRec(PSYM);
BOOL fpsymFromOff(OFF off, PSYM *ppsym);
BOOL fAddSym(PSYM psymIn, OUT PSYM* psymOut);
BOOL addSecContrib(SC& scIn);
BOOL invalidateSCforMod(IMOD imod);
inline BOOL packProcRefToGS (PSYM psym, IMOD imod, OFF off, OFF *poff);
inline BOOL packSymToGS (PSYM psym, OFF *poff);
inline BOOL packSymToPS (PSYM psym);
#ifdef INSTRUMENTED
void DumpSymbolPages();
#endif
BOOL QueryTiForUDT(SZ sz, BOOL fCase, OUT TI* pti, OUT TM** pptm);
protected:
friend PDB1;
DBI1(PDB1* ppdb1_, BOOL fWrite_, BOOL fCreate_);
~DBI1();
BOOL fInit();
BOOL fSave();
BOOL fCheckReadWriteMode(BOOL fWrite);
BOOL openModByImod(IMOD imod, OUT Mod** ppmod);
IMOD imodForModName(SZ_CONST szModule, SZ_CONST szObjFile);
MODI* pmodiForImod(IMOD imod) { return (0 <= imod && imod < imodMac) ? rgpmodi[imod] : 0; }
void NoteModCloseForImod(IMOD imod);
BOOL initFileInfo(IMOD imod, IFILE ifileMac);
BOOL addFileInfo(IMOD imod, IFILE ifile, SZ szFile);
BOOL addFilename(ST stFile, ICH *pich);
static void fixBufGpmodi(void* pDBI1, void* pOld, void* pNew);
static void fixBufBase(void* pv, void* pvOld, void* pvNew);
private:
enum {impv = (IMPV) 930803};
PDB1* ppdb1; // PDB that opened me
OTM* potmTSHead; // list of open TMTSs
OTM* potmPCTHead; // list of open TMPCTs
IMOD imodMac; // next available IMOD
IMOD imodLast; // imod last found by QueryNextMod
Buffer bufGpmodi; // buffer backing gpmodi, the catenation of the modi
Buffer bufRgpmodi; // buffer backing rgpmodi, to map imod to pmodi
Buffer bufSC; // buffer for section contribution info
Buffer bufSecMap; // buffer for section map
Buffer bufFilenames; // buffer of modules' contributor filenames
SC* pscEnd; // end of valid SC entries
MODI** rgpmodi; // module information for imod in [0..imodMac).
GSI1* pgsiGS; // gsi of global syms
PSGSI1* pgsiPS; // gsi of public syms
VirtualBuffer bufSymRecs; // buffer for symbol recs (publics and globals)
BITVEC* pbvSymRecPgs; // bit vector that gives the pages loaded
unsigned int cSymRecPgs; // count of pages of symrecs
DBIHdr dbihdr;
USHORT fWrite : 1;
USHORT fCreate: 1;
USHORT fSCCleared: 1;
USHORT fUDTOutsideRef: 1;
USHORT unused : 12;
BOOL reloadFileInfo(PB pb);
BOOL clearDBI();
BOOL writeSymRecs();
BOOL finalizeSC(OUT CB* cbOut);
BOOL fReadSymRecPage (unsigned int iPg);
inline BOOL decRefCntGS (OFF off);
friend Mod1;
friend TM;
friend TMTS;
friend TMR;
friend TMPCT;
friend GSI1;
friend PSGSI1;
friend EnumSC;
#if defined(INSTRUMENTED)
LOG log;
struct DBIInfo {
DBIInfo() { memset(this, 0, sizeof *this); }
int cModules;
int cSymbols;
int cTypesMapped;
int cTypesMappedRecursively;
int cTypesQueried;
int cTypesAdded;
int cTMTS;
int cTMR;
int cTMPCT;
} info;
#endif
};
struct MODI {
Mod* pmod; // currently open mod
SC sc; // this module's first section contribution
USHORT fWritten : 1; // TRUE if mod has been written since DBI opened
USHORT unused : 15; // spare
SN sn; // SN of module debug info (syms, lines, fpo), or snNil
CB cbSyms; // size of local symbols debug info in stream sn
CB cbLines; // size of line number debug info in stream sn
CB cbFpo; // size of frame pointer opt debug info in stream sn
IFILE ifileMac; // number of files contributing to this module
ICH* mpifileichFile; // array [0..ifileMac) of offsets into dbi.bufFilenames
char rgch[]; // szModule followed by szObjFile
void* operator new (size_t size, Buffer& bufGpmodi, SZ_CONST szModule, SZ_CONST szObjFile);
MODI(SZ_CONST szModule, SZ_CONST szObjFile);
~MODI();
SZ szModule() { return rgch; }
SZ szObjFile() { return rgch + strlen(szModule()) + 1; }
PB pbEnd() {
SZ szObjFile_ = szObjFile();
return (PB)cbAlign((CB)szObjFile_ + strlen(szObjFile_) + 1);
}
SZ szV2Module() { return rgch - sizeof(SC) + sizeof(SC20); }
SZ szV2ObjFile() { return szV2Module() + strlen(szV2Module()) + 1; }
PB pbV2End() {
SZ szObjFile_ = szV2ObjFile();
return (PB)cbAlign((CB)szObjFile_ + strlen(szObjFile_) + 1);
}
};
inline void* MODI::operator new(size_t size, Buffer& bufGpmodi, SZ_CONST szModule, SZ_CONST szObjFile)
{
if (!szModule)
return 0;
if (!szObjFile)
szObjFile = "";
PB pb;
CB cb = cbAlign(size + strlen(szModule) + 1 + strlen(szObjFile) + 1);
return bufGpmodi.Reserve(cb, &pb) ? pb : 0;
}
inline MODI::MODI(SZ_CONST szModule_, SZ_CONST szObjFile_)
: pmod(0), fWritten(FALSE), sn(snNil), cbSyms(0), cbLines(0), cbFpo(0), ifileMac(0), mpifileichFile(0)
{
expect(fAlign(this));
strcpy(szModule(), szModule_);
strcpy(szObjFile(), szObjFile_);
}
inline MODI::~MODI()
{
if(mpifileichFile)
delete mpifileichFile;
}
// MP is used to buffer the incoming public info for a module
struct MP : public DATASYM32 {
MP(SZ_CONST szPublic, ISECT isect_, OFF off_)
{
//length byte of name field can only accomodate 255 chars
CB cbStrlen = __min(0xff, strlen(szPublic));
CB cb = cbAlign(sizeof(MP) + cbStrlen);
reclen = cb - sizeof(reclen);
rectyp = S_PUB32;
off = off_;
seg = isect_;
typind = T_NOTYPE;
name[0] = (char)cbStrlen;
memcpy(&(name[1]), szPublic, cbStrlen);
memset(&(name[1]) + cbStrlen, 0, dcbAlign(cbStrlen + 1));
}
void* operator new (size_t size, PDB1* ppdb1, SZ_CONST szPublic)
{
return new (ppdb1) BYTE[cbAlign(sizeof(MP) + strlen(szPublic))];
}
};