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

Generated by: LCOV version 1.13