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