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