#pragma once #include "../Beef/BfCommon.h" #include "BeefySysLib/FileStream.h" #include "BeefySysLib/MemStream.h" #include "BeefySysLib/util/BumpAllocator.h" #include "BeefySysLib/util/ChunkedDataBuffer.h" #include "BeefySysLib/util/Array.h" #include "BeefySysLib/util/String.h" #include "BeefySysLib/util/Hash.h" #include "BeefySysLib/util/CritSect.h" #include "BeefySysLib/util/WorkThread.h" #include "BeefySysLib/util/PerfTimer.h" #include "../Compiler/BfUtil.h" #include "BlMsf.h" #include #include #include "BlPdbParser.h" //#include "Hash.h" #include "BlCvTypeSource.h" #include "BlContext.h" #include //#define BL_USE_DENSEMAP_CV #ifdef BL_USE_DENSEMAP_CV #include #include #endif NS_BF_BEGIN struct PE_SymInfo; struct COFFRelocation; class BlContext; class BlObjectData; class BlCvTypeSource; class BlCVStream { public: String mName; Array mBlocks; int mSize; public: BlCVStream() { mSize = 0; } }; class BlCvFileInfo { public: int mStrTableIdx; int mChksumOfs; int8 mHashType; uint8 mHash[16]; }; class BlCvLine { public: int mOffset; int mLineNumStart; }; class BlCvLineInfoBlock { public: int mFileInfoIdx; std::vector mLines; std::vector mColumns; }; class BlCvLineInfo { public: int mStartSegmentIdx; int mStartSegmentOffset; int mContribBytes; std::vector mLineInfoBlocks; BlCvLineInfo() { mStartSegmentIdx = -1; mStartSegmentOffset = 0; mContribBytes = 0; } }; struct BlCvSymDataBlock { void* mData; int mSize; int mOutSize; int mSourceSectOffset; COFFRelocation* mRelocStart; COFFRelocation* mRelocEnd; FILE* mFP; int mFPOfs; }; enum BlSectInfoState : intptr { BlSectInfoState_QueuedData = -1, BlSectInfoState_QueuedDebugT = -2, BlSectInfoState_QueuedDebugS = -3 }; struct BlObjectDataSectInfo { int mSegmentIdx; int mSegmentOffset; void* mRelocData; union { void* mChunkData; BlSectInfoState mState; }; uint16 mSelectNum; int8 mSelection; bool IsUsed() { return (intptr)mChunkData >= 0; } }; struct BlObjectDataSectInfo; class BlCvModuleContrib { public: int mBlSectionIdx; int mBlSectionOfs; int mSize; int mCharacteristics; public: BlCvModuleContrib() { mBlSectionIdx = 0; mBlSectionOfs = 0; mSize = 0; mCharacteristics = 0; } }; class BlCvModuleInfo { public: int mIdx; String mName; const char* mStrTab; BlObjectData* mObjectData; int mSymStreamIdx; BlCvTypeSource* mTypeSource; PE_SymInfo* mObjSyms; BfSizedVector mSymInfo; BfSizedVector mSymData; int mLineInfoSize; //BfSizedVector mContribs; BlCvModuleContrib mContrib; std::vector mFileInfos; OwnedVector mLineInfo; BfSizedVector mInlineData; BfSizedVector mSectInfos; int mDeferredSegOfsStart; int mDeferredSegOfsLen; public: BlCvModuleInfo() { mIdx = -1; mStrTab = NULL; //mObjSyms = NULL; mObjectData = NULL; mSymStreamIdx = -1; mLineInfoSize = 0; mTypeSource = NULL; mDeferredSegOfsStart = 0; mDeferredSegOfsLen = 0; mObjSyms = NULL; } ~BlCvModuleInfo() { } }; class BlTypeInfo { public: #ifdef BL_USE_DENSEMAP_CV google::dense_hash_map mTypeMap; #else std::unordered_map mTypeMap; #endif ChunkedDataBuffer mData; int mCurTagId; public: BlTypeInfo() { mCurTagId = 0x1000; #ifdef BL_USE_DENSEMAP_CV mTypeMap.set_empty_key(Val128(-1)); mTypeMap.min_load_factor(0); mTypeMap.resize(100000); #endif } }; class BlCvRecordEntry { public: Val128 mKey; int mRecordIndex; BlCvRecordEntry* mNext; }; class BlCvRecordMap { public: #ifdef BL_USE_DENSEMAP_CV google::dense_hash_set mKeySet; #else std::unordered_set mKeySet; #endif BlCodeView* mCodeView; BlCvRecordEntry* mBuckets[4096]; BumpAllocator mAlloc; int mNumEntries; public: BlCvRecordMap() { mCodeView = NULL; memset(&mBuckets, 0, sizeof(mBuckets)); mNumEntries = 0; #ifdef BL_USE_DENSEMAP_CV mKeySet.set_empty_key(Val128(-1)); mKeySet.min_load_factor(0); mKeySet.resize(100000); #endif } void Insert(const char* name, int symIdx); int TryInsert(const char* name, const Val128& key); }; class BlCvContrib { public: int mModuleIdx; int mBlSectionOfs; int mSize; int mCharacteristics; }; class BlCvContributionSeg { public: std::vector mContribs; }; class BlCvContributionMap { public: OwnedVector mSegments; }; class BlCvTypeWorkThread : public WorkThread { public: std::deque mTypeSourceWorkQueue; BlCodeView* mCodeView; CritSect mCritSect; SyncEvent mWorkEvent; volatile bool mTypesDone; volatile bool mThreadDone; public: BlCvTypeWorkThread(); ~BlCvTypeWorkThread(); virtual void Stop() override; virtual void Run() override; void Add(BlCvTypeSource* typeSource); }; class BlCvModuleWorkThread : public WorkThread { public: std::deque mModuleWorkQueue; BlCodeView* mCodeView; CritSect mCritSect; SyncEvent mWorkEvent; volatile bool mModulesDone; public: BlCvModuleWorkThread(); ~BlCvModuleWorkThread(); virtual void Stop() override; virtual void Run() override; void Add(BlCvModuleInfo* module); }; class BlCvStreamWriter { public: BlMsf* mMsf; BlCVStream* mCurStream; uint8* mCurBlockPos; uint8* mCurBlockEnd; public: BlCvStreamWriter(); void Start(BlCVStream* stream); void Continue(BlCVStream* stream); void End(bool flush = true); void Write(const void* data, int size); template void WriteT(const T& val) { Write(&val, sizeof(T)); } void Write(ChunkedDataBuffer& buffer); int GetStreamPos(); void StreamAlign(int align); void* GetStreamPtr(int pos); }; class BlCvStreamReader { public: BlMsf* mMsf; int mBlockIdx; BlCVStream* mCurStream; uint8* mCurBlockPos; uint8* mCurBlockEnd; public: BlCvStreamReader(); void Open(BlCVStream* stream); void* ReadFast(void* data, int size); void Seek(int size); int GetStreamPos(); }; class BlCodeView { public: BlContext* mContext; BumpAllocator mAlloc; BlMsf mMsf; int mStat_TypeMapInserts; int mStat_ParseTagFuncs; OwnedVector mStreams; OwnedVector mModuleInfo; int mSectStartFilePos; BlTypeInfo mTPI; BlTypeInfo mIPI; int8 mSignature[16]; int mAge; DynMemStream mSectionHeaders; ChunkedVector mSymRecordDeferredPositions; int mSymRecordsStream; //ChunkedDataBuffer mSymRecords; BlCvRecordMap mGlobals; std::unordered_map mTypeServerFiles; std::unordered_map mStrTabMap; String mStrTab; BlCvContributionMap mContribMap; BlCvTypeWorkThread mTypeWorkThread; BlCvModuleWorkThread mModuleWorkThread; ChunkedVector mDeferedSegOffsets; BlCvStreamWriter mWriter; BlCvStreamWriter mSymRecordsWriter; public: void NotImpl(); void Fail(const StringImpl& err); char* StrDup(const char* str); void FixSymAddress(void* oldDataStart, void* oldDataPos, void* outDataPos, BlCvModuleInfo* module, BlCvSymDataBlock* dataBlock, COFFRelocation*& nextReloc); int StartStream(int streamIdx = -1); void StartUnnamedStream(BlCVStream& stream); void EndStream(bool flush = true); void FlushStream(BlCVStream* stream); void CvEncodeString(const StringImpl& str); int AddToStringTable(const StringImpl& str); void WriteStringTable(const StringImpl& strTable, std::unordered_map& strTabMap); void GetOutSectionAddr(int segIdx, int segOfs, uint16& cvSectIdx, long& cvSectOfs); bool FixTPITag(BlCvModuleInfo* module, unsigned long& typeId); bool FixIPITag(BlCvModuleInfo* module, unsigned long& typeId); bool FixIPITag_Member(BlCvModuleInfo* module, unsigned long& typeId); bool OnlyHasSimpleRelocs(BlCvModuleInfo * module); void StartSection(int sectionNum); int EndSection(); void FlushMemStream(); void CreatePDBInfoStream(); void WriteTypeData(int streamId, BlTypeInfo& typeInfo); void CreateTypeStream(); void CreateIPIStream(); void WriteRecordMap(BlCvRecordMap * recordMap); int CreateGlobalStream(); int CreatePublicStream(); void FinishSymRecords(); int CreateSymRecordStream(); int CreateSectionHeaderStream(); void CreateDBIStream(); void CreateLinkInfoStream(); void CreateHeaderBlockStream(); void CreateNamesStream(); void CreateModuleStreamSyms(BlCvModuleInfo* module, BlCvSymDataBlock* dataBlock, int dataOfs); void CreateLinkerSymStream(); void CreateModuleStream(BlCvModuleInfo* module); void FinishModuleStream(BlCvModuleInfo* module); void CreateLinkerModule(); void DoFinish(); public: BlCodeView(); ~BlCodeView(); bool Create(const StringImpl& fileName); void StartWorkThreads(); void StopWorkThreads(); void Finish(); }; NS_BF_END