xref: /freebsd-src/contrib/llvm-project/llvm/lib/MC/MCMachOStreamer.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- MCMachOStreamer.cpp - MachO Streamer -------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
100b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h"
110b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
120b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
13*0fca6ea1SDimitry Andric #include "llvm/BinaryFormat/MachO.h"
140b57cec5SDimitry Andric #include "llvm/MC/MCAsmBackend.h"
150b57cec5SDimitry Andric #include "llvm/MC/MCAssembler.h"
160b57cec5SDimitry Andric #include "llvm/MC/MCCodeEmitter.h"
170b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
180b57cec5SDimitry Andric #include "llvm/MC/MCDirectives.h"
190b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h"
200b57cec5SDimitry Andric #include "llvm/MC/MCFixup.h"
210b57cec5SDimitry Andric #include "llvm/MC/MCFragment.h"
220b57cec5SDimitry Andric #include "llvm/MC/MCLinkerOptimizationHint.h"
23*0fca6ea1SDimitry Andric #include "llvm/MC/MCMachObjectWriter.h"
240b57cec5SDimitry Andric #include "llvm/MC/MCObjectFileInfo.h"
250b57cec5SDimitry Andric #include "llvm/MC/MCObjectStreamer.h"
260b57cec5SDimitry Andric #include "llvm/MC/MCObjectWriter.h"
270b57cec5SDimitry Andric #include "llvm/MC/MCSection.h"
280b57cec5SDimitry Andric #include "llvm/MC/MCSectionMachO.h"
290b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h"
300b57cec5SDimitry Andric #include "llvm/MC/MCSymbolMachO.h"
310b57cec5SDimitry Andric #include "llvm/MC/MCValue.h"
3281ad6265SDimitry Andric #include "llvm/MC/SectionKind.h"
33349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h"
340b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
350b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
360b57cec5SDimitry Andric #include <cassert>
370b57cec5SDimitry Andric #include <vector>
380b57cec5SDimitry Andric 
3981ad6265SDimitry Andric namespace llvm {
4081ad6265SDimitry Andric class MCInst;
4181ad6265SDimitry Andric class MCStreamer;
4281ad6265SDimitry Andric class MCSubtargetInfo;
4381ad6265SDimitry Andric class Triple;
4481ad6265SDimitry Andric } // namespace llvm
4581ad6265SDimitry Andric 
460b57cec5SDimitry Andric using namespace llvm;
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric namespace {
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric class MCMachOStreamer : public MCObjectStreamer {
510b57cec5SDimitry Andric private:
520b57cec5SDimitry Andric   /// LabelSections - true if each section change should emit a linker local
530b57cec5SDimitry Andric   /// label for use in relocations for assembler local references. Obviates the
540b57cec5SDimitry Andric   /// need for local relocations. False by default.
550b57cec5SDimitry Andric   bool LabelSections;
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric   /// HasSectionLabel - map of which sections have already had a non-local
580b57cec5SDimitry Andric   /// label emitted to them. Used so we don't emit extraneous linker local
590b57cec5SDimitry Andric   /// labels in the middle of the section.
600b57cec5SDimitry Andric   DenseMap<const MCSection*, bool> HasSectionLabel;
610b57cec5SDimitry Andric 
625ffd83dbSDimitry Andric   void emitInstToData(const MCInst &Inst, const MCSubtargetInfo &STI) override;
630b57cec5SDimitry Andric 
64*0fca6ea1SDimitry Andric   void emitDataRegion(MachO::DataRegionType Kind);
655ffd83dbSDimitry Andric   void emitDataRegionEnd();
660b57cec5SDimitry Andric 
670b57cec5SDimitry Andric public:
680b57cec5SDimitry Andric   MCMachOStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> MAB,
690b57cec5SDimitry Andric                   std::unique_ptr<MCObjectWriter> OW,
70*0fca6ea1SDimitry Andric                   std::unique_ptr<MCCodeEmitter> Emitter, bool label)
710b57cec5SDimitry Andric       : MCObjectStreamer(Context, std::move(MAB), std::move(OW),
720b57cec5SDimitry Andric                          std::move(Emitter)),
73*0fca6ea1SDimitry Andric         LabelSections(label) {}
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric   /// state management
760b57cec5SDimitry Andric   void reset() override {
770b57cec5SDimitry Andric     HasSectionLabel.clear();
780b57cec5SDimitry Andric     MCObjectStreamer::reset();
790b57cec5SDimitry Andric   }
800b57cec5SDimitry Andric 
81*0fca6ea1SDimitry Andric   MachObjectWriter &getWriter() {
82*0fca6ea1SDimitry Andric     return static_cast<MachObjectWriter &>(getAssembler().getWriter());
83*0fca6ea1SDimitry Andric   }
84*0fca6ea1SDimitry Andric 
850b57cec5SDimitry Andric   /// @name MCStreamer Interface
860b57cec5SDimitry Andric   /// @{
870b57cec5SDimitry Andric 
88*0fca6ea1SDimitry Andric   void changeSection(MCSection *Sect, uint32_t Subsection = 0) override;
895ffd83dbSDimitry Andric   void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
905ffd83dbSDimitry Andric   void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
915ffd83dbSDimitry Andric   void emitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol) override;
925ffd83dbSDimitry Andric   void emitAssemblerFlag(MCAssemblerFlag Flag) override;
935ffd83dbSDimitry Andric   void emitLinkerOptions(ArrayRef<std::string> Options) override;
945ffd83dbSDimitry Andric   void emitDataRegion(MCDataRegionType Kind) override;
955ffd83dbSDimitry Andric   void emitVersionMin(MCVersionMinType Kind, unsigned Major, unsigned Minor,
960b57cec5SDimitry Andric                       unsigned Update, VersionTuple SDKVersion) override;
975ffd83dbSDimitry Andric   void emitBuildVersion(unsigned Platform, unsigned Major, unsigned Minor,
980b57cec5SDimitry Andric                         unsigned Update, VersionTuple SDKVersion) override;
990eae32dcSDimitry Andric   void emitDarwinTargetVariantBuildVersion(unsigned Platform, unsigned Major,
1000eae32dcSDimitry Andric                                            unsigned Minor, unsigned Update,
1010eae32dcSDimitry Andric                                            VersionTuple SDKVersion) override;
1025ffd83dbSDimitry Andric   void emitThumbFunc(MCSymbol *Func) override;
1035ffd83dbSDimitry Andric   bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
1045ffd83dbSDimitry Andric   void emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
1055ffd83dbSDimitry Andric   void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
106bdd1243dSDimitry Andric                         Align ByteAlignment) override;
1070b57cec5SDimitry Andric 
1085ffd83dbSDimitry Andric   void emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
109bdd1243dSDimitry Andric                              Align ByteAlignment) override;
1105ffd83dbSDimitry Andric   void emitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
111bdd1243dSDimitry Andric                     uint64_t Size = 0, Align ByteAlignment = Align(1),
1120b57cec5SDimitry Andric                     SMLoc Loc = SMLoc()) override;
1135ffd83dbSDimitry Andric   void emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
114bdd1243dSDimitry Andric                       Align ByteAlignment = Align(1)) override;
1150b57cec5SDimitry Andric 
1165ffd83dbSDimitry Andric   void emitIdent(StringRef IdentString) override {
1170b57cec5SDimitry Andric     llvm_unreachable("macho doesn't support this directive");
1180b57cec5SDimitry Andric   }
1190b57cec5SDimitry Andric 
1205ffd83dbSDimitry Andric   void emitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override {
121*0fca6ea1SDimitry Andric     getWriter().getLOHContainer().addDirective(Kind, Args);
1220b57cec5SDimitry Andric   }
12304eeddc0SDimitry Andric   void emitCGProfileEntry(const MCSymbolRefExpr *From,
12404eeddc0SDimitry Andric                           const MCSymbolRefExpr *To, uint64_t Count) override {
12504eeddc0SDimitry Andric     if (!From->getSymbol().isTemporary() && !To->getSymbol().isTemporary())
126*0fca6ea1SDimitry Andric       getWriter().getCGProfile().push_back({From, To, Count});
12704eeddc0SDimitry Andric   }
1280b57cec5SDimitry Andric 
1295ffd83dbSDimitry Andric   void finishImpl() override;
13004eeddc0SDimitry Andric 
13104eeddc0SDimitry Andric   void finalizeCGProfileEntry(const MCSymbolRefExpr *&SRE);
13204eeddc0SDimitry Andric   void finalizeCGProfile();
13381ad6265SDimitry Andric   void createAddrSigSection();
1340b57cec5SDimitry Andric };
1350b57cec5SDimitry Andric 
1360b57cec5SDimitry Andric } // end anonymous namespace.
1370b57cec5SDimitry Andric 
138*0fca6ea1SDimitry Andric void MCMachOStreamer::changeSection(MCSection *Section, uint32_t Subsection) {
1390b57cec5SDimitry Andric   // Change the section normally.
140*0fca6ea1SDimitry Andric   changeSectionImpl(Section, Subsection);
1410b57cec5SDimitry Andric 
1420b57cec5SDimitry Andric   // Output a linker-local symbol so we don't need section-relative local
1430b57cec5SDimitry Andric   // relocations. The linker hates us when we do that.
1440b57cec5SDimitry Andric   if (LabelSections && !HasSectionLabel[Section] &&
1450b57cec5SDimitry Andric       !Section->getBeginSymbol()) {
1460b57cec5SDimitry Andric     MCSymbol *Label = getContext().createLinkerPrivateTempSymbol();
1470b57cec5SDimitry Andric     Section->setBeginSymbol(Label);
1480b57cec5SDimitry Andric     HasSectionLabel[Section] = true;
1490b57cec5SDimitry Andric   }
1500b57cec5SDimitry Andric }
1510b57cec5SDimitry Andric 
1525ffd83dbSDimitry Andric void MCMachOStreamer::emitEHSymAttributes(const MCSymbol *Symbol,
1530b57cec5SDimitry Andric                                           MCSymbol *EHSymbol) {
154*0fca6ea1SDimitry Andric   auto *Sym = cast<MCSymbolMachO>(Symbol);
1550b57cec5SDimitry Andric   getAssembler().registerSymbol(*Symbol);
1560b57cec5SDimitry Andric   if (Symbol->isExternal())
1575ffd83dbSDimitry Andric     emitSymbolAttribute(EHSymbol, MCSA_Global);
158*0fca6ea1SDimitry Andric   if (Sym->isWeakDefinition())
1595ffd83dbSDimitry Andric     emitSymbolAttribute(EHSymbol, MCSA_WeakDefinition);
160*0fca6ea1SDimitry Andric   if (Sym->isPrivateExtern())
1615ffd83dbSDimitry Andric     emitSymbolAttribute(EHSymbol, MCSA_PrivateExtern);
1620b57cec5SDimitry Andric }
1630b57cec5SDimitry Andric 
1645ffd83dbSDimitry Andric void MCMachOStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
1650b57cec5SDimitry Andric   // We have to create a new fragment if this is an atom defining symbol,
1660b57cec5SDimitry Andric   // fragments cannot span atoms.
167*0fca6ea1SDimitry Andric   if (cast<MCSymbolMachO>(Symbol)->isSymbolLinkerVisible())
168*0fca6ea1SDimitry Andric     insert(getContext().allocFragment<MCDataFragment>());
1690b57cec5SDimitry Andric 
1705ffd83dbSDimitry Andric   MCObjectStreamer::emitLabel(Symbol, Loc);
1710b57cec5SDimitry Andric 
1720b57cec5SDimitry Andric   // This causes the reference type flag to be cleared. Darwin 'as' was "trying"
1730b57cec5SDimitry Andric   // to clear the weak reference and weak definition bits too, but the
1740b57cec5SDimitry Andric   // implementation was buggy. For now we just try to match 'as', for
1750b57cec5SDimitry Andric   // diffability.
1760b57cec5SDimitry Andric   //
1770b57cec5SDimitry Andric   // FIXME: Cleanup this code, these bits should be emitted based on semantic
1780b57cec5SDimitry Andric   // properties, not on the order of definition, etc.
1790b57cec5SDimitry Andric   cast<MCSymbolMachO>(Symbol)->clearReferenceType();
1800b57cec5SDimitry Andric }
1810b57cec5SDimitry Andric 
1825ffd83dbSDimitry Andric void MCMachOStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
1830b57cec5SDimitry Andric   MCValue Res;
1840b57cec5SDimitry Andric 
1850b57cec5SDimitry Andric   if (Value->evaluateAsRelocatable(Res, nullptr, nullptr)) {
1860b57cec5SDimitry Andric     if (const MCSymbolRefExpr *SymAExpr = Res.getSymA()) {
1870b57cec5SDimitry Andric       const MCSymbol &SymA = SymAExpr->getSymbol();
1880b57cec5SDimitry Andric       if (!Res.getSymB() && (SymA.getName() == "" || Res.getConstant() != 0))
1890b57cec5SDimitry Andric         cast<MCSymbolMachO>(Symbol)->setAltEntry();
1900b57cec5SDimitry Andric     }
1910b57cec5SDimitry Andric   }
1925ffd83dbSDimitry Andric   MCObjectStreamer::emitAssignment(Symbol, Value);
1930b57cec5SDimitry Andric }
1940b57cec5SDimitry Andric 
195*0fca6ea1SDimitry Andric void MCMachOStreamer::emitDataRegion(MachO::DataRegionType Kind) {
1960b57cec5SDimitry Andric   // Create a temporary label to mark the start of the data region.
1970b57cec5SDimitry Andric   MCSymbol *Start = getContext().createTempSymbol();
1985ffd83dbSDimitry Andric   emitLabel(Start);
1990b57cec5SDimitry Andric   // Record the region for the object writer to use.
200*0fca6ea1SDimitry Andric   getWriter().getDataRegions().push_back({Kind, Start, nullptr});
2010b57cec5SDimitry Andric }
2020b57cec5SDimitry Andric 
2035ffd83dbSDimitry Andric void MCMachOStreamer::emitDataRegionEnd() {
204*0fca6ea1SDimitry Andric   auto &Regions = getWriter().getDataRegions();
2050b57cec5SDimitry Andric   assert(!Regions.empty() && "Mismatched .end_data_region!");
206*0fca6ea1SDimitry Andric   auto &Data = Regions.back();
2070b57cec5SDimitry Andric   assert(!Data.End && "Mismatched .end_data_region!");
2080b57cec5SDimitry Andric   // Create a temporary label to mark the end of the data region.
2090b57cec5SDimitry Andric   Data.End = getContext().createTempSymbol();
2105ffd83dbSDimitry Andric   emitLabel(Data.End);
2110b57cec5SDimitry Andric }
2120b57cec5SDimitry Andric 
2135ffd83dbSDimitry Andric void MCMachOStreamer::emitAssemblerFlag(MCAssemblerFlag Flag) {
2140b57cec5SDimitry Andric   // Let the target do whatever target specific stuff it needs to do.
2150b57cec5SDimitry Andric   getAssembler().getBackend().handleAssemblerFlag(Flag);
2160b57cec5SDimitry Andric   // Do any generic stuff we need to do.
2170b57cec5SDimitry Andric   switch (Flag) {
2180b57cec5SDimitry Andric   case MCAF_SyntaxUnified: return; // no-op here.
2190b57cec5SDimitry Andric   case MCAF_Code16: return; // Change parsing mode; no-op here.
2200b57cec5SDimitry Andric   case MCAF_Code32: return; // Change parsing mode; no-op here.
2210b57cec5SDimitry Andric   case MCAF_Code64: return; // Change parsing mode; no-op here.
2220b57cec5SDimitry Andric   case MCAF_SubsectionsViaSymbols:
223*0fca6ea1SDimitry Andric     getWriter().setSubsectionsViaSymbols(true);
2240b57cec5SDimitry Andric     return;
2250b57cec5SDimitry Andric   }
2260b57cec5SDimitry Andric }
2270b57cec5SDimitry Andric 
2285ffd83dbSDimitry Andric void MCMachOStreamer::emitLinkerOptions(ArrayRef<std::string> Options) {
229*0fca6ea1SDimitry Andric   getWriter().getLinkerOptions().push_back(Options);
2300b57cec5SDimitry Andric }
2310b57cec5SDimitry Andric 
2325ffd83dbSDimitry Andric void MCMachOStreamer::emitDataRegion(MCDataRegionType Kind) {
2330b57cec5SDimitry Andric   switch (Kind) {
2340b57cec5SDimitry Andric   case MCDR_DataRegion:
235*0fca6ea1SDimitry Andric     emitDataRegion(MachO::DataRegionType::DICE_KIND_DATA);
2360b57cec5SDimitry Andric     return;
2370b57cec5SDimitry Andric   case MCDR_DataRegionJT8:
238*0fca6ea1SDimitry Andric     emitDataRegion(MachO::DataRegionType::DICE_KIND_JUMP_TABLE8);
2390b57cec5SDimitry Andric     return;
2400b57cec5SDimitry Andric   case MCDR_DataRegionJT16:
241*0fca6ea1SDimitry Andric     emitDataRegion(MachO::DataRegionType::DICE_KIND_JUMP_TABLE16);
2420b57cec5SDimitry Andric     return;
2430b57cec5SDimitry Andric   case MCDR_DataRegionJT32:
244*0fca6ea1SDimitry Andric     emitDataRegion(MachO::DataRegionType::DICE_KIND_JUMP_TABLE32);
2450b57cec5SDimitry Andric     return;
2460b57cec5SDimitry Andric   case MCDR_DataRegionEnd:
2475ffd83dbSDimitry Andric     emitDataRegionEnd();
2480b57cec5SDimitry Andric     return;
2490b57cec5SDimitry Andric   }
2500b57cec5SDimitry Andric }
2510b57cec5SDimitry Andric 
2525ffd83dbSDimitry Andric void MCMachOStreamer::emitVersionMin(MCVersionMinType Kind, unsigned Major,
2530b57cec5SDimitry Andric                                      unsigned Minor, unsigned Update,
2540b57cec5SDimitry Andric                                      VersionTuple SDKVersion) {
255*0fca6ea1SDimitry Andric   getWriter().setVersionMin(Kind, Major, Minor, Update, SDKVersion);
2560b57cec5SDimitry Andric }
2570b57cec5SDimitry Andric 
2585ffd83dbSDimitry Andric void MCMachOStreamer::emitBuildVersion(unsigned Platform, unsigned Major,
2590b57cec5SDimitry Andric                                        unsigned Minor, unsigned Update,
2600b57cec5SDimitry Andric                                        VersionTuple SDKVersion) {
261*0fca6ea1SDimitry Andric   getWriter().setBuildVersion((MachO::PlatformType)Platform, Major, Minor,
2620b57cec5SDimitry Andric                               Update, SDKVersion);
2630b57cec5SDimitry Andric }
2640b57cec5SDimitry Andric 
2650eae32dcSDimitry Andric void MCMachOStreamer::emitDarwinTargetVariantBuildVersion(
2660eae32dcSDimitry Andric     unsigned Platform, unsigned Major, unsigned Minor, unsigned Update,
2670eae32dcSDimitry Andric     VersionTuple SDKVersion) {
268*0fca6ea1SDimitry Andric   getWriter().setTargetVariantBuildVersion((MachO::PlatformType)Platform, Major,
269*0fca6ea1SDimitry Andric                                            Minor, Update, SDKVersion);
2700eae32dcSDimitry Andric }
2710eae32dcSDimitry Andric 
2725ffd83dbSDimitry Andric void MCMachOStreamer::emitThumbFunc(MCSymbol *Symbol) {
2730b57cec5SDimitry Andric   // Remember that the function is a thumb function. Fixup and relocation
2740b57cec5SDimitry Andric   // values will need adjusted.
2750b57cec5SDimitry Andric   getAssembler().setIsThumbFunc(Symbol);
2760b57cec5SDimitry Andric   cast<MCSymbolMachO>(Symbol)->setThumbFunc();
2770b57cec5SDimitry Andric }
2780b57cec5SDimitry Andric 
2795ffd83dbSDimitry Andric bool MCMachOStreamer::emitSymbolAttribute(MCSymbol *Sym,
2800b57cec5SDimitry Andric                                           MCSymbolAttr Attribute) {
2810b57cec5SDimitry Andric   MCSymbolMachO *Symbol = cast<MCSymbolMachO>(Sym);
2820b57cec5SDimitry Andric 
2830b57cec5SDimitry Andric   // Indirect symbols are handled differently, to match how 'as' handles
2840b57cec5SDimitry Andric   // them. This makes writing matching .o files easier.
2850b57cec5SDimitry Andric   if (Attribute == MCSA_IndirectSymbol) {
2860b57cec5SDimitry Andric     // Note that we intentionally cannot use the symbol data here; this is
2870b57cec5SDimitry Andric     // important for matching the string table that 'as' generates.
288*0fca6ea1SDimitry Andric     getWriter().getIndirectSymbols().push_back(
289*0fca6ea1SDimitry Andric         {Symbol, getCurrentSectionOnly()});
2900b57cec5SDimitry Andric     return true;
2910b57cec5SDimitry Andric   }
2920b57cec5SDimitry Andric 
2930b57cec5SDimitry Andric   // Adding a symbol attribute always introduces the symbol, note that an
2940b57cec5SDimitry Andric   // important side effect of calling registerSymbol here is to register
2950b57cec5SDimitry Andric   // the symbol with the assembler.
2960b57cec5SDimitry Andric   getAssembler().registerSymbol(*Symbol);
2970b57cec5SDimitry Andric 
2980b57cec5SDimitry Andric   // The implementation of symbol attributes is designed to match 'as', but it
2990b57cec5SDimitry Andric   // leaves much to desired. It doesn't really make sense to arbitrarily add and
3000b57cec5SDimitry Andric   // remove flags, but 'as' allows this (in particular, see .desc).
3010b57cec5SDimitry Andric   //
3020b57cec5SDimitry Andric   // In the future it might be worth trying to make these operations more well
3030b57cec5SDimitry Andric   // defined.
3040b57cec5SDimitry Andric   switch (Attribute) {
3050b57cec5SDimitry Andric   case MCSA_Invalid:
3060b57cec5SDimitry Andric   case MCSA_ELF_TypeFunction:
3070b57cec5SDimitry Andric   case MCSA_ELF_TypeIndFunction:
3080b57cec5SDimitry Andric   case MCSA_ELF_TypeObject:
3090b57cec5SDimitry Andric   case MCSA_ELF_TypeTLS:
3100b57cec5SDimitry Andric   case MCSA_ELF_TypeCommon:
3110b57cec5SDimitry Andric   case MCSA_ELF_TypeNoType:
3120b57cec5SDimitry Andric   case MCSA_ELF_TypeGnuUniqueObject:
3135ffd83dbSDimitry Andric   case MCSA_Extern:
3140b57cec5SDimitry Andric   case MCSA_Hidden:
3150b57cec5SDimitry Andric   case MCSA_IndirectSymbol:
3160b57cec5SDimitry Andric   case MCSA_Internal:
3170b57cec5SDimitry Andric   case MCSA_Protected:
3180b57cec5SDimitry Andric   case MCSA_Weak:
3190b57cec5SDimitry Andric   case MCSA_Local:
3208bcb0991SDimitry Andric   case MCSA_LGlobal:
32181ad6265SDimitry Andric   case MCSA_Exported:
322bdd1243dSDimitry Andric   case MCSA_Memtag:
32306c3fb27SDimitry Andric   case MCSA_WeakAntiDep:
3240b57cec5SDimitry Andric     return false;
3250b57cec5SDimitry Andric 
3260b57cec5SDimitry Andric   case MCSA_Global:
3270b57cec5SDimitry Andric     Symbol->setExternal(true);
3280b57cec5SDimitry Andric     // This effectively clears the undefined lazy bit, in Darwin 'as', although
3290b57cec5SDimitry Andric     // it isn't very consistent because it implements this as part of symbol
3300b57cec5SDimitry Andric     // lookup.
3310b57cec5SDimitry Andric     //
3320b57cec5SDimitry Andric     // FIXME: Cleanup this code, these bits should be emitted based on semantic
3330b57cec5SDimitry Andric     // properties, not on the order of definition, etc.
3340b57cec5SDimitry Andric     Symbol->setReferenceTypeUndefinedLazy(false);
3350b57cec5SDimitry Andric     break;
3360b57cec5SDimitry Andric 
3370b57cec5SDimitry Andric   case MCSA_LazyReference:
3380b57cec5SDimitry Andric     // FIXME: This requires -dynamic.
3390b57cec5SDimitry Andric     Symbol->setNoDeadStrip();
3400b57cec5SDimitry Andric     if (Symbol->isUndefined())
3410b57cec5SDimitry Andric       Symbol->setReferenceTypeUndefinedLazy(true);
3420b57cec5SDimitry Andric     break;
3430b57cec5SDimitry Andric 
3440b57cec5SDimitry Andric     // Since .reference sets the no dead strip bit, it is equivalent to
3450b57cec5SDimitry Andric     // .no_dead_strip in practice.
3460b57cec5SDimitry Andric   case MCSA_Reference:
3470b57cec5SDimitry Andric   case MCSA_NoDeadStrip:
3480b57cec5SDimitry Andric     Symbol->setNoDeadStrip();
3490b57cec5SDimitry Andric     break;
3500b57cec5SDimitry Andric 
3510b57cec5SDimitry Andric   case MCSA_SymbolResolver:
3520b57cec5SDimitry Andric     Symbol->setSymbolResolver();
3530b57cec5SDimitry Andric     break;
3540b57cec5SDimitry Andric 
3550b57cec5SDimitry Andric   case MCSA_AltEntry:
3560b57cec5SDimitry Andric     Symbol->setAltEntry();
3570b57cec5SDimitry Andric     break;
3580b57cec5SDimitry Andric 
3590b57cec5SDimitry Andric   case MCSA_PrivateExtern:
3600b57cec5SDimitry Andric     Symbol->setExternal(true);
3610b57cec5SDimitry Andric     Symbol->setPrivateExtern(true);
3620b57cec5SDimitry Andric     break;
3630b57cec5SDimitry Andric 
3640b57cec5SDimitry Andric   case MCSA_WeakReference:
3650b57cec5SDimitry Andric     // FIXME: This requires -dynamic.
3660b57cec5SDimitry Andric     if (Symbol->isUndefined())
3670b57cec5SDimitry Andric       Symbol->setWeakReference();
3680b57cec5SDimitry Andric     break;
3690b57cec5SDimitry Andric 
3700b57cec5SDimitry Andric   case MCSA_WeakDefinition:
3710b57cec5SDimitry Andric     // FIXME: 'as' enforces that this is defined and global. The manual claims
3720b57cec5SDimitry Andric     // it has to be in a coalesced section, but this isn't enforced.
3730b57cec5SDimitry Andric     Symbol->setWeakDefinition();
3740b57cec5SDimitry Andric     break;
3750b57cec5SDimitry Andric 
3760b57cec5SDimitry Andric   case MCSA_WeakDefAutoPrivate:
3770b57cec5SDimitry Andric     Symbol->setWeakDefinition();
3780b57cec5SDimitry Andric     Symbol->setWeakReference();
3790b57cec5SDimitry Andric     break;
3800b57cec5SDimitry Andric 
3810b57cec5SDimitry Andric   case MCSA_Cold:
3820b57cec5SDimitry Andric     Symbol->setCold();
3830b57cec5SDimitry Andric     break;
3840b57cec5SDimitry Andric   }
3850b57cec5SDimitry Andric 
3860b57cec5SDimitry Andric   return true;
3870b57cec5SDimitry Andric }
3880b57cec5SDimitry Andric 
3895ffd83dbSDimitry Andric void MCMachOStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
3900b57cec5SDimitry Andric   // Encode the 'desc' value into the lowest implementation defined bits.
3910b57cec5SDimitry Andric   getAssembler().registerSymbol(*Symbol);
3920b57cec5SDimitry Andric   cast<MCSymbolMachO>(Symbol)->setDesc(DescValue);
3930b57cec5SDimitry Andric }
3940b57cec5SDimitry Andric 
3955ffd83dbSDimitry Andric void MCMachOStreamer::emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
396bdd1243dSDimitry Andric                                        Align ByteAlignment) {
3970b57cec5SDimitry Andric   // FIXME: Darwin 'as' does appear to allow redef of a .comm by itself.
3980b57cec5SDimitry Andric   assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
3990b57cec5SDimitry Andric 
4000b57cec5SDimitry Andric   getAssembler().registerSymbol(*Symbol);
4010b57cec5SDimitry Andric   Symbol->setExternal(true);
4020b57cec5SDimitry Andric   Symbol->setCommon(Size, ByteAlignment);
4030b57cec5SDimitry Andric }
4040b57cec5SDimitry Andric 
4055ffd83dbSDimitry Andric void MCMachOStreamer::emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
406bdd1243dSDimitry Andric                                             Align ByteAlignment) {
4070b57cec5SDimitry Andric   // '.lcomm' is equivalent to '.zerofill'.
4085ffd83dbSDimitry Andric   return emitZerofill(getContext().getObjectFileInfo()->getDataBSSSection(),
4090b57cec5SDimitry Andric                       Symbol, Size, ByteAlignment);
4100b57cec5SDimitry Andric }
4110b57cec5SDimitry Andric 
4125ffd83dbSDimitry Andric void MCMachOStreamer::emitZerofill(MCSection *Section, MCSymbol *Symbol,
413bdd1243dSDimitry Andric                                    uint64_t Size, Align ByteAlignment,
4140b57cec5SDimitry Andric                                    SMLoc Loc) {
4150b57cec5SDimitry Andric   // On darwin all virtual sections have zerofill type. Disallow the usage of
4160b57cec5SDimitry Andric   // .zerofill in non-virtual functions. If something similar is needed, use
4170b57cec5SDimitry Andric   // .space or .zero.
4180b57cec5SDimitry Andric   if (!Section->isVirtualSection()) {
4190b57cec5SDimitry Andric     getContext().reportError(
4200b57cec5SDimitry Andric         Loc, "The usage of .zerofill is restricted to sections of "
4210b57cec5SDimitry Andric              "ZEROFILL type. Use .zero or .space instead.");
4220b57cec5SDimitry Andric     return; // Early returning here shouldn't harm. EmitZeros should work on any
4230b57cec5SDimitry Andric             // section.
4240b57cec5SDimitry Andric   }
4250b57cec5SDimitry Andric 
42681ad6265SDimitry Andric   pushSection();
42781ad6265SDimitry Andric   switchSection(Section);
4280b57cec5SDimitry Andric 
4290b57cec5SDimitry Andric   // The symbol may not be present, which only creates the section.
4300b57cec5SDimitry Andric   if (Symbol) {
4315ffd83dbSDimitry Andric     emitValueToAlignment(ByteAlignment, 0, 1, 0);
4325ffd83dbSDimitry Andric     emitLabel(Symbol);
4335ffd83dbSDimitry Andric     emitZeros(Size);
4340b57cec5SDimitry Andric   }
43581ad6265SDimitry Andric   popSection();
4360b57cec5SDimitry Andric }
4370b57cec5SDimitry Andric 
4380b57cec5SDimitry Andric // This should always be called with the thread local bss section.  Like the
4390b57cec5SDimitry Andric // .zerofill directive this doesn't actually switch sections on us.
4405ffd83dbSDimitry Andric void MCMachOStreamer::emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
441bdd1243dSDimitry Andric                                      uint64_t Size, Align ByteAlignment) {
4425ffd83dbSDimitry Andric   emitZerofill(Section, Symbol, Size, ByteAlignment);
4430b57cec5SDimitry Andric }
4440b57cec5SDimitry Andric 
4455ffd83dbSDimitry Andric void MCMachOStreamer::emitInstToData(const MCInst &Inst,
4460b57cec5SDimitry Andric                                      const MCSubtargetInfo &STI) {
4470b57cec5SDimitry Andric   MCDataFragment *DF = getOrCreateDataFragment();
4480b57cec5SDimitry Andric 
4490b57cec5SDimitry Andric   SmallVector<MCFixup, 4> Fixups;
4500b57cec5SDimitry Andric   SmallString<256> Code;
45106c3fb27SDimitry Andric   getAssembler().getEmitter().encodeInstruction(Inst, Code, Fixups, STI);
4520b57cec5SDimitry Andric 
4530b57cec5SDimitry Andric   // Add the fixups and data.
4540b57cec5SDimitry Andric   for (MCFixup &Fixup : Fixups) {
4550b57cec5SDimitry Andric     Fixup.setOffset(Fixup.getOffset() + DF->getContents().size());
4560b57cec5SDimitry Andric     DF->getFixups().push_back(Fixup);
4570b57cec5SDimitry Andric   }
4580b57cec5SDimitry Andric   DF->setHasInstructions(STI);
4590b57cec5SDimitry Andric   DF->getContents().append(Code.begin(), Code.end());
4600b57cec5SDimitry Andric }
4610b57cec5SDimitry Andric 
4625ffd83dbSDimitry Andric void MCMachOStreamer::finishImpl() {
4635ffd83dbSDimitry Andric   emitFrames(&getAssembler().getBackend());
4640b57cec5SDimitry Andric 
4650b57cec5SDimitry Andric   // We have to set the fragment atom associations so we can relax properly for
4660b57cec5SDimitry Andric   // Mach-O.
4670b57cec5SDimitry Andric 
4680b57cec5SDimitry Andric   // First, scan the symbol table to build a lookup table from fragments to
4690b57cec5SDimitry Andric   // defining symbols.
4700b57cec5SDimitry Andric   DenseMap<const MCFragment *, const MCSymbol *> DefiningSymbolMap;
4710b57cec5SDimitry Andric   for (const MCSymbol &Symbol : getAssembler().symbols()) {
472*0fca6ea1SDimitry Andric     auto &Sym = cast<MCSymbolMachO>(Symbol);
473*0fca6ea1SDimitry Andric     if (Sym.isSymbolLinkerVisible() && Sym.isInSection() && !Sym.isVariable() &&
474*0fca6ea1SDimitry Andric         !Sym.isAltEntry()) {
4750b57cec5SDimitry Andric       // An atom defining symbol should never be internal to a fragment.
4760b57cec5SDimitry Andric       assert(Symbol.getOffset() == 0 &&
4770b57cec5SDimitry Andric              "Invalid offset in atom defining symbol!");
4780b57cec5SDimitry Andric       DefiningSymbolMap[Symbol.getFragment()] = &Symbol;
4790b57cec5SDimitry Andric     }
4800b57cec5SDimitry Andric   }
4810b57cec5SDimitry Andric 
4820b57cec5SDimitry Andric   // Set the fragment atom associations by tracking the last seen atom defining
4830b57cec5SDimitry Andric   // symbol.
4840b57cec5SDimitry Andric   for (MCSection &Sec : getAssembler()) {
485*0fca6ea1SDimitry Andric     cast<MCSectionMachO>(Sec).allocAtoms();
4860b57cec5SDimitry Andric     const MCSymbol *CurrentAtom = nullptr;
487*0fca6ea1SDimitry Andric     size_t I = 0;
4880b57cec5SDimitry Andric     for (MCFragment &Frag : Sec) {
4890b57cec5SDimitry Andric       if (const MCSymbol *Symbol = DefiningSymbolMap.lookup(&Frag))
4900b57cec5SDimitry Andric         CurrentAtom = Symbol;
491*0fca6ea1SDimitry Andric       cast<MCSectionMachO>(Sec).setAtom(I++, CurrentAtom);
4920b57cec5SDimitry Andric     }
4930b57cec5SDimitry Andric   }
4940b57cec5SDimitry Andric 
49504eeddc0SDimitry Andric   finalizeCGProfile();
49604eeddc0SDimitry Andric 
49781ad6265SDimitry Andric   createAddrSigSection();
4985ffd83dbSDimitry Andric   this->MCObjectStreamer::finishImpl();
4990b57cec5SDimitry Andric }
5000b57cec5SDimitry Andric 
50104eeddc0SDimitry Andric void MCMachOStreamer::finalizeCGProfileEntry(const MCSymbolRefExpr *&SRE) {
50204eeddc0SDimitry Andric   const MCSymbol *S = &SRE->getSymbol();
50306c3fb27SDimitry Andric   if (getAssembler().registerSymbol(*S))
50404eeddc0SDimitry Andric     S->setExternal(true);
50504eeddc0SDimitry Andric }
50604eeddc0SDimitry Andric 
50704eeddc0SDimitry Andric void MCMachOStreamer::finalizeCGProfile() {
50804eeddc0SDimitry Andric   MCAssembler &Asm = getAssembler();
509*0fca6ea1SDimitry Andric   MCObjectWriter &W = getWriter();
510*0fca6ea1SDimitry Andric   if (W.getCGProfile().empty())
51104eeddc0SDimitry Andric     return;
512*0fca6ea1SDimitry Andric   for (auto &E : W.getCGProfile()) {
51304eeddc0SDimitry Andric     finalizeCGProfileEntry(E.From);
51404eeddc0SDimitry Andric     finalizeCGProfileEntry(E.To);
51504eeddc0SDimitry Andric   }
51604eeddc0SDimitry Andric   // We can't write the section out until symbol indices are finalized which
51704eeddc0SDimitry Andric   // doesn't happen until after section layout. We need to create the section
51804eeddc0SDimitry Andric   // and set its size now so that it's accounted for in layout.
51904eeddc0SDimitry Andric   MCSection *CGProfileSection = Asm.getContext().getMachOSection(
52004eeddc0SDimitry Andric       "__LLVM", "__cg_profile", 0, SectionKind::getMetadata());
521*0fca6ea1SDimitry Andric   changeSection(CGProfileSection);
52204eeddc0SDimitry Andric   // For each entry, reserve space for 2 32-bit indices and a 64-bit count.
52304eeddc0SDimitry Andric   size_t SectionBytes =
524*0fca6ea1SDimitry Andric       W.getCGProfile().size() * (2 * sizeof(uint32_t) + sizeof(uint64_t));
525*0fca6ea1SDimitry Andric   cast<MCDataFragment>(*CGProfileSection->begin())
526*0fca6ea1SDimitry Andric       .getContents()
527*0fca6ea1SDimitry Andric       .resize(SectionBytes);
52804eeddc0SDimitry Andric }
52904eeddc0SDimitry Andric 
5300b57cec5SDimitry Andric MCStreamer *llvm::createMachOStreamer(MCContext &Context,
5310b57cec5SDimitry Andric                                       std::unique_ptr<MCAsmBackend> &&MAB,
5320b57cec5SDimitry Andric                                       std::unique_ptr<MCObjectWriter> &&OW,
5330b57cec5SDimitry Andric                                       std::unique_ptr<MCCodeEmitter> &&CE,
534*0fca6ea1SDimitry Andric                                       bool DWARFMustBeAtTheEnd,
5350b57cec5SDimitry Andric                                       bool LabelSections) {
536*0fca6ea1SDimitry Andric   MCMachOStreamer *S = new MCMachOStreamer(
537*0fca6ea1SDimitry Andric       Context, std::move(MAB), std::move(OW), std::move(CE), LabelSections);
538fe6060f1SDimitry Andric   const Triple &Target = Context.getTargetTriple();
5390eae32dcSDimitry Andric   S->emitVersionForTarget(
5400eae32dcSDimitry Andric       Target, Context.getObjectFileInfo()->getSDKVersion(),
5410eae32dcSDimitry Andric       Context.getObjectFileInfo()->getDarwinTargetVariantTriple(),
5420eae32dcSDimitry Andric       Context.getObjectFileInfo()->getDarwinTargetVariantSDKVersion());
5430b57cec5SDimitry Andric   return S;
5440b57cec5SDimitry Andric }
54581ad6265SDimitry Andric 
546fcaf7f86SDimitry Andric // The AddrSig section uses a series of relocations to refer to the symbols that
547fcaf7f86SDimitry Andric // should be considered address-significant. The only interesting content of
548fcaf7f86SDimitry Andric // these relocations is their symbol; the type, length etc will be ignored by
549fcaf7f86SDimitry Andric // the linker. The reason we are not referring to the symbol indices directly is
550fcaf7f86SDimitry Andric // that those indices will be invalidated by tools that update the symbol table.
551fcaf7f86SDimitry Andric // Symbol relocations OTOH will have their indices updated by e.g. llvm-strip.
55281ad6265SDimitry Andric void MCMachOStreamer::createAddrSigSection() {
55381ad6265SDimitry Andric   MCAssembler &Asm = getAssembler();
55481ad6265SDimitry Andric   MCObjectWriter &writer = Asm.getWriter();
55581ad6265SDimitry Andric   if (!writer.getEmitAddrsigSection())
55681ad6265SDimitry Andric     return;
557fcaf7f86SDimitry Andric   // Create the AddrSig section and first data fragment here as its layout needs
558fcaf7f86SDimitry Andric   // to be computed immediately after in order for it to be exported correctly.
55981ad6265SDimitry Andric   MCSection *AddrSigSection =
56081ad6265SDimitry Andric       Asm.getContext().getObjectFileInfo()->getAddrSigSection();
561*0fca6ea1SDimitry Andric   changeSection(AddrSigSection);
562*0fca6ea1SDimitry Andric   auto *Frag = cast<MCDataFragment>(AddrSigSection->curFragList()->Head);
563fcaf7f86SDimitry Andric   // We will generate a series of pointer-sized symbol relocations at offset
564fcaf7f86SDimitry Andric   // 0x0. Set the section size to be large enough to contain a single pointer
565fcaf7f86SDimitry Andric   // (instead of emitting a zero-sized section) so these relocations are
566fcaf7f86SDimitry Andric   // technically valid, even though we don't expect these relocations to
567fcaf7f86SDimitry Andric   // actually be applied by the linker.
568fcaf7f86SDimitry Andric   Frag->getContents().resize(8);
56981ad6265SDimitry Andric }
570