DbgModule.h 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329
  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. DbgFileExistKind mFileExistKind;
  643. int mStepFilterVersion;
  644. DbgHashKind mHashKind;
  645. uint8 mHash[32];
  646. DbgModule* mFirstLineDataDbgModule; // Just used to detect mHasLineDataFromMultipleModules
  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. mFirstLineDataDbgModule = NULL;
  655. mHadLineData = 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. const String& GetLocalPath();
  668. void GetHash(String& hashStr);
  669. };
  670. class DwCommonFrameDescriptor
  671. {
  672. public:
  673. DbgModule* mDbgModule;
  674. const char* mAugmentation;
  675. int mAugmentationLength;
  676. int mPointerSize;
  677. int mSegmentSize;
  678. int mCodeAlignmentFactor;
  679. int mDataAlignmentFactor;
  680. int mReturnAddressColumn;
  681. const uint8* mInstData;
  682. int mInstLen;
  683. int mAddressPointerEncoding;
  684. addr_target mLSDARoutine;
  685. int mLSDAPointerEncodingFDE;
  686. public:
  687. DwCommonFrameDescriptor()
  688. {
  689. mPointerSize = -1;
  690. mSegmentSize = -1;
  691. mDbgModule = NULL;
  692. mAugmentationLength = 0;
  693. mAddressPointerEncoding = 0;
  694. mLSDARoutine = 0;
  695. mLSDAPointerEncodingFDE = 0;
  696. }
  697. };
  698. class DwFrameDescriptor
  699. {
  700. public:
  701. addr_target mLowPC;
  702. addr_target mHighPC;
  703. const uint8* mInstData;
  704. int mInstLen;
  705. DwCommonFrameDescriptor* mCommonFrameDescriptor;
  706. int mAddressPointerEncoding;
  707. addr_target mLSDARoutine;
  708. public:
  709. DwFrameDescriptor()
  710. {
  711. mAddressPointerEncoding = 0;
  712. mLSDARoutine = 0;
  713. }
  714. };
  715. class DbgModule;
  716. class DbgCompileUnitContrib
  717. {
  718. public:
  719. DbgCompileUnitContrib* mNext;
  720. DbgModule* mDbgModule;
  721. addr_target mAddress;
  722. int mCompileUnitId;
  723. int mLength;
  724. };
  725. class DbgCompileUnit
  726. {
  727. public:
  728. static const DbgClassType ClassType = DbgClassType_CompileUnit;
  729. DbgModule* mDbgModule;
  730. DbgLanguage mLanguage;
  731. DbgBlock* mGlobalBlock;
  732. DbgType* mGlobalType;
  733. Array<DbgSrcFileReference> mSrcFileRefs;
  734. String mName;
  735. String mProducer;
  736. String mCompileDir;
  737. addr_target mLowPC;
  738. addr_target mHighPC;
  739. bool mNeedsLineDataFixup;
  740. bool mWasHotReplaced;
  741. bool mIsMaster;
  742. SLIList<DbgSubprogram*> mOrphanMethods;
  743. public:
  744. DbgCompileUnit(DbgModule* dbgModule);
  745. virtual ~DbgCompileUnit()
  746. {
  747. }
  748. };
  749. //static int gDbgSymbol_Idx = 0;
  750. class DbgSymbol
  751. {
  752. public:
  753. //int mDbgIdx;
  754. DbgSymbol()
  755. {
  756. //mDbgIdx = ++gDbgSymbol_Idx;
  757. }
  758. public:
  759. const char* mName;
  760. addr_target mAddress;
  761. DbgModule* mDbgModule;
  762. DbgSymbol* mNext;
  763. };
  764. class DbgSection
  765. {
  766. public:
  767. addr_target mAddrStart;
  768. addr_target mAddrLength;
  769. bool mWritingEnabled;
  770. bool mIsExecutable;
  771. int mOldProt;
  772. public:
  773. DbgSection()
  774. {
  775. mAddrStart = 0;
  776. mAddrLength = 0;
  777. mWritingEnabled = false;
  778. mIsExecutable = false;
  779. mOldProt = 0;
  780. }
  781. };
  782. struct DbgCharPtrHash
  783. {
  784. size_t operator()(const char* val) const
  785. {
  786. int curHash = 0;
  787. const char* curHashPtr = val;
  788. while (*curHashPtr != 0)
  789. {
  790. curHash = ((curHash ^ *curHashPtr) << 5) - curHash;
  791. curHashPtr++;
  792. }
  793. return curHash;
  794. }
  795. };
  796. struct DbgCharPtrEquals
  797. {
  798. bool operator()(const char* lhs, const char* rhs) const
  799. {
  800. return strcmp(lhs, rhs) == 0;
  801. }
  802. };
  803. struct DbgFileNameHash
  804. {
  805. size_t operator()(const char* val) const
  806. {
  807. int curHash = 0;
  808. const char* curHashPtr = val;
  809. while (*curHashPtr != 0)
  810. {
  811. char c = *curHashPtr;
  812. #ifdef _WIN32
  813. c = toupper((uint8)c);
  814. if (c == '\\')
  815. c = '/';
  816. #endif
  817. curHash = ((curHash ^ c) << 5) - curHash;
  818. curHashPtr++;
  819. }
  820. return curHash;
  821. }
  822. };
  823. struct DbgFileNameEquals
  824. {
  825. bool operator()(const char* lhs, const char* rhs) const
  826. {
  827. #ifdef _WIN32
  828. while (true)
  829. {
  830. char lc = toupper((uint8)*(lhs++));
  831. if (lc == '\\')
  832. lc = '/';
  833. char rc = toupper((uint8)*(rhs++));
  834. if (rc == '\\')
  835. rc = '/';
  836. if (lc != rc)
  837. return false;
  838. if (lc == 0)
  839. return true;
  840. }
  841. #else
  842. return strcmp(lhs, rhs) == 0;
  843. #endif
  844. }
  845. };
  846. struct DbgAutoStaticEntry
  847. {
  848. String mFullName;
  849. DbgVariable* mVariable;
  850. uint64 mAddrStart;
  851. uint64 mAddrLen;
  852. };
  853. class DbgHotTargetSection
  854. {
  855. public:
  856. uint8* mData;
  857. int mDataSize;
  858. addr_target mTargetSectionAddr;
  859. int mImageOffset;
  860. int mTargetSectionSize;
  861. int mPointerToRelocations;
  862. int mNumberOfRelocations;
  863. bool mNoTargetAlloc;
  864. bool mCanExecute;
  865. bool mCanWrite;
  866. public:
  867. DbgHotTargetSection()
  868. {
  869. mData = NULL;
  870. mDataSize = 0;
  871. mImageOffset = 0;
  872. mTargetSectionAddr = 0;
  873. mTargetSectionSize = 0;
  874. mPointerToRelocations = 0;
  875. mNumberOfRelocations = 0;
  876. mCanExecute = false;
  877. mCanWrite = false;
  878. mNoTargetAlloc = false;
  879. }
  880. ~DbgHotTargetSection()
  881. {
  882. }
  883. };
  884. typedef Dictionary<String, DbgType*> DbgTypeMapType;
  885. typedef Dictionary<String, std::pair<uint64, uint64> > DbgAutoValueMapType;
  886. typedef Dictionary<addr_target, int> DbgAutoStaticEntryBucketMap;
  887. struct DbgDeferredHotResolve
  888. {
  889. public:
  890. DbgHotTargetSection* mHotTargetSection;
  891. String mName;
  892. addr_target mNewAddr;
  893. COFFRelocation mReloc;
  894. };
  895. class DbgDataMap
  896. {
  897. public:
  898. // All entries we want to put in this map are at least 4 bytes apart
  899. static const int IDX_DIV = 4;
  900. DbgDebugData** mAddrs;
  901. int mOffset;
  902. int mSize;
  903. DbgDataMap(int startIdx, int endIdx)
  904. {
  905. mOffset = startIdx;
  906. mSize = (((endIdx - startIdx) + IDX_DIV - 1) / IDX_DIV) + 4; // Add a few extra at the end
  907. mAddrs = new DbgDebugData*[mSize];
  908. memset(mAddrs, 0, sizeof(DbgDebugData*)*mSize);
  909. }
  910. ~DbgDataMap()
  911. {
  912. delete mAddrs;
  913. }
  914. void Set(int tagIdx, DbgDebugData* debugData)
  915. {
  916. BF_ASSERT(debugData->mTagIdx == 0);
  917. debugData->mTagIdx = tagIdx;
  918. int mapIdx = (tagIdx - mOffset) / IDX_DIV;
  919. BF_ASSERT(mapIdx < mSize);
  920. // Search for empty slot
  921. while (true)
  922. {
  923. BF_ASSERT(mapIdx < mSize);
  924. if (mAddrs[mapIdx] == NULL)
  925. {
  926. mAddrs[mapIdx] = debugData;
  927. break;
  928. }
  929. mapIdx++;
  930. }
  931. }
  932. template <typename T>
  933. T Get(int tagIdx)
  934. {
  935. int mapIdx = (tagIdx - mOffset) / IDX_DIV;
  936. // Search for right slot
  937. while (mapIdx < mSize)
  938. {
  939. DbgDebugData* checkData = mAddrs[mapIdx];
  940. if (checkData == NULL)
  941. return NULL;
  942. if (checkData->mTagIdx == tagIdx)
  943. return (T)checkData;
  944. mapIdx++;
  945. }
  946. return NULL;
  947. }
  948. };
  949. class WdStackFrame;
  950. enum DbgModuleLoadState
  951. {
  952. DbgModuleLoadState_NotLoaded,
  953. DbgModuleLoadState_Failed,
  954. DbgModuleLoadState_Loaded
  955. };
  956. enum DbgEvalLocFlags
  957. {
  958. DbgEvalLocFlag_None = 0,
  959. DbgEvalLocFlag_DisallowReg = 1,
  960. DbgEvalLocFlag_IsParam = 2
  961. };
  962. struct DbgSizedArrayEntry
  963. {
  964. DbgType* mElementType;
  965. int mCount;
  966. bool operator==(const DbgSizedArrayEntry& other) const
  967. {
  968. return (other.mElementType == mElementType) &&
  969. (other.mCount == mCount);
  970. }
  971. };
  972. class DbgModule
  973. {
  974. public:
  975. static const int ImageBlockSize = 4096;
  976. WinDebugger* mDebugger;
  977. DebugTarget* mDebugTarget;
  978. DbgModuleLoadState mLoadState;
  979. MappedFile* mMappedImageFile;
  980. MemReporter* mMemReporter;
  981. const uint8* mDebugLineData;
  982. const uint8* mDebugInfoData;
  983. const uint8* mDebugPubNames;
  984. const uint8* mDebugFrameData;
  985. const uint8* mDebugLocationData;
  986. const uint8* mDebugRangesData;
  987. addr_target mDebugFrameAddress;
  988. addr_target mCodeAddress;
  989. const uint8* mDebugAbbrevData;
  990. const uint8* mDebugStrData;
  991. const uint8** mDebugAbbrevPtrData;
  992. Array<DbgSectionData> mExceptionDirectory;
  993. const uint8* mEHFrameData;
  994. const char* mStringTable;
  995. const uint8* mSymbolData;
  996. addr_target mEHFrameAddress;
  997. addr_target mTLSAddr;
  998. addr_target mTLSExtraAddr;
  999. int mTLSSize;
  1000. int mTLSExtraSize;
  1001. addr_target mTLSIndexAddr;
  1002. DbgFlavor mDbgFlavor;
  1003. bool mParsedGlobalsData;
  1004. bool mParsedSymbolData;
  1005. bool mParsedTypeData;
  1006. bool mPopulatedStaticVariables;
  1007. bool mParsedFrameDescriptors;
  1008. bool mMayBeOld; // If we had to load debug info from the SymCache or a SymServer then it may be old
  1009. bool mDeleting;
  1010. bool mFailed;
  1011. int mHotIdx;
  1012. String mFilePath;
  1013. String mDisplayName;
  1014. uint32 mTimeStamp;
  1015. uint32 mExpectedFileSize;
  1016. int mStartSubprogramIdx;
  1017. int mEndSubprogramIdx;
  1018. int mStartTypeIdx;
  1019. int mEndTypeIdx;
  1020. uintptr mPreferredImageBase;
  1021. uintptr mImageBase;
  1022. uint32 mImageSize;
  1023. uintptr mEntryPoint;
  1024. String mVersion;
  1025. String* mFailMsgPtr;
  1026. DbgType* mBfTypeType;
  1027. intptr mBfTypesInfoAddr;
  1028. DbgModuleMemoryCache* mOrigImageData;
  1029. DbgCompileUnit* mMasterCompileUnit;
  1030. StrHashMap<DbgVariable*> mGlobalVarMap; // Dedups entries into mMasterCompileUnit
  1031. BumpAllocator mAlloc;
  1032. std::list<DwAsmDebugLineMap> mAsmDebugLineMaps;
  1033. Array<DbgSection> mSections;
  1034. Dictionary<addr_target, int> mSecRelEncodingMap;
  1035. Array<addr_target> mSecRelEncodingVec;
  1036. bool mCheckedBfObject;
  1037. bool mBfObjectHasFlags;
  1038. DbgModuleKind mModuleKind;
  1039. bool mIsDwarf64;
  1040. HashSet<DbgSrcFile*> mSrcFileDeferredRefs;
  1041. Array<addr_target> mSectionRVAs;
  1042. SLIList<DbgSymbol*> mDeferredSymbols;
  1043. Beefy::OwnedVector<DbgDeferredHotResolve> mDeferredHotResolveList;
  1044. Array<DbgHotTargetSection*> mHotTargetSections;
  1045. HashSet<DbgType*> mHotPrimaryTypes; // List of types where we have entries in mHotReplacedMethodList
  1046. DbgCompileUnit mDefaultCompileUnit;
  1047. Dictionary<DbgType*, DbgType*> mConstTypes;
  1048. Dictionary<String, DbgFileExistKind> mFileExistsCache;
  1049. Dictionary<DbgSizedArrayEntry, DbgType*> mSizedArrayTypes;
  1050. int mAllocSizeData;
  1051. Array<const uint8*> mOwnedSectionData;
  1052. public:
  1053. Array<DbgSrcFile*> mEmptySrcFiles;
  1054. Array<DbgCompileUnit*> mCompileUnits;
  1055. Array<DbgVariable*> mStaticVariables;
  1056. DbgType* mCPrimitiveTypes[DbgType_COUNT];
  1057. DbgType* mBfPrimitiveTypes[DbgType_COUNT];
  1058. const char* mPrimitiveStructNames[DbgType_COUNT];
  1059. DbgTypeMap mTypeMap;
  1060. Array<DbgType*> mTypes;
  1061. Array<DbgSubprogram*> mSubprograms;
  1062. StrHashMap<DbgSymbol*> mSymbolNameMap;
  1063. std::unordered_map<const char*, DbgVariable*, DbgCharPtrHash, DbgCharPtrEquals> mStaticVariableMap;
  1064. public:
  1065. virtual void ParseGlobalsData();
  1066. virtual void ParseSymbolData();
  1067. virtual void ParseTypeData();
  1068. virtual DbgCompileUnit* ParseCompileUnit(int compileUnitId);
  1069. virtual void ParseCompileUnits() {}
  1070. virtual void MapCompileUnitMethods(DbgCompileUnit* compileUnit);
  1071. virtual void MapCompileUnitMethods(int compileUnitId);
  1072. virtual void PopulateType(DbgType* dbgType);
  1073. virtual void PopulateTypeGlobals(DbgType* dbgType);
  1074. virtual void PopulateSubprogram(DbgSubprogram* dbgSubprogram) { }
  1075. virtual void FixupInlinee(DbgSubprogram* dbgSubprogram) {}
  1076. virtual void PopulateStaticVariableMap();
  1077. virtual void ProcessDebugInfo();
  1078. virtual bool CanGetOldSource() { return false; }
  1079. virtual String GetOldSourceCommand(const StringImpl& path) { return ""; }
  1080. virtual bool DbgIsStrMutable(const char* str) { return true; } // Always assume its a copy
  1081. virtual addr_target LocateSymbol(const StringImpl& name) { return 0; }
  1082. virtual DbgSubprogram* FindSubprogram(DbgType* dbgType, const char* methodName);
  1083. const char* GetStringTable(DataStream* stream, int stringTablePos);
  1084. void Fail(const StringImpl& error);
  1085. void FindTemplateStr(const char*& name, int& templateNameIdx);
  1086. void TempRemoveTemplateStr(const char*& name, int& templateNameIdx);
  1087. void ReplaceTemplateStr(const char*& name, int& templateNameIdx);
  1088. char* DbgDupString(const char* str, const char* allocName = NULL);
  1089. DbgModule* GetLinkedModule();
  1090. addr_target GetTargetImageBase();
  1091. addr_target RemapAddr(addr_target addr);
  1092. template <typename T>
  1093. T GetOrCreate(int idx, DbgDataMap& dataMap);
  1094. DbgType* GetOrCreateType(int typeIdx, DbgDataMap& typeMap);
  1095. //void SplitName(const char* inName, const char*& outBaseName, const char*& outTemplateParams, bool alwaysDup = false);
  1096. void MapSubprogram(DbgSubprogram* dbgSubprogram);
  1097. bool ParseDWARF(const uint8*& dataPtr);
  1098. void ParseAbbrevData(const uint8* data);
  1099. void ParseExceptionData();
  1100. void ParseDebugFrameData();
  1101. void ParseEHFrameData();
  1102. void FlushLineData(DbgSubprogram* curSubprogram, std::list<DbgLineData>& queuedLineData);
  1103. DbgSrcFile* AddSrcFile(DbgCompileUnit* compileUnit, const String& srcFilePath);
  1104. void AddLineData(DbgCompileUnit* dwCompileUnit, DbgLineData& lineData, DbgSubprogram*& curSubProgram, std::list<DbgLineData>& queuedLineData);
  1105. bool ParseDebugLineInfo(const uint8*& data, int compileUnitIdx);
  1106. void FixupInnerTypes(int startingTypeIdx);
  1107. void MapTypes(int startingTypeIdx);
  1108. void CreateNamespaces();
  1109. bool IsObjectFile() { return mModuleKind != DbgModuleKind_Module; }
  1110. bool IsHotSwapObjectFile() { return mModuleKind == DbgModuleKind_HotObject; }
  1111. bool IsHotSwapPreserve(const String& name);
  1112. addr_target GetHotTargetAddress(DbgHotTargetSection* hotTargetSection);
  1113. uint8* GetHotTargetData(addr_target address);
  1114. void DoReloc(DbgHotTargetSection* hotTargetSection, COFFRelocation& coffReloc, addr_target resolveSymbolAddr, PE_SymInfo* symInfo);
  1115. void ParseHotTargetSections(DataStream* stream, addr_target* resovledSymbolAddrs);
  1116. void CommitHotTargetSections();
  1117. void HotReplaceType(DbgType* newType);
  1118. void ProcessHotSwapVariables();
  1119. virtual bool LoadPDB(const String& pdbPath, uint8 wantGuid[16], int32 wantAge) { return false; }
  1120. virtual bool CheckSection(const char* name, uint8* sectionData, int sectionSize) { return false; }
  1121. virtual void PreCacheImage() {}
  1122. virtual void PreCacheDebugInfo() {}
  1123. virtual bool RequestImage() { return false; }
  1124. virtual bool HasPendingDebugInfo() { return false; }
  1125. virtual bool RequestDebugInfo(bool allowRemote = true) { return false; }
  1126. virtual bool WantsAutoLoadDebugInfo() { return false; }
  1127. virtual DbgFileExistKind CheckSourceFileExist(const StringImpl& path);
  1128. virtual void ParseFrameDescriptors() {}
  1129. template <typename T>
  1130. T ReadValue(const uint8*& data, int form, int refOffset = 0, const uint8** extraData = NULL, const uint8* startData = NULL);
  1131. void EnableWriting(addr_target address);
  1132. void RevertWritingEnable();
  1133. public:
  1134. DbgModule(DebugTarget* debugTarget);
  1135. virtual ~DbgModule();
  1136. static bool CanRead(DataStream* stream, DebuggerResult* outResult);
  1137. bool ReadCOFF(DataStream* stream, DbgModuleKind dbgModuleKind);
  1138. void RemoveTargetData();
  1139. virtual void ReportMemory(MemReporter* memReporter);
  1140. int64 GetImageSize();
  1141. virtual void FinishHotSwap();
  1142. addr_target ExecuteOps(DbgSubprogram* dwSubprogram, const uint8* locData, int locDataLen, WdStackFrame* stackFrame, CPURegisters* registers, DbgAddrType* outAddrType, DbgEvalLocFlags flags, addr_target* pushValue = NULL);
  1143. virtual intptr EvaluateLocation(DbgSubprogram* dwSubprogram, const uint8* locData, int locDataLen, WdStackFrame* stackFrame, DbgAddrType* outAddrType, DbgEvalLocFlags flags = DbgEvalLocFlag_None);
  1144. //const uint8* CopyOrigImageData(addr_target address, int length);
  1145. DbgType* FindTypeHelper(const String& typeName, DbgType* checkType);
  1146. DbgType* FindType(const String& typeName, DbgType* contextType = NULL, DbgLanguage language = DbgLanguage_Unknown, bool bfObjectPtr = false);
  1147. DbgTypeMap::Entry* FindType(const char* typeName, DbgLanguage language);
  1148. DbgType* GetPointerType(DbgType* innerType);
  1149. DbgType* GetConstType(DbgType* innerType);
  1150. DbgType* GetPrimaryType(DbgType* dbgType);
  1151. DbgType* GetPrimitiveType(DbgTypeCode typeCode, DbgLanguage language);
  1152. DbgType* GetPrimitiveStructType(DbgTypeCode typeCode);
  1153. DbgType* GetInnerTypeOrVoid(DbgType* dbgType);
  1154. DbgType* GetSizedArrayType(DbgType* elementType, int count);
  1155. };
  1156. NS_BF_END
  1157. namespace std
  1158. {
  1159. template<>
  1160. struct hash<NS_BF_DBG::DbgSizedArrayEntry>
  1161. {
  1162. size_t operator()(const NS_BF_DBG::DbgSizedArrayEntry& val) const
  1163. {
  1164. return (size_t)val.mElementType ^ (val.mCount << 10);
  1165. }
  1166. };
  1167. }