12df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar//===- lib/MC/MachObjectWriter.cpp - Mach-O File Writer -------------------===//
22df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar//
32df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar//                     The LLVM Compiler Infrastructure
42df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar//
52df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar// This file is distributed under the University of Illinois Open Source
62df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar// License. See LICENSE.TXT for details.
72df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar//
82df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar//===----------------------------------------------------------------------===//
92df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar
10ae5abd595f5442767313a4c8a24008ad19323cebDaniel Dunbar#include "llvm/MC/MCMachObjectWriter.h"
112df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar#include "llvm/ADT/StringMap.h"
122df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar#include "llvm/ADT/Twine.h"
1378c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan Cheng#include "llvm/MC/MCAsmBackend.h"
14207e06ea0446c51cb1d89f6400ec7becc46487f8Daniel Dunbar#include "llvm/MC/MCAsmLayout.h"
15d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCAssembler.h"
162df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar#include "llvm/MC/MCExpr.h"
17f1d0f7781e766df878bec4e7977fa3204374f394Craig Topper#include "llvm/MC/MCFixupKindInfo.h"
18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCMachOSymbolFlags.h"
192df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar#include "llvm/MC/MCObjectWriter.h"
202df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar#include "llvm/MC/MCSectionMachO.h"
212df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar#include "llvm/MC/MCSymbol.h"
222df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar#include "llvm/MC/MCValue.h"
233e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach#include "llvm/Support/Debug.h"
242df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar#include "llvm/Support/ErrorHandling.h"
255510728d28bb1ee04abc32da3d21b7df12948053Charles Davis#include "llvm/Support/MachO.h"
262df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar#include <vector>
272df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbarusing namespace llvm;
282df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar
29dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "mc"
30dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3199cbdde6198623ff014c776743caec2cf48f4840Pedro Artigasvoid MachObjectWriter::reset() {
3299cbdde6198623ff014c776743caec2cf48f4840Pedro Artigas  Relocations.clear();
3399cbdde6198623ff014c776743caec2cf48f4840Pedro Artigas  IndirectSymBase.clear();
3499cbdde6198623ff014c776743caec2cf48f4840Pedro Artigas  StringTable.clear();
3599cbdde6198623ff014c776743caec2cf48f4840Pedro Artigas  LocalSymbolData.clear();
3699cbdde6198623ff014c776743caec2cf48f4840Pedro Artigas  ExternalSymbolData.clear();
3799cbdde6198623ff014c776743caec2cf48f4840Pedro Artigas  UndefinedSymbolData.clear();
3899cbdde6198623ff014c776743caec2cf48f4840Pedro Artigas  MCObjectWriter::reset();
3999cbdde6198623ff014c776743caec2cf48f4840Pedro Artigas}
4099cbdde6198623ff014c776743caec2cf48f4840Pedro Artigas
41ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbachbool MachObjectWriter::
42ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim GrosbachdoesSymbolRequireExternRelocation(const MCSymbolData *SD) {
43e9460ec0577dc82d1fb1f8c92e20f47a3c75abc9Daniel Dunbar  // Undefined symbols are always extern.
44e9460ec0577dc82d1fb1f8c92e20f47a3c75abc9Daniel Dunbar  if (SD->Symbol->isUndefined())
45e9460ec0577dc82d1fb1f8c92e20f47a3c75abc9Daniel Dunbar    return true;
46e9460ec0577dc82d1fb1f8c92e20f47a3c75abc9Daniel Dunbar
47e9460ec0577dc82d1fb1f8c92e20f47a3c75abc9Daniel Dunbar  // References to weak definitions require external relocation entries; the
48e9460ec0577dc82d1fb1f8c92e20f47a3c75abc9Daniel Dunbar  // definition may not always be the one in the same object file.
49e9460ec0577dc82d1fb1f8c92e20f47a3c75abc9Daniel Dunbar  if (SD->getFlags() & SF_WeakDefinition)
50e9460ec0577dc82d1fb1f8c92e20f47a3c75abc9Daniel Dunbar    return true;
51e9460ec0577dc82d1fb1f8c92e20f47a3c75abc9Daniel Dunbar
52e9460ec0577dc82d1fb1f8c92e20f47a3c75abc9Daniel Dunbar  // Otherwise, we can use an internal relocation.
53e9460ec0577dc82d1fb1f8c92e20f47a3c75abc9Daniel Dunbar  return false;
54e9460ec0577dc82d1fb1f8c92e20f47a3c75abc9Daniel Dunbar}
55e9460ec0577dc82d1fb1f8c92e20f47a3c75abc9Daniel Dunbar
56ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbachbool MachObjectWriter::
57ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim GrosbachMachSymbolData::operator<(const MachSymbolData &RHS) const {
58ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbach  return SymbolData->getSymbol().getName() <
59ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbach    RHS.SymbolData->getSymbol().getName();
60ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbach}
61f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng
62ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbachbool MachObjectWriter::isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) {
63ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbach  const MCFixupKindInfo &FKI = Asm.getBackend().getFixupKindInfo(
64ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbach    (MCFixupKind) Kind);
65f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng
66ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbach  return FKI.Flags & MCFixupKindInfo::FKF_IsPCRel;
67ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbach}
68f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng
69ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbachuint64_t MachObjectWriter::getFragmentAddress(const MCFragment *Fragment,
70ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbach                                              const MCAsmLayout &Layout) const {
71ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbach  return getSectionAddress(Fragment->getParent()) +
72ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbach    Layout.getFragmentOffset(Fragment);
73ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbach}
74f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng
75bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendlinguint64_t MachObjectWriter::getSymbolAddress(const MCSymbolData* SD,
76bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                                            const MCAsmLayout &Layout) const {
77bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  const MCSymbol &S = SD->getSymbol();
78f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng
79bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // If this is a variable, then recursively evaluate now.
80bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  if (S.isVariable()) {
8145d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach    if (const MCConstantExpr *C =
8245d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach          dyn_cast<const MCConstantExpr>(S.getVariableValue()))
8345d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach      return C->getValue();
8445d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach
8545d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach
86bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    MCValue Target;
8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (!S.getVariableValue()->EvaluateAsRelocatable(Target, &Layout))
88bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      report_fatal_error("unable to evaluate offset for variable '" +
89bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                         S.getName() + "'");
90f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng
91bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    // Verify that any used symbols are defined.
92bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    if (Target.getSymA() && Target.getSymA()->getSymbol().isUndefined())
93bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      report_fatal_error("unable to evaluate offset to undefined symbol '" +
94bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                         Target.getSymA()->getSymbol().getName() + "'");
95bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    if (Target.getSymB() && Target.getSymB()->getSymbol().isUndefined())
96bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      report_fatal_error("unable to evaluate offset to undefined symbol '" +
97bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                         Target.getSymB()->getSymbol().getName() + "'");
98f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng
99bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    uint64_t Address = Target.getConstant();
100bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    if (Target.getSymA())
101bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      Address += getSymbolAddress(&Layout.getAssembler().getSymbolData(
102bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                                    Target.getSymA()->getSymbol()), Layout);
103bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    if (Target.getSymB())
104bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      Address += getSymbolAddress(&Layout.getAssembler().getSymbolData(
105bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                                    Target.getSymB()->getSymbol()), Layout);
106bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    return Address;
107bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  }
108f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng
109bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  return getSectionAddress(SD->getFragment()->getParent()) +
110bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    Layout.getSymbolOffset(SD);
111bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling}
112f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng
113bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendlinguint64_t MachObjectWriter::getPaddingSize(const MCSectionData *SD,
114bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                                          const MCAsmLayout &Layout) const {
115bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  uint64_t EndAddr = getSectionAddress(SD) + Layout.getSectionAddressSize(SD);
116bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  unsigned Next = SD->getLayoutOrder() + 1;
117bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  if (Next >= Layout.getSectionOrder().size())
118bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    return 0;
119bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
120bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  const MCSectionData &NextSD = *Layout.getSectionOrder()[Next];
121bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  if (NextSD.getSection().isVirtualSection())
122bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    return 0;
123bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  return OffsetToAlignment(EndAddr, NextSD.getAlignment());
124bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling}
125f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng
126bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendlingvoid MachObjectWriter::WriteHeader(unsigned NumLoadCommands,
127bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                                   unsigned LoadCommandsSize,
128bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                                   bool SubsectionsViaSymbols) {
129bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  uint32_t Flags = 0;
130f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng
131bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  if (SubsectionsViaSymbols)
1325510728d28bb1ee04abc32da3d21b7df12948053Charles Davis    Flags |= MachO::MH_SUBSECTIONS_VIA_SYMBOLS;
133bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
134bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // struct mach_header (28 bytes) or
135bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // struct mach_header_64 (32 bytes)
136bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
137bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  uint64_t Start = OS.tell();
138bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  (void) Start;
139bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
1405510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  Write32(is64Bit() ? MachO::MH_MAGIC_64 : MachO::MH_MAGIC);
141bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
142bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(TargetObjectWriter->getCPUType());
143bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(TargetObjectWriter->getCPUSubtype());
144bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
1455510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  Write32(MachO::MH_OBJECT);
146bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(NumLoadCommands);
147bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(LoadCommandsSize);
148bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(Flags);
149bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  if (is64Bit())
150bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    Write32(0); // reserved
151bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
152bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  assert(OS.tell() - Start ==
1535510728d28bb1ee04abc32da3d21b7df12948053Charles Davis         (is64Bit()?sizeof(MachO::mach_header_64): sizeof(MachO::mach_header)));
154bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling}
155bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
156bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling/// WriteSegmentLoadCommand - Write a segment load command.
157bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling///
158c5252da873d547a19069eaf9030fec203f128f66Dmitri Gribenko/// \param NumSections The number of sections in this segment.
159c5252da873d547a19069eaf9030fec203f128f66Dmitri Gribenko/// \param SectionDataSize The total size of the sections.
160bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendlingvoid MachObjectWriter::WriteSegmentLoadCommand(unsigned NumSections,
161bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                                               uint64_t VMSize,
162bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                                               uint64_t SectionDataStartOffset,
163bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                                               uint64_t SectionDataSize) {
164bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // struct segment_command (56 bytes) or
165bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // struct segment_command_64 (72 bytes)
166bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
167bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  uint64_t Start = OS.tell();
168bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  (void) Start;
169bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
170bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  unsigned SegmentLoadCommandSize =
1715510728d28bb1ee04abc32da3d21b7df12948053Charles Davis    is64Bit() ? sizeof(MachO::segment_command_64):
1725510728d28bb1ee04abc32da3d21b7df12948053Charles Davis    sizeof(MachO::segment_command);
1735510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  Write32(is64Bit() ? MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT);
174bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(SegmentLoadCommandSize +
1755510728d28bb1ee04abc32da3d21b7df12948053Charles Davis          NumSections * (is64Bit() ? sizeof(MachO::section_64) :
1765510728d28bb1ee04abc32da3d21b7df12948053Charles Davis                         sizeof(MachO::section)));
177bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
178bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  WriteBytes("", 16);
179bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  if (is64Bit()) {
180bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    Write64(0); // vmaddr
181bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    Write64(VMSize); // vmsize
182bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    Write64(SectionDataStartOffset); // file offset
183bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    Write64(SectionDataSize); // file size
184bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  } else {
185bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    Write32(0); // vmaddr
186bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    Write32(VMSize); // vmsize
187bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    Write32(SectionDataStartOffset); // file offset
188bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    Write32(SectionDataSize); // file size
189f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng  }
190a38c27be0ff5dd35fcd20cfce827f9dbdb24d1eaNick Kledzik  // maxprot
191a38c27be0ff5dd35fcd20cfce827f9dbdb24d1eaNick Kledzik  Write32(MachO::VM_PROT_READ | MachO::VM_PROT_WRITE | MachO::VM_PROT_EXECUTE);
192a38c27be0ff5dd35fcd20cfce827f9dbdb24d1eaNick Kledzik  // initprot
193a38c27be0ff5dd35fcd20cfce827f9dbdb24d1eaNick Kledzik  Write32(MachO::VM_PROT_READ | MachO::VM_PROT_WRITE | MachO::VM_PROT_EXECUTE);
194bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(NumSections);
195bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(0); // flags
196f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng
197bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  assert(OS.tell() - Start == SegmentLoadCommandSize);
198bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling}
1993c3849297bd9b4aedbac52417061e1da779cc412Jim Grosbach
200bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendlingvoid MachObjectWriter::WriteSection(const MCAssembler &Asm,
201bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                                    const MCAsmLayout &Layout,
202bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                                    const MCSectionData &SD,
203bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                                    uint64_t FileOffset,
204bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                                    uint64_t RelocationsStart,
205bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                                    unsigned NumRelocations) {
206bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  uint64_t SectionSize = Layout.getSectionAddressSize(&SD);
207bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
208bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // The offset is unused for virtual sections.
209bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  if (SD.getSection().isVirtualSection()) {
210bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    assert(Layout.getSectionFileSize(&SD) == 0 && "Invalid file size!");
211bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    FileOffset = 0;
212c9ada472c87d262713b0d2df0a225e867533586cEric Christopher  }
2133c3849297bd9b4aedbac52417061e1da779cc412Jim Grosbach
214bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // struct section (68 bytes) or
215bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // struct section_64 (80 bytes)
216bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
217bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  uint64_t Start = OS.tell();
218bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  (void) Start;
219bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
220bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  const MCSectionMachO &Section = cast<MCSectionMachO>(SD.getSection());
221bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  WriteBytes(Section.getSectionName(), 16);
222bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  WriteBytes(Section.getSegmentName(), 16);
223bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  if (is64Bit()) {
224bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    Write64(getSectionAddress(&SD)); // address
225bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    Write64(SectionSize); // size
226bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  } else {
227bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    Write32(getSectionAddress(&SD)); // address
228bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    Write32(SectionSize); // size
229bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  }
230bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(FileOffset);
231bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
232bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  unsigned Flags = Section.getTypeAndAttributes();
233bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  if (SD.hasInstructions())
23436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Flags |= MachO::S_ATTR_SOME_INSTRUCTIONS;
235bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
236bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  assert(isPowerOf2_32(SD.getAlignment()) && "Invalid alignment!");
237bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(Log2_32(SD.getAlignment()));
238bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(NumRelocations ? RelocationsStart : 0);
239bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(NumRelocations);
240bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(Flags);
241bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(IndirectSymBase.lookup(&SD)); // reserved1
242bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(Section.getStubSize()); // reserved2
243bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  if (is64Bit())
244bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    Write32(0); // reserved3
245bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
2465510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  assert(OS.tell() - Start == (is64Bit() ? sizeof(MachO::section_64) :
2475510728d28bb1ee04abc32da3d21b7df12948053Charles Davis                               sizeof(MachO::section)));
248bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling}
2493664564395ede7681fac8888a213ce3bf947bbb3Daniel Dunbar
250bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendlingvoid MachObjectWriter::WriteSymtabLoadCommand(uint32_t SymbolOffset,
251bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                                              uint32_t NumSymbols,
252bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                                              uint32_t StringTableOffset,
253bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                                              uint32_t StringTableSize) {
254bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // struct symtab_command (24 bytes)
255294e67861c9a497f4b7529a410d8817d36354d5aDaniel Dunbar
256bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  uint64_t Start = OS.tell();
257bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  (void) Start;
2583664564395ede7681fac8888a213ce3bf947bbb3Daniel Dunbar
2595510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  Write32(MachO::LC_SYMTAB);
2605510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  Write32(sizeof(MachO::symtab_command));
261bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(SymbolOffset);
262bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(NumSymbols);
263bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(StringTableOffset);
264bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(StringTableSize);
2654010dd72b81b760daaa0361084de6dca8ed86fa1Daniel Dunbar
2665510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  assert(OS.tell() - Start == sizeof(MachO::symtab_command));
267bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling}
268f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng
269bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendlingvoid MachObjectWriter::WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol,
270bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                                                uint32_t NumLocalSymbols,
271bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                                                uint32_t FirstExternalSymbol,
272bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                                                uint32_t NumExternalSymbols,
273bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                                                uint32_t FirstUndefinedSymbol,
274bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                                                uint32_t NumUndefinedSymbols,
275bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                                                uint32_t IndirectSymbolOffset,
276bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                                                uint32_t NumIndirectSymbols) {
277bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // struct dysymtab_command (80 bytes)
278bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
279bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  uint64_t Start = OS.tell();
280bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  (void) Start;
281bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
2825510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  Write32(MachO::LC_DYSYMTAB);
2835510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  Write32(sizeof(MachO::dysymtab_command));
284bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(FirstLocalSymbol);
285bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(NumLocalSymbols);
286bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(FirstExternalSymbol);
287bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(NumExternalSymbols);
288bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(FirstUndefinedSymbol);
289bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(NumUndefinedSymbols);
290bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(0); // tocoff
291bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(0); // ntoc
292bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(0); // modtaboff
293bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(0); // nmodtab
294bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(0); // extrefsymoff
295bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(0); // nextrefsyms
296bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(IndirectSymbolOffset);
297bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(NumIndirectSymbols);
298bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(0); // extreloff
299bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(0); // nextrel
300bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(0); // locreloff
301bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(0); // nlocrel
302bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
3035510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  assert(OS.tell() - Start == sizeof(MachO::dysymtab_command));
304bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling}
305f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng
306cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesMachObjectWriter::MachSymbolData *
307cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesMachObjectWriter::findSymbolData(const MCSymbol &Sym) {
308cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  for (auto &Entry : LocalSymbolData)
309cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (&Entry.SymbolData->getSymbol() == &Sym)
310cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      return &Entry;
311cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
312cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  for (auto &Entry : ExternalSymbolData)
313cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (&Entry.SymbolData->getSymbol() == &Sym)
314cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      return &Entry;
315cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
316cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  for (auto &Entry : UndefinedSymbolData)
317cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (&Entry.SymbolData->getSymbol() == &Sym)
318cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      return &Entry;
319cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
320cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  return nullptr;
321cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
322cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
3233f2ea825bdf8cbe002ac542a5bdd775bd30470c9Bill Wendlingvoid MachObjectWriter::WriteNlist(MachSymbolData &MSD,
3243f2ea825bdf8cbe002ac542a5bdd775bd30470c9Bill Wendling                                  const MCAsmLayout &Layout) {
325bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  MCSymbolData &Data = *MSD.SymbolData;
326cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  const MCSymbol *Symbol = &Data.getSymbol();
327cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  const MCSymbol *AliasedSymbol = &Symbol->AliasedSymbol();
328cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  uint8_t SectionIndex = MSD.SectionIndex;
329bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  uint8_t Type = 0;
330bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  uint16_t Flags = Data.getFlags();
331739b5576adbf991cdcc49df61c1a3de3d63747f6Jim Grosbach  uint64_t Address = 0;
332cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool IsAlias = Symbol != AliasedSymbol;
333cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
334cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  MachSymbolData *AliaseeInfo;
335cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (IsAlias) {
336cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    AliaseeInfo = findSymbolData(*AliasedSymbol);
337cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (AliaseeInfo)
338cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      SectionIndex = AliaseeInfo->SectionIndex;
339cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Symbol = AliasedSymbol;
340cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
341bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
342bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // Set the N_TYPE bits. See <mach-o/nlist.h>.
343bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  //
344bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // FIXME: Are the prebound or indirect fields possible here?
345cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (IsAlias && Symbol->isUndefined())
346cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Type = MachO::N_INDR;
347cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  else if (Symbol->isUndefined())
3485510728d28bb1ee04abc32da3d21b7df12948053Charles Davis    Type = MachO::N_UNDF;
349cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  else if (Symbol->isAbsolute())
3505510728d28bb1ee04abc32da3d21b7df12948053Charles Davis    Type = MachO::N_ABS;
351bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  else
3525510728d28bb1ee04abc32da3d21b7df12948053Charles Davis    Type = MachO::N_SECT;
353bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
354bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // FIXME: Set STAB bits.
355bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
356bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  if (Data.isPrivateExtern())
3575510728d28bb1ee04abc32da3d21b7df12948053Charles Davis    Type |= MachO::N_PEXT;
358bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
359bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // Set external bit.
360cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (Data.isExternal() || (!IsAlias && Symbol->isUndefined()))
3615510728d28bb1ee04abc32da3d21b7df12948053Charles Davis    Type |= MachO::N_EXT;
362bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
363bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // Compute the symbol address.
364cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (IsAlias && Symbol->isUndefined())
365cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Address = AliaseeInfo->StringIndex;
366cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  else if (Symbol->isDefined())
36745d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach    Address = getSymbolAddress(&Data, Layout);
368cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  else if (Data.isCommon()) {
369bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    // Common symbols are encoded with the size in the address
370bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    // field, and their alignment in the flags.
371bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    Address = Data.getCommonSize();
372bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
373bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    // Common alignment is packed into the 'desc' bits.
374bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    if (unsigned Align = Data.getCommonAlignment()) {
375bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      unsigned Log2Size = Log2_32(Align);
376bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      assert((1U << Log2Size) == Align && "Invalid 'common' alignment!");
377bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      if (Log2Size > 15)
378bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling        report_fatal_error("invalid 'common' alignment '" +
379cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                           Twine(Align) + "' for '" + Symbol->getName() + "'",
380a26f4283826894ac00665f9d24fa99cacc5192abJim Grosbach                           false);
381bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      // FIXME: Keep this mask with the SymbolFlags enumeration.
382bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      Flags = (Flags & 0xF0FF) | (Log2Size << 8);
383294e67861c9a497f4b7529a410d8817d36354d5aDaniel Dunbar    }
384bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  }
3854d74305a1f55f458d401a79db4deeed726567195Daniel Dunbar
386cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (Layout.getAssembler().isThumbFunc(Symbol))
387dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Flags |= SF_ThumbFunc;
388dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
389bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // struct nlist (12 bytes)
3904d74305a1f55f458d401a79db4deeed726567195Daniel Dunbar
391bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write32(MSD.StringIndex);
392bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write8(Type);
393cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  Write8(SectionIndex);
3944d74305a1f55f458d401a79db4deeed726567195Daniel Dunbar
395bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // The Mach-O streamer uses the lowest 16-bits of the flags for the 'desc'
396bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // value.
397bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Write16(Flags);
398bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  if (is64Bit())
399bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    Write64(Address);
400bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  else
401bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    Write32(Address);
402bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling}
4034d74305a1f55f458d401a79db4deeed726567195Daniel Dunbar
4043e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbachvoid MachObjectWriter::WriteLinkeditLoadCommand(uint32_t Type,
4053e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach                                                uint32_t DataOffset,
4063e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach                                                uint32_t DataSize) {
4073e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  uint64_t Start = OS.tell();
4083e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  (void) Start;
4093e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach
4103e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  Write32(Type);
4115510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  Write32(sizeof(MachO::linkedit_data_command));
4123e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  Write32(DataOffset);
4133e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  Write32(DataSize);
4143e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach
4155510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  assert(OS.tell() - Start == sizeof(MachO::linkedit_data_command));
4163e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach}
4173e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach
418a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbarstatic unsigned ComputeLinkerOptionsLoadCommandSize(
419849209686f778e5d6fce675bea9a8300aa596d25Daniel Dunbar  const std::vector<std::string> &Options, bool is64Bit)
420a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar{
4215510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  unsigned Size = sizeof(MachO::linker_options_command);
422a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar  for (unsigned i = 0, e = Options.size(); i != e; ++i)
423a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar    Size += Options[i].size() + 1;
424849209686f778e5d6fce675bea9a8300aa596d25Daniel Dunbar  return RoundUpToAlignment(Size, is64Bit ? 8 : 4);
425a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar}
426a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar
427a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbarvoid MachObjectWriter::WriteLinkerOptionsLoadCommand(
428a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar  const std::vector<std::string> &Options)
429a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar{
430849209686f778e5d6fce675bea9a8300aa596d25Daniel Dunbar  unsigned Size = ComputeLinkerOptionsLoadCommandSize(Options, is64Bit());
431a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar  uint64_t Start = OS.tell();
432a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar  (void) Start;
433a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar
4345510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  Write32(MachO::LC_LINKER_OPTIONS);
435a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar  Write32(Size);
436a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar  Write32(Options.size());
4375510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  uint64_t BytesWritten = sizeof(MachO::linker_options_command);
438a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar  for (unsigned i = 0, e = Options.size(); i != e; ++i) {
439a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar    // Write each string, including the null byte.
440a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar    const std::string &Option = Options[i];
441a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar    WriteBytes(Option.c_str(), Option.size() + 1);
442a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar    BytesWritten += Option.size() + 1;
443a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar  }
444a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar
445849209686f778e5d6fce675bea9a8300aa596d25Daniel Dunbar  // Pad to a multiple of the pointer size.
446849209686f778e5d6fce675bea9a8300aa596d25Daniel Dunbar  WriteBytes("", OffsetToAlignment(BytesWritten, is64Bit() ? 8 : 4));
447a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar
448a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar  assert(OS.tell() - Start == Size);
449a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar}
450a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar
4513e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach
452bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendlingvoid MachObjectWriter::RecordRelocation(const MCAssembler &Asm,
453bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                                        const MCAsmLayout &Layout,
454bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                                        const MCFragment *Fragment,
455bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                                        const MCFixup &Fixup,
456bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                                        MCValue Target,
45736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                        bool &IsPCRel,
458bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                                        uint64_t &FixedValue) {
459ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbach  TargetObjectWriter->RecordRelocation(this, Asm, Layout, Fragment, Fixup,
460ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbach                                       Target, FixedValue);
461bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling}
46232c1c5ae5f2bbf0c13bb1aed71384b86ee6b7cacDaniel Dunbar
463bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendlingvoid MachObjectWriter::BindIndirectSymbols(MCAssembler &Asm) {
464bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // This is the point where 'as' creates actual symbols for indirect symbols
465bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // (in the following two passes). It would be easier for us to do this sooner
466bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // when we see the attribute, but that makes getting the order in the symbol
467bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // table much more complicated than it is worth.
468bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  //
469bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // FIXME: Revisit this when the dust settles.
47032c1c5ae5f2bbf0c13bb1aed71384b86ee6b7cacDaniel Dunbar
4714f066b6db8a7a95b206725aecf99a64fd6e9415cKevin Enderby  // Report errors for use of .indirect_symbol not in a symbol pointer section
4724f066b6db8a7a95b206725aecf99a64fd6e9415cKevin Enderby  // or stub section.
4734f066b6db8a7a95b206725aecf99a64fd6e9415cKevin Enderby  for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(),
4744f066b6db8a7a95b206725aecf99a64fd6e9415cKevin Enderby         ie = Asm.indirect_symbol_end(); it != ie; ++it) {
4754f066b6db8a7a95b206725aecf99a64fd6e9415cKevin Enderby    const MCSectionMachO &Section =
4764f066b6db8a7a95b206725aecf99a64fd6e9415cKevin Enderby      cast<MCSectionMachO>(it->SectionData->getSection());
4774f066b6db8a7a95b206725aecf99a64fd6e9415cKevin Enderby
47836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Section.getType() != MachO::S_NON_LAZY_SYMBOL_POINTERS &&
47936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Section.getType() != MachO::S_LAZY_SYMBOL_POINTERS &&
48036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Section.getType() != MachO::S_SYMBOL_STUBS) {
4814f066b6db8a7a95b206725aecf99a64fd6e9415cKevin Enderby	MCSymbol &Symbol = *it->Symbol;
4824f066b6db8a7a95b206725aecf99a64fd6e9415cKevin Enderby	report_fatal_error("indirect symbol '" + Symbol.getName() +
4834f066b6db8a7a95b206725aecf99a64fd6e9415cKevin Enderby                           "' not in a symbol pointer or stub section");
4844f066b6db8a7a95b206725aecf99a64fd6e9415cKevin Enderby    }
4854f066b6db8a7a95b206725aecf99a64fd6e9415cKevin Enderby  }
4864f066b6db8a7a95b206725aecf99a64fd6e9415cKevin Enderby
48736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Bind non-lazy symbol pointers first.
488bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  unsigned IndirectIndex = 0;
489bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(),
490bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling         ie = Asm.indirect_symbol_end(); it != ie; ++it, ++IndirectIndex) {
491bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    const MCSectionMachO &Section =
492bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      cast<MCSectionMachO>(it->SectionData->getSection());
49332c1c5ae5f2bbf0c13bb1aed71384b86ee6b7cacDaniel Dunbar
49436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Section.getType() != MachO::S_NON_LAZY_SYMBOL_POINTERS)
495bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      continue;
496bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
497bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    // Initialize the section indirect symbol base, if necessary.
49805d96f98cbd96dab7f4ea1ea4ebe4285597e7e88Benjamin Kramer    IndirectSymBase.insert(std::make_pair(it->SectionData, IndirectIndex));
499bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
500bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    Asm.getOrCreateSymbolData(*it->Symbol);
5011f3662abba2abdf5a0ab77095834271fcf846579Daniel Dunbar  }
5021f3662abba2abdf5a0ab77095834271fcf846579Daniel Dunbar
503bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // Then lazy symbol pointers and symbol stubs.
504bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  IndirectIndex = 0;
505bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(),
506bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling         ie = Asm.indirect_symbol_end(); it != ie; ++it, ++IndirectIndex) {
507bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    const MCSectionMachO &Section =
508bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      cast<MCSectionMachO>(it->SectionData->getSection());
5092df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar
51036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Section.getType() != MachO::S_LAZY_SYMBOL_POINTERS &&
51136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Section.getType() != MachO::S_SYMBOL_STUBS)
512bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      continue;
513bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
514bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    // Initialize the section indirect symbol base, if necessary.
51505d96f98cbd96dab7f4ea1ea4ebe4285597e7e88Benjamin Kramer    IndirectSymBase.insert(std::make_pair(it->SectionData, IndirectIndex));
5162df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar
517bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    // Set the symbol type to undefined lazy, but only on construction.
5182df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar    //
519bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    // FIXME: Do not hardcode.
520bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    bool Created;
521bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    MCSymbolData &Entry = Asm.getOrCreateSymbolData(*it->Symbol, &Created);
522bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    if (Created)
523bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      Entry.setFlags(Entry.getFlags() | 0x0001);
524bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  }
525bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling}
526bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
527bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling/// ComputeSymbolTable - Compute the symbol table data
528bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling///
529bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling/// \param StringTable [out] - The string table data.
530bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling/// \param StringIndexMap [out] - Map from symbol names to offsets in the
531bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling/// string table.
5323f2ea825bdf8cbe002ac542a5bdd775bd30470c9Bill Wendlingvoid MachObjectWriter::
5333f2ea825bdf8cbe002ac542a5bdd775bd30470c9Bill WendlingComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable,
5343f2ea825bdf8cbe002ac542a5bdd775bd30470c9Bill Wendling                   std::vector<MachSymbolData> &LocalSymbolData,
5353f2ea825bdf8cbe002ac542a5bdd775bd30470c9Bill Wendling                   std::vector<MachSymbolData> &ExternalSymbolData,
5363f2ea825bdf8cbe002ac542a5bdd775bd30470c9Bill Wendling                   std::vector<MachSymbolData> &UndefinedSymbolData) {
537bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // Build section lookup table.
538bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  DenseMap<const MCSection*, uint8_t> SectionIndexMap;
539bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  unsigned Index = 1;
540bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  for (MCAssembler::iterator it = Asm.begin(),
541bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling         ie = Asm.end(); it != ie; ++it, ++Index)
542bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    SectionIndexMap[&it->getSection()] = Index;
543bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  assert(Index <= 256 && "Too many sections!");
544bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
545bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // Index 0 is always the empty string.
546bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  StringMap<uint64_t> StringIndexMap;
547bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  StringTable += '\x00';
548bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
549bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // Build the symbol arrays and the string table, but only for non-local
550bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // symbols.
551bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  //
552bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // The particular order that we collect the symbols and create the string
553bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // table, then sort the symbols is chosen to match 'as'. Even though it
554bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // doesn't matter for correctness, this is important for letting us diff .o
555bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // files.
556dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (MCSymbolData &SD : Asm.symbols()) {
557dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCSymbol &Symbol = SD.getSymbol();
558bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
559bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    // Ignore non-linker visible symbols.
560dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!Asm.isSymbolLinkerVisible(SD.getSymbol()))
561bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      continue;
562bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
563dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!SD.isExternal() && !Symbol.isUndefined())
564bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      continue;
565bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
566bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    uint64_t &Entry = StringIndexMap[Symbol.getName()];
567bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    if (!Entry) {
568bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      Entry = StringTable.size();
569bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      StringTable += Symbol.getName();
570bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      StringTable += '\x00';
5712df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar    }
5722df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar
573bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    MachSymbolData MSD;
574dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MSD.SymbolData = &SD;
575bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    MSD.StringIndex = Entry;
576bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
577bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    if (Symbol.isUndefined()) {
578bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      MSD.SectionIndex = 0;
579bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      UndefinedSymbolData.push_back(MSD);
580bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    } else if (Symbol.isAbsolute()) {
581bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      MSD.SectionIndex = 0;
582bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      ExternalSymbolData.push_back(MSD);
583bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    } else {
584bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection());
585bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      assert(MSD.SectionIndex && "Invalid section index!");
586bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      ExternalSymbolData.push_back(MSD);
5872df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar    }
588bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  }
589bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
590bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // Now add the data for local symbols.
591dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (MCSymbolData &SD : Asm.symbols()) {
592dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCSymbol &Symbol = SD.getSymbol();
593bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
594bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    // Ignore non-linker visible symbols.
595dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!Asm.isSymbolLinkerVisible(SD.getSymbol()))
596bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      continue;
5972df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar
598dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (SD.isExternal() || Symbol.isUndefined())
599bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      continue;
6002df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar
601bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    uint64_t &Entry = StringIndexMap[Symbol.getName()];
602bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    if (!Entry) {
603bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      Entry = StringTable.size();
604bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      StringTable += Symbol.getName();
605bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      StringTable += '\x00';
60685f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola    }
60785f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola
608bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    MachSymbolData MSD;
609dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MSD.SymbolData = &SD;
610bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    MSD.StringIndex = Entry;
611bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
612bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    if (Symbol.isAbsolute()) {
613bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      MSD.SectionIndex = 0;
614bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      LocalSymbolData.push_back(MSD);
615bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    } else {
616bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection());
617bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      assert(MSD.SectionIndex && "Invalid section index!");
618bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      LocalSymbolData.push_back(MSD);
6192df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar    }
620bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  }
6212df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar
622bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // External and undefined symbols are required to be in lexicographic order.
623bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  std::sort(ExternalSymbolData.begin(), ExternalSymbolData.end());
624bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  std::sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end());
625bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
626bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // Set the symbol indices.
627bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  Index = 0;
628bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i)
629bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    LocalSymbolData[i].SymbolData->setIndex(Index++);
630bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i)
631bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    ExternalSymbolData[i].SymbolData->setIndex(Index++);
632bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i)
633bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    UndefinedSymbolData[i].SymbolData->setIndex(Index++);
634bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
635bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // The string table is padded to a multiple of 4.
636bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  while (StringTable.size() % 4)
637bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    StringTable += '\x00';
638bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling}
6392df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar
640bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendlingvoid MachObjectWriter::computeSectionAddresses(const MCAssembler &Asm,
641bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                                               const MCAsmLayout &Layout) {
642bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  uint64_t StartAddress = 0;
643bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  const SmallVectorImpl<MCSectionData*> &Order = Layout.getSectionOrder();
644bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  for (int i = 0, n = Order.size(); i != n ; ++i) {
645bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    const MCSectionData *SD = Order[i];
646bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    StartAddress = RoundUpToAlignment(StartAddress, SD->getAlignment());
647bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    SectionAddress[SD] = StartAddress;
648bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    StartAddress += Layout.getSectionAddressSize(SD);
649bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
650bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    // Explicitly pad the section to match the alignment requirements of the
651bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    // following one. This is for 'gas' compatibility, it shouldn't
652bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    /// strictly be necessary.
653bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    StartAddress += getPaddingSize(SD, Layout);
654bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  }
655bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling}
6562df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar
65745d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbachvoid MachObjectWriter::markAbsoluteVariableSymbols(MCAssembler &Asm,
65845d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach                                                   const MCAsmLayout &Layout) {
659dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (MCSymbolData &SD : Asm.symbols()) {
66045d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach    if (!SD.getSymbol().isVariable())
66145d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach      continue;
66245d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach
66345d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach    // Is the variable is a symbol difference (SA - SB + C) expression,
66445d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach    // and neither symbol is external, mark the variable as absolute.
66545d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach    const MCExpr *Expr = SD.getSymbol().getVariableValue();
66645d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach    MCValue Value;
66736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Expr->EvaluateAsRelocatable(Value, &Layout)) {
66845d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach      if (Value.getSymA() && Value.getSymB())
66945d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach        const_cast<MCSymbol*>(&SD.getSymbol())->setAbsolute();
67045d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach    }
67145d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach  }
67245d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach}
67345d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach
6743f2ea825bdf8cbe002ac542a5bdd775bd30470c9Bill Wendlingvoid MachObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
6753f2ea825bdf8cbe002ac542a5bdd775bd30470c9Bill Wendling                                                const MCAsmLayout &Layout) {
676bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  computeSectionAddresses(Asm, Layout);
6772df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar
678bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // Create symbol data for any indirect symbols.
679bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  BindIndirectSymbols(Asm);
6802df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar
68145d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach  // Mark symbol difference expressions in variables (from .set or = directives)
68245d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach  // as absolute.
68345d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach  markAbsoluteVariableSymbols(Asm, Layout);
68445d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach
685bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // Compute symbol table information and bind symbol indices.
686bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  ComputeSymbolTable(Asm, StringTable, LocalSymbolData, ExternalSymbolData,
687bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                     UndefinedSymbolData);
688bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling}
689bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
6903f2ea825bdf8cbe002ac542a5bdd775bd30470c9Bill Wendlingbool MachObjectWriter::
6913f2ea825bdf8cbe002ac542a5bdd775bd30470c9Bill WendlingIsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
6923f2ea825bdf8cbe002ac542a5bdd775bd30470c9Bill Wendling                                       const MCSymbolData &DataA,
6933f2ea825bdf8cbe002ac542a5bdd775bd30470c9Bill Wendling                                       const MCFragment &FB,
6943f2ea825bdf8cbe002ac542a5bdd775bd30470c9Bill Wendling                                       bool InSet,
6953f2ea825bdf8cbe002ac542a5bdd775bd30470c9Bill Wendling                                       bool IsPCRel) const {
696bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  if (InSet)
697bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    return true;
698bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
699bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // The effective address is
700bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  //     addr(atom(A)) + offset(A)
701bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  //   - addr(atom(B)) - offset(B)
702bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // and the offsets are not relocatable, so the fixup is fully resolved when
703bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  //  addr(atom(A)) - addr(atom(B)) == 0.
704dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MCSymbolData *A_Base = nullptr, *B_Base = nullptr;
705bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
706bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  const MCSymbol &SA = DataA.getSymbol().AliasedSymbol();
707bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  const MCSection &SecA = SA.getSection();
708bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  const MCSection &SecB = FB.getParent()->getSection();
709bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
710bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  if (IsPCRel) {
711bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    // The simple (Darwin, except on x86_64) way of dealing with this was to
712bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    // assume that any reference to a temporary symbol *must* be a temporary
713bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    // symbol in the same atom, unless the sections differ. Therefore, any PCrel
714bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    // relocation to a temporary symbol (in the same section) is fully
715bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    // resolved. This also works in conjunction with absolutized .set, which
716bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    // requires the compiler to use .set to absolutize the differences between
717bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    // symbols which the compiler knows to be assembly time constants, so we
718bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    // don't need to worry about considering symbol differences fully resolved.
719577b09155f9a6fa38e5a7918da9701e120b3642fJim Grosbach    //
720577b09155f9a6fa38e5a7918da9701e120b3642fJim Grosbach    // If the file isn't using sub-sections-via-symbols, we can make the
721577b09155f9a6fa38e5a7918da9701e120b3642fJim Grosbach    // same assumptions about any symbol that we normally make about
722577b09155f9a6fa38e5a7918da9701e120b3642fJim Grosbach    // assembler locals.
723bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
72436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool hasReliableSymbolDifference = isX86_64();
72536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (!hasReliableSymbolDifference) {
7268b9300b972745a6d89b482cbcd4206c01359f7dfJim Grosbach      if (!SA.isInSection() || &SecA != &SecB ||
727ec4ceb797a963b2d24b02d40fad6cc456fac3e5bJim Grosbach          (!SA.isTemporary() &&
728c389af94b66d0c5a917f81617bd07ff0864790a0Jim Grosbach           FB.getAtom() != Asm.getSymbolData(SA).getFragment()->getAtom() &&
729c389af94b66d0c5a917f81617bd07ff0864790a0Jim Grosbach           Asm.getSubsectionsViaSymbols()))
730bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling        return false;
731bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      return true;
7322df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar    }
7335afc19002e7a6b949619a5073d8c746985e8d6f2Kevin Enderby    // For Darwin x86_64, there is one special case when the reference IsPCRel.
7345afc19002e7a6b949619a5073d8c746985e8d6f2Kevin Enderby    // If the fragment with the reference does not have a base symbol but meets
7355afc19002e7a6b949619a5073d8c746985e8d6f2Kevin Enderby    // the simple way of dealing with this, in that it is a temporary symbol in
7365afc19002e7a6b949619a5073d8c746985e8d6f2Kevin Enderby    // the same atom then it is assumed to be fully resolved.  This is needed so
737d1e002a0a3c1c38bae064f3f3cc22b1653d47659Eric Christopher    // a relocation entry is not created and so the static linker does not
7385afc19002e7a6b949619a5073d8c746985e8d6f2Kevin Enderby    // mess up the reference later.
7395afc19002e7a6b949619a5073d8c746985e8d6f2Kevin Enderby    else if(!FB.getAtom() &&
7405afc19002e7a6b949619a5073d8c746985e8d6f2Kevin Enderby            SA.isTemporary() && SA.isInSection() && &SecA == &SecB){
7415afc19002e7a6b949619a5073d8c746985e8d6f2Kevin Enderby      return true;
7425afc19002e7a6b949619a5073d8c746985e8d6f2Kevin Enderby    }
743bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  } else {
744bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    if (!TargetObjectWriter->useAggressiveSymbolFolding())
745bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      return false;
746bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  }
747bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
7480d46ccfc5c2f5d0894e340907f6e58067cce5b03Benjamin Kramer  const MCFragment *FA = Asm.getSymbolData(SA).getFragment();
749bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
7500d46ccfc5c2f5d0894e340907f6e58067cce5b03Benjamin Kramer  // Bail if the symbol has no fragment.
7510d46ccfc5c2f5d0894e340907f6e58067cce5b03Benjamin Kramer  if (!FA)
7520d46ccfc5c2f5d0894e340907f6e58067cce5b03Benjamin Kramer    return false;
7530d46ccfc5c2f5d0894e340907f6e58067cce5b03Benjamin Kramer
7540d46ccfc5c2f5d0894e340907f6e58067cce5b03Benjamin Kramer  A_Base = FA->getAtom();
755bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  if (!A_Base)
756bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    return false;
757bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
758bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  B_Base = FB.getAtom();
759bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  if (!B_Base)
760bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    return false;
761bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
762bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // If the atoms are the same, they are guaranteed to have the same address.
763bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  if (A_Base == B_Base)
764bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    return true;
765bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
766bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // Otherwise, we can't prove this is fully resolved.
767bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  return false;
768bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling}
769bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
770d1e002a0a3c1c38bae064f3f3cc22b1653d47659Eric Christophervoid MachObjectWriter::WriteObject(MCAssembler &Asm,
771f68a26b5d8e06a85edba97702884a74673b60807Jim Grosbach                                   const MCAsmLayout &Layout) {
772bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  unsigned NumSections = Asm.size();
77336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const MCAssembler::VersionMinInfoType &VersionInfo =
77436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Layout.getAssembler().getVersionMinInfo();
775bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
776bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // The section data starts after the header, the segment load command (and
777bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // section headers) and the symbol table.
778bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  unsigned NumLoadCommands = 1;
779bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  uint64_t LoadCommandsSize = is64Bit() ?
7805510728d28bb1ee04abc32da3d21b7df12948053Charles Davis    sizeof(MachO::segment_command_64) + NumSections * sizeof(MachO::section_64):
7815510728d28bb1ee04abc32da3d21b7df12948053Charles Davis    sizeof(MachO::segment_command) + NumSections * sizeof(MachO::section);
782bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
78336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Add the deployment target version info load command size, if used.
78436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (VersionInfo.Major != 0) {
78536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ++NumLoadCommands;
78636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    LoadCommandsSize += sizeof(MachO::version_min_command);
78736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
78836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
789a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar  // Add the data-in-code load command size, if used.
790a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar  unsigned NumDataRegions = Asm.getDataRegions().size();
791a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar  if (NumDataRegions) {
792a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar    ++NumLoadCommands;
7935510728d28bb1ee04abc32da3d21b7df12948053Charles Davis    LoadCommandsSize += sizeof(MachO::linkedit_data_command);
794a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar  }
795a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar
79636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Add the loh load command size, if used.
79736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t LOHRawSize = Asm.getLOHContainer().getEmitSize(*this, Layout);
79836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t LOHSize = RoundUpToAlignment(LOHRawSize, is64Bit() ? 8 : 4);
79936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (LOHSize) {
80036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ++NumLoadCommands;
80136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    LoadCommandsSize += sizeof(MachO::linkedit_data_command);
80236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
80336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
804bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // Add the symbol table load command sizes, if used.
805bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  unsigned NumSymbols = LocalSymbolData.size() + ExternalSymbolData.size() +
806bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    UndefinedSymbolData.size();
807bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  if (NumSymbols) {
808bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    NumLoadCommands += 2;
8095510728d28bb1ee04abc32da3d21b7df12948053Charles Davis    LoadCommandsSize += (sizeof(MachO::symtab_command) +
8105510728d28bb1ee04abc32da3d21b7df12948053Charles Davis                         sizeof(MachO::dysymtab_command));
8112df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar  }
8122df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar
813a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar  // Add the linker option load commands sizes.
814a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar  const std::vector<std::vector<std::string> > &LinkerOptions =
815a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar    Asm.getLinkerOptions();
816a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar  for (unsigned i = 0, e = LinkerOptions.size(); i != e; ++i) {
8173e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach    ++NumLoadCommands;
818849209686f778e5d6fce675bea9a8300aa596d25Daniel Dunbar    LoadCommandsSize += ComputeLinkerOptionsLoadCommandSize(LinkerOptions[i],
819849209686f778e5d6fce675bea9a8300aa596d25Daniel Dunbar                                                            is64Bit());
8203e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  }
821a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar
822bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // Compute the total size of the section data, as well as its file size and vm
823bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // size.
8245510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  uint64_t SectionDataStart = (is64Bit() ? sizeof(MachO::mach_header_64) :
8255510728d28bb1ee04abc32da3d21b7df12948053Charles Davis                               sizeof(MachO::mach_header)) + LoadCommandsSize;
826bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  uint64_t SectionDataSize = 0;
827bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  uint64_t SectionDataFileSize = 0;
828bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  uint64_t VMSize = 0;
829bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  for (MCAssembler::const_iterator it = Asm.begin(),
830bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling         ie = Asm.end(); it != ie; ++it) {
831bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    const MCSectionData &SD = *it;
832bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    uint64_t Address = getSectionAddress(&SD);
833bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    uint64_t Size = Layout.getSectionAddressSize(&SD);
834bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    uint64_t FileSize = Layout.getSectionFileSize(&SD);
835bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    FileSize += getPaddingSize(&SD, Layout);
836bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
837bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    VMSize = std::max(VMSize, Address + Size);
838bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
839bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    if (SD.getSection().isVirtualSection())
840bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      continue;
841bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
842bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    SectionDataSize = std::max(SectionDataSize, Address + Size);
843bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    SectionDataFileSize = std::max(SectionDataFileSize, Address + FileSize);
844bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  }
845bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
846bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // The section data is padded to 4 bytes.
847bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  //
848bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // FIXME: Is this machine dependent?
849bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  unsigned SectionDataPadding = OffsetToAlignment(SectionDataFileSize, 4);
850bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  SectionDataFileSize += SectionDataPadding;
851bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
852bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // Write the prolog, starting with the header and load command...
853bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  WriteHeader(NumLoadCommands, LoadCommandsSize,
854bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling              Asm.getSubsectionsViaSymbols());
855bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  WriteSegmentLoadCommand(NumSections, VMSize,
856bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                          SectionDataStart, SectionDataSize);
857bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
858bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // ... and then the section headers.
859bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize;
860bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  for (MCAssembler::const_iterator it = Asm.begin(),
861bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling         ie = Asm.end(); it != ie; ++it) {
8625510728d28bb1ee04abc32da3d21b7df12948053Charles Davis    std::vector<MachO::any_relocation_info> &Relocs = Relocations[it];
863bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    unsigned NumRelocs = Relocs.size();
864bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    uint64_t SectionStart = SectionDataStart + getSectionAddress(it);
865bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    WriteSection(Asm, Layout, *it, SectionStart, RelocTableEnd, NumRelocs);
8665510728d28bb1ee04abc32da3d21b7df12948053Charles Davis    RelocTableEnd += NumRelocs * sizeof(MachO::any_relocation_info);
867bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  }
868bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
86936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Write out the deployment target information, if it's available.
87036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (VersionInfo.Major != 0) {
87136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(VersionInfo.Update < 256 && "unencodable update target version");
87236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(VersionInfo.Minor < 256 && "unencodable minor target version");
87336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(VersionInfo.Major < 65536 && "unencodable major target version");
87436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint32_t EncodedVersion = VersionInfo.Update | (VersionInfo.Minor << 8) |
87536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      (VersionInfo.Major << 16);
87636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Write32(VersionInfo.Kind == MCVM_OSXVersionMin ? MachO::LC_VERSION_MIN_MACOSX :
87736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            MachO::LC_VERSION_MIN_IPHONEOS);
87836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Write32(sizeof(MachO::version_min_command));
87936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Write32(EncodedVersion);
88036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Write32(0);         // reserved.
88136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
88236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
8833e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  // Write the data-in-code load command, if used.
8843e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  uint64_t DataInCodeTableEnd = RelocTableEnd + NumDataRegions * 8;
8853e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  if (NumDataRegions) {
8863e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach    uint64_t DataRegionsOffset = RelocTableEnd;
8873e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach    uint64_t DataRegionsSize = NumDataRegions * 8;
8885510728d28bb1ee04abc32da3d21b7df12948053Charles Davis    WriteLinkeditLoadCommand(MachO::LC_DATA_IN_CODE, DataRegionsOffset,
8893e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach                             DataRegionsSize);
8903e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  }
8913e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach
89236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Write the loh load command, if used.
89336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t LOHTableEnd = DataInCodeTableEnd + LOHSize;
89436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (LOHSize)
89536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    WriteLinkeditLoadCommand(MachO::LC_LINKER_OPTIMIZATION_HINT,
89636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                             DataInCodeTableEnd, LOHSize);
89736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
898bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // Write the symbol table load command, if used.
899bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  if (NumSymbols) {
900bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    unsigned FirstLocalSymbol = 0;
901bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    unsigned NumLocalSymbols = LocalSymbolData.size();
902bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    unsigned FirstExternalSymbol = FirstLocalSymbol + NumLocalSymbols;
903bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    unsigned NumExternalSymbols = ExternalSymbolData.size();
904bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    unsigned FirstUndefinedSymbol = FirstExternalSymbol + NumExternalSymbols;
905bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    unsigned NumUndefinedSymbols = UndefinedSymbolData.size();
906bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    unsigned NumIndirectSymbols = Asm.indirect_symbol_size();
907bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    unsigned NumSymTabSymbols =
908bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      NumLocalSymbols + NumExternalSymbols + NumUndefinedSymbols;
909bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    uint64_t IndirectSymbolSize = NumIndirectSymbols * 4;
910bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    uint64_t IndirectSymbolOffset = 0;
911bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
912bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    // If used, the indirect symbols are written after the section data.
913bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    if (NumIndirectSymbols)
91436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      IndirectSymbolOffset = LOHTableEnd;
915bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
916bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    // The symbol table is written after the indirect symbol data.
91736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint64_t SymbolTableOffset = LOHTableEnd + IndirectSymbolSize;
918bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
919bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    // The string table is written after symbol table.
920bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    uint64_t StringTableOffset =
9215510728d28bb1ee04abc32da3d21b7df12948053Charles Davis      SymbolTableOffset + NumSymTabSymbols * (is64Bit() ?
9225510728d28bb1ee04abc32da3d21b7df12948053Charles Davis                                              sizeof(MachO::nlist_64) :
9235510728d28bb1ee04abc32da3d21b7df12948053Charles Davis                                              sizeof(MachO::nlist));
924bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    WriteSymtabLoadCommand(SymbolTableOffset, NumSymTabSymbols,
925bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                           StringTableOffset, StringTable.size());
926bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
927bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    WriteDysymtabLoadCommand(FirstLocalSymbol, NumLocalSymbols,
928bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                             FirstExternalSymbol, NumExternalSymbols,
929bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                             FirstUndefinedSymbol, NumUndefinedSymbols,
930bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling                             IndirectSymbolOffset, NumIndirectSymbols);
931bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  }
932bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
933a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar  // Write the linker options load commands.
934a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar  for (unsigned i = 0, e = LinkerOptions.size(); i != e; ++i) {
935a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar    WriteLinkerOptionsLoadCommand(LinkerOptions[i]);
936a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar  }
937a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar
938bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // Write the actual section data.
939bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  for (MCAssembler::const_iterator it = Asm.begin(),
940bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling         ie = Asm.end(); it != ie; ++it) {
941f77d5b14af6b92403b93f7ed249f9023e99028ccJim Grosbach    Asm.writeSectionData(it, Layout);
942bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
943bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    uint64_t Pad = getPaddingSize(it, Layout);
944bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    for (unsigned int i = 0; i < Pad; ++i)
945bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      Write8(0);
946bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  }
947bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
948bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // Write the extra padding.
949bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  WriteZeros(SectionDataPadding);
950bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
951bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // Write the relocation entries.
952bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  for (MCAssembler::const_iterator it = Asm.begin(),
953bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling         ie = Asm.end(); it != ie; ++it) {
954bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    // Write the section relocation entries, in reverse order to match 'as'
955bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    // (approximately, the exact algorithm is more complicated than this).
9565510728d28bb1ee04abc32da3d21b7df12948053Charles Davis    std::vector<MachO::any_relocation_info> &Relocs = Relocations[it];
957bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
9585510728d28bb1ee04abc32da3d21b7df12948053Charles Davis      Write32(Relocs[e - i - 1].r_word0);
9595510728d28bb1ee04abc32da3d21b7df12948053Charles Davis      Write32(Relocs[e - i - 1].r_word1);
960bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    }
961bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  }
962bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
9633e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  // Write out the data-in-code region payload, if there is one.
9643e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  for (MCAssembler::const_data_region_iterator
9653e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach         it = Asm.data_region_begin(), ie = Asm.data_region_end();
9663e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach         it != ie; ++it) {
9673e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach    const DataRegionData *Data = &(*it);
968e75a98320e5d0dff0fc29d2aa39d4c70f70b9da8Jim Grosbach    uint64_t Start =
969e75a98320e5d0dff0fc29d2aa39d4c70f70b9da8Jim Grosbach      getSymbolAddress(&Layout.getAssembler().getSymbolData(*Data->Start),
970e75a98320e5d0dff0fc29d2aa39d4c70f70b9da8Jim Grosbach                       Layout);
971e75a98320e5d0dff0fc29d2aa39d4c70f70b9da8Jim Grosbach    uint64_t End =
972e75a98320e5d0dff0fc29d2aa39d4c70f70b9da8Jim Grosbach      getSymbolAddress(&Layout.getAssembler().getSymbolData(*Data->End),
973e75a98320e5d0dff0fc29d2aa39d4c70f70b9da8Jim Grosbach                       Layout);
9743e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach    DEBUG(dbgs() << "data in code region-- kind: " << Data->Kind
9753e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach                 << "  start: " << Start << "(" << Data->Start->getName() << ")"
9763e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach                 << "  end: " << End << "(" << Data->End->getName() << ")"
9773e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach                 << "  size: " << End - Start
9783e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach                 << "\n");
9793e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach    Write32(Start);
9803e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach    Write16(End - Start);
9813e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach    Write16(Data->Kind);
9823e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  }
9833e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach
98436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Write out the loh commands, if there is one.
98536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (LOHSize) {
98636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#ifndef NDEBUG
98736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned Start = OS.tell();
98836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#endif
98936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Asm.getLOHContainer().Emit(*this, Layout);
99036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Pad to a multiple of the pointer size.
99136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    WriteBytes("", OffsetToAlignment(LOHRawSize, is64Bit() ? 8 : 4));
99236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(OS.tell() - Start == LOHSize);
99336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
99436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
995bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  // Write the symbol table data, if used.
996bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  if (NumSymbols) {
997bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    // Write the indirect symbol entries.
998bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    for (MCAssembler::const_indirect_symbol_iterator
999bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling           it = Asm.indirect_symbol_begin(),
1000bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling           ie = Asm.indirect_symbol_end(); it != ie; ++it) {
100136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Indirect symbols in the non-lazy symbol pointer section have some
1002bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      // special handling.
1003bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      const MCSectionMachO &Section =
1004bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling        static_cast<const MCSectionMachO&>(it->SectionData->getSection());
100536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (Section.getType() == MachO::S_NON_LAZY_SYMBOL_POINTERS) {
1006bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling        // If this symbol is defined and internal, mark it as such.
1007bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling        if (it->Symbol->isDefined() &&
1008bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling            !Asm.getSymbolData(*it->Symbol).isExternal()) {
10095510728d28bb1ee04abc32da3d21b7df12948053Charles Davis          uint32_t Flags = MachO::INDIRECT_SYMBOL_LOCAL;
1010bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling          if (it->Symbol->isAbsolute())
10115510728d28bb1ee04abc32da3d21b7df12948053Charles Davis            Flags |= MachO::INDIRECT_SYMBOL_ABS;
1012bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling          Write32(Flags);
1013bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling          continue;
1014bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling        }
1015bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      }
1016bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
1017bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      Write32(Asm.getSymbolData(*it->Symbol).getIndex());
1018bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    }
1019bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
1020bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    // FIXME: Check that offsets match computed ones.
1021bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
1022bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    // Write the symbol table entries.
1023bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i)
1024bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      WriteNlist(LocalSymbolData[i], Layout);
1025bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i)
1026bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      WriteNlist(ExternalSymbolData[i], Layout);
1027bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i)
1028bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling      WriteNlist(UndefinedSymbolData[i], Layout);
1029bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling
1030bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    // Write the string table.
1031bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling    OS << StringTable.str();
1032bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling  }
10332df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar}
10342df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar
1035ae5abd595f5442767313a4c8a24008ad19323cebDaniel DunbarMCObjectWriter *llvm::createMachObjectWriter(MCMachObjectTargetWriter *MOTW,
10365d05d9769ec98cdee359fd934a56c9455e21232bDaniel Dunbar                                             raw_ostream &OS,
1037115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar                                             bool IsLittleEndian) {
10385d05d9769ec98cdee359fd934a56c9455e21232bDaniel Dunbar  return new MachObjectWriter(MOTW, OS, IsLittleEndian);
10392df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar}
1040