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