119f066e0e0bebd142ef9e8d50d8232a1d1c117deBill Wendling//===-- MCMachOStreamer.cpp - MachO Streamer ------------------------------===//
2fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar//
3fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar//                     The LLVM Compiler Infrastructure
4fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar//
5fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar// This file is distributed under the University of Illinois Open Source
6fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar// License. See LICENSE.TXT for details.
7fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar//
8fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar//===----------------------------------------------------------------------===//
9fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
10fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar#include "llvm/MC/MCStreamer.h"
1136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/DenseMap.h"
1236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/SmallVector.h"
13d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCAsmBackend.h"
14fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar#include "llvm/MC/MCAssembler.h"
154fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar#include "llvm/MC/MCCodeEmitter.h"
16d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCContext.h"
17d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCDwarf.h"
188c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar#include "llvm/MC/MCExpr.h"
194fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar#include "llvm/MC/MCInst.h"
2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/MC/MCLinkerOptimizationHint.h"
21d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCMachOSymbolFlags.h"
2236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/MC/MCObjectFileInfo.h"
238dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar#include "llvm/MC/MCObjectStreamer.h"
24fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar#include "llvm/MC/MCSection.h"
25b07ce60981368f816af4caa3257e1e4ebf059133Kevin Enderby#include "llvm/MC/MCSectionMachO.h"
26d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCSymbol.h"
27c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby#include "llvm/Support/Dwarf.h"
28fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar#include "llvm/Support/ErrorHandling.h"
294fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar#include "llvm/Support/raw_ostream.h"
30d8036fb0deb7daff7959b0a5407c8a45acb5e603Daniel Dunbar
31fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarusing namespace llvm;
32fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
33fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarnamespace {
34fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
358dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbarclass MCMachOStreamer : public MCObjectStreamer {
366aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbarprivate:
3736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// LabelSections - true if each section change should emit a linker local
3836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// label for use in relocations for assembler local references. Obviates the
3936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// need for local relocations. False by default.
4036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool LabelSections;
4136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
4236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// HasSectionLabel - map of which sections have already had a non-local
4336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// label emitted to them. Used so we don't emit extraneous linker local
4436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// labels in the middle of the section.
4536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DenseMap<const MCSection*, bool> HasSectionLabel;
4636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
4736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &STI) override;
482ac0c453b2de1029f35d9ccb933c1ef303be00a2Daniel Dunbar
493e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  void EmitDataRegion(DataRegionData::KindTy Kind);
503e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  void EmitDataRegionEnd();
5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
52fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarpublic:
535da3665cc501ed8928e63678254357214ec0b9ebChandler Carruth  MCMachOStreamer(MCContext &Context, MCAsmBackend &MAB, raw_ostream &OS,
5436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                  MCCodeEmitter *Emitter, bool label)
5536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      : MCObjectStreamer(Context, MAB, OS, Emitter),
5636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        LabelSections(label) {}
57ac2884a717daf3ad2aa8425320795d661e8a980bDaniel Dunbar
58fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  /// @name MCStreamer Interface
59fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  /// @{
60fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
6136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void ChangeSection(const MCSection *Sect, const MCExpr *Subsect) override;
6236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitLabel(MCSymbol *Symbol) override;
6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol) override;
6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
6536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitLinkerOptions(ArrayRef<std::string> Options) override;
6636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitDataRegion(MCDataRegionType Kind) override;
6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitVersionMin(MCVersionMinType Kind, unsigned Major,
6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                      unsigned Minor, unsigned Update) override;
6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitThumbFunc(MCSymbol *Func) override;
7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
7336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                        unsigned ByteAlignment) override;
7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void BeginCOFFSymbolDef(const MCSymbol *Symbol) override {
75858143816d43e58b17bfd11cb1b57afbd7f0f893Craig Topper    llvm_unreachable("macho doesn't support this directive");
76b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner  }
7736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitCOFFSymbolStorageClass(int StorageClass) override {
78858143816d43e58b17bfd11cb1b57afbd7f0f893Craig Topper    llvm_unreachable("macho doesn't support this directive");
79b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner  }
8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitCOFFSymbolType(int Type) override {
81858143816d43e58b17bfd11cb1b57afbd7f0f893Craig Topper    llvm_unreachable("macho doesn't support this directive");
82b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner  }
8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EndCOFFSymbolDef() override {
84858143816d43e58b17bfd11cb1b57afbd7f0f893Craig Topper    llvm_unreachable("macho doesn't support this directive");
85b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner  }
8636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) override {
87858143816d43e58b17bfd11cb1b57afbd7f0f893Craig Topper    llvm_unreachable("macho doesn't support this directive");
8899328add833807f12a4950c7de29fb2a5df04703Chris Lattner  }
8936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                             unsigned ByteAlignment) override;
91dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = nullptr,
9236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                    uint64_t Size = 0, unsigned ByteAlignment = 0) override;
93011c3f110bca748db66e437924f936a62f1969bfEric Christopher  virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                      uint64_t Size, unsigned ByteAlignment = 0) override;
952ac0c453b2de1029f35d9ccb933c1ef303be00a2Daniel Dunbar
9636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitFileDirective(StringRef Filename) override {
9796749678c9d4cf73d8cbc108a2f2f4872e4e4413Daniel Dunbar    // FIXME: Just ignore the .file; it isn't important enough to fail the
9896749678c9d4cf73d8cbc108a2f2f4872e4e4413Daniel Dunbar    // entire assembly.
9996749678c9d4cf73d8cbc108a2f2f4872e4e4413Daniel Dunbar
100c7ce3e4f42219003f30382be17d966cb2dfb4e71Rafael Espindola    // report_fatal_error("unsupported directive: '.file'");
101c7ce3e4f42219003f30382be17d966cb2dfb4e71Rafael Espindola  }
102c7ce3e4f42219003f30382be17d966cb2dfb4e71Rafael Espindola
10336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitIdent(StringRef IdentString) override {
104c7ce3e4f42219003f30382be17d966cb2dfb4e71Rafael Espindola    llvm_unreachable("macho doesn't support this directive");
105a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner  }
1062ac0c453b2de1029f35d9ccb933c1ef303be00a2Daniel Dunbar
10736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override {
10836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    getAssembler().getLOHContainer().addDirective(Kind, Args);
10936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
11036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
11136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void FinishImpl() override;
112fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar};
113fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
114fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} // end anonymous namespace.
115fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
11636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MCMachOStreamer::ChangeSection(const MCSection *Section,
11736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                    const MCExpr *Subsection) {
11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Change the section normally.
11936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCObjectStreamer::ChangeSection(Section, Subsection);
12036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Output a linker-local symbol so we don't need section-relative local
12136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // relocations. The linker hates us when we do that.
12236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (LabelSections && !HasSectionLabel[Section]) {
12336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MCSymbol *Label = getContext().CreateLinkerPrivateTempSymbol();
12436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    EmitLabel(Label);
12536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    HasSectionLabel[Section] = true;
12636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
127d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola}
128d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola
1298bca4106dfc2945723251db10e340183f3e372ddRafael Espindolavoid MCMachOStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
1308bca4106dfc2945723251db10e340183f3e372ddRafael Espindola                                          MCSymbol *EHSymbol) {
1318bca4106dfc2945723251db10e340183f3e372ddRafael Espindola  MCSymbolData &SD =
1328bca4106dfc2945723251db10e340183f3e372ddRafael Espindola    getAssembler().getOrCreateSymbolData(*Symbol);
1338bca4106dfc2945723251db10e340183f3e372ddRafael Espindola  if (SD.isExternal())
1348bca4106dfc2945723251db10e340183f3e372ddRafael Espindola    EmitSymbolAttribute(EHSymbol, MCSA_Global);
1358bca4106dfc2945723251db10e340183f3e372ddRafael Espindola  if (SD.getFlags() & SF_WeakDefinition)
1368bca4106dfc2945723251db10e340183f3e372ddRafael Espindola    EmitSymbolAttribute(EHSymbol, MCSA_WeakDefinition);
13797f7f4e43d2df00253b794d936be65d2afa78716Rafael Espindola  if (SD.isPrivateExtern())
13897f7f4e43d2df00253b794d936be65d2afa78716Rafael Espindola    EmitSymbolAttribute(EHSymbol, MCSA_PrivateExtern);
1398bca4106dfc2945723251db10e340183f3e372ddRafael Espindola}
1408bca4106dfc2945723251db10e340183f3e372ddRafael Espindola
141fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitLabel(MCSymbol *Symbol) {
142ba210243ef7d325ef6954d459091edf580a241f9Rafael Espindola  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
143ba210243ef7d325ef6954d459091edf580a241f9Rafael Espindola
144ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola  // isSymbolLinkerVisible uses the section.
1455cc319a42a914b24b164a94d9a563c728a7a4026Richard Mitton  AssignSection(Symbol, getCurrentSection().first);
146a86de1050889b61df2cd42cdc2acc5f9796b7f0cDaniel Dunbar  // We have to create a new fragment if this is an atom defining symbol,
147a86de1050889b61df2cd42cdc2acc5f9796b7f0cDaniel Dunbar  // fragments cannot span atoms.
148ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola  if (getAssembler().isSymbolLinkerVisible(*Symbol))
149df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne    insert(new MCDataFragment());
150071f73db4a0c3f7f00ef14d38af17f3c8d69827aDaniel Dunbar
151ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola  MCObjectStreamer::EmitLabel(Symbol);
1526aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar
153ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola  MCSymbolData &SD = getAssembler().getSymbolData(*Symbol);
154b18d2dd115d8ff3fd75bbaa90849473266236dc3Daniel Dunbar  // This causes the reference type flag to be cleared. Darwin 'as' was "trying"
155b18d2dd115d8ff3fd75bbaa90849473266236dc3Daniel Dunbar  // to clear the weak reference and weak definition bits too, but the
156b18d2dd115d8ff3fd75bbaa90849473266236dc3Daniel Dunbar  // implementation was buggy. For now we just try to match 'as', for
157b18d2dd115d8ff3fd75bbaa90849473266236dc3Daniel Dunbar  // diffability.
158b18d2dd115d8ff3fd75bbaa90849473266236dc3Daniel Dunbar  //
159b18d2dd115d8ff3fd75bbaa90849473266236dc3Daniel Dunbar  // FIXME: Cleanup this code, these bits should be emitted based on semantic
160b18d2dd115d8ff3fd75bbaa90849473266236dc3Daniel Dunbar  // properties, not on the order of definition, etc.
161b18d2dd115d8ff3fd75bbaa90849473266236dc3Daniel Dunbar  SD.setFlags(SD.getFlags() & ~SF_ReferenceTypeMask);
162fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
163fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
1643e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbachvoid MCMachOStreamer::EmitDataRegion(DataRegionData::KindTy Kind) {
165b4316028b3978e65cc2b97042292637857dfad49Jim Grosbach  if (!getAssembler().getBackend().hasDataInCodeSupport())
166b4316028b3978e65cc2b97042292637857dfad49Jim Grosbach    return;
1673e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  // Create a temporary label to mark the start of the data region.
1683e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  MCSymbol *Start = getContext().CreateTempSymbol();
1693e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  EmitLabel(Start);
1703e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  // Record the region for the object writer to use.
171dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  DataRegionData Data = { Kind, Start, nullptr };
1723e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  std::vector<DataRegionData> &Regions = getAssembler().getDataRegions();
1733e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  Regions.push_back(Data);
1743e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach}
1753e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach
1763e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbachvoid MCMachOStreamer::EmitDataRegionEnd() {
177b4316028b3978e65cc2b97042292637857dfad49Jim Grosbach  if (!getAssembler().getBackend().hasDataInCodeSupport())
178b4316028b3978e65cc2b97042292637857dfad49Jim Grosbach    return;
1793e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  std::vector<DataRegionData> &Regions = getAssembler().getDataRegions();
1803e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  assert(Regions.size() && "Mismatched .end_data_region!");
1813e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  DataRegionData &Data = Regions.back();
182dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(!Data.End && "Mismatched .end_data_region!");
1833e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  // Create a temporary label to mark the end of the data region.
1843e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  Data.End = getContext().CreateTempSymbol();
1853e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  EmitLabel(Data.End);
1863e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach}
1873e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach
188a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattnervoid MCMachOStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
1895be6d2af38c29e3653998978345220974cc40c01Jim Grosbach  // Let the target do whatever target specific stuff it needs to do.
190ec3433852dd11e8ff60c9610b4c84468e5935f2bJim Grosbach  getAssembler().getBackend().handleAssemblerFlag(Flag);
1915be6d2af38c29e3653998978345220974cc40c01Jim Grosbach  // Do any generic stuff we need to do.
1926009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar  switch (Flag) {
193ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach  case MCAF_SyntaxUnified: return; // no-op here.
194bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  case MCAF_Code16: return; // Change parsing mode; no-op here.
195bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  case MCAF_Code32: return; // Change parsing mode; no-op here.
196bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  case MCAF_Code64: return; // Change parsing mode; no-op here.
197a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner  case MCAF_SubsectionsViaSymbols:
1988dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar    getAssembler().setSubsectionsViaSymbols(true);
1998c3eaf46a1fb69004723ce78aaa82965d6474175Daniel Dunbar    return;
2006009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar  }
201fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
202fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
203a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbarvoid MCMachOStreamer::EmitLinkerOptions(ArrayRef<std::string> Options) {
204a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar  getAssembler().getLinkerOptions().push_back(Options);
205a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar}
206a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar
2073e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbachvoid MCMachOStreamer::EmitDataRegion(MCDataRegionType Kind) {
2083e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  switch (Kind) {
2093e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  case MCDR_DataRegion:
2103e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach    EmitDataRegion(DataRegionData::Data);
2113e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach    return;
2123e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  case MCDR_DataRegionJT8:
2133e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach    EmitDataRegion(DataRegionData::JumpTable8);
2143e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach    return;
2153e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  case MCDR_DataRegionJT16:
2163e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach    EmitDataRegion(DataRegionData::JumpTable16);
2173e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach    return;
2183e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  case MCDR_DataRegionJT32:
2193e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach    EmitDataRegion(DataRegionData::JumpTable32);
2203e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach    return;
2213e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  case MCDR_DataRegionEnd:
2223e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach    EmitDataRegionEnd();
2233e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach    return;
2243e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  }
2253e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach}
2263e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach
22736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MCMachOStreamer::EmitVersionMin(MCVersionMinType Kind, unsigned Major,
22836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                     unsigned Minor, unsigned Update) {
22936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  getAssembler().setVersionMinInfo(Kind, Major, Minor, Update);
23036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
23136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
232b2624eda5ad0ead99ec5ab7ead47b586c96d1109Daniel Dunbarvoid MCMachOStreamer::EmitThumbFunc(MCSymbol *Symbol) {
233475002078848d102b6577fe7283464c039b38af6Jim Grosbach  // Remember that the function is a thumb function. Fixup and relocation
234475002078848d102b6577fe7283464c039b38af6Jim Grosbach  // values will need adjusted.
235b2624eda5ad0ead99ec5ab7ead47b586c96d1109Daniel Dunbar  getAssembler().setIsThumbFunc(Symbol);
236ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach}
237ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach
2381c9cd021c8999d9c2c0786dff074d1e75bbd0eb2Saleem Abdulrasoolbool MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
239a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner                                          MCSymbolAttr Attribute) {
2400c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar  // Indirect symbols are handled differently, to match how 'as' handles
2410c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar  // them. This makes writing matching .o files easier.
242a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner  if (Attribute == MCSA_IndirectSymbol) {
243ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar    // Note that we intentionally cannot use the symbol data here; this is
244ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar    // important for matching the string table that 'as' generates.
2450c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar    IndirectSymbolData ISD;
2460c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar    ISD.Symbol = Symbol;
24783b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar    ISD.SectionData = getCurrentSectionData();
2488dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar    getAssembler().getIndirectSymbols().push_back(ISD);
2491c9cd021c8999d9c2c0786dff074d1e75bbd0eb2Saleem Abdulrasool    return true;
2500c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar  }
2510c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar
2526aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  // Adding a symbol attribute always introduces the symbol, note that an
25346836a783ab29f9cb49655d8b9cb8f5538a626feDaniel Dunbar  // important side effect of calling getOrCreateSymbolData here is to register
25446836a783ab29f9cb49655d8b9cb8f5538a626feDaniel Dunbar  // the symbol with the assembler.
2558dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
2566aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar
2576aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  // The implementation of symbol attributes is designed to match 'as', but it
2586aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  // leaves much to desired. It doesn't really make sense to arbitrarily add and
2596aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  // remove flags, but 'as' allows this (in particular, see .desc).
2606aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  //
2616aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  // In the future it might be worth trying to make these operations more well
2626aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  // defined.
2633edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar  switch (Attribute) {
264a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner  case MCSA_Invalid:
265ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner  case MCSA_ELF_TypeFunction:
266ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner  case MCSA_ELF_TypeIndFunction:
267ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner  case MCSA_ELF_TypeObject:
268ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner  case MCSA_ELF_TypeTLS:
269ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner  case MCSA_ELF_TypeCommon:
270ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner  case MCSA_ELF_TypeNoType:
271e13a0ff8ac6c86a04397801061e1a702d4e0eab1Rafael Espindola  case MCSA_ELF_TypeGnuUniqueObject:
272a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner  case MCSA_Hidden:
2738bcf9496d0d372245776a4eb2f4757335b4de0e1Chandler Carruth  case MCSA_IndirectSymbol:
274a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner  case MCSA_Internal:
275a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner  case MCSA_Protected:
276a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner  case MCSA_Weak:
277a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner  case MCSA_Local:
2781c9cd021c8999d9c2c0786dff074d1e75bbd0eb2Saleem Abdulrasool    return false;
2793edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar
280a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner  case MCSA_Global:
2818f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar    SD.setExternal(true);
282b18d2dd115d8ff3fd75bbaa90849473266236dc3Daniel Dunbar    // This effectively clears the undefined lazy bit, in Darwin 'as', although
283b18d2dd115d8ff3fd75bbaa90849473266236dc3Daniel Dunbar    // it isn't very consistent because it implements this as part of symbol
284b18d2dd115d8ff3fd75bbaa90849473266236dc3Daniel Dunbar    // lookup.
285b18d2dd115d8ff3fd75bbaa90849473266236dc3Daniel Dunbar    //
286b18d2dd115d8ff3fd75bbaa90849473266236dc3Daniel Dunbar    // FIXME: Cleanup this code, these bits should be emitted based on semantic
287b18d2dd115d8ff3fd75bbaa90849473266236dc3Daniel Dunbar    // properties, not on the order of definition, etc.
288b18d2dd115d8ff3fd75bbaa90849473266236dc3Daniel Dunbar    SD.setFlags(SD.getFlags() & ~SF_ReferenceTypeUndefinedLazy);
2893edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar    break;
2906aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar
291a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner  case MCSA_LazyReference:
2926aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    // FIXME: This requires -dynamic.
2936aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SD.setFlags(SD.getFlags() | SF_NoDeadStrip);
2946aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    if (Symbol->isUndefined())
2956aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar      SD.setFlags(SD.getFlags() | SF_ReferenceTypeUndefinedLazy);
2966aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    break;
2976aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar
2986aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    // Since .reference sets the no dead strip bit, it is equivalent to
2996aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    // .no_dead_strip in practice.
300a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner  case MCSA_Reference:
301a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner  case MCSA_NoDeadStrip:
3026aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SD.setFlags(SD.getFlags() | SF_NoDeadStrip);
3036aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    break;
3046aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar
305e8e98d7f2eaa0613442ce21ab6a040c0f04f5b4dKevin Enderby  case MCSA_SymbolResolver:
306e8e98d7f2eaa0613442ce21ab6a040c0f04f5b4dKevin Enderby    SD.setFlags(SD.getFlags() | SF_SymbolResolver);
307e8e98d7f2eaa0613442ce21ab6a040c0f04f5b4dKevin Enderby    break;
308e8e98d7f2eaa0613442ce21ab6a040c0f04f5b4dKevin Enderby
309a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner  case MCSA_PrivateExtern:
3106aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SD.setExternal(true);
3116aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SD.setPrivateExtern(true);
3126aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    break;
3136aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar
314a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner  case MCSA_WeakReference:
3156aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    // FIXME: This requires -dynamic.
3166aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    if (Symbol->isUndefined())
3176aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar      SD.setFlags(SD.getFlags() | SF_WeakReference);
3186aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    break;
3196aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar
320a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner  case MCSA_WeakDefinition:
3216aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    // FIXME: 'as' enforces that this is defined and global. The manual claims
3226aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    // it has to be in a coalesced section, but this isn't enforced.
3236aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SD.setFlags(SD.getFlags() | SF_WeakDefinition);
3246aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    break;
325f59cac5ed36360b4c462781051f996b3499d7e0fKevin Enderby
326f59cac5ed36360b4c462781051f996b3499d7e0fKevin Enderby  case MCSA_WeakDefAutoPrivate:
327f59cac5ed36360b4c462781051f996b3499d7e0fKevin Enderby    SD.setFlags(SD.getFlags() | SF_WeakDefinition | SF_WeakReference);
328f59cac5ed36360b4c462781051f996b3499d7e0fKevin Enderby    break;
3293edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar  }
3301c9cd021c8999d9c2c0786dff074d1e75bbd0eb2Saleem Abdulrasool
3311c9cd021c8999d9c2c0786dff074d1e75bbd0eb2Saleem Abdulrasool  return true;
332fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
333fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
334fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
3356aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  // Encode the 'desc' value into the lowest implementation defined bits.
3362ac0c453b2de1029f35d9ccb933c1ef303be00a2Daniel Dunbar  assert(DescValue == (DescValue & SF_DescFlagsMask) &&
3376aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar         "Invalid .desc value!");
3388dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar  getAssembler().getOrCreateSymbolData(*Symbol).setFlags(
3398dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar    DescValue & SF_DescFlagsMask);
340fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
341fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
3429eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattnervoid MCMachOStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
3437092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar                                       unsigned ByteAlignment) {
3448f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar  // FIXME: Darwin 'as' does appear to allow redef of a .comm by itself.
3458f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
3468f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar
347dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  AssignSection(Symbol, nullptr);
3485cc319a42a914b24b164a94d9a563c728a7a4026Richard Mitton
3498dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
3508f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar  SD.setExternal(true);
3517092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar  SD.setCommon(Size, ByteAlignment);
352fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
353fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
35439646d96e76aea5d20bffb386233a0dbb5932a21Benjamin Kramervoid MCMachOStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
35539646d96e76aea5d20bffb386233a0dbb5932a21Benjamin Kramer                                            unsigned ByteAlignment) {
35639646d96e76aea5d20bffb386233a0dbb5932a21Benjamin Kramer  // '.lcomm' is equivalent to '.zerofill'.
35736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return EmitZerofill(getContext().getObjectFileInfo()->getDataBSSSection(),
35839646d96e76aea5d20bffb386233a0dbb5932a21Benjamin Kramer                      Symbol, Size, ByteAlignment);
35939646d96e76aea5d20bffb386233a0dbb5932a21Benjamin Kramer}
36039646d96e76aea5d20bffb386233a0dbb5932a21Benjamin Kramer
3618751b94ffbd9c49df8949a37f78d6bd0be87b256Daniel Dunbarvoid MCMachOStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
362c90a1fcf9f44858b20e0f5f7e0b98049aec7a1e0Evan Cheng                                   uint64_t Size, unsigned ByteAlignment) {
3638dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar  MCSectionData &SectData = getAssembler().getOrCreateSectionData(*Section);
364d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar
365d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar  // The symbol may not be present, which only creates the section.
366d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar  if (!Symbol)
367d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar    return;
368d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar
369189f7983fb300357712689733f65dde9e3658a14Eric Christopher  // On darwin all virtual sections have zerofill type.
370189f7983fb300357712689733f65dde9e3658a14Eric Christopher  assert(Section->isVirtualSection() && "Section does not have zerofill type!");
371d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar
372d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
373d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar
3748dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
375d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar
376e73d49eda2cb4fc30b52c4a241acf69c8af98302Daniel Dunbar  // Emit an align fragment if necessary.
377e73d49eda2cb4fc30b52c4a241acf69c8af98302Daniel Dunbar  if (ByteAlignment != 1)
3781c15413ebc8f4a35545a381a789a718627396d03Daniel Dunbar    new MCAlignFragment(ByteAlignment, 0, 0, ByteAlignment, &SectData);
379e73d49eda2cb4fc30b52c4a241acf69c8af98302Daniel Dunbar
3804e544870c4c3f81b150e4c3b38a18d629d706b74Daniel Dunbar  MCFragment *F = new MCFillFragment(0, 0, Size, &SectData);
381d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar  SD.setFragment(F);
382d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar
3835cc319a42a914b24b164a94d9a563c728a7a4026Richard Mitton  AssignSection(Symbol, Section);
384d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar
385d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar  // Update the maximum alignment on the zero fill section if necessary.
386d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar  if (ByteAlignment > SectData.getAlignment())
387d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar    SectData.setAlignment(ByteAlignment);
388fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
389fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
390070c1abbc9b78fd8eef9365c5e776a13b64b9631Eric Christopher// This should always be called with the thread local bss section.  Like the
391070c1abbc9b78fd8eef9365c5e776a13b64b9631Eric Christopher// .zerofill directive this doesn't actually switch sections on us.
392011c3f110bca748db66e437924f936a62f1969bfEric Christophervoid MCMachOStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
393011c3f110bca748db66e437924f936a62f1969bfEric Christopher                                     uint64_t Size, unsigned ByteAlignment) {
394011c3f110bca748db66e437924f936a62f1969bfEric Christopher  EmitZerofill(Section, Symbol, Size, ByteAlignment);
395011c3f110bca748db66e437924f936a62f1969bfEric Christopher  return;
396482eba054ab3543ee0e1f453d3d6441092f4b76dEric Christopher}
397482eba054ab3543ee0e1f453d3d6441092f4b76dEric Christopher
39836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MCMachOStreamer::EmitInstToData(const MCInst &Inst,
39936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                     const MCSubtargetInfo &STI) {
4002ac0c453b2de1029f35d9ccb933c1ef303be00a2Daniel Dunbar  MCDataFragment *DF = getOrCreateDataFragment();
4013f4dcd92daef80f87919507b6baf2a97d4bfaa2eDaniel Dunbar
40273c557458c0e28899f37c557bcaf36c2b6701260Daniel Dunbar  SmallVector<MCFixup, 4> Fixups;
4034fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar  SmallString<256> Code;
4044fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar  raw_svector_ostream VecOS(Code);
40536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups, STI);
406f6346769b344f9b134f0661e8bd2b4245f6490eaDaniel Dunbar  VecOS.flush();
407f6346769b344f9b134f0661e8bd2b4245f6490eaDaniel Dunbar
4082ac0c453b2de1029f35d9ccb933c1ef303be00a2Daniel Dunbar  // Add the fixups and data.
4092ac0c453b2de1029f35d9ccb933c1ef303be00a2Daniel Dunbar  for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
4102ac0c453b2de1029f35d9ccb933c1ef303be00a2Daniel Dunbar    Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
41164d9a3233476553fc950f0f2fc6a2cdd2a4c05cfEli Bendersky    DF->getFixups().push_back(Fixups[i]);
4122ac0c453b2de1029f35d9ccb933c1ef303be00a2Daniel Dunbar  }
4132ac0c453b2de1029f35d9ccb933c1ef303be00a2Daniel Dunbar  DF->getContents().append(Code.begin(), Code.end());
4142ac0c453b2de1029f35d9ccb933c1ef303be00a2Daniel Dunbar}
4152ac0c453b2de1029f35d9ccb933c1ef303be00a2Daniel Dunbar
41699b4237c1647156f0e1d3d7e03efdab23ed79778Rafael Espindolavoid MCMachOStreamer::FinishImpl() {
417dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  EmitFrames(&getAssembler().getBackend());
418450a5a120789b67b27f92631e0acaf754ee99d9eRafael Espindola
419a86de1050889b61df2cd42cdc2acc5f9796b7f0cDaniel Dunbar  // We have to set the fragment atom associations so we can relax properly for
420a86de1050889b61df2cd42cdc2acc5f9796b7f0cDaniel Dunbar  // Mach-O.
421a86de1050889b61df2cd42cdc2acc5f9796b7f0cDaniel Dunbar
422a86de1050889b61df2cd42cdc2acc5f9796b7f0cDaniel Dunbar  // First, scan the symbol table to build a lookup table from fragments to
423a86de1050889b61df2cd42cdc2acc5f9796b7f0cDaniel Dunbar  // defining symbols.
424a86de1050889b61df2cd42cdc2acc5f9796b7f0cDaniel Dunbar  DenseMap<const MCFragment*, MCSymbolData*> DefiningSymbolMap;
425dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (MCSymbolData &SD : getAssembler().symbols()) {
426dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (getAssembler().isSymbolLinkerVisible(SD.getSymbol()) &&
427dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        SD.getFragment()) {
428a86de1050889b61df2cd42cdc2acc5f9796b7f0cDaniel Dunbar      // An atom defining symbol should never be internal to a fragment.
429dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      assert(SD.getOffset() == 0 && "Invalid offset in atom defining symbol!");
430dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      DefiningSymbolMap[SD.getFragment()] = &SD;
431a86de1050889b61df2cd42cdc2acc5f9796b7f0cDaniel Dunbar    }
432a86de1050889b61df2cd42cdc2acc5f9796b7f0cDaniel Dunbar  }
433a86de1050889b61df2cd42cdc2acc5f9796b7f0cDaniel Dunbar
434a86de1050889b61df2cd42cdc2acc5f9796b7f0cDaniel Dunbar  // Set the fragment atom associations by tracking the last seen atom defining
435a86de1050889b61df2cd42cdc2acc5f9796b7f0cDaniel Dunbar  // symbol.
436a86de1050889b61df2cd42cdc2acc5f9796b7f0cDaniel Dunbar  for (MCAssembler::iterator it = getAssembler().begin(),
437a86de1050889b61df2cd42cdc2acc5f9796b7f0cDaniel Dunbar         ie = getAssembler().end(); it != ie; ++it) {
438dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MCSymbolData *CurrentAtom = nullptr;
439a86de1050889b61df2cd42cdc2acc5f9796b7f0cDaniel Dunbar    for (MCSectionData::iterator it2 = it->begin(),
440a86de1050889b61df2cd42cdc2acc5f9796b7f0cDaniel Dunbar           ie2 = it->end(); it2 != ie2; ++it2) {
441a86de1050889b61df2cd42cdc2acc5f9796b7f0cDaniel Dunbar      if (MCSymbolData *SD = DefiningSymbolMap.lookup(it2))
442a86de1050889b61df2cd42cdc2acc5f9796b7f0cDaniel Dunbar        CurrentAtom = SD;
443a86de1050889b61df2cd42cdc2acc5f9796b7f0cDaniel Dunbar      it2->setAtom(CurrentAtom);
444a86de1050889b61df2cd42cdc2acc5f9796b7f0cDaniel Dunbar    }
445a86de1050889b61df2cd42cdc2acc5f9796b7f0cDaniel Dunbar  }
446a86de1050889b61df2cd42cdc2acc5f9796b7f0cDaniel Dunbar
44799b4237c1647156f0e1d3d7e03efdab23ed79778Rafael Espindola  this->MCObjectStreamer::FinishImpl();
448a86de1050889b61df2cd42cdc2acc5f9796b7f0cDaniel Dunbar}
449a86de1050889b61df2cd42cdc2acc5f9796b7f0cDaniel Dunbar
45078c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan ChengMCStreamer *llvm::createMachOStreamer(MCContext &Context, MCAsmBackend &MAB,
451ac2884a717daf3ad2aa8425320795d661e8a980bDaniel Dunbar                                      raw_ostream &OS, MCCodeEmitter *CE,
45236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                      bool RelaxAll,
45336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                      bool LabelSections) {
45436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCMachOStreamer *S = new MCMachOStreamer(Context, MAB, OS, CE, LabelSections);
455ac2884a717daf3ad2aa8425320795d661e8a980bDaniel Dunbar  if (RelaxAll)
456ac2884a717daf3ad2aa8425320795d661e8a980bDaniel Dunbar    S->getAssembler().setRelaxAll(true);
457ac2884a717daf3ad2aa8425320795d661e8a980bDaniel Dunbar  return S;
458fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
459