1 //===- llvm/MC/WinCOFFObjectWriter.cpp ------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains an implementation of a Win32 COFF object file writer.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/ADT/DenseMap.h"
15 #include "llvm/ADT/SmallString.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/ADT/Twine.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/Casting.h"
35 #include "llvm/Support/COFF.h"
36 #include "llvm/Support/Endian.h"
37 #include "llvm/Support/ErrorHandling.h"
38 #include "llvm/Support/JamCRC.h"
39 #include "llvm/Support/MathExtras.h"
40 #include "llvm/Support/raw_ostream.h"
41 #include <cassert>
42 #include <cstddef>
43 #include <cstdint>
44 #include <cstring>
45 #include <ctime>
46 #include <memory>
47 #include <string>
48 #include <vector>
49 
50 using namespace llvm;
51 using llvm::support::endian::write32le;
52 
53 #define DEBUG_TYPE "WinCOFFObjectWriter"
54 
55 namespace {
56 
57 typedef SmallString<COFF::NameSize> name;
58 
59 enum AuxiliaryType {
60   ATFunctionDefinition,
61   ATbfAndefSymbol,
62   ATWeakExternal,
63   ATFile,
64   ATSectionDefinition
65 };
66 
67 struct AuxSymbol {
68   AuxiliaryType AuxType;
69   COFF::Auxiliary Aux;
70 };
71 
72 class COFFSection;
73 
74 class COFFSymbol {
75 public:
76   COFF::symbol Data = {};
77 
78   typedef SmallVector<AuxSymbol, 1> AuxiliarySymbols;
79 
80   name Name;
81   int Index;
82   AuxiliarySymbols Aux;
83   COFFSymbol *Other = nullptr;
84   COFFSection *Section = nullptr;
85   int Relocations = 0;
86   const MCSymbol *MC = nullptr;
87 
88   COFFSymbol(StringRef Name) : Name(Name) {}
89 
90   void set_name_offset(uint32_t Offset);
91 
92   int64_t getIndex() const { return Index; }
93   void setIndex(int Value) {
94     Index = Value;
95     if (MC)
96       MC->setIndex(static_cast<uint32_t>(Value));
97   }
98 };
99 
100 // This class contains staging data for a COFF relocation entry.
101 struct COFFRelocation {
102   COFF::relocation Data;
103   COFFSymbol *Symb = nullptr;
104 
105   COFFRelocation() = default;
106 
107   static size_t size() { return COFF::RelocationSize; }
108 };
109 
110 typedef std::vector<COFFRelocation> relocations;
111 
112 class COFFSection {
113 public:
114   COFF::section Header = {};
115 
116   std::string Name;
117   int Number;
118   MCSectionCOFF const *MCSection = nullptr;
119   COFFSymbol *Symbol = nullptr;
120   relocations Relocations;
121 
122   COFFSection(StringRef Name) : Name(Name) {}
123 };
124 
125 class WinCOFFObjectWriter : public MCObjectWriter {
126 public:
127   typedef std::vector<std::unique_ptr<COFFSymbol>> symbols;
128   typedef std::vector<std::unique_ptr<COFFSection>> sections;
129 
130   typedef DenseMap<MCSymbol const *, COFFSymbol *> symbol_map;
131   typedef DenseMap<MCSection const *, COFFSection *> section_map;
132 
133   std::unique_ptr<MCWinCOFFObjectTargetWriter> TargetObjectWriter;
134 
135   // Root level file contents.
136   COFF::header Header = {};
137   sections Sections;
138   symbols Symbols;
139   StringTableBuilder Strings{StringTableBuilder::WinCOFF};
140 
141   // Maps used during object file creation.
142   section_map SectionMap;
143   symbol_map SymbolMap;
144 
145   bool UseBigObj;
146 
147   WinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW, raw_pwrite_stream &OS);
148 
149   void reset() override {
150     memset(&Header, 0, sizeof(Header));
151     Header.Machine = TargetObjectWriter->getMachine();
152     Sections.clear();
153     Symbols.clear();
154     Strings.clear();
155     SectionMap.clear();
156     SymbolMap.clear();
157     MCObjectWriter::reset();
158   }
159 
160   COFFSymbol *createSymbol(StringRef Name);
161   COFFSymbol *GetOrCreateCOFFSymbol(const MCSymbol *Symbol);
162   COFFSection *createSection(StringRef Name);
163 
164   void defineSection(MCSectionCOFF const &Sec);
165 
166   COFFSymbol *getLinkedSymbol(const MCSymbol &Symbol);
167   void DefineSymbol(const MCSymbol &Symbol, MCAssembler &Assembler,
168                     const MCAsmLayout &Layout);
169 
170   void SetSymbolName(COFFSymbol &S);
171   void SetSectionName(COFFSection &S);
172 
173   bool IsPhysicalSection(COFFSection *S);
174 
175   // Entity writing methods.
176 
177   void WriteFileHeader(const COFF::header &Header);
178   void WriteSymbol(const COFFSymbol &S);
179   void WriteAuxiliarySymbols(const COFFSymbol::AuxiliarySymbols &S);
180   void writeSectionHeaders();
181   void WriteRelocation(const COFF::relocation &R);
182   uint32_t writeSectionContents(MCAssembler &Asm, const MCAsmLayout &Layout,
183                                 const MCSection &MCSec);
184   void writeSection(MCAssembler &Asm, const MCAsmLayout &Layout,
185                     const COFFSection &Sec, const MCSection &MCSec);
186 
187   // MCObjectWriter interface implementation.
188 
189   void executePostLayoutBinding(MCAssembler &Asm,
190                                 const MCAsmLayout &Layout) override;
191 
192   bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
193                                               const MCSymbol &SymA,
194                                               const MCFragment &FB, bool InSet,
195                                               bool IsPCRel) const override;
196 
197   bool isWeak(const MCSymbol &Sym) const override;
198 
199   void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
200                         const MCFragment *Fragment, const MCFixup &Fixup,
201                         MCValue Target, bool &IsPCRel,
202                         uint64_t &FixedValue) override;
203 
204   void createFileSymbols(MCAssembler &Asm);
205   void assignSectionNumbers();
206   void assignFileOffsets(MCAssembler &Asm, const MCAsmLayout &Layout);
207 
208   void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
209 };
210 
211 } // end anonymous namespace
212 
213 //------------------------------------------------------------------------------
214 // Symbol class implementation
215 
216 // In the case that the name does not fit within 8 bytes, the offset
217 // into the string table is stored in the last 4 bytes instead, leaving
218 // the first 4 bytes as 0.
219 void COFFSymbol::set_name_offset(uint32_t Offset) {
220   write32le(Data.Name + 0, 0);
221   write32le(Data.Name + 4, Offset);
222 }
223 
224 //------------------------------------------------------------------------------
225 // WinCOFFObjectWriter class implementation
226 
227 WinCOFFObjectWriter::WinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW,
228                                          raw_pwrite_stream &OS)
229     : MCObjectWriter(OS, true), TargetObjectWriter(MOTW) {
230   Header.Machine = TargetObjectWriter->getMachine();
231 }
232 
233 COFFSymbol *WinCOFFObjectWriter::createSymbol(StringRef Name) {
234   Symbols.push_back(make_unique<COFFSymbol>(Name));
235   return Symbols.back().get();
236 }
237 
238 COFFSymbol *WinCOFFObjectWriter::GetOrCreateCOFFSymbol(const MCSymbol *Symbol) {
239   COFFSymbol *&Ret = SymbolMap[Symbol];
240   if (!Ret)
241     Ret = createSymbol(Symbol->getName());
242   return Ret;
243 }
244 
245 COFFSection *WinCOFFObjectWriter::createSection(StringRef Name) {
246   Sections.emplace_back(make_unique<COFFSection>(Name));
247   return Sections.back().get();
248 }
249 
250 static uint32_t getAlignment(const MCSectionCOFF &Sec) {
251   switch (Sec.getAlignment()) {
252   case 1:
253     return COFF::IMAGE_SCN_ALIGN_1BYTES;
254   case 2:
255     return COFF::IMAGE_SCN_ALIGN_2BYTES;
256   case 4:
257     return COFF::IMAGE_SCN_ALIGN_4BYTES;
258   case 8:
259     return COFF::IMAGE_SCN_ALIGN_8BYTES;
260   case 16:
261     return COFF::IMAGE_SCN_ALIGN_16BYTES;
262   case 32:
263     return COFF::IMAGE_SCN_ALIGN_32BYTES;
264   case 64:
265     return COFF::IMAGE_SCN_ALIGN_64BYTES;
266   case 128:
267     return COFF::IMAGE_SCN_ALIGN_128BYTES;
268   case 256:
269     return COFF::IMAGE_SCN_ALIGN_256BYTES;
270   case 512:
271     return COFF::IMAGE_SCN_ALIGN_512BYTES;
272   case 1024:
273     return COFF::IMAGE_SCN_ALIGN_1024BYTES;
274   case 2048:
275     return COFF::IMAGE_SCN_ALIGN_2048BYTES;
276   case 4096:
277     return COFF::IMAGE_SCN_ALIGN_4096BYTES;
278   case 8192:
279     return COFF::IMAGE_SCN_ALIGN_8192BYTES;
280   }
281   llvm_unreachable("unsupported section alignment");
282 }
283 
284 /// This function takes a section data object from the assembler
285 /// and creates the associated COFF section staging object.
286 void WinCOFFObjectWriter::defineSection(const MCSectionCOFF &MCSec) {
287   COFFSection *Section = createSection(MCSec.getSectionName());
288   COFFSymbol *Symbol = createSymbol(MCSec.getSectionName());
289   Section->Symbol = Symbol;
290   Symbol->Section = Section;
291   Symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_STATIC;
292 
293   // Create a COMDAT symbol if needed.
294   if (MCSec.getSelection() != COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
295     if (const MCSymbol *S = MCSec.getCOMDATSymbol()) {
296       COFFSymbol *COMDATSymbol = GetOrCreateCOFFSymbol(S);
297       if (COMDATSymbol->Section)
298         report_fatal_error("two sections have the same comdat");
299       COMDATSymbol->Section = Section;
300     }
301   }
302 
303   // In this case the auxiliary symbol is a Section Definition.
304   Symbol->Aux.resize(1);
305   Symbol->Aux[0] = {};
306   Symbol->Aux[0].AuxType = ATSectionDefinition;
307   Symbol->Aux[0].Aux.SectionDefinition.Selection = MCSec.getSelection();
308 
309   // Set section alignment.
310   Section->Header.Characteristics = MCSec.getCharacteristics();
311   Section->Header.Characteristics |= getAlignment(MCSec);
312 
313   // Bind internal COFF section to MC section.
314   Section->MCSection = &MCSec;
315   SectionMap[&MCSec] = Section;
316 }
317 
318 static uint64_t getSymbolValue(const MCSymbol &Symbol,
319                                const MCAsmLayout &Layout) {
320   if (Symbol.isCommon() && Symbol.isExternal())
321     return Symbol.getCommonSize();
322 
323   uint64_t Res;
324   if (!Layout.getSymbolOffset(Symbol, Res))
325     return 0;
326 
327   return Res;
328 }
329 
330 COFFSymbol *WinCOFFObjectWriter::getLinkedSymbol(const MCSymbol &Symbol) {
331   if (!Symbol.isVariable())
332     return nullptr;
333 
334   const MCSymbolRefExpr *SymRef =
335       dyn_cast<MCSymbolRefExpr>(Symbol.getVariableValue());
336   if (!SymRef)
337     return nullptr;
338 
339   const MCSymbol &Aliasee = SymRef->getSymbol();
340   if (!Aliasee.isUndefined())
341     return nullptr;
342   return GetOrCreateCOFFSymbol(&Aliasee);
343 }
344 
345 /// This function takes a symbol data object from the assembler
346 /// and creates the associated COFF symbol staging object.
347 void WinCOFFObjectWriter::DefineSymbol(const MCSymbol &MCSym,
348                                        MCAssembler &Assembler,
349                                        const MCAsmLayout &Layout) {
350   COFFSymbol *Sym = GetOrCreateCOFFSymbol(&MCSym);
351   const MCSymbol *Base = Layout.getBaseSymbol(MCSym);
352   COFFSection *Sec = nullptr;
353   if (Base && Base->getFragment()) {
354     Sec = SectionMap[Base->getFragment()->getParent()];
355     if (Sym->Section && Sym->Section != Sec)
356       report_fatal_error("conflicting sections for symbol");
357   }
358 
359   COFFSymbol *Local = nullptr;
360   if (cast<MCSymbolCOFF>(MCSym).isWeakExternal()) {
361     Sym->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL;
362 
363     COFFSymbol *WeakDefault = getLinkedSymbol(MCSym);
364     if (!WeakDefault) {
365       std::string WeakName = (".weak." + MCSym.getName() + ".default").str();
366       WeakDefault = createSymbol(WeakName);
367       if (!Sec)
368         WeakDefault->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE;
369       else
370         WeakDefault->Section = Sec;
371       Local = WeakDefault;
372     }
373 
374     Sym->Other = WeakDefault;
375 
376     // Setup the Weak External auxiliary symbol.
377     Sym->Aux.resize(1);
378     memset(&Sym->Aux[0], 0, sizeof(Sym->Aux[0]));
379     Sym->Aux[0].AuxType = ATWeakExternal;
380     Sym->Aux[0].Aux.WeakExternal.TagIndex = 0;
381     Sym->Aux[0].Aux.WeakExternal.Characteristics =
382         COFF::IMAGE_WEAK_EXTERN_SEARCH_LIBRARY;
383   } else {
384     if (!Base)
385       Sym->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE;
386     else
387       Sym->Section = Sec;
388     Local = Sym;
389   }
390 
391   if (Local) {
392     Local->Data.Value = getSymbolValue(MCSym, Layout);
393 
394     const MCSymbolCOFF &SymbolCOFF = cast<MCSymbolCOFF>(MCSym);
395     Local->Data.Type = SymbolCOFF.getType();
396     Local->Data.StorageClass = SymbolCOFF.getClass();
397 
398     // If no storage class was specified in the streamer, define it here.
399     if (Local->Data.StorageClass == COFF::IMAGE_SYM_CLASS_NULL) {
400       bool IsExternal = MCSym.isExternal() ||
401                         (!MCSym.getFragment() && !MCSym.isVariable());
402 
403       Local->Data.StorageClass = IsExternal ? COFF::IMAGE_SYM_CLASS_EXTERNAL
404                                             : COFF::IMAGE_SYM_CLASS_STATIC;
405     }
406   }
407 
408   Sym->MC = &MCSym;
409 }
410 
411 // Maximum offsets for different string table entry encodings.
412 enum : unsigned { Max7DecimalOffset = 9999999U };
413 enum : uint64_t { MaxBase64Offset = 0xFFFFFFFFFULL }; // 64^6, including 0
414 
415 // Encode a string table entry offset in base 64, padded to 6 chars, and
416 // prefixed with a double slash: '//AAAAAA', '//AAAAAB', ...
417 // Buffer must be at least 8 bytes large. No terminating null appended.
418 static void encodeBase64StringEntry(char *Buffer, uint64_t Value) {
419   assert(Value > Max7DecimalOffset && Value <= MaxBase64Offset &&
420          "Illegal section name encoding for value");
421 
422   static const char Alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
423                                  "abcdefghijklmnopqrstuvwxyz"
424                                  "0123456789+/";
425 
426   Buffer[0] = '/';
427   Buffer[1] = '/';
428 
429   char *Ptr = Buffer + 7;
430   for (unsigned i = 0; i < 6; ++i) {
431     unsigned Rem = Value % 64;
432     Value /= 64;
433     *(Ptr--) = Alphabet[Rem];
434   }
435 }
436 
437 void WinCOFFObjectWriter::SetSectionName(COFFSection &S) {
438   if (S.Name.size() <= COFF::NameSize) {
439     std::memcpy(S.Header.Name, S.Name.c_str(), S.Name.size());
440     return;
441   }
442 
443   uint64_t StringTableEntry = Strings.getOffset(S.Name);
444   if (StringTableEntry <= Max7DecimalOffset) {
445     SmallVector<char, COFF::NameSize> Buffer;
446     Twine('/').concat(Twine(StringTableEntry)).toVector(Buffer);
447     assert(Buffer.size() <= COFF::NameSize && Buffer.size() >= 2);
448     std::memcpy(S.Header.Name, Buffer.data(), Buffer.size());
449     return;
450   }
451   if (StringTableEntry <= MaxBase64Offset) {
452     // Starting with 10,000,000, offsets are encoded as base64.
453     encodeBase64StringEntry(S.Header.Name, StringTableEntry);
454     return;
455   }
456   report_fatal_error("COFF string table is greater than 64 GB.");
457 }
458 
459 void WinCOFFObjectWriter::SetSymbolName(COFFSymbol &S) {
460   if (S.Name.size() > COFF::NameSize)
461     S.set_name_offset(Strings.getOffset(S.Name));
462   else
463     std::memcpy(S.Data.Name, S.Name.c_str(), S.Name.size());
464 }
465 
466 bool WinCOFFObjectWriter::IsPhysicalSection(COFFSection *S) {
467   return (S->Header.Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) ==
468          0;
469 }
470 
471 //------------------------------------------------------------------------------
472 // entity writing methods
473 
474 void WinCOFFObjectWriter::WriteFileHeader(const COFF::header &Header) {
475   if (UseBigObj) {
476     writeLE16(COFF::IMAGE_FILE_MACHINE_UNKNOWN);
477     writeLE16(0xFFFF);
478     writeLE16(COFF::BigObjHeader::MinBigObjectVersion);
479     writeLE16(Header.Machine);
480     writeLE32(Header.TimeDateStamp);
481     writeBytes(StringRef(COFF::BigObjMagic, sizeof(COFF::BigObjMagic)));
482     writeLE32(0);
483     writeLE32(0);
484     writeLE32(0);
485     writeLE32(0);
486     writeLE32(Header.NumberOfSections);
487     writeLE32(Header.PointerToSymbolTable);
488     writeLE32(Header.NumberOfSymbols);
489   } else {
490     writeLE16(Header.Machine);
491     writeLE16(static_cast<int16_t>(Header.NumberOfSections));
492     writeLE32(Header.TimeDateStamp);
493     writeLE32(Header.PointerToSymbolTable);
494     writeLE32(Header.NumberOfSymbols);
495     writeLE16(Header.SizeOfOptionalHeader);
496     writeLE16(Header.Characteristics);
497   }
498 }
499 
500 void WinCOFFObjectWriter::WriteSymbol(const COFFSymbol &S) {
501   writeBytes(StringRef(S.Data.Name, COFF::NameSize));
502   writeLE32(S.Data.Value);
503   if (UseBigObj)
504     writeLE32(S.Data.SectionNumber);
505   else
506     writeLE16(static_cast<int16_t>(S.Data.SectionNumber));
507   writeLE16(S.Data.Type);
508   write8(S.Data.StorageClass);
509   write8(S.Data.NumberOfAuxSymbols);
510   WriteAuxiliarySymbols(S.Aux);
511 }
512 
513 void WinCOFFObjectWriter::WriteAuxiliarySymbols(
514     const COFFSymbol::AuxiliarySymbols &S) {
515   for (const AuxSymbol &i : S) {
516     switch (i.AuxType) {
517     case ATFunctionDefinition:
518       writeLE32(i.Aux.FunctionDefinition.TagIndex);
519       writeLE32(i.Aux.FunctionDefinition.TotalSize);
520       writeLE32(i.Aux.FunctionDefinition.PointerToLinenumber);
521       writeLE32(i.Aux.FunctionDefinition.PointerToNextFunction);
522       WriteZeros(sizeof(i.Aux.FunctionDefinition.unused));
523       if (UseBigObj)
524         WriteZeros(COFF::Symbol32Size - COFF::Symbol16Size);
525       break;
526     case ATbfAndefSymbol:
527       WriteZeros(sizeof(i.Aux.bfAndefSymbol.unused1));
528       writeLE16(i.Aux.bfAndefSymbol.Linenumber);
529       WriteZeros(sizeof(i.Aux.bfAndefSymbol.unused2));
530       writeLE32(i.Aux.bfAndefSymbol.PointerToNextFunction);
531       WriteZeros(sizeof(i.Aux.bfAndefSymbol.unused3));
532       if (UseBigObj)
533         WriteZeros(COFF::Symbol32Size - COFF::Symbol16Size);
534       break;
535     case ATWeakExternal:
536       writeLE32(i.Aux.WeakExternal.TagIndex);
537       writeLE32(i.Aux.WeakExternal.Characteristics);
538       WriteZeros(sizeof(i.Aux.WeakExternal.unused));
539       if (UseBigObj)
540         WriteZeros(COFF::Symbol32Size - COFF::Symbol16Size);
541       break;
542     case ATFile:
543       writeBytes(
544           StringRef(reinterpret_cast<const char *>(&i.Aux),
545                     UseBigObj ? COFF::Symbol32Size : COFF::Symbol16Size));
546       break;
547     case ATSectionDefinition:
548       writeLE32(i.Aux.SectionDefinition.Length);
549       writeLE16(i.Aux.SectionDefinition.NumberOfRelocations);
550       writeLE16(i.Aux.SectionDefinition.NumberOfLinenumbers);
551       writeLE32(i.Aux.SectionDefinition.CheckSum);
552       writeLE16(static_cast<int16_t>(i.Aux.SectionDefinition.Number));
553       write8(i.Aux.SectionDefinition.Selection);
554       WriteZeros(sizeof(i.Aux.SectionDefinition.unused));
555       writeLE16(static_cast<int16_t>(i.Aux.SectionDefinition.Number >> 16));
556       if (UseBigObj)
557         WriteZeros(COFF::Symbol32Size - COFF::Symbol16Size);
558       break;
559     }
560   }
561 }
562 
563 // Write the section header.
564 void WinCOFFObjectWriter::writeSectionHeaders() {
565   // Section numbers must be monotonically increasing in the section
566   // header, but our Sections array is not sorted by section number,
567   // so make a copy of Sections and sort it.
568   std::vector<COFFSection *> Arr;
569   for (auto &Section : Sections)
570     Arr.push_back(Section.get());
571   std::sort(Arr.begin(), Arr.end(),
572             [](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     writeBytes(StringRef(S.Name, COFF::NameSize));
584     writeLE32(S.VirtualSize);
585     writeLE32(S.VirtualAddress);
586     writeLE32(S.SizeOfRawData);
587     writeLE32(S.PointerToRawData);
588     writeLE32(S.PointerToRelocations);
589     writeLE32(S.PointerToLineNumbers);
590     writeLE16(S.NumberOfRelocations);
591     writeLE16(S.NumberOfLineNumbers);
592     writeLE32(S.Characteristics);
593   }
594 }
595 
596 void WinCOFFObjectWriter::WriteRelocation(const COFF::relocation &R) {
597   writeLE32(R.VirtualAddress);
598   writeLE32(R.SymbolTableIndex);
599   writeLE16(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 WinCOFFObjectWriter::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   raw_pwrite_stream &OldStream = getStream();
613 
614   // Redirect the output stream to our buffer and fill our buffer with
615   // the section data.
616   setStream(VecOS);
617   Asm.writeSectionData(&MCSec, Layout);
618 
619   // Reset the stream back to what it was before.
620   setStream(OldStream);
621 
622   // Write the section contents to the object file.
623   getStream() << Buf;
624 
625   // Calculate our CRC with an initial value of '0', this is not how
626   // JamCRC is specified but it aligns with the expected output.
627   JamCRC JC(/*Init=*/0);
628   JC.update(Buf);
629   return JC.getCRC();
630 }
631 
632 void WinCOFFObjectWriter::writeSection(MCAssembler &Asm,
633                                        const MCAsmLayout &Layout,
634                                        const COFFSection &Sec,
635                                        const MCSection &MCSec) {
636   if (Sec.Number == -1)
637     return;
638 
639   // Write the section contents.
640   if (Sec.Header.PointerToRawData != 0) {
641     assert(getStream().tell() <= Sec.Header.PointerToRawData &&
642            "Section::PointerToRawData is insane!");
643 
644     unsigned PaddingSize = Sec.Header.PointerToRawData - getStream().tell();
645     assert(PaddingSize < 4 &&
646            "Should only need at most three bytes of padding!");
647     WriteZeros(PaddingSize);
648 
649     uint32_t CRC = writeSectionContents(Asm, Layout, MCSec);
650 
651     // Update the section definition auxiliary symbol to record the CRC.
652     COFFSection *Sec = SectionMap[&MCSec];
653     COFFSymbol::AuxiliarySymbols &AuxSyms = Sec->Symbol->Aux;
654     assert(AuxSyms.size() == 1 && AuxSyms[0].AuxType == ATSectionDefinition);
655     AuxSymbol &SecDef = AuxSyms[0];
656     SecDef.Aux.SectionDefinition.CheckSum = CRC;
657   }
658 
659   // Write relocations for this section.
660   if (Sec.Relocations.empty()) {
661     assert(Sec.Header.PointerToRelocations == 0 &&
662            "Section::PointerToRelocations is insane!");
663     return;
664   }
665 
666   assert(getStream().tell() == Sec.Header.PointerToRelocations &&
667          "Section::PointerToRelocations is insane!");
668 
669   if (Sec.Relocations.size() >= 0xffff) {
670     // In case of overflow, write actual relocation count as first
671     // relocation. Including the synthetic reloc itself (+ 1).
672     COFF::relocation R;
673     R.VirtualAddress = Sec.Relocations.size() + 1;
674     R.SymbolTableIndex = 0;
675     R.Type = 0;
676     WriteRelocation(R);
677   }
678 
679   for (const auto &Relocation : Sec.Relocations)
680     WriteRelocation(Relocation.Data);
681 }
682 
683 ////////////////////////////////////////////////////////////////////////////////
684 // MCObjectWriter interface implementations
685 
686 void WinCOFFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
687                                                    const MCAsmLayout &Layout) {
688   // "Define" each section & symbol. This creates section & symbol
689   // entries in the staging area.
690   for (const auto &Section : Asm)
691     defineSection(static_cast<const MCSectionCOFF &>(Section));
692 
693   for (const MCSymbol &Symbol : Asm.symbols())
694     if (!Symbol.isTemporary())
695       DefineSymbol(Symbol, Asm, Layout);
696 }
697 
698 bool WinCOFFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
699     const MCAssembler &Asm, const MCSymbol &SymA, const MCFragment &FB,
700     bool InSet, bool IsPCRel) const {
701   // MS LINK expects to be able to replace all references to a function with a
702   // thunk to implement their /INCREMENTAL feature.  Make sure we don't optimize
703   // away any relocations to functions.
704   uint16_t Type = cast<MCSymbolCOFF>(SymA).getType();
705   if (Asm.isIncrementalLinkerCompatible() &&
706       (Type >> COFF::SCT_COMPLEX_TYPE_SHIFT) == COFF::IMAGE_SYM_DTYPE_FUNCTION)
707     return false;
708   return MCObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(Asm, SymA, FB,
709                                                                 InSet, IsPCRel);
710 }
711 
712 bool WinCOFFObjectWriter::isWeak(const MCSymbol &Sym) const {
713   if (!Sym.isExternal())
714     return false;
715 
716   if (!Sym.isInSection())
717     return false;
718 
719   const auto &Sec = cast<MCSectionCOFF>(Sym.getSection());
720   if (!Sec.getCOMDATSymbol())
721     return false;
722 
723   // It looks like for COFF it is invalid to replace a reference to a global
724   // in a comdat with a reference to a local.
725   // FIXME: Add a specification reference if available.
726   return true;
727 }
728 
729 void WinCOFFObjectWriter::recordRelocation(
730     MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment,
731     const MCFixup &Fixup, MCValue Target, bool &IsPCRel, uint64_t &FixedValue) {
732   assert(Target.getSymA() && "Relocation must reference a symbol!");
733 
734   const MCSymbol &A = Target.getSymA()->getSymbol();
735   if (!A.isRegistered()) {
736     Asm.getContext().reportError(Fixup.getLoc(),
737                                       Twine("symbol '") + A.getName() +
738                                           "' can not be undefined");
739     return;
740   }
741   if (A.isTemporary() && A.isUndefined()) {
742     Asm.getContext().reportError(Fixup.getLoc(),
743                                       Twine("assembler label '") + A.getName() +
744                                           "' can not be undefined");
745     return;
746   }
747 
748   MCSection *MCSec = Fragment->getParent();
749 
750   // Mark this symbol as requiring an entry in the symbol table.
751   assert(SectionMap.find(MCSec) != SectionMap.end() &&
752          "Section must already have been defined in executePostLayoutBinding!");
753 
754   COFFSection *Sec = SectionMap[MCSec];
755   const MCSymbolRefExpr *SymB = Target.getSymB();
756   bool CrossSection = false;
757 
758   if (SymB) {
759     const MCSymbol *B = &SymB->getSymbol();
760     if (!B->getFragment()) {
761       Asm.getContext().reportError(
762           Fixup.getLoc(),
763           Twine("symbol '") + B->getName() +
764               "' can not be undefined in a subtraction expression");
765       return;
766     }
767 
768     if (!A.getFragment()) {
769       Asm.getContext().reportError(
770           Fixup.getLoc(),
771           Twine("symbol '") + A.getName() +
772               "' can not be undefined in a subtraction expression");
773       return;
774     }
775 
776     CrossSection = &A.getSection() != &B->getSection();
777 
778     // Offset of the symbol in the section
779     int64_t OffsetOfB = Layout.getSymbolOffset(*B);
780 
781     // In the case where we have SymbA and SymB, we just need to store the delta
782     // between the two symbols.  Update FixedValue to account for the delta, and
783     // skip recording the relocation.
784     if (!CrossSection) {
785       int64_t OffsetOfA = Layout.getSymbolOffset(A);
786       FixedValue = (OffsetOfA - OffsetOfB) + Target.getConstant();
787       return;
788     }
789 
790     // Offset of the relocation in the section
791     int64_t OffsetOfRelocation =
792         Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
793 
794     FixedValue = (OffsetOfRelocation - OffsetOfB) + Target.getConstant();
795   } else {
796     FixedValue = Target.getConstant();
797   }
798 
799   COFFRelocation Reloc;
800 
801   Reloc.Data.SymbolTableIndex = 0;
802   Reloc.Data.VirtualAddress = Layout.getFragmentOffset(Fragment);
803 
804   // Turn relocations for temporary symbols into section relocations.
805   if (A.isTemporary() || CrossSection) {
806     MCSection *TargetSection = &A.getSection();
807     assert(
808         SectionMap.find(TargetSection) != SectionMap.end() &&
809         "Section must already have been defined in executePostLayoutBinding!");
810     Reloc.Symb = SectionMap[TargetSection]->Symbol;
811     FixedValue += Layout.getSymbolOffset(A);
812   } else {
813     assert(
814         SymbolMap.find(&A) != SymbolMap.end() &&
815         "Symbol must already have been defined in executePostLayoutBinding!");
816     Reloc.Symb = SymbolMap[&A];
817   }
818 
819   ++Reloc.Symb->Relocations;
820 
821   Reloc.Data.VirtualAddress += Fixup.getOffset();
822   Reloc.Data.Type = TargetObjectWriter->getRelocType(
823       Target, Fixup, CrossSection, Asm.getBackend());
824 
825   // FIXME: Can anyone explain what this does other than adjust for the size
826   // of the offset?
827   if ((Header.Machine == COFF::IMAGE_FILE_MACHINE_AMD64 &&
828        Reloc.Data.Type == COFF::IMAGE_REL_AMD64_REL32) ||
829       (Header.Machine == COFF::IMAGE_FILE_MACHINE_I386 &&
830        Reloc.Data.Type == COFF::IMAGE_REL_I386_REL32))
831     FixedValue += 4;
832 
833   if (Header.Machine == COFF::IMAGE_FILE_MACHINE_ARMNT) {
834     switch (Reloc.Data.Type) {
835     case COFF::IMAGE_REL_ARM_ABSOLUTE:
836     case COFF::IMAGE_REL_ARM_ADDR32:
837     case COFF::IMAGE_REL_ARM_ADDR32NB:
838     case COFF::IMAGE_REL_ARM_TOKEN:
839     case COFF::IMAGE_REL_ARM_SECTION:
840     case COFF::IMAGE_REL_ARM_SECREL:
841       break;
842     case COFF::IMAGE_REL_ARM_BRANCH11:
843     case COFF::IMAGE_REL_ARM_BLX11:
844     // IMAGE_REL_ARM_BRANCH11 and IMAGE_REL_ARM_BLX11 are only used for
845     // pre-ARMv7, which implicitly rules it out of ARMNT (it would be valid
846     // for Windows CE).
847     case COFF::IMAGE_REL_ARM_BRANCH24:
848     case COFF::IMAGE_REL_ARM_BLX24:
849     case COFF::IMAGE_REL_ARM_MOV32A:
850       // IMAGE_REL_ARM_BRANCH24, IMAGE_REL_ARM_BLX24, IMAGE_REL_ARM_MOV32A are
851       // only used for ARM mode code, which is documented as being unsupported
852       // by Windows on ARM.  Empirical proof indicates that masm is able to
853       // generate the relocations however the rest of the MSVC toolchain is
854       // unable to handle it.
855       llvm_unreachable("unsupported relocation");
856       break;
857     case COFF::IMAGE_REL_ARM_MOV32T:
858       break;
859     case COFF::IMAGE_REL_ARM_BRANCH20T:
860     case COFF::IMAGE_REL_ARM_BRANCH24T:
861     case COFF::IMAGE_REL_ARM_BLX23T:
862       // IMAGE_REL_BRANCH20T, IMAGE_REL_ARM_BRANCH24T, IMAGE_REL_ARM_BLX23T all
863       // perform a 4 byte adjustment to the relocation.  Relative branches are
864       // offset by 4 on ARM, however, because there is no RELA relocations, all
865       // branches are offset by 4.
866       FixedValue = FixedValue + 4;
867       break;
868     }
869   }
870 
871   // The fixed value never makes sense for section indices, ignore it.
872   if (Fixup.getKind() == FK_SecRel_2)
873     FixedValue = 0;
874 
875   if (TargetObjectWriter->recordRelocation(Fixup))
876     Sec->Relocations.push_back(Reloc);
877 }
878 
879 static std::time_t getTime() {
880   std::time_t Now = time(nullptr);
881   if (Now < 0 || !isUInt<32>(Now))
882     return UINT32_MAX;
883   return Now;
884 }
885 
886 // Create .file symbols.
887 void WinCOFFObjectWriter::createFileSymbols(MCAssembler &Asm) {
888   for (const std::string &Name : Asm.getFileNames()) {
889     // round up to calculate the number of auxiliary symbols required
890     unsigned SymbolSize = UseBigObj ? COFF::Symbol32Size : COFF::Symbol16Size;
891     unsigned Count = (Name.size() + SymbolSize - 1) / SymbolSize;
892 
893     COFFSymbol *File = createSymbol(".file");
894     File->Data.SectionNumber = COFF::IMAGE_SYM_DEBUG;
895     File->Data.StorageClass = COFF::IMAGE_SYM_CLASS_FILE;
896     File->Aux.resize(Count);
897 
898     unsigned Offset = 0;
899     unsigned Length = Name.size();
900     for (auto &Aux : File->Aux) {
901       Aux.AuxType = ATFile;
902 
903       if (Length > SymbolSize) {
904         memcpy(&Aux.Aux, Name.c_str() + Offset, SymbolSize);
905         Length = Length - SymbolSize;
906       } else {
907         memcpy(&Aux.Aux, Name.c_str() + Offset, Length);
908         memset((char *)&Aux.Aux + Length, 0, SymbolSize - Length);
909         break;
910       }
911 
912       Offset += SymbolSize;
913     }
914   }
915 }
916 
917 static bool isAssociative(const COFFSection &Section) {
918   return Section.Symbol->Aux[0].Aux.SectionDefinition.Selection ==
919          COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE;
920 }
921 
922 void WinCOFFObjectWriter::assignSectionNumbers() {
923   size_t I = 1;
924   auto Assign = [&](COFFSection &Section) {
925     Section.Number = I;
926     Section.Symbol->Data.SectionNumber = I;
927     Section.Symbol->Aux[0].Aux.SectionDefinition.Number = I;
928     ++I;
929   };
930 
931   // Although it is not explicitly requested by the Microsoft COFF spec,
932   // we should avoid emitting forward associative section references,
933   // because MSVC link.exe as of 2017 cannot handle that.
934   for (const std::unique_ptr<COFFSection> &Section : Sections)
935     if (!isAssociative(*Section))
936       Assign(*Section);
937   for (const std::unique_ptr<COFFSection> &Section : Sections)
938     if (isAssociative(*Section))
939       Assign(*Section);
940 }
941 
942 // Assign file offsets to COFF object file structures.
943 void WinCOFFObjectWriter::assignFileOffsets(MCAssembler &Asm,
944                                             const MCAsmLayout &Layout) {
945   unsigned Offset = getInitialOffset();
946 
947   Offset += UseBigObj ? COFF::Header32Size : COFF::Header16Size;
948   Offset += COFF::SectionSize * Header.NumberOfSections;
949 
950   for (const auto &Section : Asm) {
951     COFFSection *Sec = SectionMap[&Section];
952 
953     if (Sec->Number == -1)
954       continue;
955 
956     Sec->Header.SizeOfRawData = Layout.getSectionAddressSize(&Section);
957 
958     if (IsPhysicalSection(Sec)) {
959       // Align the section data to a four byte boundary.
960       Offset = alignTo(Offset, 4);
961       Sec->Header.PointerToRawData = Offset;
962 
963       Offset += Sec->Header.SizeOfRawData;
964     }
965 
966     if (!Sec->Relocations.empty()) {
967       bool RelocationsOverflow = Sec->Relocations.size() >= 0xffff;
968 
969       if (RelocationsOverflow) {
970         // Signal overflow by setting NumberOfRelocations to max value. Actual
971         // size is found in reloc #0. Microsoft tools understand this.
972         Sec->Header.NumberOfRelocations = 0xffff;
973       } else {
974         Sec->Header.NumberOfRelocations = Sec->Relocations.size();
975       }
976       Sec->Header.PointerToRelocations = Offset;
977 
978       if (RelocationsOverflow) {
979         // Reloc #0 will contain actual count, so make room for it.
980         Offset += COFF::RelocationSize;
981       }
982 
983       Offset += COFF::RelocationSize * Sec->Relocations.size();
984 
985       for (auto &Relocation : Sec->Relocations) {
986         assert(Relocation.Symb->getIndex() != -1);
987         Relocation.Data.SymbolTableIndex = Relocation.Symb->getIndex();
988       }
989     }
990 
991     assert(Sec->Symbol->Aux.size() == 1 &&
992            "Section's symbol must have one aux!");
993     AuxSymbol &Aux = Sec->Symbol->Aux[0];
994     assert(Aux.AuxType == ATSectionDefinition &&
995            "Section's symbol's aux symbol must be a Section Definition!");
996     Aux.Aux.SectionDefinition.Length = Sec->Header.SizeOfRawData;
997     Aux.Aux.SectionDefinition.NumberOfRelocations =
998         Sec->Header.NumberOfRelocations;
999     Aux.Aux.SectionDefinition.NumberOfLinenumbers =
1000         Sec->Header.NumberOfLineNumbers;
1001   }
1002 
1003   Header.PointerToSymbolTable = Offset;
1004 }
1005 
1006 void WinCOFFObjectWriter::writeObject(MCAssembler &Asm,
1007                                       const MCAsmLayout &Layout) {
1008   if (Sections.size() > INT32_MAX)
1009     report_fatal_error(
1010         "PE COFF object files can't have more than 2147483647 sections");
1011 
1012   UseBigObj = Sections.size() > COFF::MaxNumberOfSections16;
1013   Header.NumberOfSections = Sections.size();
1014   Header.NumberOfSymbols = 0;
1015 
1016   assignSectionNumbers();
1017   createFileSymbols(Asm);
1018 
1019   for (auto &Symbol : Symbols) {
1020     // Update section number & offset for symbols that have them.
1021     if (Symbol->Section)
1022       Symbol->Data.SectionNumber = Symbol->Section->Number;
1023     Symbol->setIndex(Header.NumberOfSymbols++);
1024     // Update auxiliary symbol info.
1025     Symbol->Data.NumberOfAuxSymbols = Symbol->Aux.size();
1026     Header.NumberOfSymbols += Symbol->Data.NumberOfAuxSymbols;
1027   }
1028 
1029   // Build string table.
1030   for (const auto &S : Sections)
1031     if (S->Name.size() > COFF::NameSize)
1032       Strings.add(S->Name);
1033   for (const auto &S : Symbols)
1034     if (S->Name.size() > COFF::NameSize)
1035       Strings.add(S->Name);
1036   Strings.finalize();
1037 
1038   // Set names.
1039   for (const auto &S : Sections)
1040     SetSectionName(*S);
1041   for (auto &S : Symbols)
1042     SetSymbolName(*S);
1043 
1044   // Fixup weak external references.
1045   for (auto &Symbol : Symbols) {
1046     if (Symbol->Other) {
1047       assert(Symbol->getIndex() != -1);
1048       assert(Symbol->Aux.size() == 1 && "Symbol must contain one aux symbol!");
1049       assert(Symbol->Aux[0].AuxType == ATWeakExternal &&
1050              "Symbol's aux symbol must be a Weak External!");
1051       Symbol->Aux[0].Aux.WeakExternal.TagIndex = Symbol->Other->getIndex();
1052     }
1053   }
1054 
1055   // Fixup associative COMDAT sections.
1056   for (auto &Section : Sections) {
1057     if (Section->Symbol->Aux[0].Aux.SectionDefinition.Selection !=
1058         COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)
1059       continue;
1060 
1061     const MCSectionCOFF &MCSec = *Section->MCSection;
1062 
1063     const MCSymbol *COMDAT = MCSec.getCOMDATSymbol();
1064     assert(COMDAT);
1065     COFFSymbol *COMDATSymbol = GetOrCreateCOFFSymbol(COMDAT);
1066     assert(COMDATSymbol);
1067     COFFSection *Assoc = COMDATSymbol->Section;
1068     if (!Assoc)
1069       report_fatal_error(
1070           Twine("Missing associated COMDAT section for section ") +
1071           MCSec.getSectionName());
1072 
1073     // Skip this section if the associated section is unused.
1074     if (Assoc->Number == -1)
1075       continue;
1076 
1077     Section->Symbol->Aux[0].Aux.SectionDefinition.Number = Assoc->Number;
1078   }
1079 
1080   assignFileOffsets(Asm, Layout);
1081 
1082   // MS LINK expects to be able to use this timestamp to implement their
1083   // /INCREMENTAL feature.
1084   if (Asm.isIncrementalLinkerCompatible()) {
1085     Header.TimeDateStamp = getTime();
1086   } else {
1087     // Have deterministic output if /INCREMENTAL isn't needed. Also matches GNU.
1088     Header.TimeDateStamp = 0;
1089   }
1090 
1091   // Write it all to disk...
1092   WriteFileHeader(Header);
1093   writeSectionHeaders();
1094 
1095   // Write section contents.
1096   sections::iterator I = Sections.begin();
1097   sections::iterator IE = Sections.end();
1098   MCAssembler::iterator J = Asm.begin();
1099   MCAssembler::iterator JE = Asm.end();
1100   for (; I != IE && J != JE; ++I, ++J)
1101     writeSection(Asm, Layout, **I, *J);
1102 
1103   assert(getStream().tell() == Header.PointerToSymbolTable &&
1104          "Header::PointerToSymbolTable is insane!");
1105 
1106   // Write a symbol table.
1107   for (auto &Symbol : Symbols)
1108     if (Symbol->getIndex() != -1)
1109       WriteSymbol(*Symbol);
1110 
1111   // Write a string table, which completes the entire COFF file.
1112   Strings.write(getStream());
1113 }
1114 
1115 MCWinCOFFObjectTargetWriter::MCWinCOFFObjectTargetWriter(unsigned Machine_)
1116     : Machine(Machine_) {}
1117 
1118 // Pin the vtable to this file.
1119 void MCWinCOFFObjectTargetWriter::anchor() {}
1120 
1121 //------------------------------------------------------------------------------
1122 // WinCOFFObjectWriter factory function
1123 
1124 MCObjectWriter *
1125 llvm::createWinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW,
1126                                 raw_pwrite_stream &OS) {
1127   return new WinCOFFObjectWriter(MOTW, OS);
1128 }
1129