1//===-- MCMachOStreamer.cpp - MachO Streamer ------------------------------===//
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#include "llvm/ADT/DenseMap.h"
12#include "llvm/ADT/SmallVector.h"
13#include "llvm/MC/MCAsmBackend.h"
14#include "llvm/MC/MCAssembler.h"
15#include "llvm/MC/MCCodeEmitter.h"
16#include "llvm/MC/MCContext.h"
17#include "llvm/MC/MCDwarf.h"
18#include "llvm/MC/MCExpr.h"
19#include "llvm/MC/MCInst.h"
20#include "llvm/MC/MCLinkerOptimizationHint.h"
21#include "llvm/MC/MCMachOSymbolFlags.h"
22#include "llvm/MC/MCObjectFileInfo.h"
23#include "llvm/MC/MCObjectStreamer.h"
24#include "llvm/MC/MCSection.h"
25#include "llvm/MC/MCSectionMachO.h"
26#include "llvm/MC/MCSymbol.h"
27#include "llvm/Support/Dwarf.h"
28#include "llvm/Support/ErrorHandling.h"
29#include "llvm/Support/raw_ostream.h"
30
31using namespace llvm;
32
33namespace {
34
35class MCMachOStreamer : public MCObjectStreamer {
36private:
37  /// LabelSections - true if each section change should emit a linker local
38  /// label for use in relocations for assembler local references. Obviates the
39  /// need for local relocations. False by default.
40  bool LabelSections;
41
42  /// HasSectionLabel - map of which sections have already had a non-local
43  /// label emitted to them. Used so we don't emit extraneous linker local
44  /// labels in the middle of the section.
45  DenseMap<const MCSection*, bool> HasSectionLabel;
46
47  void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &STI) override;
48
49  void EmitDataRegion(DataRegionData::KindTy Kind);
50  void EmitDataRegionEnd();
51
52public:
53  MCMachOStreamer(MCContext &Context, MCAsmBackend &MAB, raw_ostream &OS,
54                  MCCodeEmitter *Emitter, bool label)
55      : MCObjectStreamer(Context, MAB, OS, Emitter),
56        LabelSections(label) {}
57
58  /// @name MCStreamer Interface
59  /// @{
60
61  void ChangeSection(const MCSection *Sect, const MCExpr *Subsect) override;
62  void EmitLabel(MCSymbol *Symbol) override;
63  void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol) override;
64  void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
65  void EmitLinkerOptions(ArrayRef<std::string> Options) override;
66  void EmitDataRegion(MCDataRegionType Kind) override;
67  void EmitVersionMin(MCVersionMinType Kind, unsigned Major,
68                      unsigned Minor, unsigned Update) override;
69  void EmitThumbFunc(MCSymbol *Func) override;
70  bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
71  void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
72  void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
73                        unsigned ByteAlignment) override;
74  void BeginCOFFSymbolDef(const MCSymbol *Symbol) override {
75    llvm_unreachable("macho doesn't support this directive");
76  }
77  void EmitCOFFSymbolStorageClass(int StorageClass) override {
78    llvm_unreachable("macho doesn't support this directive");
79  }
80  void EmitCOFFSymbolType(int Type) override {
81    llvm_unreachable("macho doesn't support this directive");
82  }
83  void EndCOFFSymbolDef() override {
84    llvm_unreachable("macho doesn't support this directive");
85  }
86  void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) override {
87    llvm_unreachable("macho doesn't support this directive");
88  }
89  void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
90                             unsigned ByteAlignment) override;
91  void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = nullptr,
92                    uint64_t Size = 0, unsigned ByteAlignment = 0) override;
93  virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
94                      uint64_t Size, unsigned ByteAlignment = 0) override;
95
96  void EmitFileDirective(StringRef Filename) override {
97    // FIXME: Just ignore the .file; it isn't important enough to fail the
98    // entire assembly.
99
100    // report_fatal_error("unsupported directive: '.file'");
101  }
102
103  void EmitIdent(StringRef IdentString) override {
104    llvm_unreachable("macho doesn't support this directive");
105  }
106
107  void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override {
108    getAssembler().getLOHContainer().addDirective(Kind, Args);
109  }
110
111  void FinishImpl() override;
112};
113
114} // end anonymous namespace.
115
116void MCMachOStreamer::ChangeSection(const MCSection *Section,
117                                    const MCExpr *Subsection) {
118  // Change the section normally.
119  MCObjectStreamer::ChangeSection(Section, Subsection);
120  // Output a linker-local symbol so we don't need section-relative local
121  // relocations. The linker hates us when we do that.
122  if (LabelSections && !HasSectionLabel[Section]) {
123    MCSymbol *Label = getContext().CreateLinkerPrivateTempSymbol();
124    EmitLabel(Label);
125    HasSectionLabel[Section] = true;
126  }
127}
128
129void MCMachOStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
130                                          MCSymbol *EHSymbol) {
131  MCSymbolData &SD =
132    getAssembler().getOrCreateSymbolData(*Symbol);
133  if (SD.isExternal())
134    EmitSymbolAttribute(EHSymbol, MCSA_Global);
135  if (SD.getFlags() & SF_WeakDefinition)
136    EmitSymbolAttribute(EHSymbol, MCSA_WeakDefinition);
137  if (SD.isPrivateExtern())
138    EmitSymbolAttribute(EHSymbol, MCSA_PrivateExtern);
139}
140
141void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) {
142  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
143
144  // isSymbolLinkerVisible uses the section.
145  AssignSection(Symbol, getCurrentSection().first);
146  // We have to create a new fragment if this is an atom defining symbol,
147  // fragments cannot span atoms.
148  if (getAssembler().isSymbolLinkerVisible(*Symbol))
149    insert(new MCDataFragment());
150
151  MCObjectStreamer::EmitLabel(Symbol);
152
153  MCSymbolData &SD = getAssembler().getSymbolData(*Symbol);
154  // This causes the reference type flag to be cleared. Darwin 'as' was "trying"
155  // to clear the weak reference and weak definition bits too, but the
156  // implementation was buggy. For now we just try to match 'as', for
157  // diffability.
158  //
159  // FIXME: Cleanup this code, these bits should be emitted based on semantic
160  // properties, not on the order of definition, etc.
161  SD.setFlags(SD.getFlags() & ~SF_ReferenceTypeMask);
162}
163
164void MCMachOStreamer::EmitDataRegion(DataRegionData::KindTy Kind) {
165  if (!getAssembler().getBackend().hasDataInCodeSupport())
166    return;
167  // Create a temporary label to mark the start of the data region.
168  MCSymbol *Start = getContext().CreateTempSymbol();
169  EmitLabel(Start);
170  // Record the region for the object writer to use.
171  DataRegionData Data = { Kind, Start, nullptr };
172  std::vector<DataRegionData> &Regions = getAssembler().getDataRegions();
173  Regions.push_back(Data);
174}
175
176void MCMachOStreamer::EmitDataRegionEnd() {
177  if (!getAssembler().getBackend().hasDataInCodeSupport())
178    return;
179  std::vector<DataRegionData> &Regions = getAssembler().getDataRegions();
180  assert(Regions.size() && "Mismatched .end_data_region!");
181  DataRegionData &Data = Regions.back();
182  assert(!Data.End && "Mismatched .end_data_region!");
183  // Create a temporary label to mark the end of the data region.
184  Data.End = getContext().CreateTempSymbol();
185  EmitLabel(Data.End);
186}
187
188void MCMachOStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
189  // Let the target do whatever target specific stuff it needs to do.
190  getAssembler().getBackend().handleAssemblerFlag(Flag);
191  // Do any generic stuff we need to do.
192  switch (Flag) {
193  case MCAF_SyntaxUnified: return; // no-op here.
194  case MCAF_Code16: return; // Change parsing mode; no-op here.
195  case MCAF_Code32: return; // Change parsing mode; no-op here.
196  case MCAF_Code64: return; // Change parsing mode; no-op here.
197  case MCAF_SubsectionsViaSymbols:
198    getAssembler().setSubsectionsViaSymbols(true);
199    return;
200  }
201}
202
203void MCMachOStreamer::EmitLinkerOptions(ArrayRef<std::string> Options) {
204  getAssembler().getLinkerOptions().push_back(Options);
205}
206
207void MCMachOStreamer::EmitDataRegion(MCDataRegionType Kind) {
208  switch (Kind) {
209  case MCDR_DataRegion:
210    EmitDataRegion(DataRegionData::Data);
211    return;
212  case MCDR_DataRegionJT8:
213    EmitDataRegion(DataRegionData::JumpTable8);
214    return;
215  case MCDR_DataRegionJT16:
216    EmitDataRegion(DataRegionData::JumpTable16);
217    return;
218  case MCDR_DataRegionJT32:
219    EmitDataRegion(DataRegionData::JumpTable32);
220    return;
221  case MCDR_DataRegionEnd:
222    EmitDataRegionEnd();
223    return;
224  }
225}
226
227void MCMachOStreamer::EmitVersionMin(MCVersionMinType Kind, unsigned Major,
228                                     unsigned Minor, unsigned Update) {
229  getAssembler().setVersionMinInfo(Kind, Major, Minor, Update);
230}
231
232void MCMachOStreamer::EmitThumbFunc(MCSymbol *Symbol) {
233  // Remember that the function is a thumb function. Fixup and relocation
234  // values will need adjusted.
235  getAssembler().setIsThumbFunc(Symbol);
236}
237
238bool MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
239                                          MCSymbolAttr Attribute) {
240  // Indirect symbols are handled differently, to match how 'as' handles
241  // them. This makes writing matching .o files easier.
242  if (Attribute == MCSA_IndirectSymbol) {
243    // Note that we intentionally cannot use the symbol data here; this is
244    // important for matching the string table that 'as' generates.
245    IndirectSymbolData ISD;
246    ISD.Symbol = Symbol;
247    ISD.SectionData = getCurrentSectionData();
248    getAssembler().getIndirectSymbols().push_back(ISD);
249    return true;
250  }
251
252  // Adding a symbol attribute always introduces the symbol, note that an
253  // important side effect of calling getOrCreateSymbolData here is to register
254  // the symbol with the assembler.
255  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
256
257  // The implementation of symbol attributes is designed to match 'as', but it
258  // leaves much to desired. It doesn't really make sense to arbitrarily add and
259  // remove flags, but 'as' allows this (in particular, see .desc).
260  //
261  // In the future it might be worth trying to make these operations more well
262  // defined.
263  switch (Attribute) {
264  case MCSA_Invalid:
265  case MCSA_ELF_TypeFunction:
266  case MCSA_ELF_TypeIndFunction:
267  case MCSA_ELF_TypeObject:
268  case MCSA_ELF_TypeTLS:
269  case MCSA_ELF_TypeCommon:
270  case MCSA_ELF_TypeNoType:
271  case MCSA_ELF_TypeGnuUniqueObject:
272  case MCSA_Hidden:
273  case MCSA_IndirectSymbol:
274  case MCSA_Internal:
275  case MCSA_Protected:
276  case MCSA_Weak:
277  case MCSA_Local:
278    return false;
279
280  case MCSA_Global:
281    SD.setExternal(true);
282    // This effectively clears the undefined lazy bit, in Darwin 'as', although
283    // it isn't very consistent because it implements this as part of symbol
284    // lookup.
285    //
286    // FIXME: Cleanup this code, these bits should be emitted based on semantic
287    // properties, not on the order of definition, etc.
288    SD.setFlags(SD.getFlags() & ~SF_ReferenceTypeUndefinedLazy);
289    break;
290
291  case MCSA_LazyReference:
292    // FIXME: This requires -dynamic.
293    SD.setFlags(SD.getFlags() | SF_NoDeadStrip);
294    if (Symbol->isUndefined())
295      SD.setFlags(SD.getFlags() | SF_ReferenceTypeUndefinedLazy);
296    break;
297
298    // Since .reference sets the no dead strip bit, it is equivalent to
299    // .no_dead_strip in practice.
300  case MCSA_Reference:
301  case MCSA_NoDeadStrip:
302    SD.setFlags(SD.getFlags() | SF_NoDeadStrip);
303    break;
304
305  case MCSA_SymbolResolver:
306    SD.setFlags(SD.getFlags() | SF_SymbolResolver);
307    break;
308
309  case MCSA_PrivateExtern:
310    SD.setExternal(true);
311    SD.setPrivateExtern(true);
312    break;
313
314  case MCSA_WeakReference:
315    // FIXME: This requires -dynamic.
316    if (Symbol->isUndefined())
317      SD.setFlags(SD.getFlags() | SF_WeakReference);
318    break;
319
320  case MCSA_WeakDefinition:
321    // FIXME: 'as' enforces that this is defined and global. The manual claims
322    // it has to be in a coalesced section, but this isn't enforced.
323    SD.setFlags(SD.getFlags() | SF_WeakDefinition);
324    break;
325
326  case MCSA_WeakDefAutoPrivate:
327    SD.setFlags(SD.getFlags() | SF_WeakDefinition | SF_WeakReference);
328    break;
329  }
330
331  return true;
332}
333
334void MCMachOStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
335  // Encode the 'desc' value into the lowest implementation defined bits.
336  assert(DescValue == (DescValue & SF_DescFlagsMask) &&
337         "Invalid .desc value!");
338  getAssembler().getOrCreateSymbolData(*Symbol).setFlags(
339    DescValue & SF_DescFlagsMask);
340}
341
342void MCMachOStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
343                                       unsigned ByteAlignment) {
344  // FIXME: Darwin 'as' does appear to allow redef of a .comm by itself.
345  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
346
347  AssignSection(Symbol, nullptr);
348
349  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
350  SD.setExternal(true);
351  SD.setCommon(Size, ByteAlignment);
352}
353
354void MCMachOStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
355                                            unsigned ByteAlignment) {
356  // '.lcomm' is equivalent to '.zerofill'.
357  return EmitZerofill(getContext().getObjectFileInfo()->getDataBSSSection(),
358                      Symbol, Size, ByteAlignment);
359}
360
361void MCMachOStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
362                                   uint64_t Size, unsigned ByteAlignment) {
363  MCSectionData &SectData = getAssembler().getOrCreateSectionData(*Section);
364
365  // The symbol may not be present, which only creates the section.
366  if (!Symbol)
367    return;
368
369  // On darwin all virtual sections have zerofill type.
370  assert(Section->isVirtualSection() && "Section does not have zerofill type!");
371
372  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
373
374  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
375
376  // Emit an align fragment if necessary.
377  if (ByteAlignment != 1)
378    new MCAlignFragment(ByteAlignment, 0, 0, ByteAlignment, &SectData);
379
380  MCFragment *F = new MCFillFragment(0, 0, Size, &SectData);
381  SD.setFragment(F);
382
383  AssignSection(Symbol, Section);
384
385  // Update the maximum alignment on the zero fill section if necessary.
386  if (ByteAlignment > SectData.getAlignment())
387    SectData.setAlignment(ByteAlignment);
388}
389
390// This should always be called with the thread local bss section.  Like the
391// .zerofill directive this doesn't actually switch sections on us.
392void MCMachOStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
393                                     uint64_t Size, unsigned ByteAlignment) {
394  EmitZerofill(Section, Symbol, Size, ByteAlignment);
395  return;
396}
397
398void MCMachOStreamer::EmitInstToData(const MCInst &Inst,
399                                     const MCSubtargetInfo &STI) {
400  MCDataFragment *DF = getOrCreateDataFragment();
401
402  SmallVector<MCFixup, 4> Fixups;
403  SmallString<256> Code;
404  raw_svector_ostream VecOS(Code);
405  getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups, STI);
406  VecOS.flush();
407
408  // Add the fixups and data.
409  for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
410    Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
411    DF->getFixups().push_back(Fixups[i]);
412  }
413  DF->getContents().append(Code.begin(), Code.end());
414}
415
416void MCMachOStreamer::FinishImpl() {
417  EmitFrames(&getAssembler().getBackend());
418
419  // We have to set the fragment atom associations so we can relax properly for
420  // Mach-O.
421
422  // First, scan the symbol table to build a lookup table from fragments to
423  // defining symbols.
424  DenseMap<const MCFragment*, MCSymbolData*> DefiningSymbolMap;
425  for (MCSymbolData &SD : getAssembler().symbols()) {
426    if (getAssembler().isSymbolLinkerVisible(SD.getSymbol()) &&
427        SD.getFragment()) {
428      // An atom defining symbol should never be internal to a fragment.
429      assert(SD.getOffset() == 0 && "Invalid offset in atom defining symbol!");
430      DefiningSymbolMap[SD.getFragment()] = &SD;
431    }
432  }
433
434  // Set the fragment atom associations by tracking the last seen atom defining
435  // symbol.
436  for (MCAssembler::iterator it = getAssembler().begin(),
437         ie = getAssembler().end(); it != ie; ++it) {
438    MCSymbolData *CurrentAtom = nullptr;
439    for (MCSectionData::iterator it2 = it->begin(),
440           ie2 = it->end(); it2 != ie2; ++it2) {
441      if (MCSymbolData *SD = DefiningSymbolMap.lookup(it2))
442        CurrentAtom = SD;
443      it2->setAtom(CurrentAtom);
444    }
445  }
446
447  this->MCObjectStreamer::FinishImpl();
448}
449
450MCStreamer *llvm::createMachOStreamer(MCContext &Context, MCAsmBackend &MAB,
451                                      raw_ostream &OS, MCCodeEmitter *CE,
452                                      bool RelaxAll,
453                                      bool LabelSections) {
454  MCMachOStreamer *S = new MCMachOStreamer(Context, MAB, OS, CE, LabelSections);
455  if (RelaxAll)
456    S->getAssembler().setRelaxAll(true);
457  return S;
458}
459