MCMachOStreamer.cpp revision 208954
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/MC/MCMachOSymbolFlags.h"
20#include "llvm/Support/ErrorHandling.h"
21#include "llvm/Support/raw_ostream.h"
22#include "llvm/Target/TargetAsmBackend.h"
23
24using namespace llvm;
25
26namespace {
27
28class MCMachOStreamer : public MCStreamer {
29
30private:
31  MCAssembler Assembler;
32  MCSectionData *CurSectionData;
33
34  /// Track the current atom for each section.
35  DenseMap<const MCSectionData*, MCSymbolData*> CurrentAtomMap;
36
37private:
38  MCFragment *getCurrentFragment() const {
39    assert(CurSectionData && "No current section!");
40
41    if (!CurSectionData->empty())
42      return &CurSectionData->getFragmentList().back();
43
44    return 0;
45  }
46
47  /// Get a data fragment to write into, creating a new one if the current
48  /// fragment is not a data fragment.
49  MCDataFragment *getOrCreateDataFragment() const {
50    MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
51    if (!F)
52      F = createDataFragment();
53    return F;
54  }
55
56  /// Create a new data fragment in the current section.
57  MCDataFragment *createDataFragment() const {
58    MCDataFragment *DF = new MCDataFragment(CurSectionData);
59    DF->setAtom(CurrentAtomMap.lookup(CurSectionData));
60    return DF;
61  }
62
63  void EmitInstToFragment(const MCInst &Inst);
64  void EmitInstToData(const MCInst &Inst);
65
66public:
67  MCMachOStreamer(MCContext &Context, TargetAsmBackend &TAB,
68                  raw_ostream &_OS, MCCodeEmitter *_Emitter)
69    : MCStreamer(Context), Assembler(Context, TAB, *_Emitter, _OS),
70      CurSectionData(0) {}
71  ~MCMachOStreamer() {}
72
73  MCAssembler &getAssembler() { return Assembler; }
74
75  const MCExpr *AddValueSymbols(const MCExpr *Value) {
76    switch (Value->getKind()) {
77    case MCExpr::Target: assert(0 && "Can't handle target exprs yet!");
78    case MCExpr::Constant:
79      break;
80
81    case MCExpr::Binary: {
82      const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value);
83      AddValueSymbols(BE->getLHS());
84      AddValueSymbols(BE->getRHS());
85      break;
86    }
87
88    case MCExpr::SymbolRef:
89      Assembler.getOrCreateSymbolData(
90        cast<MCSymbolRefExpr>(Value)->getSymbol());
91      break;
92
93    case MCExpr::Unary:
94      AddValueSymbols(cast<MCUnaryExpr>(Value)->getSubExpr());
95      break;
96    }
97
98    return Value;
99  }
100
101  /// @name MCStreamer Interface
102  /// @{
103
104  virtual void SwitchSection(const MCSection *Section);
105  virtual void EmitLabel(MCSymbol *Symbol);
106  virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
107  virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
108  virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
109  virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
110  virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
111                                unsigned ByteAlignment);
112  virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) {
113    assert(0 && "macho doesn't support this directive");
114  }
115  virtual void EmitCOFFSymbolStorageClass(int StorageClass) {
116    assert(0 && "macho doesn't support this directive");
117  }
118  virtual void EmitCOFFSymbolType(int Type) {
119    assert(0 && "macho doesn't support this directive");
120  }
121  virtual void EndCOFFSymbolDef() {
122    assert(0 && "macho doesn't support this directive");
123  }
124  virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
125    assert(0 && "macho doesn't support this directive");
126  }
127  virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) {
128    assert(0 && "macho doesn't support this directive");
129  }
130  virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
131                            unsigned Size = 0, unsigned ByteAlignment = 0);
132  virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
133                              uint64_t Size, unsigned ByteAlignment = 0);
134  virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
135  virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace);
136  virtual void EmitGPRel32Value(const MCExpr *Value) {
137    assert(0 && "macho doesn't support this directive");
138  }
139  virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
140                                    unsigned ValueSize = 1,
141                                    unsigned MaxBytesToEmit = 0);
142  virtual void EmitCodeAlignment(unsigned ByteAlignment,
143                                 unsigned MaxBytesToEmit = 0);
144  virtual void EmitValueToOffset(const MCExpr *Offset,
145                                 unsigned char Value = 0);
146
147  virtual void EmitFileDirective(StringRef Filename) {
148    report_fatal_error("unsupported directive: '.file'");
149  }
150  virtual void EmitDwarfFileDirective(unsigned FileNo, StringRef Filename) {
151    report_fatal_error("unsupported directive: '.file'");
152  }
153
154  virtual void EmitInstruction(const MCInst &Inst);
155  virtual void Finish();
156
157  /// @}
158};
159
160} // end anonymous namespace.
161
162void MCMachOStreamer::SwitchSection(const MCSection *Section) {
163  assert(Section && "Cannot switch to a null section!");
164
165  // If already in this section, then this is a noop.
166  if (Section == CurSection) return;
167
168  CurSection = Section;
169  CurSectionData = &Assembler.getOrCreateSectionData(*Section);
170}
171
172void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) {
173  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
174  assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
175  assert(CurSection && "Cannot emit before setting section!");
176
177  MCSymbolData &SD = Assembler.getOrCreateSymbolData(*Symbol);
178
179  // Update the current atom map, if necessary.
180  bool MustCreateFragment = false;
181  if (Assembler.isSymbolLinkerVisible(&SD)) {
182    CurrentAtomMap[CurSectionData] = &SD;
183
184    // We have to create a new fragment, fragments cannot span atoms.
185    MustCreateFragment = true;
186  }
187
188  // FIXME: This is wasteful, we don't necessarily need to create a data
189  // fragment. Instead, we should mark the symbol as pointing into the data
190  // fragment if it exists, otherwise we should just queue the label and set its
191  // fragment pointer when we emit the next fragment.
192  MCDataFragment *F =
193    MustCreateFragment ? createDataFragment() : getOrCreateDataFragment();
194  assert(!SD.getFragment() && "Unexpected fragment on symbol data!");
195  SD.setFragment(F);
196  SD.setOffset(F->getContents().size());
197
198  // This causes the reference type flag to be cleared. Darwin 'as' was "trying"
199  // to clear the weak reference and weak definition bits too, but the
200  // implementation was buggy. For now we just try to match 'as', for
201  // diffability.
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_ReferenceTypeMask);
206
207  Symbol->setSection(*CurSection);
208}
209
210void MCMachOStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
211  switch (Flag) {
212  case MCAF_SubsectionsViaSymbols:
213    Assembler.setSubsectionsViaSymbols(true);
214    return;
215  }
216
217  assert(0 && "invalid assembler flag!");
218}
219
220void MCMachOStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
221  // FIXME: Lift context changes into super class.
222  Assembler.getOrCreateSymbolData(*Symbol);
223  Symbol->setVariableValue(AddValueSymbols(Value));
224}
225
226void MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
227                                          MCSymbolAttr Attribute) {
228  // Indirect symbols are handled differently, to match how 'as' handles
229  // them. This makes writing matching .o files easier.
230  if (Attribute == MCSA_IndirectSymbol) {
231    // Note that we intentionally cannot use the symbol data here; this is
232    // important for matching the string table that 'as' generates.
233    IndirectSymbolData ISD;
234    ISD.Symbol = Symbol;
235    ISD.SectionData = CurSectionData;
236    Assembler.getIndirectSymbols().push_back(ISD);
237    return;
238  }
239
240  // Adding a symbol attribute always introduces the symbol, note that an
241  // important side effect of calling getOrCreateSymbolData here is to register
242  // the symbol with the assembler.
243  MCSymbolData &SD = Assembler.getOrCreateSymbolData(*Symbol);
244
245  // The implementation of symbol attributes is designed to match 'as', but it
246  // leaves much to desired. It doesn't really make sense to arbitrarily add and
247  // remove flags, but 'as' allows this (in particular, see .desc).
248  //
249  // In the future it might be worth trying to make these operations more well
250  // defined.
251  switch (Attribute) {
252  case MCSA_Invalid:
253  case MCSA_ELF_TypeFunction:
254  case MCSA_ELF_TypeIndFunction:
255  case MCSA_ELF_TypeObject:
256  case MCSA_ELF_TypeTLS:
257  case MCSA_ELF_TypeCommon:
258  case MCSA_ELF_TypeNoType:
259  case MCSA_IndirectSymbol:
260  case MCSA_Hidden:
261  case MCSA_Internal:
262  case MCSA_Protected:
263  case MCSA_Weak:
264  case MCSA_Local:
265    assert(0 && "Invalid symbol attribute for Mach-O!");
266    break;
267
268  case MCSA_Global:
269    SD.setExternal(true);
270    // This effectively clears the undefined lazy bit, in Darwin 'as', although
271    // it isn't very consistent because it implements this as part of symbol
272    // lookup.
273    //
274    // FIXME: Cleanup this code, these bits should be emitted based on semantic
275    // properties, not on the order of definition, etc.
276    SD.setFlags(SD.getFlags() & ~SF_ReferenceTypeUndefinedLazy);
277    break;
278
279  case MCSA_LazyReference:
280    // FIXME: This requires -dynamic.
281    SD.setFlags(SD.getFlags() | SF_NoDeadStrip);
282    if (Symbol->isUndefined())
283      SD.setFlags(SD.getFlags() | SF_ReferenceTypeUndefinedLazy);
284    break;
285
286    // Since .reference sets the no dead strip bit, it is equivalent to
287    // .no_dead_strip in practice.
288  case MCSA_Reference:
289  case MCSA_NoDeadStrip:
290    SD.setFlags(SD.getFlags() | SF_NoDeadStrip);
291    break;
292
293  case MCSA_PrivateExtern:
294    SD.setExternal(true);
295    SD.setPrivateExtern(true);
296    break;
297
298  case MCSA_WeakReference:
299    // FIXME: This requires -dynamic.
300    if (Symbol->isUndefined())
301      SD.setFlags(SD.getFlags() | SF_WeakReference);
302    break;
303
304  case MCSA_WeakDefinition:
305    // FIXME: 'as' enforces that this is defined and global. The manual claims
306    // it has to be in a coalesced section, but this isn't enforced.
307    SD.setFlags(SD.getFlags() | SF_WeakDefinition);
308    break;
309  }
310}
311
312void MCMachOStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
313  // Encode the 'desc' value into the lowest implementation defined bits.
314  assert(DescValue == (DescValue & SF_DescFlagsMask) &&
315         "Invalid .desc value!");
316  Assembler.getOrCreateSymbolData(*Symbol).setFlags(DescValue&SF_DescFlagsMask);
317}
318
319void MCMachOStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
320                                       unsigned ByteAlignment) {
321  // FIXME: Darwin 'as' does appear to allow redef of a .comm by itself.
322  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
323
324  MCSymbolData &SD = Assembler.getOrCreateSymbolData(*Symbol);
325  SD.setExternal(true);
326  SD.setCommon(Size, ByteAlignment);
327}
328
329void MCMachOStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
330                                   unsigned Size, unsigned ByteAlignment) {
331  MCSectionData &SectData = Assembler.getOrCreateSectionData(*Section);
332
333  // The symbol may not be present, which only creates the section.
334  if (!Symbol)
335    return;
336
337  // FIXME: Assert that this section has the zerofill type.
338
339  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
340
341  MCSymbolData &SD = Assembler.getOrCreateSymbolData(*Symbol);
342
343  // Emit an align fragment if necessary.
344  if (ByteAlignment != 1)
345    new MCAlignFragment(ByteAlignment, 0, 0, ByteAlignment, &SectData);
346
347  MCFragment *F = new MCFillFragment(0, 0, Size, &SectData);
348  SD.setFragment(F);
349  if (Assembler.isSymbolLinkerVisible(&SD))
350    F->setAtom(&SD);
351
352  Symbol->setSection(*Section);
353
354  // Update the maximum alignment on the zero fill section if necessary.
355  if (ByteAlignment > SectData.getAlignment())
356    SectData.setAlignment(ByteAlignment);
357}
358
359// This should always be called with the thread local bss section.  Like the
360// .zerofill directive this doesn't actually switch sections on us.
361void MCMachOStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
362                                     uint64_t Size, unsigned ByteAlignment) {
363  EmitZerofill(Section, Symbol, Size, ByteAlignment);
364  return;
365}
366
367void MCMachOStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
368  getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end());
369}
370
371void MCMachOStreamer::EmitValue(const MCExpr *Value, unsigned Size,
372                                unsigned AddrSpace) {
373  MCDataFragment *DF = getOrCreateDataFragment();
374
375  // Avoid fixups when possible.
376  int64_t AbsValue;
377  if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue)) {
378    // FIXME: Endianness assumption.
379    for (unsigned i = 0; i != Size; ++i)
380      DF->getContents().push_back(uint8_t(AbsValue >> (i * 8)));
381  } else {
382    DF->addFixup(MCFixup::Create(DF->getContents().size(),
383                                 AddValueSymbols(Value),
384                                 MCFixup::getKindForSize(Size)));
385    DF->getContents().resize(DF->getContents().size() + Size, 0);
386  }
387}
388
389void MCMachOStreamer::EmitValueToAlignment(unsigned ByteAlignment,
390                                           int64_t Value, unsigned ValueSize,
391                                           unsigned MaxBytesToEmit) {
392  if (MaxBytesToEmit == 0)
393    MaxBytesToEmit = ByteAlignment;
394  MCFragment *F = new MCAlignFragment(ByteAlignment, Value, ValueSize,
395                                      MaxBytesToEmit, CurSectionData);
396  F->setAtom(CurrentAtomMap.lookup(CurSectionData));
397
398  // Update the maximum alignment on the current section if necessary.
399  if (ByteAlignment > CurSectionData->getAlignment())
400    CurSectionData->setAlignment(ByteAlignment);
401}
402
403void MCMachOStreamer::EmitCodeAlignment(unsigned ByteAlignment,
404                                        unsigned MaxBytesToEmit) {
405  if (MaxBytesToEmit == 0)
406    MaxBytesToEmit = ByteAlignment;
407  MCAlignFragment *F = new MCAlignFragment(ByteAlignment, 0, 1, MaxBytesToEmit,
408                                           CurSectionData);
409  F->setEmitNops(true);
410  F->setAtom(CurrentAtomMap.lookup(CurSectionData));
411
412  // Update the maximum alignment on the current section if necessary.
413  if (ByteAlignment > CurSectionData->getAlignment())
414    CurSectionData->setAlignment(ByteAlignment);
415}
416
417void MCMachOStreamer::EmitValueToOffset(const MCExpr *Offset,
418                                        unsigned char Value) {
419  MCFragment *F = new MCOrgFragment(*Offset, Value, CurSectionData);
420  F->setAtom(CurrentAtomMap.lookup(CurSectionData));
421}
422
423void MCMachOStreamer::EmitInstToFragment(const MCInst &Inst) {
424  MCInstFragment *IF = new MCInstFragment(Inst, CurSectionData);
425  IF->setAtom(CurrentAtomMap.lookup(CurSectionData));
426
427  // Add the fixups and data.
428  //
429  // FIXME: Revisit this design decision when relaxation is done, we may be
430  // able to get away with not storing any extra data in the MCInst.
431  SmallVector<MCFixup, 4> Fixups;
432  SmallString<256> Code;
433  raw_svector_ostream VecOS(Code);
434  Assembler.getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
435  VecOS.flush();
436
437  IF->getCode() = Code;
438  IF->getFixups() = Fixups;
439}
440
441void MCMachOStreamer::EmitInstToData(const MCInst &Inst) {
442  MCDataFragment *DF = getOrCreateDataFragment();
443
444  SmallVector<MCFixup, 4> Fixups;
445  SmallString<256> Code;
446  raw_svector_ostream VecOS(Code);
447  Assembler.getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
448  VecOS.flush();
449
450  // Add the fixups and data.
451  for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
452    Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
453    DF->addFixup(Fixups[i]);
454  }
455  DF->getContents().append(Code.begin(), Code.end());
456}
457
458void MCMachOStreamer::EmitInstruction(const MCInst &Inst) {
459  // Scan for values.
460  for (unsigned i = Inst.getNumOperands(); i--; )
461    if (Inst.getOperand(i).isExpr())
462      AddValueSymbols(Inst.getOperand(i).getExpr());
463
464  CurSectionData->setHasInstructions(true);
465
466  // If this instruction doesn't need relaxation, just emit it as data.
467  if (!Assembler.getBackend().MayNeedRelaxation(Inst)) {
468    EmitInstToData(Inst);
469    return;
470  }
471
472  // Otherwise, if we are relaxing everything, relax the instruction as much as
473  // possible and emit it as data.
474  if (Assembler.getRelaxAll()) {
475    MCInst Relaxed;
476    Assembler.getBackend().RelaxInstruction(Inst, Relaxed);
477    while (Assembler.getBackend().MayNeedRelaxation(Relaxed))
478      Assembler.getBackend().RelaxInstruction(Relaxed, Relaxed);
479    EmitInstToData(Relaxed);
480    return;
481  }
482
483  // Otherwise emit to a separate fragment.
484  EmitInstToFragment(Inst);
485}
486
487void MCMachOStreamer::Finish() {
488  Assembler.Finish();
489}
490
491MCStreamer *llvm::createMachOStreamer(MCContext &Context, TargetAsmBackend &TAB,
492                                      raw_ostream &OS, MCCodeEmitter *CE,
493                                      bool RelaxAll) {
494  MCMachOStreamer *S = new MCMachOStreamer(Context, TAB, OS, CE);
495  if (RelaxAll)
496    S->getAssembler().setRelaxAll(true);
497  return S;
498}
499