MCMachOStreamer.cpp revision f7fd4aa2610f46467369de07f3ec669561d79be0
1//===- lib/MC/MCMachOStreamer.cpp - Mach-O Object Output ------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "llvm/MC/MCStreamer.h"
11
12#include "llvm/MC/MCAssembler.h"
13#include "llvm/MC/MCContext.h"
14#include "llvm/MC/MCCodeEmitter.h"
15#include "llvm/MC/MCExpr.h"
16#include "llvm/MC/MCInst.h"
17#include "llvm/MC/MCObjectStreamer.h"
18#include "llvm/MC/MCSection.h"
19#include "llvm/MC/MCSymbol.h"
20#include "llvm/MC/MCMachOSymbolFlags.h"
21#include "llvm/MC/MCSectionMachO.h"
22#include "llvm/MC/MCDwarf.h"
23#include "llvm/Support/Dwarf.h"
24#include "llvm/Support/ErrorHandling.h"
25#include "llvm/Support/raw_ostream.h"
26#include "llvm/Target/TargetAsmBackend.h"
27
28using namespace llvm;
29
30namespace {
31
32class MCMachOStreamer : public MCObjectStreamer {
33private:
34  virtual void EmitInstToData(const MCInst &Inst);
35
36public:
37  MCMachOStreamer(MCContext &Context, TargetAsmBackend &TAB,
38                  raw_ostream &OS, MCCodeEmitter *Emitter)
39    : MCObjectStreamer(Context, TAB, OS, Emitter) {}
40
41  /// @name MCStreamer Interface
42  /// @{
43
44  virtual void InitSections();
45  virtual void EmitLabel(MCSymbol *Symbol);
46  virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
47  virtual void EmitThumbFunc(MCSymbol *Func);
48  virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
49  virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
50  virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
51  virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
52                                unsigned ByteAlignment);
53  virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) {
54    assert(0 && "macho doesn't support this directive");
55  }
56  virtual void EmitCOFFSymbolStorageClass(int StorageClass) {
57    assert(0 && "macho doesn't support this directive");
58  }
59  virtual void EmitCOFFSymbolType(int Type) {
60    assert(0 && "macho doesn't support this directive");
61  }
62  virtual void EndCOFFSymbolDef() {
63    assert(0 && "macho doesn't support this directive");
64  }
65  virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
66    assert(0 && "macho doesn't support this directive");
67  }
68  virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) {
69    assert(0 && "macho doesn't support this directive");
70  }
71  virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
72                            unsigned Size = 0, unsigned ByteAlignment = 0);
73  virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
74                              uint64_t Size, unsigned ByteAlignment = 0);
75  virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
76  virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
77                                    unsigned ValueSize = 1,
78                                    unsigned MaxBytesToEmit = 0);
79  virtual void EmitCodeAlignment(unsigned ByteAlignment,
80                                 unsigned MaxBytesToEmit = 0);
81
82  virtual void EmitFileDirective(StringRef Filename) {
83    // FIXME: Just ignore the .file; it isn't important enough to fail the
84    // entire assembly.
85
86    //report_fatal_error("unsupported directive: '.file'");
87  }
88
89  virtual void Finish();
90
91  /// @}
92};
93
94} // end anonymous namespace.
95
96void MCMachOStreamer::InitSections() {
97  SwitchSection(getContext().getMachOSection("__TEXT", "__text",
98                                    MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
99                                    0, SectionKind::getText()));
100
101}
102
103void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) {
104  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
105
106  // isSymbolLinkerVisible uses the section.
107  Symbol->setSection(*CurSection);
108  // We have to create a new fragment if this is an atom defining symbol,
109  // fragments cannot span atoms.
110  if (getAssembler().isSymbolLinkerVisible(*Symbol))
111    new MCDataFragment(getCurrentSectionData());
112
113  MCObjectStreamer::EmitLabel(Symbol);
114
115  MCSymbolData &SD = getAssembler().getSymbolData(*Symbol);
116  // This causes the reference type flag to be cleared. Darwin 'as' was "trying"
117  // to clear the weak reference and weak definition bits too, but the
118  // implementation was buggy. For now we just try to match 'as', for
119  // diffability.
120  //
121  // FIXME: Cleanup this code, these bits should be emitted based on semantic
122  // properties, not on the order of definition, etc.
123  SD.setFlags(SD.getFlags() & ~SF_ReferenceTypeMask);
124}
125
126void MCMachOStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
127  // Let the target do whatever target specific stuff it needs to do.
128  getAssembler().getBackend().HandleAssemblerFlag(Flag);
129  // Do any generic stuff we need to do.
130  switch (Flag) {
131  case MCAF_SyntaxUnified: return; // no-op here.
132  case MCAF_Code16: return; // no-op here.
133  case MCAF_Code32: return; // no-op here.
134  case MCAF_SubsectionsViaSymbols:
135    getAssembler().setSubsectionsViaSymbols(true);
136    return;
137  default:
138    llvm_unreachable("invalid assembler flag!");
139  }
140}
141
142void MCMachOStreamer::EmitThumbFunc(MCSymbol *Func) {
143  // FIXME: Flag the function ISA as thumb with DW_AT_APPLE_isa.
144}
145
146void MCMachOStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
147  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
148  // MCObjectStreamer.
149  // FIXME: Lift context changes into super class.
150  getAssembler().getOrCreateSymbolData(*Symbol);
151  Symbol->setVariableValue(AddValueSymbols(Value));
152}
153
154void MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
155                                          MCSymbolAttr Attribute) {
156  // Indirect symbols are handled differently, to match how 'as' handles
157  // them. This makes writing matching .o files easier.
158  if (Attribute == MCSA_IndirectSymbol) {
159    // Note that we intentionally cannot use the symbol data here; this is
160    // important for matching the string table that 'as' generates.
161    IndirectSymbolData ISD;
162    ISD.Symbol = Symbol;
163    ISD.SectionData = getCurrentSectionData();
164    getAssembler().getIndirectSymbols().push_back(ISD);
165    return;
166  }
167
168  // Adding a symbol attribute always introduces the symbol, note that an
169  // important side effect of calling getOrCreateSymbolData here is to register
170  // the symbol with the assembler.
171  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
172
173  // The implementation of symbol attributes is designed to match 'as', but it
174  // leaves much to desired. It doesn't really make sense to arbitrarily add and
175  // remove flags, but 'as' allows this (in particular, see .desc).
176  //
177  // In the future it might be worth trying to make these operations more well
178  // defined.
179  switch (Attribute) {
180  case MCSA_Invalid:
181  case MCSA_ELF_TypeFunction:
182  case MCSA_ELF_TypeIndFunction:
183  case MCSA_ELF_TypeObject:
184  case MCSA_ELF_TypeTLS:
185  case MCSA_ELF_TypeCommon:
186  case MCSA_ELF_TypeNoType:
187  case MCSA_ELF_TypeGnuUniqueObject:
188  case MCSA_IndirectSymbol:
189  case MCSA_Hidden:
190  case MCSA_Internal:
191  case MCSA_Protected:
192  case MCSA_Weak:
193  case MCSA_Local:
194    assert(0 && "Invalid symbol attribute for Mach-O!");
195    break;
196
197  case MCSA_Global:
198    SD.setExternal(true);
199    // This effectively clears the undefined lazy bit, in Darwin 'as', although
200    // it isn't very consistent because it implements this as part of symbol
201    // lookup.
202    //
203    // FIXME: Cleanup this code, these bits should be emitted based on semantic
204    // properties, not on the order of definition, etc.
205    SD.setFlags(SD.getFlags() & ~SF_ReferenceTypeUndefinedLazy);
206    break;
207
208  case MCSA_LazyReference:
209    // FIXME: This requires -dynamic.
210    SD.setFlags(SD.getFlags() | SF_NoDeadStrip);
211    if (Symbol->isUndefined())
212      SD.setFlags(SD.getFlags() | SF_ReferenceTypeUndefinedLazy);
213    break;
214
215    // Since .reference sets the no dead strip bit, it is equivalent to
216    // .no_dead_strip in practice.
217  case MCSA_Reference:
218  case MCSA_NoDeadStrip:
219    SD.setFlags(SD.getFlags() | SF_NoDeadStrip);
220    break;
221
222  case MCSA_SymbolResolver:
223    SD.setFlags(SD.getFlags() | SF_SymbolResolver);
224    break;
225
226  case MCSA_PrivateExtern:
227    SD.setExternal(true);
228    SD.setPrivateExtern(true);
229    break;
230
231  case MCSA_WeakReference:
232    // FIXME: This requires -dynamic.
233    if (Symbol->isUndefined())
234      SD.setFlags(SD.getFlags() | SF_WeakReference);
235    break;
236
237  case MCSA_WeakDefinition:
238    // FIXME: 'as' enforces that this is defined and global. The manual claims
239    // it has to be in a coalesced section, but this isn't enforced.
240    SD.setFlags(SD.getFlags() | SF_WeakDefinition);
241    break;
242
243  case MCSA_WeakDefAutoPrivate:
244    SD.setFlags(SD.getFlags() | SF_WeakDefinition | SF_WeakReference);
245    break;
246  }
247}
248
249void MCMachOStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
250  // Encode the 'desc' value into the lowest implementation defined bits.
251  assert(DescValue == (DescValue & SF_DescFlagsMask) &&
252         "Invalid .desc value!");
253  getAssembler().getOrCreateSymbolData(*Symbol).setFlags(
254    DescValue & SF_DescFlagsMask);
255}
256
257void MCMachOStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
258                                       unsigned ByteAlignment) {
259  // FIXME: Darwin 'as' does appear to allow redef of a .comm by itself.
260  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
261
262  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
263  SD.setExternal(true);
264  SD.setCommon(Size, ByteAlignment);
265}
266
267void MCMachOStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
268                                   unsigned Size, unsigned ByteAlignment) {
269  MCSectionData &SectData = getAssembler().getOrCreateSectionData(*Section);
270
271  // The symbol may not be present, which only creates the section.
272  if (!Symbol)
273    return;
274
275  // FIXME: Assert that this section has the zerofill type.
276
277  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
278
279  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
280
281  // Emit an align fragment if necessary.
282  if (ByteAlignment != 1)
283    new MCAlignFragment(ByteAlignment, 0, 0, ByteAlignment, &SectData);
284
285  MCFragment *F = new MCFillFragment(0, 0, Size, &SectData);
286  SD.setFragment(F);
287
288  Symbol->setSection(*Section);
289
290  // Update the maximum alignment on the zero fill section if necessary.
291  if (ByteAlignment > SectData.getAlignment())
292    SectData.setAlignment(ByteAlignment);
293}
294
295// This should always be called with the thread local bss section.  Like the
296// .zerofill directive this doesn't actually switch sections on us.
297void MCMachOStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
298                                     uint64_t Size, unsigned ByteAlignment) {
299  EmitZerofill(Section, Symbol, Size, ByteAlignment);
300  return;
301}
302
303void MCMachOStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
304  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
305  // MCObjectStreamer.
306  getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end());
307}
308
309void MCMachOStreamer::EmitValueToAlignment(unsigned ByteAlignment,
310                                           int64_t Value, unsigned ValueSize,
311                                           unsigned MaxBytesToEmit) {
312  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
313  // MCObjectStreamer.
314  if (MaxBytesToEmit == 0)
315    MaxBytesToEmit = ByteAlignment;
316  new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit,
317                      getCurrentSectionData());
318
319  // Update the maximum alignment on the current section if necessary.
320  if (ByteAlignment > getCurrentSectionData()->getAlignment())
321    getCurrentSectionData()->setAlignment(ByteAlignment);
322}
323
324void MCMachOStreamer::EmitCodeAlignment(unsigned ByteAlignment,
325                                        unsigned MaxBytesToEmit) {
326  // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
327  // MCObjectStreamer.
328  if (MaxBytesToEmit == 0)
329    MaxBytesToEmit = ByteAlignment;
330  MCAlignFragment *F = new MCAlignFragment(ByteAlignment, 0, 1, MaxBytesToEmit,
331                                           getCurrentSectionData());
332  F->setEmitNops(true);
333
334  // Update the maximum alignment on the current section if necessary.
335  if (ByteAlignment > getCurrentSectionData()->getAlignment())
336    getCurrentSectionData()->setAlignment(ByteAlignment);
337}
338
339void MCMachOStreamer::EmitInstToData(const MCInst &Inst) {
340  MCDataFragment *DF = getOrCreateDataFragment();
341
342  SmallVector<MCFixup, 4> Fixups;
343  SmallString<256> Code;
344  raw_svector_ostream VecOS(Code);
345  getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
346  VecOS.flush();
347
348  // Add the fixups and data.
349  for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
350    Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
351    DF->addFixup(Fixups[i]);
352  }
353  DF->getContents().append(Code.begin(), Code.end());
354}
355
356void MCMachOStreamer::Finish() {
357  // Dump out the dwarf file & directory tables and line tables.
358  if (getContext().hasDwarfFiles()) {
359    const MCSection *DwarfLineSection = getContext().getMachOSection("__DWARF",
360                                         "__debug_line",
361                                         MCSectionMachO::S_ATTR_DEBUG,
362                                         0, SectionKind::getDataRelLocal());
363    MCDwarfFileTable::Emit(this, DwarfLineSection);
364  }
365
366  // We have to set the fragment atom associations so we can relax properly for
367  // Mach-O.
368
369  // First, scan the symbol table to build a lookup table from fragments to
370  // defining symbols.
371  DenseMap<const MCFragment*, MCSymbolData*> DefiningSymbolMap;
372  for (MCAssembler::symbol_iterator it = getAssembler().symbol_begin(),
373         ie = getAssembler().symbol_end(); it != ie; ++it) {
374    if (getAssembler().isSymbolLinkerVisible(it->getSymbol()) &&
375        it->getFragment()) {
376      // An atom defining symbol should never be internal to a fragment.
377      assert(it->getOffset() == 0 && "Invalid offset in atom defining symbol!");
378      DefiningSymbolMap[it->getFragment()] = it;
379    }
380  }
381
382  // Set the fragment atom associations by tracking the last seen atom defining
383  // symbol.
384  for (MCAssembler::iterator it = getAssembler().begin(),
385         ie = getAssembler().end(); it != ie; ++it) {
386    MCSymbolData *CurrentAtom = 0;
387    for (MCSectionData::iterator it2 = it->begin(),
388           ie2 = it->end(); it2 != ie2; ++it2) {
389      if (MCSymbolData *SD = DefiningSymbolMap.lookup(it2))
390        CurrentAtom = SD;
391      it2->setAtom(CurrentAtom);
392    }
393  }
394
395  this->MCObjectStreamer::Finish();
396}
397
398MCStreamer *llvm::createMachOStreamer(MCContext &Context, TargetAsmBackend &TAB,
399                                      raw_ostream &OS, MCCodeEmitter *CE,
400                                      bool RelaxAll) {
401  MCMachOStreamer *S = new MCMachOStreamer(Context, TAB, OS, CE);
402  if (RelaxAll)
403    S->getAssembler().setRelaxAll(true);
404  return S;
405}
406