BeCOFFObject.cpp 71 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577
  1. #include "BeCOFFObject.h"
  2. #include "BeMCContext.h"
  3. #include "BeLibManger.h"
  4. #include "../COFFData.h"
  5. #include "BeefySysLib/MemStream.h"
  6. #include "codeview/cvinfo.h"
  7. #include "BeefySysLib/util/BeefPerf.h"
  8. #include "llvm/IR/DIBuilder.h"
  9. #include "BeefySysLib/util/AllocDebug.h"
  10. #pragma warning(disable:4996)
  11. USING_NS_BF;
  12. //////////////////////////////////////////////////////////////////////////
  13. BeInlineLineBuilder::BeInlineLineBuilder()
  14. {
  15. mCurLine = 0;
  16. mCurCodePos = 0;
  17. mStartDbgLoc = NULL;
  18. mEnded = false;
  19. }
  20. void BeInlineLineBuilder::Compress(int val)
  21. {
  22. if (val <= 0x7F)
  23. {
  24. mData.push_back((uint8)val);
  25. return;
  26. }
  27. if (val <= 0x3FFF)
  28. {
  29. mData.push_back((uint8)(val >> 8) | 0x80);
  30. mData.push_back((uint8)(val & 0xFF));
  31. return;
  32. }
  33. if (val <= 0x1FFFFFFF)
  34. {
  35. mData.push_back((uint8)(val >> 24) | 0xC0);
  36. mData.push_back((uint8)((val >> 16) & 0xFF));
  37. mData.push_back((uint8)((val >> 8) & 0xFF));
  38. mData.push_back((uint8)(val & 0xFF));
  39. return;
  40. }
  41. }
  42. void BeInlineLineBuilder::WriteSigned(int val)
  43. {
  44. if (val < 0)
  45. Compress(-val * 2 + 1);
  46. else
  47. Compress(val * 2);
  48. }
  49. void BeInlineLineBuilder::Update(BeDbgCodeEmission* codeEmission)
  50. {
  51. BF_ASSERT(!mEnded);
  52. int lineOfs = codeEmission->mDbgLoc->mLine - mCurLine;
  53. int codeOfs = codeEmission->mPos - mCurCodePos;
  54. if (codeOfs != 0)
  55. {
  56. mData.push_back(CodeViewInfo::BA_OP_ChangeLineOffset);
  57. WriteSigned(lineOfs);
  58. mData.push_back(CodeViewInfo::BA_OP_ChangeCodeOffset);
  59. Compress(codeOfs);
  60. mCurLine = codeEmission->mDbgLoc->mLine;
  61. mCurCodePos = codeEmission->mPos;
  62. }
  63. }
  64. void BeInlineLineBuilder::Start(BeDbgCodeEmission* codeEmission)
  65. {
  66. //mCurLine = codeEmission->mDbgLoc->mDbgInlinedAt->mLine;
  67. int lineOfs = codeEmission->mDbgLoc->mLine - mCurLine;
  68. int codeOfs = codeEmission->mPos - mCurCodePos;
  69. auto usingFile = codeEmission->mDbgLoc->mDbgInlinedAt->GetDbgFile();
  70. auto wantFile = codeEmission->mDbgLoc->GetDbgFile();
  71. mData.push_back(CodeViewInfo::BA_OP_ChangeLineOffset);
  72. WriteSigned(lineOfs);
  73. /*if (wantFile != usingFile)
  74. {
  75. mData.push_back(CodeViewInfo::BA_OP_ChangeFile);
  76. Compress(wantFile->mIdx * 8);
  77. }*/
  78. mData.push_back(CodeViewInfo::BA_OP_ChangeCodeOffset);
  79. Compress(codeOfs);
  80. mCurLine = codeEmission->mDbgLoc->mLine;
  81. mCurCodePos = codeEmission->mPos;
  82. /*mData.push_back(CodeViewInfo::BA_OP_ChangeLineOffset);
  83. WriteSigned(-mStartDbgLoc->mDbgInlinedAt->mLine - 1);
  84. mData.push_back(CodeViewInfo::BA_OP_ChangeCodeOffset);
  85. Compress(codeEmission->mPos);
  86. mCurLine = -1;
  87. mCurCodePos = codeEmission->mPos;*/
  88. }
  89. void BeInlineLineBuilder::End(BeDbgCodeEmission* codeEmission)
  90. {
  91. BF_ASSERT(!mEnded);
  92. int codeOfs = codeEmission->mPos - mCurCodePos;
  93. mData.push_back(CodeViewInfo::BA_OP_ChangeCodeLength);
  94. Compress(codeOfs);
  95. mCurCodePos = codeEmission->mPos;
  96. mEnded = true;
  97. }
  98. //////////////////////////////////////////////////////////////////////////
  99. BeCOFFObject::BeCOFFObject()
  100. {
  101. mWriteToLib = false;
  102. mBSSPos = 0;
  103. mCurTagId = 0x1000;
  104. mCurStringId = 0;
  105. mCurJumpTableIdx = 0;
  106. mBeModule = NULL;
  107. mTTagStartPos = -1;
  108. mSTagStartPos = -1;
  109. mSectionStartPos = -1;
  110. mTypesLocked = false;
  111. mTimestamp = 0;
  112. mPerfManager = NULL;
  113. mStream = NULL;
  114. }
  115. void BeCOFFObject::ToString(BeMDNode* mdNode, String& str)
  116. {
  117. if (auto dbgStruct = BeValueDynCast<BeDbgStructType>(mdNode))
  118. {
  119. if (auto dbgNamespace = BeValueDynCast<BeDbgNamespace>(dbgStruct->mScope))
  120. {
  121. ToString(dbgNamespace, str);
  122. str += "::";
  123. }
  124. else if (auto dbgOuterType = BeValueDynCast<BeDbgType>(dbgStruct->mScope))
  125. {
  126. ToString(dbgOuterType, str);
  127. str += "::";
  128. }
  129. str += dbgStruct->mName;
  130. }
  131. else if (auto dbgStruct = BeValueDynCast<BeDbgEnumType>(mdNode))
  132. {
  133. if (auto dbgNamespace = BeValueDynCast<BeDbgNamespace>(dbgStruct->mScope))
  134. {
  135. ToString(dbgNamespace, str);
  136. str += "::";
  137. }
  138. else if (auto dbgOuterType = BeValueDynCast<BeDbgType>(dbgStruct->mScope))
  139. {
  140. ToString(dbgOuterType, str);
  141. str += "::";
  142. }
  143. str += dbgStruct->mName;
  144. }
  145. else if (auto dbgNamespace = BeValueDynCast<BeDbgNamespace>(mdNode))
  146. {
  147. if (auto outerNamespace = BeValueDynCast<BeDbgNamespace>(dbgNamespace->mScope))
  148. {
  149. ToString(outerNamespace, str);
  150. str += "::";
  151. }
  152. str += dbgNamespace->mName;
  153. }
  154. else
  155. {
  156. BF_FATAL("err");
  157. }
  158. }
  159. int BeCOFFObject::GetCVRegNum(X64CPURegister reg, int bits)
  160. {
  161. if (bits == 8)
  162. {
  163. switch (reg)
  164. {
  165. case X64Reg_RAX: return CV_AMD64_AL;
  166. case X64Reg_RDX: return CV_AMD64_DL;
  167. case X64Reg_RCX: return CV_AMD64_CL;
  168. case X64Reg_RBX: return CV_AMD64_BL;
  169. case X64Reg_RSI: return CV_AMD64_SIL;
  170. case X64Reg_RDI: return CV_AMD64_DIL;
  171. case X64Reg_R8: return CV_AMD64_R8B;
  172. case X64Reg_R9: return CV_AMD64_R9B;
  173. case X64Reg_R10: return CV_AMD64_R10B;
  174. case X64Reg_R11: return CV_AMD64_R11B;
  175. case X64Reg_R12: return CV_AMD64_R12B;
  176. case X64Reg_R13: return CV_AMD64_R13B;
  177. case X64Reg_R14: return CV_AMD64_R14B;
  178. case X64Reg_R15: return CV_AMD64_R15B;
  179. }
  180. }
  181. if (bits == 16)
  182. {
  183. switch (reg)
  184. {
  185. case X64Reg_RAX: return CV_AMD64_AX;
  186. case X64Reg_RDX: return CV_AMD64_DX;
  187. case X64Reg_RCX: return CV_AMD64_CX;
  188. case X64Reg_RBX: return CV_AMD64_BX;
  189. case X64Reg_RSI: return CV_AMD64_SI;
  190. case X64Reg_RDI: return CV_AMD64_DI;
  191. case X64Reg_R8: return CV_AMD64_R8W;
  192. case X64Reg_R9: return CV_AMD64_R9W;
  193. case X64Reg_R10: return CV_AMD64_R10W;
  194. case X64Reg_R11: return CV_AMD64_R11W;
  195. case X64Reg_R12: return CV_AMD64_R12W;
  196. case X64Reg_R13: return CV_AMD64_R13W;
  197. case X64Reg_R14: return CV_AMD64_R14W;
  198. case X64Reg_R15: return CV_AMD64_R15W;
  199. }
  200. }
  201. if (bits == 32)
  202. {
  203. switch (reg)
  204. {
  205. case X64Reg_RAX: return CV_AMD64_EAX;
  206. case X64Reg_RDX: return CV_AMD64_EDX;
  207. case X64Reg_RCX: return CV_AMD64_ECX;
  208. case X64Reg_RBX: return CV_AMD64_EBX;
  209. case X64Reg_RSI: return CV_AMD64_ESI;
  210. case X64Reg_RDI: return CV_AMD64_EDI;
  211. case X64Reg_R8: return CV_AMD64_R8D;
  212. case X64Reg_R9: return CV_AMD64_R9D;
  213. case X64Reg_R10: return CV_AMD64_R10D;
  214. case X64Reg_R11: return CV_AMD64_R11D;
  215. case X64Reg_R12: return CV_AMD64_R12D;
  216. case X64Reg_R13: return CV_AMD64_R13D;
  217. case X64Reg_R14: return CV_AMD64_R14D;
  218. case X64Reg_R15: return CV_AMD64_R15D;
  219. }
  220. }
  221. switch (reg)
  222. {
  223. case X64Reg_RAX: return CV_AMD64_RAX;
  224. case X64Reg_RDX: return CV_AMD64_RDX;
  225. case X64Reg_RCX: return CV_AMD64_RCX;
  226. case X64Reg_RBX: return CV_AMD64_RBX;
  227. case X64Reg_RSI: return CV_AMD64_RSI;
  228. case X64Reg_RDI: return CV_AMD64_RDI;
  229. case X64Reg_RBP: return CV_AMD64_RBP;
  230. case X64Reg_RSP: return CV_AMD64_RSP;
  231. case X64Reg_R8: return CV_AMD64_R8;
  232. case X64Reg_R9: return CV_AMD64_R9;
  233. case X64Reg_R10: return CV_AMD64_R10;
  234. case X64Reg_R11: return CV_AMD64_R11;
  235. case X64Reg_R12: return CV_AMD64_R12;
  236. case X64Reg_R13: return CV_AMD64_R13;
  237. case X64Reg_R14: return CV_AMD64_R14;
  238. case X64Reg_R15: return CV_AMD64_R15;
  239. case X64Reg_RIP: return CV_AMD64_RIP;
  240. case X64Reg_EAX: return CV_AMD64_EAX;
  241. case X64Reg_EDX: return CV_AMD64_EDX;
  242. case X64Reg_ECX: return CV_AMD64_ECX;
  243. case X64Reg_EBX: return CV_AMD64_EBX;
  244. case X64Reg_ESI: return CV_AMD64_ESI;
  245. case X64Reg_EDI: return CV_AMD64_EDI;
  246. case X64Reg_R8D: return CV_AMD64_R8D;
  247. case X64Reg_R9D: return CV_AMD64_R9D;
  248. case X64Reg_R10D: return CV_AMD64_R10D;
  249. case X64Reg_R11D: return CV_AMD64_R11D;
  250. case X64Reg_R12D: return CV_AMD64_R12D;
  251. case X64Reg_R13D: return CV_AMD64_R13D;
  252. case X64Reg_R14D: return CV_AMD64_R14D;
  253. case X64Reg_R15D: return CV_AMD64_R15D;
  254. case X64Reg_AX: return CV_AMD64_AX;
  255. case X64Reg_DX: return CV_AMD64_DX;
  256. case X64Reg_CX: return CV_AMD64_CX;
  257. case X64Reg_BX: return CV_AMD64_BX;
  258. case X64Reg_SI: return CV_AMD64_SI;
  259. case X64Reg_DI: return CV_AMD64_DI;
  260. case X64Reg_R8W: return CV_AMD64_R8W;
  261. case X64Reg_R9W: return CV_AMD64_R9W;
  262. case X64Reg_R10W: return CV_AMD64_R10W;
  263. case X64Reg_R11W: return CV_AMD64_R11W;
  264. case X64Reg_R12W: return CV_AMD64_R12W;
  265. case X64Reg_R13W: return CV_AMD64_R13W;
  266. case X64Reg_R14W: return CV_AMD64_R14W;
  267. case X64Reg_R15W: return CV_AMD64_R15W;
  268. case X64Reg_AL: return CV_AMD64_AL;
  269. case X64Reg_DL: return CV_AMD64_DL;
  270. case X64Reg_CL: return CV_AMD64_CL;
  271. case X64Reg_BL: return CV_AMD64_BL;
  272. case X64Reg_SIL: return CV_AMD64_SIL;
  273. case X64Reg_DIL: return CV_AMD64_DIL;
  274. case X64Reg_R8B: return CV_AMD64_R8B;
  275. case X64Reg_R9B: return CV_AMD64_R9B;
  276. case X64Reg_R10B: return CV_AMD64_R10B;
  277. case X64Reg_R11B: return CV_AMD64_R11B;
  278. case X64Reg_R12B: return CV_AMD64_R12B;
  279. case X64Reg_R13B: return CV_AMD64_R13B;
  280. case X64Reg_R14B: return CV_AMD64_R14B;
  281. case X64Reg_R15B: return CV_AMD64_R15B;
  282. case X64Reg_XMM0_f32: case X64Reg_XMM0_f64: return CV_AMD64_XMM0_0;
  283. case X64Reg_XMM1_f32: case X64Reg_XMM1_f64: return CV_AMD64_XMM1_0;
  284. case X64Reg_XMM2_f32: case X64Reg_XMM2_f64: return CV_AMD64_XMM2_0;
  285. case X64Reg_XMM3_f32: case X64Reg_XMM3_f64: return CV_AMD64_XMM3_0;
  286. case X64Reg_XMM4_f32: case X64Reg_XMM4_f64: return CV_AMD64_XMM4_0;
  287. case X64Reg_XMM5_f32: case X64Reg_XMM5_f64: return CV_AMD64_XMM5_0;
  288. case X64Reg_XMM6_f32: case X64Reg_XMM6_f64: return CV_AMD64_XMM6_0;
  289. case X64Reg_XMM7_f32: case X64Reg_XMM7_f64: return CV_AMD64_XMM7_0;
  290. case X64Reg_XMM8_f32: case X64Reg_XMM8_f64: return CV_AMD64_XMM8_0;
  291. case X64Reg_XMM9_f32: case X64Reg_XMM9_f64: return CV_AMD64_XMM9_0;
  292. case X64Reg_XMM10_f32: case X64Reg_XMM10_f64: return CV_AMD64_XMM10_0;
  293. case X64Reg_XMM11_f32: case X64Reg_XMM11_f64: return CV_AMD64_XMM11_0;
  294. case X64Reg_XMM12_f32: case X64Reg_XMM12_f64: return CV_AMD64_XMM12_0;
  295. case X64Reg_XMM13_f32: case X64Reg_XMM13_f64: return CV_AMD64_XMM13_0;
  296. case X64Reg_XMM14_f32: case X64Reg_XMM14_f64: return CV_AMD64_XMM14_0;
  297. case X64Reg_XMM15_f32: case X64Reg_XMM15_f64: return CV_AMD64_XMM15_0;
  298. case X64Reg_XMM00: return CV_AMD64_XMM0_0;
  299. case X64Reg_XMM01: return CV_AMD64_XMM0_1;
  300. case X64Reg_XMM02: return CV_AMD64_XMM0_2;
  301. case X64Reg_XMM03: return CV_AMD64_XMM0_3;
  302. case X64Reg_XMM10: return CV_AMD64_XMM1_0;
  303. case X64Reg_XMM11: return CV_AMD64_XMM1_1;
  304. case X64Reg_XMM12: return CV_AMD64_XMM1_2;
  305. case X64Reg_XMM13: return CV_AMD64_XMM1_3;
  306. case X64Reg_XMM20: return CV_AMD64_XMM2_0;
  307. case X64Reg_XMM21: return CV_AMD64_XMM2_1;
  308. case X64Reg_XMM22: return CV_AMD64_XMM2_2;
  309. case X64Reg_XMM23: return CV_AMD64_XMM2_3;
  310. case X64Reg_XMM30: return CV_AMD64_XMM3_0;
  311. case X64Reg_XMM31: return CV_AMD64_XMM3_1;
  312. case X64Reg_XMM32: return CV_AMD64_XMM3_2;
  313. case X64Reg_XMM33: return CV_AMD64_XMM3_3;
  314. case X64Reg_XMM40: return CV_AMD64_XMM4_0;
  315. case X64Reg_XMM41: return CV_AMD64_XMM4_1;
  316. case X64Reg_XMM42: return CV_AMD64_XMM4_2;
  317. case X64Reg_XMM43: return CV_AMD64_XMM4_3;
  318. case X64Reg_XMM50: return CV_AMD64_XMM5_0;
  319. case X64Reg_XMM51: return CV_AMD64_XMM5_1;
  320. case X64Reg_XMM52: return CV_AMD64_XMM5_2;
  321. case X64Reg_XMM53: return CV_AMD64_XMM5_3;
  322. case X64Reg_XMM60: return CV_AMD64_XMM6_0;
  323. case X64Reg_XMM61: return CV_AMD64_XMM6_1;
  324. case X64Reg_XMM62: return CV_AMD64_XMM6_2;
  325. case X64Reg_XMM63: return CV_AMD64_XMM6_3;
  326. case X64Reg_XMM70: return CV_AMD64_XMM7_0;
  327. case X64Reg_XMM71: return CV_AMD64_XMM7_1;
  328. case X64Reg_XMM72: return CV_AMD64_XMM7_2;
  329. case X64Reg_XMM73: return CV_AMD64_XMM7_3;
  330. }
  331. return 0;
  332. }
  333. void BeCOFFObject::DbgEncodeConstant(DynMemStream& memStream, int64 val)
  334. {
  335. if ((val >= 0) && (val <= 0x7FFF))
  336. {
  337. memStream.Write((int16)val);
  338. return;
  339. }
  340. if ((val >= -0x80) && (val <= 0x7F))
  341. {
  342. memStream.Write((int16)LF_CHAR);
  343. memStream.Write((int8)val);
  344. return;
  345. }
  346. if ((val >= -0x8000) && (val <= 0x7FFF))
  347. {
  348. memStream.Write((int16)LF_SHORT);
  349. memStream.Write((int16)val);
  350. return;
  351. }
  352. if ((val >= -0x80000000LL) && (val <= 0x7FFFFFFF))
  353. {
  354. memStream.Write((int16)LF_LONG);
  355. memStream.Write((int32)val);
  356. return;
  357. }
  358. memStream.Write((int16)LF_QUADWORD);
  359. memStream.Write((int64)val);
  360. }
  361. void BeCOFFObject::DbgEncodeString(DynMemStream& memStream, const StringImpl& str)
  362. {
  363. memStream.Write((char*)str.c_str(), str.length() + 1);
  364. }
  365. void BeCOFFObject::DbgMakeFuncType(BeDbgFunction* dbgFunc)
  366. {
  367. if (dbgFunc->mCvTypeId != -1)
  368. return;
  369. /*auto funcTypeResultPair = mFuncTypeSet.insert(dbgFunc);
  370. if (!funcTypeResultPair.second)
  371. {
  372. // This matchesInlineScope another signature so we don't need to redefine it
  373. dbgFunc->mCvTypeId = (*funcTypeResultPair.first)->mCvTypeId;
  374. return;
  375. }*/
  376. COFFFuncTypeRef* funcTypeRefPtr = NULL;
  377. if (!mFuncTypeSet.TryAdd(dbgFunc, &funcTypeRefPtr))
  378. {
  379. // This matchesInlineScope another signature so we don't need to redefine it
  380. dbgFunc->mCvTypeId = funcTypeRefPtr->mFunc->mCvTypeId;
  381. return;
  382. }
  383. auto dbgType = BeValueDynCast<BeDbgType>(dbgFunc->mScope);
  384. auto& outT = mDebugTSect.mData;
  385. for (auto genericArgType : dbgFunc->mGenericArgs)
  386. DbgGetTypeId(genericArgType);
  387. auto parentType = BeValueDynCast<BeDbgType>(dbgFunc->mScope);
  388. DbgGetTypeId(parentType);
  389. for (auto funcParam : dbgFunc->mType->mParams)
  390. DbgGetTypeId(funcParam);
  391. DbgGetTypeId(dbgFunc->mType->mReturnType);
  392. for (auto paramType : dbgFunc->mType->mParams)
  393. DbgGetTypeId(paramType);
  394. bool hasThis = dbgFunc->HasThis();
  395. /*auto argListResultPair = mArgListSet.insert(dbgFunc);
  396. if (!argListResultPair.second)
  397. {
  398. dbgFunc->mCvArgListId = (*argListResultPair.first)->mCvArgListId;
  399. }
  400. else*/
  401. COFFArgListRef* argListRefPtr = NULL;
  402. if (!mArgListSet.TryAdd(dbgFunc, &argListRefPtr))
  403. {
  404. dbgFunc->mCvArgListId = argListRefPtr->mFunc->mCvArgListId;
  405. }
  406. else
  407. {
  408. dbgFunc->mCvArgListId = mCurTagId++;
  409. DbgTStartTag();
  410. outT.Write((int16)LF_ARGLIST);
  411. outT.Write((int32)(dbgFunc->mType->mParams.size() - (hasThis ? 1 : 0)));
  412. for (int paramIdx = hasThis ? 1 : 0; paramIdx < (int)dbgFunc->mType->mParams.size(); paramIdx++)
  413. {
  414. BeDbgType* dbgType = dbgFunc->mType->mParams[paramIdx];
  415. outT.Write(DbgGetTypeId(dbgType));
  416. }
  417. DbgTEndTag();
  418. }
  419. dbgFunc->mCvTypeId = mCurTagId++;
  420. DbgTStartTag();
  421. if (dbgType != NULL)
  422. {
  423. outT.Write((int16)LF_MFUNCTION);
  424. outT.Write(DbgGetTypeId(dbgFunc->mType->mReturnType));
  425. outT.Write(DbgGetTypeId(parentType));
  426. if (hasThis)
  427. {
  428. if ((dbgFunc->mVariables.size() > 0) && (dbgFunc->mVariables[0] == NULL))
  429. outT.Write(DbgGetTypeId(BeValueDynCast<BeDbgType>(dbgFunc->GetParamType(1)))); // 0 is sret, 1 = this
  430. else
  431. outT.Write(DbgGetTypeId(BeValueDynCast<BeDbgType>(dbgFunc->GetParamType(0)))); // 0 = this
  432. }
  433. else
  434. outT.Write((int32)T_VOID);
  435. outT.Write((uint8)0); // calltype
  436. CV_funcattr_t attr = { 0 };
  437. outT.Write(*(uint8*)&attr);
  438. outT.Write((int16)(dbgFunc->mType->mParams.size() - (hasThis ? 1 : 0)));
  439. outT.Write((int32)dbgFunc->mCvArgListId);
  440. outT.Write((int32)0); // thisadjust
  441. }
  442. else
  443. {
  444. outT.Write((int16)LF_PROCEDURE);
  445. outT.Write(DbgGetTypeId(dbgFunc->mType->mReturnType));
  446. outT.Write((uint8)0); // calltype
  447. CV_funcattr_t attr = { 0 };
  448. outT.Write(*(uint8*)&attr);
  449. outT.Write((int16)(dbgFunc->mType->mParams.size() - (hasThis ? 1 : 0)));
  450. outT.Write((int32)dbgFunc->mCvArgListId);
  451. }
  452. DbgTEndTag();
  453. }
  454. void BeCOFFObject::DbgMakeFunc(BeDbgFunction* dbgFunc)
  455. {
  456. auto& outT = mDebugTSect.mData;
  457. BF_ASSERT(dbgFunc->mCvTypeId == -1);
  458. DbgMakeFuncType(dbgFunc);
  459. auto dbgType = BeValueDynCast<BeDbgType>(dbgFunc->mScope);
  460. if (dbgType != NULL)
  461. {
  462. dbgFunc->mCvFuncId = mCurTagId++;
  463. DbgTStartTag();
  464. outT.Write((int16)LF_MFUNC_ID);
  465. outT.Write(dbgType->mCvDeclTypeId);
  466. outT.Write(dbgFunc->mCvTypeId);
  467. DbgEncodeString(outT, dbgFunc->mName);
  468. DbgTEndTag();
  469. }
  470. else
  471. {
  472. dbgFunc->mCvFuncId = mCurTagId++;
  473. DbgTStartTag();
  474. outT.Write((int16)LF_FUNC_ID);
  475. outT.Write((int32)0); // ScopeID (global)
  476. outT.Write(dbgFunc->mCvTypeId);
  477. DbgEncodeString(outT, dbgFunc->mName);
  478. DbgTEndTag();
  479. }
  480. }
  481. void BeCOFFObject::DbgTAlign()
  482. {
  483. int curPos = mDebugTSect.mData.GetPos();
  484. // Perform alignment
  485. int addPadding = (4 - (curPos & 3)) % 4;
  486. while (addPadding > 0)
  487. {
  488. mDebugTSect.mData.Write((uint8)(0xF0 + addPadding));
  489. addPadding--;
  490. }
  491. }
  492. void BeCOFFObject::DbgTStartTag()
  493. {
  494. BF_ASSERT(mTTagStartPos == -1);
  495. mTTagStartPos = mDebugTSect.mData.GetPos();
  496. mDebugTSect.mData.Write((int16)0);
  497. }
  498. void BeCOFFObject::DbgTEndTag()
  499. {
  500. BF_ASSERT(mTTagStartPos != -1);
  501. DbgTAlign();
  502. int tagSize = mDebugTSect.mData.GetPos() - mTTagStartPos;
  503. BF_ASSERT(tagSize <= 0xFFFF);
  504. *((int16*)&mDebugTSect.mData.mData[mTTagStartPos]) = (int16)(tagSize - 2);
  505. mTTagStartPos = -1;
  506. }
  507. int BeCOFFObject::DbgGetTypeId(BeDbgType* dbgType, bool doDefine)
  508. {
  509. if (dbgType == NULL)
  510. return 0;
  511. if ((!doDefine && (dbgType->mCvDeclTypeId != -1)))
  512. {
  513. if (dbgType->mCvDefTypeId != -1)
  514. return dbgType->mCvDefTypeId;
  515. return dbgType->mCvDeclTypeId;
  516. }
  517. if ((doDefine) && (dbgType->mCvDefTypeId != -1))
  518. return dbgType->mCvDefTypeId;
  519. auto& outT = mDebugTSect.mData;
  520. auto structType = BeValueDynCast<BeDbgStructType>(dbgType);
  521. if (structType != NULL)
  522. {
  523. //lfClass classInfo;
  524. //BF_CLEAR_VALUE(classInfo);
  525. //classInfo.leaf = LF_STRUCTURE;
  526. CV_prop_t structProp = { 0 };
  527. if (structType->mAlign == 1)
  528. structProp.packed = true;
  529. int fieldListTag = 0;
  530. int memberCount = 0;
  531. if (doDefine)
  532. {
  533. // Pass over all needed types first to make sure we generate any forward references we'll need
  534. // because we're locked in inbetween DbgTStartTag and DbgTEndTag
  535. DbgGetTypeId(dbgType);
  536. DbgGetTypeId(structType->mDerivedFrom);
  537. for (auto member : structType->mMembers)
  538. {
  539. auto type = member->mType;
  540. DbgGetTypeId(type);
  541. }
  542. for (auto func : structType->mMethods)
  543. DbgMakeFuncType(func);
  544. fieldListTag = mCurTagId++;
  545. //int tagStartPos = -1;
  546. DbgTStartTag();
  547. outT.Write((int16)LF_FIELDLIST);
  548. if (structType->mDerivedFrom != NULL)
  549. {
  550. outT.Write((int16)LF_BCLASS);
  551. CV_fldattr_t attr = { 0 };
  552. attr.access = 3; // public
  553. outT.Write(*(int16*)&attr);
  554. outT.Write(DbgGetTypeId(structType->mDerivedFrom));
  555. DbgEncodeConstant(outT, 0); // Offset
  556. DbgTAlign();
  557. }
  558. auto _CheckFieldOverflow = [&]()
  559. {
  560. int tagSize = mDebugTSect.mData.GetPos() - mTTagStartPos;
  561. if (tagSize >= 0xE000)
  562. {
  563. int extFieldListTag = mCurTagId++;
  564. outT.Write((int16)LF_INDEX);
  565. outT.Write((int16)0); // Padding
  566. outT.Write((int32)extFieldListTag); // Padding
  567. DbgTEndTag();
  568. DbgTStartTag();
  569. outT.Write((int16)LF_FIELDLIST);
  570. }
  571. };
  572. for (auto member : structType->mMembers)
  573. {
  574. _CheckFieldOverflow();
  575. if (member->mIsStatic)
  576. outT.Write((int16)LF_STMEMBER);
  577. else
  578. outT.Write((int16)LF_MEMBER);
  579. CV_fldattr_t attr = { 0 };
  580. if ((member->mFlags & 3) == llvm::DINode::FlagPrivate)
  581. attr.access = 1;
  582. else if ((member->mFlags & 3) == llvm::DINode::FlagProtected)
  583. attr.access = 2;
  584. else
  585. attr.access = 3;
  586. outT.Write(*(int16*)&attr);
  587. outT.Write(DbgGetTypeId(member->mType));
  588. if (!member->mIsStatic)
  589. DbgEncodeConstant(outT, member->mOffset);
  590. DbgEncodeString(outT, member->mName);
  591. memberCount++;
  592. DbgTAlign();
  593. }
  594. for (auto func : structType->mMethods)
  595. {
  596. _CheckFieldOverflow();
  597. //TODO: Handle static methods
  598. outT.Write((int16)LF_ONEMETHOD);
  599. CV_fldattr_t attr = { 0 };
  600. if ((func->mFlags & 3) == llvm::DINode::FlagPrivate)
  601. attr.access = 1;
  602. else if ((func->mFlags & 3) == llvm::DINode::FlagProtected)
  603. attr.access = 2;
  604. else
  605. attr.access = 3;
  606. if ((func->mFlags & llvm::DINode::FlagArtificial) != 0)
  607. attr.compgenx = 1;
  608. bool isVirt = func->mVK > 0;
  609. if (isVirt)
  610. attr.mprop = CV_MTintro;
  611. outT.Write(*(int16*)&attr);
  612. outT.Write(func->mCvTypeId);
  613. if (isVirt)
  614. outT.Write((int32)func->mVIndex * mBeModule->mContext->mPointerSize);
  615. DbgEncodeString(outT, func->mName);
  616. memberCount++;
  617. DbgTAlign();
  618. }
  619. // LF_FIELDLIST
  620. DbgTEndTag();
  621. }
  622. else
  623. {
  624. structProp.fwdref = 1;
  625. }
  626. DbgTStartTag();
  627. outT.Write((int16)LF_STRUCTURE);
  628. outT.Write((int16)memberCount);
  629. outT.Write(*(int16*)&structProp);
  630. outT.Write((int32)fieldListTag);
  631. outT.Write((int32)0); //derivedfrom - should we ever set this?
  632. outT.Write((int32)0); //vshape
  633. if (doDefine)
  634. DbgEncodeConstant(outT, structType->mSize);
  635. else
  636. DbgEncodeConstant(outT, 0);
  637. String fullName;
  638. ToString(structType, fullName);
  639. DbgEncodeString(outT, fullName);
  640. DbgTEndTag(); // LF_STRUCTURE
  641. if (doDefine)
  642. dbgType->mCvDefTypeId = mCurTagId++;
  643. else
  644. dbgType->mCvDeclTypeId = mCurTagId++;
  645. if (doDefine)
  646. {
  647. int strId = mCurTagId++;
  648. DbgTStartTag();
  649. outT.Write((int16)LF_STRING_ID);
  650. outT.Write(0);
  651. String fullPath;
  652. structType->mDefFile->ToString(fullPath);
  653. DbgEncodeString(outT, fullPath);
  654. DbgTEndTag();
  655. mCurTagId++;
  656. DbgTStartTag();
  657. outT.Write((int16)LF_UDT_SRC_LINE);
  658. outT.Write(structType->mCvDefTypeId);
  659. outT.Write(strId);
  660. outT.Write(structType->mDefLine + 1);
  661. DbgTEndTag();
  662. /*for (auto func : structType->mMethods)
  663. {
  664. // Yes, using declTypeId is correct here
  665. DbgTStartTag();
  666. outT.Write((int16)LF_MFUNC_ID);
  667. outT.Write(declTypeId);
  668. outT.Write(func->mCvTypeId);
  669. DbgEncodeString(outT, func->mName);
  670. DbgTEndTag();
  671. func->mCvFuncId = mCurTagId++;
  672. }*/
  673. return dbgType->mCvDefTypeId;
  674. }
  675. return dbgType->mCvDeclTypeId;
  676. }
  677. else if (auto enumType = BeValueDynCast<BeDbgEnumType>(dbgType))
  678. {
  679. int fieldListId = 0;
  680. if (enumType->mIsFullyDefined)
  681. {
  682. fieldListId = mCurTagId++;
  683. //int tagStartPos = -1;
  684. DbgTStartTag();
  685. outT.Write((int16)LF_FIELDLIST);
  686. for (auto member : enumType->mMembers)
  687. {
  688. outT.Write((int16)LF_ENUMERATE);
  689. CV_fldattr_t attr = { 0 };
  690. attr.access = 3; // public
  691. outT.Write(*(int16*)&attr);
  692. DbgEncodeConstant(outT, member->mValue);
  693. DbgEncodeString(outT, member->mName);
  694. DbgTAlign();
  695. }
  696. // LF_FIELDLIST
  697. DbgTEndTag();
  698. }
  699. int32 elementId = T_VOID;
  700. if (enumType->mElementType != NULL)
  701. elementId = DbgGetTypeId(enumType->mElementType);
  702. //int32 elementId = DbgGetTypeId(enumType->mElementType);
  703. CV_prop_t structProp = { 0 };
  704. if (!enumType->mIsFullyDefined)
  705. structProp.fwdref = 1;
  706. DbgTStartTag();
  707. outT.Write((int16)LF_ENUM);
  708. outT.Write((int16)enumType->mMembers.size());
  709. outT.Write(*(int16*)&structProp);
  710. outT.Write(elementId);
  711. outT.Write((int32)fieldListId);
  712. String fullName;
  713. ToString(dbgType, fullName);
  714. DbgEncodeString(outT, fullName);
  715. DbgTEndTag();
  716. dbgType->mCvDeclTypeId = dbgType->mCvDefTypeId = mCurTagId++;
  717. return dbgType->mCvDefTypeId;
  718. }
  719. else if (auto dbgBasicType = BeValueDynCast<BeDbgBasicType>(dbgType))
  720. {
  721. switch (dbgBasicType->mEncoding)
  722. {
  723. case llvm::dwarf::DW_ATE_address:
  724. dbgBasicType->mCvDefTypeId = 0;
  725. break;
  726. case llvm::dwarf::DW_ATE_signed:
  727. switch (dbgBasicType->mSize)
  728. {
  729. case 1: dbgBasicType->mCvDefTypeId = T_INT1; break;
  730. case 2: dbgBasicType->mCvDefTypeId = T_SHORT; break;
  731. case 4: dbgBasicType->mCvDefTypeId = T_INT4; break;
  732. case 8: dbgBasicType->mCvDefTypeId = T_QUAD; break;
  733. }
  734. break;
  735. case llvm::dwarf::DW_ATE_unsigned:
  736. switch (dbgBasicType->mSize)
  737. {
  738. case 1: dbgBasicType->mCvDefTypeId = T_UINT1; break;
  739. case 2: dbgBasicType->mCvDefTypeId = T_USHORT; break;
  740. case 4: dbgBasicType->mCvDefTypeId = T_UINT4; break;
  741. case 8: dbgBasicType->mCvDefTypeId = T_UQUAD; break;
  742. }
  743. break;
  744. case llvm::dwarf::DW_ATE_float:
  745. switch (dbgBasicType->mSize)
  746. {
  747. case 4: dbgBasicType->mCvDefTypeId = T_REAL32; break;
  748. case 8: dbgBasicType->mCvDefTypeId = T_REAL64; break;
  749. }
  750. break;
  751. case llvm::dwarf::DW_ATE_unsigned_char:
  752. switch (dbgBasicType->mSize)
  753. {
  754. case 1: dbgBasicType->mCvDefTypeId = T_CHAR; break;
  755. case 2: dbgBasicType->mCvDefTypeId = T_CHAR16; break;
  756. case 4: dbgBasicType->mCvDefTypeId = T_CHAR32; break;
  757. }
  758. break;
  759. case llvm::dwarf::DW_ATE_boolean:
  760. dbgBasicType->mCvDefTypeId = T_BOOL08;
  761. break;
  762. }
  763. dbgBasicType->mCvDeclTypeId = dbgBasicType->mCvDefTypeId;
  764. return dbgBasicType->mCvDeclTypeId;
  765. }
  766. else if (auto ptrType = BeValueDynCast<BeDbgPointerType>(dbgType))
  767. {
  768. if (auto innerBasicType = BeValueDynCast<BeDbgBasicType>(ptrType->mElement))
  769. {
  770. switch (innerBasicType->mEncoding)
  771. {
  772. case llvm::dwarf::DW_ATE_address:
  773. ptrType->mCvDefTypeId = T_PVOID;
  774. break;
  775. case llvm::dwarf::DW_ATE_signed:
  776. switch (innerBasicType->mSize)
  777. {
  778. case 1: ptrType->mCvDefTypeId = T_64PINT1; break;
  779. case 2: ptrType->mCvDefTypeId = T_64PSHORT; break;
  780. case 4: ptrType->mCvDefTypeId = T_64PINT4; break;
  781. case 8: ptrType->mCvDefTypeId = T_64PINT8; break;
  782. }
  783. break;
  784. case llvm::dwarf::DW_ATE_unsigned:
  785. switch (innerBasicType->mSize)
  786. {
  787. case 1: ptrType->mCvDefTypeId = T_64PUINT1; break;
  788. case 2: ptrType->mCvDefTypeId = T_64PUSHORT; break;
  789. case 4: ptrType->mCvDefTypeId = T_64PUINT4; break;
  790. case 8: ptrType->mCvDefTypeId = T_64PUINT8; break;
  791. }
  792. break;
  793. case llvm::dwarf::DW_ATE_float:
  794. switch (innerBasicType->mSize)
  795. {
  796. case 4: ptrType->mCvDefTypeId = T_64PREAL32; break;
  797. case 8: ptrType->mCvDefTypeId = T_64PREAL64; break;
  798. }
  799. break;
  800. case llvm::dwarf::DW_ATE_unsigned_char:
  801. switch (innerBasicType->mSize)
  802. {
  803. case 1: ptrType->mCvDefTypeId = T_64PUCHAR; break;
  804. case 2: ptrType->mCvDefTypeId = T_64PCHAR16; break;
  805. case 4: ptrType->mCvDefTypeId = T_64PCHAR32; break;
  806. }
  807. break;
  808. case llvm::dwarf::DW_ATE_boolean:
  809. ptrType->mCvDefTypeId = T_64PBOOL08;
  810. break;
  811. }
  812. if (ptrType->mCvDefTypeId != -1)
  813. {
  814. ptrType->mCvDeclTypeId = ptrType->mCvDefTypeId;
  815. return ptrType->mCvDefTypeId;
  816. }
  817. }
  818. lfPointerBody::lfPointerAttr attr = { 0 };
  819. attr.ptrtype = CV_PTR_64;
  820. attr.ptrmode = CV_PTR_MODE_PTR;
  821. attr.size = 8;
  822. int32 elementId = DbgGetTypeId(ptrType->mElement);
  823. DbgTStartTag();
  824. outT.Write((int16)LF_POINTER);
  825. outT.Write(elementId);
  826. outT.Write(*(int32*)&attr);
  827. DbgTEndTag();
  828. dbgType->mCvDeclTypeId = dbgType->mCvDefTypeId = mCurTagId++;
  829. return dbgType->mCvDefTypeId;
  830. }
  831. else if (auto refType = BeValueDynCast<BeDbgReferenceType>(dbgType))
  832. {
  833. lfPointerBody::lfPointerAttr attr = { 0 };
  834. attr.ptrtype = CV_PTR_64;
  835. attr.ptrmode = CV_PTR_MODE_LVREF;
  836. attr.size = 8;
  837. int32 elementId = DbgGetTypeId(refType->mElement);
  838. DbgTStartTag();
  839. outT.Write((int16)LF_POINTER);
  840. outT.Write(elementId);
  841. outT.Write(*(int32*)&attr);
  842. DbgTEndTag();
  843. dbgType->mCvDeclTypeId = dbgType->mCvDefTypeId = mCurTagId++;
  844. return dbgType->mCvDefTypeId;
  845. }
  846. else if (auto constType = BeValueDynCast<BeDbgConstType>(dbgType))
  847. {
  848. CV_modifier_t attr = { 0 };
  849. attr.MOD_const = 1;
  850. int32 elementId = DbgGetTypeId(BeValueDynCast<BeDbgType>(constType->mElement));
  851. DbgTStartTag();
  852. outT.Write((int16)LF_MODIFIER);
  853. outT.Write(elementId);
  854. outT.Write(*(int16*)&attr);
  855. DbgTEndTag();
  856. dbgType->mCvDeclTypeId = dbgType->mCvDefTypeId = mCurTagId++;
  857. return dbgType->mCvDefTypeId;
  858. }
  859. else if (auto artificialType = BeValueDynCast<BeDbgArtificialType>(dbgType))
  860. {
  861. return DbgGetTypeId(artificialType->mElement);
  862. }
  863. else if (auto arrayType = BeValueDynCast<BeDbgArrayType>(dbgType))
  864. {
  865. int32 elementId = DbgGetTypeId(arrayType->mElement);
  866. DbgTStartTag();
  867. outT.Write((int16)LF_ARRAY);
  868. outT.Write((int32)elementId);
  869. outT.Write((int32)0x23/*int64*/);
  870. DbgEncodeConstant(outT, BF_ALIGN(arrayType->mSize, arrayType->mAlign));
  871. DbgEncodeString(outT, "");
  872. DbgTEndTag();
  873. dbgType->mCvDeclTypeId = dbgType->mCvDefTypeId = mCurTagId++;
  874. return dbgType->mCvDefTypeId;
  875. }
  876. else
  877. BF_FATAL("NotImpl");
  878. BF_FATAL("Invalid type");
  879. return -1;
  880. }
  881. void BeCOFFObject::DbgGenerateTypeInfo()
  882. {
  883. BP_ZONE("BeCOFFObject::DbgGenerateTypeInfo");
  884. AutoPerf perf("BeCOFFObject::DbgGenerateTypeInfo", mPerfManager);
  885. auto& outT = mDebugTSect.mData;
  886. outT.Write((int)CV_SIGNATURE_C13);
  887. for (auto mdNode : mBeModule->mDbgModule->mTypes)
  888. {
  889. bool defineType = true;
  890. if (auto dbgStructType = BeValueDynCast<BeDbgStructType>(mdNode))
  891. {
  892. if (!dbgStructType->mIsFullyDefined)
  893. defineType = false;
  894. }
  895. if (defineType)
  896. {
  897. if (auto dbgType = BeValueDynCast<BeDbgType>(mdNode))
  898. DbgGetTypeId(dbgType, true);
  899. }
  900. }
  901. for (auto dbgFunc : mBeModule->mDbgModule->mFuncs)
  902. {
  903. if (dbgFunc->mValue != NULL)
  904. DbgMakeFunc(dbgFunc);
  905. }
  906. }
  907. void BeCOFFObject::DbgStartSection(int sectionNum)
  908. {
  909. auto& outS = mDebugSSect.mData;
  910. BF_ASSERT(mSectionStartPos == -1);
  911. outS.Write((int32)sectionNum);
  912. outS.Write(0); // Temporary - size
  913. mSectionStartPos = outS.GetPos();
  914. }
  915. void BeCOFFObject::DbgEndSection()
  916. {
  917. auto& outS = mDebugSSect.mData;
  918. int totalLen = outS.GetPos() - mSectionStartPos;
  919. *((int32*)&outS.mData[mSectionStartPos - 4]) = totalLen;
  920. mSectionStartPos = -1;
  921. while ((outS.GetPos() & 3) != 0)
  922. outS.Write((uint8)0);
  923. }
  924. void BeCOFFObject::DbgStartVarDefRange(BeDbgFunction* dbgFunc, BeDbgVariable* dbgVar, const BeDbgVariableLoc& varLoc, int offset, int range)
  925. {
  926. BF_ASSERT(range >= 0);
  927. auto funcSym = GetSymbol(dbgFunc->mValue);
  928. auto varType = BeValueDynCast<BeDbgType>(dbgVar->mType);
  929. auto& outS = mDebugSSect.mData;
  930. if (varLoc.mKind == BeDbgVariableLoc::Kind_SymbolAddr)
  931. {
  932. BF_FATAL("Not supported");
  933. }
  934. else if (varLoc.mKind == BeDbgVariableLoc::Kind_Reg)
  935. {
  936. if (varLoc.mOfs == 0)
  937. {
  938. outS.Write((int16)S_DEFRANGE_REGISTER);
  939. outS.Write((int16)GetCVRegNum(varLoc.mReg, varType->mSize * 8));
  940. CV_RANGEATTR rangeAttr = { 0 };
  941. outS.Write(*(int16*)&rangeAttr); // offset to register
  942. }
  943. else
  944. {
  945. outS.Write((int16)S_DEFRANGE_REGISTER_REL);
  946. outS.Write((int16)GetCVRegNum(varLoc.mReg, varType->mSize * 8));
  947. outS.Write((int16)0);
  948. outS.Write((int32)varLoc.mOfs);
  949. // CV_RANGEATTR rangeAttr = { 0 };
  950. // outS.Write(*(int16*)&rangeAttr); // offset to register
  951. }
  952. }
  953. else //if (varLoc.mKind == BeDbgVariableLoc::Kind_Indexed)
  954. {
  955. outS.Write((int16)S_DEFRANGE_REGISTER_REL);
  956. outS.Write((int16)GetCVRegNum(varLoc.mReg, 64));
  957. outS.Write((int16)0); // offset in parent
  958. outS.Write((int32)varLoc.mOfs); // offset to register
  959. }
  960. BeMCRelocation reloc;
  961. reloc.mKind = BeMCRelocationKind_SECREL;
  962. reloc.mOffset = outS.GetPos();
  963. reloc.mSymTableIdx = funcSym->mIdx;
  964. mDebugSSect.mRelocs.push_back(reloc);
  965. outS.Write((int32)offset); // offset start
  966. reloc.mKind = BeMCRelocationKind_SECTION;
  967. reloc.mOffset = outS.GetPos();
  968. reloc.mSymTableIdx = funcSym->mIdx;
  969. mDebugSSect.mRelocs.push_back(reloc);
  970. outS.Write((int16)0); // section
  971. outS.Write((int16)range); // Range
  972. }
  973. void BeCOFFObject::DbgEndLineBlock(BeDbgFunction* dbgFunc, const Array<BeDbgCodeEmission>& emissions, int blockStartPos, int emissionStartIdx, int lineCount)
  974. {
  975. auto& outS = mDebugSSect.mData;
  976. int addLineCount = 0;
  977. if ((emissionStartIdx == 0) && (dbgFunc->mLine != -1))
  978. {
  979. outS.Write((int16)0);
  980. outS.Write((int16)0);
  981. addLineCount++;
  982. }
  983. for (int emissionIdx = emissionStartIdx; emissionIdx < emissionStartIdx + lineCount; emissionIdx++)
  984. {
  985. auto& codeEmission = emissions[emissionIdx];
  986. // Start column
  987. outS.Write((int16)(codeEmission.mDbgLoc->mColumn + 1));
  988. // End column
  989. outS.Write((int16)(codeEmission.mDbgLoc->mColumn + 1));
  990. }
  991. *(int*)(&outS.mData[blockStartPos] + 4) = lineCount + addLineCount;
  992. *(int*)(&outS.mData[blockStartPos] + 8) = outS.GetPos() - blockStartPos;
  993. }
  994. void BeCOFFObject::DbgSAlign()
  995. {
  996. int curPos = mDebugSSect.mData.GetPos();
  997. // Perform alignment
  998. int addPadding = (4 - (curPos & 3)) % 4;
  999. while (addPadding > 0)
  1000. {
  1001. mDebugSSect.mData.Write((uint8)0);
  1002. addPadding--;
  1003. }
  1004. }
  1005. void BeCOFFObject::DbgSStartTag()
  1006. {
  1007. BF_ASSERT(mSTagStartPos == -1);
  1008. mSTagStartPos = mDebugSSect.mData.GetPos();
  1009. mDebugSSect.mData.Write((int16)0);
  1010. }
  1011. void BeCOFFObject::DbgSEndTag()
  1012. {
  1013. BF_ASSERT(mSTagStartPos != -1);
  1014. int tagSize = mDebugSSect.mData.GetPos() - mSTagStartPos;
  1015. BF_ASSERT(tagSize <= 0xFFFF);
  1016. *((uint16*)&mDebugSSect.mData.mData[mSTagStartPos]) = (uint16)(tagSize - 2);
  1017. mSTagStartPos = -1;
  1018. }
  1019. void BeCOFFObject::DbgOutputLocalVar(BeDbgFunction* dbgFunc, BeDbgVariable* dbgVar)
  1020. {
  1021. auto varType = BeValueDynCast<BeDbgType>(dbgVar->mType);
  1022. // CodeView only allows 16-bit lengths, so we need to split ranges for very long spans
  1023. if (dbgVar->mDeclEnd - dbgVar->mDeclStart > 0xFFFF)
  1024. {
  1025. int splitPos = dbgVar->mDeclStart + 0xFFFF;
  1026. BeDbgVariable varStart = *dbgVar;
  1027. varStart.mDeclEnd = splitPos;
  1028. Array<BeDbgVariableRange>* startArrs[2] = { &varStart.mSavedRanges, &varStart.mGaps };
  1029. for (auto& arr : startArrs)
  1030. {
  1031. for (int arrIdx = 0; arrIdx < (int)arr->size(); arrIdx++)
  1032. {
  1033. auto& gap = (*arr)[arrIdx];
  1034. int gapStart = gap.mOffset;
  1035. int gapEnd = gap.mOffset + gap.mLength;
  1036. if (gapStart > splitPos)
  1037. gapStart = splitPos;
  1038. if (gapEnd > splitPos)
  1039. gapEnd = splitPos;
  1040. if (gapStart == gapEnd)
  1041. {
  1042. arr->RemoveAt(arrIdx);
  1043. arrIdx--;
  1044. }
  1045. else
  1046. {
  1047. gap.mOffset = gapStart;
  1048. gap.mLength = gapEnd - gapStart;
  1049. BF_ASSERT(gap.mLength > 0);
  1050. }
  1051. }
  1052. }
  1053. DbgOutputLocalVar(dbgFunc, &varStart);
  1054. BeDbgVariable varEnd = *dbgVar;
  1055. varEnd.mDeclStart = splitPos;
  1056. Array<BeDbgVariableRange>* endArrs[2] = { &varEnd.mSavedRanges, &varEnd.mGaps };
  1057. for (auto& arr : endArrs)
  1058. {
  1059. for (int arrIdx = 0; arrIdx < (int)arr->size(); arrIdx++)
  1060. {
  1061. auto& gap = (*arr)[arrIdx];
  1062. int gapStart = gap.mOffset;
  1063. if (gapStart < splitPos)
  1064. gapStart = splitPos;
  1065. if (gap.mLength == -1)
  1066. {
  1067. gap.mOffset = gapStart;
  1068. continue;
  1069. }
  1070. int gapEnd = gap.mOffset + gap.mLength;
  1071. if (gapEnd < splitPos)
  1072. gapEnd = splitPos;
  1073. if (gapStart == gapEnd)
  1074. {
  1075. arr->RemoveAt(arrIdx);
  1076. arrIdx--;
  1077. }
  1078. else
  1079. {
  1080. gap.mOffset = gapStart;
  1081. gap.mLength = gapEnd - gapStart;
  1082. BF_ASSERT(gap.mLength > 0);
  1083. }
  1084. }
  1085. }
  1086. DbgOutputLocalVar(dbgFunc, &varEnd);
  1087. }
  1088. auto& outS = mDebugSSect.mData;
  1089. DbgSStartTag();
  1090. outS.Write((int16)S_LOCAL);
  1091. outS.Write(DbgGetTypeId(varType));
  1092. CV_LVARFLAGS flags = { 0 };
  1093. if (dbgVar->mParamNum != -1)
  1094. flags.fIsParam = 1;
  1095. outS.Write(*(int16*)&flags);
  1096. bool isConst = false;
  1097. String varName = dbgVar->mName;
  1098. bool isGlobal = false;
  1099. //
  1100. {
  1101. auto checkVal = dbgVar->mValue;
  1102. if (auto beCast = BeValueDynCast<BeCastConstant>(checkVal))
  1103. checkVal = beCast->mTarget;
  1104. if (auto beGlobal = BeValueDynCast<BeGlobalVariable>(checkVal))
  1105. {
  1106. isGlobal = true;
  1107. }
  1108. }
  1109. if (!isGlobal)
  1110. {
  1111. if (auto beConst = BeValueDynCast<BeConstant>(dbgVar->mValue))
  1112. {
  1113. if ((beConst->mType != NULL) && (!beConst->mType->IsPointer()))
  1114. {
  1115. int64 writeVal = beConst->mInt64;
  1116. if (beConst->mType->mTypeCode == BeTypeCode_Float)
  1117. {
  1118. // We need to do this because Singles are stored in mDouble, so we need to reduce here
  1119. float floatVal = (float)beConst->mDouble;
  1120. writeVal = *(uint32*)&floatVal;
  1121. }
  1122. if (writeVal < 0)
  1123. varName += StrFormat("$_%llu", -writeVal);
  1124. else
  1125. varName += StrFormat("$%llu", writeVal);
  1126. isConst = true;
  1127. }
  1128. }
  1129. }
  1130. DbgEncodeString(outS, varName);
  1131. DbgSEndTag();
  1132. // TODO: Split these up into multiple variables if we cover more than 0xF000 bytes...
  1133. DbgSStartTag();
  1134. /*if (dbgVar->mDeclEnd == -1)
  1135. dbgVar->mDeclEnd = dbgFunc->mCodeLen;*/
  1136. int declEnd = dbgVar->mDeclEnd;
  1137. if (declEnd == -1)
  1138. {
  1139. declEnd = dbgFunc->mCodeLen;
  1140. if ((dbgVar->mGaps.size() == 1) && (dbgVar->mGaps[0].mOffset == dbgVar->mDeclStart) && (dbgVar->mGaps[0].mLength == -1) && (!isConst))
  1141. {
  1142. // Variable not used
  1143. declEnd = dbgVar->mDeclStart;
  1144. }
  1145. }
  1146. else if (dbgVar->mDeclLifetimeExtend)
  1147. declEnd++;
  1148. DbgStartVarDefRange(dbgFunc, dbgVar, dbgVar->mPrimaryLoc, dbgVar->mDeclStart, declEnd - dbgVar->mDeclStart);
  1149. if (!isConst)
  1150. {
  1151. for (auto gap : dbgVar->mGaps)
  1152. {
  1153. if (gap.mLength == 0)
  1154. continue;
  1155. if (gap.mLength == -1)
  1156. {
  1157. // Not a real gap, and not an unused variable indicator
  1158. if (gap.mOffset > dbgVar->mDeclStart)
  1159. continue;
  1160. if (gap.mOffset == dbgVar->mDeclEnd)
  1161. continue;
  1162. }
  1163. outS.Write((int16)(gap.mOffset - dbgVar->mDeclStart));
  1164. if (gap.mLength == -1)
  1165. {
  1166. // This means we never even used the variable
  1167. BF_ASSERT(gap.mOffset == dbgVar->mDeclStart);
  1168. outS.Write((int16)(declEnd - gap.mOffset));
  1169. }
  1170. else
  1171. {
  1172. outS.Write((int16)gap.mLength);
  1173. }
  1174. }
  1175. }
  1176. DbgSEndTag(); // S_DEFRANGE_X
  1177. if (!dbgVar->mSavedRanges.empty())
  1178. {
  1179. auto& lastSavedRange = dbgVar->mSavedRanges.back();
  1180. if (lastSavedRange.mLength == -1)
  1181. {
  1182. // This can happen if our variable dies before a saved register restore
  1183. lastSavedRange.mLength = dbgFunc->mCodeLen - lastSavedRange.mOffset;
  1184. }
  1185. auto savedDeclStart = dbgVar->mSavedRanges[0].mOffset;
  1186. // If there is only one value in mSavedRanges, then encode this as just that single span with no gaps
  1187. // Otherwise add gap information for the space between the mSavedRanges values
  1188. DbgSStartTag();
  1189. DbgStartVarDefRange(dbgFunc, dbgVar, dbgVar->mSavedLoc, savedDeclStart,
  1190. (lastSavedRange.mOffset + lastSavedRange.mLength) - savedDeclStart);
  1191. for (int saveGapIdx = 0; saveGapIdx < (int)dbgVar->mSavedRanges.size() - 1; saveGapIdx++)
  1192. {
  1193. auto& saveRange0 = dbgVar->mSavedRanges[saveGapIdx];
  1194. auto& saveRange1 = dbgVar->mSavedRanges[saveGapIdx + 1];
  1195. outS.Write((int16)(saveRange0.mOffset + saveRange0.mLength - savedDeclStart));
  1196. outS.Write((int16)(saveRange1.mOffset - (saveRange0.mOffset + saveRange0.mLength)));
  1197. }
  1198. DbgSEndTag(); // S_DEFRANGE_X
  1199. }
  1200. }
  1201. void BeCOFFObject::DbgOutputLocalVars(BeInlineLineBuilder* curInlineBuilder, BeDbgFunction* dbgFunc)
  1202. {
  1203. auto& outS = mDebugSSect.mData;
  1204. for (auto dbgVar : curInlineBuilder->mVariables)
  1205. {
  1206. if (dbgVar == NULL)
  1207. continue;
  1208. DbgOutputLocalVar(dbgFunc, dbgVar);
  1209. }
  1210. }
  1211. void BeCOFFObject::DbgGenerateModuleInfo()
  1212. {
  1213. BP_ZONE("BeCOFFObject::DbgGenerateModuleInfo");
  1214. AutoPerf perf("BeCOFFObject::DbgGenerateModuleInfo", mPerfManager);
  1215. auto& outS = mDebugSSect.mData;
  1216. outS.Write((int)CV_SIGNATURE_C13);
  1217. Array<int> fileDataPositions;
  1218. Array<BeDbgFunction*> inlinees;
  1219. // Funcs
  1220. for (auto dbgFunc : mBeModule->mDbgModule->mFuncs)
  1221. {
  1222. if (dbgFunc->mValue == NULL)
  1223. continue;
  1224. if (dbgFunc->mCvFuncId == -1)
  1225. continue;
  1226. BF_ASSERT(dbgFunc->mCvFuncId != -1);
  1227. auto funcSym = GetSymbol(dbgFunc->mValue, false);
  1228. if (funcSym == NULL)
  1229. continue;
  1230. DbgStartSection(DEBUG_S_SYMBOLS);
  1231. DbgSStartTag();
  1232. if (dbgFunc->mValue->mLinkageType == BfIRLinkageType_Internal)
  1233. outS.Write((int16)S_LPROC32_ID);
  1234. else
  1235. outS.Write((int16)S_GPROC32_ID);
  1236. outS.Write((int32)0); // PtrParent
  1237. outS.Write((int32)0); // PtrEnd
  1238. outS.Write((int32)0); // PtrNext
  1239. outS.Write((int32)BF_MAX(dbgFunc->mCodeLen, 0)); // CodeSize
  1240. outS.Write((int32)0); // DbgStart
  1241. outS.Write((int32)0); // DbgEnd
  1242. outS.Write(dbgFunc->mCvFuncId);
  1243. BeMCRelocation reloc;
  1244. reloc.mKind = BeMCRelocationKind_SECREL;
  1245. reloc.mOffset = outS.GetPos();
  1246. reloc.mSymTableIdx = funcSym->mIdx;
  1247. mDebugSSect.mRelocs.push_back(reloc);
  1248. outS.Write((int32)0); // off
  1249. reloc.mKind = BeMCRelocationKind_SECTION;
  1250. reloc.mOffset = outS.GetPos();
  1251. reloc.mSymTableIdx = funcSym->mIdx;
  1252. mDebugSSect.mRelocs.push_back(reloc);
  1253. outS.Write((int16)0); // seg
  1254. CV_PROCFLAGS procFlags = { 0 };
  1255. outS.Write(*(uint8*)&procFlags);
  1256. String fullName;
  1257. if ((BeValueDynCast<BeDbgNamespace>(dbgFunc->mScope) != NULL) ||
  1258. (BeValueDynCast<BeDbgStructType>(dbgFunc->mScope) != NULL))
  1259. ToString(dbgFunc->mScope, fullName);
  1260. if (!fullName.empty())
  1261. fullName += "::";
  1262. fullName += dbgFunc->mName;
  1263. DbgEncodeString(outS, fullName);
  1264. DbgSEndTag();
  1265. BeInlineLineBuilder* curInlineBuilder = NULL;
  1266. BeDbgLoc* curDbgLoc = NULL;
  1267. OwnedVector<BeInlineLineBuilder> inlineBuilders;
  1268. Array<BeInlineLineBuilder*> inlineStack;
  1269. Dictionary<BeDbgLoc*, BeInlineLineBuilder*> inlineMap;
  1270. // Build inline table
  1271. for (int emissionIdx = 0; emissionIdx < (int)dbgFunc->mEmissions.size(); emissionIdx++)
  1272. {
  1273. auto& codeEmission = dbgFunc->mEmissions[emissionIdx];
  1274. auto newDbgLoc = codeEmission.mDbgLoc;
  1275. if (curDbgLoc != newDbgLoc)
  1276. {
  1277. curDbgLoc = newDbgLoc;
  1278. int newInlineDepth = newDbgLoc->GetInlineDepth();
  1279. int curInlineDepth = 0;
  1280. if (curInlineBuilder != NULL)
  1281. curInlineDepth = curInlineBuilder->mStartDbgLoc->GetInlineDepth();
  1282. int depthMatch = 0;
  1283. if (curInlineBuilder != NULL)
  1284. depthMatch = curDbgLoc->GetInlineMatchDepth(curInlineBuilder->mStartDbgLoc);
  1285. while (curInlineDepth > depthMatch)
  1286. {
  1287. curInlineBuilder->End(&codeEmission);
  1288. inlineStack.pop_back();
  1289. if (inlineStack.empty())
  1290. curInlineBuilder = NULL;
  1291. else
  1292. curInlineBuilder = inlineStack.back();
  1293. curInlineDepth--;
  1294. }
  1295. // Check for new inlines
  1296. while (newInlineDepth > curInlineDepth)
  1297. {
  1298. auto inlineBuilder = inlineBuilders.Alloc<BeInlineLineBuilder>();
  1299. // If we add more than one inline depth at a time then we need to set startDbgLoc appropriately
  1300. int inlineIdx = newInlineDepth - curInlineDepth - 2;
  1301. if (inlineIdx == -1)
  1302. inlineBuilder->mStartDbgLoc = codeEmission.mDbgLoc;
  1303. else
  1304. inlineBuilder->mStartDbgLoc = codeEmission.mDbgLoc->GetInlinedAt(inlineIdx);
  1305. auto dbgFunc = inlineBuilder->mStartDbgLoc->GetDbgFunc();
  1306. if (!inlinees.Contains(dbgFunc))
  1307. inlinees.Add(dbgFunc);
  1308. inlineBuilder->mCurLine = dbgFunc->mLine;
  1309. inlineBuilder->Start(&codeEmission);
  1310. curInlineBuilder = inlineBuilder;
  1311. inlineStack.push_back(curInlineBuilder);
  1312. curInlineDepth++;
  1313. BF_ASSERT(inlineBuilder->mStartDbgLoc->mDbgInlinedAt != NULL);
  1314. inlineMap[inlineBuilder->mStartDbgLoc->mDbgInlinedAt] = inlineBuilder;
  1315. }
  1316. if (curInlineBuilder != NULL)
  1317. curInlineBuilder->Update(&codeEmission);
  1318. }
  1319. }
  1320. BF_ASSERT(inlineStack.empty());
  1321. for (auto dbgVar : dbgFunc->mVariables)
  1322. {
  1323. if ((dbgVar == NULL) || (dbgVar->mDeclDbgLoc == NULL))
  1324. continue;
  1325. if (dbgVar->mDeclDbgLoc->mDbgInlinedAt == NULL)
  1326. continue;
  1327. BeInlineLineBuilder* inlineBuilder = NULL;
  1328. if (inlineMap.TryGetValue(dbgVar->mDeclDbgLoc->mDbgInlinedAt, &inlineBuilder))
  1329. {
  1330. //auto inlineBuilder = itr->second;
  1331. inlineBuilder->mVariables.push_back(dbgVar);
  1332. }
  1333. }
  1334. // Emit inlines and variables
  1335. int inlineBuilderIdx = 0;
  1336. curInlineBuilder = NULL;
  1337. for (auto dbgVar : dbgFunc->mVariables)
  1338. {
  1339. if ((dbgVar == NULL) || (dbgVar->mDeclDbgLoc == NULL))
  1340. continue;
  1341. if (dbgVar->mDeclDbgLoc->mDbgInlinedAt == NULL)
  1342. DbgOutputLocalVar(dbgFunc, dbgVar);
  1343. }
  1344. while ((inlineBuilderIdx < (int)inlineBuilders.size()) || (curInlineBuilder != NULL) /*|| (varIdx < (int)dbgFunc->mVariables.size())*/)
  1345. {
  1346. BeInlineLineBuilder* newInlineBuilder = NULL;
  1347. int curInlineDepth = 0;
  1348. if (curInlineBuilder != NULL)
  1349. curInlineDepth = curInlineBuilder->mStartDbgLoc->GetInlineDepth();
  1350. int newInlineDepth = 0;
  1351. if (inlineBuilderIdx < (int)inlineBuilders.size())
  1352. {
  1353. newInlineBuilder = inlineBuilders[inlineBuilderIdx++];
  1354. newInlineDepth = newInlineBuilder->mStartDbgLoc->GetInlineDepth();
  1355. }
  1356. int depthMatch = 0;
  1357. if ((curInlineBuilder != NULL) && (newInlineBuilder != NULL))
  1358. depthMatch = curInlineBuilder->mStartDbgLoc->GetInlineMatchDepth(newInlineBuilder->mStartDbgLoc);
  1359. if ((curInlineDepth == newInlineDepth) && (depthMatch == newInlineDepth) && (depthMatch > 0))
  1360. {
  1361. // If we inline two of the same methods on the same line then its possible they share the same inlined position
  1362. // But we know there is a unique item here
  1363. depthMatch--;
  1364. }
  1365. while (curInlineDepth > depthMatch)
  1366. {
  1367. DbgSStartTag();
  1368. outS.Write((int16)S_INLINESITE_END);
  1369. DbgSEndTag();
  1370. curInlineDepth--;
  1371. inlineStack.pop_back();
  1372. if (inlineStack.empty())
  1373. curInlineBuilder = NULL;
  1374. else
  1375. curInlineBuilder = inlineStack.back();
  1376. }
  1377. if (newInlineDepth > curInlineDepth)
  1378. {
  1379. BF_ASSERT(newInlineDepth == curInlineDepth + 1);
  1380. DbgSStartTag();
  1381. outS.Write((int16)S_INLINESITE);
  1382. outS.Write((int32)0); // pParent
  1383. outS.Write((int32)0); // pEnd
  1384. auto inlinedDbgFunc = newInlineBuilder->mStartDbgLoc->GetDbgFunc();
  1385. if (inlinedDbgFunc->mCvFuncId == -1)
  1386. DbgMakeFunc(inlinedDbgFunc);
  1387. outS.Write(inlinedDbgFunc->mCvFuncId);
  1388. outS.Write(&newInlineBuilder->mData[0], (int)newInlineBuilder->mData.size());
  1389. DbgSEndTag();
  1390. newInlineDepth++;
  1391. inlineStack.push_back(newInlineBuilder);
  1392. curInlineBuilder = newInlineBuilder;
  1393. DbgOutputLocalVars(curInlineBuilder, dbgFunc);
  1394. }
  1395. // This can fail if an inlined method is not emitted contiguously, or if multiple copies of the same method
  1396. // get inlined at exactly the same DbgLoc -- which isn't possible in Beef
  1397. //BF_ASSERT(curInlineBuilder == newInlineBuilder);
  1398. }
  1399. DbgSStartTag();
  1400. outS.Write((int16)S_PROC_ID_END);
  1401. DbgSEndTag();
  1402. DbgEndSection(); // DEBUG_S_SYMBOLS
  1403. if (dbgFunc->mEmissions.empty())
  1404. continue;
  1405. DbgStartSection(DEBUG_S_LINES);
  1406. reloc.mKind = BeMCRelocationKind_SECREL;
  1407. reloc.mOffset = outS.GetPos();
  1408. reloc.mSymTableIdx = funcSym->mIdx;
  1409. mDebugSSect.mRelocs.push_back(reloc);
  1410. outS.Write((int32)0x0); // offset contribution
  1411. reloc.mKind = BeMCRelocationKind_SECTION;
  1412. reloc.mOffset = outS.GetPos();
  1413. reloc.mSymTableIdx = funcSym->mIdx;
  1414. mDebugSSect.mRelocs.push_back(reloc);
  1415. outS.Write((int16)0); // section contribution
  1416. int16 flags = CV_LINES_HAVE_COLUMNS;
  1417. outS.Write((int16)flags);
  1418. outS.Write(dbgFunc->mCodeLen); // contribution size
  1419. // Iterate over lines
  1420. // int32 offFile (file num)
  1421. // int32 nLines
  1422. // int32 cbBlock
  1423. curDbgLoc = NULL;
  1424. BeDbgFile* curFile = NULL;
  1425. int lastBlockStartPos = -1;
  1426. int lineCount = 0;
  1427. Array<BeDbgCodeEmission> emissions;
  1428. emissions.Reserve(dbgFunc->mEmissions.size());
  1429. for (int emissionIdx = 0; emissionIdx < (int)dbgFunc->mEmissions.size(); emissionIdx++)
  1430. {
  1431. auto& codeEmission = dbgFunc->mEmissions[emissionIdx];
  1432. auto rootDbgLoc = codeEmission.mDbgLoc->GetRoot();
  1433. bool doEmission = true;
  1434. if (!emissions.empty())
  1435. {
  1436. if (rootDbgLoc == emissions.back().mDbgLoc)
  1437. doEmission = false;
  1438. }
  1439. if (doEmission)
  1440. {
  1441. BeDbgCodeEmission newEmission;
  1442. newEmission.mDbgLoc = rootDbgLoc;
  1443. newEmission.mPos = codeEmission.mPos;
  1444. emissions.push_back(newEmission);
  1445. }
  1446. }
  1447. ///
  1448. {
  1449. int fileDataPos = 0;
  1450. for (auto dbgFile : mBeModule->mDbgModule->mFiles)
  1451. {
  1452. fileDataPositions.Add(fileDataPos);
  1453. fileDataPos += 4;
  1454. if (dbgFile->mMD5Hash.IsZero())
  1455. fileDataPos += 4;
  1456. else
  1457. fileDataPos += 20;
  1458. }
  1459. }
  1460. int emissionStartIdx = 0;
  1461. BeDbgFile* curDbgFile = NULL;
  1462. for (int emissionIdx = 0; emissionIdx < (int)emissions.size(); emissionIdx++)
  1463. {
  1464. auto& codeEmission = emissions[emissionIdx];
  1465. auto dbgLoc = codeEmission.mDbgLoc;
  1466. BeDbgFile* dbgFile = dbgLoc->GetDbgFile();
  1467. if (dbgFile != curDbgFile)
  1468. {
  1469. if (curDbgLoc != NULL)
  1470. {
  1471. DbgEndLineBlock(dbgFunc, emissions, lastBlockStartPos, emissionStartIdx, lineCount);
  1472. lineCount = 0;
  1473. emissionStartIdx = emissionIdx;
  1474. }
  1475. curDbgLoc = dbgLoc;
  1476. curDbgFile = dbgFile;
  1477. lastBlockStartPos = outS.GetPos();
  1478. outS.Write((int32)fileDataPositions[dbgFile->mIdx]);
  1479. outS.Write((int32)0); // placeholder nLines
  1480. outS.Write((int32)0); // placeholder cbBlock
  1481. if ((emissionIdx == 0) && (dbgFunc->mLine != -1))
  1482. {
  1483. outS.Write((int32)0);
  1484. outS.Write((int32)dbgFunc->mLine + 1);
  1485. }
  1486. }
  1487. outS.Write((int32)codeEmission.mPos);
  1488. outS.Write((int32)codeEmission.mDbgLoc->mLine + 1);
  1489. lineCount++;
  1490. }
  1491. if (curDbgLoc != NULL)
  1492. DbgEndLineBlock(dbgFunc, emissions, lastBlockStartPos, emissionStartIdx, lineCount);
  1493. DbgEndSection(); // DEBUG_S_LINES
  1494. }
  1495. if (!inlinees.empty())
  1496. {
  1497. DbgStartSection(DEBUG_S_INLINEELINES);
  1498. outS.Write((int32)0); // Lines type
  1499. for (auto inlinedDbgFunc : inlinees)
  1500. {
  1501. BF_ASSERT(inlinedDbgFunc->mCvFuncId != -1);
  1502. outS.Write(inlinedDbgFunc->mCvFuncId);
  1503. auto dbgFile = inlinedDbgFunc->mFile;
  1504. outS.Write((int32)fileDataPositions[dbgFile->mIdx]);
  1505. outS.Write((int32)inlinedDbgFunc->mLine + 1);
  1506. }
  1507. DbgEndSection();
  1508. }
  1509. // Global variables
  1510. {
  1511. bool startedSymbols = false;
  1512. for (auto dbgGlobalVar : mBeModule->mDbgModule->mGlobalVariables)
  1513. {
  1514. auto gvSym = GetSymbol(dbgGlobalVar->mValue);
  1515. if (gvSym == NULL)
  1516. {
  1517. //TODO: Is this an error?
  1518. continue;
  1519. }
  1520. if (!startedSymbols)
  1521. {
  1522. DbgStartSection(DEBUG_S_SYMBOLS);
  1523. startedSymbols = true;
  1524. }
  1525. DbgSStartTag();
  1526. bool isTLS = false;
  1527. if (auto beGlobalVar = BeValueDynCast<BeGlobalVariable>(dbgGlobalVar->mValue))
  1528. isTLS = beGlobalVar->mIsTLS;
  1529. if (isTLS)
  1530. outS.Write(dbgGlobalVar->mIsLocalToUnit ? (int16)S_LTHREAD32 : (int16)S_GTHREAD32);
  1531. else
  1532. outS.Write(dbgGlobalVar->mIsLocalToUnit ? (int16)S_LDATA32 : (int16)S_GDATA32);
  1533. outS.Write(DbgGetTypeId(BeValueDynCast<BeDbgType>(dbgGlobalVar->mType)));
  1534. BF_ASSERT(dbgGlobalVar->mValue != NULL);
  1535. BeMCRelocation reloc;
  1536. reloc.mKind = BeMCRelocationKind_SECREL;
  1537. reloc.mOffset = outS.GetPos();
  1538. reloc.mSymTableIdx = gvSym->mIdx;
  1539. mDebugSSect.mRelocs.push_back(reloc);
  1540. outS.Write((int32)0x0); // offset contribution
  1541. reloc.mKind = BeMCRelocationKind_SECTION;
  1542. reloc.mOffset = outS.GetPos();
  1543. reloc.mSymTableIdx = gvSym->mIdx;
  1544. mDebugSSect.mRelocs.push_back(reloc);
  1545. outS.Write((int16)0); // section contribution
  1546. DbgEncodeString(outS, dbgGlobalVar->mName);
  1547. DbgSEndTag();
  1548. }
  1549. if (startedSymbols)
  1550. DbgEndSection(); // DEBUG_S_SYMBOLS
  1551. }
  1552. bool startedUDT = false;
  1553. for (auto dbgType : mBeModule->mDbgModule->mTypes)
  1554. {
  1555. if (auto dbgStructType = BeValueDynCast<BeDbgStructType>(dbgType))
  1556. {
  1557. if (dbgStructType->mIsFullyDefined)
  1558. {
  1559. if (!startedUDT)
  1560. {
  1561. DbgStartSection(DEBUG_S_SYMBOLS);
  1562. startedUDT = true;
  1563. }
  1564. DbgSStartTag();
  1565. outS.Write((int16)S_UDT);
  1566. outS.Write(DbgGetTypeId(dbgStructType));
  1567. String fullName;
  1568. ToString(dbgStructType, fullName);
  1569. DbgEncodeString(outS, fullName);
  1570. DbgSEndTag();
  1571. }
  1572. }
  1573. }
  1574. if (startedUDT)
  1575. DbgEndSection();
  1576. DbgStartSection(DEBUG_S_FILECHKSMS);
  1577. Array<char> strTable;
  1578. strTable.push_back(0);
  1579. for (auto dbgFile : mBeModule->mDbgModule->mFiles)
  1580. {
  1581. outS.Write((int32)strTable.size());
  1582. if (dbgFile->mMD5Hash.IsZero())
  1583. {
  1584. outS.Write((int32)0); // hashLen, hashType, padding
  1585. }
  1586. else
  1587. {
  1588. outS.Write((uint8)16); // hashLen
  1589. outS.Write((uint8)1); // hashType
  1590. outS.Write(&dbgFile->mMD5Hash, 16);
  1591. outS.Write((int8)0); // padding
  1592. outS.Write((int8)0);
  1593. }
  1594. String fullPath;
  1595. dbgFile->ToString(fullPath);
  1596. strTable.Insert(strTable.size(), &fullPath[0], fullPath.length());
  1597. strTable.push_back(0);
  1598. }
  1599. DbgEndSection();
  1600. DbgStartSection(DEBUG_S_STRINGTABLE);
  1601. outS.Write(&strTable[0], (int)strTable.size());
  1602. DbgSAlign();
  1603. DbgEndSection();
  1604. }
  1605. void BeCOFFObject::InitSect(BeCOFFSection& sect, const StringImpl& name, int characteristics, bool addNow, bool makeSectSymbol)
  1606. {
  1607. sect.mSectName = name;
  1608. sect.mCharacteristics = characteristics;
  1609. if (addNow)
  1610. MarkSectionUsed(sect, makeSectSymbol);
  1611. }
  1612. void BeCOFFObject::AlignConst(BeCOFFSection& sect, BeConstant* constVal)
  1613. {
  1614. auto beType = constVal->GetType();
  1615. sect.mAlign = BF_MAX(sect.mAlign, beType->mAlign);
  1616. sect.mData.Align(beType->mAlign);
  1617. }
  1618. void BeCOFFObject::WriteConst(BeCOFFSection& sect, BeConstant* constVal)
  1619. {
  1620. auto beType = constVal->GetType();
  1621. if (auto globalVar = BeValueDynCast<BeGlobalVariable>(constVal))
  1622. {
  1623. auto sym = GetSymbol(globalVar);
  1624. BeMCRelocation reloc;
  1625. reloc.mKind = BeMCRelocationKind_ADDR64;
  1626. reloc.mOffset = sect.mData.GetPos();
  1627. reloc.mSymTableIdx = sym->mIdx;
  1628. sect.mRelocs.push_back(reloc);
  1629. sect.mData.Write((int64)0);
  1630. }
  1631. else if (auto beFunc = BeValueDynCast<BeFunction>(constVal))
  1632. {
  1633. auto sym = GetSymbol(beFunc);
  1634. BeMCRelocation reloc;
  1635. reloc.mKind = BeMCRelocationKind_ADDR64;
  1636. reloc.mOffset = sect.mData.GetPos();
  1637. reloc.mSymTableIdx = sym->mIdx;
  1638. sect.mRelocs.push_back(reloc);
  1639. sect.mData.Write((int64)0);
  1640. }
  1641. else if (auto constStruct = BeValueDynCast<BeStructConstant>(constVal))
  1642. {
  1643. int startOfs = sect.mData.GetSize();
  1644. if (constStruct->mType->mTypeCode == BeTypeCode_Struct)
  1645. {
  1646. BeStructType* structType = (BeStructType*)constStruct->mType;
  1647. BF_ASSERT(structType->mMembers.size() == constStruct->mMemberValues.size());
  1648. for (int memberIdx = 0; memberIdx < (int)constStruct->mMemberValues.size(); memberIdx++)
  1649. {
  1650. auto& member = structType->mMembers[memberIdx];
  1651. // Do any per-member alignment
  1652. sect.mData.WriteZeros(member.mByteOffset - (sect.mData.GetSize() - startOfs));
  1653. WriteConst(sect, constStruct->mMemberValues[memberIdx]);
  1654. }
  1655. // Do end padding
  1656. sect.mData.WriteZeros(structType->mSize - (sect.mData.GetSize() - startOfs));
  1657. }
  1658. else if (constStruct->mType->mTypeCode == BeTypeCode_SizedArray)
  1659. {
  1660. BeSizedArrayType* arrayType = (BeSizedArrayType*)constStruct->mType;
  1661. for (auto& memberVal : constStruct->mMemberValues)
  1662. {
  1663. WriteConst(sect, memberVal);
  1664. int padding = arrayType->mElementType->GetStride() - arrayType->mElementType->mSize;
  1665. if (padding > 0)
  1666. sect.mData.WriteZeros(padding);
  1667. }
  1668. }
  1669. else
  1670. BF_FATAL("Invalid StructConst type");
  1671. }
  1672. else if (auto constStr = BeValueDynCast<BeStringConstant>(constVal))
  1673. {
  1674. sect.mData.Write((void*)constStr->mString.c_str(), (int)constStr->mString.length() + 1);
  1675. }
  1676. else if (auto constCast = BeValueDynCast<BeCastConstant>(constVal))
  1677. {
  1678. WriteConst(sect, constCast->mTarget);
  1679. }
  1680. else if (auto constGep = BeValueDynCast<BeGEP2Constant>(constVal))
  1681. {
  1682. if (auto globalVar = BeValueDynCast<BeGlobalVariable>(constGep->mTarget))
  1683. {
  1684. BF_ASSERT(constGep->mIdx0 == 0);
  1685. int64 dataOfs = 0;
  1686. if (globalVar->mType->mTypeCode == BeTypeCode_Struct)
  1687. {
  1688. auto structType = (BeStructType*)globalVar->mType;
  1689. dataOfs = structType->mMembers[constGep->mIdx1].mByteOffset;
  1690. }
  1691. else if (globalVar->mType->mTypeCode == BeTypeCode_SizedArray)
  1692. {
  1693. auto arrayType = (BeSizedArrayType*)globalVar->mType;
  1694. dataOfs = arrayType->mElementType->mSize * constGep->mIdx1;
  1695. }
  1696. else
  1697. {
  1698. BF_FATAL("Invalid GEP");
  1699. }
  1700. auto sym = GetSymbol(globalVar);
  1701. BeMCRelocation reloc;
  1702. reloc.mKind = BeMCRelocationKind_ADDR64;
  1703. reloc.mOffset = sect.mData.GetPos();
  1704. reloc.mSymTableIdx = sym->mIdx;
  1705. sect.mRelocs.push_back(reloc);
  1706. sect.mData.Write((int64)dataOfs);
  1707. }
  1708. else
  1709. {
  1710. BF_FATAL("Invalid GEPConstant");
  1711. }
  1712. }
  1713. else if ((beType->IsPointer()) && (constVal->mTarget != NULL))
  1714. {
  1715. WriteConst(sect, constVal->mTarget);
  1716. }
  1717. else if (beType->IsComposite())
  1718. {
  1719. BF_ASSERT(constVal->mInt64 == 0);
  1720. int64 zero = 0;
  1721. int sizeLeft = beType->mSize;
  1722. while (sizeLeft > 0)
  1723. {
  1724. int writeSize = BF_MIN(sizeLeft, 8);
  1725. sect.mData.Write(&zero, writeSize);
  1726. sizeLeft -= writeSize;
  1727. }
  1728. }
  1729. else if (beType->mTypeCode == BeTypeCode_Float)
  1730. {
  1731. float f = constVal->mDouble;
  1732. sect.mData.Write((void*)&f, sizeof(float));
  1733. }
  1734. else
  1735. {
  1736. sect.mData.Write((void*)&constVal->mInt64, beType->mSize);
  1737. }
  1738. }
  1739. namespace BeefyDbg64
  1740. {
  1741. void TestCoff(void* tdata, int tdataSize, void* cuData, int cuDataSize);
  1742. }
  1743. void BeCOFFObject::Generate(BeModule* module)
  1744. {
  1745. mBeModule = module;
  1746. bool hasDebugInfo = module->mDbgModule != NULL;
  1747. DynMemStream textSegData;
  1748. InitSect(mTextSect, ".text", IMAGE_SCN_CNT_CODE | IMAGE_SCN_ALIGN_16BYTES | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ, true, true);
  1749. InitSect(mDataSect, ".data", IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE, true, false);
  1750. InitSect(mRDataSect, ".rdata", IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ, true, false);
  1751. InitSect(mBSSSect, ".bss", IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE, true, false);
  1752. InitSect(mTLSSect, ".tls$", IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE, true, false);
  1753. mBSSSect.mAlign = 4;
  1754. InitSect(mXDataSect, ".xdata", IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_READ, true, true);
  1755. if (hasDebugInfo)
  1756. {
  1757. InitSect(mDebugSSect, ".debug$S", IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_DISCARDABLE | IMAGE_SCN_MEM_READ, true, false);
  1758. InitSect(mDebugTSect, ".debug$T", IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_DISCARDABLE | IMAGE_SCN_MEM_READ, true, false);
  1759. }
  1760. InitSect(mPDataSect, ".pdata", IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_READ, true, false);
  1761. mTextSect.mData.mData.Reserve(4096);
  1762. BfSizedVector<BeMCSymbol*, 32> globalVarSyms;
  1763. for (int globalVarIdx = 0; globalVarIdx < (int)module->mGlobalVariables.size(); globalVarIdx++)
  1764. {
  1765. auto globalVar = module->mGlobalVariables[globalVarIdx];
  1766. if ((globalVar->mRefCount == 0) && (globalVar->mInitializer == NULL))
  1767. {
  1768. globalVarSyms.push_back(NULL);
  1769. continue;
  1770. }
  1771. BeMCSymbol* sym = mSymbols.Alloc();
  1772. sym->mType = globalVar->mType;
  1773. sym->mName = globalVar->mName;
  1774. sym->mIsStatic = globalVar->mLinkageType == BfIRLinkageType_Internal;
  1775. sym->mSymKind = BeMCSymbolKind_External;
  1776. sym->mIdx = (int)mSymbols.size() - 1;
  1777. sym->mIsTLS = globalVar->mIsTLS;
  1778. globalVarSyms.push_back(sym);
  1779. mSymbolMap[globalVar] = sym;
  1780. }
  1781. for (int globalVarIdx = 0; globalVarIdx < (int)module->mGlobalVariables.size(); globalVarIdx++)
  1782. {
  1783. auto globalVar = module->mGlobalVariables[globalVarIdx];
  1784. if ((globalVar->mRefCount == 0) && (globalVar->mInitializer == NULL))
  1785. continue;
  1786. auto sym = globalVarSyms[globalVarIdx];
  1787. if (globalVar->mInitializer != NULL)
  1788. {
  1789. if (globalVar->mAlign == -1)
  1790. globalVar->mAlign = globalVar->mType->mAlign;
  1791. BF_ASSERT(globalVar->mAlign != -1);
  1792. if (globalVar->mIsConstant)
  1793. {
  1794. auto constVal = BeValueDynCast<BeConstant>(globalVar->mInitializer);
  1795. MarkSectionUsed(mRDataSect);
  1796. sym->mSectionNum = mRDataSect.mSectionIdx + 1;
  1797. mRDataSect.mData.Align(globalVar->mAlign);
  1798. mRDataSect.mAlign = BF_MAX(mRDataSect.mAlign, globalVar->mAlign);
  1799. AlignConst(mRDataSect, constVal);
  1800. sym->mValue = mRDataSect.mData.GetSize();
  1801. WriteConst(mRDataSect, constVal);
  1802. }
  1803. else if (globalVar->mIsTLS)
  1804. {
  1805. MarkSectionUsed(mTLSSect);
  1806. sym->mSectionNum = mTLSSect.mSectionIdx + 1;
  1807. mTLSSect.mSizeOverride = (mTLSSect.mSizeOverride + globalVar->mAlign - 1) & ~(globalVar->mAlign - 1);
  1808. mTLSSect.mAlign = BF_MAX(mTLSSect.mAlign, globalVar->mAlign);
  1809. sym->mValue = mTLSSect.mSizeOverride;
  1810. mTLSSect.mSizeOverride += globalVar->mType->mSize;
  1811. }
  1812. else if (auto funcVal = BeValueDynCast<BeFunction>(globalVar->mInitializer))
  1813. {
  1814. auto& sect = mDataSect;
  1815. MarkSectionUsed(sect);
  1816. sym->mSectionNum = sect.mSectionIdx + 1;
  1817. sect.mData.Align(globalVar->mAlign);
  1818. sect.mAlign = BF_MAX(sect.mAlign, globalVar->mAlign);
  1819. sym->mValue = sect.mData.GetSize();
  1820. auto sym = GetSymbol(funcVal);
  1821. BeMCRelocation reloc;
  1822. reloc.mKind = BeMCRelocationKind_ADDR64;
  1823. reloc.mOffset = sect.mData.GetPos();
  1824. reloc.mSymTableIdx = sym->mIdx;
  1825. sect.mRelocs.push_back(reloc);
  1826. sect.mData.Write((int64)0);
  1827. }
  1828. else if (auto constVal = BeValueDynCast<BeConstant>(globalVar->mInitializer))
  1829. {
  1830. MarkSectionUsed(mDataSect);
  1831. sym->mSectionNum = mDataSect.mSectionIdx + 1;
  1832. mDataSect.mData.Align(globalVar->mAlign);
  1833. mDataSect.mAlign = BF_MAX(mDataSect.mAlign, globalVar->mAlign);
  1834. AlignConst(mDataSect, constVal);
  1835. sym->mValue = mDataSect.mData.GetSize();
  1836. WriteConst(mDataSect, constVal);
  1837. }
  1838. else
  1839. {
  1840. MarkSectionUsed(mBSSSect);
  1841. sym->mSectionNum = mBSSSect.mSectionIdx + 1;
  1842. mBSSSect.mSizeOverride = (mBSSSect.mSizeOverride + globalVar->mAlign - 1) & ~(globalVar->mAlign - 1);
  1843. mBSSSect.mAlign = BF_MAX(mBSSSect.mAlign, globalVar->mAlign);
  1844. sym->mValue = mBSSSect.mSizeOverride;
  1845. mBSSSect.mSizeOverride += globalVar->mType->mSize;
  1846. }
  1847. }
  1848. if (globalVar->mStorageKind == BfIRStorageKind_Export)
  1849. {
  1850. mDirectives += " ";
  1851. mDirectives.Append("/EXPORT:");
  1852. mDirectives.Append(globalVar->mName);
  1853. }
  1854. }
  1855. for (int i = 0; i < mTLSSect.mSizeOverride; i++)
  1856. mTLSSect.mData.Write((uint8)0);
  1857. for (int funcIdx = 0; funcIdx < (int)module->mFunctions.size(); funcIdx++)
  1858. {
  1859. auto func = module->mFunctions[funcIdx];
  1860. if ((!func->IsDecl()) && (func->mLinkageType == BfIRLinkageType_External))
  1861. {
  1862. GetSymbol(func);
  1863. }
  1864. }
  1865. while (!mFuncWorkList.IsEmpty())
  1866. {
  1867. auto func = mFuncWorkList[0];
  1868. mFuncWorkList.RemoveAt(0);
  1869. module->mActiveFunction = func;
  1870. if (!func->IsDecl())
  1871. {
  1872. BeMCSymbol* sym = GetSymbol(func);
  1873. BF_ASSERT(sym != NULL);
  1874. sym->mValue = mTextSect.mData.GetSize();
  1875. BeMCContext context(this);
  1876. context.Generate(func);
  1877. if (func->mIsDLLExport)
  1878. {
  1879. mDirectives += " ";
  1880. mDirectives.Append("/EXPORT:");
  1881. mDirectives.Append(func->mName);
  1882. }
  1883. }
  1884. }
  1885. if (!mDirectives.IsEmpty())
  1886. {
  1887. InitSect(mDirectiveSect, ".drectve", IMAGE_SCN_LNK_INFO | IMAGE_SCN_LNK_REMOVE | IMAGE_SCN_ALIGN_1BYTES, true, false);
  1888. mDirectiveSect.mData.Write((void*)mDirectives.c_str(), (int)mDirectives.length());
  1889. }
  1890. if (hasDebugInfo)
  1891. {
  1892. DbgGenerateTypeInfo();
  1893. DbgGenerateModuleInfo();
  1894. }
  1895. {
  1896. //BeefyDbg64::TestCoff(&mDebugTSect.mData.mData[0], mDebugTSect.mData.GetSize(), &mDebugSSect.mData.mData[0], mDebugSSect.mData.GetSize());
  1897. }
  1898. }
  1899. bool BeCOFFObject::Generate(BeModule* module, const StringImpl& fileName)
  1900. {
  1901. BP_ZONE_F("BeCOFFObject::Generate %s", fileName.c_str());
  1902. AutoPerf perf("BeCOFFObject::Generate", mPerfManager);
  1903. if (mWriteToLib)
  1904. {
  1905. DynMemStream memStream;
  1906. Generate(module);
  1907. mStream = &memStream;
  1908. Finish();
  1909. mStream = NULL;
  1910. BeLibEntry* libEntry = BeLibManager::Get()->AddFile(fileName, memStream.GetPtr(), memStream.GetSize());
  1911. if (libEntry == NULL)
  1912. return false;
  1913. for (auto sym : mSymbols)
  1914. {
  1915. if (sym->mIsStatic)
  1916. continue;
  1917. if (((sym->mSymKind == BeMCSymbolKind_External) && (sym->mSectionNum != 0)) ||
  1918. ((sym->mSymKind == BeMCSymbolKind_Function)))
  1919. {
  1920. libEntry->AddSymbol(sym->mName);
  1921. }
  1922. }
  1923. }
  1924. else
  1925. {
  1926. SysFileStream fileStream;
  1927. bool success = fileStream.Open(fileName, BfpFileCreateKind_CreateAlways, BfpFileCreateFlag_Write);
  1928. if (!success)
  1929. return false;
  1930. Generate(module);
  1931. mStream = &fileStream;
  1932. Finish();
  1933. mStream = NULL;
  1934. {
  1935. BP_ZONE("BeCOFFObject::Generate.fclose");
  1936. AutoPerf perf("BeCOFFObject::Generate - fclose", mPerfManager);
  1937. fileStream.Close();
  1938. }
  1939. }
  1940. return true;
  1941. }
  1942. void BeCOFFObject::Finish()
  1943. {
  1944. BP_ZONE("BeCOFFObject::Finish");
  1945. //AutoPerf perf("BeCOFFObject::Finish", mPerfManager);
  1946. PEFileHeader header;
  1947. memset(&header, 0, sizeof(header));
  1948. header.mMachine = PE_MACHINE_X64;
  1949. header.mTimeDateStamp = mTimestamp;
  1950. header.mNumberOfSections = (int)mUsedSections.size();
  1951. SizedArray<PESectionHeader, 16> sectHdrs;
  1952. sectHdrs.resize(header.mNumberOfSections);
  1953. SizedArray<BeCOFFSection*, 16> sectData;
  1954. sectData.resize(header.mNumberOfSections);
  1955. int filePos = sizeof(PEFileHeader) + header.mNumberOfSections*sizeof(PESectionHeader);
  1956. for (int sectNum = 0; sectNum < header.mNumberOfSections; sectNum++)
  1957. {
  1958. PESectionHeader& sectHdr = sectHdrs[sectNum];
  1959. memset(&sectHdr, 0, sizeof(sectHdr));
  1960. BeCOFFSection* sect = mUsedSections[sectNum];
  1961. strcpy(sectHdr.mName, sect->mSectName.c_str());
  1962. int characteristics = sect->mCharacteristics;
  1963. if (sect->mAlign != 0)
  1964. {
  1965. if (sect->mAlign == 8192) characteristics |= IMAGE_SCN_ALIGN_8192BYTES;
  1966. else if (sect->mAlign == 4096) characteristics |= IMAGE_SCN_ALIGN_4096BYTES;
  1967. else if (sect->mAlign == 2048) characteristics |= IMAGE_SCN_ALIGN_2048BYTES;
  1968. else if (sect->mAlign == 1024) characteristics |= IMAGE_SCN_ALIGN_1024BYTES;
  1969. else if (sect->mAlign == 512) characteristics |= IMAGE_SCN_ALIGN_512BYTES;
  1970. else if (sect->mAlign == 256) characteristics |= IMAGE_SCN_ALIGN_256BYTES;
  1971. else if (sect->mAlign == 128) characteristics |= IMAGE_SCN_ALIGN_128BYTES;
  1972. else if (sect->mAlign == 64) characteristics |= IMAGE_SCN_ALIGN_64BYTES;
  1973. else if (sect->mAlign == 32) characteristics |= IMAGE_SCN_ALIGN_32BYTES;
  1974. else if (sect->mAlign == 16) characteristics |= IMAGE_SCN_ALIGN_16BYTES;
  1975. else if (sect->mAlign == 8) characteristics |= IMAGE_SCN_ALIGN_8BYTES;
  1976. else if (sect->mAlign == 4) characteristics |= IMAGE_SCN_ALIGN_4BYTES;
  1977. else if (sect->mAlign == 2) characteristics |= IMAGE_SCN_ALIGN_2BYTES;
  1978. }
  1979. sectData[sectNum] = sect;
  1980. int dataSize = sect->mData.GetSize();
  1981. if (dataSize != 0)
  1982. {
  1983. sectHdr.mPointerToRawData = filePos;
  1984. sectHdr.mSizeOfRawData = dataSize;
  1985. filePos += dataSize;
  1986. if (!sect->mRelocs.empty())
  1987. {
  1988. sectHdr.mPointerToRelocations = filePos;
  1989. if (sect->mRelocs.size() > 0xFFFF)
  1990. {
  1991. characteristics |= IMAGE_SCN_LNK_NRELOC_OVFL;
  1992. // Extended reloc count
  1993. sectHdr.mNumberOfRelocations = 0xFFFF;
  1994. filePos += sizeof(COFFRelocation);
  1995. }
  1996. else
  1997. {
  1998. sectHdr.mNumberOfRelocations = (int)sect->mRelocs.size();
  1999. }
  2000. filePos += (int)sect->mRelocs.size() * sizeof(COFFRelocation);
  2001. }
  2002. }
  2003. else
  2004. {
  2005. sectHdr.mSizeOfRawData = sect->mSizeOverride;
  2006. }
  2007. sectHdr.mCharacteristics = characteristics;
  2008. BF_ASSERT(characteristics != 0);
  2009. }
  2010. header.mPointerToSymbolTable = filePos;
  2011. header.mNumberOfSymbols = (int)mSymbols.size();
  2012. mStream->WriteT(header);
  2013. for (int sectNum = 0; sectNum < header.mNumberOfSections; sectNum++)
  2014. {
  2015. PESectionHeader& sectHdr = sectHdrs[sectNum];
  2016. mStream->WriteT(sectHdr);
  2017. }
  2018. for (int sectNum = 0; sectNum < header.mNumberOfSections; sectNum++)
  2019. {
  2020. BeCOFFSection* sect = sectData[sectNum];
  2021. if (sect == NULL)
  2022. continue;
  2023. PESectionHeader& sectHdr = sectHdrs[sectNum];
  2024. if (sectHdr.mPointerToRawData != 0)
  2025. BF_ASSERT(mStream->GetPos() == sectHdr.mPointerToRawData);
  2026. if (sect->mData.GetSize() != 0)
  2027. {
  2028. mStream->Write((uint8*)sect->mData.GetPtr(), (int)sect->mData.GetSize());
  2029. BF_ASSERT(mStream->GetPos() == sectHdr.mPointerToRawData + (int)sect->mData.GetSize());
  2030. }
  2031. int relocIdx = 0;
  2032. if (sect->mRelocs.size() > 0xFFFF)
  2033. {
  2034. // Extended reloc count
  2035. COFFRelocation coffReloc = { 0 };
  2036. coffReloc.mVirtualAddress = sect->mRelocs.size() + 1;
  2037. mStream->WriteT(coffReloc);
  2038. relocIdx++;
  2039. }
  2040. for (auto& reloc : sect->mRelocs)
  2041. {
  2042. COFFRelocation coffReloc;
  2043. coffReloc.mVirtualAddress = reloc.mOffset;
  2044. coffReloc.mSymbolTableIndex = reloc.mSymTableIdx;
  2045. coffReloc.mType = IMAGE_REL_AMD64_ABSOLUTE;
  2046. switch (reloc.mKind)
  2047. {
  2048. case BeMCRelocationKind_ADDR32NB:
  2049. coffReloc.mType = IMAGE_REL_AMD64_ADDR32NB;
  2050. break;
  2051. case BeMCRelocationKind_ADDR64:
  2052. coffReloc.mType = IMAGE_REL_AMD64_ADDR64;
  2053. break;
  2054. case BeMCRelocationKind_REL32:
  2055. coffReloc.mType = IMAGE_REL_AMD64_REL32;
  2056. break;
  2057. case BeMCRelocationKind_SECREL:
  2058. coffReloc.mType = IMAGE_REL_AMD64_SECREL;
  2059. break;
  2060. case BeMCRelocationKind_SECTION:
  2061. coffReloc.mType = IMAGE_REL_AMD64_SECTION;
  2062. break;
  2063. }
  2064. mStream->WriteT(coffReloc);
  2065. relocIdx++;
  2066. BF_ASSERT(mStream->GetPos() == sectHdr.mPointerToRawData + (int)sect->mData.GetSize() + relocIdx*10);
  2067. }
  2068. }
  2069. BF_ASSERT(mStream->GetPos() == filePos);
  2070. SizedArray<PE_SymInfo, 16> symInfoVec;
  2071. symInfoVec.reserve(mSymbols.size() + 16);
  2072. for (auto& sym : mSymbols)
  2073. {
  2074. //BP_ZONE("Finish - AddSym");
  2075. if (sym->mSymKind == BeMCSymbolKind_AuxPlaceholder)
  2076. continue;
  2077. PE_SymInfo symInfo;
  2078. memset(&symInfo, 0, sizeof(symInfo));
  2079. if (sym->mName.length() > 7)
  2080. {
  2081. int strTablePos = mStrTable.mPos;
  2082. mStrTable.Write((uint8*)sym->mName.c_str(), (int)sym->mName.length() + 1);
  2083. symInfo.mNameOfs[1] = strTablePos + 4;
  2084. }
  2085. else
  2086. strcpy(symInfo.mName, sym->mName.c_str());
  2087. if (sym->mSymKind == BeMCSymbolKind_SectionDef)
  2088. {
  2089. symInfo.mSectionNum = sym->mSectionNum;
  2090. symInfo.mStorageClass = IMAGE_SYM_CLASS_STATIC;
  2091. symInfo.mNumOfAuxSymbols = 1;
  2092. symInfoVec.push_back(symInfo);
  2093. static_assert(sizeof(PE_SymInfoAux) == sizeof(PE_SymInfo), "PE_SymInfo size mismatch");
  2094. BeCOFFSection& section = mXDataSect;
  2095. PE_SymInfoAux auxSymInfo;
  2096. auxSymInfo.mLength = section.mData.GetSize();
  2097. auxSymInfo.mNumberOfRelocations = (int)section.mRelocs.size();
  2098. auxSymInfo.mNumberOfLinenumbers = 0;
  2099. auxSymInfo.mCheckSum = 0;
  2100. auxSymInfo.mNumber = 0;
  2101. auxSymInfo.mSelection = 2; // Pick any (only applicable for COMDAT but ignored elsewhere)
  2102. auxSymInfo.mUnused = 0;
  2103. auxSymInfo.mUnused2 = 0;
  2104. auxSymInfo.mUnused3 = 0;
  2105. symInfoVec.push_back(*(PE_SymInfo*)&auxSymInfo);
  2106. continue;
  2107. }
  2108. else if (sym->mSymKind == BeMCSymbolKind_SectionRef)
  2109. {
  2110. symInfo.mSectionNum = sym->mSectionNum;
  2111. symInfo.mStorageClass = IMAGE_SYM_CLASS_SECTION;
  2112. }
  2113. else if (sym->mSymKind == BeMCSymbolKind_Function)
  2114. {
  2115. symInfo.mValue = sym->mValue;
  2116. symInfo.mSectionNum = mTextSect.mSectionIdx + 1;
  2117. symInfo.mType = 0x20; //DT_FUNCTION
  2118. if (sym->mIsStatic)
  2119. symInfo.mStorageClass = IMAGE_SYM_CLASS_STATIC;
  2120. else
  2121. symInfo.mStorageClass = IMAGE_SYM_CLASS_EXTERNAL;
  2122. }
  2123. else if (sym->mSymKind == BeMCSymbolKind_COMDAT)
  2124. {
  2125. symInfo.mValue = sym->mValue;
  2126. symInfo.mSectionNum = sym->mSectionNum;
  2127. symInfo.mStorageClass = IMAGE_SYM_CLASS_EXTERNAL;
  2128. }
  2129. else
  2130. {
  2131. if (sym->mIsStatic)
  2132. symInfo.mStorageClass = IMAGE_SYM_CLASS_STATIC;
  2133. else
  2134. symInfo.mStorageClass = IMAGE_SYM_CLASS_EXTERNAL;
  2135. symInfo.mValue = sym->mValue;
  2136. symInfo.mSectionNum = sym->mSectionNum;
  2137. }
  2138. symInfoVec.push_back(symInfo);
  2139. }
  2140. if (!symInfoVec.IsEmpty())
  2141. mStream->Write(&symInfoVec[0], (int)(sizeof(PE_SymInfo)*symInfoVec.size()));
  2142. int32 strTableSize = (int32)mStrTable.GetSize();
  2143. mStream->Write(strTableSize + 4);
  2144. if (strTableSize != 0)
  2145. mStream->Write((uint8*)&mStrTable.mData[0], (int)mStrTable.mData.size());
  2146. }
  2147. BeMCSymbol* BeCOFFObject::GetSymbol(BeValue* value, bool allowCreate)
  2148. {
  2149. /*auto itr = mSymbolMap.find(value);
  2150. if (itr != mSymbolMap.end())
  2151. return itr->second;*/
  2152. BeMCSymbol** symbolPtr = NULL;
  2153. if (mSymbolMap.TryGetValue(value, &symbolPtr))
  2154. return *symbolPtr;
  2155. if (allowCreate)
  2156. {
  2157. if (auto func = BeValueDynCast<BeFunction>(value))
  2158. {
  2159. mFuncWorkList.Add(func);
  2160. BeMCSymbol* sym = mSymbols.Alloc();
  2161. sym->mType = func->GetType();
  2162. sym->mName = func->mName;
  2163. sym->mIsStatic = func->mLinkageType == BfIRLinkageType_Internal;
  2164. if (func->mBlocks.empty())
  2165. {
  2166. sym->mSymKind = BeMCSymbolKind_External;
  2167. }
  2168. else
  2169. {
  2170. sym->mSymKind = BeMCSymbolKind_Function;
  2171. }
  2172. sym->mIdx = (int)mSymbols.size() - 1;
  2173. sym->mBeFunction = func;
  2174. mSymbolMap[func] = sym;
  2175. return sym;
  2176. }
  2177. }
  2178. return NULL;
  2179. }
  2180. BeMCSymbol* BeCOFFObject::GetSymbolRef(const StringImpl& name)
  2181. {
  2182. /*auto itr = mNamedSymbolMap.find(name);
  2183. if (itr != mNamedSymbolMap.end())
  2184. return itr->second;*/
  2185. BeMCSymbol** symbolPtr = NULL;
  2186. if (mNamedSymbolMap.TryGetValue(name, &symbolPtr))
  2187. return *symbolPtr;
  2188. auto sym = mSymbols.Alloc();
  2189. sym->mName = name;
  2190. sym->mSymKind = BeMCSymbolKind_External;
  2191. sym->mIdx = (int)mSymbols.size() - 1;
  2192. mNamedSymbolMap[name] = sym;
  2193. return sym;
  2194. }
  2195. void BeCOFFObject::MarkSectionUsed(BeCOFFSection& sect, bool getSectSymbol)
  2196. {
  2197. if (sect.mSectionIdx == -1)
  2198. {
  2199. sect.mSectionIdx = (int)mUsedSections.size();
  2200. mUsedSections.push_back(&sect);
  2201. }
  2202. if (getSectSymbol)
  2203. {
  2204. //TODO: We previously only did sectionDefs when we needed the SelectionNum value, but
  2205. // omitting this causes the MS linker to throw "multiple '<X>' sections found with different
  2206. // attributes (0000000000) errors. This change could potentially break LIB creation in the
  2207. // linker. Verify it still works.
  2208. if (((sect.mCharacteristics & IMAGE_SCN_LNK_COMDAT) != 0) || (true))
  2209. {
  2210. if (sect.mSymbolIdx == -1)
  2211. {
  2212. BeMCSymbol* sym;
  2213. sym = mSymbols.Alloc();
  2214. sym->mSymKind = BeMCSymbolKind_SectionDef;
  2215. sym->mName = sect.mSectName;
  2216. sym->mIsStatic = false;
  2217. sym->mSectionNum = sect.mSectionIdx + 1;
  2218. sym->mIdx = (int)mSymbols.size() - 1;
  2219. sect.mSymbolIdx = sym->mIdx;
  2220. sym = mSymbols.Alloc();
  2221. sym->mSymKind = BeMCSymbolKind_AuxPlaceholder;
  2222. }
  2223. }
  2224. else
  2225. {
  2226. // It's important for the linker's import library output to include
  2227. // section refs and not section defs, even when they aren't an external
  2228. // reference
  2229. BeMCSymbol* sym;
  2230. sym = mSymbols.Alloc();
  2231. sym->mSymKind = BeMCSymbolKind_SectionRef;
  2232. sym->mName = sect.mSectName;
  2233. sym->mIsStatic = false;
  2234. sym->mSectionNum = sect.mSectionIdx + 1;
  2235. sym->mIdx = (int)mSymbols.size() - 1;
  2236. sect.mSymbolIdx = sym->mIdx;
  2237. }
  2238. }
  2239. }
  2240. BeMCSymbol* BeCOFFObject::GetCOMDAT(const StringImpl& name, void* data, int size, int align)
  2241. {
  2242. /*auto itr = mNamedSymbolMap.find(name);
  2243. if (itr != mNamedSymbolMap.end())
  2244. return itr->second;*/
  2245. BeMCSymbol** symbolPtr = NULL;
  2246. if (mNamedSymbolMap.TryGetValue(name, &symbolPtr))
  2247. return *symbolPtr;
  2248. BeCOFFSection mRData8Sect;
  2249. auto* rdataSect = mDynSects.Alloc();
  2250. int characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_LNK_COMDAT | IMAGE_SCN_MEM_READ;
  2251. InitSect(*rdataSect, ".rdata", characteristics, true, true);
  2252. rdataSect->mAlign = align;
  2253. auto sym = mSymbols.Alloc();
  2254. sym->mName = name;
  2255. sym->mSymKind = BeMCSymbolKind_COMDAT;
  2256. sym->mIdx = (int)mSymbols.size() - 1;
  2257. sym->mSectionNum = rdataSect->mSectionIdx + 1;
  2258. sym->mValue = rdataSect->mData.GetPos();
  2259. mNamedSymbolMap[name] = sym;
  2260. rdataSect->mData.Write(data, size);
  2261. return sym;
  2262. }
  2263. BeCOFFSection* BeCOFFObject::CreateSect(const StringImpl& name, int characteristics, bool makeSectSymbol)
  2264. {
  2265. auto* sect = mDynSects.Alloc();
  2266. sect->mCharacteristics = characteristics;
  2267. InitSect(*sect, name, characteristics, true, makeSectSymbol);
  2268. return sect;
  2269. }