LCOV - code coverage report
Current view: top level - lib/MC - MCMachOStreamer.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 170 181 93.9 %
Date: 2017-09-14 15:23:50 Functions: 22 25 88.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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/ADT/DenseMap.h"
      11             : #include "llvm/ADT/SmallString.h"
      12             : #include "llvm/ADT/SmallVector.h"
      13             : #include "llvm/ADT/StringRef.h"
      14             : #include "llvm/ADT/Triple.h"
      15             : #include "llvm/MC/MCAsmBackend.h"
      16             : #include "llvm/MC/MCAssembler.h"
      17             : #include "llvm/MC/MCCodeEmitter.h"
      18             : #include "llvm/MC/MCContext.h"
      19             : #include "llvm/MC/MCDirectives.h"
      20             : #include "llvm/MC/MCExpr.h"
      21             : #include "llvm/MC/MCFixup.h"
      22             : #include "llvm/MC/MCFragment.h"
      23             : #include "llvm/MC/MCInst.h"
      24             : #include "llvm/MC/MCLinkerOptimizationHint.h"
      25             : #include "llvm/MC/MCObjectFileInfo.h"
      26             : #include "llvm/MC/MCObjectStreamer.h"
      27             : #include "llvm/MC/MCSection.h"
      28             : #include "llvm/MC/MCSectionMachO.h"
      29             : #include "llvm/MC/MCStreamer.h"
      30             : #include "llvm/MC/MCSymbol.h"
      31             : #include "llvm/MC/MCSymbolMachO.h"
      32             : #include "llvm/MC/MCValue.h"
      33             : #include "llvm/Support/Casting.h"
      34             : #include "llvm/Support/ErrorHandling.h"
      35             : #include "llvm/Support/TargetRegistry.h"
      36             : #include "llvm/Support/raw_ostream.h"
      37             : #include <cassert>
      38             : #include <vector>
      39             : 
      40             : using namespace llvm;
      41             : 
      42             : namespace {
      43             : 
      44        1052 : class MCMachOStreamer : public MCObjectStreamer {
      45             : private:
      46             :   /// LabelSections - true if each section change should emit a linker local
      47             :   /// label for use in relocations for assembler local references. Obviates the
      48             :   /// need for local relocations. False by default.
      49             :   bool LabelSections;
      50             : 
      51             :   bool DWARFMustBeAtTheEnd;
      52             :   bool CreatedADWARFSection;
      53             : 
      54             :   /// HasSectionLabel - map of which sections have already had a non-local
      55             :   /// label emitted to them. Used so we don't emit extraneous linker local
      56             :   /// labels in the middle of the section.
      57             :   DenseMap<const MCSection*, bool> HasSectionLabel;
      58             : 
      59             :   void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &STI) override;
      60             : 
      61             :   void EmitDataRegion(DataRegionData::KindTy Kind);
      62             :   void EmitDataRegionEnd();
      63             : 
      64             : public:
      65             :   MCMachOStreamer(MCContext &Context, MCAsmBackend &MAB, raw_pwrite_stream &OS,
      66             :                   MCCodeEmitter *Emitter, bool DWARFMustBeAtTheEnd, bool label)
      67         527 :       : MCObjectStreamer(Context, MAB, OS, Emitter), LabelSections(label),
      68        1054 :         DWARFMustBeAtTheEnd(DWARFMustBeAtTheEnd), CreatedADWARFSection(false) {}
      69             : 
      70             :   /// state management
      71         245 :   void reset() override {
      72         245 :     CreatedADWARFSection = false;
      73         245 :     HasSectionLabel.clear();
      74         245 :     MCObjectStreamer::reset();
      75         245 :   }
      76             : 
      77             :   /// @name MCStreamer Interface
      78             :   /// @{
      79             : 
      80             :   void ChangeSection(MCSection *Sect, const MCExpr *Subsect) override;
      81             :   void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
      82             :   void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
      83             :   void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol) override;
      84             :   void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
      85             :   void EmitLinkerOptions(ArrayRef<std::string> Options) override;
      86             :   void EmitDataRegion(MCDataRegionType Kind) override;
      87             :   void EmitVersionMin(MCVersionMinType Kind, unsigned Major,
      88             :                       unsigned Minor, unsigned Update) override;
      89             :   void EmitThumbFunc(MCSymbol *Func) override;
      90             :   bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
      91             :   void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
      92             :   void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
      93             :                         unsigned ByteAlignment) override;
      94             : 
      95             :   void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
      96             :                              unsigned ByteAlignment) override;
      97             :   void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
      98             :                     uint64_t Size = 0, unsigned ByteAlignment = 0) override;
      99             :   void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
     100             :                       unsigned ByteAlignment = 0) override;
     101             : 
     102           0 :   void EmitIdent(StringRef IdentString) override {
     103           0 :     llvm_unreachable("macho doesn't support this directive");
     104             :   }
     105             : 
     106           1 :   void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override {
     107           2 :     getAssembler().getLOHContainer().addDirective(Kind, Args);
     108           1 :   }
     109             : 
     110             :   void FinishImpl() override;
     111             : };
     112             : 
     113             : } // end anonymous namespace.
     114             : 
     115             : static bool canGoAfterDWARF(const MCSectionMachO &MSec) {
     116             :   // These sections are created by the assembler itself after the end of
     117             :   // the .s file.
     118             :   StringRef SegName = MSec.getSegmentName();
     119             :   StringRef SecName = MSec.getSectionName();
     120             : 
     121             :   if (SegName == "__LD" && SecName == "__compact_unwind")
     122             :     return true;
     123             : 
     124             :   if (SegName == "__IMPORT") {
     125             :     if (SecName == "__jump_table")
     126             :       return true;
     127             : 
     128             :     if (SecName == "__pointers")
     129             :       return true;
     130             :   }
     131             : 
     132             :   if (SegName == "__TEXT" && SecName == "__eh_frame")
     133             :     return true;
     134             : 
     135             :   if (SegName == "__DATA" && (SecName == "__nl_symbol_ptr" ||
     136             :                               SecName == "__thread_ptr"))
     137             :     return true;
     138             : 
     139             :   return false;
     140             : }
     141             : 
     142        3373 : void MCMachOStreamer::ChangeSection(MCSection *Section,
     143             :                                     const MCExpr *Subsection) {
     144             :   // Change the section normally.
     145        3373 :   bool Created = changeSectionImpl(Section, Subsection);
     146        3373 :   const MCSectionMachO &MSec = *cast<MCSectionMachO>(Section);
     147        3373 :   StringRef SegName = MSec.getSegmentName();
     148        5538 :   if (SegName == "__DWARF")
     149        2165 :     CreatedADWARFSection = true;
     150             :   else if (Created && DWARFMustBeAtTheEnd && !canGoAfterDWARF(MSec))
     151             :     assert(!CreatedADWARFSection && "Creating regular section after DWARF");
     152             : 
     153             :   // Output a linker-local symbol so we don't need section-relative local
     154             :   // relocations. The linker hates us when we do that.
     155        3627 :   if (LabelSections && !HasSectionLabel[Section] &&
     156         122 :       !Section->getBeginSymbol()) {
     157          69 :     MCSymbol *Label = getContext().createLinkerPrivateTempSymbol();
     158         138 :     Section->setBeginSymbol(Label);
     159         138 :     HasSectionLabel[Section] = true;
     160             :   }
     161        3373 : }
     162             : 
     163           0 : void MCMachOStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
     164             :                                           MCSymbol *EHSymbol) {
     165           0 :   getAssembler().registerSymbol(*Symbol);
     166           0 :   if (Symbol->isExternal())
     167           0 :     EmitSymbolAttribute(EHSymbol, MCSA_Global);
     168           0 :   if (cast<MCSymbolMachO>(Symbol)->isWeakDefinition())
     169           0 :     EmitSymbolAttribute(EHSymbol, MCSA_WeakDefinition);
     170           0 :   if (Symbol->isPrivateExtern())
     171           0 :     EmitSymbolAttribute(EHSymbol, MCSA_PrivateExtern);
     172           0 : }
     173             : 
     174       10217 : void MCMachOStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
     175             :   // We have to create a new fragment if this is an atom defining symbol,
     176             :   // fragments cannot span atoms.
     177       10217 :   if (getAssembler().isSymbolLinkerVisible(*Symbol))
     178        1880 :     insert(new MCDataFragment());
     179             : 
     180       10217 :   MCObjectStreamer::EmitLabel(Symbol, Loc);
     181             : 
     182             :   // This causes the reference type flag to be cleared. Darwin 'as' was "trying"
     183             :   // to clear the weak reference and weak definition bits too, but the
     184             :   // implementation was buggy. For now we just try to match 'as', for
     185             :   // diffability.
     186             :   //
     187             :   // FIXME: Cleanup this code, these bits should be emitted based on semantic
     188             :   // properties, not on the order of definition, etc.
     189       20434 :   cast<MCSymbolMachO>(Symbol)->clearReferenceType();
     190       10217 : }
     191             : 
     192        2425 : void MCMachOStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
     193        2425 :   MCValue Res;
     194             : 
     195        2425 :   if (Value->evaluateAsRelocatable(Res, nullptr, nullptr)) {
     196        2425 :     if (const MCSymbolRefExpr *SymAExpr = Res.getSymA()) {
     197        2421 :       const MCSymbol &SymA = SymAExpr->getSymbol();
     198        2499 :       if (!Res.getSymB() && (SymA.getName() == "" || Res.getConstant() != 0))
     199          18 :         cast<MCSymbolMachO>(Symbol)->setAltEntry();
     200             :     }
     201             :   }
     202        2425 :   MCObjectStreamer::EmitAssignment(Symbol, Value);
     203        2425 : }
     204             : 
     205          47 : void MCMachOStreamer::EmitDataRegion(DataRegionData::KindTy Kind) {
     206             :   // Create a temporary label to mark the start of the data region.
     207          47 :   MCSymbol *Start = getContext().createTempSymbol();
     208          47 :   EmitLabel(Start);
     209             :   // Record the region for the object writer to use.
     210          47 :   DataRegionData Data = { Kind, Start, nullptr };
     211          94 :   std::vector<DataRegionData> &Regions = getAssembler().getDataRegions();
     212          47 :   Regions.push_back(Data);
     213          47 : }
     214             : 
     215          47 : void MCMachOStreamer::EmitDataRegionEnd() {
     216          47 :   std::vector<DataRegionData> &Regions = getAssembler().getDataRegions();
     217             :   assert(!Regions.empty() && "Mismatched .end_data_region!");
     218          47 :   DataRegionData &Data = Regions.back();
     219             :   assert(!Data.End && "Mismatched .end_data_region!");
     220             :   // Create a temporary label to mark the end of the data region.
     221          47 :   Data.End = getContext().createTempSymbol();
     222          47 :   EmitLabel(Data.End);
     223          47 : }
     224             : 
     225         459 : void MCMachOStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
     226             :   // Let the target do whatever target specific stuff it needs to do.
     227         459 :   getAssembler().getBackend().handleAssemblerFlag(Flag);
     228             :   // Do any generic stuff we need to do.
     229         459 :   switch (Flag) {
     230             :   case MCAF_SyntaxUnified: return; // no-op here.
     231             :   case MCAF_Code16: return; // Change parsing mode; no-op here.
     232             :   case MCAF_Code32: return; // Change parsing mode; no-op here.
     233             :   case MCAF_Code64: return; // Change parsing mode; no-op here.
     234         283 :   case MCAF_SubsectionsViaSymbols:
     235         283 :     getAssembler().setSubsectionsViaSymbols(true);
     236             :     return;
     237             :   }
     238             : }
     239             : 
     240           5 : void MCMachOStreamer::EmitLinkerOptions(ArrayRef<std::string> Options) {
     241          20 :   getAssembler().getLinkerOptions().push_back(Options);
     242           5 : }
     243             : 
     244          94 : void MCMachOStreamer::EmitDataRegion(MCDataRegionType Kind) {
     245          94 :   switch (Kind) {
     246          31 :   case MCDR_DataRegion:
     247          31 :     EmitDataRegion(DataRegionData::Data);
     248          31 :     return;
     249           4 :   case MCDR_DataRegionJT8:
     250           4 :     EmitDataRegion(DataRegionData::JumpTable8);
     251           4 :     return;
     252           6 :   case MCDR_DataRegionJT16:
     253           6 :     EmitDataRegion(DataRegionData::JumpTable16);
     254           6 :     return;
     255           6 :   case MCDR_DataRegionJT32:
     256           6 :     EmitDataRegion(DataRegionData::JumpTable32);
     257           6 :     return;
     258          47 :   case MCDR_DataRegionEnd:
     259          47 :     EmitDataRegionEnd();
     260          47 :     return;
     261             :   }
     262             : }
     263             : 
     264         136 : void MCMachOStreamer::EmitVersionMin(MCVersionMinType Kind, unsigned Major,
     265             :                                      unsigned Minor, unsigned Update) {
     266         532 :   getAssembler().setVersionMinInfo(Kind, Major, Minor, Update);
     267         136 : }
     268             : 
     269         102 : void MCMachOStreamer::EmitThumbFunc(MCSymbol *Symbol) {
     270             :   // Remember that the function is a thumb function. Fixup and relocation
     271             :   // values will need adjusted.
     272         204 :   getAssembler().setIsThumbFunc(Symbol);
     273         204 :   cast<MCSymbolMachO>(Symbol)->setThumbFunc();
     274         102 : }
     275             : 
     276         719 : bool MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Sym,
     277             :                                           MCSymbolAttr Attribute) {
     278         719 :   MCSymbolMachO *Symbol = cast<MCSymbolMachO>(Sym);
     279             : 
     280             :   // Indirect symbols are handled differently, to match how 'as' handles
     281             :   // them. This makes writing matching .o files easier.
     282         719 :   if (Attribute == MCSA_IndirectSymbol) {
     283             :     // Note that we intentionally cannot use the symbol data here; this is
     284             :     // important for matching the string table that 'as' generates.
     285             :     IndirectSymbolData ISD;
     286          41 :     ISD.Symbol = Symbol;
     287          82 :     ISD.Section = getCurrentSectionOnly();
     288          82 :     getAssembler().getIndirectSymbols().push_back(ISD);
     289             :     return true;
     290             :   }
     291             : 
     292             :   // Adding a symbol attribute always introduces the symbol, note that an
     293             :   // important side effect of calling registerSymbol here is to register
     294             :   // the symbol with the assembler.
     295         678 :   getAssembler().registerSymbol(*Symbol);
     296             : 
     297             :   // The implementation of symbol attributes is designed to match 'as', but it
     298             :   // leaves much to desired. It doesn't really make sense to arbitrarily add and
     299             :   // remove flags, but 'as' allows this (in particular, see .desc).
     300             :   //
     301             :   // In the future it might be worth trying to make these operations more well
     302             :   // defined.
     303         678 :   switch (Attribute) {
     304             :   case MCSA_Invalid:
     305             :   case MCSA_ELF_TypeFunction:
     306             :   case MCSA_ELF_TypeIndFunction:
     307             :   case MCSA_ELF_TypeObject:
     308             :   case MCSA_ELF_TypeTLS:
     309             :   case MCSA_ELF_TypeCommon:
     310             :   case MCSA_ELF_TypeNoType:
     311             :   case MCSA_ELF_TypeGnuUniqueObject:
     312             :   case MCSA_Hidden:
     313             :   case MCSA_IndirectSymbol:
     314             :   case MCSA_Internal:
     315             :   case MCSA_Protected:
     316             :   case MCSA_Weak:
     317             :   case MCSA_Local:
     318             :     return false;
     319             : 
     320         562 :   case MCSA_Global:
     321        1124 :     Symbol->setExternal(true);
     322             :     // This effectively clears the undefined lazy bit, in Darwin 'as', although
     323             :     // it isn't very consistent because it implements this as part of symbol
     324             :     // lookup.
     325             :     //
     326             :     // FIXME: Cleanup this code, these bits should be emitted based on semantic
     327             :     // properties, not on the order of definition, etc.
     328             :     Symbol->setReferenceTypeUndefinedLazy(false);
     329             :     break;
     330             : 
     331           5 :   case MCSA_LazyReference:
     332             :     // FIXME: This requires -dynamic.
     333           5 :     Symbol->setNoDeadStrip();
     334          10 :     if (Symbol->isUndefined())
     335             :       Symbol->setReferenceTypeUndefinedLazy(true);
     336             :     break;
     337             : 
     338             :     // Since .reference sets the no dead strip bit, it is equivalent to
     339             :     // .no_dead_strip in practice.
     340          41 :   case MCSA_Reference:
     341             :   case MCSA_NoDeadStrip:
     342             :     Symbol->setNoDeadStrip();
     343             :     break;
     344             : 
     345           1 :   case MCSA_SymbolResolver:
     346             :     Symbol->setSymbolResolver();
     347             :     break;
     348             : 
     349           3 :   case MCSA_AltEntry:
     350             :     Symbol->setAltEntry();
     351             :     break;
     352             : 
     353          17 :   case MCSA_PrivateExtern:
     354          34 :     Symbol->setExternal(true);
     355          17 :     Symbol->setPrivateExtern(true);
     356             :     break;
     357             : 
     358           5 :   case MCSA_WeakReference:
     359             :     // FIXME: This requires -dynamic.
     360          10 :     if (Symbol->isUndefined())
     361             :       Symbol->setWeakReference();
     362             :     break;
     363             : 
     364          34 :   case MCSA_WeakDefinition:
     365             :     // FIXME: 'as' enforces that this is defined and global. The manual claims
     366             :     // it has to be in a coalesced section, but this isn't enforced.
     367             :     Symbol->setWeakDefinition();
     368             :     break;
     369             : 
     370           6 :   case MCSA_WeakDefAutoPrivate:
     371           6 :     Symbol->setWeakDefinition();
     372             :     Symbol->setWeakReference();
     373             :     break;
     374             :   }
     375             : 
     376             :   return true;
     377             : }
     378             : 
     379           4 : void MCMachOStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
     380             :   // Encode the 'desc' value into the lowest implementation defined bits.
     381           4 :   getAssembler().registerSymbol(*Symbol);
     382           8 :   cast<MCSymbolMachO>(Symbol)->setDesc(DescValue);
     383           4 : }
     384             : 
     385          51 : void MCMachOStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
     386             :                                        unsigned ByteAlignment) {
     387             :   // FIXME: Darwin 'as' does appear to allow redef of a .comm by itself.
     388             :   assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
     389             : 
     390          51 :   getAssembler().registerSymbol(*Symbol);
     391          51 :   Symbol->setExternal(true);
     392          51 :   Symbol->setCommon(Size, ByteAlignment);
     393          51 : }
     394             : 
     395           6 : void MCMachOStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
     396             :                                             unsigned ByteAlignment) {
     397             :   // '.lcomm' is equivalent to '.zerofill'.
     398           6 :   return EmitZerofill(getContext().getObjectFileInfo()->getDataBSSSection(),
     399           6 :                       Symbol, Size, ByteAlignment);
     400             : }
     401             : 
     402          60 : void MCMachOStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol,
     403             :                                    uint64_t Size, unsigned ByteAlignment) {
     404          60 :   getAssembler().registerSection(*Section);
     405             : 
     406             :   // The symbol may not be present, which only creates the section.
     407          60 :   if (!Symbol)
     408             :     return;
     409             : 
     410             :   // On darwin all virtual sections have zerofill type.
     411             :   assert(Section->isVirtualSection() && "Section does not have zerofill type!");
     412             : 
     413             :   assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
     414             : 
     415          60 :   getAssembler().registerSymbol(*Symbol);
     416             : 
     417             :   // Emit an align fragment if necessary.
     418          60 :   if (ByteAlignment != 1)
     419          38 :     new MCAlignFragment(ByteAlignment, 0, 0, ByteAlignment, Section);
     420             : 
     421         120 :   MCFragment *F = new MCFillFragment(0, Size, Section);
     422          60 :   Symbol->setFragment(F);
     423             : 
     424             :   // Update the maximum alignment on the zero fill section if necessary.
     425          60 :   if (ByteAlignment > Section->getAlignment())
     426          33 :     Section->setAlignment(ByteAlignment);
     427             : }
     428             : 
     429             : // This should always be called with the thread local bss section.  Like the
     430             : // .zerofill directive this doesn't actually switch sections on us.
     431           6 : void MCMachOStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
     432             :                                      uint64_t Size, unsigned ByteAlignment) {
     433           6 :   EmitZerofill(Section, Symbol, Size, ByteAlignment);
     434           6 : }
     435             : 
     436       13618 : void MCMachOStreamer::EmitInstToData(const MCInst &Inst,
     437             :                                      const MCSubtargetInfo &STI) {
     438       13618 :   MCDataFragment *DF = getOrCreateDataFragment();
     439             : 
     440       27236 :   SmallVector<MCFixup, 4> Fixups;
     441       27236 :   SmallString<256> Code;
     442       27236 :   raw_svector_ostream VecOS(Code);
     443       13618 :   getAssembler().getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI);
     444             : 
     445             :   // Add the fixups and data.
     446       43054 :   for (MCFixup &Fixup : Fixups) {
     447        6600 :     Fixup.setOffset(Fixup.getOffset() + DF->getContents().size());
     448        2200 :     DF->getFixups().push_back(Fixup);
     449             :   }
     450       54472 :   DF->getContents().append(Code.begin(), Code.end());
     451       13618 : }
     452             : 
     453         499 : void MCMachOStreamer::FinishImpl() {
     454         499 :   EmitFrames(&getAssembler().getBackend());
     455             : 
     456             :   // We have to set the fragment atom associations so we can relax properly for
     457             :   // Mach-O.
     458             : 
     459             :   // First, scan the symbol table to build a lookup table from fragments to
     460             :   // defining symbols.
     461         997 :   DenseMap<const MCFragment *, const MCSymbol *> DefiningSymbolMap;
     462       24525 :   for (const MCSymbol &Symbol : getAssembler().symbols()) {
     463       12541 :     if (getAssembler().isSymbolLinkerVisible(Symbol) && Symbol.isInSection() &&
     464        1027 :         !Symbol.isVariable()) {
     465             :       // An atom defining symbol should never be internal to a fragment.
     466             :       assert(Symbol.getOffset() == 0 &&
     467             :              "Invalid offset in atom defining symbol!");
     468        1996 :       DefiningSymbolMap[Symbol.getFragment()] = &Symbol;
     469             :     }
     470             :   }
     471             : 
     472             :   // Set the fragment atom associations by tracking the last seen atom defining
     473             :   // symbol.
     474        6992 :   for (MCSection &Sec : getAssembler()) {
     475        2498 :     const MCSymbol *CurrentAtom = nullptr;
     476       13100 :     for (MCFragment &Frag : Sec) {
     477        5606 :       if (const MCSymbol *Symbol = DefiningSymbolMap.lookup(&Frag))
     478         998 :         CurrentAtom = Symbol;
     479       11212 :       Frag.setAtom(CurrentAtom);
     480             :     }
     481             :   }
     482             : 
     483         499 :   this->MCObjectStreamer::FinishImpl();
     484         498 : }
     485             : 
     486         527 : MCStreamer *llvm::createMachOStreamer(MCContext &Context, MCAsmBackend &MAB,
     487             :                                       raw_pwrite_stream &OS, MCCodeEmitter *CE,
     488             :                                       bool RelaxAll, bool DWARFMustBeAtTheEnd,
     489             :                                       bool LabelSections) {
     490             :   MCMachOStreamer *S = new MCMachOStreamer(Context, MAB, OS, CE,
     491        1054 :                                            DWARFMustBeAtTheEnd, LabelSections);
     492        1054 :   const Triple &TT = Context.getObjectFileInfo()->getTargetTriple();
     493             :   if (TT.isOSDarwin()) {
     494             :     unsigned Major, Minor, Update;
     495         269 :     TT.getOSVersion(Major, Minor, Update);
     496             :     // If there is a version specified, Major will be non-zero.
     497         269 :     if (Major) {
     498             :       MCVersionMinType VersionType;
     499         130 :       if (TT.isWatchOS())
     500             :         VersionType = MCVM_WatchOSVersionMin;
     501         128 :       else if (TT.isTvOS())
     502             :         VersionType = MCVM_TvOSVersionMin;
     503           9 :       else if (TT.isMacOSX())
     504             :         VersionType = MCVM_OSXVersionMin;
     505             :       else {
     506             :         assert(TT.isiOS() && "Must only be iOS platform left");
     507             :         VersionType = MCVM_IOSVersionMin;
     508             :       }
     509         130 :       S->EmitVersionMin(VersionType, Major, Minor, Update);
     510             :     }
     511             :   }
     512         527 :   if (RelaxAll)
     513           3 :     S->getAssembler().setRelaxAll(true);
     514         527 :   return S;
     515             : }

Generated by: LCOV version 1.13