xref: /freebsd-src/contrib/llvm-project/llvm/lib/MC/MCELFStreamer.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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