Home | History | Annotate | Line # | Download | only in MC
      1 //===- MCMachOStreamer.cpp - MachO Streamer -------------------------------===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 
      9 #include "llvm/ADT/DenseMap.h"
     10 #include "llvm/ADT/SmallString.h"
     11 #include "llvm/ADT/SmallVector.h"
     12 #include "llvm/ADT/StringRef.h"
     13 #include "llvm/ADT/Triple.h"
     14 #include "llvm/MC/MCAsmBackend.h"
     15 #include "llvm/MC/MCAssembler.h"
     16 #include "llvm/MC/MCCodeEmitter.h"
     17 #include "llvm/MC/MCContext.h"
     18 #include "llvm/MC/MCDirectives.h"
     19 #include "llvm/MC/MCExpr.h"
     20 #include "llvm/MC/MCFixup.h"
     21 #include "llvm/MC/MCFragment.h"
     22 #include "llvm/MC/MCInst.h"
     23 #include "llvm/MC/MCLinkerOptimizationHint.h"
     24 #include "llvm/MC/MCObjectFileInfo.h"
     25 #include "llvm/MC/MCObjectStreamer.h"
     26 #include "llvm/MC/MCObjectWriter.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 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, std::unique_ptr<MCAsmBackend> MAB,
     66                   std::unique_ptr<MCObjectWriter> OW,
     67                   std::unique_ptr<MCCodeEmitter> Emitter,
     68                   bool DWARFMustBeAtTheEnd, bool label)
     69       : MCObjectStreamer(Context, std::move(MAB), std::move(OW),
     70                          std::move(Emitter)),
     71         LabelSections(label), DWARFMustBeAtTheEnd(DWARFMustBeAtTheEnd),
     72         CreatedADWARFSection(false) {}
     73 
     74   /// state management
     75   void reset() override {
     76     CreatedADWARFSection = false;
     77     HasSectionLabel.clear();
     78     MCObjectStreamer::reset();
     79   }
     80 
     81   /// @name MCStreamer Interface
     82   /// @{
     83 
     84   void changeSection(MCSection *Sect, const MCExpr *Subsect) override;
     85   void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
     86   void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
     87   void emitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol) override;
     88   void emitAssemblerFlag(MCAssemblerFlag Flag) override;
     89   void emitLinkerOptions(ArrayRef<std::string> Options) override;
     90   void emitDataRegion(MCDataRegionType Kind) override;
     91   void emitVersionMin(MCVersionMinType Kind, unsigned Major, unsigned Minor,
     92                       unsigned Update, VersionTuple SDKVersion) override;
     93   void emitBuildVersion(unsigned Platform, unsigned Major, unsigned Minor,
     94                         unsigned Update, VersionTuple SDKVersion) override;
     95   void emitThumbFunc(MCSymbol *Func) override;
     96   bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
     97   void emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
     98   void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
     99                         unsigned ByteAlignment) override;
    100 
    101   void emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
    102                              unsigned ByteAlignment) override;
    103   void emitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
    104                     uint64_t Size = 0, unsigned ByteAlignment = 0,
    105                     SMLoc Loc = SMLoc()) override;
    106   void emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
    107                       unsigned ByteAlignment = 0) override;
    108 
    109   void emitIdent(StringRef IdentString) override {
    110     llvm_unreachable("macho doesn't support this directive");
    111   }
    112 
    113   void emitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override {
    114     getAssembler().getLOHContainer().addDirective(Kind, Args);
    115   }
    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.getName();
    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 void MCMachOStreamer::changeSection(MCSection *Section,
    150                                     const MCExpr *Subsection) {
    151   // Change the section normally.
    152   bool Created = changeSectionImpl(Section, Subsection);
    153   const MCSectionMachO &MSec = *cast<MCSectionMachO>(Section);
    154   StringRef SegName = MSec.getSegmentName();
    155   if (SegName == "__DWARF")
    156     CreatedADWARFSection = true;
    157   else if (Created && DWARFMustBeAtTheEnd && !canGoAfterDWARF(MSec))
    158     assert((!CreatedADWARFSection ||
    159             Section == getContext().getObjectFileInfo()->getStackMapSection())
    160            && "Creating regular section after DWARF");
    161 
    162   // Output a linker-local symbol so we don't need section-relative local
    163   // relocations. The linker hates us when we do that.
    164   if (LabelSections && !HasSectionLabel[Section] &&
    165       !Section->getBeginSymbol()) {
    166     MCSymbol *Label = getContext().createLinkerPrivateTempSymbol();
    167     Section->setBeginSymbol(Label);
    168     HasSectionLabel[Section] = true;
    169   }
    170 }
    171 
    172 void MCMachOStreamer::emitEHSymAttributes(const MCSymbol *Symbol,
    173                                           MCSymbol *EHSymbol) {
    174   getAssembler().registerSymbol(*Symbol);
    175   if (Symbol->isExternal())
    176     emitSymbolAttribute(EHSymbol, MCSA_Global);
    177   if (cast<MCSymbolMachO>(Symbol)->isWeakDefinition())
    178     emitSymbolAttribute(EHSymbol, MCSA_WeakDefinition);
    179   if (Symbol->isPrivateExtern())
    180     emitSymbolAttribute(EHSymbol, MCSA_PrivateExtern);
    181 }
    182 
    183 void MCMachOStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
    184   // We have to create a new fragment if this is an atom defining symbol,
    185   // fragments cannot span atoms.
    186   if (getAssembler().isSymbolLinkerVisible(*Symbol))
    187     insert(new MCDataFragment());
    188 
    189   MCObjectStreamer::emitLabel(Symbol, Loc);
    190 
    191   // This causes the reference type flag to be cleared. Darwin 'as' was "trying"
    192   // to clear the weak reference and weak definition bits too, but the
    193   // implementation was buggy. For now we just try to match 'as', for
    194   // diffability.
    195   //
    196   // FIXME: Cleanup this code, these bits should be emitted based on semantic
    197   // properties, not on the order of definition, etc.
    198   cast<MCSymbolMachO>(Symbol)->clearReferenceType();
    199 }
    200 
    201 void MCMachOStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
    202   MCValue Res;
    203 
    204   if (Value->evaluateAsRelocatable(Res, nullptr, nullptr)) {
    205     if (const MCSymbolRefExpr *SymAExpr = Res.getSymA()) {
    206       const MCSymbol &SymA = SymAExpr->getSymbol();
    207       if (!Res.getSymB() && (SymA.getName() == "" || Res.getConstant() != 0))
    208         cast<MCSymbolMachO>(Symbol)->setAltEntry();
    209     }
    210   }
    211   MCObjectStreamer::emitAssignment(Symbol, Value);
    212 }
    213 
    214 void MCMachOStreamer::emitDataRegion(DataRegionData::KindTy Kind) {
    215   // Create a temporary label to mark the start of the data region.
    216   MCSymbol *Start = getContext().createTempSymbol();
    217   emitLabel(Start);
    218   // Record the region for the object writer to use.
    219   DataRegionData Data = { Kind, Start, nullptr };
    220   std::vector<DataRegionData> &Regions = getAssembler().getDataRegions();
    221   Regions.push_back(Data);
    222 }
    223 
    224 void MCMachOStreamer::emitDataRegionEnd() {
    225   std::vector<DataRegionData> &Regions = getAssembler().getDataRegions();
    226   assert(!Regions.empty() && "Mismatched .end_data_region!");
    227   DataRegionData &Data = Regions.back();
    228   assert(!Data.End && "Mismatched .end_data_region!");
    229   // Create a temporary label to mark the end of the data region.
    230   Data.End = getContext().createTempSymbol();
    231   emitLabel(Data.End);
    232 }
    233 
    234 void MCMachOStreamer::emitAssemblerFlag(MCAssemblerFlag Flag) {
    235   // Let the target do whatever target specific stuff it needs to do.
    236   getAssembler().getBackend().handleAssemblerFlag(Flag);
    237   // Do any generic stuff we need to do.
    238   switch (Flag) {
    239   case MCAF_SyntaxUnified: return; // no-op here.
    240   case MCAF_Code16: return; // Change parsing mode; no-op here.
    241   case MCAF_Code32: return; // Change parsing mode; no-op here.
    242   case MCAF_Code64: return; // Change parsing mode; no-op here.
    243   case MCAF_SubsectionsViaSymbols:
    244     getAssembler().setSubsectionsViaSymbols(true);
    245     return;
    246   }
    247 }
    248 
    249 void MCMachOStreamer::emitLinkerOptions(ArrayRef<std::string> Options) {
    250   getAssembler().getLinkerOptions().push_back(Options);
    251 }
    252 
    253 void MCMachOStreamer::emitDataRegion(MCDataRegionType Kind) {
    254   switch (Kind) {
    255   case MCDR_DataRegion:
    256     emitDataRegion(DataRegionData::Data);
    257     return;
    258   case MCDR_DataRegionJT8:
    259     emitDataRegion(DataRegionData::JumpTable8);
    260     return;
    261   case MCDR_DataRegionJT16:
    262     emitDataRegion(DataRegionData::JumpTable16);
    263     return;
    264   case MCDR_DataRegionJT32:
    265     emitDataRegion(DataRegionData::JumpTable32);
    266     return;
    267   case MCDR_DataRegionEnd:
    268     emitDataRegionEnd();
    269     return;
    270   }
    271 }
    272 
    273 void MCMachOStreamer::emitVersionMin(MCVersionMinType Kind, unsigned Major,
    274                                      unsigned Minor, unsigned Update,
    275                                      VersionTuple SDKVersion) {
    276   getAssembler().setVersionMin(Kind, Major, Minor, Update, SDKVersion);
    277 }
    278 
    279 void MCMachOStreamer::emitBuildVersion(unsigned Platform, unsigned Major,
    280                                        unsigned Minor, unsigned Update,
    281                                        VersionTuple SDKVersion) {
    282   getAssembler().setBuildVersion((MachO::PlatformType)Platform, Major, Minor,
    283                                  Update, SDKVersion);
    284 }
    285 
    286 void MCMachOStreamer::emitThumbFunc(MCSymbol *Symbol) {
    287   // Remember that the function is a thumb function. Fixup and relocation
    288   // values will need adjusted.
    289   getAssembler().setIsThumbFunc(Symbol);
    290   cast<MCSymbolMachO>(Symbol)->setThumbFunc();
    291 }
    292 
    293 bool MCMachOStreamer::emitSymbolAttribute(MCSymbol *Sym,
    294                                           MCSymbolAttr Attribute) {
    295   MCSymbolMachO *Symbol = cast<MCSymbolMachO>(Sym);
    296 
    297   // Indirect symbols are handled differently, to match how 'as' handles
    298   // them. This makes writing matching .o files easier.
    299   if (Attribute == MCSA_IndirectSymbol) {
    300     // Note that we intentionally cannot use the symbol data here; this is
    301     // important for matching the string table that 'as' generates.
    302     IndirectSymbolData ISD;
    303     ISD.Symbol = Symbol;
    304     ISD.Section = getCurrentSectionOnly();
    305     getAssembler().getIndirectSymbols().push_back(ISD);
    306     return true;
    307   }
    308 
    309   // Adding a symbol attribute always introduces the symbol, note that an
    310   // important side effect of calling registerSymbol here is to register
    311   // the symbol with the assembler.
    312   getAssembler().registerSymbol(*Symbol);
    313 
    314   // The implementation of symbol attributes is designed to match 'as', but it
    315   // leaves much to desired. It doesn't really make sense to arbitrarily add and
    316   // remove flags, but 'as' allows this (in particular, see .desc).
    317   //
    318   // In the future it might be worth trying to make these operations more well
    319   // defined.
    320   switch (Attribute) {
    321   case MCSA_Invalid:
    322   case MCSA_ELF_TypeFunction:
    323   case MCSA_ELF_TypeIndFunction:
    324   case MCSA_ELF_TypeObject:
    325   case MCSA_ELF_TypeTLS:
    326   case MCSA_ELF_TypeCommon:
    327   case MCSA_ELF_TypeNoType:
    328   case MCSA_ELF_TypeGnuUniqueObject:
    329   case MCSA_Extern:
    330   case MCSA_Hidden:
    331   case MCSA_IndirectSymbol:
    332   case MCSA_Internal:
    333   case MCSA_Protected:
    334   case MCSA_Weak:
    335   case MCSA_Local:
    336   case MCSA_LGlobal:
    337     return false;
    338 
    339   case MCSA_Global:
    340     Symbol->setExternal(true);
    341     // This effectively clears the undefined lazy bit, in Darwin 'as', although
    342     // it isn't very consistent because it implements this as part of symbol
    343     // lookup.
    344     //
    345     // FIXME: Cleanup this code, these bits should be emitted based on semantic
    346     // properties, not on the order of definition, etc.
    347     Symbol->setReferenceTypeUndefinedLazy(false);
    348     break;
    349 
    350   case MCSA_LazyReference:
    351     // FIXME: This requires -dynamic.
    352     Symbol->setNoDeadStrip();
    353     if (Symbol->isUndefined())
    354       Symbol->setReferenceTypeUndefinedLazy(true);
    355     break;
    356 
    357     // Since .reference sets the no dead strip bit, it is equivalent to
    358     // .no_dead_strip in practice.
    359   case MCSA_Reference:
    360   case MCSA_NoDeadStrip:
    361     Symbol->setNoDeadStrip();
    362     break;
    363 
    364   case MCSA_SymbolResolver:
    365     Symbol->setSymbolResolver();
    366     break;
    367 
    368   case MCSA_AltEntry:
    369     Symbol->setAltEntry();
    370     break;
    371 
    372   case MCSA_PrivateExtern:
    373     Symbol->setExternal(true);
    374     Symbol->setPrivateExtern(true);
    375     break;
    376 
    377   case MCSA_WeakReference:
    378     // FIXME: This requires -dynamic.
    379     if (Symbol->isUndefined())
    380       Symbol->setWeakReference();
    381     break;
    382 
    383   case MCSA_WeakDefinition:
    384     // FIXME: 'as' enforces that this is defined and global. The manual claims
    385     // it has to be in a coalesced section, but this isn't enforced.
    386     Symbol->setWeakDefinition();
    387     break;
    388 
    389   case MCSA_WeakDefAutoPrivate:
    390     Symbol->setWeakDefinition();
    391     Symbol->setWeakReference();
    392     break;
    393 
    394   case MCSA_Cold:
    395     Symbol->setCold();
    396     break;
    397   }
    398 
    399   return true;
    400 }
    401 
    402 void MCMachOStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
    403   // Encode the 'desc' value into the lowest implementation defined bits.
    404   getAssembler().registerSymbol(*Symbol);
    405   cast<MCSymbolMachO>(Symbol)->setDesc(DescValue);
    406 }
    407 
    408 void MCMachOStreamer::emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
    409                                        unsigned ByteAlignment) {
    410   // FIXME: Darwin 'as' does appear to allow redef of a .comm by itself.
    411   assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
    412 
    413   getAssembler().registerSymbol(*Symbol);
    414   Symbol->setExternal(true);
    415   Symbol->setCommon(Size, ByteAlignment);
    416 }
    417 
    418 void MCMachOStreamer::emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
    419                                             unsigned ByteAlignment) {
    420   // '.lcomm' is equivalent to '.zerofill'.
    421   return emitZerofill(getContext().getObjectFileInfo()->getDataBSSSection(),
    422                       Symbol, Size, ByteAlignment);
    423 }
    424 
    425 void MCMachOStreamer::emitZerofill(MCSection *Section, MCSymbol *Symbol,
    426                                    uint64_t Size, unsigned ByteAlignment,
    427                                    SMLoc Loc) {
    428   // On darwin all virtual sections have zerofill type. Disallow the usage of
    429   // .zerofill in non-virtual functions. If something similar is needed, use
    430   // .space or .zero.
    431   if (!Section->isVirtualSection()) {
    432     getContext().reportError(
    433         Loc, "The usage of .zerofill is restricted to sections of "
    434              "ZEROFILL type. Use .zero or .space instead.");
    435     return; // Early returning here shouldn't harm. EmitZeros should work on any
    436             // section.
    437   }
    438 
    439   PushSection();
    440   SwitchSection(Section);
    441 
    442   // The symbol may not be present, which only creates the section.
    443   if (Symbol) {
    444     emitValueToAlignment(ByteAlignment, 0, 1, 0);
    445     emitLabel(Symbol);
    446     emitZeros(Size);
    447   }
    448   PopSection();
    449 }
    450 
    451 // This should always be called with the thread local bss section.  Like the
    452 // .zerofill directive this doesn't actually switch sections on us.
    453 void MCMachOStreamer::emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
    454                                      uint64_t Size, unsigned ByteAlignment) {
    455   emitZerofill(Section, Symbol, Size, ByteAlignment);
    456 }
    457 
    458 void MCMachOStreamer::emitInstToData(const MCInst &Inst,
    459                                      const MCSubtargetInfo &STI) {
    460   MCDataFragment *DF = getOrCreateDataFragment();
    461 
    462   SmallVector<MCFixup, 4> Fixups;
    463   SmallString<256> Code;
    464   raw_svector_ostream VecOS(Code);
    465   getAssembler().getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI);
    466 
    467   // Add the fixups and data.
    468   for (MCFixup &Fixup : Fixups) {
    469     Fixup.setOffset(Fixup.getOffset() + DF->getContents().size());
    470     DF->getFixups().push_back(Fixup);
    471   }
    472   DF->setHasInstructions(STI);
    473   DF->getContents().append(Code.begin(), Code.end());
    474 }
    475 
    476 void MCMachOStreamer::finishImpl() {
    477   emitFrames(&getAssembler().getBackend());
    478 
    479   // We have to set the fragment atom associations so we can relax properly for
    480   // Mach-O.
    481 
    482   // First, scan the symbol table to build a lookup table from fragments to
    483   // defining symbols.
    484   DenseMap<const MCFragment *, const MCSymbol *> DefiningSymbolMap;
    485   for (const MCSymbol &Symbol : getAssembler().symbols()) {
    486     if (getAssembler().isSymbolLinkerVisible(Symbol) && Symbol.isInSection() &&
    487         !Symbol.isVariable()) {
    488       // An atom defining symbol should never be internal to a fragment.
    489       assert(Symbol.getOffset() == 0 &&
    490              "Invalid offset in atom defining symbol!");
    491       DefiningSymbolMap[Symbol.getFragment()] = &Symbol;
    492     }
    493   }
    494 
    495   // Set the fragment atom associations by tracking the last seen atom defining
    496   // symbol.
    497   for (MCSection &Sec : getAssembler()) {
    498     const MCSymbol *CurrentAtom = nullptr;
    499     for (MCFragment &Frag : Sec) {
    500       if (const MCSymbol *Symbol = DefiningSymbolMap.lookup(&Frag))
    501         CurrentAtom = Symbol;
    502       Frag.setAtom(CurrentAtom);
    503     }
    504   }
    505 
    506   this->MCObjectStreamer::finishImpl();
    507 }
    508 
    509 MCStreamer *llvm::createMachOStreamer(MCContext &Context,
    510                                       std::unique_ptr<MCAsmBackend> &&MAB,
    511                                       std::unique_ptr<MCObjectWriter> &&OW,
    512                                       std::unique_ptr<MCCodeEmitter> &&CE,
    513                                       bool RelaxAll, bool DWARFMustBeAtTheEnd,
    514                                       bool LabelSections) {
    515   MCMachOStreamer *S =
    516       new MCMachOStreamer(Context, std::move(MAB), std::move(OW), std::move(CE),
    517                           DWARFMustBeAtTheEnd, LabelSections);
    518   const Triple &Target = Context.getTargetTriple();
    519   S->emitVersionForTarget(Target, Context.getObjectFileInfo()->getSDKVersion());
    520   if (RelaxAll)
    521     S->getAssembler().setRelaxAll(true);
    522   return S;
    523 }
    524