DbgModule.h 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333
  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 mId;
  1012. int mHotIdx;
  1013. String mFilePath;
  1014. String mDisplayName;
  1015. uint32 mTimeStamp;
  1016. uint32 mExpectedFileSize;
  1017. int mStartSubprogramIdx;
  1018. int mEndSubprogramIdx;
  1019. int mStartTypeIdx;
  1020. int mEndTypeIdx;
  1021. uintptr mPreferredImageBase;
  1022. uintptr mImageBase;
  1023. uint32 mImageSize;
  1024. uintptr mEntryPoint;
  1025. String mVersion;
  1026. String* mFailMsgPtr;
  1027. DbgType* mBfTypeType;
  1028. intptr mBfTypesInfoAddr;
  1029. DbgModuleMemoryCache* mOrigImageData;
  1030. DbgCompileUnit* mMasterCompileUnit;
  1031. StrHashMap<DbgVariable*> mGlobalVarMap; // Dedups entries into mMasterCompileUnit
  1032. BumpAllocator mAlloc;
  1033. std::list<DwAsmDebugLineMap> mAsmDebugLineMaps;
  1034. Array<DbgSection> mSections;
  1035. Dictionary<addr_target, int> mSecRelEncodingMap;
  1036. Array<addr_target> mSecRelEncodingVec;
  1037. bool mCheckedBfObject;
  1038. bool mBfObjectHasFlags;
  1039. DbgModuleKind mModuleKind;
  1040. bool mIsDwarf64;
  1041. HashSet<DbgSrcFile*> mSrcFileDeferredRefs;
  1042. Array<addr_target> mSectionRVAs;
  1043. SLIList<DbgSymbol*> mDeferredSymbols;
  1044. Beefy::OwnedVector<DbgDeferredHotResolve> mDeferredHotResolveList;
  1045. Array<DbgHotTargetSection*> mHotTargetSections;
  1046. HashSet<DbgType*> mHotPrimaryTypes; // List of types where we have entries in mHotReplacedMethodList
  1047. DbgCompileUnit mDefaultCompileUnit;
  1048. Dictionary<DbgType*, DbgType*> mConstTypes;
  1049. Dictionary<String, DbgFileExistKind> mFileExistsCache;
  1050. Dictionary<DbgSizedArrayEntry, DbgType*> mSizedArrayTypes;
  1051. int mAllocSizeData;
  1052. Array<const uint8*> mOwnedSectionData;
  1053. public:
  1054. Array<DbgSrcFile*> mEmptySrcFiles;
  1055. Array<DbgCompileUnit*> mCompileUnits;
  1056. Array<DbgVariable*> mStaticVariables;
  1057. DbgType* mCPrimitiveTypes[DbgType_COUNT];
  1058. DbgType* mBfPrimitiveTypes[DbgType_COUNT];
  1059. const char* mPrimitiveStructNames[DbgType_COUNT];
  1060. DbgTypeMap mTypeMap;
  1061. Array<DbgType*> mTypes;
  1062. Array<DbgSubprogram*> mSubprograms;
  1063. StrHashMap<DbgSymbol*> mSymbolNameMap;
  1064. std::unordered_map<const char*, DbgVariable*, DbgCharPtrHash, DbgCharPtrEquals> mStaticVariableMap;
  1065. public:
  1066. virtual void ParseGlobalsData();
  1067. virtual void ParseSymbolData();
  1068. virtual void ParseTypeData();
  1069. virtual DbgCompileUnit* ParseCompileUnit(int compileUnitId);
  1070. virtual void ParseCompileUnits() {}
  1071. virtual void MapCompileUnitMethods(DbgCompileUnit* compileUnit);
  1072. virtual void MapCompileUnitMethods(int compileUnitId);
  1073. virtual void PopulateType(DbgType* dbgType);
  1074. virtual void PopulateTypeGlobals(DbgType* dbgType);
  1075. virtual void PopulateSubprogram(DbgSubprogram* dbgSubprogram) { }
  1076. virtual void FixupInlinee(DbgSubprogram* dbgSubprogram) {}
  1077. virtual void PopulateStaticVariableMap();
  1078. virtual void ProcessDebugInfo();
  1079. virtual bool CanGetOldSource() { return false; }
  1080. virtual String GetOldSourceCommand(const StringImpl& path) { return ""; }
  1081. virtual bool GetEmitSource(const StringImpl& filePath, String& outText) { return false; }
  1082. virtual bool DbgIsStrMutable(const char* str) { return true; } // Always assume its a copy
  1083. virtual addr_target LocateSymbol(const StringImpl& name) { return 0; }
  1084. virtual DbgSubprogram* FindSubprogram(DbgType* dbgType, const char* methodName);
  1085. const char* GetStringTable(DataStream* stream, int stringTablePos);
  1086. virtual void Fail(const StringImpl& error);
  1087. virtual void SoftFail(const StringImpl& error);
  1088. virtual void HardFail(const StringImpl& error);
  1089. void FindTemplateStr(const char*& name, int& templateNameIdx);
  1090. void TempRemoveTemplateStr(const char*& name, int& templateNameIdx);
  1091. void ReplaceTemplateStr(const char*& name, int& templateNameIdx);
  1092. char* DbgDupString(const char* str, const char* allocName = NULL);
  1093. DbgModule* GetLinkedModule();
  1094. addr_target GetTargetImageBase();
  1095. addr_target RemapAddr(addr_target addr);
  1096. template <typename T>
  1097. T GetOrCreate(int idx, DbgDataMap& dataMap);
  1098. DbgType* GetOrCreateType(int typeIdx, DbgDataMap& typeMap);
  1099. //void SplitName(const char* inName, const char*& outBaseName, const char*& outTemplateParams, bool alwaysDup = false);
  1100. void MapSubprogram(DbgSubprogram* dbgSubprogram);
  1101. bool ParseDWARF(const uint8*& dataPtr);
  1102. void ParseAbbrevData(const uint8* data);
  1103. void ParseExceptionData();
  1104. void ParseDebugFrameData();
  1105. void ParseEHFrameData();
  1106. void FlushLineData(DbgSubprogram* curSubprogram, std::list<DbgLineData>& queuedLineData);
  1107. DbgSrcFile* AddSrcFile(DbgCompileUnit* compileUnit, const String& srcFilePath);
  1108. void AddLineData(DbgCompileUnit* dwCompileUnit, DbgLineData& lineData, DbgSubprogram*& curSubProgram, std::list<DbgLineData>& queuedLineData);
  1109. bool ParseDebugLineInfo(const uint8*& data, int compileUnitIdx);
  1110. void FixupInnerTypes(int startingTypeIdx);
  1111. void MapTypes(int startingTypeIdx);
  1112. void CreateNamespaces();
  1113. bool IsObjectFile() { return mModuleKind != DbgModuleKind_Module; }
  1114. bool IsHotSwapObjectFile() { return mModuleKind == DbgModuleKind_HotObject; }
  1115. bool IsHotSwapPreserve(const String& name);
  1116. addr_target GetHotTargetAddress(DbgHotTargetSection* hotTargetSection);
  1117. uint8* GetHotTargetData(addr_target address);
  1118. void DoReloc(DbgHotTargetSection* hotTargetSection, COFFRelocation& coffReloc, addr_target resolveSymbolAddr, PE_SymInfo* symInfo);
  1119. void ParseHotTargetSections(DataStream* stream, addr_target* resovledSymbolAddrs);
  1120. void CommitHotTargetSections();
  1121. void HotReplaceType(DbgType* newType);
  1122. void ProcessHotSwapVariables();
  1123. virtual bool LoadPDB(const String& pdbPath, uint8 wantGuid[16], int32 wantAge) { return false; }
  1124. virtual bool CheckSection(const char* name, uint8* sectionData, int sectionSize) { return false; }
  1125. virtual void PreCacheImage() {}
  1126. virtual void PreCacheDebugInfo() {}
  1127. virtual bool RequestImage() { return false; }
  1128. virtual bool HasPendingDebugInfo() { return false; }
  1129. virtual bool RequestDebugInfo(bool allowRemote = true) { return false; }
  1130. virtual bool WantsAutoLoadDebugInfo() { return false; }
  1131. virtual DbgFileExistKind CheckSourceFileExist(const StringImpl& path);
  1132. virtual void ParseFrameDescriptors() {}
  1133. template <typename T>
  1134. T ReadValue(const uint8*& data, int form, int refOffset = 0, const uint8** extraData = NULL, const uint8* startData = NULL);
  1135. void EnableWriting(addr_target address);
  1136. void RevertWritingEnable();
  1137. public:
  1138. DbgModule(DebugTarget* debugTarget);
  1139. virtual ~DbgModule();
  1140. static bool CanRead(DataStream* stream, DebuggerResult* outResult);
  1141. bool ReadCOFF(DataStream* stream, DbgModuleKind dbgModuleKind);
  1142. void RemoveTargetData();
  1143. virtual void ReportMemory(MemReporter* memReporter);
  1144. int64 GetImageSize();
  1145. virtual void FinishHotSwap();
  1146. addr_target ExecuteOps(DbgSubprogram* dwSubprogram, const uint8* locData, int locDataLen, WdStackFrame* stackFrame, CPURegisters* registers, DbgAddrType* outAddrType, DbgEvalLocFlags flags, addr_target* pushValue = NULL);
  1147. virtual intptr EvaluateLocation(DbgSubprogram* dwSubprogram, const uint8* locData, int locDataLen, WdStackFrame* stackFrame, DbgAddrType* outAddrType, DbgEvalLocFlags flags = DbgEvalLocFlag_None);
  1148. //const uint8* CopyOrigImageData(addr_target address, int length);
  1149. DbgType* FindTypeHelper(const String& typeName, DbgType* checkType);
  1150. DbgType* FindType(const String& typeName, DbgType* contextType = NULL, DbgLanguage language = DbgLanguage_Unknown, bool bfObjectPtr = false);
  1151. DbgTypeMap::Entry* FindType(const char* typeName, DbgLanguage language);
  1152. DbgType* GetPointerType(DbgType* innerType);
  1153. DbgType* GetConstType(DbgType* innerType);
  1154. DbgType* GetPrimaryType(DbgType* dbgType);
  1155. DbgType* GetPrimitiveType(DbgTypeCode typeCode, DbgLanguage language);
  1156. DbgType* GetPrimitiveStructType(DbgTypeCode typeCode);
  1157. DbgType* GetInnerTypeOrVoid(DbgType* dbgType);
  1158. DbgType* GetSizedArrayType(DbgType* elementType, int count);
  1159. };
  1160. NS_BF_END
  1161. namespace std
  1162. {
  1163. template<>
  1164. struct hash<NS_BF_DBG::DbgSizedArrayEntry>
  1165. {
  1166. size_t operator()(const NS_BF_DBG::DbgSizedArrayEntry& val) const
  1167. {
  1168. return (size_t)val.mElementType ^ (val.mCount << 10);
  1169. }
  1170. };
  1171. }