LCOV - code coverage report
Current view: top level - lib/MC - MachObjectWriter.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 473 482 98.1 %
Date: 2017-09-14 15:23:50 Functions: 26 26 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- lib/MC/MachObjectWriter.cpp - Mach-O File Writer -------------------===//
       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             : #include "llvm/ADT/DenseMap.h"
      11             : #include "llvm/ADT/Twine.h"
      12             : #include "llvm/ADT/iterator_range.h"
      13             : #include "llvm/BinaryFormat/MachO.h"
      14             : #include "llvm/MC/MCAsmBackend.h"
      15             : #include "llvm/MC/MCAsmLayout.h"
      16             : #include "llvm/MC/MCAssembler.h"
      17             : #include "llvm/MC/MCDirectives.h"
      18             : #include "llvm/MC/MCExpr.h"
      19             : #include "llvm/MC/MCFixupKindInfo.h"
      20             : #include "llvm/MC/MCFragment.h"
      21             : #include "llvm/MC/MCMachObjectWriter.h"
      22             : #include "llvm/MC/MCObjectWriter.h"
      23             : #include "llvm/MC/MCSection.h"
      24             : #include "llvm/MC/MCSectionMachO.h"
      25             : #include "llvm/MC/MCSymbol.h"
      26             : #include "llvm/MC/MCSymbolMachO.h"
      27             : #include "llvm/MC/MCValue.h"
      28             : #include "llvm/Support/Casting.h"
      29             : #include "llvm/Support/Debug.h"
      30             : #include "llvm/Support/ErrorHandling.h"
      31             : #include "llvm/Support/MathExtras.h"
      32             : #include "llvm/Support/raw_ostream.h"
      33             : #include <algorithm>
      34             : #include <cassert>
      35             : #include <cstdint>
      36             : #include <string>
      37             : #include <utility>
      38             : #include <vector>
      39             : 
      40             : using namespace llvm;
      41             : 
      42             : #define DEBUG_TYPE "mc"
      43             : 
      44         245 : void MachObjectWriter::reset() {
      45         245 :   Relocations.clear();
      46         245 :   IndirectSymBase.clear();
      47         245 :   StringTable.clear();
      48         490 :   LocalSymbolData.clear();
      49         490 :   ExternalSymbolData.clear();
      50         490 :   UndefinedSymbolData.clear();
      51         245 :   MCObjectWriter::reset();
      52         245 : }
      53             : 
      54        1459 : bool MachObjectWriter::doesSymbolRequireExternRelocation(const MCSymbol &S) {
      55             :   // Undefined symbols are always extern.
      56        1459 :   if (S.isUndefined())
      57             :     return true;
      58             : 
      59             :   // References to weak definitions require external relocation entries; the
      60             :   // definition may not always be the one in the same object file.
      61         498 :   if (cast<MCSymbolMachO>(S).isWeakDefinition())
      62             :     return true;
      63             : 
      64             :   // Otherwise, we can use an internal relocation.
      65         245 :   return false;
      66             : }
      67             : 
      68        1639 : bool MachObjectWriter::
      69             : MachSymbolData::operator<(const MachSymbolData &RHS) const {
      70        4917 :   return Symbol->getName() < RHS.Symbol->getName();
      71             : }
      72             : 
      73        3191 : bool MachObjectWriter::isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) {
      74        3191 :   const MCFixupKindInfo &FKI = Asm.getBackend().getFixupKindInfo(
      75        3191 :     (MCFixupKind) Kind);
      76             : 
      77        3191 :   return FKI.Flags & MCFixupKindInfo::FKF_IsPCRel;
      78             : }
      79             : 
      80        1259 : uint64_t MachObjectWriter::getFragmentAddress(const MCFragment *Fragment,
      81             :                                               const MCAsmLayout &Layout) const {
      82        2518 :   return getSectionAddress(Fragment->getParent()) +
      83        1259 :          Layout.getFragmentOffset(Fragment);
      84             : }
      85             : 
      86        2141 : uint64_t MachObjectWriter::getSymbolAddress(const MCSymbol &S,
      87             :                                             const MCAsmLayout &Layout) const {
      88             :   // If this is a variable, then recursively evaluate now.
      89        2141 :   if (S.isVariable()) {
      90             :     if (const MCConstantExpr *C =
      91          44 :           dyn_cast<const MCConstantExpr>(S.getVariableValue()))
      92           4 :       return C->getValue();
      93             : 
      94          36 :     MCValue Target;
      95          36 :     if (!S.getVariableValue()->evaluateAsRelocatable(Target, &Layout, nullptr))
      96           0 :       report_fatal_error("unable to evaluate offset for variable '" +
      97           0 :                          S.getName() + "'");
      98             : 
      99             :     // Verify that any used symbols are defined.
     100          72 :     if (Target.getSymA() && Target.getSymA()->getSymbol().isUndefined())
     101           0 :       report_fatal_error("unable to evaluate offset to undefined symbol '" +
     102           0 :                          Target.getSymA()->getSymbol().getName() + "'");
     103          42 :     if (Target.getSymB() && Target.getSymB()->getSymbol().isUndefined())
     104           0 :       report_fatal_error("unable to evaluate offset to undefined symbol '" +
     105           0 :                          Target.getSymB()->getSymbol().getName() + "'");
     106             : 
     107          36 :     uint64_t Address = Target.getConstant();
     108          36 :     if (Target.getSymA())
     109          36 :       Address += getSymbolAddress(Target.getSymA()->getSymbol(), Layout);
     110          36 :     if (Target.getSymB())
     111           3 :       Address += getSymbolAddress(Target.getSymB()->getSymbol(), Layout);
     112             :     return Address;
     113             :   }
     114             : 
     115        4202 :   return getSectionAddress(S.getFragment()->getParent()) +
     116        2101 :          Layout.getSymbolOffset(S);
     117             : }
     118             : 
     119        8094 : uint64_t MachObjectWriter::getPaddingSize(const MCSection *Sec,
     120             :                                           const MCAsmLayout &Layout) const {
     121        8094 :   uint64_t EndAddr = getSectionAddress(Sec) + Layout.getSectionAddressSize(Sec);
     122        8094 :   unsigned Next = Sec->getLayoutOrder() + 1;
     123       16188 :   if (Next >= Layout.getSectionOrder().size())
     124             :     return 0;
     125             : 
     126       13154 :   const MCSection &NextSec = *Layout.getSectionOrder()[Next];
     127        6577 :   if (NextSec.isVirtualSection())
     128             :     return 0;
     129       12938 :   return OffsetToAlignment(EndAddr, NextSec.getAlignment());
     130             : }
     131             : 
     132         523 : void MachObjectWriter::writeHeader(MachO::HeaderFileType Type,
     133             :                                    unsigned NumLoadCommands,
     134             :                                    unsigned LoadCommandsSize,
     135             :                                    bool SubsectionsViaSymbols) {
     136         523 :   uint32_t Flags = 0;
     137             : 
     138         523 :   if (SubsectionsViaSymbols)
     139         283 :     Flags |= MachO::MH_SUBSECTIONS_VIA_SYMBOLS;
     140             : 
     141             :   // struct mach_header (28 bytes) or
     142             :   // struct mach_header_64 (32 bytes)
     143             : 
     144        1046 :   uint64_t Start = getStream().tell();
     145             :   (void) Start;
     146             : 
     147        1046 :   write32(is64Bit() ? MachO::MH_MAGIC_64 : MachO::MH_MAGIC);
     148             : 
     149        1046 :   write32(TargetObjectWriter->getCPUType());
     150        1046 :   write32(TargetObjectWriter->getCPUSubtype());
     151             : 
     152         523 :   write32(Type);
     153         523 :   write32(NumLoadCommands);
     154         523 :   write32(LoadCommandsSize);
     155         523 :   write32(Flags);
     156         523 :   if (is64Bit())
     157         336 :     write32(0); // reserved
     158             : 
     159             :   assert(
     160             :       getStream().tell() - Start ==
     161             :       (is64Bit() ? sizeof(MachO::mach_header_64) : sizeof(MachO::mach_header)));
     162         523 : }
     163             : 
     164             : /// writeSegmentLoadCommand - Write a segment load command.
     165             : ///
     166             : /// \param NumSections The number of sections in this segment.
     167             : /// \param SectionDataSize The total size of the sections.
     168         523 : void MachObjectWriter::writeSegmentLoadCommand(
     169             :     StringRef Name, unsigned NumSections, uint64_t VMAddr, uint64_t VMSize,
     170             :     uint64_t SectionDataStartOffset, uint64_t SectionDataSize, uint32_t MaxProt,
     171             :     uint32_t InitProt) {
     172             :   // struct segment_command (56 bytes) or
     173             :   // struct segment_command_64 (72 bytes)
     174             : 
     175        1046 :   uint64_t Start = getStream().tell();
     176             :   (void) Start;
     177             : 
     178             :   unsigned SegmentLoadCommandSize =
     179         523 :     is64Bit() ? sizeof(MachO::segment_command_64):
     180         523 :     sizeof(MachO::segment_command);
     181        1046 :   write32(is64Bit() ? MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT);
     182        1046 :   write32(SegmentLoadCommandSize +
     183         523 :           NumSections * (is64Bit() ? sizeof(MachO::section_64) :
     184             :                          sizeof(MachO::section)));
     185             : 
     186             :   assert(Name.size() <= 16);
     187        1046 :   writeBytes(Name, 16);
     188         523 :   if (is64Bit()) {
     189         336 :     write64(VMAddr);                 // vmaddr
     190         336 :     write64(VMSize); // vmsize
     191         336 :     write64(SectionDataStartOffset); // file offset
     192         336 :     write64(SectionDataSize); // file size
     193             :   } else {
     194         187 :     write32(VMAddr);                 // vmaddr
     195         187 :     write32(VMSize); // vmsize
     196         187 :     write32(SectionDataStartOffset); // file offset
     197         187 :     write32(SectionDataSize); // file size
     198             :   }
     199             :   // maxprot
     200         523 :   write32(MaxProt);
     201             :   // initprot
     202         523 :   write32(InitProt);
     203         523 :   write32(NumSections);
     204         523 :   write32(0); // flags
     205             : 
     206             :   assert(getStream().tell() - Start == SegmentLoadCommandSize);
     207         523 : }
     208             : 
     209        2820 : void MachObjectWriter::writeSection(const MCAsmLayout &Layout,
     210             :                                     const MCSection &Sec, uint64_t VMAddr,
     211             :                                     uint64_t FileOffset, unsigned Flags,
     212             :                                     uint64_t RelocationsStart,
     213             :                                     unsigned NumRelocations) {
     214        2820 :   uint64_t SectionSize = Layout.getSectionAddressSize(&Sec);
     215        2820 :   const MCSectionMachO &Section = cast<MCSectionMachO>(Sec);
     216             : 
     217             :   // The offset is unused for virtual sections.
     218        2820 :   if (Section.isVirtualSection()) {
     219             :     assert(Layout.getSectionFileSize(&Sec) == 0 && "Invalid file size!");
     220          36 :     FileOffset = 0;
     221             :   }
     222             : 
     223             :   // struct section (68 bytes) or
     224             :   // struct section_64 (80 bytes)
     225             : 
     226        5640 :   uint64_t Start = getStream().tell();
     227             :   (void) Start;
     228             : 
     229        8460 :   writeBytes(Section.getSectionName(), 16);
     230        8460 :   writeBytes(Section.getSegmentName(), 16);
     231        2820 :   if (is64Bit()) {
     232        2194 :     write64(VMAddr);      // address
     233        2194 :     write64(SectionSize); // size
     234             :   } else {
     235         626 :     write32(VMAddr);      // address
     236         626 :     write32(SectionSize); // size
     237             :   }
     238        2820 :   write32(FileOffset);
     239             : 
     240             :   assert(isPowerOf2_32(Section.getAlignment()) && "Invalid alignment!");
     241        5640 :   write32(Log2_32(Section.getAlignment()));
     242        2820 :   write32(NumRelocations ? RelocationsStart : 0);
     243        2820 :   write32(NumRelocations);
     244        2820 :   write32(Flags);
     245        5640 :   write32(IndirectSymBase.lookup(&Sec)); // reserved1
     246        2820 :   write32(Section.getStubSize()); // reserved2
     247        2820 :   if (is64Bit())
     248        2194 :     write32(0); // reserved3
     249             : 
     250             :   assert(getStream().tell() - Start ==
     251             :          (is64Bit() ? sizeof(MachO::section_64) : sizeof(MachO::section)));
     252        2820 : }
     253             : 
     254         438 : void MachObjectWriter::writeSymtabLoadCommand(uint32_t SymbolOffset,
     255             :                                               uint32_t NumSymbols,
     256             :                                               uint32_t StringTableOffset,
     257             :                                               uint32_t StringTableSize) {
     258             :   // struct symtab_command (24 bytes)
     259             : 
     260         876 :   uint64_t Start = getStream().tell();
     261             :   (void) Start;
     262             : 
     263         438 :   write32(MachO::LC_SYMTAB);
     264         438 :   write32(sizeof(MachO::symtab_command));
     265         438 :   write32(SymbolOffset);
     266         438 :   write32(NumSymbols);
     267         438 :   write32(StringTableOffset);
     268         438 :   write32(StringTableSize);
     269             : 
     270             :   assert(getStream().tell() - Start == sizeof(MachO::symtab_command));
     271         438 : }
     272             : 
     273         413 : void MachObjectWriter::writeDysymtabLoadCommand(uint32_t FirstLocalSymbol,
     274             :                                                 uint32_t NumLocalSymbols,
     275             :                                                 uint32_t FirstExternalSymbol,
     276             :                                                 uint32_t NumExternalSymbols,
     277             :                                                 uint32_t FirstUndefinedSymbol,
     278             :                                                 uint32_t NumUndefinedSymbols,
     279             :                                                 uint32_t IndirectSymbolOffset,
     280             :                                                 uint32_t NumIndirectSymbols) {
     281             :   // struct dysymtab_command (80 bytes)
     282             : 
     283         826 :   uint64_t Start = getStream().tell();
     284             :   (void) Start;
     285             : 
     286         413 :   write32(MachO::LC_DYSYMTAB);
     287         413 :   write32(sizeof(MachO::dysymtab_command));
     288         413 :   write32(FirstLocalSymbol);
     289         413 :   write32(NumLocalSymbols);
     290         413 :   write32(FirstExternalSymbol);
     291         413 :   write32(NumExternalSymbols);
     292         413 :   write32(FirstUndefinedSymbol);
     293         413 :   write32(NumUndefinedSymbols);
     294         413 :   write32(0); // tocoff
     295         413 :   write32(0); // ntoc
     296         413 :   write32(0); // modtaboff
     297         413 :   write32(0); // nmodtab
     298         413 :   write32(0); // extrefsymoff
     299         413 :   write32(0); // nextrefsyms
     300         413 :   write32(IndirectSymbolOffset);
     301         413 :   write32(NumIndirectSymbols);
     302         413 :   write32(0); // extreloff
     303         413 :   write32(0); // nextrel
     304         413 :   write32(0); // locreloff
     305         413 :   write32(0); // nlocrel
     306             : 
     307             :   assert(getStream().tell() - Start == sizeof(MachO::dysymtab_command));
     308         413 : }
     309             : 
     310             : MachObjectWriter::MachSymbolData *
     311          24 : MachObjectWriter::findSymbolData(const MCSymbol &Sym) {
     312          69 :   for (auto *SymbolData :
     313          48 :        {&LocalSymbolData, &ExternalSymbolData, &UndefinedSymbolData})
     314         286 :     for (MachSymbolData &Entry : *SymbolData)
     315         127 :       if (Entry.Symbol == &Sym)
     316             :         return &Entry;
     317             : 
     318             :   return nullptr;
     319             : }
     320             : 
     321        4661 : const MCSymbol &MachObjectWriter::findAliasedSymbol(const MCSymbol &Sym) const {
     322        4661 :   const MCSymbol *S = &Sym;
     323        4719 :   while (S->isVariable()) {
     324          51 :     const MCExpr *Value = S->getVariableValue();
     325          29 :     const auto *Ref = dyn_cast<MCSymbolRefExpr>(Value);
     326             :     if (!Ref)
     327             :       return *S;
     328          29 :     S = &Ref->getSymbol();
     329             :   }
     330             :   return *S;
     331             : }
     332             : 
     333        1497 : void MachObjectWriter::writeNlist(MachSymbolData &MSD,
     334             :                                   const MCAsmLayout &Layout) {
     335        1497 :   const MCSymbol *Symbol = MSD.Symbol;
     336        1497 :   const MCSymbol &Data = *Symbol;
     337        1497 :   const MCSymbol *AliasedSymbol = &findAliasedSymbol(*Symbol);
     338        1497 :   uint8_t SectionIndex = MSD.SectionIndex;
     339        1497 :   uint8_t Type = 0;
     340        1497 :   uint64_t Address = 0;
     341        1497 :   bool IsAlias = Symbol != AliasedSymbol;
     342             : 
     343        1497 :   const MCSymbol &OrigSymbol = *Symbol;
     344             :   MachSymbolData *AliaseeInfo;
     345        1497 :   if (IsAlias) {
     346          24 :     AliaseeInfo = findSymbolData(*AliasedSymbol);
     347          24 :     if (AliaseeInfo)
     348          21 :       SectionIndex = AliaseeInfo->SectionIndex;
     349             :     Symbol = AliasedSymbol;
     350             :     // FIXME: Should this update Data as well?
     351             :   }
     352             : 
     353             :   // Set the N_TYPE bits. See <mach-o/nlist.h>.
     354             :   //
     355             :   // FIXME: Are the prebound or indirect fields possible here?
     356        1521 :   if (IsAlias && Symbol->isUndefined())
     357             :     Type = MachO::N_INDR;
     358        1492 :   else if (Symbol->isUndefined())
     359             :     Type = MachO::N_UNDF;
     360        1049 :   else if (Symbol->isAbsolute())
     361             :     Type = MachO::N_ABS;
     362             :   else
     363        1042 :     Type = MachO::N_SECT;
     364             : 
     365             :   // FIXME: Set STAB bits.
     366             : 
     367        1497 :   if (Data.isPrivateExtern())
     368          17 :     Type |= MachO::N_PEXT;
     369             : 
     370             :   // Set external bit.
     371        2364 :   if (Data.isExternal() || (!IsAlias && Symbol->isUndefined()))
     372         979 :     Type |= MachO::N_EXT;
     373             : 
     374             :   // Compute the symbol address.
     375        1521 :   if (IsAlias && Symbol->isUndefined())
     376           5 :     Address = AliaseeInfo->StringIndex;
     377        1492 :   else if (Symbol->isDefined())
     378        1049 :     Address = getSymbolAddress(OrigSymbol, Layout);
     379         443 :   else if (Symbol->isCommon()) {
     380             :     // Common symbols are encoded with the size in the address
     381             :     // field, and their alignment in the flags.
     382          51 :     Address = Symbol->getCommonSize();
     383             :   }
     384             : 
     385             :   // struct nlist (12 bytes)
     386             : 
     387        1497 :   write32(MSD.StringIndex);
     388        1497 :   write8(Type);
     389        1497 :   write8(SectionIndex);
     390             : 
     391             :   // The Mach-O streamer uses the lowest 16-bits of the flags for the 'desc'
     392             :   // value.
     393             :   bool EncodeAsAltEntry =
     394        1545 :     IsAlias && cast<MCSymbolMachO>(OrigSymbol).isAltEntry();
     395        2994 :   write16(cast<MCSymbolMachO>(Symbol)->getEncodedFlags(EncodeAsAltEntry));
     396        1497 :   if (is64Bit())
     397         874 :     write64(Address);
     398             :   else
     399         623 :     write32(Address);
     400        1497 : }
     401             : 
     402          16 : void MachObjectWriter::writeLinkeditLoadCommand(uint32_t Type,
     403             :                                                 uint32_t DataOffset,
     404             :                                                 uint32_t DataSize) {
     405          32 :   uint64_t Start = getStream().tell();
     406             :   (void) Start;
     407             : 
     408          16 :   write32(Type);
     409          16 :   write32(sizeof(MachO::linkedit_data_command));
     410          16 :   write32(DataOffset);
     411          16 :   write32(DataSize);
     412             : 
     413             :   assert(getStream().tell() - Start == sizeof(MachO::linkedit_data_command));
     414          16 : }
     415             : 
     416             : static unsigned ComputeLinkerOptionsLoadCommandSize(
     417             :   const std::vector<std::string> &Options, bool is64Bit)
     418             : {
     419          10 :   unsigned Size = sizeof(MachO::linker_option_command);
     420          54 :   for (const std::string &Option : Options)
     421          14 :     Size += Option.size() + 1;
     422          20 :   return alignTo(Size, is64Bit ? 8 : 4);
     423             : }
     424             : 
     425           5 : void MachObjectWriter::writeLinkerOptionsLoadCommand(
     426             :   const std::vector<std::string> &Options)
     427             : {
     428          10 :   unsigned Size = ComputeLinkerOptionsLoadCommandSize(Options, is64Bit());
     429          10 :   uint64_t Start = getStream().tell();
     430             :   (void) Start;
     431             : 
     432           5 :   write32(MachO::LC_LINKER_OPTION);
     433           5 :   write32(Size);
     434          10 :   write32(Options.size());
     435           5 :   uint64_t BytesWritten = sizeof(MachO::linker_option_command);
     436          27 :   for (const std::string &Option : Options) {
     437             :     // Write each string, including the null byte.
     438          14 :     writeBytes(Option, Option.size() + 1);
     439           7 :     BytesWritten += Option.size() + 1;
     440             :   }
     441             : 
     442             :   // Pad to a multiple of the pointer size.
     443          20 :   writeBytes("", OffsetToAlignment(BytesWritten, is64Bit() ? 8 : 4));
     444             : 
     445             :   assert(getStream().tell() - Start == Size);
     446           5 : }
     447             : 
     448        3065 : void MachObjectWriter::recordRelocation(MCAssembler &Asm,
     449             :                                         const MCAsmLayout &Layout,
     450             :                                         const MCFragment *Fragment,
     451             :                                         const MCFixup &Fixup, MCValue Target,
     452             :                                         uint64_t &FixedValue) {
     453        9195 :   TargetObjectWriter->recordRelocation(this, Asm, Layout, Fragment, Fixup,
     454        3065 :                                        Target, FixedValue);
     455        3065 : }
     456             : 
     457         524 : void MachObjectWriter::bindIndirectSymbols(MCAssembler &Asm) {
     458             :   // This is the point where 'as' creates actual symbols for indirect symbols
     459             :   // (in the following two passes). It would be easier for us to do this sooner
     460             :   // when we see the attribute, but that makes getting the order in the symbol
     461             :   // table much more complicated than it is worth.
     462             :   //
     463             :   // FIXME: Revisit this when the dust settles.
     464             : 
     465             :   // Report errors for use of .indirect_symbol not in a symbol pointer section
     466             :   // or stub section.
     467         524 :   for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(),
     468        1089 :          ie = Asm.indirect_symbol_end(); it != ie; ++it) {
     469          82 :     const MCSectionMachO &Section = cast<MCSectionMachO>(*it->Section);
     470             : 
     471          13 :     if (Section.getType() != MachO::S_NON_LAZY_SYMBOL_POINTERS &&
     472           7 :         Section.getType() != MachO::S_LAZY_SYMBOL_POINTERS &&
     473          46 :         Section.getType() != MachO::S_THREAD_LOCAL_VARIABLE_POINTERS &&
     474             :         Section.getType() != MachO::S_SYMBOL_STUBS) {
     475           0 :       MCSymbol &Symbol = *it->Symbol;
     476           0 :       report_fatal_error("indirect symbol '" + Symbol.getName() +
     477           0 :                          "' not in a symbol pointer or stub section");
     478             :     }
     479             :   }
     480             : 
     481             :   // Bind non-lazy symbol pointers first.
     482             :   unsigned IndirectIndex = 0;
     483          41 :   for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(),
     484         565 :          ie = Asm.indirect_symbol_end(); it != ie; ++it, ++IndirectIndex) {
     485          82 :     const MCSectionMachO &Section = cast<MCSectionMachO>(*it->Section);
     486             : 
     487          52 :     if (Section.getType() != MachO::S_NON_LAZY_SYMBOL_POINTERS &&
     488             :         Section.getType() !=  MachO::S_THREAD_LOCAL_VARIABLE_POINTERS)
     489          11 :       continue;
     490             : 
     491             :     // Initialize the section indirect symbol base, if necessary.
     492         120 :     IndirectSymBase.insert(std::make_pair(it->Section, IndirectIndex));
     493             : 
     494          30 :     Asm.registerSymbol(*it->Symbol);
     495             :   }
     496             : 
     497             :   // Then lazy symbol pointers and symbol stubs.
     498         524 :   IndirectIndex = 0;
     499         565 :   for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(),
     500        1089 :          ie = Asm.indirect_symbol_end(); it != ie; ++it, ++IndirectIndex) {
     501          82 :     const MCSectionMachO &Section = cast<MCSectionMachO>(*it->Section);
     502             : 
     503          71 :     if (Section.getType() != MachO::S_LAZY_SYMBOL_POINTERS &&
     504             :         Section.getType() != MachO::S_SYMBOL_STUBS)
     505          30 :       continue;
     506             : 
     507             :     // Initialize the section indirect symbol base, if necessary.
     508          44 :     IndirectSymBase.insert(std::make_pair(it->Section, IndirectIndex));
     509             : 
     510             :     // Set the symbol type to undefined lazy, but only on construction.
     511             :     //
     512             :     // FIXME: Do not hardcode.
     513             :     bool Created;
     514          11 :     Asm.registerSymbol(*it->Symbol, &Created);
     515          11 :     if (Created)
     516           8 :       cast<MCSymbolMachO>(it->Symbol)->setReferenceTypeUndefinedLazy(true);
     517             :   }
     518         524 : }
     519             : 
     520             : /// computeSymbolTable - Compute the symbol table data
     521         498 : void MachObjectWriter::computeSymbolTable(
     522             :     MCAssembler &Asm, std::vector<MachSymbolData> &LocalSymbolData,
     523             :     std::vector<MachSymbolData> &ExternalSymbolData,
     524             :     std::vector<MachSymbolData> &UndefinedSymbolData) {
     525             :   // Build section lookup table.
     526         996 :   DenseMap<const MCSection*, uint8_t> SectionIndexMap;
     527         498 :   unsigned Index = 1;
     528        3134 :   for (MCAssembler::iterator it = Asm.begin(),
     529        3632 :          ie = Asm.end(); it != ie; ++it, ++Index)
     530        5272 :     SectionIndexMap[&*it] = Index;
     531             :   assert(Index <= 256 && "Too many sections!");
     532             : 
     533             :   // Build the string table.
     534       25526 :   for (const MCSymbol &Symbol : Asm.symbols()) {
     535       12265 :     if (!Asm.isSymbolLinkerVisible(Symbol))
     536       10768 :       continue;
     537             : 
     538        2994 :     StringTable.add(Symbol.getName());
     539             :   }
     540         498 :   StringTable.finalize();
     541             : 
     542             :   // Build the symbol arrays but only for non-local symbols.
     543             :   //
     544             :   // The particular order that we collect and then sort the symbols is chosen to
     545             :   // match 'as'. Even though it doesn't matter for correctness, this is
     546             :   // important for letting us diff .o files.
     547       25526 :   for (const MCSymbol &Symbol : Asm.symbols()) {
     548             :     // Ignore non-linker visible symbols.
     549       12265 :     if (!Asm.isSymbolLinkerVisible(Symbol))
     550       22053 :       continue;
     551             : 
     552        2379 :     if (!Symbol.isExternal() && !Symbol.isUndefined())
     553         517 :       continue;
     554             : 
     555             :     MachSymbolData MSD;
     556         980 :     MSD.Symbol = &Symbol;
     557        1960 :     MSD.StringIndex = StringTable.getOffset(Symbol.getName());
     558             : 
     559         980 :     if (Symbol.isUndefined()) {
     560         448 :       MSD.SectionIndex = 0;
     561         448 :       UndefinedSymbolData.push_back(MSD);
     562         532 :     } else if (Symbol.isAbsolute()) {
     563           3 :       MSD.SectionIndex = 0;
     564           3 :       ExternalSymbolData.push_back(MSD);
     565             :     } else {
     566        1058 :       MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection());
     567             :       assert(MSD.SectionIndex && "Invalid section index!");
     568         529 :       ExternalSymbolData.push_back(MSD);
     569             :     }
     570             :   }
     571             : 
     572             :   // Now add the data for local symbols.
     573       25526 :   for (const MCSymbol &Symbol : Asm.symbols()) {
     574             :     // Ignore non-linker visible symbols.
     575       12265 :     if (!Asm.isSymbolLinkerVisible(Symbol))
     576       22516 :       continue;
     577             : 
     578        3359 :     if (Symbol.isExternal() || Symbol.isUndefined())
     579         980 :       continue;
     580             : 
     581             :     MachSymbolData MSD;
     582         517 :     MSD.Symbol = &Symbol;
     583        1034 :     MSD.StringIndex = StringTable.getOffset(Symbol.getName());
     584             : 
     585         517 :     if (Symbol.isAbsolute()) {
     586           4 :       MSD.SectionIndex = 0;
     587           4 :       LocalSymbolData.push_back(MSD);
     588             :     } else {
     589        1026 :       MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection());
     590             :       assert(MSD.SectionIndex && "Invalid section index!");
     591         513 :       LocalSymbolData.push_back(MSD);
     592             :     }
     593             :   }
     594             : 
     595             :   // External and undefined symbols are required to be in lexicographic order.
     596        1494 :   std::sort(ExternalSymbolData.begin(), ExternalSymbolData.end());
     597         996 :   std::sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end());
     598             : 
     599             :   // Set the symbol indices.
     600         498 :   Index = 0;
     601        2988 :   for (auto *SymbolData :
     602         996 :        {&LocalSymbolData, &ExternalSymbolData, &UndefinedSymbolData})
     603        7473 :     for (MachSymbolData &Entry : *SymbolData)
     604        2994 :       Entry.Symbol->setIndex(Index++);
     605             : 
     606        7264 :   for (const MCSection &Section : Asm) {
     607       16114 :     for (RelAndSymbol &Rel : Relocations[&Section]) {
     608        2934 :       if (!Rel.Sym)
     609        1094 :         continue;
     610             : 
     611             :       // Set the Index and the IsExtern bit.
     612        1840 :       unsigned Index = Rel.Sym->getIndex();
     613             :       assert(isInt<24>(Index));
     614        1840 :       if (IsLittleEndian)
     615        1839 :         Rel.MRE.r_word1 = (Rel.MRE.r_word1 & (~0U << 24)) | Index | (1 << 27);
     616             :       else
     617           1 :         Rel.MRE.r_word1 = (Rel.MRE.r_word1 & 0xff) | Index << 8 | (1 << 4);
     618             :     }
     619             :   }
     620         498 : }
     621             : 
     622         524 : void MachObjectWriter::computeSectionAddresses(const MCAssembler &Asm,
     623             :                                                const MCAsmLayout &Layout) {
     624         524 :   uint64_t StartAddress = 0;
     625        4394 :   for (const MCSection *Sec : Layout.getSectionOrder()) {
     626        5644 :     StartAddress = alignTo(StartAddress, Sec->getAlignment());
     627        5644 :     SectionAddress[Sec] = StartAddress;
     628        2822 :     StartAddress += Layout.getSectionAddressSize(Sec);
     629             : 
     630             :     // Explicitly pad the section to match the alignment requirements of the
     631             :     // following one. This is for 'gas' compatibility, it shouldn't
     632             :     /// strictly be necessary.
     633        2822 :     StartAddress += getPaddingSize(Sec, Layout);
     634             :   }
     635         524 : }
     636             : 
     637         524 : void MachObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
     638             :                                                 const MCAsmLayout &Layout) {
     639         524 :   computeSectionAddresses(Asm, Layout);
     640             : 
     641             :   // Create symbol data for any indirect symbols.
     642         524 :   bindIndirectSymbols(Asm);
     643         524 : }
     644             : 
     645        6456 : bool MachObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
     646             :     const MCAssembler &Asm, const MCSymbol &A, const MCSymbol &B,
     647             :     bool InSet) const {
     648             :   // FIXME: We don't handle things like
     649             :   // foo = .
     650             :   // creating atoms.
     651       12910 :   if (A.isVariable() || B.isVariable())
     652             :     return false;
     653        6453 :   return MCObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(Asm, A, B,
     654        6453 :                                                                 InSet);
     655             : }
     656             : 
     657        7449 : bool MachObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
     658             :     const MCAssembler &Asm, const MCSymbol &SymA, const MCFragment &FB,
     659             :     bool InSet, bool IsPCRel) const {
     660        7449 :   if (InSet)
     661             :     return true;
     662             : 
     663             :   // The effective address is
     664             :   //     addr(atom(A)) + offset(A)
     665             :   //   - addr(atom(B)) - offset(B)
     666             :   // and the offsets are not relocatable, so the fixup is fully resolved when
     667             :   //  addr(atom(A)) - addr(atom(B)) == 0.
     668        3152 :   const MCSymbol &SA = findAliasedSymbol(SymA);
     669        3152 :   const MCSection &SecA = SA.getSection();
     670        3152 :   const MCSection &SecB = *FB.getParent();
     671             : 
     672        3152 :   if (IsPCRel) {
     673             :     // The simple (Darwin, except on x86_64) way of dealing with this was to
     674             :     // assume that any reference to a temporary symbol *must* be a temporary
     675             :     // symbol in the same atom, unless the sections differ. Therefore, any PCrel
     676             :     // relocation to a temporary symbol (in the same section) is fully
     677             :     // resolved. This also works in conjunction with absolutized .set, which
     678             :     // requires the compiler to use .set to absolutize the differences between
     679             :     // symbols which the compiler knows to be assembly time constants, so we
     680             :     // don't need to worry about considering symbol differences fully resolved.
     681             :     //
     682             :     // If the file isn't using sub-sections-via-symbols, we can make the
     683             :     // same assumptions about any symbol that we normally make about
     684             :     // assembler locals.
     685             : 
     686         996 :     bool hasReliableSymbolDifference = isX86_64();
     687         996 :     if (!hasReliableSymbolDifference) {
     688        1203 :       if (!SA.isInSection() || &SecA != &SecB ||
     689         700 :           (!SA.isTemporary() && FB.getAtom() != SA.getFragment()->getAtom() &&
     690          49 :            Asm.getSubsectionsViaSymbols()))
     691             :         return false;
     692             :       return true;
     693             :     }
     694             :     // For Darwin x86_64, there is one special case when the reference IsPCRel.
     695             :     // If the fragment with the reference does not have a base symbol but meets
     696             :     // the simple way of dealing with this, in that it is a temporary symbol in
     697             :     // the same atom then it is assumed to be fully resolved.  This is needed so
     698             :     // a relocation entry is not created and so the static linker does not
     699             :     // mess up the reference later.
     700         432 :     else if(!FB.getAtom() &&
     701         462 :             SA.isTemporary() && SA.isInSection() && &SecA == &SecB){
     702             :       return true;
     703             :     }
     704             :   }
     705             : 
     706             :   // If they are not in the same section, we can't compute the diff.
     707        2542 :   if (&SecA != &SecB)
     708             :     return false;
     709             : 
     710        2315 :   const MCFragment *FA = SA.getFragment();
     711             : 
     712             :   // Bail if the symbol has no fragment.
     713        2315 :   if (!FA)
     714             :     return false;
     715             : 
     716             :   // If the atoms are the same, they are guaranteed to have the same address.
     717        2315 :   if (FA->getAtom() == FB.getAtom())
     718             :     return true;
     719             : 
     720             :   // Otherwise, we can't prove this is fully resolved.
     721         175 :   return false;
     722             : }
     723             : 
     724         498 : void MachObjectWriter::writeObject(MCAssembler &Asm,
     725             :                                    const MCAsmLayout &Layout) {
     726             :   // Compute symbol table information and bind symbol indices.
     727         498 :   computeSymbolTable(Asm, LocalSymbolData, ExternalSymbolData,
     728             :                      UndefinedSymbolData);
     729             : 
     730         498 :   unsigned NumSections = Asm.size();
     731             :   const MCAssembler::VersionMinInfoType &VersionInfo =
     732         498 :     Layout.getAssembler().getVersionMinInfo();
     733             : 
     734             :   // The section data starts after the header, the segment load command (and
     735             :   // section headers) and the symbol table.
     736         498 :   unsigned NumLoadCommands = 1;
     737         996 :   uint64_t LoadCommandsSize = is64Bit() ?
     738         314 :     sizeof(MachO::segment_command_64) + NumSections * sizeof(MachO::section_64):
     739         682 :     sizeof(MachO::segment_command) + NumSections * sizeof(MachO::section);
     740             : 
     741             :   // Add the deployment target version info load command size, if used.
     742         498 :   if (VersionInfo.Major != 0) {
     743         257 :     ++NumLoadCommands;
     744         257 :     LoadCommandsSize += sizeof(MachO::version_min_command);
     745             :   }
     746             : 
     747             :   // Add the data-in-code load command size, if used.
     748         996 :   unsigned NumDataRegions = Asm.getDataRegions().size();
     749         498 :   if (NumDataRegions) {
     750          15 :     ++NumLoadCommands;
     751          15 :     LoadCommandsSize += sizeof(MachO::linkedit_data_command);
     752             :   }
     753             : 
     754             :   // Add the loh load command size, if used.
     755         498 :   uint64_t LOHRawSize = Asm.getLOHContainer().getEmitSize(*this, Layout);
     756         996 :   uint64_t LOHSize = alignTo(LOHRawSize, is64Bit() ? 8 : 4);
     757         498 :   if (LOHSize) {
     758           1 :     ++NumLoadCommands;
     759           1 :     LoadCommandsSize += sizeof(MachO::linkedit_data_command);
     760             :   }
     761             : 
     762             :   // Add the symbol table load command sizes, if used.
     763        1992 :   unsigned NumSymbols = LocalSymbolData.size() + ExternalSymbolData.size() +
     764         996 :     UndefinedSymbolData.size();
     765         498 :   if (NumSymbols) {
     766         413 :     NumLoadCommands += 2;
     767         413 :     LoadCommandsSize += (sizeof(MachO::symtab_command) +
     768             :                          sizeof(MachO::dysymtab_command));
     769             :   }
     770             : 
     771             :   // Add the linker option load commands sizes.
     772        1997 :   for (const auto &Option : Asm.getLinkerOptions()) {
     773           5 :     ++NumLoadCommands;
     774          10 :     LoadCommandsSize += ComputeLinkerOptionsLoadCommandSize(Option, is64Bit());
     775             :   }
     776             : 
     777             :   // Compute the total size of the section data, as well as its file size and vm
     778             :   // size.
     779         498 :   uint64_t SectionDataStart = (is64Bit() ? sizeof(MachO::mach_header_64) :
     780         498 :                                sizeof(MachO::mach_header)) + LoadCommandsSize;
     781         498 :   uint64_t SectionDataSize = 0;
     782         498 :   uint64_t SectionDataFileSize = 0;
     783         498 :   uint64_t VMSize = 0;
     784        7264 :   for (const MCSection &Sec : Asm) {
     785        2636 :     uint64_t Address = getSectionAddress(&Sec);
     786        2636 :     uint64_t Size = Layout.getSectionAddressSize(&Sec);
     787        2636 :     uint64_t FileSize = Layout.getSectionFileSize(&Sec);
     788        2636 :     FileSize += getPaddingSize(&Sec, Layout);
     789             : 
     790        5272 :     VMSize = std::max(VMSize, Address + Size);
     791             : 
     792        2636 :     if (Sec.isVirtualSection())
     793          36 :       continue;
     794             : 
     795        5200 :     SectionDataSize = std::max(SectionDataSize, Address + Size);
     796        5200 :     SectionDataFileSize = std::max(SectionDataFileSize, Address + FileSize);
     797             :   }
     798             : 
     799             :   // The section data is padded to 4 bytes.
     800             :   //
     801             :   // FIXME: Is this machine dependent?
     802         996 :   unsigned SectionDataPadding = OffsetToAlignment(SectionDataFileSize, 4);
     803         498 :   SectionDataFileSize += SectionDataPadding;
     804             : 
     805             :   // Write the prolog, starting with the header and load command...
     806         498 :   writeHeader(MachO::MH_OBJECT, NumLoadCommands, LoadCommandsSize,
     807         498 :               Asm.getSubsectionsViaSymbols());
     808         498 :   uint32_t Prot =
     809             :       MachO::VM_PROT_READ | MachO::VM_PROT_WRITE | MachO::VM_PROT_EXECUTE;
     810         996 :   writeSegmentLoadCommand("", NumSections, 0, VMSize, SectionDataStart,
     811             :                           SectionDataSize, Prot, Prot);
     812             : 
     813             :   // ... and then the section headers.
     814         498 :   uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize;
     815        7264 :   for (const MCSection &Section : Asm) {
     816        2636 :     const auto &Sec = cast<MCSectionMachO>(Section);
     817        5272 :     std::vector<RelAndSymbol> &Relocs = Relocations[&Sec];
     818        2636 :     unsigned NumRelocs = Relocs.size();
     819        5272 :     uint64_t SectionStart = SectionDataStart + getSectionAddress(&Sec);
     820        2636 :     unsigned Flags = Sec.getTypeAndAttributes();
     821        5272 :     if (Sec.hasInstructions())
     822         342 :       Flags |= MachO::S_ATTR_SOME_INSTRUCTIONS;
     823        5272 :     writeSection(Layout, Sec, getSectionAddress(&Sec), SectionStart, Flags,
     824             :                  RelocTableEnd, NumRelocs);
     825        2636 :     RelocTableEnd += NumRelocs * sizeof(MachO::any_relocation_info);
     826             :   }
     827             : 
     828             :   // Write out the deployment target information, if it's available.
     829         498 :   if (VersionInfo.Major != 0) {
     830             :     assert(VersionInfo.Update < 256 && "unencodable update target version");
     831             :     assert(VersionInfo.Minor < 256 && "unencodable minor target version");
     832             :     assert(VersionInfo.Major < 65536 && "unencodable major target version");
     833         514 :     uint32_t EncodedVersion = VersionInfo.Update | (VersionInfo.Minor << 8) |
     834         257 :       (VersionInfo.Major << 16);
     835             :     MachO::LoadCommandType LCType;
     836         257 :     switch (VersionInfo.Kind) {
     837         236 :     case MCVM_OSXVersionMin:
     838         236 :       LCType = MachO::LC_VERSION_MIN_MACOSX;
     839         236 :       break;
     840          16 :     case MCVM_IOSVersionMin:
     841          16 :       LCType = MachO::LC_VERSION_MIN_IPHONEOS;
     842          16 :       break;
     843           2 :     case MCVM_TvOSVersionMin:
     844           2 :       LCType = MachO::LC_VERSION_MIN_TVOS;
     845           2 :       break;
     846           3 :     case MCVM_WatchOSVersionMin:
     847           3 :       LCType = MachO::LC_VERSION_MIN_WATCHOS;
     848           3 :       break;
     849             :     }
     850         257 :     write32(LCType);
     851         257 :     write32(sizeof(MachO::version_min_command));
     852         257 :     write32(EncodedVersion);
     853         257 :     write32(0);         // reserved.
     854             :   }
     855             : 
     856             :   // Write the data-in-code load command, if used.
     857         498 :   uint64_t DataInCodeTableEnd = RelocTableEnd + NumDataRegions * 8;
     858         498 :   if (NumDataRegions) {
     859          15 :     uint64_t DataRegionsOffset = RelocTableEnd;
     860          15 :     uint64_t DataRegionsSize = NumDataRegions * 8;
     861          15 :     writeLinkeditLoadCommand(MachO::LC_DATA_IN_CODE, DataRegionsOffset,
     862             :                              DataRegionsSize);
     863             :   }
     864             : 
     865             :   // Write the loh load command, if used.
     866         498 :   uint64_t LOHTableEnd = DataInCodeTableEnd + LOHSize;
     867         498 :   if (LOHSize)
     868           1 :     writeLinkeditLoadCommand(MachO::LC_LINKER_OPTIMIZATION_HINT,
     869             :                              DataInCodeTableEnd, LOHSize);
     870             : 
     871             :   // Write the symbol table load command, if used.
     872         498 :   if (NumSymbols) {
     873         413 :     unsigned FirstLocalSymbol = 0;
     874         826 :     unsigned NumLocalSymbols = LocalSymbolData.size();
     875         413 :     unsigned FirstExternalSymbol = FirstLocalSymbol + NumLocalSymbols;
     876         826 :     unsigned NumExternalSymbols = ExternalSymbolData.size();
     877         413 :     unsigned FirstUndefinedSymbol = FirstExternalSymbol + NumExternalSymbols;
     878         826 :     unsigned NumUndefinedSymbols = UndefinedSymbolData.size();
     879         413 :     unsigned NumIndirectSymbols = Asm.indirect_symbol_size();
     880         413 :     unsigned NumSymTabSymbols =
     881             :       NumLocalSymbols + NumExternalSymbols + NumUndefinedSymbols;
     882         413 :     uint64_t IndirectSymbolSize = NumIndirectSymbols * 4;
     883         413 :     uint64_t IndirectSymbolOffset = 0;
     884             : 
     885             :     // If used, the indirect symbols are written after the section data.
     886         413 :     if (NumIndirectSymbols)
     887          16 :       IndirectSymbolOffset = LOHTableEnd;
     888             : 
     889             :     // The symbol table is written after the indirect symbol data.
     890         413 :     uint64_t SymbolTableOffset = LOHTableEnd + IndirectSymbolSize;
     891             : 
     892             :     // The string table is written after symbol table.
     893             :     uint64_t StringTableOffset =
     894         826 :       SymbolTableOffset + NumSymTabSymbols * (is64Bit() ?
     895             :                                               sizeof(MachO::nlist_64) :
     896         413 :                                               sizeof(MachO::nlist));
     897         413 :     writeSymtabLoadCommand(SymbolTableOffset, NumSymTabSymbols,
     898         413 :                            StringTableOffset, StringTable.getSize());
     899             : 
     900         413 :     writeDysymtabLoadCommand(FirstLocalSymbol, NumLocalSymbols,
     901             :                              FirstExternalSymbol, NumExternalSymbols,
     902             :                              FirstUndefinedSymbol, NumUndefinedSymbols,
     903             :                              IndirectSymbolOffset, NumIndirectSymbols);
     904             :   }
     905             : 
     906             :   // Write the linker options load commands.
     907        1997 :   for (const auto &Option : Asm.getLinkerOptions())
     908           5 :     writeLinkerOptionsLoadCommand(Option);
     909             : 
     910             :   // Write the actual section data.
     911        7264 :   for (const MCSection &Sec : Asm) {
     912        2636 :     Asm.writeSectionData(&Sec, Layout);
     913             : 
     914        2636 :     uint64_t Pad = getPaddingSize(&Sec, Layout);
     915        2636 :     WriteZeros(Pad);
     916             :   }
     917             : 
     918             :   // Write the extra padding.
     919         498 :   WriteZeros(SectionDataPadding);
     920             : 
     921             :   // Write the relocation entries.
     922        7264 :   for (const MCSection &Sec : Asm) {
     923             :     // Write the section relocation entries, in reverse order to match 'as'
     924             :     // (approximately, the exact algorithm is more complicated than this).
     925        5272 :     std::vector<RelAndSymbol> &Relocs = Relocations[&Sec];
     926       19048 :     for (const RelAndSymbol &Rel : make_range(Relocs.rbegin(), Relocs.rend())) {
     927        2934 :       write32(Rel.MRE.r_word0);
     928        2934 :       write32(Rel.MRE.r_word1);
     929             :     }
     930             :   }
     931             : 
     932             :   // Write out the data-in-code region payload, if there is one.
     933             :   for (MCAssembler::const_data_region_iterator
     934        1992 :          it = Asm.data_region_begin(), ie = Asm.data_region_end();
     935         545 :          it != ie; ++it) {
     936          47 :     const DataRegionData *Data = &(*it);
     937          47 :     uint64_t Start = getSymbolAddress(*Data->Start, Layout);
     938          47 :     uint64_t End = getSymbolAddress(*Data->End, Layout);
     939             :     DEBUG(dbgs() << "data in code region-- kind: " << Data->Kind
     940             :                  << "  start: " << Start << "(" << Data->Start->getName() << ")"
     941             :                  << "  end: " << End << "(" << Data->End->getName() << ")"
     942             :                  << "  size: " << End - Start
     943             :                  << "\n");
     944          47 :     write32(Start);
     945          47 :     write16(End - Start);
     946          47 :     write16(Data->Kind);
     947             :   }
     948             : 
     949             :   // Write out the loh commands, if there is one.
     950         498 :   if (LOHSize) {
     951             : #ifndef NDEBUG
     952             :     unsigned Start = getStream().tell();
     953             : #endif
     954           2 :     Asm.getLOHContainer().emit(*this, Layout);
     955             :     // Pad to a multiple of the pointer size.
     956           4 :     writeBytes("", OffsetToAlignment(LOHRawSize, is64Bit() ? 8 : 4));
     957             :     assert(getStream().tell() - Start == LOHSize);
     958             :   }
     959             : 
     960             :   // Write the symbol table data, if used.
     961         498 :   if (NumSymbols) {
     962             :     // Write the indirect symbol entries.
     963             :     for (MCAssembler::const_indirect_symbol_iterator
     964         826 :            it = Asm.indirect_symbol_begin(),
     965        1280 :            ie = Asm.indirect_symbol_end(); it != ie; ++it) {
     966             :       // Indirect symbols in the non-lazy symbol pointer section have some
     967             :       // special handling.
     968             :       const MCSectionMachO &Section =
     969          41 :           static_cast<const MCSectionMachO &>(*it->Section);
     970          82 :       if (Section.getType() == MachO::S_NON_LAZY_SYMBOL_POINTERS) {
     971             :         // If this symbol is defined and internal, mark it as such.
     972          60 :         if (it->Symbol->isDefined() && !it->Symbol->isExternal()) {
     973           3 :           uint32_t Flags = MachO::INDIRECT_SYMBOL_LOCAL;
     974           6 :           if (it->Symbol->isAbsolute())
     975           1 :             Flags |= MachO::INDIRECT_SYMBOL_ABS;
     976           3 :           write32(Flags);
     977           3 :           continue;
     978             :         }
     979             :       }
     980             : 
     981          38 :       write32(it->Symbol->getIndex());
     982             :     }
     983             : 
     984             :     // FIXME: Check that offsets match computed ones.
     985             : 
     986             :     // Write the symbol table entries.
     987        2478 :     for (auto *SymbolData :
     988         826 :          {&LocalSymbolData, &ExternalSymbolData, &UndefinedSymbolData})
     989        6453 :       for (MachSymbolData &Entry : *SymbolData)
     990        1497 :         writeNlist(Entry, Layout);
     991             : 
     992             :     // Write the string table.
     993         413 :     StringTable.write(getStream());
     994             :   }
     995         498 : }
     996             : 
     997         527 : MCObjectWriter *llvm::createMachObjectWriter(MCMachObjectTargetWriter *MOTW,
     998             :                                              raw_pwrite_stream &OS,
     999             :                                              bool IsLittleEndian) {
    1000         527 :   return new MachObjectWriter(MOTW, OS, IsLittleEndian);
    1001             : }

Generated by: LCOV version 1.13