1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 11:38:21 +02:00
Beef/IDEHelper/COFF.h
Brian Fiete b63a243fd7 Working on installer, fixing more Win32 issues
Throwing error on member references with ".." cascade token outside invocations (ie: "ts..mA = 123")
Fixed 'Thread.ModuleTLSIndex' error - which caused us TLS lookup failures in Beef DLLs
Fixed some hotswap errors
Made BeefPerf shut down properly
Fixed an 'int literal' FixIntUnknown issue where rhs was System.Object which caused an illegal boxing
Fixed COFF::LocateSymbol issues with Win32 and also with linking to static libraries - showed up with hot-linking in fmod when hot-adding a floating point mod
Fixed a couple memory leaks
Fixed alignment issue in COFF::ParseCompileUnit
2019-09-02 17:39:47 -07:00

413 lines
10 KiB
C++

#pragma once
#include "DbgModule.h"
#include "StrBloomMap.h"
#include "DbgSymSrv.h"
#include "Compiler/BfUtil.h"
#include "Backend/BeLibManger.h"
namespace Beefy
{
class FileStream;
class DataStream;
class MemStream;
class SafeMemStream;
}
struct CV_LVAR_ADDR_RANGE;
struct CV_LVAR_ADDR_GAP;
NS_BF_DBG_BEGIN
struct CvSectionContrib
{
int16 mSection;
int16 mPad1;
int32 mOffset;
int32 mSize;
uint32 mFlags;
int16 mModule;
int16 mPad2;
uint32 mDataCrc;
uint32 mRelocCrc;
};
struct CvModuleInfoBase
{
uint32 mOpened;
CvSectionContrib mSectionContrib;
uint16 mFlags;
int16 mStream;
int32 mSymbolBytes;
int32 mOldLinesBytes;
int32 mLinesBytes;
int16 mNumFiles;
uint16 mPadding;
uint32 mOffsets;
int32 mSourceFileCount;
int32 mCompilerNameCount;
};
class CvCompileUnit;
struct CvCrossScopeImport
{
const char* mScopeName;
CvCompileUnit* mScopeCompileUnit;
Array<uint32> mImports;
};
struct CvCrossScopeExportEntry
{
uint32 mLocalId;
uint32 mGlobalId;
};
class CvCompileUnit : public DbgCompileUnit
{
public:
Array<CvCrossScopeExportEntry> mExports;
Array<CvCrossScopeImport> mImports;
Dictionary<uint32, uint32> mExportMap;
int mModuleIdx;
CvCompileUnit(DbgModule* dbgModule) : DbgCompileUnit(dbgModule)
{
}
};
struct CvModuleInfo : public CvModuleInfoBase
{
const char* mModuleName;
const char* mObjectName;
CvCompileUnit* mCompileUnit;
int mIdx;
bool mHasMappedMethods;
};
struct CvStringTable
{
int mStream;
int mStreamOffset;
const char* mStrTable;
CvStringTable()
{
mStream = -1;
mStreamOffset = 0;
mStrTable = NULL;
}
};
enum CvSymStreamType
{
CvSymStreamType_Globals_Scan,
CvSymStreamType_Globals_Targeted,
CvSymStreamType_Symbols
};
struct CvModuleRef
{
CvModuleRef* mNext;
int mModule;
};
struct CvInlineInfo
{
CvInlineInfo* mNext;
CvInlineInfo* mTail;
DbgSubprogram* mSubprogram;
uint8* mData;
int mDataLen;
int mInlinee;
bool mDebugDump;
};
typedef Array<CvInlineInfo> CvInlineInfoVec;
class CvModuleInfoNameEntry
{
public:
CvModuleInfo* mModuleInfo;
bool operator==(const CvModuleInfoNameEntry& other) const
{
return mModuleInfo == other.mModuleInfo;
}
static size_t GetHashCode(const char* str, int len)
{
int curHash = 0;
const char* strP = str;
for (int i = 0; i < len; i++)
{
char c = *(strP++);
if (c == 0)
break;
c = tolower(c);
curHash = ((curHash ^ c) << 5) - curHash;
}
return curHash;
}
static size_t GetHashCode(const StringImpl& str)
{
for (int i = str.mLength - 1; i >= 0; i--)
{
char c = str[i];
if ((c == '\\') || (c == '/'))
{
return GetHashCode((const char*)&str[i], str.mLength - i);
}
}
if (str.mLength == 0)
return 0;
return GetHashCode((const char*)&str[0], str.mLength);
}
};
class COFF;
class CvStreamReader
{
public:
COFF* mCOFF;
int mPageBits;
Array<uint8*> mStreamPtrs;
Array<uint8> mTempData;
int mSize;
public:
CvStreamReader()
{
mCOFF = NULL;
mPageBits = 0;
mSize = 0;
}
bool IsSetup()
{
return mCOFF != NULL;
}
uint8* GetTempPtr(int offset, int size, bool mayRecurse = false, bool* madeCopy = NULL);
uint8* GetPermanentPtr(int offset, int size, bool* madeCopy = NULL);
//char* GetPermanentCharPtr(int offset, int size);
};
class CvLibInfo
{
public:
BeLibFile mLibFile;
Dictionary<String, BeLibEntry*> mSymDict;
};
class COFF : public DbgModule
{
public:
enum ParseKind
{
ParseKind_Header,
ParseKind_Info,
ParseKind_Full
};
public:
uint8 mPDBGuid[16];
int mFileAge;
int mDebugAge;
ParseKind mParseKind;
bool mPDBLoaded;
int mCvPageSize;
int mCvPageBits;
int mCvMinTag;
int mCvMaxTag;
int mCvIPIMinTag;
int mCvIPIMaxTag;
//Array<void*> mCvTagData; // a DbgType* for type info, or a ptr to the data stream for child info
Array<DbgType*> mCvTypeMap;
Array<int> mCvTagStartMap;
Array<int> mCvIPITagStartMap;
Array<Array<uint8>> mTempBufs;
int mTempBufIdx;
Array<DbgType*> mCvSystemTypes;
Array<int32> mCvStreamSizes;
Array<int32> mCvStreamPtrStartIdxs;
Array<int32> mCvStreamPtrs;
CvStreamReader mCvTypeSectionReader;
CvStreamReader mCvIPIReader;
CvStreamReader mCvSymbolRecordReader;
String mPDBPath;
SafeMemStream* mCvDataStream;
CvStringTable mStringTable;
uint8* mCvHeaderData;
//uint8* mCvTypeSectionData
uint8* mCvStrTableData;
uint8* mCvPublicSymbolData;
uint8* mCvGlobalSymbolData;
uint8* mNewFPOData;
int mCvGlobalSymbolInfoStream;
int mCvPublicSymbolInfoStream;
int mCvSymbolRecordStream;
int mCvSrcSrvStream;
int mCvNewFPOStream;
Array<CvModuleInfo*> mCvModuleInfo;
Dictionary<int, DbgSrcFile*> mCVSrcFileRefCache;
Dictionary<CaseInsensitiveString, CvModuleInfo*> mModuleNameMap;
HashSet<CvModuleInfoNameEntry> mModuleNameSet;
Dictionary<String, CvLibInfo*> mHotLibMap;
Dictionary<String, BeLibEntry*> mHotLibSymMap;
addr_target mHotThunkCurAddr;
int mHotThunkDataLeft;
DbgType* mGlobalsTargetType;
const char* mPrevScanName;
// For hot data
Array<DbgSectionData> mCvTypeSectionData;
Array<DbgSectionData> mCvCompileUnitData;
//int mCvTypeSectionDataSize;
//uint8* mCvCompileUnitData;
//int mCvCompileUnitDataSize;
HANDLE mCvMappedFile;
void* mCvMappedViewOfFile;
size_t mCvMappedFileSize;
HANDLE mCvMappedFileMapping;
bool mIsFastLink;
bool mTriedSymSrv;
DbgSymRequest* mDbgSymRequest;
bool mWantsAutoLoadDebugInfo;
int mProcSymCount;
public:
virtual void ParseGlobalsData() override;
virtual void ParseSymbolData() override;
virtual void ParseTypeData(CvStreamReader& reader, int dataOffset);
void ParseTypeData(int sectionNum, CvStreamReader& reader, int& sectionSize, int& dataOfs, int& hashStream, int& hashAdjOffset, int& hashAdjSize, int& minVal, int& maxVal);
virtual void ParseTypeData() override;
void ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionData, uint8* data, uint8* dataEnd, CvInlineInfoVec& inlineDataVec, bool deferInternals, DbgSubprogram* useSubprogram);
CvCompileUnit* ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* compileUnit, uint8* sectionData, int sectionSize);
virtual CvCompileUnit* ParseCompileUnit(int compileUnitId) override;
virtual void MapCompileUnitMethods(DbgCompileUnit* compileUnit) override;
virtual void MapCompileUnitMethods(int compileUnitId) override;
virtual void PopulateType(DbgType* dbgType) override;
virtual void PopulateTypeGlobals(DbgType* dbgType) override;
virtual void PopulateSubprogram(DbgSubprogram* dbgSubprogram) override;
int MapImport(CvCompileUnit* compileUnit, int Id);
void FixupInlinee(DbgSubprogram* dbgSubprogram, uint32 ipiTag);
virtual void FixupInlinee(DbgSubprogram* dbgSubprogram) override;
virtual void PopulateStaticVariableMap() override;
virtual void ProcessDebugInfo() override;
virtual void FinishHotSwap() override;
virtual addr_target EvaluateLocation(DbgSubprogram* dwSubprogram, const uint8* locData, int locDataLen, WdStackFrame* stackFrame, DbgAddrType* outAddrType, bool allowReg) override;
virtual bool CanGetOldSource() override;
virtual String GetOldSourceCommand(const StringImpl& path) override;
virtual bool HasPendingDebugInfo() override;
virtual void PreCacheImage() override;
virtual void PreCacheDebugInfo() override;
virtual bool RequestImage() override;
virtual bool RequestDebugInfo(bool allowRemote) override;
virtual bool WantsAutoLoadDebugInfo() override;
virtual bool DbgIsStrMutable(const char* str) override;
virtual addr_target LocateSymbol(const StringImpl& name) override;
virtual void ParseFrameDescriptors() override;
void FixConstant(DbgVariable* variable);
void MapRanges(DbgVariable* variable, CV_LVAR_ADDR_RANGE* range, CV_LVAR_ADDR_GAP* gaps);
void MakeThis(DbgSubprogram* curSubprogram, DbgVariable*& curParam);
const char* CvCheckTargetMatch(const char* name, bool& wasBeef);
int CvGetStringHash(const char* str);
void CvFixupName(char* name);
DbgType* CvGetTypeOrNamespace(char* name, DbgLanguage language = DbgLanguage_Unknown);
void ParseSymbolStream(CvSymStreamType symStreamType);
void ScanCompileUnit(int compileUnitId);
void ParseFrameDescriptors(uint8* data, int size, addr_target baseAddr);
const char* CvParseSymbol(int offset, CvSymStreamType symStreamType, addr_target& outAddr);
uint8* HandleSymStreamEntries(CvSymStreamType symStreamType, uint8* data, uint8* addrMap);
const char* CvParseString(uint8*& data);
const char* CvParseAndDupString(uint8*& data);
void CvReadStream(int sectionIdx, CvStreamReader& streamReader);
void CvInitStreamRaw(CvStreamReader& streamReader, uint8* data, int size);
uint8* CvReadStream(int sectionIdx, int* outSize = NULL);
uint8* CvReadStreamSegment(int sectionIdx, int offset, int size);
void ReleaseTempBuf(uint8* buf);
void InitCvTypes();
DbgType* CvCreateType();
int CvConvRegNum(int regNum, int* outBits = NULL);
addr_target GetSectionAddr(uint16 section, uint32 offset);
int64 CvParseConstant(uint16 constVal, uint8*& data);
int64 CvParseConstant(uint8*& data);
DbgType* CvGetType(int typeId);
DbgType* CvGetType(int typeId, CvCompileUnit* compileUnit);
int CvGetTagStart(int tagIdx, bool ipi);
uint8* CvGetTagData(int tagIdx, bool ipi, int* outDataSize = NULL);
void CvParseArgList(DbgSubprogram* subprogram, int tagIdx, bool ipi);
DbgSubprogram* CvParseMethod(DbgType* parentType, const char* methodName, int tagIdx, bool ipi, DbgSubprogram* subprogram = NULL);
void CvParseMethodList(DbgType* parentType, const char* methodName, int tagIdx, bool ipi);
void CvParseMembers(DbgType* parentType, int tagIdx, bool ipi);
DbgType* CvParseType(int tagIdx, bool ipi = false);
bool CvParseDBI(int wantAge);
void ParseSectionHeader(int sectionIdx);
void CvParseIPI();
bool CvParseHeader(uint8 wantGuid[16], int32 wantAge);
void FixTypes(int startingIdx);
bool ParseCv(DataStream& CvFS, uint8* rootDirData, int pageSize, uint8 wantGuid[16], int32 wantAge);
bool TryLoadPDB(const String& CvPath, uint8 wantGuid[16], int32 wantAge);
void ClosePDB();
virtual void ReportMemory(MemReporter* memReporter) override;
public:
COFF(DebugTarget* debugTarget);
~COFF();
virtual bool LoadPDB(const String& CvPath, uint8 wantGuid[16], int32 wantAge) override;
virtual bool CheckSection(const char* name, uint8* sectionData,
int sectionSize) override;
};
class CvAutoReleaseTempData
{
public:
COFF * mCOFF;
uint8* mData;
public:
CvAutoReleaseTempData(COFF* coff, uint8* data)
{
mCOFF = coff;
mData = data;
}
~CvAutoReleaseTempData()
{
mCOFF->ReleaseTempBuf(mData);
}
};
NS_BF_DBG_END
namespace std
{
template<>
struct hash<NS_BF_DBG::CvModuleInfoNameEntry>
{
size_t operator()(const NS_BF_DBG::CvModuleInfoNameEntry& val) const
{
return NS_BF_DBG::CvModuleInfoNameEntry::GetHashCode(val.mModuleInfo->mModuleName);
}
};
}