DbgModule.h 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334
  1. #pragma once
  2. #include "DebugCommon.h"
  3. #include "CPU.h"
  4. #include "BeefySysLib/Common.h"
  5. #include "BeefySysLib/util/SLIList.h"
  6. #include "BeefySysLib/util/BumpAllocator.h"
  7. #include "BeefySysLib/util/HashSet.h"
  8. #include "BeefySysLib/util/MappedFile.h"
  9. #include "BeefySysLib/DataStream.h"
  10. #include "Compiler/BfAst.h"
  11. #include "Compiler/BfUtil.h"
  12. #include "BumpList.h"
  13. #include "RadixMap.h"
  14. #include <unordered_map>
  15. #include <unordered_set>
  16. #include <functional>
  17. #include "Debugger.h"
  18. #include "StrHashMap.h"
  19. #include "DbgTypeMap.h"
  20. #include "COFFData.h"
  21. #include "X86Target.h"
  22. NS_BF_DBG_BEGIN
  23. using namespace Beefy;
  24. class DbgModule;
  25. enum DbgTypeCode : uint8
  26. {
  27. DbgType_Void,
  28. DbgType_Root,
  29. DbgType_Null,
  30. DbgType_i8,
  31. DbgType_u8,
  32. DbgType_i16,
  33. DbgType_u16,
  34. DbgType_i32,
  35. DbgType_u32,
  36. DbgType_i64,
  37. DbgType_u64,
  38. DbgType_i128,
  39. DbgType_u128,
  40. DbgType_Single,
  41. DbgType_Double,
  42. DbgType_Float96,
  43. DbgType_Float128,
  44. DbgType_ComplexFloat,
  45. DbgType_ComplexDouble,
  46. DbgType_ComplexDouble96,
  47. DbgType_ComplexDouble128,
  48. DbgType_SChar,
  49. DbgType_SChar16,
  50. DbgType_SChar32,
  51. DbgType_UChar,
  52. DbgType_UChar16,
  53. DbgType_UChar32,
  54. DbgType_Utf8,
  55. DbgType_Utf16,
  56. DbgType_Utf32,
  57. DbgType_Bool,
  58. DbgType_Namespace,
  59. DbgType_Enum,
  60. DbgType_VTable,
  61. DbgType_Bitfield,
  62. DbgType_Class,
  63. DbgType_Struct,
  64. DbgType_Union,
  65. DbgType_TypeDef,
  66. #ifdef BF_DBG_32
  67. DbgType_IntPtr_Alias = DbgType_i32,
  68. DbgType_UIntPtr_Alias = DbgType_u32,
  69. #else
  70. DbgType_IntPtr_Alias = DbgType_i64,
  71. DbgType_UIntPtr_Alias = DbgType_u64,
  72. #endif
  73. DbgType_DefinitionEnd = DbgType_TypeDef,
  74. DbgType_Ptr,
  75. DbgType_PtrToMember,
  76. DbgType_SizedArray,
  77. DbgType_Ref,
  78. DbgType_RValueReference,
  79. DbgType_Const,
  80. DbgType_Volatile,
  81. DbgType_Unaligned,
  82. DbgType_Restrict,
  83. DbgType_Subroutine,
  84. DbgType_Unspecified,
  85. DbgType_RawText,
  86. DbgType_RegGroup,
  87. DbgType_COUNT,
  88. };
  89. class DebugTarget;
  90. class WinDebugger;
  91. class DbgType;
  92. class DbgBlock;
  93. enum DbgClassType : uint8
  94. {
  95. DbgClassType_None,
  96. DbgClassType_CompileUnit,
  97. DbgClassType_Subprogram,
  98. DbgClassType_Type,
  99. DbgClassType_Member,
  100. DbgClassType_Block,
  101. DbgClassType_Variable,
  102. };
  103. enum DbgFileExistKind : uint8
  104. {
  105. DbgFileExistKind_NotChecked,
  106. DbgFileExistKind_NotFound,
  107. DbgFileExistKind_HasOldSourceCommand,
  108. DbgFileExistKind_Found
  109. };
  110. enum DbgModuleKind : uint8
  111. {
  112. DbgModuleKind_Module,
  113. DbgModuleKind_HotObject,
  114. DbgModuleKind_FromLocateSymbol
  115. };
  116. class DbgCompileUnit;
  117. struct DbgSectionData
  118. {
  119. uint8* mData;
  120. int mSize;
  121. };
  122. class DbgDebugData
  123. {
  124. public:
  125. DbgCompileUnit* mCompileUnit;
  126. int mTagIdx;
  127. public:
  128. DbgDebugData()
  129. {
  130. mCompileUnit = NULL;
  131. }
  132. #ifdef _DEBUG
  133. virtual ~DbgDebugData()
  134. {
  135. }
  136. #endif
  137. };
  138. enum DbgLocationLenKind
  139. {
  140. DbgLocationLenKind_SegPlusOffset = -0x80
  141. };
  142. class DbgVariable : public DbgDebugData
  143. {
  144. public:
  145. static const DbgClassType ClassType = DbgClassType_Variable;
  146. const char* mName;
  147. const char* mLinkName;
  148. addr_target mRangeStart;
  149. int64 mConstValue;
  150. DbgType* mType;
  151. const uint8* mLocationData;
  152. int mRangeLen;
  153. int mMemberOffset;
  154. int8 mLocationLen;
  155. uint8 mBitSize;
  156. uint8 mBitOffset;
  157. bool mIsExtern;
  158. bool mIsParam;
  159. bool mIsMember;
  160. bool mIsStatic;
  161. bool mIsConst;
  162. bool mInAutoStaticMap;
  163. bool mSigNoPointer; // Signature was without pointer, mType has pointer
  164. addr_target mStaticCachedAddr;
  165. DbgVariable* mNext;
  166. public:
  167. DbgVariable()
  168. {
  169. mBitSize = 0;
  170. mBitOffset = 0;
  171. mIsParam = false;
  172. mLocationData = NULL;
  173. mLocationLen = 0;
  174. mIsStatic = false;
  175. mIsConst = false;
  176. mConstValue = 0;
  177. mMemberOffset = 0;
  178. mInAutoStaticMap = false;
  179. mStaticCachedAddr = 0;
  180. }
  181. const char* GetMappedName()
  182. {
  183. if (mLinkName != NULL)
  184. return mLinkName;
  185. return mName;
  186. }
  187. };
  188. class DbgType;
  189. class DbgDataMap;
  190. typedef std::map<int, Array<int> > DwAsmDebugLineMap;
  191. class DbgBlock : public DbgDebugData
  192. {
  193. public:
  194. static const DbgClassType ClassType = DbgClassType_Block;
  195. addr_target mLowPC; // If LowPC is -1 then mHighPC is index into debugRanges
  196. addr_target mHighPC;
  197. SLIList<DbgVariable*> mVariables;
  198. SLIList<DbgBlock*> mSubBlocks;
  199. DwAsmDebugLineMap* mAsmDebugLineMap; // empty unless inline asm is used
  200. DbgBlock* mNext;
  201. bool mAutoStaticVariablesProcessed;
  202. public:
  203. DbgBlock()
  204. {
  205. mLowPC = 0;
  206. mHighPC = 0;
  207. mAutoStaticVariablesProcessed = false;
  208. }
  209. bool IsEmpty()
  210. {
  211. return mLowPC == mHighPC;
  212. }
  213. };
  214. enum DbgMethodType
  215. {
  216. DbgMethodType_Ctor,
  217. DbgMethodType_Normal,
  218. };
  219. class DbgModule;
  220. class DbgSrcFile;
  221. class DbgSrcFileReference;
  222. class DbgSubprogram;
  223. class DbgLineData
  224. {
  225. public:
  226. uint32 mRelAddress;
  227. int32 mLine;
  228. int16 mColumn;
  229. uint16 mContribSize;
  230. uint16 mCtxIdx;
  231. bool IsStackFrameSetup()
  232. {
  233. return mColumn != -2;
  234. }
  235. };
  236. struct DbgLineDataEx
  237. {
  238. public:
  239. DbgLineData* mLineData;
  240. DbgSubprogram* mSubprogram;
  241. DbgLineDataEx()
  242. {
  243. mLineData = NULL;
  244. mSubprogram = NULL;
  245. }
  246. DbgLineDataEx(DbgLineData* lineData, DbgSubprogram* subprogram)
  247. {
  248. mLineData = lineData;
  249. mSubprogram = subprogram;
  250. }
  251. addr_target GetAddress();
  252. DbgSrcFile* GetSrcFile();
  253. bool operator==(DbgLineData* lineData)
  254. {
  255. return lineData == mLineData;
  256. }
  257. bool IsNull()
  258. {
  259. return mLineData == NULL;
  260. }
  261. };
  262. class DbgLineInfoCtx
  263. {
  264. public:
  265. DbgSubprogram* mInlinee;
  266. DbgSrcFile* mSrcFile;
  267. };
  268. class DbgLineInfo
  269. {
  270. public:
  271. DbgLineInfoCtx* mContexts;
  272. BfSizedArray<DbgLineData> mLines;
  273. bool mHasInlinees;
  274. };
  275. class HotReplacedLineInfo
  276. {
  277. public:
  278. struct Entry
  279. {
  280. DbgLineInfo* mLineInfo;
  281. DbgSubprogram* mSubprogram;
  282. };
  283. Array<Entry> mEntries;
  284. };
  285. class DbgInlineeInfo
  286. {
  287. public:
  288. DbgSubprogram* mInlineParent;
  289. DbgSubprogram* mRootInliner;
  290. DbgLineData mFirstLineData;
  291. DbgLineData mLastLineData;
  292. uint32 mInlineeId;
  293. int mInlineDepth;
  294. };
  295. class DbgSubprogram : public DbgDebugData
  296. {
  297. public:
  298. static const DbgClassType ClassType = DbgClassType_Subprogram;
  299. #ifdef BF_DBG_32
  300. enum LocalBaseRegKind : uint8
  301. {
  302. LocalBaseRegKind_None,
  303. LocalBaseRegKind_VFRAME,
  304. LocalBaseRegKind_EBP,
  305. LocalBaseRegKind_EBX
  306. };
  307. #else
  308. enum LocalBaseRegKind : uint8
  309. {
  310. LocalBaseRegKind_None,
  311. LocalBaseRegKind_RSP,
  312. LocalBaseRegKind_RBP,
  313. LocalBaseRegKind_R13
  314. };
  315. #endif
  316. enum HotReplaceKind : uint8
  317. {
  318. HotReplaceKind_None = 0,
  319. HotReplaceKind_Replaced = 1,
  320. HotReplaceKind_Orphaned = 2, // Module was hot replaced but a new version of the subprogram wasn't found
  321. HotReplaceKind_Invalid = 3 // Mangles matched but arguments were incompatible
  322. };
  323. const char* mName;
  324. const char* mLinkName;
  325. int mTemplateNameIdx;
  326. int mFrameBaseLen;
  327. int mPrologueSize;
  328. const uint8* mFrameBaseData;
  329. DbgBlock mBlock;
  330. int mDeferredInternalsSize;
  331. int mVTableLoc;
  332. int mStepFilterVersion;
  333. LocalBaseRegKind mParamBaseReg;
  334. LocalBaseRegKind mLocalBaseReg;
  335. bool mHasQualifiedName:1;
  336. bool mIsStepFiltered:1;
  337. bool mIsStepFilteredDefault:1;
  338. bool mVirtual:1;
  339. bool mHasThis:1;
  340. bool mNeedLineDataFixup:1;
  341. bool mIsOptimized:1;
  342. bool mHasLineAddrGaps:1; // There are gaps of addresses which are not covered by lineinfo
  343. HotReplaceKind mHotReplaceKind;
  344. DbgLineInfo* mLineInfo;
  345. DbgInlineeInfo* mInlineeInfo;
  346. DbgType* mParentType;
  347. DbgType* mReturnType;
  348. DbgMethodType mMethodType;
  349. BfProtection mProtection;
  350. BfCheckedKind mCheckedKind;
  351. SLIList<DbgVariable*> mParams;
  352. DbgSubprogram* mNext;
  353. public:
  354. DbgSubprogram()
  355. {
  356. mName = NULL;
  357. mLinkName = NULL;
  358. mHasThis = false;
  359. mNeedLineDataFixup = true;
  360. mHotReplaceKind = HotReplaceKind_None;
  361. mHasLineAddrGaps = false;
  362. mPrologueSize = -1;
  363. mParentType = NULL;
  364. mInlineeInfo = NULL;
  365. mFrameBaseData = NULL;
  366. mFrameBaseLen = 0;
  367. mReturnType = NULL;
  368. mNext = NULL;
  369. mMethodType = DbgMethodType_Normal;
  370. mProtection = BfProtection_Public;
  371. mCheckedKind = BfCheckedKind_NotSet;
  372. mVTableLoc = -1;
  373. mStepFilterVersion = -1;
  374. }
  375. ~DbgSubprogram();
  376. void ToString(StringImpl& str, bool internalName);
  377. String ToString();
  378. DbgLineData* FindClosestLine(addr_target addr, DbgSubprogram** inlinedSubprogram = NULL, DbgSrcFile** srcFile = NULL, int* outLineIdx = NULL);
  379. DbgType* GetParent();
  380. DbgType* GetTargetType(); // usually mParentType except for closures
  381. DbgLanguage GetLanguage();
  382. bool Equals(DbgSubprogram* checkMethod, bool allowThisMismatch = false);
  383. int GetParamCount();
  384. String GetParamName(int paramIdx);
  385. bool IsGenericMethod();
  386. bool ThisIsSplat();
  387. bool IsLambda();
  388. DbgSubprogram* GetRootInlineParent()
  389. {
  390. if (mInlineeInfo == NULL)
  391. return this;
  392. return mInlineeInfo->mRootInliner;
  393. }
  394. int GetInlineDepth()
  395. {
  396. int inlineDepth = 0;
  397. auto checkSubprogram = this;
  398. while (checkSubprogram->mInlineeInfo != NULL)
  399. {
  400. checkSubprogram = checkSubprogram->mInlineeInfo->mInlineParent;
  401. inlineDepth++;
  402. }
  403. if (mInlineeInfo != NULL)
  404. BF_ASSERT(inlineDepth == mInlineeInfo->mInlineDepth);
  405. return inlineDepth;
  406. }
  407. addr_target GetLineAddr(const DbgLineData& lineData);
  408. DbgSubprogram* GetLineInlinee(const DbgLineData& lineData);
  409. DbgSrcFile* GetLineSrcFile(const DbgLineData& lineData);
  410. bool HasValidLines();
  411. void PopulateSubprogram();
  412. };
  413. class DbgSubprogramMapEntry
  414. {
  415. public:
  416. addr_target mAddress;
  417. DbgSubprogram* mEntry;
  418. DbgSubprogramMapEntry* mNext;
  419. };
  420. class DbgExceptionDirectoryEntry
  421. {
  422. public:
  423. DbgExceptionDirectoryEntry* mNext;
  424. DbgModule* mDbgModule;
  425. addr_target mAddress;
  426. int mOrigAddressOffset;
  427. int mAddressLength;
  428. int mExceptionPos;
  429. };
  430. class DbgBaseTypeEntry
  431. {
  432. public:
  433. DbgType* mBaseType;
  434. DbgBaseTypeEntry* mNext;
  435. int mThisOffset;
  436. int mVTableOffset;
  437. public:
  438. DbgBaseTypeEntry()
  439. {
  440. mVTableOffset = -1;
  441. }
  442. };
  443. enum DbgTypePriority
  444. {
  445. DbgTypePriority_Normal,
  446. DbgTypePriority_Unique,
  447. DbgTypePriority_Primary_Implicit,
  448. DbgTypePriority_Primary_Explicit
  449. };
  450. struct DbgMethodNameEntry
  451. {
  452. const char* mName;
  453. int mCompileUnitId;
  454. DbgMethodNameEntry* mNext;
  455. };
  456. enum DbgExtType : int8
  457. {
  458. DbgExtType_Unknown,
  459. DbgExtType_Normal,
  460. DbgExtType_BfObject,
  461. DbgExtType_BfPayloadEnum,
  462. DbgExtType_BfUnion,
  463. DbgExtType_Interface
  464. };
  465. class DbgType : public DbgDebugData
  466. {
  467. public:
  468. static const DbgClassType ClassType = DbgClassType_Type;
  469. DbgType* mParent;
  470. BumpList<DbgType*> mAlternates; // From other compile units
  471. DbgType* mPrimaryType;
  472. DbgTypeCode mTypeCode;
  473. SLIList<DbgBaseTypeEntry*> mBaseTypes;
  474. DbgType* mTypeParam;
  475. SLIList<DbgVariable*> mMemberList;
  476. DbgType* mPtrType;
  477. DbgBlock* mBlockParam;
  478. SLIList<DbgMethodNameEntry*> mMethodNameList;
  479. SLIList<DbgSubprogram*> mMethodList;
  480. SLIList<DbgType*> mSubTypeList;
  481. BumpList<DbgType*> mUsingNamespaces;
  482. SLIList<DbgSubprogram*> mHotReplacedMethodList; // Old methods
  483. DbgType* mHotNewType; // Only non-null during actual hotloading
  484. const char* mName;
  485. const char* mTypeName;
  486. intptr mSize; // In bytes
  487. int mTemplateNameIdx;
  488. int mAlign;
  489. int mTypeIdx;
  490. uint16 mDefinedMembersSize;
  491. uint16 mMethodsWithParamsCount;
  492. bool mIsIncomplete:1; // Not fully loaded
  493. bool mIsPacked:1;
  494. bool mNeedsGlobalsPopulated:1;
  495. bool mHasGlobalsPopulated:1;
  496. bool mIsDeclaration:1;
  497. bool mHasStaticMembers:1;
  498. bool mHasVTable:1;
  499. bool mFixedName:1;
  500. DbgLanguage mLanguage;
  501. DbgExtType mExtType;
  502. DbgTypePriority mPriority; // Is the one stored in the type map
  503. bool mSizeCalculated;
  504. DbgType* mNext;
  505. public:
  506. DbgType();
  507. ~DbgType();
  508. //uint64 GetHash();
  509. DbgType* ResolveTypeDef();
  510. bool Equals(DbgType* dbgType);
  511. bool IsRoot();
  512. bool IsNull();
  513. bool IsVoid();
  514. bool IsValuelessType();
  515. bool IsPrimitiveType();
  516. bool IsStruct();
  517. bool IsValueType();
  518. bool IsTypedPrimitive();
  519. bool IsBoolean();
  520. bool IsInteger();
  521. bool IsIntegral();
  522. bool IsChar();
  523. bool IsChar(DbgLanguage language);
  524. bool IsNamespace();
  525. bool IsFloat();
  526. bool IsCompositeType();
  527. bool WantsRefThis(); // Beef valuetypes want 'this' by ref, Objects and C++ want 'this' by pointer
  528. bool IsBfObjectPtr();
  529. bool IsBfObject();
  530. bool IsBfPayloadEnum();
  531. bool IsBfEnum();
  532. bool IsBfTuple();
  533. bool IsBfUnion();
  534. bool HasCPPVTable();
  535. bool IsBaseBfObject();
  536. bool IsInterface();
  537. bool IsEnum();
  538. bool IsSigned();
  539. bool IsRef();
  540. bool IsConst();
  541. bool IsPointer(bool includeBfObjectPointer = true);
  542. bool HasPointer(bool includeBfObjectPointer = true);
  543. bool IsPointerOrRef(bool includeBfObjectPointer = true);
  544. bool IsSizedArray();
  545. bool IsAnonymous();
  546. bool IsGlobalsContainer();
  547. DbgExtType CalcExtType();
  548. DbgLanguage GetLanguage();
  549. void FixName();
  550. void PopulateType();
  551. DbgModule* GetDbgModule();
  552. DbgType* GetUnderlyingType();
  553. DbgType* GetPrimaryType();
  554. DbgType* GetBaseType();
  555. DbgType* GetRootBaseType();
  556. DbgType* RemoveModifiers(bool* hadRef = NULL);
  557. String ToStringRaw(DbgLanguage language = DbgLanguage_Unknown);
  558. void ToString(StringImpl& str, DbgLanguage language, bool allowDirectBfObject, bool internalName);
  559. String ToString(DbgLanguage language = DbgLanguage_Unknown, bool allowDirectBfObject = false);
  560. intptr GetByteCount();
  561. intptr GetStride();
  562. int GetAlign();
  563. void EnsureMethodsMapped();
  564. };
  565. class DbgBitfieldType : public DbgType
  566. {
  567. public:
  568. int mPosition;
  569. int mLength;
  570. };
  571. /*enum DbgDerivedTypeRefKind
  572. {
  573. DbgDerivedTypeRefKind_Ptr
  574. };
  575. class DbgDerivedTypeRef : public DbgType
  576. {
  577. public:
  578. DbgType* mRefType;
  579. };*/
  580. class DbgLineDataBuilder
  581. {
  582. public:
  583. class SubprogramRecord
  584. {
  585. public:
  586. Array<DbgLineInfoCtx, AllocatorBump<DbgLineInfoCtx> > mContexts;
  587. Array<DbgLineData, AllocatorBump<DbgLineData> > mLines;
  588. int mCurContext;
  589. bool mHasInlinees;
  590. };
  591. BumpAllocator mAlloc;
  592. DbgModule* mDbgModule;
  593. Dictionary<DbgSubprogram*, SubprogramRecord*> mRecords;
  594. DbgSubprogram* mCurSubprogram;
  595. SubprogramRecord* mCurRecord;
  596. public:
  597. DbgLineDataBuilder(DbgModule* dbgModule);
  598. // The pointer returned is invalid after the next add
  599. DbgLineData* Add(DbgCompileUnit* compileUnit, DbgLineData& lineData, DbgSrcFile* srcFile, DbgSubprogram* inlinee);
  600. void Commit();
  601. };
  602. class DbgLineDataState : public DbgLineData
  603. {
  604. public:
  605. int mOpIndex;
  606. int mDiscriminator;
  607. int mIsa;
  608. bool mBasicBlock;
  609. bool mIsStmt;
  610. };
  611. class DbgSrcFileReference
  612. {
  613. public:
  614. DbgCompileUnit* mCompileUnit;
  615. DbgSrcFile* mSrcFile;
  616. };
  617. class DbgDeferredSrcFileReference
  618. {
  619. public:
  620. DbgModule* mDbgModule;
  621. int mCompileUnitId;
  622. };
  623. typedef Array<DbgLineData*> LineDataVector;
  624. class DbgLineDataList
  625. {
  626. public:
  627. LineDataVector mLineData;
  628. };
  629. enum DbgHashKind
  630. {
  631. DbgHashKind_None,
  632. DbgHashKind_MD5,
  633. DbgHashKind_SHA256
  634. };
  635. class DbgSrcFile
  636. {
  637. public:
  638. String mFilePath;
  639. String mLocalPath;
  640. bool mHadLineData;
  641. bool mHasLineDataFromMultipleModules;
  642. bool mVerifiedPath;
  643. DbgFileExistKind mFileExistKind;
  644. int mStepFilterVersion;
  645. DbgHashKind mHashKind;
  646. uint8 mHash[32];
  647. Array<DbgDeferredSrcFileReference> mDeferredRefs;
  648. Array<DbgSubprogram*> mLineDataRefs;
  649. Array<HotReplacedLineInfo*> mHotReplacedDbgLineInfo; // Indexing starts at -1
  650. public:
  651. DbgSrcFile()
  652. {
  653. mHasLineDataFromMultipleModules = false;
  654. mHadLineData = false;
  655. mVerifiedPath = false;
  656. mHashKind = DbgHashKind_None;
  657. mFileExistKind = DbgFileExistKind_NotChecked;
  658. mStepFilterVersion = 0;
  659. //mLineData.Reserve(64);
  660. }
  661. bool IsBeef();
  662. ~DbgSrcFile();
  663. void RemoveDeferredRefs(DbgModule* debugModule);
  664. void RemoveLines(DbgModule* debugModule);
  665. void RemoveLines(DbgModule* debugModule, DbgSubprogram* dbgSubprogram, bool isHotReplaced);
  666. void RehupLineData();
  667. void VerifyPath();
  668. const String& GetLocalPath();
  669. void GetHash(String& hashStr);
  670. };
  671. class DwCommonFrameDescriptor
  672. {
  673. public:
  674. DbgModule* mDbgModule;
  675. const char* mAugmentation;
  676. int mAugmentationLength;
  677. int mPointerSize;
  678. int mSegmentSize;
  679. int mCodeAlignmentFactor;
  680. int mDataAlignmentFactor;
  681. int mReturnAddressColumn;
  682. const uint8* mInstData;
  683. int mInstLen;
  684. int mAddressPointerEncoding;
  685. addr_target mLSDARoutine;
  686. int mLSDAPointerEncodingFDE;
  687. public:
  688. DwCommonFrameDescriptor()
  689. {
  690. mPointerSize = -1;
  691. mSegmentSize = -1;
  692. mDbgModule = NULL;
  693. mAugmentationLength = 0;
  694. mAddressPointerEncoding = 0;
  695. mLSDARoutine = 0;
  696. mLSDAPointerEncodingFDE = 0;
  697. }
  698. };
  699. class DwFrameDescriptor
  700. {
  701. public:
  702. addr_target mLowPC;
  703. addr_target mHighPC;
  704. const uint8* mInstData;
  705. int mInstLen;
  706. DwCommonFrameDescriptor* mCommonFrameDescriptor;
  707. int mAddressPointerEncoding;
  708. addr_target mLSDARoutine;
  709. public:
  710. DwFrameDescriptor()
  711. {
  712. mAddressPointerEncoding = 0;
  713. mLSDARoutine = 0;
  714. }
  715. };
  716. class DbgModule;
  717. class DbgCompileUnitContrib
  718. {
  719. public:
  720. DbgCompileUnitContrib* mNext;
  721. DbgModule* mDbgModule;
  722. addr_target mAddress;
  723. int mCompileUnitId;
  724. int mLength;
  725. };
  726. class DbgCompileUnit
  727. {
  728. public:
  729. static const DbgClassType ClassType = DbgClassType_CompileUnit;
  730. DbgModule* mDbgModule;
  731. DbgLanguage mLanguage;
  732. DbgBlock* mGlobalBlock;
  733. DbgType* mGlobalType;
  734. Array<DbgSrcFileReference> mSrcFileRefs;
  735. String mName;
  736. String mProducer;
  737. String mCompileDir;
  738. addr_target mLowPC;
  739. addr_target mHighPC;
  740. bool mNeedsLineDataFixup;
  741. bool mWasHotReplaced;
  742. bool mIsMaster;
  743. SLIList<DbgSubprogram*> mOrphanMethods;
  744. public:
  745. DbgCompileUnit(DbgModule* dbgModule);
  746. virtual ~DbgCompileUnit()
  747. {
  748. }
  749. };
  750. //static int gDbgSymbol_Idx = 0;
  751. class DbgSymbol
  752. {
  753. public:
  754. //int mDbgIdx;
  755. DbgSymbol()
  756. {
  757. //mDbgIdx = ++gDbgSymbol_Idx;
  758. }
  759. public:
  760. const char* mName;
  761. addr_target mAddress;
  762. DbgModule* mDbgModule;
  763. DbgSymbol* mNext;
  764. };
  765. class DbgSection
  766. {
  767. public:
  768. addr_target mAddrStart;
  769. addr_target mAddrLength;
  770. bool mWritingEnabled;
  771. bool mIsExecutable;
  772. int mOldProt;
  773. public:
  774. DbgSection()
  775. {
  776. mAddrStart = 0;
  777. mAddrLength = 0;
  778. mWritingEnabled = false;
  779. mIsExecutable = false;
  780. mOldProt = 0;
  781. }
  782. };
  783. struct DbgCharPtrHash
  784. {
  785. size_t operator()(const char* val) const
  786. {
  787. int curHash = 0;
  788. const char* curHashPtr = val;
  789. while (*curHashPtr != 0)
  790. {
  791. curHash = ((curHash ^ *curHashPtr) << 5) - curHash;
  792. curHashPtr++;
  793. }
  794. return curHash;
  795. }
  796. };
  797. struct DbgCharPtrEquals
  798. {
  799. bool operator()(const char* lhs, const char* rhs) const
  800. {
  801. return strcmp(lhs, rhs) == 0;
  802. }
  803. };
  804. struct DbgFileNameHash
  805. {
  806. size_t operator()(const char* val) const
  807. {
  808. int curHash = 0;
  809. const char* curHashPtr = val;
  810. while (*curHashPtr != 0)
  811. {
  812. char c = *curHashPtr;
  813. #ifdef _WIN32
  814. c = toupper((uint8)c);
  815. if (c == '\\')
  816. c = '/';
  817. #endif
  818. curHash = ((curHash ^ c) << 5) - curHash;
  819. curHashPtr++;
  820. }
  821. return curHash;
  822. }
  823. };
  824. struct DbgFileNameEquals
  825. {
  826. bool operator()(const char* lhs, const char* rhs) const
  827. {
  828. #ifdef _WIN32
  829. while (true)
  830. {
  831. char lc = toupper((uint8)*(lhs++));
  832. if (lc == '\\')
  833. lc = '/';
  834. char rc = toupper((uint8)*(rhs++));
  835. if (rc == '\\')
  836. rc = '/';
  837. if (lc != rc)
  838. return false;
  839. if (lc == 0)
  840. return true;
  841. }
  842. #else
  843. return strcmp(lhs, rhs) == 0;
  844. #endif
  845. }
  846. };
  847. struct DbgAutoStaticEntry
  848. {
  849. String mFullName;
  850. DbgVariable* mVariable;
  851. uint64 mAddrStart;
  852. uint64 mAddrLen;
  853. };
  854. class DbgHotTargetSection
  855. {
  856. public:
  857. uint8* mData;
  858. int mDataSize;
  859. addr_target mTargetSectionAddr;
  860. int mImageOffset;
  861. int mTargetSectionSize;
  862. int mPointerToRelocations;
  863. int mNumberOfRelocations;
  864. bool mNoTargetAlloc;
  865. bool mCanExecute;
  866. bool mCanWrite;
  867. public:
  868. DbgHotTargetSection()
  869. {
  870. mData = NULL;
  871. mDataSize = 0;
  872. mImageOffset = 0;
  873. mTargetSectionAddr = 0;
  874. mTargetSectionSize = 0;
  875. mPointerToRelocations = 0;
  876. mNumberOfRelocations = 0;
  877. mCanExecute = false;
  878. mCanWrite = false;
  879. mNoTargetAlloc = false;
  880. }
  881. ~DbgHotTargetSection()
  882. {
  883. }
  884. };
  885. typedef Dictionary<String, DbgType*> DbgTypeMapType;
  886. typedef Dictionary<String, std::pair<uint64, uint64> > DbgAutoValueMapType;
  887. typedef Dictionary<addr_target, int> DbgAutoStaticEntryBucketMap;
  888. struct DbgDeferredHotResolve
  889. {
  890. public:
  891. DbgHotTargetSection* mHotTargetSection;
  892. String mName;
  893. addr_target mNewAddr;
  894. COFFRelocation mReloc;
  895. };
  896. class DbgDataMap
  897. {
  898. public:
  899. // All entries we want to put in this map are at least 4 bytes apart
  900. static const int IDX_DIV = 4;
  901. DbgDebugData** mAddrs;
  902. int mOffset;
  903. int mSize;
  904. DbgDataMap(int startIdx, int endIdx)
  905. {
  906. mOffset = startIdx;
  907. mSize = (((endIdx - startIdx) + IDX_DIV - 1) / IDX_DIV) + 4; // Add a few extra at the end
  908. mAddrs = new DbgDebugData*[mSize];
  909. memset(mAddrs, 0, sizeof(DbgDebugData*)*mSize);
  910. }
  911. ~DbgDataMap()
  912. {
  913. delete mAddrs;
  914. }
  915. void Set(int tagIdx, DbgDebugData* debugData)
  916. {
  917. BF_ASSERT(debugData->mTagIdx == 0);
  918. debugData->mTagIdx = tagIdx;
  919. int mapIdx = (tagIdx - mOffset) / IDX_DIV;
  920. BF_ASSERT(mapIdx < mSize);
  921. // Search for empty slot
  922. while (true)
  923. {
  924. BF_ASSERT(mapIdx < mSize);
  925. if (mAddrs[mapIdx] == NULL)
  926. {
  927. mAddrs[mapIdx] = debugData;
  928. break;
  929. }
  930. mapIdx++;
  931. }
  932. }
  933. template <typename T>
  934. T Get(int tagIdx)
  935. {
  936. int mapIdx = (tagIdx - mOffset) / IDX_DIV;
  937. // Search for right slot
  938. while (mapIdx < mSize)
  939. {
  940. DbgDebugData* checkData = mAddrs[mapIdx];
  941. if (checkData == NULL)
  942. return NULL;
  943. if (checkData->mTagIdx == tagIdx)
  944. return (T)checkData;
  945. mapIdx++;
  946. }
  947. return NULL;
  948. }
  949. };
  950. class WdStackFrame;
  951. enum DbgModuleLoadState
  952. {
  953. DbgModuleLoadState_NotLoaded,
  954. DbgModuleLoadState_Failed,
  955. DbgModuleLoadState_Loaded
  956. };
  957. enum DbgEvalLocFlags
  958. {
  959. DbgEvalLocFlag_None = 0,
  960. DbgEvalLocFlag_DisallowReg = 1,
  961. DbgEvalLocFlag_IsParam = 2
  962. };
  963. struct DbgSizedArrayEntry
  964. {
  965. DbgType* mElementType;
  966. int mCount;
  967. bool operator==(const DbgSizedArrayEntry& other) const
  968. {
  969. return (other.mElementType == mElementType) &&
  970. (other.mCount == mCount);
  971. }
  972. };
  973. class DbgModule
  974. {
  975. public:
  976. static const int ImageBlockSize = 4096;
  977. WinDebugger* mDebugger;
  978. DebugTarget* mDebugTarget;
  979. DbgModuleLoadState mLoadState;
  980. MappedFile* mMappedImageFile;
  981. MemReporter* mMemReporter;
  982. const uint8* mDebugLineData;
  983. const uint8* mDebugInfoData;
  984. const uint8* mDebugPubNames;
  985. const uint8* mDebugFrameData;
  986. const uint8* mDebugLocationData;
  987. const uint8* mDebugRangesData;
  988. addr_target mDebugFrameAddress;
  989. addr_target mCodeAddress;
  990. const uint8* mDebugAbbrevData;
  991. const uint8* mDebugStrData;
  992. const uint8** mDebugAbbrevPtrData;
  993. Array<DbgSectionData> mExceptionDirectory;
  994. const uint8* mEHFrameData;
  995. const char* mStringTable;
  996. const uint8* mSymbolData;
  997. addr_target mEHFrameAddress;
  998. addr_target mTLSAddr;
  999. addr_target mTLSExtraAddr;
  1000. int mTLSSize;
  1001. int mTLSExtraSize;
  1002. addr_target mTLSIndexAddr;
  1003. DbgFlavor mDbgFlavor;
  1004. bool mParsedGlobalsData;
  1005. bool mParsedSymbolData;
  1006. bool mParsedTypeData;
  1007. bool mPopulatedStaticVariables;
  1008. bool mParsedFrameDescriptors;
  1009. bool mMayBeOld; // If we had to load debug info from the SymCache or a SymServer then it may be old
  1010. bool mDeleting;
  1011. bool mFailed;
  1012. int mId;
  1013. int mHotIdx;
  1014. String mFilePath;
  1015. String mDisplayName;
  1016. uint32 mTimeStamp;
  1017. uint32 mExpectedFileSize;
  1018. int mStartSubprogramIdx;
  1019. int mEndSubprogramIdx;
  1020. int mStartTypeIdx;
  1021. int mEndTypeIdx;
  1022. uintptr mPreferredImageBase;
  1023. uintptr mImageBase;
  1024. uint32 mImageSize;
  1025. uintptr mEntryPoint;
  1026. String mVersion;
  1027. String* mFailMsgPtr;
  1028. DbgType* mBfTypeType;
  1029. intptr mBfTypesInfoAddr;
  1030. DbgModuleMemoryCache* mOrigImageData;
  1031. DbgCompileUnit* mMasterCompileUnit;
  1032. StrHashMap<DbgVariable*> mGlobalVarMap; // Dedups entries into mMasterCompileUnit
  1033. BumpAllocator mAlloc;
  1034. std::list<DwAsmDebugLineMap> mAsmDebugLineMaps;
  1035. Array<DbgSection> mSections;
  1036. Dictionary<addr_target, int> mSecRelEncodingMap;
  1037. Array<addr_target> mSecRelEncodingVec;
  1038. bool mCheckedBfObject;
  1039. bool mBfObjectHasFlags;
  1040. DbgModuleKind mModuleKind;
  1041. bool mIsDwarf64;
  1042. HashSet<DbgSrcFile*> mSrcFileDeferredRefs;
  1043. Array<addr_target> mSectionRVAs;
  1044. SLIList<DbgSymbol*> mDeferredSymbols;
  1045. Beefy::OwnedVector<DbgDeferredHotResolve> mDeferredHotResolveList;
  1046. Array<DbgHotTargetSection*> mHotTargetSections;
  1047. HashSet<DbgType*> mHotPrimaryTypes; // List of types where we have entries in mHotReplacedMethodList
  1048. DbgCompileUnit mDefaultCompileUnit;
  1049. Dictionary<DbgType*, DbgType*> mConstTypes;
  1050. Dictionary<String, DbgFileExistKind> mFileExistsCache;
  1051. Dictionary<DbgSizedArrayEntry, DbgType*> mSizedArrayTypes;
  1052. int mAllocSizeData;
  1053. Array<const uint8*> mOwnedSectionData;
  1054. public:
  1055. Array<DbgSrcFile*> mEmptySrcFiles;
  1056. Array<DbgCompileUnit*> mCompileUnits;
  1057. Array<DbgVariable*> mStaticVariables;
  1058. DbgType* mCPrimitiveTypes[DbgType_COUNT];
  1059. DbgType* mBfPrimitiveTypes[DbgType_COUNT];
  1060. const char* mPrimitiveStructNames[DbgType_COUNT];
  1061. DbgTypeMap mTypeMap;
  1062. Array<DbgType*> mTypes;
  1063. Array<DbgSubprogram*> mSubprograms;
  1064. StrHashMap<DbgSymbol*> mSymbolNameMap;
  1065. std::unordered_map<const char*, DbgVariable*, DbgCharPtrHash, DbgCharPtrEquals> mStaticVariableMap;
  1066. public:
  1067. virtual void ParseGlobalsData();
  1068. virtual void ParseSymbolData();
  1069. virtual void ParseTypeData();
  1070. virtual DbgCompileUnit* ParseCompileUnit(int compileUnitId);
  1071. virtual void ParseCompileUnits() {}
  1072. virtual void MapCompileUnitMethods(DbgCompileUnit* compileUnit);
  1073. virtual void MapCompileUnitMethods(int compileUnitId);
  1074. virtual void PopulateType(DbgType* dbgType);
  1075. virtual void PopulateTypeGlobals(DbgType* dbgType);
  1076. virtual void PopulateSubprogram(DbgSubprogram* dbgSubprogram) { }
  1077. virtual void FixupInlinee(DbgSubprogram* dbgSubprogram) {}
  1078. virtual void PopulateStaticVariableMap();
  1079. virtual void ProcessDebugInfo();
  1080. virtual bool CanGetOldSource() { return false; }
  1081. virtual String GetOldSourceCommand(const StringImpl& path) { return ""; }
  1082. virtual bool GetEmitSource(const StringImpl& filePath, String& outText) { return false; }
  1083. virtual bool DbgIsStrMutable(const char* str) { return true; } // Always assume its a copy
  1084. virtual addr_target LocateSymbol(const StringImpl& name) { return 0; }
  1085. virtual DbgSubprogram* FindSubprogram(DbgType* dbgType, const char* methodName);
  1086. const char* GetStringTable(DataStream* stream, int stringTablePos);
  1087. virtual void Fail(const StringImpl& error);
  1088. virtual void SoftFail(const StringImpl& error);
  1089. virtual void HardFail(const StringImpl& error);
  1090. void FindTemplateStr(const char*& name, int& templateNameIdx);
  1091. void TempRemoveTemplateStr(const char*& name, int& templateNameIdx);
  1092. void ReplaceTemplateStr(const char*& name, int& templateNameIdx);
  1093. char* DbgDupString(const char* str, const char* allocName = NULL);
  1094. DbgModule* GetLinkedModule();
  1095. addr_target GetTargetImageBase();
  1096. addr_target RemapAddr(addr_target addr);
  1097. template <typename T>
  1098. T GetOrCreate(int idx, DbgDataMap& dataMap);
  1099. DbgType* GetOrCreateType(int typeIdx, DbgDataMap& typeMap);
  1100. //void SplitName(const char* inName, const char*& outBaseName, const char*& outTemplateParams, bool alwaysDup = false);
  1101. void MapSubprogram(DbgSubprogram* dbgSubprogram);
  1102. bool ParseDWARF(const uint8*& dataPtr);
  1103. void ParseAbbrevData(const uint8* data);
  1104. void ParseExceptionData();
  1105. void ParseDebugFrameData();
  1106. void ParseEHFrameData();
  1107. void FlushLineData(DbgSubprogram* curSubprogram, std::list<DbgLineData>& queuedLineData);
  1108. DbgSrcFile* AddSrcFile(DbgCompileUnit* compileUnit, const String& srcFilePath);
  1109. void AddLineData(DbgCompileUnit* dwCompileUnit, DbgLineData& lineData, DbgSubprogram*& curSubProgram, std::list<DbgLineData>& queuedLineData);
  1110. bool ParseDebugLineInfo(const uint8*& data, int compileUnitIdx);
  1111. void FixupInnerTypes(int startingTypeIdx);
  1112. void MapTypes(int startingTypeIdx);
  1113. void CreateNamespaces();
  1114. bool IsObjectFile() { return mModuleKind != DbgModuleKind_Module; }
  1115. bool IsHotSwapObjectFile() { return mModuleKind == DbgModuleKind_HotObject; }
  1116. bool IsHotSwapPreserve(const String& name);
  1117. addr_target GetHotTargetAddress(DbgHotTargetSection* hotTargetSection);
  1118. uint8* GetHotTargetData(addr_target address);
  1119. void DoReloc(DbgHotTargetSection* hotTargetSection, COFFRelocation& coffReloc, addr_target resolveSymbolAddr, PE_SymInfo* symInfo);
  1120. void ParseHotTargetSections(DataStream* stream, addr_target* resovledSymbolAddrs);
  1121. void CommitHotTargetSections();
  1122. void HotReplaceType(DbgType* newType);
  1123. void ProcessHotSwapVariables();
  1124. virtual bool LoadPDB(const String& pdbPath, uint8 wantGuid[16], int32 wantAge) { return false; }
  1125. virtual bool CheckSection(const char* name, uint8* sectionData, int sectionSize) { return false; }
  1126. virtual void PreCacheImage() {}
  1127. virtual void PreCacheDebugInfo() {}
  1128. virtual bool RequestImage() { return false; }
  1129. virtual bool HasPendingDebugInfo() { return false; }
  1130. virtual bool RequestDebugInfo(bool allowRemote = true) { return false; }
  1131. virtual bool WantsAutoLoadDebugInfo() { return false; }
  1132. virtual DbgFileExistKind CheckSourceFileExist(const StringImpl& path);
  1133. virtual void ParseFrameDescriptors() {}
  1134. template <typename T>
  1135. T ReadValue(const uint8*& data, int form, int refOffset = 0, const uint8** extraData = NULL, const uint8* startData = NULL);
  1136. void EnableWriting(addr_target address);
  1137. void RevertWritingEnable();
  1138. public:
  1139. DbgModule(DebugTarget* debugTarget);
  1140. virtual ~DbgModule();
  1141. static bool CanRead(DataStream* stream, DebuggerResult* outResult);
  1142. bool ReadCOFF(DataStream* stream, DbgModuleKind dbgModuleKind);
  1143. void RemoveTargetData();
  1144. virtual void ReportMemory(MemReporter* memReporter);
  1145. int64 GetImageSize();
  1146. virtual void FinishHotSwap();
  1147. addr_target ExecuteOps(DbgSubprogram* dwSubprogram, const uint8* locData, int locDataLen, WdStackFrame* stackFrame, CPURegisters* registers, DbgAddrType* outAddrType, DbgEvalLocFlags flags, addr_target* pushValue = NULL);
  1148. virtual intptr EvaluateLocation(DbgSubprogram* dwSubprogram, const uint8* locData, int locDataLen, WdStackFrame* stackFrame, DbgAddrType* outAddrType, DbgEvalLocFlags flags = DbgEvalLocFlag_None);
  1149. //const uint8* CopyOrigImageData(addr_target address, int length);
  1150. DbgType* FindTypeHelper(const String& typeName, DbgType* checkType);
  1151. DbgType* FindType(const String& typeName, DbgType* contextType = NULL, DbgLanguage language = DbgLanguage_Unknown, bool bfObjectPtr = false);
  1152. DbgTypeMap::Entry* FindType(const char* typeName, DbgLanguage language);
  1153. DbgType* GetPointerType(DbgType* innerType);
  1154. DbgType* GetConstType(DbgType* innerType);
  1155. DbgType* GetPrimaryType(DbgType* dbgType);
  1156. DbgType* GetPrimitiveType(DbgTypeCode typeCode, DbgLanguage language);
  1157. DbgType* GetPrimitiveStructType(DbgTypeCode typeCode);
  1158. DbgType* GetInnerTypeOrVoid(DbgType* dbgType);
  1159. DbgType* GetSizedArrayType(DbgType* elementType, int count);
  1160. };
  1161. NS_BF_END
  1162. namespace std
  1163. {
  1164. template<>
  1165. struct hash<NS_BF_DBG::DbgSizedArrayEntry>
  1166. {
  1167. size_t operator()(const NS_BF_DBG::DbgSizedArrayEntry& val) const
  1168. {
  1169. return (size_t)val.mElementType ^ (val.mCount << 10);
  1170. }
  1171. };
  1172. }