LCOV - code coverage report
Current view: top level - lib/MC - WinCOFFObjectWriter.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 387 454 85.2 %
Date: 2018-02-23 15:42:53 Functions: 34 35 97.1 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13