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