mirror of https://github.com/lianthony/NT4.0
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
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))];
|
|
}
|
|
};
|