BlCodeView.cpp 61 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481
  1. #include "BlCodeView.h"
  2. #include "codeview/cvinfo.h"
  3. #include "BlContext.h"
  4. #include "BlHash.h"
  5. #include "../COFFData.h"
  6. #include "../Compiler/BfAstAllocator.h"
  7. #include "BeefySysLib/util/BeefPerf.h"
  8. #include <direct.h>
  9. #include <time.h>
  10. //#define BL_AUTOPERF_CV(name) AutoPerf autoPerf##__LINE__(name);
  11. #define BL_AUTOPERF_CV(name)
  12. USING_NS_BF;
  13. #define CV_BLOCK_SIZE 0x1000
  14. #define GET(T) *((T*)(data += sizeof(T)) - 1)
  15. #define PTR_ALIGN(ptr, origPtr, alignSize) ptr = ( (origPtr)+( ((ptr - (origPtr)) + (alignSize - 1)) & ~(alignSize - 1) ) )
  16. //////////////////////////////////////////////////////////////////////////
  17. void BlCvRecordMap::Insert(const char* name, int symIdx)
  18. {
  19. int hashKey = BlHash::HashStr_PdbV1(name) % 4096;
  20. auto entry = mAlloc.Alloc<BlCvRecordEntry>();
  21. entry->mRecordIndex = symIdx;
  22. entry->mNext = mBuckets[hashKey];
  23. mBuckets[hashKey] = entry;
  24. mNumEntries++;
  25. }
  26. int BlCvRecordMap::TryInsert(const char* name, const Val128& key)
  27. {
  28. auto pair = mKeySet.insert(key);
  29. if (!pair.second)
  30. return -1;
  31. //BL_AUTOPERF_CV("BlCvRecordMap::TryInsert insert");
  32. int hashKey = BlHash::HashStr_PdbV1(name) % 4096;
  33. /*auto checkEntry = mBuckets[hashKey];
  34. while (checkEntry != NULL)
  35. {
  36. if (checkEntry->mKey == key)
  37. return -1;
  38. checkEntry = checkEntry->mNext;
  39. }*/
  40. auto entry = mAlloc.Alloc<BlCvRecordEntry>();
  41. entry->mKey = key;
  42. entry->mNext = mBuckets[hashKey];
  43. mBuckets[hashKey] = entry;
  44. mNumEntries++;
  45. entry->mRecordIndex = mCodeView->mSymRecordsWriter.GetStreamPos();
  46. return entry->mRecordIndex;
  47. }
  48. //////////////////////////////////////////////////////////////////////////
  49. BlCvTypeWorkThread::BlCvTypeWorkThread()
  50. {
  51. mTypesDone = false;
  52. mThreadDone = false;
  53. }
  54. BlCvTypeWorkThread::~BlCvTypeWorkThread()
  55. {
  56. Stop();
  57. }
  58. void BlCvTypeWorkThread::Stop()
  59. {
  60. mTypesDone = true;
  61. mWorkEvent.Set();
  62. WorkThread::Stop();
  63. }
  64. void BlCvTypeWorkThread::Run()
  65. {
  66. // Any failure is instant-abort
  67. while (!mCodeView->mContext->mFailed)
  68. {
  69. BlCvTypeSource* typeSource = NULL;
  70. mCritSect.Lock();
  71. if (!mTypeSourceWorkQueue.empty())
  72. {
  73. typeSource = mTypeSourceWorkQueue.front();
  74. mTypeSourceWorkQueue.pop_front();
  75. }
  76. mCritSect.Unlock();
  77. if (typeSource == NULL)
  78. {
  79. if (mTypesDone)
  80. break;
  81. BP_ZONE("Waiting");
  82. mWorkEvent.WaitFor();
  83. continue;
  84. }
  85. BF_ASSERT(!typeSource->mIsDone);
  86. if (typeSource->mTypeServerLib != NULL)
  87. {
  88. BP_ZONE("Load TypeServerLib");
  89. if (!typeSource->mTypeServerLib->Load(typeSource->mTypeServerLib->mFileName))
  90. {
  91. mCodeView->mContext->Fail(StrFormat("Failed to load: %s", typeSource->mTypeServerLib->mFileName.c_str()));
  92. }
  93. }
  94. else
  95. {
  96. BP_ZONE("Load Obj");
  97. typeSource->mTPI.ScanTypeData();
  98. typeSource->mTPI.ParseTypeData();
  99. }
  100. typeSource->mIsDone = true;
  101. //typeSource->mDoneSignal.Set();
  102. // The module work thread may be waiting for this type source
  103. mCodeView->mModuleWorkThread.mWorkEvent.Set();
  104. }
  105. // Wake up module work thread
  106. mThreadDone = true;
  107. mCodeView->mModuleWorkThread.mWorkEvent.Set();
  108. }
  109. void BlCvTypeWorkThread::Add(BlCvTypeSource* typeSource)
  110. {
  111. AutoCrit autoCrit(mCritSect);
  112. mTypeSourceWorkQueue.push_back(typeSource);
  113. mWorkEvent.Set();
  114. }
  115. //////////////////////////////////////////////////////////////////////////
  116. BlCvModuleWorkThread::BlCvModuleWorkThread()
  117. {
  118. mModulesDone = false;
  119. }
  120. BlCvModuleWorkThread::~BlCvModuleWorkThread()
  121. {
  122. Stop();
  123. }
  124. void BlCvModuleWorkThread::Stop()
  125. {
  126. mModulesDone = true;
  127. mWorkEvent.Set();
  128. WorkThread::Stop();
  129. }
  130. void BlCvModuleWorkThread::Run()
  131. {
  132. {
  133. BP_ZONE("Initial Waiting");
  134. //mCodeView->mTypeWorkThread.WaitForFinish();
  135. }
  136. // Any failure is instant-abort
  137. while (!mCodeView->mContext->mFailed)
  138. {
  139. BlCvModuleInfo* module = NULL;
  140. mCritSect.Lock();
  141. if (!mModuleWorkQueue.empty())
  142. {
  143. module = mModuleWorkQueue.front();
  144. if ((module->mTypeSource == NULL) || (module->mTypeSource->mIsDone))
  145. {
  146. mModuleWorkQueue.pop_front();
  147. }
  148. else
  149. {
  150. module = NULL;
  151. }
  152. }
  153. mCritSect.Unlock();
  154. if (module == NULL)
  155. {
  156. if ((mModulesDone) && (mCodeView->mTypeWorkThread.mThreadDone))
  157. break;
  158. BP_ZONE("Waiting");
  159. mWorkEvent.WaitFor();
  160. continue;
  161. }
  162. BF_ASSERT(module->mSymStreamIdx == -1);
  163. mCodeView->CreateModuleStream(module);
  164. }
  165. //
  166. {
  167. BP_ZONE("Waiting for TypeThread");
  168. mCodeView->mTypeWorkThread.WaitForFinish();
  169. }
  170. if (!mCodeView->mContext->mFailed)
  171. {
  172. BP_ZONE("DoFinish");
  173. mCodeView->DoFinish();
  174. }
  175. }
  176. void BlCvModuleWorkThread::Add(BlCvModuleInfo* module)
  177. {
  178. AutoCrit autoCrit(mCritSect);
  179. mModuleWorkQueue.push_back(module);
  180. mWorkEvent.Set();
  181. }
  182. //////////////////////////////////////////////////////////////////////////
  183. BlCvStreamWriter::BlCvStreamWriter()
  184. {
  185. mCurStream = NULL;
  186. mCurStream = NULL;
  187. mCurBlockPos = NULL;
  188. mCurBlockEnd = NULL;
  189. }
  190. void BlCvStreamWriter::Start(BlCVStream * stream)
  191. {
  192. mCurStream = stream;
  193. BF_ASSERT(mCurStream->mBlocks.empty());
  194. }
  195. void BlCvStreamWriter::Continue(BlCVStream * stream)
  196. {
  197. mCurStream = stream;
  198. if (!stream->mBlocks.empty())
  199. {
  200. mCurBlockPos = (uint8*)mMsf->mBlocks[mCurStream->mBlocks.back()]->mData;
  201. mCurBlockEnd = mCurBlockPos + CV_BLOCK_SIZE;
  202. mCurBlockPos += stream->mSize % CV_BLOCK_SIZE;
  203. }
  204. }
  205. void BlCvStreamWriter::End(bool flush)
  206. {
  207. if (flush)
  208. {
  209. for (auto block : mCurStream->mBlocks)
  210. mMsf->FlushBlock(block);
  211. }
  212. mCurStream->mSize = GetStreamPos();
  213. mCurBlockPos = NULL;
  214. mCurBlockEnd = NULL;
  215. mCurStream = NULL;
  216. }
  217. void BlCvStreamWriter::Write(const void* data, int size)
  218. {
  219. while (mCurBlockPos + size > mCurBlockEnd)
  220. {
  221. int writeBytes = (int)(mCurBlockEnd - mCurBlockPos);
  222. if (writeBytes > 0)
  223. {
  224. memcpy(mCurBlockPos, data, writeBytes);
  225. data = (uint8*)data + writeBytes;
  226. size -= writeBytes;
  227. }
  228. int newBlock = mMsf->Alloc();
  229. mCurStream->mBlocks.Add(newBlock);
  230. mCurBlockPos = (uint8*)mMsf->mBlocks[newBlock]->mData;
  231. mCurBlockEnd = mCurBlockPos + CV_BLOCK_SIZE;
  232. }
  233. if (size > 0)
  234. {
  235. memcpy(mCurBlockPos, data, size);
  236. mCurBlockPos += size;
  237. }
  238. }
  239. void BlCvStreamWriter::Write(ChunkedDataBuffer& buffer)
  240. {
  241. int size = buffer.GetSize();
  242. buffer.SetReadPos(0);
  243. while (buffer.mReadCurPtr + size > buffer.mReadNextAlloc)
  244. {
  245. int curSize = (int)(buffer.mReadNextAlloc - buffer.mReadCurPtr);
  246. if (curSize > 0)
  247. Write(buffer.mReadCurPtr, curSize);
  248. buffer.NextReadPool();
  249. size -= curSize;
  250. }
  251. Write(buffer.mReadCurPtr, size);
  252. buffer.mReadCurPtr += size;
  253. }
  254. int BlCvStreamWriter::GetStreamPos()
  255. {
  256. return (int)((mCurStream->mBlocks.size() - 1)*CV_BLOCK_SIZE + (mCurBlockPos - (mCurBlockEnd - CV_BLOCK_SIZE)));
  257. }
  258. void BlCvStreamWriter::StreamAlign(int align)
  259. {
  260. PTR_ALIGN(mCurBlockPos, mCurBlockEnd - CV_BLOCK_SIZE, align);
  261. }
  262. void* BlCvStreamWriter::GetStreamPtr(int pos)
  263. {
  264. int blockNum = mCurStream->mBlocks[pos / CV_BLOCK_SIZE];
  265. auto data = (uint8*)mMsf->mBlocks[blockNum]->mData;
  266. return (uint8*)data + (pos % CV_BLOCK_SIZE);
  267. }
  268. //////////////////////////////////////////////////////////////////////////
  269. BlCvStreamReader::BlCvStreamReader()
  270. {
  271. mMsf = NULL;
  272. mBlockIdx = -1;
  273. mCurBlockPos = NULL;
  274. mCurBlockEnd = NULL;
  275. }
  276. void BlCvStreamReader::Open(BlCVStream* stream)
  277. {
  278. mCurStream = stream;
  279. if (!mCurStream->mBlocks.empty())
  280. {
  281. mBlockIdx = 0;
  282. mCurBlockPos = (uint8*)mMsf->mBlocks[stream->mBlocks[mBlockIdx]]->mData;
  283. mCurBlockEnd = mCurBlockPos + CV_BLOCK_SIZE;
  284. }
  285. else
  286. {
  287. mBlockIdx = -1;
  288. mCurBlockPos = NULL;
  289. mCurBlockEnd = NULL;
  290. }
  291. }
  292. // Pass NULL to data to make sure we have a mutable pointer into the stream. This can
  293. // only work if we know the alignment of a stream and we are reading an aligned member
  294. // with a size less than or equal to the stream's alignment
  295. void* BlCvStreamReader::ReadFast(void* data, int size)
  296. {
  297. if (mCurBlockPos + size <= mCurBlockEnd)
  298. {
  299. // The FAST case, just return a pointer
  300. void* ptr = mCurBlockPos;
  301. mCurBlockPos += size;
  302. return ptr;
  303. }
  304. void* ptr = data;
  305. while (mCurBlockPos + size > mCurBlockEnd)
  306. {
  307. int readBytes = (int)(mCurBlockEnd - mCurBlockPos);
  308. if (readBytes > 0)
  309. {
  310. memcpy(data, mCurBlockPos, readBytes);
  311. data = (uint8*)data + readBytes;
  312. size -= readBytes;
  313. }
  314. mBlockIdx++;
  315. mCurBlockPos = (uint8*)mMsf->mBlocks[mCurStream->mBlocks[mBlockIdx]]->mData;
  316. mCurBlockEnd = mCurBlockPos + CV_BLOCK_SIZE;
  317. }
  318. // We had to load new data but nothing got read in yet
  319. if (ptr == data)
  320. {
  321. void* ptr = mCurBlockPos;
  322. mCurBlockPos += size;
  323. return ptr;
  324. }
  325. if (size > 0)
  326. {
  327. memcpy(data, mCurBlockPos, size);
  328. mCurBlockPos += size;
  329. }
  330. return ptr;
  331. }
  332. void BlCvStreamReader::Seek(int size)
  333. {
  334. while (mCurBlockPos + size > mCurBlockEnd)
  335. {
  336. int readBytes = (int)(mCurBlockEnd - mCurBlockPos);
  337. size -= readBytes;
  338. mBlockIdx++;
  339. mCurBlockPos = (uint8*)mMsf->mBlocks[mCurStream->mBlocks[mBlockIdx]]->mData;
  340. mCurBlockEnd = mCurBlockPos + CV_BLOCK_SIZE;
  341. }
  342. mCurBlockPos += size;
  343. }
  344. int BlCvStreamReader::GetStreamPos()
  345. {
  346. return (int)(mBlockIdx*CV_BLOCK_SIZE + (mCurBlockPos - (mCurBlockEnd - CV_BLOCK_SIZE)));
  347. }
  348. //////////////////////////////////////////////////////////////////////////
  349. #pragma comment(lib, "rpcrt4.lib")
  350. BlCodeView::BlCodeView()
  351. {
  352. //mTagBufPtr = NULL;
  353. mSymRecordsStream = -1;
  354. mStat_TypeMapInserts = 0;
  355. mStat_ParseTagFuncs = 0;
  356. mSectStartFilePos = -1;
  357. for (int i = 0; i < 5; i++)
  358. mStreams.Alloc();
  359. memset(mSignature, 0, sizeof(mSignature));
  360. //uint32 sig[] = { 0x8BB4B1E6, 0x32C63441, 0xB5BD0FDC, 0x8206881A };
  361. //uint32 sig[] = { 0x00000000, 0x00000001, 0x00000000, 0x00000000 };
  362. //memcpy(mSignature, sig, 16);
  363. UuidCreate((UUID*)&mSignature);
  364. mAge = 1;
  365. mGlobals.mCodeView = this;
  366. mTypeWorkThread.mCodeView = this;
  367. mModuleWorkThread.mCodeView = this;
  368. mWriter.mMsf = &mMsf;
  369. mSymRecordsWriter.mMsf = &mMsf;
  370. AddToStringTable("");
  371. }
  372. BlCodeView::~BlCodeView()
  373. {
  374. for (auto pair : mTypeServerFiles)
  375. delete pair.second;
  376. }
  377. void BlCodeView::Fail(const StringImpl& err)
  378. {
  379. mContext->Fail(err);
  380. }
  381. char* BlCodeView::StrDup(const char* str)
  382. {
  383. int len = (int)strlen(str);
  384. char* newStr = (char*)mAlloc.AllocBytes(len + 1);
  385. memcpy(newStr, str, len + 1);
  386. return newStr;
  387. }
  388. void BlCodeView::NotImpl()
  389. {
  390. BF_FATAL("NotImpl");
  391. }
  392. void BlCodeView::FixSymAddress(void* oldDataStart, void* oldDataPos, void* outDataPos, BlCvModuleInfo* module, BlCvSymDataBlock* dataBlock, COFFRelocation*& nextReloc)
  393. {
  394. //BL_AUTOPERF_CV("BlCodeView::FixSymAddress");
  395. int posOfs = (int)((uint8*)oldDataPos - (uint8*)oldDataStart) + dataBlock->mSourceSectOffset;
  396. int posSect = posOfs + 4;
  397. if ((nextReloc->mVirtualAddress != posOfs) || (nextReloc == dataBlock->mRelocEnd))
  398. return;
  399. auto objSym = &module->mSymInfo[nextReloc->mSymbolTableIndex];
  400. int segmentIdx = -1;
  401. int segmentOffset = -1;
  402. if (objSym->mSym == NULL)
  403. {
  404. segmentIdx = objSym->mSegmentIdx;
  405. segmentOffset = objSym->mSegmentOffset;
  406. }
  407. else
  408. {
  409. auto sym = objSym->mSym;
  410. BF_ASSERT(sym != NULL);
  411. if (sym != NULL)
  412. {
  413. if (sym->mKind == BlSymKind_WeakSymbol)
  414. sym = mContext->ProcessSymbol(sym);
  415. if (sym->mSegmentIdx >= 0)
  416. {
  417. segmentIdx = sym->mSegmentIdx;
  418. segmentOffset = sym->mSegmentOffset;
  419. }
  420. else if (sym->mKind == BlSymKind_ImageBaseRel)
  421. {
  422. // Leave zeros
  423. }
  424. else if (sym->mKind == BlSymKind_Absolute)
  425. {
  426. *(int32*)(outDataPos) += sym->mParam;
  427. *((int16*)outDataPos + 2) += (int)mContext->mOutSections.size(); // One past end is 'Abs' section
  428. }
  429. else if (sym->mKind == BlSymKind_ImportImp)
  430. {
  431. int segmentIdx = mContext->mIDataSeg->mSegmentIdx;
  432. auto lookup = mContext->mImportLookups[sym->mParam];
  433. int segmentOffset = lookup->mIDataIdx * 8;
  434. /*auto segment = mContext->mSegments[segmentIdx];
  435. auto outSection = mContext->mOutSections[segment->mOutSectionIdx];
  436. *(int32*)(outDataPos) += (segment->mRVA - outSection->mRVA) + segmentOffset;
  437. *((int16*)outDataPos + 2) += outSection->mIdx + 1;*/
  438. }
  439. else
  440. {
  441. // Invalid address
  442. BF_FATAL("Invalid address");
  443. }
  444. }
  445. }
  446. if (segmentIdx != -1)
  447. {
  448. auto segment = mContext->mSegments[segmentIdx];
  449. auto outSection = mContext->mOutSections[segment->mOutSectionIdx];
  450. *(int32*)(outDataPos) += (segment->mRVA - outSection->mRVA) + segmentOffset;
  451. *((int16*)outDataPos + 2) += outSection->mIdx + 1;
  452. }
  453. nextReloc++;
  454. if (nextReloc->mVirtualAddress != posSect)
  455. Fail("Symbol remap failure");
  456. // It MUST be the same sym
  457. nextReloc++;
  458. }
  459. int BlCodeView::StartStream(int streamIdx)
  460. {
  461. BF_ASSERT(mWriter.mCurStream == NULL);
  462. BF_ASSERT(streamIdx <= 5);
  463. if (streamIdx == -1)
  464. {
  465. streamIdx = (int)mStreams.size();
  466. mStreams.Alloc();
  467. }
  468. mWriter.Start(mStreams[streamIdx]);
  469. return streamIdx;
  470. }
  471. void BlCodeView::StartUnnamedStream(BlCVStream& stream)
  472. {
  473. mWriter.Start(&stream);
  474. }
  475. void BlCodeView::EndStream(bool flush)
  476. {
  477. mWriter.End(flush);
  478. }
  479. void BlCodeView::FlushStream(BlCVStream* stream)
  480. {
  481. for (auto block : stream->mBlocks)
  482. mMsf.FlushBlock(block);
  483. }
  484. void BlCodeView::CvEncodeString(const StringImpl& str)
  485. {
  486. mWriter.Write((void*)str.c_str(), (int)str.length() + 1);
  487. }
  488. int BlCodeView::AddToStringTable(const StringImpl&str)
  489. {
  490. auto pairVal = mStrTabMap.insert(std::make_pair(str, -1));
  491. if (pairVal.second)
  492. {
  493. pairVal.first->second = (int)mStrTab.length();
  494. mStrTab.Append(str.c_str(), str.length());
  495. }
  496. return pairVal.first->second;
  497. }
  498. void BlCodeView::WriteStringTable(const StringImpl&strTab, std::unordered_map<String, int>& strTabMap)
  499. {
  500. mWriter.WriteT((int32)0xEFFEEFFE);
  501. mWriter.WriteT(1); // Version
  502. mWriter.WriteT((int32)strTab.length() + 1);
  503. mWriter.Write((char*)strTab.c_str(), (int)strTab.length() + 1);
  504. int bucketCount = (int)(strTabMap.size() * 1.25) + 1;
  505. std::vector<uint32> buckets;
  506. buckets.resize(bucketCount);
  507. mWriter.WriteT(bucketCount);
  508. for (auto pair : mStrTabMap)
  509. {
  510. int idx = pair.second;
  511. uint32 hash = BlHash::HashStr_PdbV1(pair.first.c_str());
  512. for (int ofs = 0; ofs < bucketCount; ofs++)
  513. {
  514. int slot = (hash + ofs) % bucketCount;
  515. if (slot == 0)
  516. continue; // 0 is reserved
  517. if (buckets[slot] != 0)
  518. continue;
  519. buckets[slot] = idx;
  520. break;
  521. }
  522. }
  523. mWriter.Write((void*)&buckets[0], (int)buckets.size() * 4);
  524. mWriter.WriteT((int)strTabMap.size());
  525. }
  526. void BlCodeView::GetOutSectionAddr(int segIdx, int segOfs, uint16& cvSectIdx, long& cvSectOfs)
  527. {
  528. auto segment = mContext->mSegments[segIdx];
  529. auto outSect = mContext->mOutSections[segment->mOutSectionIdx];
  530. cvSectIdx = outSect->mIdx + 1;
  531. cvSectOfs = (segment->mRVA - outSect->mRVA) + segOfs;
  532. }
  533. void BlCodeView::StartSection(int sectionNum)
  534. {
  535. mSectStartFilePos = mWriter.GetStreamPos();
  536. BF_ASSERT((mSectStartFilePos % 4) == 0);
  537. mWriter.WriteT((int32)sectionNum);
  538. mWriter.WriteT((int32)0); // Temporary - size
  539. }
  540. int BlCodeView::EndSection()
  541. {
  542. int totalLen = mWriter.GetStreamPos() - mSectStartFilePos - 8;
  543. *((int32*)mWriter.GetStreamPtr(mSectStartFilePos + 4)) = totalLen;
  544. return totalLen + 8;
  545. }
  546. bool BlCodeView::Create(const StringImpl& fileName)
  547. {
  548. if (!mMsf.Create(fileName))
  549. return false;
  550. mSymRecordsStream = StartStream();
  551. mSymRecordsWriter.Start(mWriter.mCurStream);
  552. EndStream(false);
  553. CreateLinkerModule();
  554. return true;
  555. }
  556. void BlCodeView::StartWorkThreads()
  557. {
  558. mTypeWorkThread.Start();
  559. mModuleWorkThread.Start();
  560. }
  561. void BlCodeView::StopWorkThreads()
  562. {
  563. BL_AUTOPERF_CV("BlCodeView::StopWorkThread");
  564. mTypeWorkThread.Stop();
  565. mModuleWorkThread.Stop();
  566. }
  567. void BlCodeView::CreatePDBInfoStream()
  568. {
  569. //PDB Info Stream
  570. StartStream(1);
  571. mWriter.WriteT((int32)20000404); //VC70
  572. mWriter.WriteT((int32)mContext->mTimestamp);
  573. mWriter.WriteT((int32)mAge);
  574. mWriter.WriteT(mSignature);
  575. int strCount = 0;
  576. String namesStr;
  577. for (auto& stream : mStreams)
  578. {
  579. if (!stream->mName.empty())
  580. {
  581. namesStr += stream->mName;
  582. namesStr.Append((char)0);
  583. strCount++;
  584. }
  585. }
  586. // Named string table
  587. mWriter.WriteT((int32)namesStr.length());
  588. mWriter.Write(namesStr.c_str(), (int)namesStr.length());
  589. mWriter.WriteT((int32)strCount); // actual item count
  590. mWriter.WriteT((int32)strCount * 2); // max item count. What should this be?
  591. mWriter.WriteT((int32)1); // usedLength
  592. int32 usedBits = 0;
  593. // This is supposed to be hashed but we just fill in the correct number of bits.
  594. for (int i = 0; i < strCount; i++)
  595. usedBits |= 1 << i;
  596. mWriter.WriteT((int32)usedBits);
  597. mWriter.WriteT((int32)0); // deletedLength
  598. int strTabIdx = 0;
  599. for (int streamIdx = 0; streamIdx < (int)mStreams.size(); streamIdx++)
  600. {
  601. auto& stream = mStreams[streamIdx];
  602. if (!stream->mName.empty())
  603. {
  604. mWriter.WriteT((int32)strTabIdx);
  605. mWriter.WriteT((int32)streamIdx);
  606. strTabIdx += (int)stream->mName.length() + 1;
  607. }
  608. }
  609. // Features info
  610. mWriter.WriteT((int32)0);
  611. mWriter.WriteT((int32)20140508); // PdbImplVC140
  612. EndStream();
  613. }
  614. void BlCodeView::WriteTypeData(int streamId, BlTypeInfo& typeInfo)
  615. {
  616. int hashStream = StartStream();
  617. int pos = 0;
  618. uint8 tempData[0x10002];
  619. int hashBucketsSize = 0x3FFFF;
  620. int numTags = typeInfo.mCurTagId - 0x1000;
  621. struct _JumpEntry
  622. {
  623. int mTypeIdx;
  624. int mOfs;
  625. };
  626. Array<_JumpEntry> indexEntries;
  627. uint8* curChunk = NULL;
  628. typeInfo.mData.SetReadPos(0);
  629. for (int tagId = 0x1000; tagId < typeInfo.mCurTagId; tagId++)
  630. {
  631. // Align
  632. typeInfo.mData.mReadCurPtr = (uint8*)(((intptr)typeInfo.mData.mReadCurPtr + 3) & ~3);
  633. // Chunks are every 8k, which is perfect for the jump table
  634. if (curChunk != typeInfo.mData.mReadCurAlloc)
  635. {
  636. indexEntries.Add({ tagId, typeInfo.mData.GetReadPos() });
  637. curChunk = typeInfo.mData.mReadCurAlloc;
  638. }
  639. uint8* dataHead = (uint8*)typeInfo.mData.FastRead(tempData, 4);
  640. // Pointer not valid
  641. uint8* data = dataHead;
  642. int trLength = GET(uint16);
  643. if (dataHead == tempData)
  644. {
  645. typeInfo.mData.Read(tempData + 4, trLength - 2);
  646. }
  647. else
  648. {
  649. uint8* leafData = (uint8*)typeInfo.mData.FastRead(tempData + 4, trLength - 2);
  650. if (leafData != dataHead + 4)
  651. {
  652. memcpy(tempData, dataHead, 4);
  653. dataHead = tempData;
  654. }
  655. }
  656. data = dataHead;
  657. int32 hashVal = BlHash::GetTypeHash(data) % hashBucketsSize;
  658. mWriter.WriteT(hashVal);
  659. //typeInfo.mData.TryGetPtr
  660. }
  661. mWriter.Write(&indexEntries[0], (int)indexEntries.size() * 8);
  662. // Adjuster
  663. /*mWriter.WriteT(0); // Adjust count
  664. mWriter.WriteT(0); // Adjust capacity
  665. mWriter.WriteT(0); // Used len
  666. mWriter.WriteT(0); // Deleted len*/
  667. EndStream();
  668. int hashValsSize = numTags * 4;
  669. int hashTypeInfoSize = (int)indexEntries.size() * 8;
  670. int adjusterSize = 0;
  671. StartStream(streamId);
  672. mWriter.WriteT(0x0131ca0b); // ver
  673. mWriter.WriteT(56); // headerSize
  674. mWriter.WriteT(0x1000); // minVal
  675. mWriter.WriteT(typeInfo.mCurTagId); // maxVal
  676. mWriter.WriteT(typeInfo.mData.GetSize()); // followSize - should be total section size - headerSize(56)
  677. mWriter.WriteT((int16)hashStream); // hashStream
  678. mWriter.WriteT((int16)-1); // hashStreamPadding
  679. mWriter.WriteT(4); // hashKeySize
  680. mWriter.WriteT(hashBucketsSize); // hashBucketsSize
  681. mWriter.WriteT(0); // hashValsOffset
  682. mWriter.WriteT(hashValsSize); // hashValsSize
  683. mWriter.WriteT(hashValsSize); // hashTypeInfoOffset
  684. mWriter.WriteT(hashTypeInfoSize); // hashTypeInfoSize
  685. mWriter.WriteT(hashValsSize + hashTypeInfoSize); // hashAdjOffset
  686. mWriter.WriteT(adjusterSize); // hashAdjSize
  687. typeInfo.mData.SetReadPos(0);
  688. mWriter.Write(typeInfo.mData);
  689. EndStream();
  690. }
  691. void BlCodeView::CreateTypeStream()
  692. {
  693. //BL_AUTOPERF_CV("BlCodeView::CreateTypeStream");
  694. BP_ZONE("BlCodeView::CreateTypeStream");
  695. WriteTypeData(2, mTPI);
  696. }
  697. void BlCodeView::CreateIPIStream()
  698. {
  699. //BL_AUTOPERF_CV("BlCodeView::CreateIPIStream");
  700. BP_ZONE("BlCodeView::CreateIPIStream");
  701. WriteTypeData(4, mIPI);
  702. }
  703. void BlCodeView::WriteRecordMap(BlCvRecordMap* recordMap)
  704. {
  705. mWriter.WriteT((int32)-1); // verSig
  706. mWriter.WriteT((int32)0xf12f091a); // verHdr
  707. mWriter.WriteT((int32)(recordMap->mNumEntries * 4 * 2)); // sizeHr
  708. int bucketsCount = 0;
  709. for (int hashKey = 0; hashKey < 4096; hashKey++)
  710. if (recordMap->mBuckets[hashKey] != NULL)
  711. bucketsCount++;
  712. mWriter.WriteT((int32)(0x81 * 4 + bucketsCount * 4)); // sizeBuckets
  713. uint32 bucketBits[0x80] = { 0 };
  714. int32 buckets[4096];
  715. int bucketIdx = 0;
  716. // HR
  717. int hrIdx = 0;
  718. for (int hashKey = 0; hashKey < 4096; hashKey++)
  719. {
  720. auto checkEntry = recordMap->mBuckets[hashKey];
  721. if (checkEntry == NULL)
  722. continue;
  723. bucketBits[hashKey / 32] |= 1 << (hashKey % 32);
  724. buckets[bucketIdx++] = hrIdx;
  725. while (checkEntry != NULL)
  726. {
  727. mWriter.WriteT(checkEntry->mRecordIndex + 1);
  728. mWriter.WriteT(1);
  729. checkEntry = checkEntry->mNext;
  730. hrIdx++;
  731. }
  732. }
  733. for (int i = 0; i < 0x80; i++)
  734. mWriter.WriteT((int32)bucketBits[i]);
  735. mWriter.WriteT(0);
  736. for (int i = 0; i < bucketIdx; i++)
  737. mWriter.WriteT(buckets[i] * 12);
  738. }
  739. int BlCodeView::CreateGlobalStream()
  740. {
  741. BP_ZONE("BlCodeView::CreateGlobalStream");
  742. int globalStreamIdx = StartStream();
  743. WriteRecordMap(&mGlobals);
  744. EndStream();
  745. return globalStreamIdx;
  746. }
  747. int BlCodeView::CreatePublicStream()
  748. {
  749. BP_ZONE("BlCodeView::CreatePublicStream");
  750. int publicStreamIdx = StartStream();
  751. BlCvRecordMap publics;
  752. struct _SortEntry
  753. {
  754. uint64 mAddr;
  755. int mRecordIdx;
  756. };
  757. Array<_SortEntry> addrMap;
  758. addrMap.Reserve(mContext->mSymTable.mMap.size());
  759. for (auto symPair : mContext->mSymTable.mMap)
  760. {
  761. auto sym = symPair.second;
  762. if ((sym->mSegmentIdx >= 0) || (sym->mKind == BlSymKind_Absolute))
  763. {
  764. bool isAbs = sym->mKind == BlSymKind_Absolute;
  765. #define ADDR_FLAG_ABS 0x8000000000000000L
  766. auto segment = (isAbs) ? (BlSegment*)NULL : mContext->mSegments[sym->mSegmentIdx];
  767. int pubSymLen = (int)offsetof(PUBSYM32, name);
  768. int nameSize = (int)strlen(sym->mName) + 1;
  769. PUBSYM32 pubSym = { 0 };
  770. pubSym.reclen = pubSymLen + nameSize - 2;
  771. pubSym.rectyp = S_PUB32;
  772. if (isAbs)
  773. {
  774. pubSym.seg = (int)mContext->mOutSections.size(); // One past end is 'Abs' section
  775. pubSym.off = sym->mSegmentOffset;
  776. }
  777. else
  778. {
  779. auto outSection = mContext->mOutSections[segment->mOutSectionIdx];
  780. if ((outSection->mCharacteristics & IMAGE_SCN_MEM_EXECUTE) != 0)
  781. {
  782. pubSym.pubsymflags.fFunction = 1;
  783. pubSym.pubsymflags.fCode = 1;
  784. }
  785. pubSym.off = (segment->mRVA - outSection->mRVA) + sym->mSegmentOffset;
  786. pubSym.seg = outSection->mIdx + 1;
  787. }
  788. int addBytes = ((nameSize + 2 + 3) & ~3) - (nameSize + 2);
  789. pubSym.reclen += addBytes;
  790. int idx = mSymRecordsWriter.GetStreamPos();
  791. if (isAbs)
  792. addrMap.Add({ ADDR_FLAG_ABS + sym->mSegmentOffset, idx});
  793. else
  794. addrMap.Add({ (uint64)(segment->mRVA + sym->mSegmentOffset), idx });
  795. mSymRecordsWriter.Write(&pubSym, pubSymLen);
  796. mSymRecordsWriter.Write(sym->mName, nameSize);
  797. if (addBytes > 0)
  798. {
  799. int zero = 0;
  800. mSymRecordsWriter.Write(&zero, addBytes);
  801. }
  802. publics.Insert(sym->mName, idx);
  803. }
  804. }
  805. std::sort(addrMap.begin(), addrMap.end(), [](const _SortEntry& lhs, const _SortEntry& rhs) { return lhs.mAddr < rhs.mAddr; });
  806. int bucketsCount = 0;
  807. for (int hashKey = 0; hashKey < 4096; hashKey++)
  808. if (publics.mBuckets[hashKey] != NULL)
  809. bucketsCount++;
  810. int symHashSize = 16 + (int32)(publics.mNumEntries * 4 * 2) + (int32)(0x81 * 4 + bucketsCount * 4);
  811. int addrHashSize = (int)addrMap.size() * 4;
  812. mWriter.WriteT(symHashSize); // symHashSize
  813. mWriter.WriteT(addrHashSize); // addrMapSize
  814. mWriter.WriteT(0); // thunkCount
  815. mWriter.WriteT(0); // thunkSize
  816. mWriter.WriteT(0); // thunkTableStream
  817. mWriter.WriteT(0); // thunkTableOfs
  818. mWriter.WriteT(0); // thunkSectCount
  819. int symHashPos = mWriter.GetStreamPos();
  820. WriteRecordMap(&publics);
  821. BF_ASSERT(mWriter.GetStreamPos() - symHashPos == symHashSize);
  822. for (auto& addrMapEntry : addrMap)
  823. {
  824. mWriter.WriteT(addrMapEntry.mRecordIdx);
  825. }
  826. EndStream();
  827. return publicStreamIdx;
  828. }
  829. void BlCodeView::FinishSymRecords()
  830. {
  831. BP_ZONE("BlCodeView::FinishSymRecords");
  832. BlCvStreamReader reader;
  833. reader.mMsf = &mMsf;
  834. reader.Open(mStreams[mSymRecordsStream]);
  835. auto itr = mSymRecordDeferredPositions.begin();
  836. auto endItr = mSymRecordDeferredPositions.end();
  837. int wantPos = mSymRecordsWriter.GetStreamPos();
  838. int curPos = 0;
  839. while (itr != endItr)
  840. {
  841. int wantOfs = *itr;
  842. reader.Seek(wantOfs - curPos);
  843. curPos = wantOfs;
  844. int16 hdrBuf[2];
  845. int16* hdr = (int16*)reader.ReadFast(&hdrBuf, 4);
  846. int16 symLen = hdr[0];
  847. int16 symType = hdr[1];
  848. int wantSeekBytes = symLen - 2;
  849. int addrOfs;
  850. switch (symType)
  851. {
  852. case S_LPROC32:
  853. case S_GPROC32:
  854. addrOfs = offsetof(PROCSYM32, off);
  855. break;
  856. case S_LTHREAD32:
  857. case S_GTHREAD32:
  858. addrOfs = offsetof(THREADSYM32, off);
  859. break;
  860. case S_LDATA32:
  861. case S_GDATA32:
  862. addrOfs = offsetof(DATASYM32, off);
  863. break;
  864. default:
  865. NotImpl();
  866. break;
  867. }
  868. reader.Seek(addrOfs - 4);
  869. int32* ofsPtr = (int32*)reader.ReadFast(NULL, 4);
  870. int16* segPtr = (int16*)reader.ReadFast(NULL, 2);
  871. auto segment = mContext->mSegments[*segPtr];
  872. auto outSection = mContext->mOutSections[segment->mOutSectionIdx];
  873. *ofsPtr += segment->mRVA - outSection->mRVA;
  874. *segPtr = outSection->mIdx + 1;
  875. reader.Seek(wantSeekBytes - addrOfs - 2);
  876. curPos += 2 + symLen;
  877. BF_ASSERT(curPos == reader.GetStreamPos());
  878. ++itr;
  879. }
  880. mSymRecordsWriter.End();
  881. }
  882. /*int BlCodeView::CreateSymRecordStream()
  883. {
  884. int symRecordStreamIdx = StartStream();
  885. //mSymRecords.Read(mFS, mSymRecords.GetSize());
  886. //mWriter.Write(mSymRecords);
  887. EndStream();
  888. return symRecordStreamIdx;
  889. }*/
  890. int BlCodeView::CreateSectionHeaderStream()
  891. {
  892. int symRecordStreamIdx = StartStream();
  893. mWriter.Write(mSectionHeaders.GetPtr(), mSectionHeaders.GetSize());
  894. EndStream();
  895. return symRecordStreamIdx;
  896. }
  897. void BlCodeView::CreateDBIStream()
  898. {
  899. int globalStreamIdx = CreateGlobalStream();
  900. int publicStreamIdx = CreatePublicStream();
  901. //int symRecordStreamIdx = CreateSymRecordStream();
  902. int symRecordStreamIdx = mSymRecordsStream;
  903. int sectionHeaderStreamIdx = CreateSectionHeaderStream();
  904. StartStream(3);
  905. mWriter.WriteT((int32)-1); // VersionSignature
  906. mWriter.WriteT((int32)19990903); // VersionHeader V70
  907. mWriter.WriteT((int32)mAge);
  908. mWriter.WriteT((int16)globalStreamIdx);
  909. //int buildNum = (1 << 15) | (12 << 8) | (0); // Fake as 'NewVersionFormat' 12.0 (MSVC 2013)
  910. mWriter.WriteT((int16)0x8e00);
  911. mWriter.WriteT((int16)publicStreamIdx);
  912. mWriter.WriteT((int16)0x5e92); // PdbDllVersion
  913. mWriter.WriteT((int16)symRecordStreamIdx);
  914. mWriter.WriteT((int16)0); // PdbDllRbld
  915. int substreamSizesPos = mWriter.GetStreamPos();
  916. int32* sizePtrs = (int32*)mWriter.mCurBlockPos;
  917. mWriter.WriteT((int32)0); // ModInfoSize
  918. mWriter.WriteT((int32)0); // SectionContributionSize
  919. mWriter.WriteT((int32)0); // SectionMapSize
  920. mWriter.WriteT((int32)0); // SourceInfoSize
  921. mWriter.WriteT((int32)0); // TypeServerSize
  922. mWriter.WriteT((int32)0); // MFCTypeServerIndex
  923. mWriter.WriteT((int32)0); // OptionalDbgHeaderSize
  924. mWriter.WriteT((int32)0); // ECSubstreamSize
  925. int16 flags = 0; // WasIncrementallyLinked, ArePrivateSymbolsStripped, HasConfictingTypes (?)
  926. mWriter.WriteT((int16)flags);
  927. mWriter.WriteT((int16)0x8664); // Machine type
  928. mWriter.WriteT((int32)0); // Padding
  929. struct _SectionContribEntry
  930. {
  931. uint32 mSectionIdx;
  932. int32 mOffset;
  933. int32 mSize;
  934. uint32 mCharacteristics;
  935. uint32 mModuleIdx;
  936. uint32 mDataCrc;
  937. uint32 mRelocCrc;
  938. };
  939. //////////////////////////////////////////////////////////////////////////
  940. // ModuleInfo
  941. int curPos = mWriter.GetStreamPos();
  942. for (auto moduleInfo : mModuleInfo)
  943. {
  944. mWriter.WriteT((int32)0); // Unused
  945. _SectionContribEntry contribEntry = { 0 };
  946. if (!moduleInfo->mContrib.mCharacteristics != 0)
  947. {
  948. auto& contrib = moduleInfo->mContrib;
  949. auto blSection = mContext->mSegments[contrib.mBlSectionIdx];
  950. auto outSection = mContext->mOutSections[blSection->mOutSectionIdx];
  951. contribEntry.mCharacteristics = contrib.mCharacteristics;
  952. contribEntry.mSectionIdx = outSection->mIdx + 1;
  953. contribEntry.mOffset = (blSection->mRVA - outSection->mRVA) + contrib.mBlSectionOfs;
  954. contribEntry.mSize = contrib.mSize;
  955. contribEntry.mModuleIdx = moduleInfo->mIdx;
  956. //TODO: DataCRC, RelocCRC
  957. }
  958. mWriter.WriteT(contribEntry);
  959. int16 flags = 0; //
  960. mWriter.WriteT(flags);
  961. mWriter.WriteT((int16)moduleInfo->mSymStreamIdx);
  962. int symSize = 4;
  963. for (auto& block : moduleInfo->mSymData)
  964. {
  965. BF_ASSERT(block.mOutSize >= 0);
  966. symSize += block.mOutSize;
  967. }
  968. BF_ASSERT(symSize % 4 == 0);
  969. mWriter.WriteT(symSize);
  970. mWriter.WriteT(0); // C11-style LineInfo size
  971. mWriter.WriteT(moduleInfo->mLineInfoSize); //C13-style LineInfo size
  972. mWriter.WriteT((int32)moduleInfo->mFileInfos.size()); // Source file count
  973. mWriter.WriteT((int32)0); // Unusued
  974. mWriter.WriteT((int32)0); // SourceFileNameIndex
  975. // What about special "* Linker *" module? The only case this should be non-zero?
  976. mWriter.WriteT((int32)0); // PdbFilePathNameIndex
  977. if (!moduleInfo->mName.empty())
  978. CvEncodeString(moduleInfo->mName);
  979. else
  980. CvEncodeString(moduleInfo->mObjectData->mName);
  981. if (moduleInfo->mObjectData != NULL)
  982. CvEncodeString(moduleInfo->mObjectData->mName);
  983. else
  984. mWriter.WriteT((uint8)0);
  985. mWriter.StreamAlign(4);
  986. }
  987. int32 modInfoSize = mWriter.GetStreamPos() - curPos;
  988. //////////////////////////////////////////////////////////////////////////
  989. // SectionContributionSize
  990. curPos = mWriter.GetStreamPos();
  991. mWriter.WriteT((int32)(0xeffe0000 + 19970605)); // Ver60
  992. for (auto& outSection : mContext->mOutSections)
  993. {
  994. for (auto& segment : outSection->mSegments)
  995. {
  996. if (segment->mSegmentIdx >= mContribMap.mSegments.size())
  997. continue;
  998. for (auto& contrib : mContribMap.mSegments[segment->mSegmentIdx]->mContribs)
  999. {
  1000. _SectionContribEntry contribEntry = { 0 };
  1001. contribEntry.mCharacteristics = contrib.mCharacteristics;
  1002. contribEntry.mSectionIdx = outSection->mIdx + 1;
  1003. contribEntry.mOffset = (segment->mRVA - outSection->mRVA) + contrib.mBlSectionOfs;
  1004. contribEntry.mSize = contrib.mSize;
  1005. contribEntry.mModuleIdx = contrib.mModuleIdx;
  1006. mWriter.WriteT(contribEntry);
  1007. }
  1008. }
  1009. }
  1010. int32 sectionContributionSize = mWriter.GetStreamPos() - curPos;
  1011. //////////////////////////////////////////////////////////////////////////
  1012. // SectionMap
  1013. curPos = mWriter.GetStreamPos();
  1014. mWriter.WriteT((int16)mContext->mOutSections.size()); // Section count
  1015. mWriter.WriteT((int16)mContext->mOutSections.size()); // Log section count
  1016. for (auto outSection : mContext->mOutSections)
  1017. {
  1018. int16 flags = (1 << 3) | (1 << 8); // AddressIs32Bit, IsSelector
  1019. if ((outSection->mCharacteristics & IMAGE_SCN_MEM_READ) != 0)
  1020. flags |= (1 << 0);
  1021. if ((outSection->mCharacteristics & IMAGE_SCN_MEM_WRITE) != 0)
  1022. flags |= (1 << 1);
  1023. if ((outSection->mCharacteristics & IMAGE_SCN_MEM_EXECUTE) != 0)
  1024. flags |= (1 << 2);
  1025. mWriter.WriteT(flags);
  1026. mWriter.WriteT((int16)0); // Logical overlay number - ?
  1027. mWriter.WriteT((int16)0); // Group
  1028. mWriter.WriteT((int16)(outSection->mIdx + 1)); // Frame
  1029. mWriter.WriteT((int16)-1); // Section name string idx
  1030. mWriter.WriteT((int16)-1); // Class name string idx
  1031. mWriter.WriteT((int32)0); // Offset
  1032. mWriter.WriteT((int32)outSection->mVirtualSize); // SectionLength
  1033. }
  1034. int32 sectionMapSize = mWriter.GetStreamPos() - curPos;
  1035. //////////////////////////////////////////////////////////////////////////
  1036. // FileInfo
  1037. curPos = mWriter.GetStreamPos();
  1038. mWriter.WriteT((int16)mModuleInfo.size());
  1039. int numSourceFiles = 0;
  1040. for (auto module : mModuleInfo)
  1041. numSourceFiles += (int)module->mFileInfos.size();
  1042. mWriter.WriteT((int16)numSourceFiles); // NumSourceFiles - this is ignored now since it would only allow 64k files
  1043. // ModIndices
  1044. int curFileIdx = 0;
  1045. for (auto module : mModuleInfo)
  1046. {
  1047. mWriter.WriteT((int16)curFileIdx);
  1048. curFileIdx += (int)module->mFileInfos.size();
  1049. }
  1050. // ModFileCounts
  1051. for (auto module : mModuleInfo)
  1052. mWriter.WriteT((int16)module->mFileInfos.size());
  1053. int strIdx = 0;
  1054. for (auto module : mModuleInfo)
  1055. {
  1056. for (auto& cvFileInfo : module->mFileInfos)
  1057. {
  1058. char* str = (char*)mStrTab.c_str() + cvFileInfo.mStrTableIdx;
  1059. mWriter.WriteT((int32)strIdx);
  1060. strIdx += (int)strlen(str) + 1;
  1061. }
  1062. }
  1063. for (auto module : mModuleInfo)
  1064. {
  1065. for (auto& cvFileInfo : module->mFileInfos)
  1066. {
  1067. char* str = (char*)mStrTab.c_str() + cvFileInfo.mStrTableIdx;
  1068. mWriter.Write(str, (int)strlen(str) + 1);
  1069. }
  1070. }
  1071. mWriter.StreamAlign(4);
  1072. int32 fileInfoSize = mWriter.GetStreamPos() - curPos;
  1073. //////////////////////////////////////////////////////////////////////////
  1074. // Type Server
  1075. curPos = mWriter.GetStreamPos();
  1076. int typeServerSize = mWriter.GetStreamPos() - curPos;
  1077. //////////////////////////////////////////////////////////////////////////
  1078. // EC
  1079. curPos = mWriter.GetStreamPos();
  1080. String ecStrTab;
  1081. std::unordered_map<String, int> ecStrTabMap;
  1082. WriteStringTable(ecStrTab, ecStrTabMap);
  1083. int ecSize = mWriter.GetStreamPos() - curPos;
  1084. //////////////////////////////////////////////////////////////////////////
  1085. // Optional debug header
  1086. curPos = mWriter.GetStreamPos();
  1087. mWriter.WriteT((int16)-1); // fpo
  1088. mWriter.WriteT((int16)-1); // exception
  1089. mWriter.WriteT((int16)-1); // fixup
  1090. mWriter.WriteT((int16)-1); // omap_to_src
  1091. mWriter.WriteT((int16)-1); // omap_from_src
  1092. mWriter.WriteT((int16)sectionHeaderStreamIdx); // section_header
  1093. mWriter.WriteT((int16)-1); // token_rid_map
  1094. mWriter.WriteT((int16)-1); // x_data
  1095. mWriter.WriteT((int16)-1); // p_data
  1096. mWriter.WriteT((int16)-1); // new_fpo
  1097. mWriter.WriteT((int16)-1); // section_header_origin
  1098. int optionalDbgHeaderSize = mWriter.GetStreamPos() - curPos;
  1099. // Go back and fill in substream sizes
  1100. sizePtrs[0] = modInfoSize;
  1101. sizePtrs[1] = sectionContributionSize;
  1102. sizePtrs[2] = sectionMapSize;
  1103. sizePtrs[3] = fileInfoSize;
  1104. sizePtrs[4] = typeServerSize;
  1105. sizePtrs[5] = 0; // MFCTypeServerIndex
  1106. // Note: the position of the optionalDbgHeader and ecSize seem reversed, but this is correct
  1107. sizePtrs[6] = optionalDbgHeaderSize;
  1108. sizePtrs[7] = ecSize;
  1109. EndStream();
  1110. }
  1111. void BlCodeView::CreateNamesStream()
  1112. {
  1113. StartStream();
  1114. mWriter.mCurStream->mName = "/names";
  1115. WriteStringTable(mStrTab, mStrTabMap);
  1116. EndStream();
  1117. }
  1118. void BlCodeView::CreateLinkInfoStream()
  1119. {
  1120. StartStream();
  1121. mWriter.mCurStream->mName = "/LinkInfo";
  1122. EndStream();
  1123. }
  1124. void BlCodeView::CreateHeaderBlockStream()
  1125. {
  1126. StartStream();
  1127. mWriter.mCurStream->mName = "/src/headerblock";
  1128. EndStream();
  1129. }
  1130. bool BlCodeView::FixTPITag(BlCvModuleInfo* module, unsigned long& typeId)
  1131. {
  1132. if (typeId < 0x1000)
  1133. return true;
  1134. //BL_AUTOPERF_CV("BlCodeView::FixTPITag");
  1135. auto& tpi = module->mTypeSource->mTPI;
  1136. if (tpi.mCvMinTag == -1)
  1137. {
  1138. typeId = 0;
  1139. return false;
  1140. }
  1141. typeId = tpi.GetMasterTPITag(typeId);
  1142. return true;
  1143. }
  1144. bool BlCodeView::FixIPITag(BlCvModuleInfo* module, unsigned long& typeId)
  1145. {
  1146. if (typeId < 0x1000)
  1147. return true;
  1148. //BL_AUTOPERF_CV("BlCodeView::FixTPITag");
  1149. auto ipi = module->mTypeSource->mIPI;
  1150. int masterTag = ipi->GetMasterIPITag(typeId);
  1151. /*if ((masterTag & BlTypeMapFlag_InfoExt_ProcId_TypeOnly) != 0)
  1152. {
  1153. // Force loading of whole type now
  1154. module->mTypeSource->mIPI->ParseTag(typeId, true);
  1155. masterTag = ipi->GetMasterIPITag(typeId);
  1156. }
  1157. if ((masterTag & BlTypeMapFlag_InfoExt_ProcId_Resolved) != 0)
  1158. {
  1159. int extId = masterTag & BlTypeMapFlag_InfoExt_MASK;
  1160. masterTag = module->mTypeSource->mIPI->mInfoExts[extId].mMasterTag;
  1161. }*/
  1162. typeId = masterTag;
  1163. return true;
  1164. }
  1165. bool BlCodeView::FixIPITag_Member(BlCvModuleInfo* module, unsigned long& typeId)
  1166. {
  1167. if (typeId == 0)
  1168. return true;
  1169. //BL_AUTOPERF_CV("BlCodeView::FixIPITag");
  1170. auto ipi = module->mTypeSource->mIPI;
  1171. int memberTag = ipi->mElementMap[typeId - ipi->mCvMinTag];
  1172. BF_ASSERT(memberTag != -1);
  1173. typeId = memberTag;
  1174. /*typeId = ipi->GetMasterIPITag(typeId);
  1175. if ((typeId & BlTypeMapFlag_InfoExt_ProcId_TypeOnly) != 0)
  1176. typeId = typeId & BlTypeMapFlag_InfoExt_MASK;
  1177. else if ((typeId & BlTypeMapFlag_InfoExt_ProcId_Resolved) != 0)
  1178. {
  1179. int extId = typeId & BlTypeMapFlag_InfoExt_MASK;
  1180. typeId = module->mTypeSource->mIPI->mInfoExts[extId].mMemberMasterTag;
  1181. }
  1182. else
  1183. {
  1184. BF_FATAL("No member found");
  1185. }*/
  1186. return true;
  1187. }
  1188. void BlCodeView::CreateModuleStreamSyms(BlCvModuleInfo* module, BlCvSymDataBlock* dataBlock, int dataOfs)
  1189. {
  1190. //BL_AUTOPERF_CV("BlCodeView::CreateModuleStreamSyms");
  1191. int streamStartPos = mWriter.GetStreamPos();
  1192. #define DECL_SYM(symType, symName) \
  1193. symType& old_##symName = *(symType*)dataStart; \
  1194. symType& symName = *((symType*)(dataOut += sizeof(symType)) - 1); \
  1195. symName = old_##symName;
  1196. #define _FIX_SYM_ADDRESS(ofsName) \
  1197. FixSymAddress(sectionStart, &old_##ofsName, &ofsName, module, dataBlock, nextReloc)
  1198. #define FIX_SYM_ADDRESS(ofsName) \
  1199. _FixSymAddress(&old_##ofsName, &ofsName)
  1200. #define FIXTPI(typeVal) \
  1201. FixTPITag(module, typeVal)
  1202. #define FIXIPI(typeVal) \
  1203. FixIPITag(module, typeVal)
  1204. // For FIXTPI, if we fail to lookup type then we just don't include this symbol.
  1205. // This can happen when we have a TYPESERVER but don't have the referenced PDB
  1206. /*#define FIXTPI(typeVal) \
  1207. if (!FixType(module, typeVal)) \
  1208. { \
  1209. dataOut = dataOutStart; \
  1210. data = dataEnd; \
  1211. continue; \
  1212. }*/
  1213. COFFRelocation* nextReloc = dataBlock->mRelocStart;
  1214. int dataOutMaxSize = dataBlock->mSize * 2; // Alignment may add size
  1215. //uint8* dataOut = new uint8[dataOutMaxSize];
  1216. //uint8* dataOutHead = dataOut;
  1217. //uint8* dataOutMax = dataOut + dataOutMaxSize;
  1218. const static int MAX_BLOCK_DEPTH = 256;
  1219. int blockIdx = 0;
  1220. //int blockPositions[MAX_BLOCK_DEPTH];
  1221. int blockPtrs[MAX_BLOCK_DEPTH];
  1222. const char* lastProcName = NULL;
  1223. int curStreamPos = streamStartPos;
  1224. int streamDataOfs = -streamStartPos + dataOfs;
  1225. static int procId = 0;
  1226. uint8* data = (uint8*)dataBlock->mData;
  1227. uint8* sectionStart = data;
  1228. uint8* sectionEnd = data + dataBlock->mSize;
  1229. uint8 dataChunk[0x10000];
  1230. auto _SkipSymAddress = [&](void* oldDataPos, void* outDataPos)
  1231. {
  1232. int posOfs = (int)((uint8*)oldDataPos - (uint8*)sectionStart) + dataBlock->mSourceSectOffset;
  1233. int posSect = posOfs + 4;
  1234. if ((nextReloc->mVirtualAddress != posOfs) || (nextReloc == dataBlock->mRelocEnd))
  1235. return;
  1236. nextReloc++;
  1237. if (nextReloc->mVirtualAddress != posSect)
  1238. Fail("Symbol remap failure");
  1239. // It MUST be the same sym
  1240. nextReloc++;
  1241. };
  1242. int deferredOutIdx = -1;
  1243. bool addrIsInvalid = false;
  1244. auto _FixSymAddress = [&](void* oldDataPos, void* outDataPos)
  1245. {
  1246. int posOfs = (int)((uint8*)oldDataPos - (uint8*)sectionStart) + dataBlock->mSourceSectOffset;
  1247. int posSect = posOfs + 4;
  1248. if ((nextReloc->mVirtualAddress != posOfs) || (nextReloc == dataBlock->mRelocEnd))
  1249. return;
  1250. auto objSym = &module->mSymInfo[nextReloc->mSymbolTableIndex];
  1251. int segmentIdx = -1;
  1252. int segmentOffset = -1;
  1253. if (objSym->mKind == BlObjectDataSymInfo::Kind_Section)
  1254. {
  1255. auto& sectInfo = module->mSectInfos[objSym->mSectionNum - 1];
  1256. segmentIdx = sectInfo.mSegmentIdx;
  1257. segmentOffset = sectInfo.mSegmentOffset;
  1258. }
  1259. else
  1260. {
  1261. segmentIdx = objSym->mSegmentIdx;
  1262. segmentOffset = objSym->mSegmentOffset;
  1263. }
  1264. if (segmentIdx != -1)
  1265. {
  1266. auto segment = mContext->mSegments[segmentIdx];
  1267. bool deferAddr = true;
  1268. if (deferAddr)
  1269. {
  1270. int outOfs = (int)((uint8*)outDataPos - dataChunk);
  1271. deferredOutIdx = curStreamPos + outOfs;
  1272. *(int32*)(outDataPos) += segmentOffset;
  1273. *((int16*)outDataPos + 2) += segmentIdx;
  1274. }
  1275. else
  1276. {
  1277. auto outSection = mContext->mOutSections[segment->mOutSectionIdx];
  1278. *(int32*)(outDataPos) += (segment->mRVA - outSection->mRVA) + segmentOffset;
  1279. *((int16*)outDataPos + 2) += outSection->mIdx + 1;
  1280. }
  1281. }
  1282. else
  1283. {
  1284. addrIsInvalid = true;
  1285. }
  1286. nextReloc++;
  1287. if (nextReloc->mVirtualAddress != posSect)
  1288. Fail("Symbol remap failure");
  1289. // It MUST be the same sym
  1290. nextReloc++;
  1291. };
  1292. while (data < sectionEnd)
  1293. {
  1294. int symLen;
  1295. int symType;
  1296. uint8* dataOut = dataChunk;
  1297. uint8* dataStart = data;
  1298. uint8* dataOutStart = dataChunk;
  1299. uint8* dataEnd;
  1300. uint8* dataOutEnd;
  1301. symLen = GET(uint16);
  1302. dataEnd = data + symLen;
  1303. dataOutEnd = dataChunk + symLen + 2;
  1304. symType = GET(uint16);
  1305. bool skipEntry = false;
  1306. const char* globalsName = NULL;
  1307. bool isProcRef = false;
  1308. deferredOutIdx = -1;
  1309. addrIsInvalid = false;
  1310. switch (symType)
  1311. {
  1312. case S_OBJNAME:
  1313. {
  1314. DECL_SYM(OBJNAMESYM, objNameSym);
  1315. }
  1316. break;
  1317. case S_COMPILE3:
  1318. {
  1319. DECL_SYM(COMPILESYM3, compileSym);
  1320. }
  1321. break;
  1322. case S_ENVBLOCK:
  1323. {
  1324. DECL_SYM(ENVBLOCKSYM, envBlock);
  1325. }
  1326. break;
  1327. case S_BUILDINFO:
  1328. {
  1329. BUILDINFOSYM& buildInfoSym = *(BUILDINFOSYM*)dataStart;
  1330. skipEntry = true;
  1331. }
  1332. break;
  1333. case S_CONSTANT:
  1334. {
  1335. struct _ConstSymShort
  1336. {
  1337. unsigned short reclen; // Record length
  1338. unsigned short rectyp; // S_CONSTANT or S_MANCONSTANT
  1339. CV_typ_t typind; // Type index (containing enum if enumerate) or metadata token
  1340. };
  1341. CONSTSYM& oldConstSym = *(CONSTSYM*)dataStart;
  1342. globalsName = (char*)oldConstSym.name;
  1343. DECL_SYM(_ConstSymShort, constSym);
  1344. FIXTPI(constSym.typind);
  1345. skipEntry = true;
  1346. }
  1347. break;
  1348. case S_UDT:
  1349. {
  1350. DECL_SYM(UDTSYM, udtSym);
  1351. FIXTPI(udtSym.typind);
  1352. //TODO: JUST TESTING!
  1353. //udtSym.typind = 0x0074;
  1354. globalsName = (const char*)udtSym.name;
  1355. skipEntry = true;
  1356. }
  1357. break;
  1358. case S_LDATA32:
  1359. case S_GDATA32:
  1360. {
  1361. DECL_SYM(DATASYM32, dataSym);
  1362. FIX_SYM_ADDRESS(dataSym.off);
  1363. FIXTPI(dataSym.typind);
  1364. globalsName = (char*)old_dataSym.name;
  1365. skipEntry = true;
  1366. }
  1367. break;
  1368. case S_GTHREAD32:
  1369. case S_LTHREAD32:
  1370. {
  1371. DECL_SYM(THREADSYM32, threadSym);
  1372. FIX_SYM_ADDRESS(threadSym.off);
  1373. FIXTPI(threadSym.typind);
  1374. globalsName = (char*)old_threadSym.name;
  1375. skipEntry = true;
  1376. }
  1377. break;
  1378. case S_EXPORT:
  1379. {
  1380. EXPORTSYM& exportSym = *(EXPORTSYM*)dataStart;
  1381. }
  1382. break;
  1383. case S_LPROC32:
  1384. case S_GPROC32:
  1385. {
  1386. DECL_SYM(PROCSYM32, procSym);
  1387. FIX_SYM_ADDRESS(procSym.off);
  1388. FIXTPI(procSym.typind);
  1389. blockPtrs[blockIdx++] = curStreamPos;
  1390. globalsName = (const char*)old_procSym.name;
  1391. isProcRef = true;
  1392. }
  1393. break;
  1394. case S_LPROC32_ID:
  1395. case S_GPROC32_ID:
  1396. {
  1397. DECL_SYM(PROCSYM32, procSym);
  1398. FIX_SYM_ADDRESS(procSym.off);
  1399. lastProcName = (char*)old_procSym.name;
  1400. FixIPITag_Member(module, procSym.typind);
  1401. if (!addrIsInvalid)
  1402. blockPtrs[blockIdx++] = curStreamPos;
  1403. globalsName = (const char*)old_procSym.name;
  1404. isProcRef = true;
  1405. if (symType == S_LPROC32_ID)
  1406. procSym.rectyp = S_LPROC32;
  1407. else
  1408. procSym.rectyp = S_GPROC32;
  1409. }
  1410. break;
  1411. case S_FRAMEPROC:
  1412. {
  1413. //DECL_SYM(FRAMEPROCSYM, frameProc);
  1414. //FixSymAddress(&frameProc.);
  1415. }
  1416. break;
  1417. case S_THUNK32:
  1418. {
  1419. DECL_SYM(THUNKSYM32, thunkSym);
  1420. FIX_SYM_ADDRESS(thunkSym.off);
  1421. lastProcName = (char*)old_thunkSym.name;
  1422. blockPtrs[blockIdx++] = curStreamPos;
  1423. }
  1424. break;
  1425. case S_BLOCK32:
  1426. {
  1427. DECL_SYM(BLOCKSYM32, blockSym);
  1428. FIX_SYM_ADDRESS(blockSym.off);
  1429. if (blockIdx > 0)
  1430. blockSym.pParent = blockPtrs[blockIdx - 1] + streamDataOfs;
  1431. blockPtrs[blockIdx++] = curStreamPos;
  1432. }
  1433. break;
  1434. case S_LOCAL:
  1435. {
  1436. DECL_SYM(LOCALSYM, localSym);
  1437. FIXTPI(localSym.typind);
  1438. }
  1439. break;
  1440. case S_BPREL32:
  1441. {
  1442. DECL_SYM(BPRELSYM32, bpRel32);
  1443. FIXTPI(bpRel32.typind);
  1444. }
  1445. break;
  1446. case S_REGISTER:
  1447. {
  1448. DECL_SYM(REGSYM, regSym);
  1449. FIXTPI(regSym.typind);
  1450. }
  1451. break;
  1452. case S_REGREL32:
  1453. {
  1454. DECL_SYM(REGREL32, regRel32);
  1455. FIXTPI(regRel32.typind);
  1456. }
  1457. break;
  1458. case S_DEFRANGE_REGISTER:
  1459. {
  1460. DECL_SYM(DEFRANGESYMREGISTER, defRangeReg);
  1461. FIX_SYM_ADDRESS(defRangeReg.range.offStart);
  1462. }
  1463. break;
  1464. case S_DEFRANGE_FRAMEPOINTER_REL:
  1465. {
  1466. DECL_SYM(DEFRANGESYMFRAMEPOINTERREL, defRangeFPRel);
  1467. FIX_SYM_ADDRESS(defRangeFPRel.range.offStart);
  1468. }
  1469. break;
  1470. case S_DEFRANGE_SUBFIELD_REGISTER:
  1471. {
  1472. DECL_SYM(DEFRANGESYMSUBFIELDREGISTER, defRangeSubFieldReg);
  1473. FIX_SYM_ADDRESS(defRangeSubFieldReg.range.offStart);
  1474. }
  1475. break;
  1476. case S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE:
  1477. {
  1478. DECL_SYM(DEFRANGESYMFRAMEPOINTERREL_FULL_SCOPE, defRangeFPRel);
  1479. }
  1480. break;
  1481. case S_DEFRANGE_REGISTER_REL:
  1482. {
  1483. DECL_SYM(DEFRANGESYMREGISTERREL, defRangeRegRel);
  1484. FIX_SYM_ADDRESS(defRangeRegRel.range.offStart);
  1485. }
  1486. break;
  1487. case S_ENDARG:
  1488. //BF_ASSERT(curParam == NULL);
  1489. break;
  1490. case S_PROC_ID_END:
  1491. {
  1492. struct _ENDSYM
  1493. {
  1494. unsigned short reclen;
  1495. unsigned short rectyp;
  1496. };
  1497. DECL_SYM(_ENDSYM, endSym);
  1498. endSym.rectyp = S_END;
  1499. }
  1500. // Fall through
  1501. case S_INLINESITE_END:
  1502. // Fall through
  1503. case S_END:
  1504. {
  1505. if (blockIdx == 0)
  1506. {
  1507. // Parent was omitted
  1508. skipEntry = true;
  1509. }
  1510. else
  1511. {
  1512. /*struct _SRCSYM // Either a BLOCKSYM32, PROCSYM32, WITHSYM32...
  1513. {
  1514. unsigned short reclen; // Record length
  1515. unsigned short rectyp; // S_BLOCK32
  1516. unsigned long pParent; // pointer to the parent
  1517. unsigned long pEnd; // pointer to this blocks end
  1518. };*/
  1519. long* pEnd = (long*)mWriter.GetStreamPtr(blockPtrs[--blockIdx] + 8);
  1520. BF_ASSERT(*pEnd == 0);
  1521. *pEnd = curStreamPos + streamDataOfs;
  1522. }
  1523. }
  1524. break;
  1525. case S_FRAMECOOKIE:
  1526. {
  1527. FRAMECOOKIE& frameCookie = *(FRAMECOOKIE*)dataStart;
  1528. }
  1529. break;
  1530. case S_LABEL32:
  1531. {
  1532. DECL_SYM(LABELSYM32, labelSym);
  1533. FIX_SYM_ADDRESS(labelSym.off);
  1534. }
  1535. break;
  1536. case S_CALLSITEINFO:
  1537. {
  1538. DECL_SYM(CALLSITEINFO, callSiteInfo);
  1539. FIX_SYM_ADDRESS(callSiteInfo.off);
  1540. FIXTPI(callSiteInfo.typind);
  1541. }
  1542. break;
  1543. case S_HEAPALLOCSITE:
  1544. {
  1545. DECL_SYM(HEAPALLOCSITE, heapAllocSite);
  1546. FIX_SYM_ADDRESS(heapAllocSite.off);
  1547. FIXTPI(heapAllocSite.typind);
  1548. }
  1549. break;
  1550. case S_FILESTATIC:
  1551. {
  1552. DECL_SYM(FILESTATICSYM, fileStaticSym);
  1553. FIXTPI(fileStaticSym.typind);
  1554. }
  1555. break;
  1556. case S_CALLEES:
  1557. {
  1558. DECL_SYM(FUNCTIONLIST, calleeList);
  1559. for (int i = 0; i < (int)calleeList.count; i++)
  1560. {
  1561. calleeList.funcs[i] = old_calleeList.funcs[i];
  1562. FIXTPI(calleeList.funcs[i]);
  1563. }
  1564. dataOut = (uint8*)(&calleeList.funcs[calleeList.count]);
  1565. }
  1566. break;
  1567. case S_CALLERS:
  1568. {
  1569. DECL_SYM(FUNCTIONLIST, callerList);
  1570. for (int i = 0; i < (int)callerList.count; i++)
  1571. {
  1572. callerList.funcs[i] = old_callerList.funcs[i];
  1573. FIXTPI(callerList.funcs[i]);
  1574. }
  1575. dataOut = (uint8*)(&callerList.funcs[callerList.count]);
  1576. }
  1577. break;
  1578. case S_POGODATA:
  1579. {
  1580. DECL_SYM(POGOINFO, pogoInfo);
  1581. }
  1582. break;
  1583. case S_INLINESITE:
  1584. {
  1585. DECL_SYM(INLINESITESYM, inlineSite);
  1586. FIXIPI(inlineSite.inlinee);
  1587. if (blockIdx > 0)
  1588. inlineSite.pParent = blockPtrs[blockIdx - 1] + streamDataOfs;
  1589. blockPtrs[blockIdx++] = curStreamPos;
  1590. }
  1591. break;
  1592. case S_ANNOTATION:
  1593. {
  1594. DECL_SYM(ANNOTATIONSYM, annotation);
  1595. FIX_SYM_ADDRESS(annotation.off);
  1596. }
  1597. break;
  1598. case S_TRAMPOLINE:
  1599. break;
  1600. case S_COFFGROUP:
  1601. {
  1602. DECL_SYM(COFFGROUPSYM, coffGroup);
  1603. FIX_SYM_ADDRESS(coffGroup.off);
  1604. }
  1605. break;
  1606. case S_SECTION:
  1607. NotImpl();
  1608. break;
  1609. case S_SSEARCH:
  1610. {
  1611. SEARCHSYM* searchSym = (SEARCHSYM*)dataStart;
  1612. }
  1613. break;
  1614. default:
  1615. NotImpl();
  1616. break;
  1617. }
  1618. data = dataEnd;
  1619. if (addrIsInvalid)
  1620. {
  1621. dataOut = dataOutStart;
  1622. continue;
  1623. }
  1624. if (dataOut < dataOutEnd)
  1625. {
  1626. //BL_AUTOPERF_CV("BlCodeView::CreateModuleStreamSyms EndCopy");
  1627. int copyBytes = (int)(dataOutEnd - dataOut);
  1628. memcpy(dataOut, data - copyBytes, copyBytes);
  1629. dataOut = dataOutEnd;
  1630. }
  1631. bool writeToSymRecord = false;
  1632. if (globalsName != NULL)
  1633. {
  1634. // We only include the first instance of each name
  1635. int idx;
  1636. Val128 hashVal;
  1637. hashVal = Hash128(globalsName, (int)strlen(globalsName));
  1638. idx = mGlobals.TryInsert(globalsName, hashVal);
  1639. //idx = -1;
  1640. if (idx >= 0)
  1641. {
  1642. if (isProcRef)
  1643. {
  1644. //BL_AUTOPERF_CV("BlCodeView::CreateModuleStreamSyms ProcRef");
  1645. int nameSize = (int)strlen(globalsName) + 1;
  1646. REFSYM2 refSym = { 0 };
  1647. refSym.reclen = (int)offsetof(REFSYM2, name) + nameSize - 2;
  1648. refSym.rectyp = S_PROCREF;
  1649. refSym.imod = module->mIdx + 1;
  1650. refSym.ibSym = curStreamPos + streamDataOfs;
  1651. int addBytes = ((nameSize + 2 + 3) & ~3) - (nameSize + 2);
  1652. refSym.reclen += addBytes;
  1653. //if (deferredOutIdx >= 0)
  1654. //mSymRecordDeferredPositions.Append((int)mSymRecordsWriter.GetStreamPos());
  1655. mSymRecordsWriter.Write(&refSym, (int)offsetof(REFSYM2, name));
  1656. mSymRecordsWriter.Write(globalsName, nameSize);
  1657. if (addBytes > 0)
  1658. {
  1659. int zero = 0;
  1660. mSymRecordsWriter.Write(&zero, addBytes);
  1661. }
  1662. }
  1663. else
  1664. {
  1665. writeToSymRecord = true;
  1666. }
  1667. }
  1668. /*auto pair = mGlobals.mMap.insert(hashVal);
  1669. if (pair.second)
  1670. {
  1671. int idx = mSymRecords.GetSize();
  1672. mGlobals.mRecordIndices.Append(idx);
  1673. mSymRecords.Write(dataOutStart, (int)(dataOutEnd - dataOutStart));
  1674. }*/
  1675. }
  1676. if ((skipEntry) && (!writeToSymRecord))
  1677. {
  1678. dataOut = dataOutStart;
  1679. continue;
  1680. }
  1681. // Align
  1682. if ((intptr)dataOut % 4 != 0)
  1683. {
  1684. //BL_AUTOPERF_CV("BlCodeView::CreateModuleStreamSyms Finish");
  1685. dataOutEnd = (uint8*)(((intptr)dataOut + 3) & ~3);
  1686. int addBytes = (int)(dataOutEnd - dataOut);
  1687. if (addBytes > 0)
  1688. {
  1689. *(int32*)(dataOut) = 0;
  1690. // Add to length
  1691. *(int16*)dataOutStart += (int16)addBytes;
  1692. }
  1693. dataOut = dataOutEnd;
  1694. }
  1695. if (writeToSymRecord)
  1696. {
  1697. //BL_AUTOPERF_CV("BlCodeView::CreateModuleStreamSyms WriteToSymRecord");
  1698. if (deferredOutIdx >= 0)
  1699. mSymRecordDeferredPositions.push_back((int)mSymRecordsWriter.GetStreamPos());
  1700. mSymRecordsWriter.Write(dataOutStart, (int)(dataOutEnd - dataOutStart));
  1701. }
  1702. if (skipEntry)
  1703. {
  1704. //dataOut = dataOutStart;
  1705. continue;
  1706. }
  1707. if (deferredOutIdx != -1)
  1708. {
  1709. mDeferedSegOffsets.push_back(deferredOutIdx);
  1710. module->mDeferredSegOfsLen++;
  1711. }
  1712. int dataSize = (int)(dataOutEnd - dataOutStart);
  1713. mWriter.Write(dataOutStart, dataSize);
  1714. curStreamPos += dataSize;
  1715. BF_ASSERT(curStreamPos == mWriter.GetStreamPos());
  1716. //BF_ASSERT(dataOut < dataOutMax);
  1717. }
  1718. BF_ASSERT(nextReloc == dataBlock->mRelocEnd);
  1719. BF_ASSERT(blockIdx == 0);
  1720. //int outSize = (int)(dataOut - dataOutHead);
  1721. dataBlock->mOutSize = mWriter.GetStreamPos() - streamStartPos;
  1722. {
  1723. //BL_AUTOPERF_CV("BlCodeView::CreateModuleStreamSyms Write");
  1724. //mWriter.Write(dataOutHead, outSize);
  1725. }
  1726. //delete [] dataOutHead;
  1727. }
  1728. void BlCodeView::CreateLinkerSymStream()
  1729. {
  1730. #define SALIGN(recLen) recLen = ((recLen + 2 + 3) & ~3) - 2;
  1731. #define OUT_WITH_STR(typeName, recName, nameMember) \
  1732. symLen = (int)offsetof(typeName, nameMember); \
  1733. recName.reclen = (symLen - 2) + (int)str.length() + 1; \
  1734. SALIGN(recName.reclen); \
  1735. mWriter.Write(&recName, symLen); \
  1736. mWriter.Write((void*)str.c_str(), (int)str.length() + 1); \
  1737. mWriter.StreamAlign(4);
  1738. String str;
  1739. int symLen;
  1740. OBJNAMESYM objNameSym = { 0 };
  1741. objNameSym.rectyp = S_OBJNAME;
  1742. str = "* Linker *";
  1743. OUT_WITH_STR(OBJNAMESYM, objNameSym, name);
  1744. COMPILESYM3 compileSym = { 0 };
  1745. compileSym.rectyp = S_COMPILE3;
  1746. compileSym.flags.iLanguage = 7; // Link
  1747. compileSym.machine = 0xD0;
  1748. compileSym.verMajor = 14;
  1749. compileSym.verMinor = 0;
  1750. compileSym.verFEBuild = 24215;
  1751. compileSym.verQFE = 1;
  1752. str = "Microsoft (R) Link";
  1753. OUT_WITH_STR(COMPILESYM3, compileSym, verSz);
  1754. char cwd[MAX_PATH];
  1755. _getcwd(cwd, MAX_PATH);
  1756. char moduleFileName[MAX_PATH];
  1757. GetModuleFileNameA(NULL, moduleFileName, MAX_PATH);
  1758. ENVBLOCKSYM envBlock = { 0 };
  1759. envBlock.rectyp = S_ENVBLOCK;
  1760. str = "cwd"; str.Append('\0');
  1761. str += cwd; str.Append('\0');
  1762. str += "exe"; str.Append('\0');
  1763. str += moduleFileName; str.Append('\0');
  1764. str += "pdb"; str.Append('\0');
  1765. str += mMsf.mFileName; str.Append('\0');
  1766. str += "cmd"; str.Append('\0');
  1767. str += GetCommandLineA(); str.Append('\0');
  1768. OUT_WITH_STR(ENVBLOCKSYM, envBlock, rgsz);
  1769. for (auto segment : mContext->mSegments)
  1770. {
  1771. auto outSection = mContext->mOutSections[segment->mOutSectionIdx];
  1772. COFFGROUPSYM coffGroupSym = { 0 };
  1773. coffGroupSym.rectyp = S_COFFGROUP;
  1774. coffGroupSym.seg = segment->mOutSectionIdx + 1;
  1775. coffGroupSym.off = (int)(segment->mRVA - outSection->mRVA);
  1776. coffGroupSym.characteristics = segment->mCharacteristics;
  1777. coffGroupSym.cb = segment->mCurSize;
  1778. str = segment->mName;
  1779. OUT_WITH_STR(COFFGROUPSYM, coffGroupSym, name);
  1780. }
  1781. for (auto outSection : mContext->mOutSections)
  1782. {
  1783. SECTIONSYM sectionSym = { 0 };
  1784. sectionSym.rectyp = S_SECTION;
  1785. sectionSym.rva = outSection->mRVA;
  1786. sectionSym.align = outSection->mAlign;
  1787. sectionSym.isec = outSection->mIdx + 1;
  1788. sectionSym.characteristics = outSection->mCharacteristics;
  1789. sectionSym.cb = outSection->mRawSize;
  1790. str = outSection->mName;
  1791. OUT_WITH_STR(SECTIONSYM, sectionSym, name);
  1792. }
  1793. }
  1794. bool BlCodeView::OnlyHasSimpleRelocs(BlCvModuleInfo* module)
  1795. {
  1796. /*for (auto& block : module->mSymData)
  1797. {
  1798. for (COFFRelocation* coffReloc = block.mRelocStart; coffReloc < block.mRelocEnd; coffReloc++)
  1799. {
  1800. auto& symInfo = module->mSymInfo[coffReloc->mSymbolTableIndex];
  1801. if (symInfo.mSegmentIdx < 0)
  1802. return false;
  1803. if (symInfo.mSegmentIdx >= mContext->mNumFixedSegs)
  1804. {
  1805. auto seg = mContext->mSegments[symInfo.mSegmentIdx];
  1806. OutputDebugStrF("Failed on: %s in %s\n", seg->mName.c_str(), module->mObjectData->mName);
  1807. return false;
  1808. }
  1809. }
  1810. }*/
  1811. return true;
  1812. }
  1813. void BlCodeView::CreateModuleStream(BlCvModuleInfo* module)
  1814. {
  1815. BP_ZONE("BlCodeView::CreateModuleStream");
  1816. //BL_AUTOPERF_CV("BlCodeView::CreateModuleStream");
  1817. //OutputDebugStrF("CreateModuleStream %d\n", module->mIdx);
  1818. //
  1819. {
  1820. BP_ZONE("BlCodeView::CreateModuleStream WaitForDoneSignal");
  1821. /*if (module->mTypeSource != NULL)
  1822. module->mTypeSource->mDoneSignal.WaitFor();*/
  1823. }
  1824. if (mContext->mFailed)
  1825. return;
  1826. module->mSymStreamIdx = StartStream();
  1827. mWriter.WriteT((int32)CV_SIGNATURE_C13);
  1828. //int startPos = mWriter.GetStreamPos();
  1829. if (module->mObjectData == NULL)
  1830. {
  1831. int startSize = mWriter.GetStreamPos();
  1832. if (module->mName == "* Linker *")
  1833. CreateLinkerSymStream();
  1834. BlCvSymDataBlock data = { 0 };
  1835. data.mOutSize = mWriter.GetStreamPos() - startSize;
  1836. module->mSymData.push_back(data);
  1837. }
  1838. else
  1839. {
  1840. int dataOfs = 4;
  1841. /*const char* invalidStrs[] = { "delete_scalar", "new_scalar" };
  1842. for (const char* invalidStr : invalidStrs)
  1843. {
  1844. //TODO:
  1845. if (strstr(module->mObjectData->mName, invalidStr) != NULL)
  1846. {
  1847. module->mSymData.clear();
  1848. module->mLineInfo.clear();
  1849. module->mFileInfos.clear();
  1850. break;
  1851. }
  1852. }*/
  1853. {
  1854. BL_AUTOPERF_CV("BlCodeView::CreateModuleStream CreateModuleStreamSyms");
  1855. module->mDeferredSegOfsStart = (int)mDeferedSegOffsets.size();
  1856. for (auto& block : module->mSymData)
  1857. {
  1858. CreateModuleStreamSyms(module, &block, dataOfs);
  1859. dataOfs += block.mOutSize;
  1860. }
  1861. }
  1862. }
  1863. //mFS.Align(4);
  1864. // TODO: Write symbol data...
  1865. //module->mSymSize = mWriter.GetStreamPos() - startPos;
  1866. if (!module->mFileInfos.empty())
  1867. {
  1868. int sectStart = mWriter.GetStreamPos();
  1869. StartSection(DEBUG_S_FILECHKSMS);
  1870. for (auto& fileInfo : module->mFileInfos)
  1871. {
  1872. struct _CVFileInfo
  1873. {
  1874. int32 mFileTabOfs;
  1875. int8 mHashLen;
  1876. int8 mHashType;
  1877. uint8 mHash[16];
  1878. uint16 mPadding;
  1879. };
  1880. BF_ASSERT(fileInfo.mChksumOfs == (mWriter.GetStreamPos() - sectStart) - 8);
  1881. _CVFileInfo cvFileInfo;
  1882. cvFileInfo.mFileTabOfs = fileInfo.mStrTableIdx;
  1883. if (fileInfo.mHashType == 1)
  1884. {
  1885. cvFileInfo.mHashLen = 16;
  1886. cvFileInfo.mHashType = 1; //MD5
  1887. memcpy(cvFileInfo.mHash, fileInfo.mHash, 16);
  1888. mWriter.WriteT(cvFileInfo);
  1889. }
  1890. else
  1891. {
  1892. cvFileInfo.mHashLen = 0;
  1893. cvFileInfo.mHashType = 0;
  1894. cvFileInfo.mHash[0] = 0; // Padding
  1895. cvFileInfo.mHash[1] = 0;
  1896. mWriter.Write(&cvFileInfo, 8);
  1897. }
  1898. }
  1899. module->mLineInfoSize += EndSection();
  1900. }
  1901. for (auto lineInfo : module->mLineInfo)
  1902. {
  1903. StartSection(DEBUG_S_LINES);
  1904. CV_DebugSLinesHeader_t lineSect = { 0 };
  1905. lineSect.flags = 0;
  1906. if (!lineInfo->mLineInfoBlocks.empty())
  1907. {
  1908. if (!lineInfo->mLineInfoBlocks[0].mColumns.empty())
  1909. lineSect.flags |= CV_LINES_HAVE_COLUMNS;
  1910. }
  1911. //GetOutSectionAddr(lineInfo->mStartSegmentIdx, lineInfo->mStartSegmentOffset, lineSect.segCon, lineSect.offCon);
  1912. lineSect.segCon = lineInfo->mStartSegmentIdx;
  1913. lineSect.offCon = lineInfo->mStartSegmentOffset;
  1914. mDeferedSegOffsets.push_back(mWriter.GetStreamPos());
  1915. module->mDeferredSegOfsLen++;
  1916. lineSect.cbCon = lineInfo->mContribBytes;
  1917. mWriter.WriteT(lineSect);
  1918. for (auto& lineBlocks : lineInfo->mLineInfoBlocks)
  1919. {
  1920. //TODO: Ensure cbBlock is correct
  1921. CV_DebugSLinesFileBlockHeader_t lineBlockHeader = { 0 };
  1922. lineBlockHeader.cbBlock = (int)sizeof(CV_DebugSLinesFileBlockHeader_t) + (int)(lineBlocks.mLines.size() * sizeof(CV_Line_t));
  1923. lineBlockHeader.cbBlock += (int)(lineBlocks.mColumns.size() * sizeof(int16) * 2);
  1924. lineBlockHeader.nLines = (int)lineBlocks.mLines.size();
  1925. //int bytesPerFile = 24;
  1926. //lineBlockHeader.offFile = lineBlocks.mFileInfoIdx * bytesPerFile;
  1927. auto fileInfo = module->mFileInfos[lineBlocks.mFileInfoIdx];
  1928. lineBlockHeader.offFile = fileInfo.mChksumOfs;
  1929. mWriter.WriteT(lineBlockHeader);
  1930. for (auto& line : lineBlocks.mLines)
  1931. {
  1932. CV_Line_t cvLineData;
  1933. cvLineData.offset = line.mOffset;
  1934. cvLineData.linenumStart = line.mLineNumStart;
  1935. cvLineData.fStatement = 0;
  1936. cvLineData.deltaLineEnd = 0;
  1937. mWriter.WriteT(cvLineData);
  1938. }
  1939. for (auto column : lineBlocks.mColumns)
  1940. {
  1941. int16 colVals[2] = { column, column };
  1942. mWriter.WriteT(colVals);
  1943. }
  1944. }
  1945. module->mLineInfoSize += EndSection();
  1946. }
  1947. for (auto& inlineData : module->mInlineData)
  1948. {
  1949. StartSection(DEBUG_S_INLINEELINES);
  1950. uint8* data = (uint8*)inlineData.mData;
  1951. uint8* dataEnd = data + inlineData.mSize;
  1952. int linesType = GET(int);
  1953. mWriter.WriteT(linesType);
  1954. BF_ASSERT(linesType == 0);
  1955. while (data < dataEnd)
  1956. {
  1957. CodeViewInfo::InlineeSourceLine lineInfo = GET(CodeViewInfo::InlineeSourceLine);
  1958. FixIPITag(module, lineInfo.inlinee);
  1959. mWriter.WriteT(lineInfo);
  1960. }
  1961. module->mLineInfoSize += EndSection();
  1962. }
  1963. mWriter.WriteT(0); // GlobalRefsSize
  1964. bool flushNow = module->mDeferredSegOfsLen == 0;
  1965. EndStream(flushNow);
  1966. }
  1967. void BlCodeView::FinishModuleStream(BlCvModuleInfo* module)
  1968. {
  1969. BP_ZONE("BlCodeView::FinishModuleStream");
  1970. auto streamInfo = mStreams[module->mSymStreamIdx];
  1971. auto fixItr = mDeferedSegOffsets.GetIterator(module->mDeferredSegOfsStart);
  1972. for (int deferIdx = 0; deferIdx < module->mDeferredSegOfsLen; deferIdx++)
  1973. {
  1974. int deferredIdx = *fixItr;
  1975. int dataIdx = deferredIdx;
  1976. int blockIdx = streamInfo->mBlocks[dataIdx / CV_BLOCK_SIZE];
  1977. uint8* data = (uint8*)mMsf.mBlocks[blockIdx]->mData + (dataIdx % CV_BLOCK_SIZE);
  1978. int32* ofsPtr = (int32*)data;
  1979. dataIdx = deferredIdx + 4;
  1980. blockIdx = streamInfo->mBlocks[dataIdx / CV_BLOCK_SIZE];
  1981. data = (uint8*)mMsf.mBlocks[blockIdx]->mData + (dataIdx % CV_BLOCK_SIZE);
  1982. int16* segPtr = (int16*)data;
  1983. auto segment = mContext->mSegments[*segPtr];
  1984. auto outSection = mContext->mOutSections[segment->mOutSectionIdx];
  1985. *ofsPtr += segment->mRVA - outSection->mRVA;
  1986. *segPtr = outSection->mIdx + 1;
  1987. ++fixItr;
  1988. }
  1989. FlushStream(streamInfo);
  1990. }
  1991. void BlCodeView::CreateLinkerModule()
  1992. {
  1993. auto module = mModuleInfo.Alloc();
  1994. module->mName = "* Linker *";
  1995. module->mIdx = (int)mModuleInfo.size() - 1;
  1996. }
  1997. void BlCodeView::DoFinish()
  1998. {
  1999. //TODO:
  2000. //StopWorkThread();
  2001. int simpleRelocCount = 0;
  2002. for (auto module : mModuleInfo)
  2003. {
  2004. if (module->mSymStreamIdx == -1)
  2005. {
  2006. //simpleRelocCount += OnlyHasSimpleRelocs(module);
  2007. CreateModuleStream(module);
  2008. }
  2009. if (module->mDeferredSegOfsLen > 0)
  2010. {
  2011. FinishModuleStream(module);
  2012. }
  2013. }
  2014. /*for (auto module : mModuleInfo)
  2015. {
  2016. String dbgStr = StrFormat("Module #%d:", module->mIdx);
  2017. for (auto block : mStreams[module->mSymStreamIdx]->mBlocks)
  2018. {
  2019. dbgStr += StrFormat(" %d", block);
  2020. }
  2021. dbgStr += "\n";
  2022. OutputDebugStringA(dbgStr.c_str());
  2023. }*/
  2024. //StopWorkThread();
  2025. if (mContext->mFailed)
  2026. {
  2027. // We can't continue if any types may have failed
  2028. return;
  2029. }
  2030. CreateDBIStream();
  2031. // CreateDBIStream does CreateGlobalsStream/CreatePublicsStream, so the symRecords
  2032. // aren't done until after that
  2033. FinishSymRecords();
  2034. CreateTypeStream();
  2035. CreateIPIStream();
  2036. CreateNamesStream();
  2037. CreateLinkInfoStream();
  2038. CreateHeaderBlockStream();
  2039. CreatePDBInfoStream();
  2040. // Stream dir
  2041. //int streamDirLoc = mMSF.Alloc();
  2042. BlCVStream dirStream;
  2043. StartUnnamedStream(dirStream);
  2044. mWriter.WriteT((int32)mStreams.size());
  2045. for (auto& stream : mStreams)
  2046. {
  2047. BF_ASSERT(stream->mSize >= 0);
  2048. mWriter.WriteT((int32)stream->mSize);
  2049. }
  2050. std::vector<int> streamBlocks;
  2051. uint8* streamDataPos = NULL;
  2052. uint8* streamDataEnd = NULL;
  2053. for (auto& stream : mStreams)
  2054. {
  2055. //int numBlocks = (stream.mSize + CV_BLOCK_SIZE - 1) / CV_BLOCK_SIZE;
  2056. //for (int blockIdx = stream.mBlockStart; blockIdx < stream.mBlockStart + numBlocks; blockIdx++)
  2057. //mWriter.WriteT(blockIdx);
  2058. for (auto blockIdx : stream->mBlocks)
  2059. mWriter.WriteT((int32)blockIdx);
  2060. }
  2061. //int streamDirLen = mWriter.GetStreamPos() - (streamDirLoc * CV_BLOCK_SIZE);
  2062. //int numStreamDirBlocks = (streamDirLen + CV_BLOCK_SIZE - 1) / CV_BLOCK_SIZE;
  2063. //EndBlock();
  2064. EndStream();
  2065. // Root block
  2066. //int rootBlockNum = mMSF.Alloc();
  2067. BlCVStream rootStream;
  2068. StartUnnamedStream(rootStream);
  2069. for (auto block : dirStream.mBlocks)
  2070. mWriter.WriteT((int32)block);
  2071. EndStream();
  2072. //for (int streamDirBlockIdx = streamDirLoc; streamDirBlockIdx < streamDirLoc + numStreamDirBlocks; streamDirBlockIdx++)
  2073. //mWriter.WriteT((int32)streamDirBlockIdx);
  2074. //EndBlock();
  2075. // Fix header
  2076. /*MemStream headerStream(mMSF.mBlocks[0]->mData, CV_BLOCK_SIZE, false);
  2077. int headerStart = 32;
  2078. headerStream.SetPos(headerStart + 8);
  2079. headerStream.Write((int32)mNumBlocks);
  2080. headerStream.Write((int32)streamDirLen);
  2081. headerStream.Write((int32)0); // Unknown
  2082. headerStream.Write((int32)rootBlockNum);*/
  2083. // Fix bitmap
  2084. /*mFS.SetPos(CV_BLOCK_SIZE);
  2085. BfBitSet bitset;
  2086. bitset.Init(mNumBlocks);
  2087. int numBytes = (mNumBlocks + 7) / 8;
  2088. memset(bitset.mBits, 0xFF, numBytes);
  2089. for (int i = 1; i < mNumBlocks; i++)
  2090. bitset.Clear(i);
  2091. mWriter.WriteT(bitset.mBits, numBytes);
  2092. BF_ASSERT(mFS.GetSize() == mNumBlocks * CV_BLOCK_SIZE);
  2093. mFS.Close();*/
  2094. BF_ASSERT(rootStream.mBlocks.size() == 1);
  2095. //AutoPerf autoPerf("Write", &gCVThreadPerfManager);
  2096. BP_ZONE("BlCodeView::DoFinish Write");
  2097. {
  2098. BP_ZONE("BlCodeView::DoFinish Write Wait");
  2099. mMsf.mWorkThread.Stop();
  2100. }
  2101. mMsf.Finish(rootStream.mBlocks[0], dirStream.mSize);
  2102. }
  2103. void BlCodeView::Finish()
  2104. {
  2105. /*if (mWorkThread == NULL)
  2106. {
  2107. DoFinish();
  2108. }
  2109. else
  2110. {
  2111. mWorkDone = true;
  2112. mWorkEvent.Set();
  2113. }*/
  2114. mTypeWorkThread.mTypesDone = true;
  2115. mTypeWorkThread.mWorkEvent.Set();
  2116. mModuleWorkThread.mModulesDone = true;
  2117. mModuleWorkThread.mWorkEvent.Set();
  2118. }