MCMachOStreamer.cpp revision d8036fb0deb7daff7959b0a5407c8a45acb5e603
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/MCSection.h"
18#include "llvm/MC/MCSymbol.h"
19#include "llvm/Support/ErrorHandling.h"
20#include "llvm/Support/raw_ostream.h"
21#include "llvm/Target/TargetAsmBackend.h"
22
23using namespace llvm;
24
25namespace {
26
27class MCMachOStreamer : public MCStreamer {
28  /// SymbolFlags - We store the value for the 'desc' symbol field in the lowest
29  /// 16 bits of the implementation defined flags.
30  enum SymbolFlags { // See <mach-o/nlist.h>.
31    SF_DescFlagsMask                        = 0xFFFF,
32
33    // Reference type flags.
34    SF_ReferenceTypeMask                    = 0x0007,
35    SF_ReferenceTypeUndefinedNonLazy        = 0x0000,
36    SF_ReferenceTypeUndefinedLazy           = 0x0001,
37    SF_ReferenceTypeDefined                 = 0x0002,
38    SF_ReferenceTypePrivateDefined          = 0x0003,
39    SF_ReferenceTypePrivateUndefinedNonLazy = 0x0004,
40    SF_ReferenceTypePrivateUndefinedLazy    = 0x0005,
41
42    // Other 'desc' flags.
43    SF_NoDeadStrip                          = 0x0020,
44    SF_WeakReference                        = 0x0040,
45    SF_WeakDefinition                       = 0x0080
46  };
47
48private:
49  MCAssembler Assembler;
50  MCSectionData *CurSectionData;
51
52private:
53  MCFragment *getCurrentFragment() const {
54    assert(CurSectionData && "No current section!");
55
56    if (!CurSectionData->empty())
57      return &CurSectionData->getFragmentList().back();
58
59    return 0;
60  }
61
62  /// Get a data fragment to write into, creating a new one if the current
63  /// fragment is not a data fragment.
64  MCDataFragment *getOrCreateDataFragment() const {
65    MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
66    if (!F)
67      F = new MCDataFragment(CurSectionData);
68    return F;
69  }
70
71public:
72  MCMachOStreamer(MCContext &Context, TargetAsmBackend &TAB,
73                  raw_ostream &_OS, MCCodeEmitter *_Emitter)
74    : MCStreamer(Context), Assembler(Context, TAB, *_Emitter, _OS),
75      CurSectionData(0) {}
76  ~MCMachOStreamer() {}
77
78  const MCExpr *AddValueSymbols(const MCExpr *Value) {
79    switch (Value->getKind()) {
80    case MCExpr::Target: assert(0 && "Can't handle target exprs yet!");
81    case MCExpr::Constant:
82      break;
83
84    case MCExpr::Binary: {
85      const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value);
86      AddValueSymbols(BE->getLHS());
87      AddValueSymbols(BE->getRHS());
88      break;
89    }
90
91    case MCExpr::SymbolRef:
92      Assembler.getOrCreateSymbolData(
93        cast<MCSymbolRefExpr>(Value)->getSymbol());
94      break;
95
96    case MCExpr::Unary:
97      AddValueSymbols(cast<MCUnaryExpr>(Value)->getSubExpr());
98      break;
99    }
100
101    return Value;
102  }
103
104  /// @name MCStreamer Interface
105  /// @{
106
107  virtual void SwitchSection(const MCSection *Section);
108  virtual void EmitLabel(MCSymbol *Symbol);
109  virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
110  virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
111  virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
112  virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
113  virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
114                                unsigned ByteAlignment);
115  virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
116    assert(0 && "macho doesn't support this directive");
117  }
118  virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) {
119    assert(0 && "macho doesn't support this directive");
120  }
121  virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
122                            unsigned Size = 0, unsigned ByteAlignment = 0);
123  virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
124  virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace);
125  virtual void EmitGPRel32Value(const MCExpr *Value) {
126    assert(0 && "macho doesn't support this directive");
127  }
128  virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
129                                    unsigned ValueSize = 1,
130                                    unsigned MaxBytesToEmit = 0);
131  virtual void EmitCodeAlignment(unsigned ByteAlignment,
132                                 unsigned MaxBytesToEmit = 0);
133  virtual void EmitValueToOffset(const MCExpr *Offset,
134                                 unsigned char Value = 0);
135
136  virtual void EmitFileDirective(StringRef Filename) {
137    errs() << "FIXME: MCMachoStreamer:EmitFileDirective not implemented\n";
138  }
139  virtual void EmitDwarfFileDirective(unsigned FileNo, StringRef Filename) {
140    errs() << "FIXME: MCMachoStreamer:EmitDwarfFileDirective not implemented\n";
141  }
142
143  virtual void EmitInstruction(const MCInst &Inst);
144  virtual void Finish();
145
146  /// @}
147};
148
149} // end anonymous namespace.
150
151void MCMachOStreamer::SwitchSection(const MCSection *Section) {
152  assert(Section && "Cannot switch to a null section!");
153
154  // If already in this section, then this is a noop.
155  if (Section == CurSection) return;
156
157  CurSection = Section;
158  CurSectionData = &Assembler.getOrCreateSectionData(*Section);
159}
160
161void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) {
162  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
163
164  // FIXME: This is wasteful, we don't necessarily need to create a data
165  // fragment. Instead, we should mark the symbol as pointing into the data
166  // fragment if it exists, otherwise we should just queue the label and set its
167  // fragment pointer when we emit the next fragment.
168  MCDataFragment *F = getOrCreateDataFragment();
169  MCSymbolData &SD = Assembler.getOrCreateSymbolData(*Symbol);
170  assert(!SD.getFragment() && "Unexpected fragment on symbol data!");
171  SD.setFragment(F);
172  SD.setOffset(F->getContents().size());
173
174  // This causes the reference type and weak reference flags to be cleared.
175  SD.setFlags(SD.getFlags() & ~(SF_WeakReference | SF_ReferenceTypeMask));
176
177  Symbol->setSection(*CurSection);
178}
179
180void MCMachOStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
181  switch (Flag) {
182  case MCAF_SubsectionsViaSymbols:
183    Assembler.setSubsectionsViaSymbols(true);
184    return;
185  }
186
187  assert(0 && "invalid assembler flag!");
188}
189
190void MCMachOStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
191  // Only absolute symbols can be redefined.
192  assert((Symbol->isUndefined() || Symbol->isAbsolute()) &&
193         "Cannot define a symbol twice!");
194
195  // FIXME: Lift context changes into super class.
196  // FIXME: Set associated section.
197  Symbol->setValue(AddValueSymbols(Value));
198}
199
200void MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
201                                          MCSymbolAttr Attribute) {
202  // Indirect symbols are handled differently, to match how 'as' handles
203  // them. This makes writing matching .o files easier.
204  if (Attribute == MCSA_IndirectSymbol) {
205    // Note that we intentionally cannot use the symbol data here; this is
206    // important for matching the string table that 'as' generates.
207    IndirectSymbolData ISD;
208    ISD.Symbol = Symbol;
209    ISD.SectionData = CurSectionData;
210    Assembler.getIndirectSymbols().push_back(ISD);
211    return;
212  }
213
214  // Adding a symbol attribute always introduces the symbol, note that an
215  // important side effect of calling getOrCreateSymbolData here is to register
216  // the symbol with the assembler.
217  MCSymbolData &SD = Assembler.getOrCreateSymbolData(*Symbol);
218
219  // The implementation of symbol attributes is designed to match 'as', but it
220  // leaves much to desired. It doesn't really make sense to arbitrarily add and
221  // remove flags, but 'as' allows this (in particular, see .desc).
222  //
223  // In the future it might be worth trying to make these operations more well
224  // defined.
225  switch (Attribute) {
226  case MCSA_Invalid:
227  case MCSA_ELF_TypeFunction:
228  case MCSA_ELF_TypeIndFunction:
229  case MCSA_ELF_TypeObject:
230  case MCSA_ELF_TypeTLS:
231  case MCSA_ELF_TypeCommon:
232  case MCSA_ELF_TypeNoType:
233  case MCSA_IndirectSymbol:
234  case MCSA_Hidden:
235  case MCSA_Internal:
236  case MCSA_Protected:
237  case MCSA_Weak:
238  case MCSA_Local:
239    assert(0 && "Invalid symbol attribute for Mach-O!");
240    break;
241
242  case MCSA_Global:
243    SD.setExternal(true);
244    break;
245
246  case MCSA_LazyReference:
247    // FIXME: This requires -dynamic.
248    SD.setFlags(SD.getFlags() | SF_NoDeadStrip);
249    if (Symbol->isUndefined())
250      SD.setFlags(SD.getFlags() | SF_ReferenceTypeUndefinedLazy);
251    break;
252
253    // Since .reference sets the no dead strip bit, it is equivalent to
254    // .no_dead_strip in practice.
255  case MCSA_Reference:
256  case MCSA_NoDeadStrip:
257    SD.setFlags(SD.getFlags() | SF_NoDeadStrip);
258    break;
259
260  case MCSA_PrivateExtern:
261    SD.setExternal(true);
262    SD.setPrivateExtern(true);
263    break;
264
265  case MCSA_WeakReference:
266    // FIXME: This requires -dynamic.
267    if (Symbol->isUndefined())
268      SD.setFlags(SD.getFlags() | SF_WeakReference);
269    break;
270
271  case MCSA_WeakDefinition:
272    // FIXME: 'as' enforces that this is defined and global. The manual claims
273    // it has to be in a coalesced section, but this isn't enforced.
274    SD.setFlags(SD.getFlags() | SF_WeakDefinition);
275    break;
276  }
277}
278
279void MCMachOStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
280  // Encode the 'desc' value into the lowest implementation defined bits.
281  assert(DescValue == (DescValue & SF_DescFlagsMask) &&
282         "Invalid .desc value!");
283  Assembler.getOrCreateSymbolData(*Symbol).setFlags(DescValue&SF_DescFlagsMask);
284}
285
286void MCMachOStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
287                                       unsigned ByteAlignment) {
288  // FIXME: Darwin 'as' does appear to allow redef of a .comm by itself.
289  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
290
291  MCSymbolData &SD = Assembler.getOrCreateSymbolData(*Symbol);
292  SD.setExternal(true);
293  SD.setCommon(Size, ByteAlignment);
294}
295
296void MCMachOStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
297                                   unsigned Size, unsigned ByteAlignment) {
298  MCSectionData &SectData = Assembler.getOrCreateSectionData(*Section);
299
300  // The symbol may not be present, which only creates the section.
301  if (!Symbol)
302    return;
303
304  // FIXME: Assert that this section has the zerofill type.
305
306  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
307
308  MCSymbolData &SD = Assembler.getOrCreateSymbolData(*Symbol);
309
310  MCFragment *F = new MCZeroFillFragment(Size, ByteAlignment, &SectData);
311  SD.setFragment(F);
312
313  Symbol->setSection(*Section);
314
315  // Update the maximum alignment on the zero fill section if necessary.
316  if (ByteAlignment > SectData.getAlignment())
317    SectData.setAlignment(ByteAlignment);
318}
319
320void MCMachOStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
321  getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end());
322}
323
324void MCMachOStreamer::EmitValue(const MCExpr *Value, unsigned Size,
325                                unsigned AddrSpace) {
326  MCDataFragment *DF = getOrCreateDataFragment();
327
328  // Avoid fixups when possible.
329  int64_t AbsValue;
330  if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue)) {
331    // FIXME: Endianness assumption.
332    for (unsigned i = 0; i != Size; ++i)
333      DF->getContents().push_back(uint8_t(AbsValue >> (i * 8)));
334  } else {
335    DF->addFixup(MCAsmFixup(DF->getContents().size(), *AddValueSymbols(Value),
336                            MCFixup::getKindForSize(Size)));
337    DF->getContents().resize(DF->getContents().size() + Size, 0);
338  }
339}
340
341void MCMachOStreamer::EmitValueToAlignment(unsigned ByteAlignment,
342                                           int64_t Value, unsigned ValueSize,
343                                           unsigned MaxBytesToEmit) {
344  if (MaxBytesToEmit == 0)
345    MaxBytesToEmit = ByteAlignment;
346  new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit,
347                      false /* EmitNops */, CurSectionData);
348
349  // Update the maximum alignment on the current section if necessary.
350  if (ByteAlignment > CurSectionData->getAlignment())
351    CurSectionData->setAlignment(ByteAlignment);
352}
353
354void MCMachOStreamer::EmitCodeAlignment(unsigned ByteAlignment,
355                                        unsigned MaxBytesToEmit) {
356  if (MaxBytesToEmit == 0)
357    MaxBytesToEmit = ByteAlignment;
358  new MCAlignFragment(ByteAlignment, 0, 1, MaxBytesToEmit,
359                      true /* EmitNops */, CurSectionData);
360
361  // Update the maximum alignment on the current section if necessary.
362  if (ByteAlignment > CurSectionData->getAlignment())
363    CurSectionData->setAlignment(ByteAlignment);
364}
365
366void MCMachOStreamer::EmitValueToOffset(const MCExpr *Offset,
367                                        unsigned char Value) {
368  new MCOrgFragment(*Offset, Value, CurSectionData);
369}
370
371void MCMachOStreamer::EmitInstruction(const MCInst &Inst) {
372  // Scan for values.
373  for (unsigned i = 0; i != Inst.getNumOperands(); ++i)
374    if (Inst.getOperand(i).isExpr())
375      AddValueSymbols(Inst.getOperand(i).getExpr());
376
377  CurSectionData->setHasInstructions(true);
378
379  // FIXME-PERF: Common case is that we don't need to relax, encode directly
380  // onto the data fragments buffers.
381
382  SmallVector<MCFixup, 4> Fixups;
383  SmallString<256> Code;
384  raw_svector_ostream VecOS(Code);
385  Assembler.getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
386  VecOS.flush();
387
388  // FIXME: Eliminate this copy.
389  SmallVector<MCAsmFixup, 4> AsmFixups;
390  for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
391    MCFixup &F = Fixups[i];
392    AsmFixups.push_back(MCAsmFixup(F.getOffset(), *F.getValue(),
393                                   F.getKind()));
394  }
395
396  // See if we might need to relax this instruction, if so it needs its own
397  // fragment.
398  //
399  // FIXME-PERF: Support target hook to do a fast path that avoids the encoder,
400  // when we can immediately tell that we will get something which might need
401  // relaxation (and compute its size).
402  //
403  // FIXME-PERF: We should also be smart about immediately relaxing instructions
404  // which we can already show will never possibly fit (we can also do a very
405  // good job of this before we do the first relaxation pass, because we have
406  // total knowledge about undefined symbols at that point). Even now, though,
407  // we can do a decent job, especially on Darwin where scattering means that we
408  // are going to often know that we can never fully resolve a fixup.
409  if (Assembler.getBackend().MayNeedRelaxation(Inst, AsmFixups)) {
410    MCInstFragment *IF = new MCInstFragment(Inst, CurSectionData);
411
412    // Add the fixups and data.
413    //
414    // FIXME: Revisit this design decision when relaxation is done, we may be
415    // able to get away with not storing any extra data in the MCInst.
416    IF->getCode() = Code;
417    IF->getFixups() = AsmFixups;
418
419    return;
420  }
421
422  // Add the fixups and data.
423  MCDataFragment *DF = getOrCreateDataFragment();
424  for (unsigned i = 0, e = AsmFixups.size(); i != e; ++i) {
425    AsmFixups[i].Offset += DF->getContents().size();
426    DF->addFixup(AsmFixups[i]);
427  }
428  DF->getContents().append(Code.begin(), Code.end());
429}
430
431void MCMachOStreamer::Finish() {
432  Assembler.Finish();
433}
434
435MCStreamer *llvm::createMachOStreamer(MCContext &Context, TargetAsmBackend &TAB,
436                                      raw_ostream &OS, MCCodeEmitter *CE) {
437  return new MCMachOStreamer(Context, TAB, OS, CE);
438}
439