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