WinCOFFObjectWriter.cpp 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184
  1. //===- llvm/MC/WinCOFFObjectWriter.cpp ------------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file contains an implementation of a Win32 COFF object file writer.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "llvm/ADT/DenseMap.h"
  13. #include "llvm/ADT/DenseSet.h"
  14. #include "llvm/ADT/STLExtras.h"
  15. #include "llvm/ADT/SmallString.h"
  16. #include "llvm/ADT/SmallVector.h"
  17. #include "llvm/ADT/StringRef.h"
  18. #include "llvm/ADT/Twine.h"
  19. #include "llvm/BinaryFormat/COFF.h"
  20. #include "llvm/MC/MCAsmLayout.h"
  21. #include "llvm/MC/MCAssembler.h"
  22. #include "llvm/MC/MCContext.h"
  23. #include "llvm/MC/MCExpr.h"
  24. #include "llvm/MC/MCFixup.h"
  25. #include "llvm/MC/MCFragment.h"
  26. #include "llvm/MC/MCObjectWriter.h"
  27. #include "llvm/MC/MCSection.h"
  28. #include "llvm/MC/MCSectionCOFF.h"
  29. #include "llvm/MC/MCSymbol.h"
  30. #include "llvm/MC/MCSymbolCOFF.h"
  31. #include "llvm/MC/MCValue.h"
  32. #include "llvm/MC/MCWinCOFFObjectWriter.h"
  33. #include "llvm/MC/StringTableBuilder.h"
  34. #include "llvm/Support/CRC.h"
  35. #include "llvm/Support/Casting.h"
  36. #include "llvm/Support/EndianStream.h"
  37. #include "llvm/Support/ErrorHandling.h"
  38. #include "llvm/Support/LEB128.h"
  39. #include "llvm/Support/MathExtras.h"
  40. #include "llvm/Support/raw_ostream.h"
  41. #include <algorithm>
  42. #include <cassert>
  43. #include <cstddef>
  44. #include <cstdint>
  45. #include <cstring>
  46. #include <ctime>
  47. #include <memory>
  48. #include <string>
  49. #include <vector>
  50. using namespace llvm;
  51. using llvm::support::endian::write32le;
  52. #define DEBUG_TYPE "WinCOFFObjectWriter"
  53. namespace {
  54. constexpr int OffsetLabelIntervalBits = 20;
  55. using name = SmallString<COFF::NameSize>;
  56. enum AuxiliaryType {
  57. ATWeakExternal,
  58. ATFile,
  59. ATSectionDefinition
  60. };
  61. struct AuxSymbol {
  62. AuxiliaryType AuxType;
  63. COFF::Auxiliary Aux;
  64. };
  65. class COFFSection;
  66. class COFFSymbol {
  67. public:
  68. COFF::symbol Data = {};
  69. using AuxiliarySymbols = SmallVector<AuxSymbol, 1>;
  70. name Name;
  71. int Index;
  72. AuxiliarySymbols Aux;
  73. COFFSymbol *Other = nullptr;
  74. COFFSection *Section = nullptr;
  75. int Relocations = 0;
  76. const MCSymbol *MC = nullptr;
  77. COFFSymbol(StringRef Name) : Name(Name) {}
  78. void set_name_offset(uint32_t Offset);
  79. int64_t getIndex() const { return Index; }
  80. void setIndex(int Value) {
  81. Index = Value;
  82. if (MC)
  83. MC->setIndex(static_cast<uint32_t>(Value));
  84. }
  85. };
  86. // This class contains staging data for a COFF relocation entry.
  87. struct COFFRelocation {
  88. COFF::relocation Data;
  89. COFFSymbol *Symb = nullptr;
  90. COFFRelocation() = default;
  91. static size_t size() { return COFF::RelocationSize; }
  92. };
  93. using relocations = std::vector<COFFRelocation>;
  94. class COFFSection {
  95. public:
  96. COFF::section Header = {};
  97. std::string Name;
  98. int Number;
  99. MCSectionCOFF const *MCSection = nullptr;
  100. COFFSymbol *Symbol = nullptr;
  101. relocations Relocations;
  102. COFFSection(StringRef Name) : Name(std::string(Name)) {}
  103. SmallVector<COFFSymbol *, 1> OffsetSymbols;
  104. };
  105. class WinCOFFObjectWriter : public MCObjectWriter {
  106. public:
  107. support::endian::Writer W;
  108. using symbols = std::vector<std::unique_ptr<COFFSymbol>>;
  109. using sections = std::vector<std::unique_ptr<COFFSection>>;
  110. using symbol_map = DenseMap<MCSymbol const *, COFFSymbol *>;
  111. using section_map = DenseMap<MCSection const *, COFFSection *>;
  112. using symbol_list = DenseSet<COFFSymbol *>;
  113. std::unique_ptr<MCWinCOFFObjectTargetWriter> TargetObjectWriter;
  114. // Root level file contents.
  115. COFF::header Header = {};
  116. sections Sections;
  117. symbols Symbols;
  118. StringTableBuilder Strings{StringTableBuilder::WinCOFF};
  119. // Maps used during object file creation.
  120. section_map SectionMap;
  121. symbol_map SymbolMap;
  122. symbol_list WeakDefaults;
  123. bool UseBigObj;
  124. bool UseOffsetLabels = false;
  125. bool EmitAddrsigSection = false;
  126. MCSectionCOFF *AddrsigSection;
  127. std::vector<const MCSymbol *> AddrsigSyms;
  128. MCSectionCOFF *CGProfileSection = nullptr;
  129. WinCOFFObjectWriter(std::unique_ptr<MCWinCOFFObjectTargetWriter> MOTW,
  130. raw_pwrite_stream &OS);
  131. void reset() override {
  132. memset(&Header, 0, sizeof(Header));
  133. Header.Machine = TargetObjectWriter->getMachine();
  134. Sections.clear();
  135. Symbols.clear();
  136. Strings.clear();
  137. SectionMap.clear();
  138. SymbolMap.clear();
  139. MCObjectWriter::reset();
  140. }
  141. COFFSymbol *createSymbol(StringRef Name);
  142. COFFSymbol *GetOrCreateCOFFSymbol(const MCSymbol *Symbol);
  143. COFFSection *createSection(StringRef Name);
  144. void defineSection(MCSectionCOFF const &Sec, const MCAsmLayout &Layout);
  145. COFFSymbol *getLinkedSymbol(const MCSymbol &Symbol);
  146. void DefineSymbol(const MCSymbol &Symbol, MCAssembler &Assembler,
  147. const MCAsmLayout &Layout);
  148. void SetSymbolName(COFFSymbol &S);
  149. void SetSectionName(COFFSection &S);
  150. bool IsPhysicalSection(COFFSection *S);
  151. // Entity writing methods.
  152. void WriteFileHeader(const COFF::header &Header);
  153. void WriteSymbol(const COFFSymbol &S);
  154. void WriteAuxiliarySymbols(const COFFSymbol::AuxiliarySymbols &S);
  155. void writeSectionHeaders();
  156. void WriteRelocation(const COFF::relocation &R);
  157. uint32_t writeSectionContents(MCAssembler &Asm, const MCAsmLayout &Layout,
  158. const MCSection &MCSec);
  159. void writeSection(MCAssembler &Asm, const MCAsmLayout &Layout,
  160. const COFFSection &Sec, const MCSection &MCSec);
  161. // MCObjectWriter interface implementation.
  162. void executePostLayoutBinding(MCAssembler &Asm,
  163. const MCAsmLayout &Layout) override;
  164. bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
  165. const MCSymbol &SymA,
  166. const MCFragment &FB, bool InSet,
  167. bool IsPCRel) const override;
  168. void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
  169. const MCFragment *Fragment, const MCFixup &Fixup,
  170. MCValue Target, uint64_t &FixedValue) override;
  171. void createFileSymbols(MCAssembler &Asm);
  172. void setWeakDefaultNames();
  173. void assignSectionNumbers();
  174. void assignFileOffsets(MCAssembler &Asm, const MCAsmLayout &Layout);
  175. void emitAddrsigSection() override { EmitAddrsigSection = true; }
  176. void addAddrsigSymbol(const MCSymbol *Sym) override {
  177. AddrsigSyms.push_back(Sym);
  178. }
  179. uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
  180. };
  181. } // end anonymous namespace
  182. //------------------------------------------------------------------------------
  183. // Symbol class implementation
  184. // In the case that the name does not fit within 8 bytes, the offset
  185. // into the string table is stored in the last 4 bytes instead, leaving
  186. // the first 4 bytes as 0.
  187. void COFFSymbol::set_name_offset(uint32_t Offset) {
  188. write32le(Data.Name + 0, 0);
  189. write32le(Data.Name + 4, Offset);
  190. }
  191. //------------------------------------------------------------------------------
  192. // WinCOFFObjectWriter class implementation
  193. WinCOFFObjectWriter::WinCOFFObjectWriter(
  194. std::unique_ptr<MCWinCOFFObjectTargetWriter> MOTW, raw_pwrite_stream &OS)
  195. : W(OS, support::little), TargetObjectWriter(std::move(MOTW)) {
  196. Header.Machine = TargetObjectWriter->getMachine();
  197. // Some relocations on ARM64 (the 21 bit ADRP relocations) have a slightly
  198. // limited range for the immediate offset (+/- 1 MB); create extra offset
  199. // label symbols with regular intervals to allow referencing a
  200. // non-temporary symbol that is close enough.
  201. UseOffsetLabels = Header.Machine == COFF::IMAGE_FILE_MACHINE_ARM64;
  202. }
  203. COFFSymbol *WinCOFFObjectWriter::createSymbol(StringRef Name) {
  204. Symbols.push_back(std::make_unique<COFFSymbol>(Name));
  205. return Symbols.back().get();
  206. }
  207. COFFSymbol *WinCOFFObjectWriter::GetOrCreateCOFFSymbol(const MCSymbol *Symbol) {
  208. COFFSymbol *&Ret = SymbolMap[Symbol];
  209. if (!Ret)
  210. Ret = createSymbol(Symbol->getName());
  211. return Ret;
  212. }
  213. COFFSection *WinCOFFObjectWriter::createSection(StringRef Name) {
  214. Sections.emplace_back(std::make_unique<COFFSection>(Name));
  215. return Sections.back().get();
  216. }
  217. static uint32_t getAlignment(const MCSectionCOFF &Sec) {
  218. switch (Sec.getAlignment()) {
  219. case 1:
  220. return COFF::IMAGE_SCN_ALIGN_1BYTES;
  221. case 2:
  222. return COFF::IMAGE_SCN_ALIGN_2BYTES;
  223. case 4:
  224. return COFF::IMAGE_SCN_ALIGN_4BYTES;
  225. case 8:
  226. return COFF::IMAGE_SCN_ALIGN_8BYTES;
  227. case 16:
  228. return COFF::IMAGE_SCN_ALIGN_16BYTES;
  229. case 32:
  230. return COFF::IMAGE_SCN_ALIGN_32BYTES;
  231. case 64:
  232. return COFF::IMAGE_SCN_ALIGN_64BYTES;
  233. case 128:
  234. return COFF::IMAGE_SCN_ALIGN_128BYTES;
  235. case 256:
  236. return COFF::IMAGE_SCN_ALIGN_256BYTES;
  237. case 512:
  238. return COFF::IMAGE_SCN_ALIGN_512BYTES;
  239. case 1024:
  240. return COFF::IMAGE_SCN_ALIGN_1024BYTES;
  241. case 2048:
  242. return COFF::IMAGE_SCN_ALIGN_2048BYTES;
  243. case 4096:
  244. return COFF::IMAGE_SCN_ALIGN_4096BYTES;
  245. case 8192:
  246. return COFF::IMAGE_SCN_ALIGN_8192BYTES;
  247. }
  248. llvm_unreachable("unsupported section alignment");
  249. }
  250. /// This function takes a section data object from the assembler
  251. /// and creates the associated COFF section staging object.
  252. void WinCOFFObjectWriter::defineSection(const MCSectionCOFF &MCSec,
  253. const MCAsmLayout &Layout) {
  254. COFFSection *Section = createSection(MCSec.getName());
  255. COFFSymbol *Symbol = createSymbol(MCSec.getName());
  256. Section->Symbol = Symbol;
  257. Symbol->Section = Section;
  258. Symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_STATIC;
  259. // Create a COMDAT symbol if needed.
  260. if (MCSec.getSelection() != COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
  261. if (const MCSymbol *S = MCSec.getCOMDATSymbol()) {
  262. COFFSymbol *COMDATSymbol = GetOrCreateCOFFSymbol(S);
  263. if (COMDATSymbol->Section)
  264. report_fatal_error("two sections have the same comdat");
  265. COMDATSymbol->Section = Section;
  266. }
  267. }
  268. // In this case the auxiliary symbol is a Section Definition.
  269. Symbol->Aux.resize(1);
  270. Symbol->Aux[0] = {};
  271. Symbol->Aux[0].AuxType = ATSectionDefinition;
  272. Symbol->Aux[0].Aux.SectionDefinition.Selection = MCSec.getSelection();
  273. // Set section alignment.
  274. Section->Header.Characteristics = MCSec.getCharacteristics();
  275. Section->Header.Characteristics |= getAlignment(MCSec);
  276. // Bind internal COFF section to MC section.
  277. Section->MCSection = &MCSec;
  278. SectionMap[&MCSec] = Section;
  279. if (UseOffsetLabels && !MCSec.getFragmentList().empty()) {
  280. const uint32_t Interval = 1 << OffsetLabelIntervalBits;
  281. uint32_t N = 1;
  282. for (uint32_t Off = Interval, E = Layout.getSectionAddressSize(&MCSec);
  283. Off < E; Off += Interval) {
  284. auto Name = ("$L" + MCSec.getName() + "_" + Twine(N++)).str();
  285. COFFSymbol *Label = createSymbol(Name);
  286. Label->Section = Section;
  287. Label->Data.StorageClass = COFF::IMAGE_SYM_CLASS_LABEL;
  288. Label->Data.Value = Off;
  289. Section->OffsetSymbols.push_back(Label);
  290. }
  291. }
  292. }
  293. static uint64_t getSymbolValue(const MCSymbol &Symbol,
  294. const MCAsmLayout &Layout) {
  295. if (Symbol.isCommon() && Symbol.isExternal())
  296. return Symbol.getCommonSize();
  297. uint64_t Res;
  298. if (!Layout.getSymbolOffset(Symbol, Res))
  299. return 0;
  300. return Res;
  301. }
  302. COFFSymbol *WinCOFFObjectWriter::getLinkedSymbol(const MCSymbol &Symbol) {
  303. if (!Symbol.isVariable())
  304. return nullptr;
  305. const MCSymbolRefExpr *SymRef =
  306. dyn_cast<MCSymbolRefExpr>(Symbol.getVariableValue());
  307. if (!SymRef)
  308. return nullptr;
  309. const MCSymbol &Aliasee = SymRef->getSymbol();
  310. if (Aliasee.isUndefined() || Aliasee.isExternal())
  311. return GetOrCreateCOFFSymbol(&Aliasee);
  312. else
  313. return nullptr;
  314. }
  315. /// This function takes a symbol data object from the assembler
  316. /// and creates the associated COFF symbol staging object.
  317. void WinCOFFObjectWriter::DefineSymbol(const MCSymbol &MCSym,
  318. MCAssembler &Assembler,
  319. const MCAsmLayout &Layout) {
  320. COFFSymbol *Sym = GetOrCreateCOFFSymbol(&MCSym);
  321. const MCSymbol *Base = Layout.getBaseSymbol(MCSym);
  322. COFFSection *Sec = nullptr;
  323. if (Base && Base->getFragment()) {
  324. Sec = SectionMap[Base->getFragment()->getParent()];
  325. if (Sym->Section && Sym->Section != Sec)
  326. report_fatal_error("conflicting sections for symbol");
  327. }
  328. COFFSymbol *Local = nullptr;
  329. if (cast<MCSymbolCOFF>(MCSym).isWeakExternal()) {
  330. Sym->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL;
  331. Sym->Section = nullptr;
  332. COFFSymbol *WeakDefault = getLinkedSymbol(MCSym);
  333. if (!WeakDefault) {
  334. std::string WeakName = (".weak." + MCSym.getName() + ".default").str();
  335. WeakDefault = createSymbol(WeakName);
  336. if (!Sec)
  337. WeakDefault->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE;
  338. else
  339. WeakDefault->Section = Sec;
  340. WeakDefaults.insert(WeakDefault);
  341. Local = WeakDefault;
  342. }
  343. Sym->Other = WeakDefault;
  344. // Setup the Weak External auxiliary symbol.
  345. Sym->Aux.resize(1);
  346. memset(&Sym->Aux[0], 0, sizeof(Sym->Aux[0]));
  347. Sym->Aux[0].AuxType = ATWeakExternal;
  348. Sym->Aux[0].Aux.WeakExternal.TagIndex = 0;
  349. Sym->Aux[0].Aux.WeakExternal.Characteristics =
  350. COFF::IMAGE_WEAK_EXTERN_SEARCH_ALIAS;
  351. } else {
  352. if (!Base)
  353. Sym->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE;
  354. else
  355. Sym->Section = Sec;
  356. Local = Sym;
  357. }
  358. if (Local) {
  359. Local->Data.Value = getSymbolValue(MCSym, Layout);
  360. const MCSymbolCOFF &SymbolCOFF = cast<MCSymbolCOFF>(MCSym);
  361. Local->Data.Type = SymbolCOFF.getType();
  362. Local->Data.StorageClass = SymbolCOFF.getClass();
  363. // If no storage class was specified in the streamer, define it here.
  364. if (Local->Data.StorageClass == COFF::IMAGE_SYM_CLASS_NULL) {
  365. bool IsExternal = MCSym.isExternal() ||
  366. (!MCSym.getFragment() && !MCSym.isVariable());
  367. Local->Data.StorageClass = IsExternal ? COFF::IMAGE_SYM_CLASS_EXTERNAL
  368. : COFF::IMAGE_SYM_CLASS_STATIC;
  369. }
  370. }
  371. Sym->MC = &MCSym;
  372. }
  373. void WinCOFFObjectWriter::SetSectionName(COFFSection &S) {
  374. if (S.Name.size() <= COFF::NameSize) {
  375. std::memcpy(S.Header.Name, S.Name.c_str(), S.Name.size());
  376. return;
  377. }
  378. uint64_t StringTableEntry = Strings.getOffset(S.Name);
  379. if (!COFF::encodeSectionName(S.Header.Name, StringTableEntry))
  380. report_fatal_error("COFF string table is greater than 64 GB.");
  381. }
  382. void WinCOFFObjectWriter::SetSymbolName(COFFSymbol &S) {
  383. if (S.Name.size() > COFF::NameSize)
  384. S.set_name_offset(Strings.getOffset(S.Name));
  385. else
  386. std::memcpy(S.Data.Name, S.Name.c_str(), S.Name.size());
  387. }
  388. bool WinCOFFObjectWriter::IsPhysicalSection(COFFSection *S) {
  389. return (S->Header.Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) ==
  390. 0;
  391. }
  392. //------------------------------------------------------------------------------
  393. // entity writing methods
  394. void WinCOFFObjectWriter::WriteFileHeader(const COFF::header &Header) {
  395. if (UseBigObj) {
  396. W.write<uint16_t>(COFF::IMAGE_FILE_MACHINE_UNKNOWN);
  397. W.write<uint16_t>(0xFFFF);
  398. W.write<uint16_t>(COFF::BigObjHeader::MinBigObjectVersion);
  399. W.write<uint16_t>(Header.Machine);
  400. W.write<uint32_t>(Header.TimeDateStamp);
  401. W.OS.write(COFF::BigObjMagic, sizeof(COFF::BigObjMagic));
  402. W.write<uint32_t>(0);
  403. W.write<uint32_t>(0);
  404. W.write<uint32_t>(0);
  405. W.write<uint32_t>(0);
  406. W.write<uint32_t>(Header.NumberOfSections);
  407. W.write<uint32_t>(Header.PointerToSymbolTable);
  408. W.write<uint32_t>(Header.NumberOfSymbols);
  409. } else {
  410. W.write<uint16_t>(Header.Machine);
  411. W.write<uint16_t>(static_cast<int16_t>(Header.NumberOfSections));
  412. W.write<uint32_t>(Header.TimeDateStamp);
  413. W.write<uint32_t>(Header.PointerToSymbolTable);
  414. W.write<uint32_t>(Header.NumberOfSymbols);
  415. W.write<uint16_t>(Header.SizeOfOptionalHeader);
  416. W.write<uint16_t>(Header.Characteristics);
  417. }
  418. }
  419. void WinCOFFObjectWriter::WriteSymbol(const COFFSymbol &S) {
  420. W.OS.write(S.Data.Name, COFF::NameSize);
  421. W.write<uint32_t>(S.Data.Value);
  422. if (UseBigObj)
  423. W.write<uint32_t>(S.Data.SectionNumber);
  424. else
  425. W.write<uint16_t>(static_cast<int16_t>(S.Data.SectionNumber));
  426. W.write<uint16_t>(S.Data.Type);
  427. W.OS << char(S.Data.StorageClass);
  428. W.OS << char(S.Data.NumberOfAuxSymbols);
  429. WriteAuxiliarySymbols(S.Aux);
  430. }
  431. void WinCOFFObjectWriter::WriteAuxiliarySymbols(
  432. const COFFSymbol::AuxiliarySymbols &S) {
  433. for (const AuxSymbol &i : S) {
  434. switch (i.AuxType) {
  435. case ATWeakExternal:
  436. W.write<uint32_t>(i.Aux.WeakExternal.TagIndex);
  437. W.write<uint32_t>(i.Aux.WeakExternal.Characteristics);
  438. W.OS.write_zeros(sizeof(i.Aux.WeakExternal.unused));
  439. if (UseBigObj)
  440. W.OS.write_zeros(COFF::Symbol32Size - COFF::Symbol16Size);
  441. break;
  442. case ATFile:
  443. W.OS.write(reinterpret_cast<const char *>(&i.Aux),
  444. UseBigObj ? COFF::Symbol32Size : COFF::Symbol16Size);
  445. break;
  446. case ATSectionDefinition:
  447. W.write<uint32_t>(i.Aux.SectionDefinition.Length);
  448. W.write<uint16_t>(i.Aux.SectionDefinition.NumberOfRelocations);
  449. W.write<uint16_t>(i.Aux.SectionDefinition.NumberOfLinenumbers);
  450. W.write<uint32_t>(i.Aux.SectionDefinition.CheckSum);
  451. W.write<uint16_t>(static_cast<int16_t>(i.Aux.SectionDefinition.Number));
  452. W.OS << char(i.Aux.SectionDefinition.Selection);
  453. W.OS.write_zeros(sizeof(i.Aux.SectionDefinition.unused));
  454. W.write<uint16_t>(static_cast<int16_t>(i.Aux.SectionDefinition.Number >> 16));
  455. if (UseBigObj)
  456. W.OS.write_zeros(COFF::Symbol32Size - COFF::Symbol16Size);
  457. break;
  458. }
  459. }
  460. }
  461. // Write the section header.
  462. void WinCOFFObjectWriter::writeSectionHeaders() {
  463. // Section numbers must be monotonically increasing in the section
  464. // header, but our Sections array is not sorted by section number,
  465. // so make a copy of Sections and sort it.
  466. std::vector<COFFSection *> Arr;
  467. for (auto &Section : Sections)
  468. Arr.push_back(Section.get());
  469. llvm::sort(Arr, [](const COFFSection *A, const COFFSection *B) {
  470. return A->Number < B->Number;
  471. });
  472. for (auto &Section : Arr) {
  473. if (Section->Number == -1)
  474. continue;
  475. COFF::section &S = Section->Header;
  476. if (Section->Relocations.size() >= 0xffff)
  477. S.Characteristics |= COFF::IMAGE_SCN_LNK_NRELOC_OVFL;
  478. W.OS.write(S.Name, COFF::NameSize);
  479. W.write<uint32_t>(S.VirtualSize);
  480. W.write<uint32_t>(S.VirtualAddress);
  481. W.write<uint32_t>(S.SizeOfRawData);
  482. W.write<uint32_t>(S.PointerToRawData);
  483. W.write<uint32_t>(S.PointerToRelocations);
  484. W.write<uint32_t>(S.PointerToLineNumbers);
  485. W.write<uint16_t>(S.NumberOfRelocations);
  486. W.write<uint16_t>(S.NumberOfLineNumbers);
  487. W.write<uint32_t>(S.Characteristics);
  488. }
  489. }
  490. void WinCOFFObjectWriter::WriteRelocation(const COFF::relocation &R) {
  491. W.write<uint32_t>(R.VirtualAddress);
  492. W.write<uint32_t>(R.SymbolTableIndex);
  493. W.write<uint16_t>(R.Type);
  494. }
  495. // Write MCSec's contents. What this function does is essentially
  496. // "Asm.writeSectionData(&MCSec, Layout)", but it's a bit complicated
  497. // because it needs to compute a CRC.
  498. uint32_t WinCOFFObjectWriter::writeSectionContents(MCAssembler &Asm,
  499. const MCAsmLayout &Layout,
  500. const MCSection &MCSec) {
  501. // Save the contents of the section to a temporary buffer, we need this
  502. // to CRC the data before we dump it into the object file.
  503. SmallVector<char, 128> Buf;
  504. raw_svector_ostream VecOS(Buf);
  505. Asm.writeSectionData(VecOS, &MCSec, Layout);
  506. // Write the section contents to the object file.
  507. W.OS << Buf;
  508. // Calculate our CRC with an initial value of '0', this is not how
  509. // JamCRC is specified but it aligns with the expected output.
  510. JamCRC JC(/*Init=*/0);
  511. JC.update(makeArrayRef(reinterpret_cast<uint8_t*>(Buf.data()), Buf.size()));
  512. return JC.getCRC();
  513. }
  514. void WinCOFFObjectWriter::writeSection(MCAssembler &Asm,
  515. const MCAsmLayout &Layout,
  516. const COFFSection &Sec,
  517. const MCSection &MCSec) {
  518. if (Sec.Number == -1)
  519. return;
  520. // Write the section contents.
  521. if (Sec.Header.PointerToRawData != 0) {
  522. assert(W.OS.tell() == Sec.Header.PointerToRawData &&
  523. "Section::PointerToRawData is insane!");
  524. uint32_t CRC = writeSectionContents(Asm, Layout, MCSec);
  525. // Update the section definition auxiliary symbol to record the CRC.
  526. COFFSection *Sec = SectionMap[&MCSec];
  527. COFFSymbol::AuxiliarySymbols &AuxSyms = Sec->Symbol->Aux;
  528. assert(AuxSyms.size() == 1 && AuxSyms[0].AuxType == ATSectionDefinition);
  529. AuxSymbol &SecDef = AuxSyms[0];
  530. SecDef.Aux.SectionDefinition.CheckSum = CRC;
  531. }
  532. // Write relocations for this section.
  533. if (Sec.Relocations.empty()) {
  534. assert(Sec.Header.PointerToRelocations == 0 &&
  535. "Section::PointerToRelocations is insane!");
  536. return;
  537. }
  538. assert(W.OS.tell() == Sec.Header.PointerToRelocations &&
  539. "Section::PointerToRelocations is insane!");
  540. if (Sec.Relocations.size() >= 0xffff) {
  541. // In case of overflow, write actual relocation count as first
  542. // relocation. Including the synthetic reloc itself (+ 1).
  543. COFF::relocation R;
  544. R.VirtualAddress = Sec.Relocations.size() + 1;
  545. R.SymbolTableIndex = 0;
  546. R.Type = 0;
  547. WriteRelocation(R);
  548. }
  549. for (const auto &Relocation : Sec.Relocations)
  550. WriteRelocation(Relocation.Data);
  551. }
  552. ////////////////////////////////////////////////////////////////////////////////
  553. // MCObjectWriter interface implementations
  554. void WinCOFFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
  555. const MCAsmLayout &Layout) {
  556. if (EmitAddrsigSection) {
  557. AddrsigSection = Asm.getContext().getCOFFSection(
  558. ".llvm_addrsig", COFF::IMAGE_SCN_LNK_REMOVE,
  559. SectionKind::getMetadata());
  560. Asm.registerSection(*AddrsigSection);
  561. }
  562. if (!Asm.CGProfile.empty()) {
  563. CGProfileSection = Asm.getContext().getCOFFSection(
  564. ".llvm.call-graph-profile", COFF::IMAGE_SCN_LNK_REMOVE,
  565. SectionKind::getMetadata());
  566. Asm.registerSection(*CGProfileSection);
  567. }
  568. // "Define" each section & symbol. This creates section & symbol
  569. // entries in the staging area.
  570. for (const auto &Section : Asm)
  571. defineSection(static_cast<const MCSectionCOFF &>(Section), Layout);
  572. for (const MCSymbol &Symbol : Asm.symbols())
  573. if (!Symbol.isTemporary())
  574. DefineSymbol(Symbol, Asm, Layout);
  575. }
  576. bool WinCOFFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
  577. const MCAssembler &Asm, const MCSymbol &SymA, const MCFragment &FB,
  578. bool InSet, bool IsPCRel) const {
  579. // Don't drop relocations between functions, even if they are in the same text
  580. // section. Multiple Visual C++ linker features depend on having the
  581. // relocations present. The /INCREMENTAL flag will cause these relocations to
  582. // point to thunks, and the /GUARD:CF flag assumes that it can use relocations
  583. // to approximate the set of all address taken functions. LLD's implementation
  584. // of /GUARD:CF also relies on the existance of these relocations.
  585. uint16_t Type = cast<MCSymbolCOFF>(SymA).getType();
  586. if ((Type >> COFF::SCT_COMPLEX_TYPE_SHIFT) == COFF::IMAGE_SYM_DTYPE_FUNCTION)
  587. return false;
  588. return MCObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(Asm, SymA, FB,
  589. InSet, IsPCRel);
  590. }
  591. void WinCOFFObjectWriter::recordRelocation(MCAssembler &Asm,
  592. const MCAsmLayout &Layout,
  593. const MCFragment *Fragment,
  594. const MCFixup &Fixup, MCValue Target,
  595. uint64_t &FixedValue) {
  596. assert(Target.getSymA() && "Relocation must reference a symbol!");
  597. const MCSymbol &A = Target.getSymA()->getSymbol();
  598. if (!A.isRegistered()) {
  599. Asm.getContext().reportError(Fixup.getLoc(),
  600. Twine("symbol '") + A.getName() +
  601. "' can not be undefined");
  602. return;
  603. }
  604. if (A.isTemporary() && A.isUndefined()) {
  605. Asm.getContext().reportError(Fixup.getLoc(),
  606. Twine("assembler label '") + A.getName() +
  607. "' can not be undefined");
  608. return;
  609. }
  610. MCSection *MCSec = Fragment->getParent();
  611. // Mark this symbol as requiring an entry in the symbol table.
  612. assert(SectionMap.find(MCSec) != SectionMap.end() &&
  613. "Section must already have been defined in executePostLayoutBinding!");
  614. COFFSection *Sec = SectionMap[MCSec];
  615. const MCSymbolRefExpr *SymB = Target.getSymB();
  616. if (SymB) {
  617. const MCSymbol *B = &SymB->getSymbol();
  618. if (!B->getFragment()) {
  619. Asm.getContext().reportError(
  620. Fixup.getLoc(),
  621. Twine("symbol '") + B->getName() +
  622. "' can not be undefined in a subtraction expression");
  623. return;
  624. }
  625. // Offset of the symbol in the section
  626. int64_t OffsetOfB = Layout.getSymbolOffset(*B);
  627. // Offset of the relocation in the section
  628. int64_t OffsetOfRelocation =
  629. Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
  630. FixedValue = (OffsetOfRelocation - OffsetOfB) + Target.getConstant();
  631. } else {
  632. FixedValue = Target.getConstant();
  633. }
  634. COFFRelocation Reloc;
  635. Reloc.Data.SymbolTableIndex = 0;
  636. Reloc.Data.VirtualAddress = Layout.getFragmentOffset(Fragment);
  637. // Turn relocations for temporary symbols into section relocations.
  638. if (A.isTemporary()) {
  639. MCSection *TargetSection = &A.getSection();
  640. assert(
  641. SectionMap.find(TargetSection) != SectionMap.end() &&
  642. "Section must already have been defined in executePostLayoutBinding!");
  643. COFFSection *Section = SectionMap[TargetSection];
  644. Reloc.Symb = Section->Symbol;
  645. FixedValue += Layout.getSymbolOffset(A);
  646. // Technically, we should do the final adjustments of FixedValue (below)
  647. // before picking an offset symbol, otherwise we might choose one which
  648. // is slightly too far away. The relocations where it really matters
  649. // (arm64 adrp relocations) don't get any offset though.
  650. if (UseOffsetLabels && !Section->OffsetSymbols.empty()) {
  651. uint64_t LabelIndex = FixedValue >> OffsetLabelIntervalBits;
  652. if (LabelIndex > 0) {
  653. if (LabelIndex <= Section->OffsetSymbols.size())
  654. Reloc.Symb = Section->OffsetSymbols[LabelIndex - 1];
  655. else
  656. Reloc.Symb = Section->OffsetSymbols.back();
  657. FixedValue -= Reloc.Symb->Data.Value;
  658. }
  659. }
  660. } else {
  661. assert(
  662. SymbolMap.find(&A) != SymbolMap.end() &&
  663. "Symbol must already have been defined in executePostLayoutBinding!");
  664. Reloc.Symb = SymbolMap[&A];
  665. }
  666. ++Reloc.Symb->Relocations;
  667. Reloc.Data.VirtualAddress += Fixup.getOffset();
  668. Reloc.Data.Type = TargetObjectWriter->getRelocType(
  669. Asm.getContext(), Target, Fixup, SymB, Asm.getBackend());
  670. // The *_REL32 relocations are relative to the end of the relocation,
  671. // not to the start.
  672. if ((Header.Machine == COFF::IMAGE_FILE_MACHINE_AMD64 &&
  673. Reloc.Data.Type == COFF::IMAGE_REL_AMD64_REL32) ||
  674. (Header.Machine == COFF::IMAGE_FILE_MACHINE_I386 &&
  675. Reloc.Data.Type == COFF::IMAGE_REL_I386_REL32) ||
  676. (Header.Machine == COFF::IMAGE_FILE_MACHINE_ARMNT &&
  677. Reloc.Data.Type == COFF::IMAGE_REL_ARM_REL32) ||
  678. (Header.Machine == COFF::IMAGE_FILE_MACHINE_ARM64 &&
  679. Reloc.Data.Type == COFF::IMAGE_REL_ARM64_REL32))
  680. FixedValue += 4;
  681. if (Header.Machine == COFF::IMAGE_FILE_MACHINE_ARMNT) {
  682. switch (Reloc.Data.Type) {
  683. case COFF::IMAGE_REL_ARM_ABSOLUTE:
  684. case COFF::IMAGE_REL_ARM_ADDR32:
  685. case COFF::IMAGE_REL_ARM_ADDR32NB:
  686. case COFF::IMAGE_REL_ARM_TOKEN:
  687. case COFF::IMAGE_REL_ARM_SECTION:
  688. case COFF::IMAGE_REL_ARM_SECREL:
  689. break;
  690. case COFF::IMAGE_REL_ARM_BRANCH11:
  691. case COFF::IMAGE_REL_ARM_BLX11:
  692. // IMAGE_REL_ARM_BRANCH11 and IMAGE_REL_ARM_BLX11 are only used for
  693. // pre-ARMv7, which implicitly rules it out of ARMNT (it would be valid
  694. // for Windows CE).
  695. case COFF::IMAGE_REL_ARM_BRANCH24:
  696. case COFF::IMAGE_REL_ARM_BLX24:
  697. case COFF::IMAGE_REL_ARM_MOV32A:
  698. // IMAGE_REL_ARM_BRANCH24, IMAGE_REL_ARM_BLX24, IMAGE_REL_ARM_MOV32A are
  699. // only used for ARM mode code, which is documented as being unsupported
  700. // by Windows on ARM. Empirical proof indicates that masm is able to
  701. // generate the relocations however the rest of the MSVC toolchain is
  702. // unable to handle it.
  703. llvm_unreachable("unsupported relocation");
  704. break;
  705. case COFF::IMAGE_REL_ARM_MOV32T:
  706. break;
  707. case COFF::IMAGE_REL_ARM_BRANCH20T:
  708. case COFF::IMAGE_REL_ARM_BRANCH24T:
  709. case COFF::IMAGE_REL_ARM_BLX23T:
  710. // IMAGE_REL_BRANCH20T, IMAGE_REL_ARM_BRANCH24T, IMAGE_REL_ARM_BLX23T all
  711. // perform a 4 byte adjustment to the relocation. Relative branches are
  712. // offset by 4 on ARM, however, because there is no RELA relocations, all
  713. // branches are offset by 4.
  714. FixedValue = FixedValue + 4;
  715. break;
  716. }
  717. }
  718. // The fixed value never makes sense for section indices, ignore it.
  719. if (Fixup.getKind() == FK_SecRel_2)
  720. FixedValue = 0;
  721. if (TargetObjectWriter->recordRelocation(Fixup))
  722. Sec->Relocations.push_back(Reloc);
  723. }
  724. static std::time_t getTime() {
  725. std::time_t Now = time(nullptr);
  726. if (Now < 0 || !isUInt<32>(Now))
  727. return UINT32_MAX;
  728. return Now;
  729. }
  730. // Create .file symbols.
  731. void WinCOFFObjectWriter::createFileSymbols(MCAssembler &Asm) {
  732. for (const std::pair<std::string, size_t> &It : Asm.getFileNames()) {
  733. // round up to calculate the number of auxiliary symbols required
  734. const std::string &Name = It.first;
  735. unsigned SymbolSize = UseBigObj ? COFF::Symbol32Size : COFF::Symbol16Size;
  736. unsigned Count = (Name.size() + SymbolSize - 1) / SymbolSize;
  737. COFFSymbol *File = createSymbol(".file");
  738. File->Data.SectionNumber = COFF::IMAGE_SYM_DEBUG;
  739. File->Data.StorageClass = COFF::IMAGE_SYM_CLASS_FILE;
  740. File->Aux.resize(Count);
  741. unsigned Offset = 0;
  742. unsigned Length = Name.size();
  743. for (auto &Aux : File->Aux) {
  744. Aux.AuxType = ATFile;
  745. if (Length > SymbolSize) {
  746. memcpy(&Aux.Aux, Name.c_str() + Offset, SymbolSize);
  747. Length = Length - SymbolSize;
  748. } else {
  749. memcpy(&Aux.Aux, Name.c_str() + Offset, Length);
  750. memset((char *)&Aux.Aux + Length, 0, SymbolSize - Length);
  751. break;
  752. }
  753. Offset += SymbolSize;
  754. }
  755. }
  756. }
  757. void WinCOFFObjectWriter::setWeakDefaultNames() {
  758. if (WeakDefaults.empty())
  759. return;
  760. // If multiple object files use a weak symbol (either with a regular
  761. // defined default, or an absolute zero symbol as default), the defaults
  762. // cause duplicate definitions unless their names are made unique. Look
  763. // for a defined extern symbol, that isn't comdat - that should be unique
  764. // unless there are other duplicate definitions. And if none is found,
  765. // allow picking a comdat symbol, as that's still better than nothing.
  766. COFFSymbol *Unique = nullptr;
  767. for (bool AllowComdat : {false, true}) {
  768. for (auto &Sym : Symbols) {
  769. // Don't include the names of the defaults themselves
  770. if (WeakDefaults.count(Sym.get()))
  771. continue;
  772. // Only consider external symbols
  773. if (Sym->Data.StorageClass != COFF::IMAGE_SYM_CLASS_EXTERNAL)
  774. continue;
  775. // Only consider symbols defined in a section or that are absolute
  776. if (!Sym->Section && Sym->Data.SectionNumber != COFF::IMAGE_SYM_ABSOLUTE)
  777. continue;
  778. if (!AllowComdat && Sym->Section &&
  779. Sym->Section->Header.Characteristics & COFF::IMAGE_SCN_LNK_COMDAT)
  780. continue;
  781. Unique = Sym.get();
  782. break;
  783. }
  784. if (Unique)
  785. break;
  786. }
  787. // If we didn't find any unique symbol to use for the names, just skip this.
  788. if (!Unique)
  789. return;
  790. for (auto *Sym : WeakDefaults) {
  791. Sym->Name.append(".");
  792. Sym->Name.append(Unique->Name);
  793. }
  794. }
  795. static bool isAssociative(const COFFSection &Section) {
  796. return Section.Symbol->Aux[0].Aux.SectionDefinition.Selection ==
  797. COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE;
  798. }
  799. void WinCOFFObjectWriter::assignSectionNumbers() {
  800. size_t I = 1;
  801. auto Assign = [&](COFFSection &Section) {
  802. Section.Number = I;
  803. Section.Symbol->Data.SectionNumber = I;
  804. Section.Symbol->Aux[0].Aux.SectionDefinition.Number = I;
  805. ++I;
  806. };
  807. // Although it is not explicitly requested by the Microsoft COFF spec,
  808. // we should avoid emitting forward associative section references,
  809. // because MSVC link.exe as of 2017 cannot handle that.
  810. for (const std::unique_ptr<COFFSection> &Section : Sections)
  811. if (!isAssociative(*Section))
  812. Assign(*Section);
  813. for (const std::unique_ptr<COFFSection> &Section : Sections)
  814. if (isAssociative(*Section))
  815. Assign(*Section);
  816. }
  817. // Assign file offsets to COFF object file structures.
  818. void WinCOFFObjectWriter::assignFileOffsets(MCAssembler &Asm,
  819. const MCAsmLayout &Layout) {
  820. unsigned Offset = W.OS.tell();
  821. Offset += UseBigObj ? COFF::Header32Size : COFF::Header16Size;
  822. Offset += COFF::SectionSize * Header.NumberOfSections;
  823. for (const auto &Section : Asm) {
  824. COFFSection *Sec = SectionMap[&Section];
  825. if (Sec->Number == -1)
  826. continue;
  827. Sec->Header.SizeOfRawData = Layout.getSectionAddressSize(&Section);
  828. if (IsPhysicalSection(Sec)) {
  829. Sec->Header.PointerToRawData = Offset;
  830. Offset += Sec->Header.SizeOfRawData;
  831. }
  832. if (!Sec->Relocations.empty()) {
  833. bool RelocationsOverflow = Sec->Relocations.size() >= 0xffff;
  834. if (RelocationsOverflow) {
  835. // Signal overflow by setting NumberOfRelocations to max value. Actual
  836. // size is found in reloc #0. Microsoft tools understand this.
  837. Sec->Header.NumberOfRelocations = 0xffff;
  838. } else {
  839. Sec->Header.NumberOfRelocations = Sec->Relocations.size();
  840. }
  841. Sec->Header.PointerToRelocations = Offset;
  842. if (RelocationsOverflow) {
  843. // Reloc #0 will contain actual count, so make room for it.
  844. Offset += COFF::RelocationSize;
  845. }
  846. Offset += COFF::RelocationSize * Sec->Relocations.size();
  847. for (auto &Relocation : Sec->Relocations) {
  848. assert(Relocation.Symb->getIndex() != -1);
  849. Relocation.Data.SymbolTableIndex = Relocation.Symb->getIndex();
  850. }
  851. }
  852. assert(Sec->Symbol->Aux.size() == 1 &&
  853. "Section's symbol must have one aux!");
  854. AuxSymbol &Aux = Sec->Symbol->Aux[0];
  855. assert(Aux.AuxType == ATSectionDefinition &&
  856. "Section's symbol's aux symbol must be a Section Definition!");
  857. Aux.Aux.SectionDefinition.Length = Sec->Header.SizeOfRawData;
  858. Aux.Aux.SectionDefinition.NumberOfRelocations =
  859. Sec->Header.NumberOfRelocations;
  860. Aux.Aux.SectionDefinition.NumberOfLinenumbers =
  861. Sec->Header.NumberOfLineNumbers;
  862. }
  863. Header.PointerToSymbolTable = Offset;
  864. }
  865. uint64_t WinCOFFObjectWriter::writeObject(MCAssembler &Asm,
  866. const MCAsmLayout &Layout) {
  867. uint64_t StartOffset = W.OS.tell();
  868. if (Sections.size() > INT32_MAX)
  869. report_fatal_error(
  870. "PE COFF object files can't have more than 2147483647 sections");
  871. UseBigObj = Sections.size() > COFF::MaxNumberOfSections16;
  872. Header.NumberOfSections = Sections.size();
  873. Header.NumberOfSymbols = 0;
  874. setWeakDefaultNames();
  875. assignSectionNumbers();
  876. createFileSymbols(Asm);
  877. for (auto &Symbol : Symbols) {
  878. // Update section number & offset for symbols that have them.
  879. if (Symbol->Section)
  880. Symbol->Data.SectionNumber = Symbol->Section->Number;
  881. Symbol->setIndex(Header.NumberOfSymbols++);
  882. // Update auxiliary symbol info.
  883. Symbol->Data.NumberOfAuxSymbols = Symbol->Aux.size();
  884. Header.NumberOfSymbols += Symbol->Data.NumberOfAuxSymbols;
  885. }
  886. // Build string table.
  887. for (const auto &S : Sections)
  888. if (S->Name.size() > COFF::NameSize)
  889. Strings.add(S->Name);
  890. for (const auto &S : Symbols)
  891. if (S->Name.size() > COFF::NameSize)
  892. Strings.add(S->Name);
  893. Strings.finalize();
  894. // Set names.
  895. for (const auto &S : Sections)
  896. SetSectionName(*S);
  897. for (auto &S : Symbols)
  898. SetSymbolName(*S);
  899. // Fixup weak external references.
  900. for (auto &Symbol : Symbols) {
  901. if (Symbol->Other) {
  902. assert(Symbol->getIndex() != -1);
  903. assert(Symbol->Aux.size() == 1 && "Symbol must contain one aux symbol!");
  904. assert(Symbol->Aux[0].AuxType == ATWeakExternal &&
  905. "Symbol's aux symbol must be a Weak External!");
  906. Symbol->Aux[0].Aux.WeakExternal.TagIndex = Symbol->Other->getIndex();
  907. }
  908. }
  909. // Fixup associative COMDAT sections.
  910. for (auto &Section : Sections) {
  911. if (Section->Symbol->Aux[0].Aux.SectionDefinition.Selection !=
  912. COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)
  913. continue;
  914. const MCSectionCOFF &MCSec = *Section->MCSection;
  915. const MCSymbol *AssocMCSym = MCSec.getCOMDATSymbol();
  916. assert(AssocMCSym);
  917. // It's an error to try to associate with an undefined symbol or a symbol
  918. // without a section.
  919. if (!AssocMCSym->isInSection()) {
  920. Asm.getContext().reportError(
  921. SMLoc(), Twine("cannot make section ") + MCSec.getName() +
  922. Twine(" associative with sectionless symbol ") +
  923. AssocMCSym->getName());
  924. continue;
  925. }
  926. const auto *AssocMCSec = cast<MCSectionCOFF>(&AssocMCSym->getSection());
  927. assert(SectionMap.count(AssocMCSec));
  928. COFFSection *AssocSec = SectionMap[AssocMCSec];
  929. // Skip this section if the associated section is unused.
  930. if (AssocSec->Number == -1)
  931. continue;
  932. Section->Symbol->Aux[0].Aux.SectionDefinition.Number = AssocSec->Number;
  933. }
  934. // Create the contents of the .llvm_addrsig section.
  935. if (EmitAddrsigSection) {
  936. auto Frag = new MCDataFragment(AddrsigSection);
  937. Frag->setLayoutOrder(0);
  938. raw_svector_ostream OS(Frag->getContents());
  939. for (const MCSymbol *S : AddrsigSyms) {
  940. if (!S->isTemporary()) {
  941. encodeULEB128(S->getIndex(), OS);
  942. continue;
  943. }
  944. MCSection *TargetSection = &S->getSection();
  945. assert(SectionMap.find(TargetSection) != SectionMap.end() &&
  946. "Section must already have been defined in "
  947. "executePostLayoutBinding!");
  948. encodeULEB128(SectionMap[TargetSection]->Symbol->getIndex(), OS);
  949. }
  950. }
  951. // Create the contents of the .llvm.call-graph-profile section.
  952. if (CGProfileSection) {
  953. auto *Frag = new MCDataFragment(CGProfileSection);
  954. Frag->setLayoutOrder(0);
  955. raw_svector_ostream OS(Frag->getContents());
  956. for (const MCAssembler::CGProfileEntry &CGPE : Asm.CGProfile) {
  957. uint32_t FromIndex = CGPE.From->getSymbol().getIndex();
  958. uint32_t ToIndex = CGPE.To->getSymbol().getIndex();
  959. support::endian::write(OS, FromIndex, W.Endian);
  960. support::endian::write(OS, ToIndex, W.Endian);
  961. support::endian::write(OS, CGPE.Count, W.Endian);
  962. }
  963. }
  964. assignFileOffsets(Asm, Layout);
  965. // MS LINK expects to be able to use this timestamp to implement their
  966. // /INCREMENTAL feature.
  967. if (Asm.isIncrementalLinkerCompatible()) {
  968. Header.TimeDateStamp = getTime();
  969. } else {
  970. // Have deterministic output if /INCREMENTAL isn't needed. Also matches GNU.
  971. Header.TimeDateStamp = 0;
  972. }
  973. // Write it all to disk...
  974. WriteFileHeader(Header);
  975. writeSectionHeaders();
  976. // Write section contents.
  977. sections::iterator I = Sections.begin();
  978. sections::iterator IE = Sections.end();
  979. MCAssembler::iterator J = Asm.begin();
  980. MCAssembler::iterator JE = Asm.end();
  981. for (; I != IE && J != JE; ++I, ++J)
  982. writeSection(Asm, Layout, **I, *J);
  983. assert(W.OS.tell() == Header.PointerToSymbolTable &&
  984. "Header::PointerToSymbolTable is insane!");
  985. // Write a symbol table.
  986. for (auto &Symbol : Symbols)
  987. if (Symbol->getIndex() != -1)
  988. WriteSymbol(*Symbol);
  989. // Write a string table, which completes the entire COFF file.
  990. Strings.write(W.OS);
  991. return W.OS.tell() - StartOffset;
  992. }
  993. MCWinCOFFObjectTargetWriter::MCWinCOFFObjectTargetWriter(unsigned Machine_)
  994. : Machine(Machine_) {}
  995. // Pin the vtable to this file.
  996. void MCWinCOFFObjectTargetWriter::anchor() {}
  997. //------------------------------------------------------------------------------
  998. // WinCOFFObjectWriter factory function
  999. std::unique_ptr<MCObjectWriter> llvm::createWinCOFFObjectWriter(
  1000. std::unique_ptr<MCWinCOFFObjectTargetWriter> MOTW, raw_pwrite_stream &OS) {
  1001. return std::make_unique<WinCOFFObjectWriter>(std::move(MOTW), OS);
  1002. }