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:
MCMachOStreamer(MCContext & Context,std::unique_ptr<MCAsmBackend> MAB,std::unique_ptr<MCObjectWriter> OW,std::unique_ptr<MCCodeEmitter> Emitter,bool label)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
reset()760b57cec5SDimitry Andric void reset() override {
770b57cec5SDimitry Andric HasSectionLabel.clear();
780b57cec5SDimitry Andric MCObjectStreamer::reset();
790b57cec5SDimitry Andric }
800b57cec5SDimitry Andric
getWriter()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
emitIdent(StringRef IdentString)1165ffd83dbSDimitry Andric void emitIdent(StringRef IdentString) override {
1170b57cec5SDimitry Andric llvm_unreachable("macho doesn't support this directive");
1180b57cec5SDimitry Andric }
1190b57cec5SDimitry Andric
emitLOHDirective(MCLOHType Kind,const MCLOHArgs & Args)1205ffd83dbSDimitry Andric void emitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override {
121*0fca6ea1SDimitry Andric getWriter().getLOHContainer().addDirective(Kind, Args);
1220b57cec5SDimitry Andric }
emitCGProfileEntry(const MCSymbolRefExpr * From,const MCSymbolRefExpr * To,uint64_t Count)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
changeSection(MCSection * Section,uint32_t Subsection)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
emitEHSymAttributes(const MCSymbol * Symbol,MCSymbol * EHSymbol)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
emitLabel(MCSymbol * Symbol,SMLoc Loc)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
emitAssignment(MCSymbol * Symbol,const MCExpr * Value)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
emitDataRegion(MachO::DataRegionType Kind)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
emitDataRegionEnd()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
emitAssemblerFlag(MCAssemblerFlag Flag)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
emitLinkerOptions(ArrayRef<std::string> Options)2285ffd83dbSDimitry Andric void MCMachOStreamer::emitLinkerOptions(ArrayRef<std::string> Options) {
229*0fca6ea1SDimitry Andric getWriter().getLinkerOptions().push_back(Options);
2300b57cec5SDimitry Andric }
2310b57cec5SDimitry Andric
emitDataRegion(MCDataRegionType Kind)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
emitVersionMin(MCVersionMinType Kind,unsigned Major,unsigned Minor,unsigned Update,VersionTuple SDKVersion)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
emitBuildVersion(unsigned Platform,unsigned Major,unsigned Minor,unsigned Update,VersionTuple SDKVersion)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
emitDarwinTargetVariantBuildVersion(unsigned Platform,unsigned Major,unsigned Minor,unsigned Update,VersionTuple SDKVersion)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
emitThumbFunc(MCSymbol * Symbol)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
emitSymbolAttribute(MCSymbol * Sym,MCSymbolAttr Attribute)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
emitSymbolDesc(MCSymbol * Symbol,unsigned DescValue)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
emitCommonSymbol(MCSymbol * Symbol,uint64_t Size,Align ByteAlignment)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
emitLocalCommonSymbol(MCSymbol * Symbol,uint64_t Size,Align ByteAlignment)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
emitZerofill(MCSection * Section,MCSymbol * Symbol,uint64_t Size,Align ByteAlignment,SMLoc Loc)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.
emitTBSSSymbol(MCSection * Section,MCSymbol * Symbol,uint64_t Size,Align ByteAlignment)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
emitInstToData(const MCInst & Inst,const MCSubtargetInfo & STI)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
finishImpl()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
finalizeCGProfileEntry(const MCSymbolRefExpr * & SRE)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
finalizeCGProfile()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
createMachOStreamer(MCContext & Context,std::unique_ptr<MCAsmBackend> && MAB,std::unique_ptr<MCObjectWriter> && OW,std::unique_ptr<MCCodeEmitter> && CE,bool DWARFMustBeAtTheEnd,bool LabelSections)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.
createAddrSigSection()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