10b57cec5SDimitry Andric //===- lib/MC/MCELFStreamer.cpp - ELF Object Output -----------------------===// 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 // This file assembles .s files and emits ELF .o object files. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "llvm/MC/MCELFStreamer.h" 140b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h" 150b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 160b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELF.h" 170b57cec5SDimitry Andric #include "llvm/MC/MCAsmBackend.h" 180b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h" 190b57cec5SDimitry Andric #include "llvm/MC/MCAssembler.h" 200b57cec5SDimitry Andric #include "llvm/MC/MCCodeEmitter.h" 210b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 220b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h" 230b57cec5SDimitry Andric #include "llvm/MC/MCFixup.h" 240b57cec5SDimitry Andric #include "llvm/MC/MCFragment.h" 250b57cec5SDimitry Andric #include "llvm/MC/MCObjectFileInfo.h" 260b57cec5SDimitry Andric #include "llvm/MC/MCObjectWriter.h" 270b57cec5SDimitry Andric #include "llvm/MC/MCSection.h" 280b57cec5SDimitry Andric #include "llvm/MC/MCSectionELF.h" 290b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h" 300b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h" 310b57cec5SDimitry Andric #include "llvm/MC/MCSymbolELF.h" 32349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h" 330b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 340b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 35fe6060f1SDimitry Andric #include "llvm/Support/LEB128.h" 360b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 370b57cec5SDimitry Andric #include <cassert> 380b57cec5SDimitry Andric #include <cstdint> 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric using namespace llvm; 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric MCELFStreamer::MCELFStreamer(MCContext &Context, 430b57cec5SDimitry Andric std::unique_ptr<MCAsmBackend> TAB, 440b57cec5SDimitry Andric std::unique_ptr<MCObjectWriter> OW, 450b57cec5SDimitry Andric std::unique_ptr<MCCodeEmitter> Emitter) 460b57cec5SDimitry Andric : MCObjectStreamer(Context, std::move(TAB), std::move(OW), 470b57cec5SDimitry Andric std::move(Emitter)) {} 480b57cec5SDimitry Andric 49*0fca6ea1SDimitry Andric ELFObjectWriter &MCELFStreamer::getWriter() { 50*0fca6ea1SDimitry Andric return static_cast<ELFObjectWriter &>(getAssembler().getWriter()); 51*0fca6ea1SDimitry Andric } 52*0fca6ea1SDimitry Andric 530b57cec5SDimitry Andric bool MCELFStreamer::isBundleLocked() const { 540b57cec5SDimitry Andric return getCurrentSectionOnly()->isBundleLocked(); 550b57cec5SDimitry Andric } 560b57cec5SDimitry Andric 57349cc55cSDimitry Andric void MCELFStreamer::initSections(bool NoExecStack, const MCSubtargetInfo &STI) { 580b57cec5SDimitry Andric MCContext &Ctx = getContext(); 5981ad6265SDimitry Andric switchSection(Ctx.getObjectFileInfo()->getTextSection()); 60bdd1243dSDimitry Andric emitCodeAlignment(Align(Ctx.getObjectFileInfo()->getTextSectionAlignment()), 61bdd1243dSDimitry Andric &STI); 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric if (NoExecStack) 6481ad6265SDimitry Andric switchSection(Ctx.getAsmInfo()->getNonexecutableStackSection(Ctx)); 650b57cec5SDimitry Andric } 660b57cec5SDimitry Andric 675ffd83dbSDimitry Andric void MCELFStreamer::emitLabel(MCSymbol *S, SMLoc Loc) { 680b57cec5SDimitry Andric auto *Symbol = cast<MCSymbolELF>(S); 695ffd83dbSDimitry Andric MCObjectStreamer::emitLabel(Symbol, Loc); 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric const MCSectionELF &Section = 720b57cec5SDimitry Andric static_cast<const MCSectionELF &>(*getCurrentSectionOnly()); 730b57cec5SDimitry Andric if (Section.getFlags() & ELF::SHF_TLS) 740b57cec5SDimitry Andric Symbol->setType(ELF::STT_TLS); 750b57cec5SDimitry Andric } 760b57cec5SDimitry Andric 77*0fca6ea1SDimitry Andric void MCELFStreamer::emitLabelAtPos(MCSymbol *S, SMLoc Loc, MCDataFragment &F, 78480093f4SDimitry Andric uint64_t Offset) { 790b57cec5SDimitry Andric auto *Symbol = cast<MCSymbolELF>(S); 805ffd83dbSDimitry Andric MCObjectStreamer::emitLabelAtPos(Symbol, Loc, F, Offset); 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric const MCSectionELF &Section = 830b57cec5SDimitry Andric static_cast<const MCSectionELF &>(*getCurrentSectionOnly()); 840b57cec5SDimitry Andric if (Section.getFlags() & ELF::SHF_TLS) 850b57cec5SDimitry Andric Symbol->setType(ELF::STT_TLS); 860b57cec5SDimitry Andric } 870b57cec5SDimitry Andric 885ffd83dbSDimitry Andric void MCELFStreamer::emitAssemblerFlag(MCAssemblerFlag Flag) { 890b57cec5SDimitry Andric // Let the target do whatever target specific stuff it needs to do. 900b57cec5SDimitry Andric getAssembler().getBackend().handleAssemblerFlag(Flag); 910b57cec5SDimitry Andric } 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric // If bundle alignment is used and there are any instructions in the section, it 940b57cec5SDimitry Andric // needs to be aligned to at least the bundle size. 950b57cec5SDimitry Andric static void setSectionAlignmentForBundling(const MCAssembler &Assembler, 960b57cec5SDimitry Andric MCSection *Section) { 97*0fca6ea1SDimitry Andric if (Assembler.isBundlingEnabled() && Section->hasInstructions()) 98bdd1243dSDimitry Andric Section->ensureMinAlignment(Align(Assembler.getBundleAlignSize())); 990b57cec5SDimitry Andric } 1000b57cec5SDimitry Andric 101*0fca6ea1SDimitry Andric void MCELFStreamer::changeSection(MCSection *Section, uint32_t Subsection) { 102*0fca6ea1SDimitry Andric MCAssembler &Asm = getAssembler(); 103*0fca6ea1SDimitry Andric if (auto *F = getCurrentFragment()) { 104*0fca6ea1SDimitry Andric if (isBundleLocked()) 1050b57cec5SDimitry Andric report_fatal_error("Unterminated .bundle_lock when changing a section"); 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric // Ensure the previous section gets aligned if necessary. 108*0fca6ea1SDimitry Andric setSectionAlignmentForBundling(Asm, F->getParent()); 109*0fca6ea1SDimitry Andric } 1100b57cec5SDimitry Andric auto *SectionELF = static_cast<const MCSectionELF *>(Section); 1110b57cec5SDimitry Andric const MCSymbol *Grp = SectionELF->getGroup(); 1120b57cec5SDimitry Andric if (Grp) 1130b57cec5SDimitry Andric Asm.registerSymbol(*Grp); 114fe6060f1SDimitry Andric if (SectionELF->getFlags() & ELF::SHF_GNU_RETAIN) 115*0fca6ea1SDimitry Andric getWriter().markGnuAbi(); 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric changeSectionImpl(Section, Subsection); 1180b57cec5SDimitry Andric Asm.registerSymbol(*Section->getBeginSymbol()); 1190b57cec5SDimitry Andric } 1200b57cec5SDimitry Andric 1215ffd83dbSDimitry Andric void MCELFStreamer::emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) { 1220b57cec5SDimitry Andric getAssembler().registerSymbol(*Symbol); 1230b57cec5SDimitry Andric const MCExpr *Value = MCSymbolRefExpr::create( 1240b57cec5SDimitry Andric Symbol, MCSymbolRefExpr::VK_WEAKREF, getContext()); 1250b57cec5SDimitry Andric Alias->setVariableValue(Value); 1260b57cec5SDimitry Andric } 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric // When GNU as encounters more than one .type declaration for an object it seems 1290b57cec5SDimitry Andric // to use a mechanism similar to the one below to decide which type is actually 1300b57cec5SDimitry Andric // used in the object file. The greater of T1 and T2 is selected based on the 1310b57cec5SDimitry Andric // following ordering: 1320b57cec5SDimitry Andric // STT_NOTYPE < STT_OBJECT < STT_FUNC < STT_GNU_IFUNC < STT_TLS < anything else 1330b57cec5SDimitry Andric // If neither T1 < T2 nor T2 < T1 according to this ordering, use T2 (the user 1340b57cec5SDimitry Andric // provided type). 1350b57cec5SDimitry Andric static unsigned CombineSymbolTypes(unsigned T1, unsigned T2) { 1360b57cec5SDimitry Andric for (unsigned Type : {ELF::STT_NOTYPE, ELF::STT_OBJECT, ELF::STT_FUNC, 1370b57cec5SDimitry Andric ELF::STT_GNU_IFUNC, ELF::STT_TLS}) { 1380b57cec5SDimitry Andric if (T1 == Type) 1390b57cec5SDimitry Andric return T2; 1400b57cec5SDimitry Andric if (T2 == Type) 1410b57cec5SDimitry Andric return T1; 1420b57cec5SDimitry Andric } 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric return T2; 1450b57cec5SDimitry Andric } 1460b57cec5SDimitry Andric 1475ffd83dbSDimitry Andric bool MCELFStreamer::emitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) { 1480b57cec5SDimitry Andric auto *Symbol = cast<MCSymbolELF>(S); 1490b57cec5SDimitry Andric 1500b57cec5SDimitry Andric // Adding a symbol attribute always introduces the symbol, note that an 1510b57cec5SDimitry Andric // important side effect of calling registerSymbol here is to register 1520b57cec5SDimitry Andric // the symbol with the assembler. 1530b57cec5SDimitry Andric getAssembler().registerSymbol(*Symbol); 1540b57cec5SDimitry Andric 1550b57cec5SDimitry Andric // The implementation of symbol attributes is designed to match 'as', but it 1560b57cec5SDimitry Andric // leaves much to desired. It doesn't really make sense to arbitrarily add and 1570b57cec5SDimitry Andric // remove flags, but 'as' allows this (in particular, see .desc). 1580b57cec5SDimitry Andric // 1590b57cec5SDimitry Andric // In the future it might be worth trying to make these operations more well 1600b57cec5SDimitry Andric // defined. 1610b57cec5SDimitry Andric switch (Attribute) { 1620b57cec5SDimitry Andric case MCSA_Cold: 1635ffd83dbSDimitry Andric case MCSA_Extern: 1640b57cec5SDimitry Andric case MCSA_LazyReference: 1650b57cec5SDimitry Andric case MCSA_Reference: 1660b57cec5SDimitry Andric case MCSA_SymbolResolver: 1670b57cec5SDimitry Andric case MCSA_PrivateExtern: 1680b57cec5SDimitry Andric case MCSA_WeakDefinition: 1690b57cec5SDimitry Andric case MCSA_WeakDefAutoPrivate: 1700b57cec5SDimitry Andric case MCSA_Invalid: 1710b57cec5SDimitry Andric case MCSA_IndirectSymbol: 17281ad6265SDimitry Andric case MCSA_Exported: 17306c3fb27SDimitry Andric case MCSA_WeakAntiDep: 1740b57cec5SDimitry Andric return false; 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andric case MCSA_NoDeadStrip: 1770b57cec5SDimitry Andric // Ignore for now. 1780b57cec5SDimitry Andric break; 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric case MCSA_ELF_TypeGnuUniqueObject: 1810b57cec5SDimitry Andric Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_OBJECT)); 1820b57cec5SDimitry Andric Symbol->setBinding(ELF::STB_GNU_UNIQUE); 183*0fca6ea1SDimitry Andric getWriter().markGnuAbi(); 1840b57cec5SDimitry Andric break; 1850b57cec5SDimitry Andric 1860b57cec5SDimitry Andric case MCSA_Global: 187e8d8bef9SDimitry Andric // For `.weak x; .global x`, GNU as sets the binding to STB_WEAK while we 188e8d8bef9SDimitry Andric // traditionally set the binding to STB_GLOBAL. This is error-prone, so we 189e8d8bef9SDimitry Andric // error on such cases. Note, we also disallow changed binding from .local. 190e8d8bef9SDimitry Andric if (Symbol->isBindingSet() && Symbol->getBinding() != ELF::STB_GLOBAL) 191e8d8bef9SDimitry Andric getContext().reportError(getStartTokLoc(), 192e8d8bef9SDimitry Andric Symbol->getName() + 193e8d8bef9SDimitry Andric " changed binding to STB_GLOBAL"); 1940b57cec5SDimitry Andric Symbol->setBinding(ELF::STB_GLOBAL); 1950b57cec5SDimitry Andric break; 1960b57cec5SDimitry Andric 1970b57cec5SDimitry Andric case MCSA_WeakReference: 1980b57cec5SDimitry Andric case MCSA_Weak: 199e8d8bef9SDimitry Andric // For `.global x; .weak x`, both MC and GNU as set the binding to STB_WEAK. 200e8d8bef9SDimitry Andric // We emit a warning for now but may switch to an error in the future. 201e8d8bef9SDimitry Andric if (Symbol->isBindingSet() && Symbol->getBinding() != ELF::STB_WEAK) 202e8d8bef9SDimitry Andric getContext().reportWarning( 203e8d8bef9SDimitry Andric getStartTokLoc(), Symbol->getName() + " changed binding to STB_WEAK"); 2040b57cec5SDimitry Andric Symbol->setBinding(ELF::STB_WEAK); 2050b57cec5SDimitry Andric break; 2060b57cec5SDimitry Andric 2070b57cec5SDimitry Andric case MCSA_Local: 208e8d8bef9SDimitry Andric if (Symbol->isBindingSet() && Symbol->getBinding() != ELF::STB_LOCAL) 209e8d8bef9SDimitry Andric getContext().reportError(getStartTokLoc(), 210e8d8bef9SDimitry Andric Symbol->getName() + 211e8d8bef9SDimitry Andric " changed binding to STB_LOCAL"); 2120b57cec5SDimitry Andric Symbol->setBinding(ELF::STB_LOCAL); 2130b57cec5SDimitry Andric break; 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric case MCSA_ELF_TypeFunction: 2160b57cec5SDimitry Andric Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_FUNC)); 2170b57cec5SDimitry Andric break; 2180b57cec5SDimitry Andric 2190b57cec5SDimitry Andric case MCSA_ELF_TypeIndFunction: 2200b57cec5SDimitry Andric Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_GNU_IFUNC)); 221*0fca6ea1SDimitry Andric getWriter().markGnuAbi(); 2220b57cec5SDimitry Andric break; 2230b57cec5SDimitry Andric 2240b57cec5SDimitry Andric case MCSA_ELF_TypeObject: 2250b57cec5SDimitry Andric Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_OBJECT)); 2260b57cec5SDimitry Andric break; 2270b57cec5SDimitry Andric 2280b57cec5SDimitry Andric case MCSA_ELF_TypeTLS: 2290b57cec5SDimitry Andric Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_TLS)); 2300b57cec5SDimitry Andric break; 2310b57cec5SDimitry Andric 2320b57cec5SDimitry Andric case MCSA_ELF_TypeCommon: 2330b57cec5SDimitry Andric // TODO: Emit these as a common symbol. 2340b57cec5SDimitry Andric Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_OBJECT)); 2350b57cec5SDimitry Andric break; 2360b57cec5SDimitry Andric 2370b57cec5SDimitry Andric case MCSA_ELF_TypeNoType: 2380b57cec5SDimitry Andric Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_NOTYPE)); 2390b57cec5SDimitry Andric break; 2400b57cec5SDimitry Andric 2410b57cec5SDimitry Andric case MCSA_Protected: 2420b57cec5SDimitry Andric Symbol->setVisibility(ELF::STV_PROTECTED); 2430b57cec5SDimitry Andric break; 2440b57cec5SDimitry Andric 245bdd1243dSDimitry Andric case MCSA_Memtag: 246bdd1243dSDimitry Andric Symbol->setMemtag(true); 247bdd1243dSDimitry Andric break; 248bdd1243dSDimitry Andric 2490b57cec5SDimitry Andric case MCSA_Hidden: 2500b57cec5SDimitry Andric Symbol->setVisibility(ELF::STV_HIDDEN); 2510b57cec5SDimitry Andric break; 2520b57cec5SDimitry Andric 2530b57cec5SDimitry Andric case MCSA_Internal: 2540b57cec5SDimitry Andric Symbol->setVisibility(ELF::STV_INTERNAL); 2550b57cec5SDimitry Andric break; 2560b57cec5SDimitry Andric 2570b57cec5SDimitry Andric case MCSA_AltEntry: 2580b57cec5SDimitry Andric llvm_unreachable("ELF doesn't support the .alt_entry attribute"); 2598bcb0991SDimitry Andric 2608bcb0991SDimitry Andric case MCSA_LGlobal: 2618bcb0991SDimitry Andric llvm_unreachable("ELF doesn't support the .lglobl attribute"); 2620b57cec5SDimitry Andric } 2630b57cec5SDimitry Andric 2640b57cec5SDimitry Andric return true; 2650b57cec5SDimitry Andric } 2660b57cec5SDimitry Andric 2675ffd83dbSDimitry Andric void MCELFStreamer::emitCommonSymbol(MCSymbol *S, uint64_t Size, 268bdd1243dSDimitry Andric Align ByteAlignment) { 2690b57cec5SDimitry Andric auto *Symbol = cast<MCSymbolELF>(S); 2700b57cec5SDimitry Andric getAssembler().registerSymbol(*Symbol); 2710b57cec5SDimitry Andric 272e8d8bef9SDimitry Andric if (!Symbol->isBindingSet()) 2730b57cec5SDimitry Andric Symbol->setBinding(ELF::STB_GLOBAL); 2740b57cec5SDimitry Andric 2750b57cec5SDimitry Andric Symbol->setType(ELF::STT_OBJECT); 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric if (Symbol->getBinding() == ELF::STB_LOCAL) { 2780b57cec5SDimitry Andric MCSection &Section = *getAssembler().getContext().getELFSection( 2790b57cec5SDimitry Andric ".bss", ELF::SHT_NOBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC); 2800b57cec5SDimitry Andric MCSectionSubPair P = getCurrentSection(); 28181ad6265SDimitry Andric switchSection(&Section); 2820b57cec5SDimitry Andric 2835ffd83dbSDimitry Andric emitValueToAlignment(ByteAlignment, 0, 1, 0); 2845ffd83dbSDimitry Andric emitLabel(Symbol); 2855ffd83dbSDimitry Andric emitZeros(Size); 2860b57cec5SDimitry Andric 28781ad6265SDimitry Andric switchSection(P.first, P.second); 2880b57cec5SDimitry Andric } else { 2890b57cec5SDimitry Andric if (Symbol->declareCommon(Size, ByteAlignment)) 290349cc55cSDimitry Andric report_fatal_error(Twine("Symbol: ") + Symbol->getName() + 2910b57cec5SDimitry Andric " redeclared as different type"); 2920b57cec5SDimitry Andric } 2930b57cec5SDimitry Andric 2940b57cec5SDimitry Andric cast<MCSymbolELF>(Symbol) 2950b57cec5SDimitry Andric ->setSize(MCConstantExpr::create(Size, getContext())); 2960b57cec5SDimitry Andric } 2970b57cec5SDimitry Andric 2980b57cec5SDimitry Andric void MCELFStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) { 2990b57cec5SDimitry Andric cast<MCSymbolELF>(Symbol)->setSize(Value); 3000b57cec5SDimitry Andric } 3010b57cec5SDimitry Andric 302fe6060f1SDimitry Andric void MCELFStreamer::emitELFSymverDirective(const MCSymbol *OriginalSym, 303fe6060f1SDimitry Andric StringRef Name, 304fe6060f1SDimitry Andric bool KeepOriginalSym) { 305*0fca6ea1SDimitry Andric getWriter().Symvers.push_back(ELFObjectWriter::Symver{ 306fe6060f1SDimitry Andric getStartTokLoc(), OriginalSym, Name, KeepOriginalSym}); 3070b57cec5SDimitry Andric } 3080b57cec5SDimitry Andric 3095ffd83dbSDimitry Andric void MCELFStreamer::emitLocalCommonSymbol(MCSymbol *S, uint64_t Size, 310bdd1243dSDimitry Andric Align ByteAlignment) { 3110b57cec5SDimitry Andric auto *Symbol = cast<MCSymbolELF>(S); 3120b57cec5SDimitry Andric // FIXME: Should this be caught and done earlier? 3130b57cec5SDimitry Andric getAssembler().registerSymbol(*Symbol); 3140b57cec5SDimitry Andric Symbol->setBinding(ELF::STB_LOCAL); 3155ffd83dbSDimitry Andric emitCommonSymbol(Symbol, Size, ByteAlignment); 3160b57cec5SDimitry Andric } 3170b57cec5SDimitry Andric 3185ffd83dbSDimitry Andric void MCELFStreamer::emitValueImpl(const MCExpr *Value, unsigned Size, 3190b57cec5SDimitry Andric SMLoc Loc) { 3200b57cec5SDimitry Andric if (isBundleLocked()) 3210b57cec5SDimitry Andric report_fatal_error("Emitting values inside a locked bundle is forbidden"); 3220b57cec5SDimitry Andric fixSymbolsInTLSFixups(Value); 3235ffd83dbSDimitry Andric MCObjectStreamer::emitValueImpl(Value, Size, Loc); 3240b57cec5SDimitry Andric } 3250b57cec5SDimitry Andric 326bdd1243dSDimitry Andric void MCELFStreamer::emitValueToAlignment(Align Alignment, int64_t Value, 3270b57cec5SDimitry Andric unsigned ValueSize, 3280b57cec5SDimitry Andric unsigned MaxBytesToEmit) { 3290b57cec5SDimitry Andric if (isBundleLocked()) 3300b57cec5SDimitry Andric report_fatal_error("Emitting values inside a locked bundle is forbidden"); 331bdd1243dSDimitry Andric MCObjectStreamer::emitValueToAlignment(Alignment, Value, ValueSize, 332bdd1243dSDimitry Andric MaxBytesToEmit); 3330b57cec5SDimitry Andric } 3340b57cec5SDimitry Andric 3350b57cec5SDimitry Andric void MCELFStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From, 3360b57cec5SDimitry Andric const MCSymbolRefExpr *To, 3370b57cec5SDimitry Andric uint64_t Count) { 338*0fca6ea1SDimitry Andric getWriter().getCGProfile().push_back({From, To, Count}); 3390b57cec5SDimitry Andric } 3400b57cec5SDimitry Andric 3415ffd83dbSDimitry Andric void MCELFStreamer::emitIdent(StringRef IdentString) { 3420b57cec5SDimitry Andric MCSection *Comment = getAssembler().getContext().getELFSection( 343fe6060f1SDimitry Andric ".comment", ELF::SHT_PROGBITS, ELF::SHF_MERGE | ELF::SHF_STRINGS, 1); 34481ad6265SDimitry Andric pushSection(); 34581ad6265SDimitry Andric switchSection(Comment); 3460b57cec5SDimitry Andric if (!SeenIdent) { 3475ffd83dbSDimitry Andric emitInt8(0); 3480b57cec5SDimitry Andric SeenIdent = true; 3490b57cec5SDimitry Andric } 3505ffd83dbSDimitry Andric emitBytes(IdentString); 3515ffd83dbSDimitry Andric emitInt8(0); 35281ad6265SDimitry Andric popSection(); 3530b57cec5SDimitry Andric } 3540b57cec5SDimitry Andric 3550b57cec5SDimitry Andric void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) { 3560b57cec5SDimitry Andric switch (expr->getKind()) { 3570b57cec5SDimitry Andric case MCExpr::Target: 3580b57cec5SDimitry Andric cast<MCTargetExpr>(expr)->fixELFSymbolsInTLSFixups(getAssembler()); 3590b57cec5SDimitry Andric break; 3600b57cec5SDimitry Andric case MCExpr::Constant: 3610b57cec5SDimitry Andric break; 3620b57cec5SDimitry Andric 3630b57cec5SDimitry Andric case MCExpr::Binary: { 3640b57cec5SDimitry Andric const MCBinaryExpr *be = cast<MCBinaryExpr>(expr); 3650b57cec5SDimitry Andric fixSymbolsInTLSFixups(be->getLHS()); 3660b57cec5SDimitry Andric fixSymbolsInTLSFixups(be->getRHS()); 3670b57cec5SDimitry Andric break; 3680b57cec5SDimitry Andric } 3690b57cec5SDimitry Andric 3700b57cec5SDimitry Andric case MCExpr::SymbolRef: { 3710b57cec5SDimitry Andric const MCSymbolRefExpr &symRef = *cast<MCSymbolRefExpr>(expr); 3720b57cec5SDimitry Andric switch (symRef.getKind()) { 3730b57cec5SDimitry Andric default: 3740b57cec5SDimitry Andric return; 3750b57cec5SDimitry Andric case MCSymbolRefExpr::VK_GOTTPOFF: 3760b57cec5SDimitry Andric case MCSymbolRefExpr::VK_INDNTPOFF: 3770b57cec5SDimitry Andric case MCSymbolRefExpr::VK_NTPOFF: 3780b57cec5SDimitry Andric case MCSymbolRefExpr::VK_GOTNTPOFF: 3790b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TLSCALL: 3800b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TLSDESC: 3810b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TLSGD: 3820b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TLSLD: 3830b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TLSLDM: 3840b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TPOFF: 3850b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TPREL: 3860b57cec5SDimitry Andric case MCSymbolRefExpr::VK_DTPOFF: 3870b57cec5SDimitry Andric case MCSymbolRefExpr::VK_DTPREL: 3880b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPMOD: 3890b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_LO: 3900b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_HI: 3910b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_HA: 3920b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_HIGH: 3930b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_HIGHA: 3940b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER: 3950b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA: 3960b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST: 3970b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA: 3980b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_LO: 3990b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_HI: 4000b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_HA: 4010b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_HIGH: 4020b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHA: 4030b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER: 4040b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA: 4050b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST: 4060b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA: 4070b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TPREL: 4080b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO: 4090b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI: 4100b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA: 411e8d8bef9SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TPREL_PCREL: 4120b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_DTPREL: 4130b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO: 4140b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI: 4150b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA: 4160b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TLS: 417e8d8bef9SDimitry Andric case MCSymbolRefExpr::VK_PPC_TLS_PCREL: 4180b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSGD: 4190b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO: 4200b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI: 4210b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA: 422e8d8bef9SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_PCREL: 4230b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TLSGD: 4240b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSLD: 4250b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO: 4260b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI: 4270b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA: 4280b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_TLSLD: 4290b57cec5SDimitry Andric break; 4300b57cec5SDimitry Andric } 4310b57cec5SDimitry Andric getAssembler().registerSymbol(symRef.getSymbol()); 4320b57cec5SDimitry Andric cast<MCSymbolELF>(symRef.getSymbol()).setType(ELF::STT_TLS); 4330b57cec5SDimitry Andric break; 4340b57cec5SDimitry Andric } 4350b57cec5SDimitry Andric 4360b57cec5SDimitry Andric case MCExpr::Unary: 4370b57cec5SDimitry Andric fixSymbolsInTLSFixups(cast<MCUnaryExpr>(expr)->getSubExpr()); 4380b57cec5SDimitry Andric break; 4390b57cec5SDimitry Andric } 4400b57cec5SDimitry Andric } 4410b57cec5SDimitry Andric 442fe6060f1SDimitry Andric void MCELFStreamer::finalizeCGProfileEntry(const MCSymbolRefExpr *&SRE, 443fe6060f1SDimitry Andric uint64_t Offset) { 4440b57cec5SDimitry Andric const MCSymbol *S = &SRE->getSymbol(); 4450b57cec5SDimitry Andric if (S->isTemporary()) { 4460b57cec5SDimitry Andric if (!S->isInSection()) { 4470b57cec5SDimitry Andric getContext().reportError( 4480b57cec5SDimitry Andric SRE->getLoc(), Twine("Reference to undefined temporary symbol ") + 4490b57cec5SDimitry Andric "`" + S->getName() + "`"); 4500b57cec5SDimitry Andric return; 4510b57cec5SDimitry Andric } 4520b57cec5SDimitry Andric S = S->getSection().getBeginSymbol(); 4530b57cec5SDimitry Andric S->setUsedInReloc(); 454fe6060f1SDimitry Andric SRE = MCSymbolRefExpr::create(S, MCSymbolRefExpr::VK_None, getContext(), 455fe6060f1SDimitry Andric SRE->getLoc()); 4560b57cec5SDimitry Andric } 457fe6060f1SDimitry Andric const MCConstantExpr *MCOffset = MCConstantExpr::create(Offset, getContext()); 458bdd1243dSDimitry Andric if (std::optional<std::pair<bool, std::string>> Err = 459fe6060f1SDimitry Andric MCObjectStreamer::emitRelocDirective( 460fe6060f1SDimitry Andric *MCOffset, "BFD_RELOC_NONE", SRE, SRE->getLoc(), 461fe6060f1SDimitry Andric *getContext().getSubtargetInfo())) 462fe6060f1SDimitry Andric report_fatal_error("Relocation for CG Profile could not be created: " + 463349cc55cSDimitry Andric Twine(Err->second)); 4640b57cec5SDimitry Andric } 4650b57cec5SDimitry Andric 4660b57cec5SDimitry Andric void MCELFStreamer::finalizeCGProfile() { 467*0fca6ea1SDimitry Andric ELFObjectWriter &W = getWriter(); 468*0fca6ea1SDimitry Andric if (W.getCGProfile().empty()) 469fe6060f1SDimitry Andric return; 470fe6060f1SDimitry Andric MCSection *CGProfile = getAssembler().getContext().getELFSection( 471fe6060f1SDimitry Andric ".llvm.call-graph-profile", ELF::SHT_LLVM_CALL_GRAPH_PROFILE, 472fe6060f1SDimitry Andric ELF::SHF_EXCLUDE, /*sizeof(Elf_CGProfile_Impl<>)=*/8); 47381ad6265SDimitry Andric pushSection(); 47481ad6265SDimitry Andric switchSection(CGProfile); 475fe6060f1SDimitry Andric uint64_t Offset = 0; 476*0fca6ea1SDimitry Andric for (auto &E : W.getCGProfile()) { 477fe6060f1SDimitry Andric finalizeCGProfileEntry(E.From, Offset); 478fe6060f1SDimitry Andric finalizeCGProfileEntry(E.To, Offset); 479fe6060f1SDimitry Andric emitIntValue(E.Count, sizeof(uint64_t)); 480fe6060f1SDimitry Andric Offset += sizeof(uint64_t); 4810b57cec5SDimitry Andric } 48281ad6265SDimitry Andric popSection(); 4830b57cec5SDimitry Andric } 4840b57cec5SDimitry Andric 4855ffd83dbSDimitry Andric void MCELFStreamer::emitInstToFragment(const MCInst &Inst, 4860b57cec5SDimitry Andric const MCSubtargetInfo &STI) { 4875ffd83dbSDimitry Andric this->MCObjectStreamer::emitInstToFragment(Inst, STI); 4880b57cec5SDimitry Andric MCRelaxableFragment &F = *cast<MCRelaxableFragment>(getCurrentFragment()); 4890b57cec5SDimitry Andric 490fe6060f1SDimitry Andric for (auto &Fixup : F.getFixups()) 491fe6060f1SDimitry Andric fixSymbolsInTLSFixups(Fixup.getValue()); 4920b57cec5SDimitry Andric } 4930b57cec5SDimitry Andric 4940b57cec5SDimitry Andric // A fragment can only have one Subtarget, and when bundling is enabled we 4950b57cec5SDimitry Andric // sometimes need to use the same fragment. We give an error if there 4960b57cec5SDimitry Andric // are conflicting Subtargets. 4970b57cec5SDimitry Andric static void CheckBundleSubtargets(const MCSubtargetInfo *OldSTI, 4980b57cec5SDimitry Andric const MCSubtargetInfo *NewSTI) { 4990b57cec5SDimitry Andric if (OldSTI && NewSTI && OldSTI != NewSTI) 5000b57cec5SDimitry Andric report_fatal_error("A Bundle can only have one Subtarget."); 5010b57cec5SDimitry Andric } 5020b57cec5SDimitry Andric 5035ffd83dbSDimitry Andric void MCELFStreamer::emitInstToData(const MCInst &Inst, 5040b57cec5SDimitry Andric const MCSubtargetInfo &STI) { 5050b57cec5SDimitry Andric MCAssembler &Assembler = getAssembler(); 5060b57cec5SDimitry Andric 5070b57cec5SDimitry Andric // There are several possibilities here: 5080b57cec5SDimitry Andric // 5090b57cec5SDimitry Andric // If bundling is disabled, append the encoded instruction to the current data 5100b57cec5SDimitry Andric // fragment (or create a new such fragment if the current fragment is not a 5110b57cec5SDimitry Andric // data fragment, or the Subtarget has changed). 5120b57cec5SDimitry Andric // 5130b57cec5SDimitry Andric // If bundling is enabled: 5140b57cec5SDimitry Andric // - If we're not in a bundle-locked group, emit the instruction into a 515*0fca6ea1SDimitry Andric // fragment of its own. 5160b57cec5SDimitry Andric // - If we're in a bundle-locked group, append the instruction to the current 5170b57cec5SDimitry Andric // data fragment because we want all the instructions in a group to get into 5180b57cec5SDimitry Andric // the same fragment. Be careful not to do that for the first instruction in 5190b57cec5SDimitry Andric // the group, though. 5200b57cec5SDimitry Andric MCDataFragment *DF; 5210b57cec5SDimitry Andric 5220b57cec5SDimitry Andric if (Assembler.isBundlingEnabled()) { 5230b57cec5SDimitry Andric MCSection &Sec = *getCurrentSectionOnly(); 524*0fca6ea1SDimitry Andric if (isBundleLocked() && !Sec.isBundleGroupBeforeFirstInst()) { 5250b57cec5SDimitry Andric // If we are bundle-locked, we re-use the current fragment. 5260b57cec5SDimitry Andric // The bundle-locking directive ensures this is a new data fragment. 5270b57cec5SDimitry Andric DF = cast<MCDataFragment>(getCurrentFragment()); 5280b57cec5SDimitry Andric CheckBundleSubtargets(DF->getSubtargetInfo(), &STI); 5290b57cec5SDimitry Andric } else { 530*0fca6ea1SDimitry Andric DF = getContext().allocFragment<MCDataFragment>(); 5310b57cec5SDimitry Andric insert(DF); 5320b57cec5SDimitry Andric } 5330b57cec5SDimitry Andric if (Sec.getBundleLockState() == MCSection::BundleLockedAlignToEnd) { 5340b57cec5SDimitry Andric // If this fragment is for a group marked "align_to_end", set a flag 5350b57cec5SDimitry Andric // in the fragment. This can happen after the fragment has already been 5360b57cec5SDimitry Andric // created if there are nested bundle_align groups and an inner one 5370b57cec5SDimitry Andric // is the one marked align_to_end. 5380b57cec5SDimitry Andric DF->setAlignToBundleEnd(true); 5390b57cec5SDimitry Andric } 5400b57cec5SDimitry Andric 5410b57cec5SDimitry Andric // We're now emitting an instruction in a bundle group, so this flag has 5420b57cec5SDimitry Andric // to be turned off. 5430b57cec5SDimitry Andric Sec.setBundleGroupBeforeFirstInst(false); 5440b57cec5SDimitry Andric } else { 5450b57cec5SDimitry Andric DF = getOrCreateDataFragment(&STI); 5460b57cec5SDimitry Andric } 5470b57cec5SDimitry Andric 548*0fca6ea1SDimitry Andric // Emit instruction directly into data fragment. 549*0fca6ea1SDimitry Andric size_t FixupStartIndex = DF->getFixups().size(); 550*0fca6ea1SDimitry Andric size_t CodeOffset = DF->getContents().size(); 551*0fca6ea1SDimitry Andric Assembler.getEmitter().encodeInstruction(Inst, DF->getContents(), 552*0fca6ea1SDimitry Andric DF->getFixups(), STI); 553*0fca6ea1SDimitry Andric 554*0fca6ea1SDimitry Andric auto Fixups = MutableArrayRef(DF->getFixups()).slice(FixupStartIndex); 555fe6060f1SDimitry Andric for (auto &Fixup : Fixups) { 556*0fca6ea1SDimitry Andric Fixup.setOffset(Fixup.getOffset() + CodeOffset); 557*0fca6ea1SDimitry Andric fixSymbolsInTLSFixups(Fixup.getValue()); 5580b57cec5SDimitry Andric } 559fe6060f1SDimitry Andric 5600b57cec5SDimitry Andric DF->setHasInstructions(STI); 56106c3fb27SDimitry Andric if (!Fixups.empty() && Fixups.back().getTargetKind() == 56206c3fb27SDimitry Andric getAssembler().getBackend().RelaxFixupKind) 56306c3fb27SDimitry Andric DF->setLinkerRelaxable(); 5640b57cec5SDimitry Andric } 5650b57cec5SDimitry Andric 566bdd1243dSDimitry Andric void MCELFStreamer::emitBundleAlignMode(Align Alignment) { 567bdd1243dSDimitry Andric assert(Log2(Alignment) <= 30 && "Invalid bundle alignment"); 5680b57cec5SDimitry Andric MCAssembler &Assembler = getAssembler(); 569bdd1243dSDimitry Andric if (Alignment > 1 && (Assembler.getBundleAlignSize() == 0 || 570bdd1243dSDimitry Andric Assembler.getBundleAlignSize() == Alignment.value())) 571bdd1243dSDimitry Andric Assembler.setBundleAlignSize(Alignment.value()); 5720b57cec5SDimitry Andric else 5730b57cec5SDimitry Andric report_fatal_error(".bundle_align_mode cannot be changed once set"); 5740b57cec5SDimitry Andric } 5750b57cec5SDimitry Andric 5765ffd83dbSDimitry Andric void MCELFStreamer::emitBundleLock(bool AlignToEnd) { 5770b57cec5SDimitry Andric MCSection &Sec = *getCurrentSectionOnly(); 5780b57cec5SDimitry Andric 5790b57cec5SDimitry Andric if (!getAssembler().isBundlingEnabled()) 5800b57cec5SDimitry Andric report_fatal_error(".bundle_lock forbidden when bundling is disabled"); 5810b57cec5SDimitry Andric 5820b57cec5SDimitry Andric if (!isBundleLocked()) 5830b57cec5SDimitry Andric Sec.setBundleGroupBeforeFirstInst(true); 5840b57cec5SDimitry Andric 5850b57cec5SDimitry Andric Sec.setBundleLockState(AlignToEnd ? MCSection::BundleLockedAlignToEnd 5860b57cec5SDimitry Andric : MCSection::BundleLocked); 5870b57cec5SDimitry Andric } 5880b57cec5SDimitry Andric 5895ffd83dbSDimitry Andric void MCELFStreamer::emitBundleUnlock() { 5900b57cec5SDimitry Andric MCSection &Sec = *getCurrentSectionOnly(); 5910b57cec5SDimitry Andric 5920b57cec5SDimitry Andric if (!getAssembler().isBundlingEnabled()) 5930b57cec5SDimitry Andric report_fatal_error(".bundle_unlock forbidden when bundling is disabled"); 5940b57cec5SDimitry Andric else if (!isBundleLocked()) 5950b57cec5SDimitry Andric report_fatal_error(".bundle_unlock without matching lock"); 5960b57cec5SDimitry Andric else if (Sec.isBundleGroupBeforeFirstInst()) 5970b57cec5SDimitry Andric report_fatal_error("Empty bundle-locked group is forbidden"); 5980b57cec5SDimitry Andric 5990b57cec5SDimitry Andric Sec.setBundleLockState(MCSection::NotBundleLocked); 6000b57cec5SDimitry Andric } 6010b57cec5SDimitry Andric 6025ffd83dbSDimitry Andric void MCELFStreamer::finishImpl() { 603fe6060f1SDimitry Andric // Emit the .gnu attributes section if any attributes have been added. 604fe6060f1SDimitry Andric if (!GNUAttributes.empty()) { 605fe6060f1SDimitry Andric MCSection *DummyAttributeSection = nullptr; 606fe6060f1SDimitry Andric createAttributesSection("gnu", ".gnu.attributes", ELF::SHT_GNU_ATTRIBUTES, 607fe6060f1SDimitry Andric DummyAttributeSection, GNUAttributes); 608fe6060f1SDimitry Andric } 609fe6060f1SDimitry Andric 6100b57cec5SDimitry Andric // Ensure the last section gets aligned if necessary. 611*0fca6ea1SDimitry Andric if (MCFragment *F = getCurrentFragment()) 612*0fca6ea1SDimitry Andric setSectionAlignmentForBundling(getAssembler(), F->getParent()); 6130b57cec5SDimitry Andric 6140b57cec5SDimitry Andric finalizeCGProfile(); 6155ffd83dbSDimitry Andric emitFrames(nullptr); 6160b57cec5SDimitry Andric 6175ffd83dbSDimitry Andric this->MCObjectStreamer::finishImpl(); 6180b57cec5SDimitry Andric } 6190b57cec5SDimitry Andric 6205ffd83dbSDimitry Andric void MCELFStreamer::emitThumbFunc(MCSymbol *Func) { 6210b57cec5SDimitry Andric llvm_unreachable("Generic ELF doesn't support this directive"); 6220b57cec5SDimitry Andric } 6230b57cec5SDimitry Andric 6245ffd83dbSDimitry Andric void MCELFStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { 6250b57cec5SDimitry Andric llvm_unreachable("ELF doesn't support this directive"); 6260b57cec5SDimitry Andric } 6270b57cec5SDimitry Andric 6285ffd83dbSDimitry Andric void MCELFStreamer::emitZerofill(MCSection *Section, MCSymbol *Symbol, 629bdd1243dSDimitry Andric uint64_t Size, Align ByteAlignment, 6300b57cec5SDimitry Andric SMLoc Loc) { 6310b57cec5SDimitry Andric llvm_unreachable("ELF doesn't support this directive"); 6320b57cec5SDimitry Andric } 6330b57cec5SDimitry Andric 6345ffd83dbSDimitry Andric void MCELFStreamer::emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, 635bdd1243dSDimitry Andric uint64_t Size, Align ByteAlignment) { 6360b57cec5SDimitry Andric llvm_unreachable("ELF doesn't support this directive"); 6370b57cec5SDimitry Andric } 6380b57cec5SDimitry Andric 639fe6060f1SDimitry Andric void MCELFStreamer::setAttributeItem(unsigned Attribute, unsigned Value, 640fe6060f1SDimitry Andric bool OverwriteExisting) { 641fe6060f1SDimitry Andric // Look for existing attribute item 642fe6060f1SDimitry Andric if (AttributeItem *Item = getAttributeItem(Attribute)) { 643fe6060f1SDimitry Andric if (!OverwriteExisting) 644fe6060f1SDimitry Andric return; 645fe6060f1SDimitry Andric Item->Type = AttributeItem::NumericAttribute; 646fe6060f1SDimitry Andric Item->IntValue = Value; 647fe6060f1SDimitry Andric return; 648fe6060f1SDimitry Andric } 649fe6060f1SDimitry Andric 650fe6060f1SDimitry Andric // Create new attribute item 651fe6060f1SDimitry Andric AttributeItem Item = {AttributeItem::NumericAttribute, Attribute, Value, 652fe6060f1SDimitry Andric std::string(StringRef(""))}; 653fe6060f1SDimitry Andric Contents.push_back(Item); 654fe6060f1SDimitry Andric } 655fe6060f1SDimitry Andric 656fe6060f1SDimitry Andric void MCELFStreamer::setAttributeItem(unsigned Attribute, StringRef Value, 657fe6060f1SDimitry Andric bool OverwriteExisting) { 658fe6060f1SDimitry Andric // Look for existing attribute item 659fe6060f1SDimitry Andric if (AttributeItem *Item = getAttributeItem(Attribute)) { 660fe6060f1SDimitry Andric if (!OverwriteExisting) 661fe6060f1SDimitry Andric return; 662fe6060f1SDimitry Andric Item->Type = AttributeItem::TextAttribute; 663fe6060f1SDimitry Andric Item->StringValue = std::string(Value); 664fe6060f1SDimitry Andric return; 665fe6060f1SDimitry Andric } 666fe6060f1SDimitry Andric 667fe6060f1SDimitry Andric // Create new attribute item 668fe6060f1SDimitry Andric AttributeItem Item = {AttributeItem::TextAttribute, Attribute, 0, 669fe6060f1SDimitry Andric std::string(Value)}; 670fe6060f1SDimitry Andric Contents.push_back(Item); 671fe6060f1SDimitry Andric } 672fe6060f1SDimitry Andric 673fe6060f1SDimitry Andric void MCELFStreamer::setAttributeItems(unsigned Attribute, unsigned IntValue, 674fe6060f1SDimitry Andric StringRef StringValue, 675fe6060f1SDimitry Andric bool OverwriteExisting) { 676fe6060f1SDimitry Andric // Look for existing attribute item 677fe6060f1SDimitry Andric if (AttributeItem *Item = getAttributeItem(Attribute)) { 678fe6060f1SDimitry Andric if (!OverwriteExisting) 679fe6060f1SDimitry Andric return; 680fe6060f1SDimitry Andric Item->Type = AttributeItem::NumericAndTextAttributes; 681fe6060f1SDimitry Andric Item->IntValue = IntValue; 682fe6060f1SDimitry Andric Item->StringValue = std::string(StringValue); 683fe6060f1SDimitry Andric return; 684fe6060f1SDimitry Andric } 685fe6060f1SDimitry Andric 686fe6060f1SDimitry Andric // Create new attribute item 687fe6060f1SDimitry Andric AttributeItem Item = {AttributeItem::NumericAndTextAttributes, Attribute, 688fe6060f1SDimitry Andric IntValue, std::string(StringValue)}; 689fe6060f1SDimitry Andric Contents.push_back(Item); 690fe6060f1SDimitry Andric } 691fe6060f1SDimitry Andric 692fe6060f1SDimitry Andric MCELFStreamer::AttributeItem * 693fe6060f1SDimitry Andric MCELFStreamer::getAttributeItem(unsigned Attribute) { 694*0fca6ea1SDimitry Andric for (AttributeItem &Item : Contents) 695*0fca6ea1SDimitry Andric if (Item.Tag == Attribute) 696*0fca6ea1SDimitry Andric return &Item; 697fe6060f1SDimitry Andric return nullptr; 698fe6060f1SDimitry Andric } 699fe6060f1SDimitry Andric 700fe6060f1SDimitry Andric size_t 701fe6060f1SDimitry Andric MCELFStreamer::calculateContentSize(SmallVector<AttributeItem, 64> &AttrsVec) { 702fe6060f1SDimitry Andric size_t Result = 0; 703*0fca6ea1SDimitry Andric for (const AttributeItem &Item : AttrsVec) { 704fe6060f1SDimitry Andric switch (Item.Type) { 705fe6060f1SDimitry Andric case AttributeItem::HiddenAttribute: 706fe6060f1SDimitry Andric break; 707fe6060f1SDimitry Andric case AttributeItem::NumericAttribute: 708fe6060f1SDimitry Andric Result += getULEB128Size(Item.Tag); 709fe6060f1SDimitry Andric Result += getULEB128Size(Item.IntValue); 710fe6060f1SDimitry Andric break; 711fe6060f1SDimitry Andric case AttributeItem::TextAttribute: 712fe6060f1SDimitry Andric Result += getULEB128Size(Item.Tag); 713fe6060f1SDimitry Andric Result += Item.StringValue.size() + 1; // string + '\0' 714fe6060f1SDimitry Andric break; 715fe6060f1SDimitry Andric case AttributeItem::NumericAndTextAttributes: 716fe6060f1SDimitry Andric Result += getULEB128Size(Item.Tag); 717fe6060f1SDimitry Andric Result += getULEB128Size(Item.IntValue); 718fe6060f1SDimitry Andric Result += Item.StringValue.size() + 1; // string + '\0'; 719fe6060f1SDimitry Andric break; 720fe6060f1SDimitry Andric } 721fe6060f1SDimitry Andric } 722fe6060f1SDimitry Andric return Result; 723fe6060f1SDimitry Andric } 724fe6060f1SDimitry Andric 725fe6060f1SDimitry Andric void MCELFStreamer::createAttributesSection( 726fe6060f1SDimitry Andric StringRef Vendor, const Twine &Section, unsigned Type, 727fe6060f1SDimitry Andric MCSection *&AttributeSection, SmallVector<AttributeItem, 64> &AttrsVec) { 728fe6060f1SDimitry Andric // <format-version> 729fe6060f1SDimitry Andric // [ <section-length> "vendor-name" 730fe6060f1SDimitry Andric // [ <file-tag> <size> <attribute>* 731fe6060f1SDimitry Andric // | <section-tag> <size> <section-number>* 0 <attribute>* 732fe6060f1SDimitry Andric // | <symbol-tag> <size> <symbol-number>* 0 <attribute>* 733fe6060f1SDimitry Andric // ]+ 734fe6060f1SDimitry Andric // ]* 735fe6060f1SDimitry Andric 736fe6060f1SDimitry Andric // Switch section to AttributeSection or get/create the section. 737fe6060f1SDimitry Andric if (AttributeSection) { 73881ad6265SDimitry Andric switchSection(AttributeSection); 739fe6060f1SDimitry Andric } else { 740fe6060f1SDimitry Andric AttributeSection = getContext().getELFSection(Section, Type, 0); 74181ad6265SDimitry Andric switchSection(AttributeSection); 742fe6060f1SDimitry Andric 743fe6060f1SDimitry Andric // Format version 744fe6060f1SDimitry Andric emitInt8(0x41); 745fe6060f1SDimitry Andric } 746fe6060f1SDimitry Andric 747fe6060f1SDimitry Andric // Vendor size + Vendor name + '\0' 748fe6060f1SDimitry Andric const size_t VendorHeaderSize = 4 + Vendor.size() + 1; 749fe6060f1SDimitry Andric 750fe6060f1SDimitry Andric // Tag + Tag Size 751fe6060f1SDimitry Andric const size_t TagHeaderSize = 1 + 4; 752fe6060f1SDimitry Andric 753fe6060f1SDimitry Andric const size_t ContentsSize = calculateContentSize(AttrsVec); 754fe6060f1SDimitry Andric 755fe6060f1SDimitry Andric emitInt32(VendorHeaderSize + TagHeaderSize + ContentsSize); 756fe6060f1SDimitry Andric emitBytes(Vendor); 757fe6060f1SDimitry Andric emitInt8(0); // '\0' 758fe6060f1SDimitry Andric 759fe6060f1SDimitry Andric emitInt8(ARMBuildAttrs::File); 760fe6060f1SDimitry Andric emitInt32(TagHeaderSize + ContentsSize); 761fe6060f1SDimitry Andric 762fe6060f1SDimitry Andric // Size should have been accounted for already, now 763fe6060f1SDimitry Andric // emit each field as its type (ULEB or String) 764*0fca6ea1SDimitry Andric for (const AttributeItem &Item : AttrsVec) { 765fe6060f1SDimitry Andric emitULEB128IntValue(Item.Tag); 766fe6060f1SDimitry Andric switch (Item.Type) { 767fe6060f1SDimitry Andric default: 768fe6060f1SDimitry Andric llvm_unreachable("Invalid attribute type"); 769fe6060f1SDimitry Andric case AttributeItem::NumericAttribute: 770fe6060f1SDimitry Andric emitULEB128IntValue(Item.IntValue); 771fe6060f1SDimitry Andric break; 772fe6060f1SDimitry Andric case AttributeItem::TextAttribute: 773fe6060f1SDimitry Andric emitBytes(Item.StringValue); 774fe6060f1SDimitry Andric emitInt8(0); // '\0' 775fe6060f1SDimitry Andric break; 776fe6060f1SDimitry Andric case AttributeItem::NumericAndTextAttributes: 777fe6060f1SDimitry Andric emitULEB128IntValue(Item.IntValue); 778fe6060f1SDimitry Andric emitBytes(Item.StringValue); 779fe6060f1SDimitry Andric emitInt8(0); // '\0' 780fe6060f1SDimitry Andric break; 781fe6060f1SDimitry Andric } 782fe6060f1SDimitry Andric } 783fe6060f1SDimitry Andric 784fe6060f1SDimitry Andric AttrsVec.clear(); 785fe6060f1SDimitry Andric } 786fe6060f1SDimitry Andric 7870b57cec5SDimitry Andric MCStreamer *llvm::createELFStreamer(MCContext &Context, 7880b57cec5SDimitry Andric std::unique_ptr<MCAsmBackend> &&MAB, 7890b57cec5SDimitry Andric std::unique_ptr<MCObjectWriter> &&OW, 790*0fca6ea1SDimitry Andric std::unique_ptr<MCCodeEmitter> &&CE) { 7910b57cec5SDimitry Andric MCELFStreamer *S = 7920b57cec5SDimitry Andric new MCELFStreamer(Context, std::move(MAB), std::move(OW), std::move(CE)); 7930b57cec5SDimitry Andric return S; 7940b57cec5SDimitry Andric } 795