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

Generated by: LCOV version 1.13