MCMachOStreamer.cpp revision 821e3334ed3390d931f497300e6a5f1dc21bcfb3
1fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar//===- lib/MC/MCMachOStreamer.cpp - Mach-O Object Output ------------===//
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"
11fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
12fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar#include "llvm/MC/MCAssembler.h"
13fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar#include "llvm/MC/MCContext.h"
144fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar#include "llvm/MC/MCCodeEmitter.h"
158c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar#include "llvm/MC/MCExpr.h"
164fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar#include "llvm/MC/MCInst.h"
17fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar#include "llvm/MC/MCSection.h"
18fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar#include "llvm/MC/MCSymbol.h"
19821e3334ed3390d931f497300e6a5f1dc21bcfb3Daniel Dunbar#include "llvm/MC/MCValue.h"
20fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar#include "llvm/Support/ErrorHandling.h"
214fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar#include "llvm/Support/raw_ostream.h"
22fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarusing namespace llvm;
23fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
24fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarnamespace {
25fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
26fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarclass MCMachOStreamer : public MCStreamer {
276aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  /// SymbolFlags - We store the value for the 'desc' symbol field in the lowest
286aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  /// 16 bits of the implementation defined flags.
296aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  enum SymbolFlags { // See <mach-o/nlist.h>.
306aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SF_DescFlagsMask                        = 0xFFFF,
316aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar
326aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    // Reference type flags.
336aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SF_ReferenceTypeMask                    = 0x0007,
346aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SF_ReferenceTypeUndefinedNonLazy        = 0x0000,
356aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SF_ReferenceTypeUndefinedLazy           = 0x0001,
366aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SF_ReferenceTypeDefined                 = 0x0002,
376aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SF_ReferenceTypePrivateDefined          = 0x0003,
386aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SF_ReferenceTypePrivateUndefinedNonLazy = 0x0004,
396aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SF_ReferenceTypePrivateUndefinedLazy    = 0x0005,
406aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar
416aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    // Other 'desc' flags.
426aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SF_NoDeadStrip                          = 0x0020,
436aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SF_WeakReference                        = 0x0040,
446aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SF_WeakDefinition                       = 0x0080
456aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  };
466aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar
476aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbarprivate:
48fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  MCAssembler Assembler;
49fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
504fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar  MCCodeEmitter *Emitter;
514fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar
52fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  MCSectionData *CurSectionData;
53fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
54fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  DenseMap<const MCSection*, MCSectionData*> SectionMap;
55f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar
56f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar  DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap;
57f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar
58f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbarprivate:
59f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar  MCFragment *getCurrentFragment() const {
60f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar    assert(CurSectionData && "No current section!");
61f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar
62f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar    if (!CurSectionData->empty())
63f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar      return &CurSectionData->getFragmentList().back();
64f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar
65f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar    return 0;
66f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar  }
67f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar
680f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar  MCSectionData &getSectionData(const MCSection &Section) {
690f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar    MCSectionData *&Entry = SectionMap[&Section];
700f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar
710f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar    if (!Entry)
720f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar      Entry = new MCSectionData(Section, &Assembler);
730f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar
740f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar    return *Entry;
750f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar  }
760f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar
77cb579b3338fe8d9e4424b138f597a4696cb89de3Daniel Dunbar  MCSymbolData &getSymbolData(const MCSymbol &Symbol) {
78f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar    MCSymbolData *&Entry = SymbolMap[&Symbol];
79f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar
80f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar    if (!Entry)
81f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar      Entry = new MCSymbolData(Symbol, 0, 0, &Assembler);
82f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar
83f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar    return *Entry;
84f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar  }
85fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
86fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarpublic:
874fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar  MCMachOStreamer(MCContext &Context, raw_ostream &_OS, MCCodeEmitter *_Emitter)
88a03a368acca1c5ea7eb7de7a4164cbd22308c82fDaniel Dunbar    : MCStreamer(Context), Assembler(Context, _OS), Emitter(_Emitter),
894fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar      CurSectionData(0) {}
90fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  ~MCMachOStreamer() {}
91fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
928c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar  const MCExpr *AddValueSymbols(const MCExpr *Value) {
938c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar    switch (Value->getKind()) {
948c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar    case MCExpr::Constant:
958c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar      break;
968c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar
978c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar    case MCExpr::Binary: {
988c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar      const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value);
998c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar      AddValueSymbols(BE->getLHS());
1008c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar      AddValueSymbols(BE->getRHS());
1018c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar      break;
1028c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar    }
1038c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar
1048c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar    case MCExpr::SymbolRef:
1058c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar      getSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol());
1068c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar      break;
1078c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar
1088c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar    case MCExpr::Unary:
1098c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar      AddValueSymbols(cast<MCUnaryExpr>(Value)->getSubExpr());
1108c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar      break;
1118c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar    }
1128c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar
1138c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar    return Value;
1148c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar  }
1158c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar
116fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  /// @name MCStreamer Interface
117fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  /// @{
118fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
119fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  virtual void SwitchSection(const MCSection *Section);
120fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
121fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  virtual void EmitLabel(MCSymbol *Symbol);
122fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
123fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  virtual void EmitAssemblerFlag(AssemblerFlag Flag);
124fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
125821e3334ed3390d931f497300e6a5f1dc21bcfb3Daniel Dunbar  virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
126fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
127fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  virtual void EmitSymbolAttribute(MCSymbol *Symbol, SymbolAttr Attribute);
128fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
129fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
130fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
131fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  virtual void EmitCommonSymbol(MCSymbol *Symbol, unsigned Size,
1327092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar                                unsigned ByteAlignment);
133fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
1348751b94ffbd9c49df8949a37f78d6bd0be87b256Daniel Dunbar  virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
1357092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar                            unsigned Size = 0, unsigned ByteAlignment = 0);
136fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
137fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  virtual void EmitBytes(const StringRef &Data);
138fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
139821e3334ed3390d931f497300e6a5f1dc21bcfb3Daniel Dunbar  virtual void EmitValue(const MCExpr *Value, unsigned Size);
140fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
141fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
142fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar                                    unsigned ValueSize = 1,
143fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar                                    unsigned MaxBytesToEmit = 0);
144fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
145821e3334ed3390d931f497300e6a5f1dc21bcfb3Daniel Dunbar  virtual void EmitValueToOffset(const MCExpr *Offset,
146fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar                                 unsigned char Value = 0);
147fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
148fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  virtual void EmitInstruction(const MCInst &Inst);
149fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
150fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  virtual void Finish();
151fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
152fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  /// @}
153fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar};
154fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
155fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} // end anonymous namespace.
156fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
157fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::SwitchSection(const MCSection *Section) {
158fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  assert(Section && "Cannot switch to a null section!");
159cda7f78233b889772e1454a1246130c576681bb8Chris Lattner
160cda7f78233b889772e1454a1246130c576681bb8Chris Lattner  // If already in this section, then this is a noop.
161cda7f78233b889772e1454a1246130c576681bb8Chris Lattner  if (Section == CurSection) return;
162fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
1630f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar  CurSection = Section;
1640f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar  CurSectionData = &getSectionData(*Section);
165fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
166fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
167fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitLabel(MCSymbol *Symbol) {
1688906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
169fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
1705e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel Dunbar  // FIXME: We should also use offsets into Fill fragments.
171f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar  MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
172f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar  if (!F)
173f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar    F = new MCDataFragment(CurSectionData);
174fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
175f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar  MCSymbolData &SD = getSymbolData(*Symbol);
176f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar  assert(!SD.getFragment() && "Unexpected fragment on symbol data!");
177f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar  SD.setFragment(F);
178f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar  SD.setOffset(F->getContents().size());
1796aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar
1806aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  // This causes the reference type and weak reference flags to be cleared.
1816aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  SD.setFlags(SD.getFlags() & ~(SF_WeakReference | SF_ReferenceTypeMask));
182f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar
1838906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar  Symbol->setSection(*CurSection);
184fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
185fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
186fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitAssemblerFlag(AssemblerFlag Flag) {
1876009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar  switch (Flag) {
1886009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar  case SubsectionsViaSymbols:
1896009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar    Assembler.setSubsectionsViaSymbols(true);
1908c3eaf46a1fb69004723ce78aaa82965d6474175Daniel Dunbar    return;
1916009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar  }
1928c3eaf46a1fb69004723ce78aaa82965d6474175Daniel Dunbar
1938c3eaf46a1fb69004723ce78aaa82965d6474175Daniel Dunbar  assert(0 && "invalid assembler flag!");
194fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
195fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
196821e3334ed3390d931f497300e6a5f1dc21bcfb3Daniel Dunbarvoid MCMachOStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
1978906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar  // Only absolute symbols can be redefined.
1988906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar  assert((Symbol->isUndefined() || Symbol->isAbsolute()) &&
1998906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar         "Cannot define a symbol twice!");
200fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
201fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  llvm_unreachable("FIXME: Not yet implemented!");
202fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
203fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
204fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
205fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar                                          SymbolAttr Attribute) {
2060c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar  // Indirect symbols are handled differently, to match how 'as' handles
2070c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar  // them. This makes writing matching .o files easier.
2080c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar  if (Attribute == MCStreamer::IndirectSymbol) {
209ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar    // Note that we intentionally cannot use the symbol data here; this is
210ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar    // important for matching the string table that 'as' generates.
2110c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar    IndirectSymbolData ISD;
2120c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar    ISD.Symbol = Symbol;
2130c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar    ISD.SectionData = CurSectionData;
2140c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar    Assembler.getIndirectSymbols().push_back(ISD);
2150c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar    return;
2160c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar  }
2170c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar
2186aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  // Adding a symbol attribute always introduces the symbol, note that an
2196aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  // important side effect of calling getSymbolData here is to register the
2206aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  // symbol with the assembler.
2216aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  MCSymbolData &SD = getSymbolData(*Symbol);
2226aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar
2236aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  // The implementation of symbol attributes is designed to match 'as', but it
2246aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  // leaves much to desired. It doesn't really make sense to arbitrarily add and
2256aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  // remove flags, but 'as' allows this (in particular, see .desc).
2266aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  //
2276aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  // In the future it might be worth trying to make these operations more well
2286aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  // defined.
2293edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar  switch (Attribute) {
2300c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar  case MCStreamer::IndirectSymbol:
2316aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  case MCStreamer::Hidden:
2326aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  case MCStreamer::Internal:
2336aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  case MCStreamer::Protected:
2346aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  case MCStreamer::Weak:
2356aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    assert(0 && "Invalid symbol attribute for Mach-O!");
2366aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    break;
2373edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar
2383edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar  case MCStreamer::Global:
2398f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar    SD.setExternal(true);
2403edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar    break;
2416aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar
2426aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  case MCStreamer::LazyReference:
2436aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    // FIXME: This requires -dynamic.
2446aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SD.setFlags(SD.getFlags() | SF_NoDeadStrip);
2456aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    if (Symbol->isUndefined())
2466aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar      SD.setFlags(SD.getFlags() | SF_ReferenceTypeUndefinedLazy);
2476aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    break;
2486aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar
2496aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    // Since .reference sets the no dead strip bit, it is equivalent to
2506aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    // .no_dead_strip in practice.
2516aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  case MCStreamer::Reference:
2526aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  case MCStreamer::NoDeadStrip:
2536aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SD.setFlags(SD.getFlags() | SF_NoDeadStrip);
2546aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    break;
2556aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar
2566aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  case MCStreamer::PrivateExtern:
2576aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SD.setExternal(true);
2586aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SD.setPrivateExtern(true);
2596aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    break;
2606aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar
2616aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  case MCStreamer::WeakReference:
2626aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    // FIXME: This requires -dynamic.
2636aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    if (Symbol->isUndefined())
2646aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar      SD.setFlags(SD.getFlags() | SF_WeakReference);
2656aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    break;
2666aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar
2676aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  case MCStreamer::WeakDefinition:
2686aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    // FIXME: 'as' enforces that this is defined and global. The manual claims
2696aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    // it has to be in a coalesced section, but this isn't enforced.
2706aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SD.setFlags(SD.getFlags() | SF_WeakDefinition);
2716aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    break;
2723edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar  }
273fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
274fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
275fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
2766aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  // Encode the 'desc' value into the lowest implementation defined bits.
2776aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  assert(DescValue == (DescValue & SF_DescFlagsMask) &&
2786aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar         "Invalid .desc value!");
2796aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  getSymbolData(*Symbol).setFlags(DescValue & SF_DescFlagsMask);
280fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
281fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
282fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitCommonSymbol(MCSymbol *Symbol, unsigned Size,
2837092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar                                       unsigned ByteAlignment) {
2848f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar  // FIXME: Darwin 'as' does appear to allow redef of a .comm by itself.
2858f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
2868f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar
2878f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar  MCSymbolData &SD = getSymbolData(*Symbol);
2888f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar  SD.setExternal(true);
2897092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar  SD.setCommon(Size, ByteAlignment);
290fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
291fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
2928751b94ffbd9c49df8949a37f78d6bd0be87b256Daniel Dunbarvoid MCMachOStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
2937092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar                                   unsigned Size, unsigned ByteAlignment) {
294d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar  MCSectionData &SectData = getSectionData(*Section);
295d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar
296d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar  // The symbol may not be present, which only creates the section.
297d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar  if (!Symbol)
298d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar    return;
299d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar
300d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar  // FIXME: Assert that this section has the zerofill type.
301d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar
302d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
303d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar
304d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar  MCSymbolData &SD = getSymbolData(*Symbol);
305d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar
3067092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar  MCFragment *F = new MCZeroFillFragment(Size, ByteAlignment, &SectData);
307d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar  SD.setFragment(F);
308d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar
309d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar  Symbol->setSection(*Section);
310d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar
311d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar  // Update the maximum alignment on the zero fill section if necessary.
312d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar  if (ByteAlignment > SectData.getAlignment())
313d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar    SectData.setAlignment(ByteAlignment);
314fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
315fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
316fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitBytes(const StringRef &Data) {
317f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar  MCDataFragment *DF = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
318f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar  if (!DF)
319f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar    DF = new MCDataFragment(CurSectionData);
3200705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar  DF->getContents().append(Data.begin(), Data.end());
321fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
322fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
323821e3334ed3390d931f497300e6a5f1dc21bcfb3Daniel Dunbarvoid MCMachOStreamer::EmitValue(const MCExpr *Value, unsigned Size) {
324821e3334ed3390d931f497300e6a5f1dc21bcfb3Daniel Dunbar  MCValue RelocValue;
325821e3334ed3390d931f497300e6a5f1dc21bcfb3Daniel Dunbar
326821e3334ed3390d931f497300e6a5f1dc21bcfb3Daniel Dunbar  if (!AddValueSymbols(Value)->EvaluateAsRelocatable(getContext(), RelocValue))
327821e3334ed3390d931f497300e6a5f1dc21bcfb3Daniel Dunbar    return llvm_report_error("expected relocatable expression");
328821e3334ed3390d931f497300e6a5f1dc21bcfb3Daniel Dunbar
329821e3334ed3390d931f497300e6a5f1dc21bcfb3Daniel Dunbar  new MCFillFragment(RelocValue, Size, 1, CurSectionData);
330fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
331fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
332fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitValueToAlignment(unsigned ByteAlignment,
333fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar                                           int64_t Value, unsigned ValueSize,
334fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar                                           unsigned MaxBytesToEmit) {
335d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar  if (MaxBytesToEmit == 0)
336d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar    MaxBytesToEmit = ByteAlignment;
3370705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar  new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit,
3380705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar                      CurSectionData);
3390705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar
340f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar  // Update the maximum alignment on the current section if necessary.
3410705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar  if (ByteAlignment > CurSectionData->getAlignment())
3420705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar    CurSectionData->setAlignment(ByteAlignment);
343fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
344fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
345821e3334ed3390d931f497300e6a5f1dc21bcfb3Daniel Dunbarvoid MCMachOStreamer::EmitValueToOffset(const MCExpr *Offset,
346fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar                                        unsigned char Value) {
347821e3334ed3390d931f497300e6a5f1dc21bcfb3Daniel Dunbar  MCValue RelocOffset;
348821e3334ed3390d931f497300e6a5f1dc21bcfb3Daniel Dunbar
349821e3334ed3390d931f497300e6a5f1dc21bcfb3Daniel Dunbar  if (!AddValueSymbols(Offset)->EvaluateAsRelocatable(getContext(),
350821e3334ed3390d931f497300e6a5f1dc21bcfb3Daniel Dunbar                                                      RelocOffset))
351821e3334ed3390d931f497300e6a5f1dc21bcfb3Daniel Dunbar    return llvm_report_error("expected relocatable expression");
352821e3334ed3390d931f497300e6a5f1dc21bcfb3Daniel Dunbar
353821e3334ed3390d931f497300e6a5f1dc21bcfb3Daniel Dunbar  new MCOrgFragment(RelocOffset, Value, CurSectionData);
354fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
355fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
356fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitInstruction(const MCInst &Inst) {
3574fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar  // Scan for values.
3584fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar  for (unsigned i = 0; i != Inst.getNumOperands(); ++i)
3598c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar    if (Inst.getOperand(i).isExpr())
3608c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar      AddValueSymbols(Inst.getOperand(i).getExpr());
3614fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar
3624fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar  if (!Emitter)
3634fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar    llvm_unreachable("no code emitter available!");
3644fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar
3654fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar  // FIXME: Relocations!
3664fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar  SmallString<256> Code;
3674fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar  raw_svector_ostream VecOS(Code);
3684fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar  Emitter->EncodeInstruction(Inst, VecOS);
3694fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar  EmitBytes(VecOS.str());
370fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
371fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
372fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::Finish() {
373fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  Assembler.Finish();
374fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
375fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
3764fac74950a1ff08b995b366bfb84369c1507faefDaniel DunbarMCStreamer *llvm::createMachOStreamer(MCContext &Context, raw_ostream &OS,
3774fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar                                      MCCodeEmitter *CE) {
3784fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar  return new MCMachOStreamer(Context, OS, CE);
379fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
380