BeCOFFObject.h 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. #pragma once
  2. #include "BeMCContext.h"
  3. #include "BeefySysLib/FileStream.h"
  4. #include "../Compiler/BfCodeGen.h"
  5. #include "BeefySysLib/MemStream.h"
  6. NS_BF_BEGIN
  7. enum BeMCSymbolKind
  8. {
  9. BeMCSymbolKind_AuxPlaceholder,
  10. BeMCSymbolKind_SectionDef,
  11. BeMCSymbolKind_SectionCOFFDef,
  12. BeMCSymbolKind_SectionRef,
  13. BeMCSymbolKind_External,
  14. BeMCSymbolKind_Function,
  15. BeMCSymbolKind_COMDAT
  16. };
  17. class BeMCSymbol
  18. {
  19. public:
  20. String mName;
  21. BeType* mType;
  22. bool mIsStatic;
  23. bool mIsTLS;
  24. BeMCSymbolKind mSymKind;
  25. int mValue;
  26. int mIdx;
  27. int mSectionNum;
  28. BeFunction* mBeFunction;
  29. public:
  30. BeMCSymbol()
  31. {
  32. mType = NULL;
  33. mIsStatic = false;
  34. mIsTLS = false;
  35. mSymKind = BeMCSymbolKind_External;
  36. mValue = 0;
  37. mIdx = -1;
  38. mSectionNum = 0;
  39. mBeFunction = NULL;
  40. }
  41. };
  42. enum BeMCRelocationKind
  43. {
  44. BeMCRelocationKind_NONE,
  45. BeMCRelocationKind_ADDR32NB,
  46. BeMCRelocationKind_ADDR64,
  47. BeMCRelocationKind_REL32,
  48. BeMCRelocationKind_SECREL,
  49. BeMCRelocationKind_SECTION,
  50. };
  51. class BeMCRelocation
  52. {
  53. public:
  54. BeMCRelocationKind mKind;
  55. int mOffset;
  56. int mSymTableIdx;
  57. };
  58. class BeCOFFSection
  59. {
  60. public:
  61. DynMemStream mData;
  62. Array<BeMCRelocation> mRelocs;
  63. int mSymbolIdx;
  64. int mSectionIdx;
  65. String mSectName;
  66. int mCharacteristics;
  67. int mSizeOverride;
  68. int mAlign;
  69. public:
  70. BeCOFFSection()
  71. {
  72. mSymbolIdx = -1;
  73. mSectionIdx = -1;
  74. mCharacteristics = 0;
  75. mSizeOverride = 0;
  76. mAlign = 0;
  77. }
  78. };
  79. struct BeInlineLineBuilder
  80. {
  81. public:
  82. Array<uint8> mData;
  83. int mCurLine;
  84. int mCurCodePos;
  85. BeDbgLoc* mStartDbgLoc;
  86. bool mEnded;
  87. Array<BeDbgVariable*> mVariables;
  88. public:
  89. BeInlineLineBuilder();
  90. void Compress(int val);
  91. void WriteSigned(int val);
  92. void Update(BeDbgCodeEmission* codeEmission);
  93. void Start(BeDbgCodeEmission* codeEmission);
  94. void End(BeDbgCodeEmission* codeEmission);
  95. };
  96. struct COFFArgListRef
  97. {
  98. public:
  99. BeDbgFunction* mFunc;
  100. COFFArgListRef()
  101. {
  102. mFunc = NULL;
  103. }
  104. COFFArgListRef(BeDbgFunction* func)
  105. {
  106. mFunc = func;
  107. }
  108. bool operator==(const COFFArgListRef& rhsRef) const
  109. {
  110. auto lhs = mFunc;
  111. auto rhs = rhsRef.mFunc;
  112. int lhsParamOfs = lhs->HasThis() ? 1 : 0;
  113. int rhsParamOfs = rhs->HasThis() ? 1 : 0;
  114. if (lhs->mType->mParams.size() - lhsParamOfs != rhs->mType->mParams.size() - rhsParamOfs)
  115. return false;
  116. for (int i = 0; i < (int)lhs->mType->mParams.size() - lhsParamOfs; i++)
  117. if (lhs->mType->mParams[i + lhsParamOfs] != rhs->mType->mParams[i + rhsParamOfs])
  118. return false;
  119. return true;
  120. }
  121. };
  122. struct COFFFuncTypeRef
  123. {
  124. public:
  125. BeDbgFunction* mFunc;
  126. COFFFuncTypeRef()
  127. {
  128. mFunc = NULL;
  129. }
  130. COFFFuncTypeRef(BeDbgFunction* func)
  131. {
  132. mFunc = func;
  133. }
  134. bool operator==(const COFFFuncTypeRef& rhsRef) const
  135. {
  136. auto lhs = mFunc;
  137. auto rhs = rhsRef.mFunc;
  138. if (lhs->mIsStaticMethod != rhs->mIsStaticMethod)
  139. return false;
  140. if (lhs->mScope != rhs->mScope)
  141. return false;
  142. if (lhs->mType->mReturnType != rhs->mType->mReturnType)
  143. return false;
  144. if (lhs->mType->mParams.size() != rhs->mType->mParams.size())
  145. return false;
  146. for (int i = 0; i < (int)lhs->mType->mParams.size(); i++)
  147. if (lhs->mType->mParams[i] != rhs->mType->mParams[i])
  148. return false;
  149. return true;
  150. }
  151. };
  152. NS_BF_END;
  153. namespace std
  154. {
  155. template <>
  156. struct hash<Beefy::COFFArgListRef>
  157. {
  158. size_t operator()(const Beefy::COFFArgListRef& val)
  159. {
  160. auto func = val.mFunc;
  161. intptr curHash = 0;
  162. for (int paramIdx = func->HasThis() ? 1 : 0; paramIdx < (int)func->mType->mParams.size(); paramIdx++)
  163. curHash = Beefy::Hash64((intptr)func->mType->mParams[paramIdx], curHash);
  164. return curHash;
  165. }
  166. };
  167. template <>
  168. struct hash<Beefy::COFFFuncTypeRef>
  169. {
  170. size_t operator()(const Beefy::COFFFuncTypeRef& val)
  171. {
  172. auto func = val.mFunc;
  173. intptr curHash = (intptr)func->mType->mReturnType;
  174. for (int paramIdx = 0; paramIdx < (int)func->mType->mParams.size(); paramIdx++)
  175. curHash = Beefy::Hash64((intptr)func->mType->mParams[paramIdx], curHash);
  176. return curHash;
  177. }
  178. };
  179. }
  180. NS_BF_BEGIN;
  181. class BeCOFFObject
  182. {
  183. public:
  184. bool mWriteToLib;
  185. PerfManager* mPerfManager;
  186. DataStream* mStream;
  187. BumpAllocator mAlloc;
  188. BeModule* mBeModule;
  189. OwnedVector<BeMCSymbol> mSymbols;
  190. OwnedVector<BeCOFFSection> mDynSects;
  191. uint32 mTimestamp;
  192. BeCOFFSection mTextSect;
  193. BeCOFFSection mDataSect;
  194. BeCOFFSection mRDataSect;
  195. BeCOFFSection mBSSSect;
  196. BeCOFFSection mTLSSect;
  197. BeCOFFSection mPDataSect;
  198. BeCOFFSection mXDataSect;
  199. BeCOFFSection mDebugSSect;
  200. BeCOFFSection mDebugTSect;
  201. BeCOFFSection mDirectiveSect;
  202. DynMemStream mStrTable;
  203. int mBSSPos;
  204. Array<BeCOFFSection*> mUsedSections;
  205. Dictionary<BeValue*, BeMCSymbol*> mSymbolMap;
  206. Dictionary<String, BeMCSymbol*> mNamedSymbolMap;
  207. HashSet<COFFArgListRef> mArgListSet;
  208. HashSet<COFFFuncTypeRef> mFuncTypeSet;
  209. Deque<BeFunction*> mFuncWorkList;
  210. int mTTagStartPos;
  211. int mSTagStartPos;
  212. int mCurTagId;
  213. int mSectionStartPos;
  214. int mCurStringId;
  215. int mCurJumpTableIdx;
  216. bool mTypesLocked;
  217. String mDirectives;
  218. public:
  219. void ToString(BeMDNode* mdNode, String& str);
  220. int GetCVRegNum(X64CPURegister reg, int bits);
  221. void DbgTAlign();
  222. void DbgTStartTag();
  223. void DbgTEndTag();
  224. void DbgEncodeConstant(DynMemStream& memStream, int64 val);
  225. void DbgEncodeString(DynMemStream& memStream, const StringImpl& str);
  226. void DbgMakeFuncType(BeDbgFunction* dbgFunc);
  227. void DbgMakeFunc(BeDbgFunction* dbgFunc);
  228. int DbgGetTypeId(BeDbgType* dbgType, bool doDefine = false);
  229. void DbgGenerateTypeInfo();
  230. void DbgSAlign();
  231. void DbgSStartTag();
  232. void DbgSEndTag();
  233. void DbgOutputLocalVar(BeDbgFunction* dbgFunc, BeDbgVariable* dbgVar);
  234. void DbgOutputLocalVars(BeInlineLineBuilder* curInlineBuilder, BeDbgFunction* func);
  235. void DbgStartSection(int sectionNum);
  236. void DbgEndSection();
  237. void DbgStartVarDefRange(BeDbgFunction* dbgFunc, BeDbgVariable* dbgVar, const BeDbgVariableLoc& varLoc, int offset, int range);
  238. void DbgEndLineBlock(BeDbgFunction* dbgFunc, const Array<BeDbgCodeEmission>& emissions, int blockStartPos, int emissionStartIdx, int lineCount);
  239. void DbgGenerateModuleInfo();
  240. void InitSect(BeCOFFSection& sect, const StringImpl& name, int characteristics, bool addNow, bool makeSectSymbol);
  241. void AlignConst(BeCOFFSection& sect, BeConstant* constVal);
  242. void WriteConst(BeCOFFSection& sect, BeConstant* constVal);
  243. void Generate(BeModule* module);
  244. public:
  245. BeCOFFObject();
  246. void Finish();
  247. bool Generate(BeModule* module, const StringImpl& fileName);
  248. BeMCSymbol* GetSymbol(BeValue* value, bool allowCreate = true);
  249. BeMCSymbol* GetSymbolRef(const StringImpl& name);
  250. void MarkSectionUsed(BeCOFFSection& sect, bool getSectSymbol = false);
  251. BeMCSymbol* GetCOMDAT(const StringImpl& name, void* data, int size, int align);
  252. BeCOFFSection* CreateSect(const StringImpl& name, int characteristics, bool makeSectSymbol = true);
  253. };
  254. NS_BF_END