MCMachOStreamer.cpp revision 8f4d146c340c9423271ebd7bb3fd32b880000bc9
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"
154fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar#include "llvm/MC/MCInst.h"
16fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar#include "llvm/MC/MCSection.h"
17fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar#include "llvm/MC/MCSymbol.h"
18fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar#include "llvm/Support/ErrorHandling.h"
194fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar#include "llvm/Support/raw_ostream.h"
20fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarusing namespace llvm;
21fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
22fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarnamespace {
23fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
24fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarclass MCMachOStreamer : public MCStreamer {
256aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  /// SymbolFlags - We store the value for the 'desc' symbol field in the lowest
266aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  /// 16 bits of the implementation defined flags.
276aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  enum SymbolFlags { // See <mach-o/nlist.h>.
286aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SF_DescFlagsMask                        = 0xFFFF,
296aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar
306aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    // Reference type flags.
316aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SF_ReferenceTypeMask                    = 0x0007,
326aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SF_ReferenceTypeUndefinedNonLazy        = 0x0000,
336aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SF_ReferenceTypeUndefinedLazy           = 0x0001,
346aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SF_ReferenceTypeDefined                 = 0x0002,
356aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SF_ReferenceTypePrivateDefined          = 0x0003,
366aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SF_ReferenceTypePrivateUndefinedNonLazy = 0x0004,
376aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SF_ReferenceTypePrivateUndefinedLazy    = 0x0005,
386aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar
396aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    // Other 'desc' flags.
406aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SF_NoDeadStrip                          = 0x0020,
416aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SF_WeakReference                        = 0x0040,
426aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SF_WeakDefinition                       = 0x0080
436aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  };
446aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar
456aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbarprivate:
46fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  MCAssembler Assembler;
47fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
484fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar  MCCodeEmitter *Emitter;
494fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar
50fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  MCSectionData *CurSectionData;
51fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
52fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  DenseMap<const MCSection*, MCSectionData*> SectionMap;
53f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar
54f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar  DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap;
55f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar
56f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbarprivate:
57f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar  MCFragment *getCurrentFragment() const {
58f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar    assert(CurSectionData && "No current section!");
59f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar
60f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar    if (!CurSectionData->empty())
61f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar      return &CurSectionData->getFragmentList().back();
62f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar
63f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar    return 0;
64f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar  }
65f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar
660f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar  MCSectionData &getSectionData(const MCSection &Section) {
670f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar    MCSectionData *&Entry = SectionMap[&Section];
680f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar
690f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar    if (!Entry)
700f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar      Entry = new MCSectionData(Section, &Assembler);
710f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar
720f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar    return *Entry;
730f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar  }
740f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar
75f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar  MCSymbolData &getSymbolData(MCSymbol &Symbol) {
76f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar    MCSymbolData *&Entry = SymbolMap[&Symbol];
77f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar
78f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar    if (!Entry)
79f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar      Entry = new MCSymbolData(Symbol, 0, 0, &Assembler);
80f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar
81f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar    return *Entry;
82f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar  }
83fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
84fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarpublic:
854fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar  MCMachOStreamer(MCContext &Context, raw_ostream &_OS, MCCodeEmitter *_Emitter)
864fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar    : MCStreamer(Context), Assembler(_OS), Emitter(_Emitter),
874fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar      CurSectionData(0) {}
88fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  ~MCMachOStreamer() {}
89fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
90a421de11df9d2a07b9f95a1ad817467af426803aDaniel Dunbar  const MCValue &AddValueSymbols(const MCValue &Value) {
91a421de11df9d2a07b9f95a1ad817467af426803aDaniel Dunbar    if (Value.getSymA())
92a421de11df9d2a07b9f95a1ad817467af426803aDaniel Dunbar      getSymbolData(*const_cast<MCSymbol*>(Value.getSymA()));
93a421de11df9d2a07b9f95a1ad817467af426803aDaniel Dunbar    if (Value.getSymB())
94a421de11df9d2a07b9f95a1ad817467af426803aDaniel Dunbar      getSymbolData(*const_cast<MCSymbol*>(Value.getSymB()));
95a421de11df9d2a07b9f95a1ad817467af426803aDaniel Dunbar    return Value;
96a421de11df9d2a07b9f95a1ad817467af426803aDaniel Dunbar  }
97a421de11df9d2a07b9f95a1ad817467af426803aDaniel Dunbar
98fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  /// @name MCStreamer Interface
99fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  /// @{
100fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
101fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  virtual void SwitchSection(const MCSection *Section);
102fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
103fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  virtual void EmitLabel(MCSymbol *Symbol);
104fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
105fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  virtual void EmitAssemblerFlag(AssemblerFlag Flag);
106fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
107fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  virtual void EmitAssignment(MCSymbol *Symbol, const MCValue &Value,
108fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar                              bool MakeAbsolute = false);
109fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
110fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  virtual void EmitSymbolAttribute(MCSymbol *Symbol, SymbolAttr Attribute);
111fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
112fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
113fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
114fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  virtual void EmitLocalSymbol(MCSymbol *Symbol, const MCValue &Value);
115fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
116fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  virtual void EmitCommonSymbol(MCSymbol *Symbol, unsigned Size,
117e6cdbf2f92a753ad547e3287e279bf47585b228dDaniel Dunbar                                unsigned Pow2Alignment);
118fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
1198751b94ffbd9c49df8949a37f78d6bd0be87b256Daniel Dunbar  virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
120fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar                            unsigned Size = 0, unsigned Pow2Alignment = 0);
121fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
122fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  virtual void EmitBytes(const StringRef &Data);
123fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
124fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  virtual void EmitValue(const MCValue &Value, unsigned Size);
125fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
126fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
127fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar                                    unsigned ValueSize = 1,
128fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar                                    unsigned MaxBytesToEmit = 0);
129fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
130fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  virtual void EmitValueToOffset(const MCValue &Offset,
131fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar                                 unsigned char Value = 0);
132fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
133fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  virtual void EmitInstruction(const MCInst &Inst);
134fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
135fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  virtual void Finish();
136fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
137fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  /// @}
138fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar};
139fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
140fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} // end anonymous namespace.
141fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
142fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::SwitchSection(const MCSection *Section) {
143fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  assert(Section && "Cannot switch to a null section!");
144cda7f78233b889772e1454a1246130c576681bb8Chris Lattner
145cda7f78233b889772e1454a1246130c576681bb8Chris Lattner  // If already in this section, then this is a noop.
146cda7f78233b889772e1454a1246130c576681bb8Chris Lattner  if (Section == CurSection) return;
147fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
1480f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar  CurSection = Section;
1490f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar  CurSectionData = &getSectionData(*Section);
150fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
151fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
152fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitLabel(MCSymbol *Symbol) {
1538906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
154fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
1555e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel Dunbar  // FIXME: We should also use offsets into Fill fragments.
156f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar  MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
157f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar  if (!F)
158f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar    F = new MCDataFragment(CurSectionData);
159fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
160f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar  MCSymbolData &SD = getSymbolData(*Symbol);
161f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar  assert(!SD.getFragment() && "Unexpected fragment on symbol data!");
162f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar  SD.setFragment(F);
163f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar  SD.setOffset(F->getContents().size());
1646aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar
1656aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  // This causes the reference type and weak reference flags to be cleared.
1666aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  SD.setFlags(SD.getFlags() & ~(SF_WeakReference | SF_ReferenceTypeMask));
167f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar
1688906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar  Symbol->setSection(*CurSection);
169fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
170fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
171fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitAssemblerFlag(AssemblerFlag Flag) {
1726009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar  switch (Flag) {
1736009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar  default:
1746009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar    llvm_unreachable("FIXME: Not yet implemented!");
1756009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar
1766009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar  case SubsectionsViaSymbols:
1776009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar    Assembler.setSubsectionsViaSymbols(true);
1786009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar    break;
1796009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar  }
180fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
181fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
182fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitAssignment(MCSymbol *Symbol,
183fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar                                     const MCValue &Value,
184fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar                                     bool MakeAbsolute) {
1858906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar  // Only absolute symbols can be redefined.
1868906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar  assert((Symbol->isUndefined() || Symbol->isAbsolute()) &&
1878906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar         "Cannot define a symbol twice!");
188fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
189fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  llvm_unreachable("FIXME: Not yet implemented!");
190fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
191fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
192fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
193fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar                                          SymbolAttr Attribute) {
1940c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar  // Indirect symbols are handled differently, to match how 'as' handles
1950c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar  // them. This makes writing matching .o files easier.
1960c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar  if (Attribute == MCStreamer::IndirectSymbol) {
197ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar    // Note that we intentionally cannot use the symbol data here; this is
198ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar    // important for matching the string table that 'as' generates.
1990c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar    IndirectSymbolData ISD;
2000c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar    ISD.Symbol = Symbol;
2010c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar    ISD.SectionData = CurSectionData;
2020c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar    Assembler.getIndirectSymbols().push_back(ISD);
2030c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar    return;
2040c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar  }
2050c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar
2066aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  // Adding a symbol attribute always introduces the symbol, note that an
2076aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  // important side effect of calling getSymbolData here is to register the
2086aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  // symbol with the assembler.
2096aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  MCSymbolData &SD = getSymbolData(*Symbol);
2106aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar
2116aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  // The implementation of symbol attributes is designed to match 'as', but it
2126aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  // leaves much to desired. It doesn't really make sense to arbitrarily add and
2136aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  // remove flags, but 'as' allows this (in particular, see .desc).
2146aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  //
2156aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  // In the future it might be worth trying to make these operations more well
2166aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  // defined.
2173edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar  switch (Attribute) {
2180c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar  case MCStreamer::IndirectSymbol:
2196aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  case MCStreamer::Hidden:
2206aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  case MCStreamer::Internal:
2216aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  case MCStreamer::Protected:
2226aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  case MCStreamer::Weak:
2236aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    assert(0 && "Invalid symbol attribute for Mach-O!");
2246aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    break;
2253edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar
2263edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar  case MCStreamer::Global:
2278f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar    SD.setExternal(true);
2283edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar    break;
2296aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar
2306aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  case MCStreamer::LazyReference:
2316aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    // FIXME: This requires -dynamic.
2326aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SD.setFlags(SD.getFlags() | SF_NoDeadStrip);
2336aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    if (Symbol->isUndefined())
2346aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar      SD.setFlags(SD.getFlags() | SF_ReferenceTypeUndefinedLazy);
2356aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    break;
2366aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar
2376aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    // Since .reference sets the no dead strip bit, it is equivalent to
2386aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    // .no_dead_strip in practice.
2396aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  case MCStreamer::Reference:
2406aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  case MCStreamer::NoDeadStrip:
2416aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SD.setFlags(SD.getFlags() | SF_NoDeadStrip);
2426aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    break;
2436aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar
2446aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  case MCStreamer::PrivateExtern:
2456aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SD.setExternal(true);
2466aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SD.setPrivateExtern(true);
2476aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    break;
2486aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar
2496aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  case MCStreamer::WeakReference:
2506aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    // FIXME: This requires -dynamic.
2516aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    if (Symbol->isUndefined())
2526aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar      SD.setFlags(SD.getFlags() | SF_WeakReference);
2536aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    break;
2546aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar
2556aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  case MCStreamer::WeakDefinition:
2566aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    // FIXME: 'as' enforces that this is defined and global. The manual claims
2576aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    // it has to be in a coalesced section, but this isn't enforced.
2586aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    SD.setFlags(SD.getFlags() | SF_WeakDefinition);
2596aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar    break;
2603edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar  }
261fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
262fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
263fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
2646aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  // Encode the 'desc' value into the lowest implementation defined bits.
2656aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  assert(DescValue == (DescValue & SF_DescFlagsMask) &&
2666aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar         "Invalid .desc value!");
2676aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar  getSymbolData(*Symbol).setFlags(DescValue & SF_DescFlagsMask);
268fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
269fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
270fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitLocalSymbol(MCSymbol *Symbol, const MCValue &Value) {
271fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  llvm_unreachable("FIXME: Not yet implemented!");
272fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
273fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
274fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitCommonSymbol(MCSymbol *Symbol, unsigned Size,
275e6cdbf2f92a753ad547e3287e279bf47585b228dDaniel Dunbar                                       unsigned Pow2Alignment) {
2768f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar  // FIXME: Darwin 'as' does appear to allow redef of a .comm by itself.
2778f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
2788f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar
2798f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar  MCSymbolData &SD = getSymbolData(*Symbol);
2808f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar  SD.setExternal(true);
2818f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar  SD.setCommon(Size, 1 << Pow2Alignment);
282fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
283fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
2848751b94ffbd9c49df8949a37f78d6bd0be87b256Daniel Dunbarvoid MCMachOStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
285fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar                                   unsigned Size, unsigned Pow2Alignment) {
286d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar  unsigned ByteAlignment = 1 << Pow2Alignment;
287d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar  MCSectionData &SectData = getSectionData(*Section);
288d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar
289d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar  // The symbol may not be present, which only creates the section.
290d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar  if (!Symbol)
291d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar    return;
292d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar
293d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar  // FIXME: Assert that this section has the zerofill type.
294d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar
295d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
296d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar
297d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar  MCSymbolData &SD = getSymbolData(*Symbol);
298d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar
299d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar  MCFragment *F = new MCZeroFillFragment(Size, 1 << Pow2Alignment, &SectData);
300d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar  SD.setFragment(F);
301d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar
302d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar  Symbol->setSection(*Section);
303d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar
304d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar  // Update the maximum alignment on the zero fill section if necessary.
305d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar  if (ByteAlignment > SectData.getAlignment())
306d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar    SectData.setAlignment(ByteAlignment);
307fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
308fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
309fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitBytes(const StringRef &Data) {
310f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar  MCDataFragment *DF = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
311f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar  if (!DF)
312f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar    DF = new MCDataFragment(CurSectionData);
3130705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar  DF->getContents().append(Data.begin(), Data.end());
314fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
315fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
316fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitValue(const MCValue &Value, unsigned Size) {
317a421de11df9d2a07b9f95a1ad817467af426803aDaniel Dunbar  new MCFillFragment(AddValueSymbols(Value), Size, 1, CurSectionData);
318fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
319fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
320fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitValueToAlignment(unsigned ByteAlignment,
321fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar                                           int64_t Value, unsigned ValueSize,
322fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar                                           unsigned MaxBytesToEmit) {
323d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar  if (MaxBytesToEmit == 0)
324d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar    MaxBytesToEmit = ByteAlignment;
3250705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar  new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit,
3260705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar                      CurSectionData);
3270705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar
328f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar  // Update the maximum alignment on the current section if necessary.
3290705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar  if (ByteAlignment > CurSectionData->getAlignment())
3300705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar    CurSectionData->setAlignment(ByteAlignment);
331fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
332fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
333fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitValueToOffset(const MCValue &Offset,
334fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar                                        unsigned char Value) {
335a421de11df9d2a07b9f95a1ad817467af426803aDaniel Dunbar  new MCOrgFragment(AddValueSymbols(Offset), Value, CurSectionData);
336fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
337fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
338fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitInstruction(const MCInst &Inst) {
3394fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar  // Scan for values.
3404fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar  for (unsigned i = 0; i != Inst.getNumOperands(); ++i)
3414fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar    if (Inst.getOperand(i).isMCValue())
3424fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar      AddValueSymbols(Inst.getOperand(i).getMCValue());
3434fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar
3444fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar  if (!Emitter)
3454fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar    llvm_unreachable("no code emitter available!");
3464fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar
3474fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar  // FIXME: Relocations!
3484fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar  SmallString<256> Code;
3494fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar  raw_svector_ostream VecOS(Code);
3504fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar  Emitter->EncodeInstruction(Inst, VecOS);
3514fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar  EmitBytes(VecOS.str());
352fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
353fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
354fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::Finish() {
355fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  Assembler.Finish();
356fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
357fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
3584fac74950a1ff08b995b366bfb84369c1507faefDaniel DunbarMCStreamer *llvm::createMachOStreamer(MCContext &Context, raw_ostream &OS,
3594fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar                                      MCCodeEmitter *CE) {
3604fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar  return new MCMachOStreamer(Context, OS, CE);
361fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}
362