BeCOFFObject.cpp 70 KB

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