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

Generated by: LCOV version 1.13