BlCvTypeSource.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913
  1. #include "BlCvTypeSource.h"
  2. #include "BlContext.h"
  3. #include "codeview/cvinfo.h"
  4. #include "BlCvParser.h"
  5. #include "BlPdbParser.h"
  6. #include "BlCodeView.h"
  7. #define GET(T) *((T*)(data += sizeof(T)) - 1)
  8. #define GET_INTO(T, name) T name = GET(T)
  9. #define PTR_ALIGN(ptr, origPtr, alignSize) ptr = ( (origPtr)+( ((ptr - origPtr) + (alignSize - 1)) & ~(alignSize - 1) ) )
  10. USING_NS_BF;
  11. static int sIdx = 0;
  12. BlCvTypeContainer::BlCvTypeContainer()
  13. {
  14. mSectionData = NULL;
  15. mSectionSize = 0;
  16. mCvMinTag = -1;
  17. mCvMaxTag = -1;
  18. mCodeView = NULL;
  19. mOutTypeInfo = NULL;
  20. mIdx = sIdx++;
  21. }
  22. BlCvTypeContainer::~BlCvTypeContainer()
  23. {
  24. }
  25. void BlCvTypeContainer::Fail(const StringImpl& err)
  26. {
  27. BF_FATAL("Err");
  28. }
  29. const char* BlCvTypeContainer::CvParseAndDupString(uint8*& data, bool hasUniqueName)
  30. {
  31. const char* strStart = (const char*)data;
  32. int strLen = (int)strlen((const char*)data);
  33. if (strLen == 0)
  34. return NULL;
  35. data += strLen + 1;
  36. if (hasUniqueName)
  37. {
  38. strLen = (int)strlen((const char*)data);
  39. data += strLen + 1;
  40. }
  41. char* retVal = (char*)mCodeView->mAlloc.AllocBytes((int)(data - (uint8*)strStart));
  42. memcpy(retVal, strStart, data - (uint8*)strStart);
  43. return retVal;
  44. }
  45. int BlCvTypeContainer::CreateMasterTag(int tagId, BlTypeInfo* outTypeInfo)
  46. {
  47. #define DECL_LEAF(leafType, leafName) \
  48. leafType& leafName = *(leafType*)&outBuffer[2];
  49. #define FIXTPI(varName) \
  50. varName = GetMasterTPITag(varName);
  51. #define FIXIPI(varName) \
  52. varName = GetMasterIPITag(varName);
  53. uint8* sectionData = mSectionData; //mCvTypeSectionData;
  54. uint8* srcDataStart = sectionData + mCvTagStartMap[tagId - mCvMinTag];
  55. int16 tagLen = *(int16*)(srcDataStart - 2);
  56. uint8* srcDataEnd = srcDataStart + tagLen;
  57. int outSize = (int)(srcDataEnd - srcDataStart) + 2;
  58. uint8 outBuffer[0x10000];
  59. memcpy(outBuffer, srcDataStart - 2, outSize);
  60. uint8* data = (uint8*)outBuffer + 2;
  61. uint8* dataEnd = data + tagLen;
  62. int16 trLeafType = GET(uint16);
  63. BF_ASSERT(((intptr)data) % 4 == 0);
  64. switch (trLeafType)
  65. {
  66. case LF_VTSHAPE:
  67. break;
  68. case LF_LABEL:
  69. break;
  70. case LF_STRUCTURE:
  71. case LF_CLASS:
  72. {
  73. DECL_LEAF(lfClass, classInfo);
  74. FIXTPI(classInfo.derived);
  75. FIXTPI(classInfo.field);
  76. FIXTPI(classInfo.vshape);
  77. }
  78. break;
  79. case LF_ENUM:
  80. {
  81. DECL_LEAF(lfEnum, enumInfo);
  82. FIXTPI(enumInfo.field);
  83. }
  84. break;
  85. case LF_UNION:
  86. {
  87. DECL_LEAF(lfUnion, unionInfo);
  88. FIXTPI(unionInfo.field);
  89. }
  90. break;
  91. case LF_ARRAY:
  92. {
  93. DECL_LEAF(lfArray, arrayInfo);
  94. FIXTPI(arrayInfo.elemtype);
  95. FIXTPI(arrayInfo.idxtype);
  96. }
  97. break;
  98. case LF_POINTER:
  99. {
  100. DECL_LEAF(lfPointer, pointerInfo);
  101. FIXTPI(pointerInfo.utype);
  102. if ((pointerInfo.attr.ptrmode == CV_PTR_MODE_PMEM) || (pointerInfo.attr.ptrmode == CV_PTR_MODE_PMFUNC))
  103. {
  104. FIXTPI(pointerInfo.pbase.pm.pmclass);
  105. }
  106. else if (pointerInfo.attr.ptrmode == CV_PTR_BASE_TYPE)
  107. {
  108. FIXTPI(pointerInfo.pbase.btype.index);
  109. }
  110. }
  111. break;
  112. case LF_MODIFIER:
  113. {
  114. DECL_LEAF(lfModifier, modifierInfo);
  115. FIXTPI(modifierInfo.type);
  116. }
  117. break;
  118. case LF_MFUNCTION:
  119. {
  120. DECL_LEAF(lfMFunc, func);
  121. FIXTPI(func.rvtype);
  122. FIXTPI(func.classtype);
  123. FIXTPI(func.thistype);
  124. FIXTPI(func.arglist);
  125. }
  126. break;
  127. case LF_PROCEDURE:
  128. {
  129. DECL_LEAF(lfProc, proc);
  130. FIXTPI(proc.rvtype);
  131. FIXTPI(proc.arglist);
  132. }
  133. break;
  134. case LF_FIELDLIST:
  135. {
  136. while (data < dataEnd)
  137. {
  138. static int itrIdx = 0;
  139. itrIdx++;
  140. uint8* leafDataStart = data;
  141. int leafType = (int)GET(uint16);
  142. switch (leafType)
  143. {
  144. case LF_VFUNCTAB:
  145. {
  146. lfVFuncTab& vfuncTab = *(lfVFuncTab*)leafDataStart;
  147. FIXTPI(vfuncTab.type);
  148. data = (uint8*)(&vfuncTab + 1);
  149. }
  150. break;
  151. case LF_BCLASS:
  152. {
  153. lfBClass& baseClassInfo = *(lfBClass*)leafDataStart;
  154. data = (uint8*)&baseClassInfo.offset;
  155. int thisOffset = (int)BlCvParser::CvParseConstant(data);
  156. FIXTPI(baseClassInfo.index);
  157. }
  158. break;
  159. case LF_VBCLASS:
  160. case LF_IVBCLASS:
  161. {
  162. lfVBClass& baseClassInfo = *(lfVBClass*)leafDataStart;
  163. data = (uint8*)&baseClassInfo.vbpoff;
  164. int thisOffset = (int)BlCvParser::CvParseConstant(data);
  165. int vTableOffset = (int)BlCvParser::CvParseConstant(data);
  166. FIXTPI(baseClassInfo.index);
  167. FIXTPI(baseClassInfo.vbptr);
  168. }
  169. break;
  170. case LF_ENUMERATE:
  171. {
  172. CV_fldattr_t fieldAttr = GET(CV_fldattr_t);
  173. int64 fieldVal = BlCvParser::CvParseConstant(data);
  174. const char* fieldName = BlCvParser::CvParseString(data);
  175. }
  176. break;
  177. case LF_NESTTYPE:
  178. {
  179. lfNestType& nestType = *(lfNestType*)leafDataStart;
  180. FIXTPI(nestType.index);
  181. data = (uint8*)&nestType.Name;
  182. const char* typeName = BlCvParser::CvParseString(data);
  183. }
  184. break;
  185. case LF_ONEMETHOD:
  186. {
  187. lfOneMethod& oneMethod = *(lfOneMethod*)leafDataStart;
  188. FIXTPI(oneMethod.index);
  189. data = (uint8*)&oneMethod.vbaseoff;
  190. int virtOffset = -1;
  191. if ((oneMethod.attr.mprop == CV_MTintro) || (oneMethod.attr.mprop == CV_MTpureintro))
  192. {
  193. virtOffset = GET(int32);
  194. }
  195. const char* methodName = BlCvParser::CvParseString(data);
  196. }
  197. break;
  198. case LF_METHOD:
  199. {
  200. lfMethod& method = *(lfMethod*)leafDataStart;
  201. FIXTPI(method.mList);
  202. data = (uint8*)&method.Name;
  203. const char* methodName = BlCvParser::CvParseString(data);
  204. }
  205. break;
  206. case LF_MEMBER:
  207. case LF_STMEMBER:
  208. {
  209. lfMember& member = *(lfMember*)leafDataStart;
  210. FIXTPI(member.index);
  211. bool isStatic = leafType == LF_STMEMBER;
  212. data = (uint8*)&member.offset;
  213. int memberOffset = -1;
  214. if (!isStatic)
  215. {
  216. memberOffset = (int)BlCvParser::CvParseConstant(data);
  217. //
  218. }
  219. char* fieldName = (char*)BlCvParser::CvParseString(data);
  220. }
  221. break;
  222. default:
  223. BF_FATAL("Unhandled");
  224. }
  225. PTR_ALIGN(data, outBuffer, 4);
  226. //BF_ASSERT(((intptr)data) % 4 == 0);
  227. }
  228. }
  229. break;
  230. case LF_ARGLIST:
  231. {
  232. int argCount = GET(int32);
  233. for (int argIdx = 0; argIdx < argCount; argIdx++)
  234. {
  235. CV_typ_t& argTypeId = GET(CV_typ_t);
  236. FIXTPI(argTypeId);
  237. }
  238. }
  239. break;
  240. case LF_METHODLIST:
  241. {
  242. while (data < dataEnd)
  243. {
  244. mlMethod& method = *(mlMethod*)data;
  245. FIXTPI(method.index);
  246. data = (uint8*)method.vbaseoff;
  247. if ((method.attr.mprop == CV_MTintro) || (method.attr.mprop == CV_MTpureintro))
  248. {
  249. int virtOffset = GET(int32);
  250. }
  251. }
  252. }
  253. break;
  254. case LF_STRING_ID:
  255. break;
  256. case LF_SUBSTR_LIST:
  257. {
  258. DECL_LEAF(lfArgList, argList);
  259. data = (uint8*)&argList.arg;
  260. for (int idx = 0; idx < (int)argList.count; idx++)
  261. {
  262. CV_ItemId& itemId = GET(CV_ItemId);
  263. FIXIPI(itemId);
  264. }
  265. }
  266. break;
  267. case LF_UDT_SRC_LINE:
  268. {
  269. DECL_LEAF(lfUdtSrcLine, udtSrcLine);
  270. udtSrcLine.leaf = LF_UDT_MOD_SRC_LINE;
  271. FIXTPI(udtSrcLine.type);
  272. FIXIPI(udtSrcLine.src);
  273. lfUdtModSrcLine& udtModSrcLine = *(lfUdtModSrcLine*)&udtSrcLine;
  274. udtModSrcLine.imod = 1;
  275. outSize += 4;
  276. *(int16*)(outBuffer) += 4;
  277. }
  278. break;
  279. case LF_FUNC_ID:
  280. {
  281. DECL_LEAF(lfFuncId, funcId);
  282. FIXIPI(funcId.scopeId);
  283. FIXTPI(funcId.type);
  284. }
  285. break;
  286. case LF_MFUNC_ID:
  287. {
  288. DECL_LEAF(lfMFuncId, mfuncId);
  289. FIXTPI(mfuncId.parentType);
  290. FIXTPI(mfuncId.type);
  291. }
  292. break;
  293. case LF_BUILDINFO:
  294. {
  295. DECL_LEAF(lfBuildInfo, buildInfo);
  296. data = (uint8*)&buildInfo.arg;
  297. for (int idx = 0; idx < buildInfo.count; idx++)
  298. {
  299. CV_ItemId& itemId = GET(CV_ItemId);
  300. FIXIPI(itemId);
  301. }
  302. }
  303. break;
  304. case LF_BITFIELD:
  305. {
  306. DECL_LEAF(lfBitfield, bitfield);
  307. FIXTPI(bitfield.type);
  308. }
  309. break;
  310. case LF_VFTABLE:
  311. {
  312. DECL_LEAF(lfVftable, vtTable);
  313. FIXTPI(vtTable.type);
  314. FIXTPI(vtTable.baseVftable);
  315. }
  316. break;
  317. default:
  318. NotImpl();
  319. break;
  320. }
  321. BF_ASSERT(*(int16*)(outBuffer) == outSize - 2);
  322. outTypeInfo->mData.Write(outBuffer, outSize);
  323. return outTypeInfo->mCurTagId++;
  324. }
  325. void BlCvTypeContainer::HashName(const char* namePtr, bool hasMangledName, HashContext& hashContext)
  326. {
  327. int hashSize = (int)strlen(namePtr);
  328. if (hasMangledName)
  329. hashSize += 1 + (int)strlen(namePtr + hashSize + 1);
  330. hashContext.Mixin(namePtr, hashSize);
  331. }
  332. int BlCvTypeContainer::GetMasterTPITag(int tagId)
  333. {
  334. if (tagId == 0)
  335. return 0;
  336. if (tagId < mCvMinTag)
  337. return tagId;
  338. int masterTag = (*mTPIMap)[tagId - mCvMinTag];
  339. if (masterTag == -1)
  340. {
  341. // Ensure we're TPI
  342. BF_ASSERT(&mTagMap == mTPIMap);
  343. ParseTag(tagId);
  344. masterTag = (*mTPIMap)[tagId - mCvMinTag];
  345. BF_ASSERT(masterTag != -1);
  346. return masterTag;
  347. }
  348. BF_ASSERT(masterTag != -1);
  349. return masterTag;
  350. }
  351. int BlCvTypeContainer::GetMasterIPITag(int tagId)
  352. {
  353. if (tagId == 0)
  354. return 0;
  355. // Ensure we're IPI
  356. BF_ASSERT(&mTagMap == mIPIMap);
  357. if (tagId < mCvMinTag)
  358. return tagId;
  359. int typeIdx = mTagMap[tagId - mCvMinTag];
  360. BF_ASSERT(typeIdx != -1);
  361. return typeIdx;
  362. }
  363. void BlCvTypeContainer::NotImpl()
  364. {
  365. BF_FATAL("NotImpl");
  366. }
  367. void BlCvTypeContainer::ScanTypeData()
  368. {
  369. uint8* sectionData = mSectionData;
  370. int sectionSize = mSectionSize;
  371. uint8* data = (uint8*)sectionData;
  372. uint8* dataEnd = data + sectionSize;
  373. if (mCvMinTag == -1)
  374. {
  375. mCvMinTag = 0x1000;
  376. int tagCountGuess = sectionSize / 128;
  377. mCvTagStartMap.reserve(tagCountGuess);
  378. int tagIdx = mCvMinTag;
  379. while (data < dataEnd)
  380. {
  381. int tagLen = GET(uint16);
  382. uint8* dataStart = data;
  383. uint8* dataTagEnd = data + tagLen;
  384. mCvTagStartMap.push_back((int)(data - sectionData));
  385. data = dataTagEnd;
  386. tagIdx++;
  387. }
  388. mCvMaxTag = tagIdx;
  389. }
  390. else
  391. {
  392. int tagIdx = mCvMinTag;
  393. while (data < dataEnd)
  394. {
  395. int tagLen = GET(uint16);
  396. uint8* dataStart = data;
  397. uint8* dataTagEnd = data + tagLen;
  398. mCvTagStartMap[tagIdx - mCvMinTag] = (int)(data - sectionData);
  399. data = dataTagEnd;
  400. tagIdx++;
  401. }
  402. }
  403. }
  404. void BlCvTypeContainer::HashTPITag(int tagId, HashContext& hashContext)
  405. {
  406. int masterTagId = GetMasterTPITag(tagId);
  407. hashContext.Mixin(masterTagId);
  408. }
  409. void BlCvTypeContainer::HashIPITag(int tagId, HashContext& hashContext)
  410. {
  411. int masterTagId = GetMasterIPITag(tagId);
  412. hashContext.Mixin(masterTagId);
  413. }
  414. void BlCvTypeContainer::HashTagContent(int tagId, HashContext& hashContext, bool& isIPI)
  415. {
  416. uint8* sectionData = mSectionData; //mCvTypeSectionData;
  417. uint8* data = sectionData + mCvTagStartMap[tagId - mCvMinTag];
  418. uint8* dataStart = data;
  419. int16 tagLen = *(int16*)(data - 2);
  420. uint8* dataEnd = data + tagLen;
  421. int16 trLeafType = GET(uint16);
  422. hashContext.Mixin(trLeafType);
  423. switch (trLeafType)
  424. {
  425. case LF_VTSHAPE:
  426. {
  427. lfVTShape& vtShape = *(lfVTShape*)dataStart;
  428. data = (uint8*)&vtShape.desc;
  429. int shapeBytes = (vtShape.count + 1) / 2;
  430. hashContext.Mixin(data, shapeBytes);
  431. }
  432. break;
  433. case LF_LABEL:
  434. {
  435. lfLabel& label = *(lfLabel*)dataStart;
  436. hashContext.Mixin(label.mode);
  437. }
  438. break;
  439. case LF_ARGLIST:
  440. {
  441. int argCount = (int)GET(int32);
  442. hashContext.Mixin(argCount);
  443. for (int argIdx = 0; argIdx < (int)argCount; argIdx++)
  444. {
  445. HashTPITag(GET(CV_typ_t), hashContext);
  446. }
  447. }
  448. break;
  449. case LF_FIELDLIST:
  450. {
  451. while (data < dataEnd)
  452. {
  453. uint8* leafDataStart = data;
  454. int leafType = (int)GET(uint16);
  455. hashContext.Mixin(leafType);
  456. switch (leafType)
  457. {
  458. case LF_VFUNCTAB:
  459. {
  460. lfVFuncTab& vfuncTab = *(lfVFuncTab*)leafDataStart;
  461. HashTPITag(vfuncTab.type, hashContext);
  462. data = (uint8*)(&vfuncTab + 1);
  463. }
  464. break;
  465. case LF_BCLASS:
  466. {
  467. lfBClass& baseClassInfo = *(lfBClass*)leafDataStart;
  468. data = (uint8*)&baseClassInfo.offset;
  469. int thisOffset = (int)BlCvParser::CvParseConstant(data);
  470. hashContext.Mixin(thisOffset);
  471. HashTPITag(baseClassInfo.index, hashContext);
  472. }
  473. break;
  474. case LF_VBCLASS:
  475. case LF_IVBCLASS:
  476. {
  477. lfVBClass& baseClassInfo = *(lfVBClass*)leafDataStart;
  478. data = (uint8*)&baseClassInfo.vbpoff;
  479. int thisOffset = (int)BlCvParser::CvParseConstant(data);
  480. int vTableOffset = (int)BlCvParser::CvParseConstant(data);
  481. hashContext.Mixin(baseClassInfo.attr);
  482. HashTPITag(baseClassInfo.index, hashContext);
  483. HashTPITag(baseClassInfo.vbptr, hashContext);
  484. HashTPITag(thisOffset, hashContext);
  485. HashTPITag(vTableOffset, hashContext);
  486. }
  487. break;
  488. case LF_ENUMERATE:
  489. {
  490. CV_fldattr_t fieldAttr = GET(CV_fldattr_t);
  491. int64 fieldVal = BlCvParser::CvParseConstant(data);
  492. const char* fieldName = BlCvParser::CvParseString(data);
  493. hashContext.Mixin(fieldAttr);
  494. hashContext.Mixin(fieldVal);
  495. hashContext.MixinStr(fieldName);
  496. }
  497. break;
  498. case LF_NESTTYPE:
  499. {
  500. int16 pad = GET(int16);
  501. int32 nestedTypeId = GET(int32);
  502. //int64 nestedSize = BlCvParser::CvParseConstant(data);
  503. const char* typeName = BlCvParser::CvParseString(data);
  504. HashTPITag(nestedTypeId, hashContext);
  505. }
  506. break;
  507. case LF_ONEMETHOD:
  508. {
  509. CV_fldattr_t attr = GET(CV_fldattr_t);
  510. CV_typ_t methodTypeId = GET(CV_typ_t);
  511. hashContext.Mixin(attr);
  512. HashTPITag(methodTypeId, hashContext);
  513. int virtOffset = -1;
  514. if ((attr.mprop == CV_MTintro) || (attr.mprop == CV_MTpureintro))
  515. {
  516. virtOffset = GET(int32);
  517. hashContext.Mixin(virtOffset);
  518. }
  519. const char* name = BlCvParser::CvParseString(data);
  520. hashContext.MixinStr(name);
  521. }
  522. break;
  523. case LF_METHOD:
  524. {
  525. int count = (int)GET(uint16);
  526. int32 methodList = GET(int32);
  527. const char* name = BlCvParser::CvParseString(data);
  528. hashContext.MixinStr(name);
  529. }
  530. break;
  531. case LF_MEMBER:
  532. case LF_STMEMBER:
  533. {
  534. bool isStatic = leafType == LF_STMEMBER;
  535. bool isConst = false;
  536. CV_fldattr_t attr = GET(CV_fldattr_t);
  537. CV_typ_t fieldTypeId = GET(CV_typ_t);
  538. hashContext.Mixin(attr);
  539. int memberOffset = -1;
  540. if (!isStatic)
  541. {
  542. memberOffset = (int)BlCvParser::CvParseConstant(data);
  543. hashContext.Mixin(memberOffset);
  544. }
  545. const char* name = BlCvParser::CvParseString(data);
  546. hashContext.MixinStr(name);
  547. HashTPITag(fieldTypeId, hashContext);
  548. }
  549. break;
  550. default:
  551. BF_FATAL("Unhandled");
  552. }
  553. PTR_ALIGN(data, sectionData, 4);
  554. }
  555. }
  556. break;
  557. case LF_METHODLIST:
  558. {
  559. while (data < dataEnd)
  560. {
  561. mlMethod& method = *(mlMethod*)data;
  562. bool tempBool = false;
  563. HashTagContent(method.index, hashContext, tempBool);
  564. data = (uint8*)method.vbaseoff;
  565. if ((method.attr.mprop == CV_MTintro) || (method.attr.mprop == CV_MTpureintro))
  566. {
  567. int virtOffset = GET(int32);
  568. hashContext.Mixin(virtOffset);
  569. }
  570. }
  571. }
  572. break;
  573. case LF_STRUCTURE:
  574. case LF_CLASS:
  575. {
  576. lfClass& classInfo = *(lfClass*)dataStart;
  577. data = (uint8*)&classInfo.data;
  578. int dataSize = (int)BlCvParser::CvParseConstant(data);
  579. HashName((char*)data, classInfo.property.hasuniquename, hashContext);
  580. hashContext.Mixin(dataSize);
  581. hashContext.Mixin(classInfo.property);
  582. HashTPITag(classInfo.field, hashContext);
  583. HashTPITag(classInfo.derived, hashContext);
  584. HashTPITag(classInfo.vshape, hashContext);
  585. }
  586. break;
  587. case LF_ENUM:
  588. {
  589. lfEnum& enumInfo = *(lfEnum*)dataStart;
  590. data = (uint8*)enumInfo.Name;
  591. HashName((char*)data, enumInfo.property.hasuniquename, hashContext);
  592. hashContext.Mixin(enumInfo.property);
  593. HashTPITag(enumInfo.utype, hashContext);
  594. HashTPITag(enumInfo.field, hashContext);
  595. }
  596. break;
  597. case LF_UNION:
  598. {
  599. lfUnion& unionInfo = *(lfUnion*)dataStart;
  600. data = (uint8*)unionInfo.data;
  601. int dataSize = (int)BlCvParser::CvParseConstant(data);
  602. HashName((char*)data, unionInfo.property.hasuniquename, hashContext);
  603. hashContext.Mixin(dataSize);
  604. hashContext.Mixin(unionInfo.property);
  605. HashTPITag(unionInfo.field, hashContext);
  606. }
  607. break;
  608. case LF_ARRAY:
  609. {
  610. lfArray& arrayInfo = *(lfArray*)dataStart;
  611. data = (uint8*)arrayInfo.data;
  612. int dataSize = (int)BlCvParser::CvParseConstant(data);
  613. HashName((char*)data, false, hashContext);
  614. HashTPITag(arrayInfo.elemtype, hashContext);
  615. HashTPITag(arrayInfo.idxtype, hashContext);
  616. }
  617. break;
  618. case LF_MFUNCTION:
  619. {
  620. lfMFunc& func = *(lfMFunc*)dataStart;
  621. HashTPITag(func.thistype, hashContext);
  622. HashTPITag(func.classtype, hashContext);
  623. HashTPITag(func.rvtype, hashContext);
  624. HashTPITag(func.arglist, hashContext);
  625. hashContext.Mixin(func.funcattr);
  626. hashContext.Mixin(func.calltype);
  627. hashContext.Mixin(func.parmcount);
  628. hashContext.Mixin(func.thisadjust);
  629. }
  630. break;
  631. case LF_PROCEDURE:
  632. {
  633. lfProc& proc = *(lfProc*)dataStart;
  634. HashTPITag(proc.rvtype, hashContext);
  635. HashTPITag(proc.arglist, hashContext);
  636. hashContext.Mixin(proc.funcattr);
  637. hashContext.Mixin(proc.calltype);
  638. hashContext.Mixin(proc.parmcount);
  639. }
  640. break;
  641. case LF_POINTER:
  642. {
  643. lfPointer& pointerInfo = *(lfPointer*)dataStart;
  644. HashTPITag(pointerInfo.utype, hashContext);
  645. hashContext.Mixin(pointerInfo.attr);
  646. }
  647. break;
  648. case LF_MODIFIER:
  649. {
  650. lfModifier& modifierInfo = *(lfModifier*)dataStart;
  651. HashTPITag(modifierInfo.type, hashContext);
  652. hashContext.Mixin(modifierInfo.attr);
  653. }
  654. break;
  655. case LF_STRING_ID:
  656. {
  657. isIPI = true;
  658. lfStringId& stringId = *(lfStringId*)dataStart;
  659. HashIPITag(stringId.id, hashContext);
  660. HashName((char*)stringId.name, false, hashContext);
  661. }
  662. break;
  663. case LF_SUBSTR_LIST:
  664. {
  665. lfArgList& argList = *(lfArgList*)dataStart;
  666. data = (uint8*)&argList.arg;
  667. for (int idx = 0; idx < (int)argList.count; idx++)
  668. {
  669. CV_ItemId& itemId = GET(CV_ItemId);
  670. HashIPITag(itemId, hashContext);
  671. }
  672. }
  673. break;
  674. case LF_UDT_SRC_LINE:
  675. {
  676. lfUdtSrcLine& srcLine = *(lfUdtSrcLine*)dataStart;
  677. HashTPITag(srcLine.type, hashContext);
  678. HashIPITag(srcLine.src, hashContext);
  679. }
  680. break;
  681. case LF_FUNC_ID:
  682. {
  683. isIPI = true;
  684. lfFuncId& funcId = *(lfFuncId*)dataStart;
  685. HashIPITag(funcId.scopeId, hashContext);
  686. HashTPITag(funcId.type, hashContext);
  687. HashName((char*)funcId.name, false, hashContext);
  688. }
  689. break;
  690. case LF_MFUNC_ID:
  691. {
  692. isIPI = true;
  693. lfMFuncId& mfuncId = *(lfMFuncId*)dataStart;
  694. HashTPITag(mfuncId.parentType, hashContext);
  695. HashTPITag(mfuncId.type, hashContext);
  696. HashName((char*)mfuncId.name, false, hashContext);
  697. }
  698. break;
  699. case LF_BUILDINFO:
  700. {
  701. lfBuildInfo& buildInfo = *(lfBuildInfo*)dataStart;
  702. data = (uint8*)&buildInfo.arg;
  703. for (int idx = 0; idx < (int)buildInfo.count; idx++)
  704. {
  705. CV_ItemId& itemId = GET(CV_ItemId);
  706. HashIPITag(itemId, hashContext);
  707. }
  708. }
  709. break;
  710. case LF_BITFIELD:
  711. {
  712. lfBitfield& bitfield = *(lfBitfield*)dataStart;
  713. HashTPITag(bitfield.type, hashContext);
  714. hashContext.Mixin(bitfield.length);
  715. hashContext.Mixin(bitfield.position);
  716. }
  717. break;
  718. case LF_VFTABLE:
  719. {
  720. lfVftable& vtTable = *(lfVftable*)dataStart;
  721. HashTPITag(vtTable.type, hashContext);
  722. HashTPITag(vtTable.baseVftable, hashContext);
  723. hashContext.Mixin(vtTable.offsetInObjectLayout);
  724. data = (uint8*)&vtTable.Names;
  725. hashContext.Mixin(data, vtTable.len);
  726. }
  727. break;
  728. default:
  729. NotImpl();
  730. break;
  731. }
  732. }
  733. void BlCvTypeContainer::ParseTag(int tagId, bool forceFull)
  734. {
  735. uint8* data = mSectionData + mCvTagStartMap[tagId - mCvMinTag];
  736. uint8* dataStart = data;
  737. int16 tagLen = *(int16*)(data - 2);
  738. uint8* dataEnd = data + tagLen;
  739. int16 trLeafType = GET(uint16);
  740. //TODO: Bad? Good?
  741. //forceFull = true;
  742. bool wantsExt = false;
  743. int memberMasterTag = 0;
  744. switch (trLeafType)
  745. {
  746. case LF_FUNC_ID:
  747. {
  748. mCodeView->mStat_ParseTagFuncs++;
  749. wantsExt = true;
  750. lfFuncId& funcId = *(lfFuncId*)dataStart;
  751. int memberTagId = GetMasterTPITag(funcId.type);
  752. mElementMap[tagId - mCvMinTag] = memberTagId;
  753. /*if (!forceFull)
  754. {
  755. mTagMap[tagId - mCvMinTag] = memberMasterTag | BlTypeMapFlag_InfoExt_ProcId_TypeOnly;
  756. return;
  757. }*/
  758. //return;
  759. }
  760. break;
  761. case LF_MFUNC_ID:
  762. {
  763. mCodeView->mStat_ParseTagFuncs++;
  764. wantsExt = true;
  765. lfMFuncId& funcId = *(lfMFuncId*)dataStart;
  766. int memberTagId = GetMasterTPITag(funcId.type);
  767. mElementMap[tagId - mCvMinTag] = memberTagId;
  768. /*if (!forceFull)
  769. {
  770. mTagMap[tagId - mCvMinTag] = memberMasterTag | BlTypeMapFlag_InfoExt_ProcId_TypeOnly;
  771. return;
  772. }*/
  773. //return;
  774. }
  775. break;
  776. }
  777. HashContext hashContext;
  778. bool isIPI = false;
  779. HashTagContent(tagId, hashContext, isIPI);
  780. auto outTypeInfo = mOutTypeInfo;
  781. if (isIPI)
  782. outTypeInfo = &mCodeView->mIPI;
  783. mCodeView->mStat_TypeMapInserts++;
  784. Val128 hashVal = hashContext.Finish128();
  785. int masterTagId;
  786. auto insertPair = outTypeInfo->mTypeMap.insert(std::make_pair(hashVal, -1));
  787. if (insertPair.second)
  788. {
  789. masterTagId = CreateMasterTag(tagId, outTypeInfo);
  790. insertPair.first->second = masterTagId;
  791. }
  792. else
  793. {
  794. masterTagId = insertPair.first->second;
  795. }
  796. /*if (wantsExt)
  797. {
  798. mTagMap[tagId - mCvMinTag] = (int)mInfoExts.size() | BlTypeMapFlag_InfoExt_ProcId_Resolved;
  799. BlCvTypeInfoExt infoExt;
  800. infoExt.mMasterTag = masterTagId;
  801. infoExt.mMemberMasterTag = memberMasterTag;
  802. mInfoExts.push_back(infoExt);
  803. }
  804. else*/
  805. mTagMap[tagId - mCvMinTag] = masterTagId;
  806. }
  807. void BlCvTypeContainer::ParseTypeData()
  808. {
  809. mTagMap.insert(mTagMap.begin(), mCvTagStartMap.size(), -1);
  810. mElementMap.insert(mElementMap.begin(), mCvTagStartMap.size(), -1);
  811. for (int tagId = mCvMinTag; tagId < mCvMaxTag; tagId++)
  812. {
  813. if (mTagMap[tagId - mCvMinTag] == -1)
  814. ParseTag(tagId);
  815. }
  816. }
  817. //////////////////////////////////////////////////////////////////////////
  818. BlCvTypeSource::BlCvTypeSource()
  819. {
  820. mTypeServerLib = NULL;
  821. mIPI = NULL;
  822. mIsDone = false;
  823. mObjectData = NULL;
  824. }
  825. BlCvTypeSource::~BlCvTypeSource()
  826. {
  827. delete mTypeServerLib;
  828. if (mIPI != &mTPI)
  829. delete mIPI;
  830. }
  831. void BlCvTypeSource::CreateIPI()
  832. {
  833. auto codeView = mTPI.mCodeView;
  834. BF_ASSERT(mIPI == &mTPI);
  835. mIPI = new BlCvTypeContainer();
  836. mIPI->mCodeView = codeView;
  837. mIPI->mOutTypeInfo = &codeView->mIPI;
  838. mIPI->mTPIMap = &mTPI.mTagMap;
  839. mIPI->mIPIMap = &mIPI->mTagMap;
  840. }
  841. void BlCvTypeSource::Init(BlCodeView* codeView)
  842. {
  843. mTPI.mCodeView = codeView;
  844. mTPI.mOutTypeInfo = &codeView->mTPI;
  845. mTPI.mTPIMap = &mTPI.mTagMap;
  846. mTPI.mIPIMap = &mTPI.mTagMap;
  847. mIPI = &mTPI;
  848. }