106f32e7eSjoerg //===- lib/MC/ARMELFStreamer.cpp - ELF Object Output for ARM --------------===//
206f32e7eSjoerg //
306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information.
506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606f32e7eSjoerg //
706f32e7eSjoerg //===----------------------------------------------------------------------===//
806f32e7eSjoerg //
906f32e7eSjoerg // This file assembles .s files and emits ARM ELF .o object files. Different
1006f32e7eSjoerg // from generic ELF streamer in emitting mapping symbols ($a, $t and $d) to
1106f32e7eSjoerg // delimit regions of data and code.
1206f32e7eSjoerg //
1306f32e7eSjoerg //===----------------------------------------------------------------------===//
1406f32e7eSjoerg 
1506f32e7eSjoerg #include "ARMRegisterInfo.h"
1606f32e7eSjoerg #include "ARMUnwindOpAsm.h"
1706f32e7eSjoerg #include "llvm/ADT/DenseMap.h"
1806f32e7eSjoerg #include "llvm/ADT/SmallString.h"
1906f32e7eSjoerg #include "llvm/ADT/SmallVector.h"
2006f32e7eSjoerg #include "llvm/ADT/StringRef.h"
2106f32e7eSjoerg #include "llvm/ADT/Triple.h"
2206f32e7eSjoerg #include "llvm/ADT/Twine.h"
2306f32e7eSjoerg #include "llvm/BinaryFormat/ELF.h"
2406f32e7eSjoerg #include "llvm/MC/MCAsmBackend.h"
2506f32e7eSjoerg #include "llvm/MC/MCAsmInfo.h"
2606f32e7eSjoerg #include "llvm/MC/MCAssembler.h"
2706f32e7eSjoerg #include "llvm/MC/MCCodeEmitter.h"
2806f32e7eSjoerg #include "llvm/MC/MCContext.h"
2906f32e7eSjoerg #include "llvm/MC/MCELFStreamer.h"
3006f32e7eSjoerg #include "llvm/MC/MCExpr.h"
3106f32e7eSjoerg #include "llvm/MC/MCFixup.h"
3206f32e7eSjoerg #include "llvm/MC/MCFragment.h"
3306f32e7eSjoerg #include "llvm/MC/MCInst.h"
3406f32e7eSjoerg #include "llvm/MC/MCInstPrinter.h"
3506f32e7eSjoerg #include "llvm/MC/MCObjectWriter.h"
3606f32e7eSjoerg #include "llvm/MC/MCRegisterInfo.h"
3706f32e7eSjoerg #include "llvm/MC/MCSection.h"
3806f32e7eSjoerg #include "llvm/MC/MCSectionELF.h"
3906f32e7eSjoerg #include "llvm/MC/MCStreamer.h"
4006f32e7eSjoerg #include "llvm/MC/MCSubtargetInfo.h"
4106f32e7eSjoerg #include "llvm/MC/MCSymbol.h"
4206f32e7eSjoerg #include "llvm/MC/MCSymbolELF.h"
4306f32e7eSjoerg #include "llvm/MC/SectionKind.h"
4406f32e7eSjoerg #include "llvm/Support/ARMBuildAttributes.h"
4506f32e7eSjoerg #include "llvm/Support/ARMEHABI.h"
4606f32e7eSjoerg #include "llvm/Support/Casting.h"
4706f32e7eSjoerg #include "llvm/Support/ErrorHandling.h"
4806f32e7eSjoerg #include "llvm/Support/FormattedStream.h"
4906f32e7eSjoerg #include "llvm/Support/LEB128.h"
5006f32e7eSjoerg #include "llvm/Support/TargetParser.h"
5106f32e7eSjoerg #include "llvm/Support/raw_ostream.h"
5206f32e7eSjoerg #include <algorithm>
5306f32e7eSjoerg #include <cassert>
5406f32e7eSjoerg #include <climits>
5506f32e7eSjoerg #include <cstddef>
5606f32e7eSjoerg #include <cstdint>
5706f32e7eSjoerg #include <string>
5806f32e7eSjoerg 
5906f32e7eSjoerg using namespace llvm;
6006f32e7eSjoerg 
GetAEABIUnwindPersonalityName(unsigned Index)6106f32e7eSjoerg static std::string GetAEABIUnwindPersonalityName(unsigned Index) {
6206f32e7eSjoerg   assert(Index < ARM::EHABI::NUM_PERSONALITY_INDEX &&
6306f32e7eSjoerg          "Invalid personality index");
6406f32e7eSjoerg   return (Twine("__aeabi_unwind_cpp_pr") + Twine(Index)).str();
6506f32e7eSjoerg }
6606f32e7eSjoerg 
6706f32e7eSjoerg namespace {
6806f32e7eSjoerg 
6906f32e7eSjoerg class ARMELFStreamer;
7006f32e7eSjoerg 
7106f32e7eSjoerg class ARMTargetAsmStreamer : public ARMTargetStreamer {
7206f32e7eSjoerg   formatted_raw_ostream &OS;
7306f32e7eSjoerg   MCInstPrinter &InstPrinter;
7406f32e7eSjoerg   bool IsVerboseAsm;
7506f32e7eSjoerg 
7606f32e7eSjoerg   void emitFnStart() override;
7706f32e7eSjoerg   void emitFnEnd() override;
7806f32e7eSjoerg   void emitCantUnwind() override;
7906f32e7eSjoerg   void emitPersonality(const MCSymbol *Personality) override;
8006f32e7eSjoerg   void emitPersonalityIndex(unsigned Index) override;
8106f32e7eSjoerg   void emitHandlerData() override;
8206f32e7eSjoerg   void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0) override;
8306f32e7eSjoerg   void emitMovSP(unsigned Reg, int64_t Offset = 0) override;
8406f32e7eSjoerg   void emitPad(int64_t Offset) override;
8506f32e7eSjoerg   void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
8606f32e7eSjoerg                    bool isVector) override;
8706f32e7eSjoerg   void emitUnwindRaw(int64_t Offset,
8806f32e7eSjoerg                      const SmallVectorImpl<uint8_t> &Opcodes) override;
8906f32e7eSjoerg 
9006f32e7eSjoerg   void switchVendor(StringRef Vendor) override;
9106f32e7eSjoerg   void emitAttribute(unsigned Attribute, unsigned Value) override;
9206f32e7eSjoerg   void emitTextAttribute(unsigned Attribute, StringRef String) override;
9306f32e7eSjoerg   void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
9406f32e7eSjoerg                             StringRef StringValue) override;
9506f32e7eSjoerg   void emitArch(ARM::ArchKind Arch) override;
96*da58b97aSjoerg   void emitArchExtension(uint64_t ArchExt) override;
9706f32e7eSjoerg   void emitObjectArch(ARM::ArchKind Arch) override;
9806f32e7eSjoerg   void emitFPU(unsigned FPU) override;
9906f32e7eSjoerg   void emitInst(uint32_t Inst, char Suffix = '\0') override;
10006f32e7eSjoerg   void finishAttributeSection() override;
10106f32e7eSjoerg 
10206f32e7eSjoerg   void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override;
10306f32e7eSjoerg   void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override;
10406f32e7eSjoerg 
10506f32e7eSjoerg public:
10606f32e7eSjoerg   ARMTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS,
10706f32e7eSjoerg                        MCInstPrinter &InstPrinter, bool VerboseAsm);
10806f32e7eSjoerg };
10906f32e7eSjoerg 
ARMTargetAsmStreamer(MCStreamer & S,formatted_raw_ostream & OS,MCInstPrinter & InstPrinter,bool VerboseAsm)11006f32e7eSjoerg ARMTargetAsmStreamer::ARMTargetAsmStreamer(MCStreamer &S,
11106f32e7eSjoerg                                            formatted_raw_ostream &OS,
11206f32e7eSjoerg                                            MCInstPrinter &InstPrinter,
11306f32e7eSjoerg                                            bool VerboseAsm)
11406f32e7eSjoerg     : ARMTargetStreamer(S), OS(OS), InstPrinter(InstPrinter),
11506f32e7eSjoerg       IsVerboseAsm(VerboseAsm) {}
11606f32e7eSjoerg 
emitFnStart()11706f32e7eSjoerg void ARMTargetAsmStreamer::emitFnStart() { OS << "\t.fnstart\n"; }
emitFnEnd()11806f32e7eSjoerg void ARMTargetAsmStreamer::emitFnEnd() { OS << "\t.fnend\n"; }
emitCantUnwind()11906f32e7eSjoerg void ARMTargetAsmStreamer::emitCantUnwind() { OS << "\t.cantunwind\n"; }
12006f32e7eSjoerg 
emitPersonality(const MCSymbol * Personality)12106f32e7eSjoerg void ARMTargetAsmStreamer::emitPersonality(const MCSymbol *Personality) {
12206f32e7eSjoerg   OS << "\t.personality " << Personality->getName() << '\n';
12306f32e7eSjoerg }
12406f32e7eSjoerg 
emitPersonalityIndex(unsigned Index)12506f32e7eSjoerg void ARMTargetAsmStreamer::emitPersonalityIndex(unsigned Index) {
12606f32e7eSjoerg   OS << "\t.personalityindex " << Index << '\n';
12706f32e7eSjoerg }
12806f32e7eSjoerg 
emitHandlerData()12906f32e7eSjoerg void ARMTargetAsmStreamer::emitHandlerData() { OS << "\t.handlerdata\n"; }
13006f32e7eSjoerg 
emitSetFP(unsigned FpReg,unsigned SpReg,int64_t Offset)13106f32e7eSjoerg void ARMTargetAsmStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
13206f32e7eSjoerg                                      int64_t Offset) {
13306f32e7eSjoerg   OS << "\t.setfp\t";
13406f32e7eSjoerg   InstPrinter.printRegName(OS, FpReg);
13506f32e7eSjoerg   OS << ", ";
13606f32e7eSjoerg   InstPrinter.printRegName(OS, SpReg);
13706f32e7eSjoerg   if (Offset)
13806f32e7eSjoerg     OS << ", #" << Offset;
13906f32e7eSjoerg   OS << '\n';
14006f32e7eSjoerg }
14106f32e7eSjoerg 
emitMovSP(unsigned Reg,int64_t Offset)14206f32e7eSjoerg void ARMTargetAsmStreamer::emitMovSP(unsigned Reg, int64_t Offset) {
14306f32e7eSjoerg   assert((Reg != ARM::SP && Reg != ARM::PC) &&
14406f32e7eSjoerg          "the operand of .movsp cannot be either sp or pc");
14506f32e7eSjoerg 
14606f32e7eSjoerg   OS << "\t.movsp\t";
14706f32e7eSjoerg   InstPrinter.printRegName(OS, Reg);
14806f32e7eSjoerg   if (Offset)
14906f32e7eSjoerg     OS << ", #" << Offset;
15006f32e7eSjoerg   OS << '\n';
15106f32e7eSjoerg }
15206f32e7eSjoerg 
emitPad(int64_t Offset)15306f32e7eSjoerg void ARMTargetAsmStreamer::emitPad(int64_t Offset) {
15406f32e7eSjoerg   OS << "\t.pad\t#" << Offset << '\n';
15506f32e7eSjoerg }
15606f32e7eSjoerg 
emitRegSave(const SmallVectorImpl<unsigned> & RegList,bool isVector)15706f32e7eSjoerg void ARMTargetAsmStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
15806f32e7eSjoerg                                        bool isVector) {
15906f32e7eSjoerg   assert(RegList.size() && "RegList should not be empty");
16006f32e7eSjoerg   if (isVector)
16106f32e7eSjoerg     OS << "\t.vsave\t{";
16206f32e7eSjoerg   else
16306f32e7eSjoerg     OS << "\t.save\t{";
16406f32e7eSjoerg 
16506f32e7eSjoerg   InstPrinter.printRegName(OS, RegList[0]);
16606f32e7eSjoerg 
16706f32e7eSjoerg   for (unsigned i = 1, e = RegList.size(); i != e; ++i) {
16806f32e7eSjoerg     OS << ", ";
16906f32e7eSjoerg     InstPrinter.printRegName(OS, RegList[i]);
17006f32e7eSjoerg   }
17106f32e7eSjoerg 
17206f32e7eSjoerg   OS << "}\n";
17306f32e7eSjoerg }
17406f32e7eSjoerg 
switchVendor(StringRef Vendor)17506f32e7eSjoerg void ARMTargetAsmStreamer::switchVendor(StringRef Vendor) {}
17606f32e7eSjoerg 
emitAttribute(unsigned Attribute,unsigned Value)17706f32e7eSjoerg void ARMTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
17806f32e7eSjoerg   OS << "\t.eabi_attribute\t" << Attribute << ", " << Twine(Value);
17906f32e7eSjoerg   if (IsVerboseAsm) {
180*da58b97aSjoerg     StringRef Name =
181*da58b97aSjoerg         ELFAttrs::attrTypeAsString(Attribute, ARMBuildAttrs::ARMAttributeTags);
18206f32e7eSjoerg     if (!Name.empty())
18306f32e7eSjoerg       OS << "\t@ " << Name;
18406f32e7eSjoerg   }
18506f32e7eSjoerg   OS << "\n";
18606f32e7eSjoerg }
18706f32e7eSjoerg 
emitTextAttribute(unsigned Attribute,StringRef String)18806f32e7eSjoerg void ARMTargetAsmStreamer::emitTextAttribute(unsigned Attribute,
18906f32e7eSjoerg                                              StringRef String) {
19006f32e7eSjoerg   switch (Attribute) {
19106f32e7eSjoerg   case ARMBuildAttrs::CPU_name:
19206f32e7eSjoerg     OS << "\t.cpu\t" << String.lower();
19306f32e7eSjoerg     break;
19406f32e7eSjoerg   default:
19506f32e7eSjoerg     OS << "\t.eabi_attribute\t" << Attribute << ", \"" << String << "\"";
19606f32e7eSjoerg     if (IsVerboseAsm) {
197*da58b97aSjoerg       StringRef Name = ELFAttrs::attrTypeAsString(
198*da58b97aSjoerg           Attribute, ARMBuildAttrs::ARMAttributeTags);
19906f32e7eSjoerg       if (!Name.empty())
20006f32e7eSjoerg         OS << "\t@ " << Name;
20106f32e7eSjoerg     }
20206f32e7eSjoerg     break;
20306f32e7eSjoerg   }
20406f32e7eSjoerg   OS << "\n";
20506f32e7eSjoerg }
20606f32e7eSjoerg 
emitIntTextAttribute(unsigned Attribute,unsigned IntValue,StringRef StringValue)20706f32e7eSjoerg void ARMTargetAsmStreamer::emitIntTextAttribute(unsigned Attribute,
20806f32e7eSjoerg                                                 unsigned IntValue,
20906f32e7eSjoerg                                                 StringRef StringValue) {
21006f32e7eSjoerg   switch (Attribute) {
21106f32e7eSjoerg   default: llvm_unreachable("unsupported multi-value attribute in asm mode");
21206f32e7eSjoerg   case ARMBuildAttrs::compatibility:
21306f32e7eSjoerg     OS << "\t.eabi_attribute\t" << Attribute << ", " << IntValue;
21406f32e7eSjoerg     if (!StringValue.empty())
21506f32e7eSjoerg       OS << ", \"" << StringValue << "\"";
21606f32e7eSjoerg     if (IsVerboseAsm)
217*da58b97aSjoerg       OS << "\t@ "
218*da58b97aSjoerg          << ELFAttrs::attrTypeAsString(Attribute,
219*da58b97aSjoerg                                        ARMBuildAttrs::ARMAttributeTags);
22006f32e7eSjoerg     break;
22106f32e7eSjoerg   }
22206f32e7eSjoerg   OS << "\n";
22306f32e7eSjoerg }
22406f32e7eSjoerg 
emitArch(ARM::ArchKind Arch)22506f32e7eSjoerg void ARMTargetAsmStreamer::emitArch(ARM::ArchKind Arch) {
22606f32e7eSjoerg   OS << "\t.arch\t" << ARM::getArchName(Arch) << "\n";
22706f32e7eSjoerg }
22806f32e7eSjoerg 
emitArchExtension(uint64_t ArchExt)229*da58b97aSjoerg void ARMTargetAsmStreamer::emitArchExtension(uint64_t ArchExt) {
23006f32e7eSjoerg   OS << "\t.arch_extension\t" << ARM::getArchExtName(ArchExt) << "\n";
23106f32e7eSjoerg }
23206f32e7eSjoerg 
emitObjectArch(ARM::ArchKind Arch)23306f32e7eSjoerg void ARMTargetAsmStreamer::emitObjectArch(ARM::ArchKind Arch) {
23406f32e7eSjoerg   OS << "\t.object_arch\t" << ARM::getArchName(Arch) << '\n';
23506f32e7eSjoerg }
23606f32e7eSjoerg 
emitFPU(unsigned FPU)23706f32e7eSjoerg void ARMTargetAsmStreamer::emitFPU(unsigned FPU) {
23806f32e7eSjoerg   OS << "\t.fpu\t" << ARM::getFPUName(FPU) << "\n";
23906f32e7eSjoerg }
24006f32e7eSjoerg 
finishAttributeSection()24106f32e7eSjoerg void ARMTargetAsmStreamer::finishAttributeSection() {}
24206f32e7eSjoerg 
24306f32e7eSjoerg void
AnnotateTLSDescriptorSequence(const MCSymbolRefExpr * S)24406f32e7eSjoerg ARMTargetAsmStreamer::AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *S) {
245*da58b97aSjoerg   OS << "\t.tlsdescseq\t" << S->getSymbol().getName() << "\n";
24606f32e7eSjoerg }
24706f32e7eSjoerg 
emitThumbSet(MCSymbol * Symbol,const MCExpr * Value)24806f32e7eSjoerg void ARMTargetAsmStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) {
24906f32e7eSjoerg   const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();
25006f32e7eSjoerg 
25106f32e7eSjoerg   OS << "\t.thumb_set\t";
25206f32e7eSjoerg   Symbol->print(OS, MAI);
25306f32e7eSjoerg   OS << ", ";
25406f32e7eSjoerg   Value->print(OS, MAI);
25506f32e7eSjoerg   OS << '\n';
25606f32e7eSjoerg }
25706f32e7eSjoerg 
emitInst(uint32_t Inst,char Suffix)25806f32e7eSjoerg void ARMTargetAsmStreamer::emitInst(uint32_t Inst, char Suffix) {
25906f32e7eSjoerg   OS << "\t.inst";
26006f32e7eSjoerg   if (Suffix)
26106f32e7eSjoerg     OS << "." << Suffix;
26206f32e7eSjoerg   OS << "\t0x" << Twine::utohexstr(Inst) << "\n";
26306f32e7eSjoerg }
26406f32e7eSjoerg 
emitUnwindRaw(int64_t Offset,const SmallVectorImpl<uint8_t> & Opcodes)26506f32e7eSjoerg void ARMTargetAsmStreamer::emitUnwindRaw(int64_t Offset,
26606f32e7eSjoerg                                       const SmallVectorImpl<uint8_t> &Opcodes) {
26706f32e7eSjoerg   OS << "\t.unwind_raw " << Offset;
26806f32e7eSjoerg   for (SmallVectorImpl<uint8_t>::const_iterator OCI = Opcodes.begin(),
26906f32e7eSjoerg                                                 OCE = Opcodes.end();
27006f32e7eSjoerg        OCI != OCE; ++OCI)
27106f32e7eSjoerg     OS << ", 0x" << Twine::utohexstr(*OCI);
27206f32e7eSjoerg   OS << '\n';
27306f32e7eSjoerg }
27406f32e7eSjoerg 
27506f32e7eSjoerg class ARMTargetELFStreamer : public ARMTargetStreamer {
27606f32e7eSjoerg private:
27706f32e7eSjoerg   // This structure holds all attributes, accounting for
27806f32e7eSjoerg   // their string/numeric value, so we can later emit them
27906f32e7eSjoerg   // in declaration order, keeping all in the same vector
28006f32e7eSjoerg   struct AttributeItem {
28106f32e7eSjoerg     enum {
28206f32e7eSjoerg       HiddenAttribute = 0,
28306f32e7eSjoerg       NumericAttribute,
28406f32e7eSjoerg       TextAttribute,
28506f32e7eSjoerg       NumericAndTextAttributes
28606f32e7eSjoerg     } Type;
28706f32e7eSjoerg     unsigned Tag;
28806f32e7eSjoerg     unsigned IntValue;
28906f32e7eSjoerg     std::string StringValue;
29006f32e7eSjoerg 
LessTag__anon5806bc350111::ARMTargetELFStreamer::AttributeItem29106f32e7eSjoerg     static bool LessTag(const AttributeItem &LHS, const AttributeItem &RHS) {
29206f32e7eSjoerg       // The conformance tag must be emitted first when serialised
29306f32e7eSjoerg       // into an object file. Specifically, the addenda to the ARM ABI
29406f32e7eSjoerg       // states that (2.3.7.4):
29506f32e7eSjoerg       //
29606f32e7eSjoerg       // "To simplify recognition by consumers in the common case of
29706f32e7eSjoerg       // claiming conformity for the whole file, this tag should be
29806f32e7eSjoerg       // emitted first in a file-scope sub-subsection of the first
29906f32e7eSjoerg       // public subsection of the attributes section."
30006f32e7eSjoerg       //
30106f32e7eSjoerg       // So it is special-cased in this comparison predicate when the
30206f32e7eSjoerg       // attributes are sorted in finishAttributeSection().
30306f32e7eSjoerg       return (RHS.Tag != ARMBuildAttrs::conformance) &&
30406f32e7eSjoerg              ((LHS.Tag == ARMBuildAttrs::conformance) || (LHS.Tag < RHS.Tag));
30506f32e7eSjoerg     }
30606f32e7eSjoerg   };
30706f32e7eSjoerg 
30806f32e7eSjoerg   StringRef CurrentVendor;
30906f32e7eSjoerg   unsigned FPU = ARM::FK_INVALID;
31006f32e7eSjoerg   ARM::ArchKind Arch = ARM::ArchKind::INVALID;
31106f32e7eSjoerg   ARM::ArchKind EmittedArch = ARM::ArchKind::INVALID;
31206f32e7eSjoerg   SmallVector<AttributeItem, 64> Contents;
31306f32e7eSjoerg 
31406f32e7eSjoerg   MCSection *AttributeSection = nullptr;
31506f32e7eSjoerg 
getAttributeItem(unsigned Attribute)31606f32e7eSjoerg   AttributeItem *getAttributeItem(unsigned Attribute) {
31706f32e7eSjoerg     for (size_t i = 0; i < Contents.size(); ++i)
31806f32e7eSjoerg       if (Contents[i].Tag == Attribute)
31906f32e7eSjoerg         return &Contents[i];
32006f32e7eSjoerg     return nullptr;
32106f32e7eSjoerg   }
32206f32e7eSjoerg 
setAttributeItem(unsigned Attribute,unsigned Value,bool OverwriteExisting)32306f32e7eSjoerg   void setAttributeItem(unsigned Attribute, unsigned Value,
32406f32e7eSjoerg                         bool OverwriteExisting) {
32506f32e7eSjoerg     // Look for existing attribute item
32606f32e7eSjoerg     if (AttributeItem *Item = getAttributeItem(Attribute)) {
32706f32e7eSjoerg       if (!OverwriteExisting)
32806f32e7eSjoerg         return;
32906f32e7eSjoerg       Item->Type = AttributeItem::NumericAttribute;
33006f32e7eSjoerg       Item->IntValue = Value;
33106f32e7eSjoerg       return;
33206f32e7eSjoerg     }
33306f32e7eSjoerg 
33406f32e7eSjoerg     // Create new attribute item
335*da58b97aSjoerg     AttributeItem Item = {AttributeItem::NumericAttribute, Attribute, Value,
336*da58b97aSjoerg                           std::string(StringRef(""))};
33706f32e7eSjoerg     Contents.push_back(Item);
33806f32e7eSjoerg   }
33906f32e7eSjoerg 
setAttributeItem(unsigned Attribute,StringRef Value,bool OverwriteExisting)34006f32e7eSjoerg   void setAttributeItem(unsigned Attribute, StringRef Value,
34106f32e7eSjoerg                         bool OverwriteExisting) {
34206f32e7eSjoerg     // Look for existing attribute item
34306f32e7eSjoerg     if (AttributeItem *Item = getAttributeItem(Attribute)) {
34406f32e7eSjoerg       if (!OverwriteExisting)
34506f32e7eSjoerg         return;
34606f32e7eSjoerg       Item->Type = AttributeItem::TextAttribute;
347*da58b97aSjoerg       Item->StringValue = std::string(Value);
34806f32e7eSjoerg       return;
34906f32e7eSjoerg     }
35006f32e7eSjoerg 
35106f32e7eSjoerg     // Create new attribute item
352*da58b97aSjoerg     AttributeItem Item = {AttributeItem::TextAttribute, Attribute, 0,
353*da58b97aSjoerg                           std::string(Value)};
35406f32e7eSjoerg     Contents.push_back(Item);
35506f32e7eSjoerg   }
35606f32e7eSjoerg 
setAttributeItems(unsigned Attribute,unsigned IntValue,StringRef StringValue,bool OverwriteExisting)35706f32e7eSjoerg   void setAttributeItems(unsigned Attribute, unsigned IntValue,
35806f32e7eSjoerg                          StringRef StringValue, bool OverwriteExisting) {
35906f32e7eSjoerg     // Look for existing attribute item
36006f32e7eSjoerg     if (AttributeItem *Item = getAttributeItem(Attribute)) {
36106f32e7eSjoerg       if (!OverwriteExisting)
36206f32e7eSjoerg         return;
36306f32e7eSjoerg       Item->Type = AttributeItem::NumericAndTextAttributes;
36406f32e7eSjoerg       Item->IntValue = IntValue;
365*da58b97aSjoerg       Item->StringValue = std::string(StringValue);
36606f32e7eSjoerg       return;
36706f32e7eSjoerg     }
36806f32e7eSjoerg 
36906f32e7eSjoerg     // Create new attribute item
370*da58b97aSjoerg     AttributeItem Item = {AttributeItem::NumericAndTextAttributes, Attribute,
371*da58b97aSjoerg                           IntValue, std::string(StringValue)};
37206f32e7eSjoerg     Contents.push_back(Item);
37306f32e7eSjoerg   }
37406f32e7eSjoerg 
37506f32e7eSjoerg   void emitArchDefaultAttributes();
37606f32e7eSjoerg   void emitFPUDefaultAttributes();
37706f32e7eSjoerg 
37806f32e7eSjoerg   ARMELFStreamer &getStreamer();
37906f32e7eSjoerg 
38006f32e7eSjoerg   void emitFnStart() override;
38106f32e7eSjoerg   void emitFnEnd() override;
38206f32e7eSjoerg   void emitCantUnwind() override;
38306f32e7eSjoerg   void emitPersonality(const MCSymbol *Personality) override;
38406f32e7eSjoerg   void emitPersonalityIndex(unsigned Index) override;
38506f32e7eSjoerg   void emitHandlerData() override;
38606f32e7eSjoerg   void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0) override;
38706f32e7eSjoerg   void emitMovSP(unsigned Reg, int64_t Offset = 0) override;
38806f32e7eSjoerg   void emitPad(int64_t Offset) override;
38906f32e7eSjoerg   void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
39006f32e7eSjoerg                    bool isVector) override;
39106f32e7eSjoerg   void emitUnwindRaw(int64_t Offset,
39206f32e7eSjoerg                      const SmallVectorImpl<uint8_t> &Opcodes) override;
39306f32e7eSjoerg 
39406f32e7eSjoerg   void switchVendor(StringRef Vendor) override;
39506f32e7eSjoerg   void emitAttribute(unsigned Attribute, unsigned Value) override;
39606f32e7eSjoerg   void emitTextAttribute(unsigned Attribute, StringRef String) override;
39706f32e7eSjoerg   void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
39806f32e7eSjoerg                             StringRef StringValue) override;
39906f32e7eSjoerg   void emitArch(ARM::ArchKind Arch) override;
40006f32e7eSjoerg   void emitObjectArch(ARM::ArchKind Arch) override;
40106f32e7eSjoerg   void emitFPU(unsigned FPU) override;
40206f32e7eSjoerg   void emitInst(uint32_t Inst, char Suffix = '\0') override;
40306f32e7eSjoerg   void finishAttributeSection() override;
40406f32e7eSjoerg   void emitLabel(MCSymbol *Symbol) override;
40506f32e7eSjoerg 
40606f32e7eSjoerg   void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override;
40706f32e7eSjoerg   void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override;
40806f32e7eSjoerg 
40906f32e7eSjoerg   size_t calculateContentSize() const;
41006f32e7eSjoerg 
41106f32e7eSjoerg   // Reset state between object emissions
41206f32e7eSjoerg   void reset() override;
41306f32e7eSjoerg 
41406f32e7eSjoerg public:
ARMTargetELFStreamer(MCStreamer & S)41506f32e7eSjoerg   ARMTargetELFStreamer(MCStreamer &S)
41606f32e7eSjoerg     : ARMTargetStreamer(S), CurrentVendor("aeabi") {}
41706f32e7eSjoerg };
41806f32e7eSjoerg 
41906f32e7eSjoerg /// Extend the generic ELFStreamer class so that it can emit mapping symbols at
42006f32e7eSjoerg /// the appropriate points in the object files. These symbols are defined in the
42106f32e7eSjoerg /// ARM ELF ABI: infocenter.arm.com/help/topic/com.arm.../IHI0044D_aaelf.pdf.
42206f32e7eSjoerg ///
42306f32e7eSjoerg /// In brief: $a, $t or $d should be emitted at the start of each contiguous
42406f32e7eSjoerg /// region of ARM code, Thumb code or data in a section. In practice, this
42506f32e7eSjoerg /// emission does not rely on explicit assembler directives but on inherent
42606f32e7eSjoerg /// properties of the directives doing the emission (e.g. ".byte" is data, "add
42706f32e7eSjoerg /// r0, r0, r0" an instruction).
42806f32e7eSjoerg ///
42906f32e7eSjoerg /// As a result this system is orthogonal to the DataRegion infrastructure used
43006f32e7eSjoerg /// by MachO. Beware!
43106f32e7eSjoerg class ARMELFStreamer : public MCELFStreamer {
43206f32e7eSjoerg public:
43306f32e7eSjoerg   friend class ARMTargetELFStreamer;
43406f32e7eSjoerg 
ARMELFStreamer(MCContext & Context,std::unique_ptr<MCAsmBackend> TAB,std::unique_ptr<MCObjectWriter> OW,std::unique_ptr<MCCodeEmitter> Emitter,bool IsThumb,bool IsAndroid)43506f32e7eSjoerg   ARMELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
436*da58b97aSjoerg                  std::unique_ptr<MCObjectWriter> OW,
437*da58b97aSjoerg                  std::unique_ptr<MCCodeEmitter> Emitter, bool IsThumb,
438*da58b97aSjoerg                  bool IsAndroid)
439*da58b97aSjoerg       : MCELFStreamer(Context, std::move(TAB), std::move(OW),
440*da58b97aSjoerg                       std::move(Emitter)),
441*da58b97aSjoerg         IsThumb(IsThumb), IsAndroid(IsAndroid) {
44206f32e7eSjoerg     EHReset();
44306f32e7eSjoerg   }
44406f32e7eSjoerg 
44506f32e7eSjoerg   ~ARMELFStreamer() override = default;
44606f32e7eSjoerg 
447*da58b97aSjoerg   void finishImpl() override;
44806f32e7eSjoerg 
44906f32e7eSjoerg   // ARM exception handling directives
45006f32e7eSjoerg   void emitFnStart();
45106f32e7eSjoerg   void emitFnEnd();
45206f32e7eSjoerg   void emitCantUnwind();
45306f32e7eSjoerg   void emitPersonality(const MCSymbol *Per);
45406f32e7eSjoerg   void emitPersonalityIndex(unsigned index);
45506f32e7eSjoerg   void emitHandlerData();
45606f32e7eSjoerg   void emitSetFP(unsigned NewFpReg, unsigned NewSpReg, int64_t Offset = 0);
45706f32e7eSjoerg   void emitMovSP(unsigned Reg, int64_t Offset = 0);
45806f32e7eSjoerg   void emitPad(int64_t Offset);
45906f32e7eSjoerg   void emitRegSave(const SmallVectorImpl<unsigned> &RegList, bool isVector);
46006f32e7eSjoerg   void emitUnwindRaw(int64_t Offset, const SmallVectorImpl<uint8_t> &Opcodes);
emitFill(const MCExpr & NumBytes,uint64_t FillValue,SMLoc Loc)46106f32e7eSjoerg   void emitFill(const MCExpr &NumBytes, uint64_t FillValue,
46206f32e7eSjoerg                 SMLoc Loc) override {
463*da58b97aSjoerg     emitDataMappingSymbol();
46406f32e7eSjoerg     MCObjectStreamer::emitFill(NumBytes, FillValue, Loc);
46506f32e7eSjoerg   }
46606f32e7eSjoerg 
changeSection(MCSection * Section,const MCExpr * Subsection)467*da58b97aSjoerg   void changeSection(MCSection *Section, const MCExpr *Subsection) override {
46806f32e7eSjoerg     LastMappingSymbols[getCurrentSection().first] = std::move(LastEMSInfo);
469*da58b97aSjoerg     MCELFStreamer::changeSection(Section, Subsection);
47006f32e7eSjoerg     auto LastMappingSymbol = LastMappingSymbols.find(Section);
47106f32e7eSjoerg     if (LastMappingSymbol != LastMappingSymbols.end()) {
47206f32e7eSjoerg       LastEMSInfo = std::move(LastMappingSymbol->second);
47306f32e7eSjoerg       return;
47406f32e7eSjoerg     }
47506f32e7eSjoerg     LastEMSInfo.reset(new ElfMappingSymbolInfo(SMLoc(), nullptr, 0));
47606f32e7eSjoerg   }
47706f32e7eSjoerg 
47806f32e7eSjoerg   /// This function is the one used to emit instruction data into the ELF
47906f32e7eSjoerg   /// streamer. We override it to add the appropriate mapping symbol if
48006f32e7eSjoerg   /// necessary.
emitInstruction(const MCInst & Inst,const MCSubtargetInfo & STI)481*da58b97aSjoerg   void emitInstruction(const MCInst &Inst,
48206f32e7eSjoerg                        const MCSubtargetInfo &STI) override {
48306f32e7eSjoerg     if (IsThumb)
48406f32e7eSjoerg       EmitThumbMappingSymbol();
48506f32e7eSjoerg     else
48606f32e7eSjoerg       EmitARMMappingSymbol();
48706f32e7eSjoerg 
488*da58b97aSjoerg     MCELFStreamer::emitInstruction(Inst, STI);
48906f32e7eSjoerg   }
49006f32e7eSjoerg 
emitInst(uint32_t Inst,char Suffix)49106f32e7eSjoerg   void emitInst(uint32_t Inst, char Suffix) {
49206f32e7eSjoerg     unsigned Size;
49306f32e7eSjoerg     char Buffer[4];
49406f32e7eSjoerg     const bool LittleEndian = getContext().getAsmInfo()->isLittleEndian();
49506f32e7eSjoerg 
49606f32e7eSjoerg     switch (Suffix) {
49706f32e7eSjoerg     case '\0':
49806f32e7eSjoerg       Size = 4;
49906f32e7eSjoerg 
50006f32e7eSjoerg       assert(!IsThumb);
50106f32e7eSjoerg       EmitARMMappingSymbol();
50206f32e7eSjoerg       for (unsigned II = 0, IE = Size; II != IE; II++) {
50306f32e7eSjoerg         const unsigned I = LittleEndian ? (Size - II - 1) : II;
50406f32e7eSjoerg         Buffer[Size - II - 1] = uint8_t(Inst >> I * CHAR_BIT);
50506f32e7eSjoerg       }
50606f32e7eSjoerg 
50706f32e7eSjoerg       break;
50806f32e7eSjoerg     case 'n':
50906f32e7eSjoerg     case 'w':
51006f32e7eSjoerg       Size = (Suffix == 'n' ? 2 : 4);
51106f32e7eSjoerg 
51206f32e7eSjoerg       assert(IsThumb);
51306f32e7eSjoerg       EmitThumbMappingSymbol();
51406f32e7eSjoerg       // Thumb wide instructions are emitted as a pair of 16-bit words of the
51506f32e7eSjoerg       // appropriate endianness.
51606f32e7eSjoerg       for (unsigned II = 0, IE = Size; II != IE; II = II + 2) {
51706f32e7eSjoerg         const unsigned I0 = LittleEndian ? II + 0 : II + 1;
51806f32e7eSjoerg         const unsigned I1 = LittleEndian ? II + 1 : II + 0;
51906f32e7eSjoerg         Buffer[Size - II - 2] = uint8_t(Inst >> I0 * CHAR_BIT);
52006f32e7eSjoerg         Buffer[Size - II - 1] = uint8_t(Inst >> I1 * CHAR_BIT);
52106f32e7eSjoerg       }
52206f32e7eSjoerg 
52306f32e7eSjoerg       break;
52406f32e7eSjoerg     default:
52506f32e7eSjoerg       llvm_unreachable("Invalid Suffix");
52606f32e7eSjoerg     }
52706f32e7eSjoerg 
528*da58b97aSjoerg     MCELFStreamer::emitBytes(StringRef(Buffer, Size));
52906f32e7eSjoerg   }
53006f32e7eSjoerg 
53106f32e7eSjoerg   /// This is one of the functions used to emit data into an ELF section, so the
53206f32e7eSjoerg   /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if
53306f32e7eSjoerg   /// necessary.
emitBytes(StringRef Data)534*da58b97aSjoerg   void emitBytes(StringRef Data) override {
535*da58b97aSjoerg     emitDataMappingSymbol();
536*da58b97aSjoerg     MCELFStreamer::emitBytes(Data);
53706f32e7eSjoerg   }
53806f32e7eSjoerg 
FlushPendingMappingSymbol()53906f32e7eSjoerg   void FlushPendingMappingSymbol() {
54006f32e7eSjoerg     if (!LastEMSInfo->hasInfo())
54106f32e7eSjoerg       return;
54206f32e7eSjoerg     ElfMappingSymbolInfo *EMS = LastEMSInfo.get();
54306f32e7eSjoerg     EmitMappingSymbol("$d", EMS->Loc, EMS->F, EMS->Offset);
54406f32e7eSjoerg     EMS->resetInfo();
54506f32e7eSjoerg   }
54606f32e7eSjoerg 
54706f32e7eSjoerg   /// This is one of the functions used to emit data into an ELF section, so the
54806f32e7eSjoerg   /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if
54906f32e7eSjoerg   /// necessary.
emitValueImpl(const MCExpr * Value,unsigned Size,SMLoc Loc)550*da58b97aSjoerg   void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override {
55106f32e7eSjoerg     if (const MCSymbolRefExpr *SRE = dyn_cast_or_null<MCSymbolRefExpr>(Value)) {
55206f32e7eSjoerg       if (SRE->getKind() == MCSymbolRefExpr::VK_ARM_SBREL && !(Size == 4)) {
55306f32e7eSjoerg         getContext().reportError(Loc, "relocated expression must be 32-bit");
55406f32e7eSjoerg         return;
55506f32e7eSjoerg       }
55606f32e7eSjoerg       getOrCreateDataFragment();
55706f32e7eSjoerg     }
55806f32e7eSjoerg 
559*da58b97aSjoerg     emitDataMappingSymbol();
560*da58b97aSjoerg     MCELFStreamer::emitValueImpl(Value, Size, Loc);
56106f32e7eSjoerg   }
56206f32e7eSjoerg 
emitAssemblerFlag(MCAssemblerFlag Flag)563*da58b97aSjoerg   void emitAssemblerFlag(MCAssemblerFlag Flag) override {
564*da58b97aSjoerg     MCELFStreamer::emitAssemblerFlag(Flag);
56506f32e7eSjoerg 
56606f32e7eSjoerg     switch (Flag) {
56706f32e7eSjoerg     case MCAF_SyntaxUnified:
56806f32e7eSjoerg       return; // no-op here.
56906f32e7eSjoerg     case MCAF_Code16:
57006f32e7eSjoerg       IsThumb = true;
57106f32e7eSjoerg       return; // Change to Thumb mode
57206f32e7eSjoerg     case MCAF_Code32:
57306f32e7eSjoerg       IsThumb = false;
57406f32e7eSjoerg       return; // Change to ARM mode
57506f32e7eSjoerg     case MCAF_Code64:
57606f32e7eSjoerg       return;
57706f32e7eSjoerg     case MCAF_SubsectionsViaSymbols:
57806f32e7eSjoerg       return;
57906f32e7eSjoerg     }
58006f32e7eSjoerg   }
58106f32e7eSjoerg 
582*da58b97aSjoerg   /// If a label is defined before the .type directive sets the label's type
583*da58b97aSjoerg   /// then the label can't be recorded as thumb function when the label is
584*da58b97aSjoerg   /// defined. We override emitSymbolAttribute() which is called as part of the
585*da58b97aSjoerg   /// parsing of .type so that if the symbol has already been defined we can
586*da58b97aSjoerg   /// record the label as Thumb. FIXME: there is a corner case where the state
587*da58b97aSjoerg   /// is changed in between the label definition and the .type directive, this
588*da58b97aSjoerg   /// is not expected to occur in practice and handling it would require the
589*da58b97aSjoerg   /// backend to track IsThumb for every label.
emitSymbolAttribute(MCSymbol * Symbol,MCSymbolAttr Attribute)590*da58b97aSjoerg   bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override {
591*da58b97aSjoerg     bool Val = MCELFStreamer::emitSymbolAttribute(Symbol, Attribute);
592*da58b97aSjoerg 
593*da58b97aSjoerg     if (!IsThumb)
594*da58b97aSjoerg       return Val;
595*da58b97aSjoerg 
596*da58b97aSjoerg     unsigned Type = cast<MCSymbolELF>(Symbol)->getType();
597*da58b97aSjoerg     if ((Type == ELF::STT_FUNC || Type == ELF::STT_GNU_IFUNC) &&
598*da58b97aSjoerg         Symbol->isDefined())
599*da58b97aSjoerg       getAssembler().setIsThumbFunc(Symbol);
600*da58b97aSjoerg 
601*da58b97aSjoerg     return Val;
602*da58b97aSjoerg   };
603*da58b97aSjoerg 
60406f32e7eSjoerg private:
60506f32e7eSjoerg   enum ElfMappingSymbol {
60606f32e7eSjoerg     EMS_None,
60706f32e7eSjoerg     EMS_ARM,
60806f32e7eSjoerg     EMS_Thumb,
60906f32e7eSjoerg     EMS_Data
61006f32e7eSjoerg   };
61106f32e7eSjoerg 
61206f32e7eSjoerg   struct ElfMappingSymbolInfo {
ElfMappingSymbolInfo__anon5806bc350111::ARMELFStreamer::ElfMappingSymbolInfo61306f32e7eSjoerg     explicit ElfMappingSymbolInfo(SMLoc Loc, MCFragment *F, uint64_t O)
61406f32e7eSjoerg         : Loc(Loc), F(F), Offset(O), State(EMS_None) {}
resetInfo__anon5806bc350111::ARMELFStreamer::ElfMappingSymbolInfo61506f32e7eSjoerg     void resetInfo() {
61606f32e7eSjoerg       F = nullptr;
61706f32e7eSjoerg       Offset = 0;
61806f32e7eSjoerg     }
hasInfo__anon5806bc350111::ARMELFStreamer::ElfMappingSymbolInfo61906f32e7eSjoerg     bool hasInfo() { return F != nullptr; }
62006f32e7eSjoerg     SMLoc Loc;
62106f32e7eSjoerg     MCFragment *F;
62206f32e7eSjoerg     uint64_t Offset;
62306f32e7eSjoerg     ElfMappingSymbol State;
62406f32e7eSjoerg   };
62506f32e7eSjoerg 
emitDataMappingSymbol()626*da58b97aSjoerg   void emitDataMappingSymbol() {
62706f32e7eSjoerg     if (LastEMSInfo->State == EMS_Data)
62806f32e7eSjoerg       return;
62906f32e7eSjoerg     else if (LastEMSInfo->State == EMS_None) {
63006f32e7eSjoerg       // This is a tentative symbol, it won't really be emitted until it's
63106f32e7eSjoerg       // actually needed.
63206f32e7eSjoerg       ElfMappingSymbolInfo *EMS = LastEMSInfo.get();
63306f32e7eSjoerg       auto *DF = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
63406f32e7eSjoerg       if (!DF)
63506f32e7eSjoerg         return;
63606f32e7eSjoerg       EMS->Loc = SMLoc();
63706f32e7eSjoerg       EMS->F = getCurrentFragment();
63806f32e7eSjoerg       EMS->Offset = DF->getContents().size();
63906f32e7eSjoerg       LastEMSInfo->State = EMS_Data;
64006f32e7eSjoerg       return;
64106f32e7eSjoerg     }
64206f32e7eSjoerg     EmitMappingSymbol("$d");
64306f32e7eSjoerg     LastEMSInfo->State = EMS_Data;
64406f32e7eSjoerg   }
64506f32e7eSjoerg 
EmitThumbMappingSymbol()64606f32e7eSjoerg   void EmitThumbMappingSymbol() {
64706f32e7eSjoerg     if (LastEMSInfo->State == EMS_Thumb)
64806f32e7eSjoerg       return;
64906f32e7eSjoerg     FlushPendingMappingSymbol();
65006f32e7eSjoerg     EmitMappingSymbol("$t");
65106f32e7eSjoerg     LastEMSInfo->State = EMS_Thumb;
65206f32e7eSjoerg   }
65306f32e7eSjoerg 
EmitARMMappingSymbol()65406f32e7eSjoerg   void EmitARMMappingSymbol() {
65506f32e7eSjoerg     if (LastEMSInfo->State == EMS_ARM)
65606f32e7eSjoerg       return;
65706f32e7eSjoerg     FlushPendingMappingSymbol();
65806f32e7eSjoerg     EmitMappingSymbol("$a");
65906f32e7eSjoerg     LastEMSInfo->State = EMS_ARM;
66006f32e7eSjoerg   }
66106f32e7eSjoerg 
EmitMappingSymbol(StringRef Name)66206f32e7eSjoerg   void EmitMappingSymbol(StringRef Name) {
66306f32e7eSjoerg     auto *Symbol = cast<MCSymbolELF>(getContext().getOrCreateSymbol(
66406f32e7eSjoerg         Name + "." + Twine(MappingSymbolCounter++)));
665*da58b97aSjoerg     emitLabel(Symbol);
66606f32e7eSjoerg 
66706f32e7eSjoerg     Symbol->setType(ELF::STT_NOTYPE);
66806f32e7eSjoerg     Symbol->setBinding(ELF::STB_LOCAL);
66906f32e7eSjoerg   }
67006f32e7eSjoerg 
EmitMappingSymbol(StringRef Name,SMLoc Loc,MCFragment * F,uint64_t Offset)67106f32e7eSjoerg   void EmitMappingSymbol(StringRef Name, SMLoc Loc, MCFragment *F,
67206f32e7eSjoerg                          uint64_t Offset) {
67306f32e7eSjoerg     auto *Symbol = cast<MCSymbolELF>(getContext().getOrCreateSymbol(
67406f32e7eSjoerg         Name + "." + Twine(MappingSymbolCounter++)));
675*da58b97aSjoerg     emitLabelAtPos(Symbol, Loc, F, Offset);
67606f32e7eSjoerg     Symbol->setType(ELF::STT_NOTYPE);
67706f32e7eSjoerg     Symbol->setBinding(ELF::STB_LOCAL);
67806f32e7eSjoerg   }
67906f32e7eSjoerg 
emitThumbFunc(MCSymbol * Func)680*da58b97aSjoerg   void emitThumbFunc(MCSymbol *Func) override {
68106f32e7eSjoerg     getAssembler().setIsThumbFunc(Func);
682*da58b97aSjoerg     emitSymbolAttribute(Func, MCSA_ELF_TypeFunction);
68306f32e7eSjoerg   }
68406f32e7eSjoerg 
68506f32e7eSjoerg   // Helper functions for ARM exception handling directives
68606f32e7eSjoerg   void EHReset();
68706f32e7eSjoerg 
68806f32e7eSjoerg   // Reset state between object emissions
68906f32e7eSjoerg   void reset() override;
69006f32e7eSjoerg 
69106f32e7eSjoerg   void EmitPersonalityFixup(StringRef Name);
69206f32e7eSjoerg   void FlushPendingOffset();
69306f32e7eSjoerg   void FlushUnwindOpcodes(bool NoHandlerData);
69406f32e7eSjoerg 
69506f32e7eSjoerg   void SwitchToEHSection(StringRef Prefix, unsigned Type, unsigned Flags,
69606f32e7eSjoerg                          SectionKind Kind, const MCSymbol &Fn);
69706f32e7eSjoerg   void SwitchToExTabSection(const MCSymbol &FnStart);
69806f32e7eSjoerg   void SwitchToExIdxSection(const MCSymbol &FnStart);
69906f32e7eSjoerg 
70006f32e7eSjoerg   void EmitFixup(const MCExpr *Expr, MCFixupKind Kind);
70106f32e7eSjoerg 
70206f32e7eSjoerg   bool IsThumb;
703*da58b97aSjoerg   bool IsAndroid;
70406f32e7eSjoerg   int64_t MappingSymbolCounter = 0;
70506f32e7eSjoerg 
70606f32e7eSjoerg   DenseMap<const MCSection *, std::unique_ptr<ElfMappingSymbolInfo>>
70706f32e7eSjoerg       LastMappingSymbols;
70806f32e7eSjoerg 
70906f32e7eSjoerg   std::unique_ptr<ElfMappingSymbolInfo> LastEMSInfo;
71006f32e7eSjoerg 
71106f32e7eSjoerg   // ARM Exception Handling Frame Information
71206f32e7eSjoerg   MCSymbol *ExTab;
71306f32e7eSjoerg   MCSymbol *FnStart;
71406f32e7eSjoerg   const MCSymbol *Personality;
71506f32e7eSjoerg   unsigned PersonalityIndex;
71606f32e7eSjoerg   unsigned FPReg; // Frame pointer register
71706f32e7eSjoerg   int64_t FPOffset; // Offset: (final frame pointer) - (initial $sp)
71806f32e7eSjoerg   int64_t SPOffset; // Offset: (final $sp) - (initial $sp)
71906f32e7eSjoerg   int64_t PendingOffset; // Offset: (final $sp) - (emitted $sp)
72006f32e7eSjoerg   bool UsedFP;
72106f32e7eSjoerg   bool CantUnwind;
72206f32e7eSjoerg   SmallVector<uint8_t, 64> Opcodes;
72306f32e7eSjoerg   UnwindOpcodeAssembler UnwindOpAsm;
72406f32e7eSjoerg };
72506f32e7eSjoerg 
72606f32e7eSjoerg } // end anonymous namespace
72706f32e7eSjoerg 
getStreamer()72806f32e7eSjoerg ARMELFStreamer &ARMTargetELFStreamer::getStreamer() {
72906f32e7eSjoerg   return static_cast<ARMELFStreamer &>(Streamer);
73006f32e7eSjoerg }
73106f32e7eSjoerg 
emitFnStart()73206f32e7eSjoerg void ARMTargetELFStreamer::emitFnStart() { getStreamer().emitFnStart(); }
emitFnEnd()73306f32e7eSjoerg void ARMTargetELFStreamer::emitFnEnd() { getStreamer().emitFnEnd(); }
emitCantUnwind()73406f32e7eSjoerg void ARMTargetELFStreamer::emitCantUnwind() { getStreamer().emitCantUnwind(); }
73506f32e7eSjoerg 
emitPersonality(const MCSymbol * Personality)73606f32e7eSjoerg void ARMTargetELFStreamer::emitPersonality(const MCSymbol *Personality) {
73706f32e7eSjoerg   getStreamer().emitPersonality(Personality);
73806f32e7eSjoerg }
73906f32e7eSjoerg 
emitPersonalityIndex(unsigned Index)74006f32e7eSjoerg void ARMTargetELFStreamer::emitPersonalityIndex(unsigned Index) {
74106f32e7eSjoerg   getStreamer().emitPersonalityIndex(Index);
74206f32e7eSjoerg }
74306f32e7eSjoerg 
emitHandlerData()74406f32e7eSjoerg void ARMTargetELFStreamer::emitHandlerData() {
74506f32e7eSjoerg   getStreamer().emitHandlerData();
74606f32e7eSjoerg }
74706f32e7eSjoerg 
emitSetFP(unsigned FpReg,unsigned SpReg,int64_t Offset)74806f32e7eSjoerg void ARMTargetELFStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
74906f32e7eSjoerg                                      int64_t Offset) {
75006f32e7eSjoerg   getStreamer().emitSetFP(FpReg, SpReg, Offset);
75106f32e7eSjoerg }
75206f32e7eSjoerg 
emitMovSP(unsigned Reg,int64_t Offset)75306f32e7eSjoerg void ARMTargetELFStreamer::emitMovSP(unsigned Reg, int64_t Offset) {
75406f32e7eSjoerg   getStreamer().emitMovSP(Reg, Offset);
75506f32e7eSjoerg }
75606f32e7eSjoerg 
emitPad(int64_t Offset)75706f32e7eSjoerg void ARMTargetELFStreamer::emitPad(int64_t Offset) {
75806f32e7eSjoerg   getStreamer().emitPad(Offset);
75906f32e7eSjoerg }
76006f32e7eSjoerg 
emitRegSave(const SmallVectorImpl<unsigned> & RegList,bool isVector)76106f32e7eSjoerg void ARMTargetELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
76206f32e7eSjoerg                                        bool isVector) {
76306f32e7eSjoerg   getStreamer().emitRegSave(RegList, isVector);
76406f32e7eSjoerg }
76506f32e7eSjoerg 
emitUnwindRaw(int64_t Offset,const SmallVectorImpl<uint8_t> & Opcodes)76606f32e7eSjoerg void ARMTargetELFStreamer::emitUnwindRaw(int64_t Offset,
76706f32e7eSjoerg                                       const SmallVectorImpl<uint8_t> &Opcodes) {
76806f32e7eSjoerg   getStreamer().emitUnwindRaw(Offset, Opcodes);
76906f32e7eSjoerg }
77006f32e7eSjoerg 
switchVendor(StringRef Vendor)77106f32e7eSjoerg void ARMTargetELFStreamer::switchVendor(StringRef Vendor) {
77206f32e7eSjoerg   assert(!Vendor.empty() && "Vendor cannot be empty.");
77306f32e7eSjoerg 
77406f32e7eSjoerg   if (CurrentVendor == Vendor)
77506f32e7eSjoerg     return;
77606f32e7eSjoerg 
77706f32e7eSjoerg   if (!CurrentVendor.empty())
77806f32e7eSjoerg     finishAttributeSection();
77906f32e7eSjoerg 
78006f32e7eSjoerg   assert(Contents.empty() &&
78106f32e7eSjoerg          ".ARM.attributes should be flushed before changing vendor");
78206f32e7eSjoerg   CurrentVendor = Vendor;
78306f32e7eSjoerg 
78406f32e7eSjoerg }
78506f32e7eSjoerg 
emitAttribute(unsigned Attribute,unsigned Value)78606f32e7eSjoerg void ARMTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
78706f32e7eSjoerg   setAttributeItem(Attribute, Value, /* OverwriteExisting= */ true);
78806f32e7eSjoerg }
78906f32e7eSjoerg 
emitTextAttribute(unsigned Attribute,StringRef Value)79006f32e7eSjoerg void ARMTargetELFStreamer::emitTextAttribute(unsigned Attribute,
79106f32e7eSjoerg                                              StringRef Value) {
79206f32e7eSjoerg   setAttributeItem(Attribute, Value, /* OverwriteExisting= */ true);
79306f32e7eSjoerg }
79406f32e7eSjoerg 
emitIntTextAttribute(unsigned Attribute,unsigned IntValue,StringRef StringValue)79506f32e7eSjoerg void ARMTargetELFStreamer::emitIntTextAttribute(unsigned Attribute,
79606f32e7eSjoerg                                                 unsigned IntValue,
79706f32e7eSjoerg                                                 StringRef StringValue) {
79806f32e7eSjoerg   setAttributeItems(Attribute, IntValue, StringValue,
79906f32e7eSjoerg                     /* OverwriteExisting= */ true);
80006f32e7eSjoerg }
80106f32e7eSjoerg 
emitArch(ARM::ArchKind Value)80206f32e7eSjoerg void ARMTargetELFStreamer::emitArch(ARM::ArchKind Value) {
80306f32e7eSjoerg   Arch = Value;
80406f32e7eSjoerg }
80506f32e7eSjoerg 
emitObjectArch(ARM::ArchKind Value)80606f32e7eSjoerg void ARMTargetELFStreamer::emitObjectArch(ARM::ArchKind Value) {
80706f32e7eSjoerg   EmittedArch = Value;
80806f32e7eSjoerg }
80906f32e7eSjoerg 
emitArchDefaultAttributes()81006f32e7eSjoerg void ARMTargetELFStreamer::emitArchDefaultAttributes() {
81106f32e7eSjoerg   using namespace ARMBuildAttrs;
81206f32e7eSjoerg 
81306f32e7eSjoerg   setAttributeItem(CPU_name,
81406f32e7eSjoerg                    ARM::getCPUAttr(Arch),
81506f32e7eSjoerg                    false);
81606f32e7eSjoerg 
81706f32e7eSjoerg   if (EmittedArch == ARM::ArchKind::INVALID)
81806f32e7eSjoerg     setAttributeItem(CPU_arch,
81906f32e7eSjoerg                      ARM::getArchAttr(Arch),
82006f32e7eSjoerg                      false);
82106f32e7eSjoerg   else
82206f32e7eSjoerg     setAttributeItem(CPU_arch,
82306f32e7eSjoerg                      ARM::getArchAttr(EmittedArch),
82406f32e7eSjoerg                      false);
82506f32e7eSjoerg 
82606f32e7eSjoerg   switch (Arch) {
82706f32e7eSjoerg   case ARM::ArchKind::ARMV2:
82806f32e7eSjoerg   case ARM::ArchKind::ARMV2A:
82906f32e7eSjoerg   case ARM::ArchKind::ARMV3:
83006f32e7eSjoerg   case ARM::ArchKind::ARMV3M:
83106f32e7eSjoerg   case ARM::ArchKind::ARMV4:
83206f32e7eSjoerg     setAttributeItem(ARM_ISA_use, Allowed, false);
83306f32e7eSjoerg     break;
83406f32e7eSjoerg 
83506f32e7eSjoerg   case ARM::ArchKind::ARMV4T:
83606f32e7eSjoerg   case ARM::ArchKind::ARMV5T:
83706f32e7eSjoerg   case ARM::ArchKind::ARMV5TE:
83806f32e7eSjoerg   case ARM::ArchKind::ARMV6:
83906f32e7eSjoerg     setAttributeItem(ARM_ISA_use, Allowed, false);
84006f32e7eSjoerg     setAttributeItem(THUMB_ISA_use, Allowed, false);
84106f32e7eSjoerg     break;
84206f32e7eSjoerg 
84306f32e7eSjoerg   case ARM::ArchKind::ARMV6T2:
84406f32e7eSjoerg     setAttributeItem(ARM_ISA_use, Allowed, false);
84506f32e7eSjoerg     setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
84606f32e7eSjoerg     break;
84706f32e7eSjoerg 
84806f32e7eSjoerg   case ARM::ArchKind::ARMV6K:
84906f32e7eSjoerg   case ARM::ArchKind::ARMV6KZ:
85006f32e7eSjoerg     setAttributeItem(ARM_ISA_use, Allowed, false);
85106f32e7eSjoerg     setAttributeItem(THUMB_ISA_use, Allowed, false);
85206f32e7eSjoerg     setAttributeItem(Virtualization_use, AllowTZ, false);
85306f32e7eSjoerg     break;
85406f32e7eSjoerg 
85506f32e7eSjoerg   case ARM::ArchKind::ARMV6M:
85606f32e7eSjoerg     setAttributeItem(THUMB_ISA_use, Allowed, false);
85706f32e7eSjoerg     break;
85806f32e7eSjoerg 
85906f32e7eSjoerg   case ARM::ArchKind::ARMV7A:
86006f32e7eSjoerg     setAttributeItem(CPU_arch_profile, ApplicationProfile, false);
86106f32e7eSjoerg     setAttributeItem(ARM_ISA_use, Allowed, false);
86206f32e7eSjoerg     setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
86306f32e7eSjoerg     break;
86406f32e7eSjoerg 
86506f32e7eSjoerg   case ARM::ArchKind::ARMV7R:
86606f32e7eSjoerg     setAttributeItem(CPU_arch_profile, RealTimeProfile, false);
86706f32e7eSjoerg     setAttributeItem(ARM_ISA_use, Allowed, false);
86806f32e7eSjoerg     setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
86906f32e7eSjoerg     break;
87006f32e7eSjoerg 
87106f32e7eSjoerg   case ARM::ArchKind::ARMV7EM:
87206f32e7eSjoerg   case ARM::ArchKind::ARMV7M:
87306f32e7eSjoerg     setAttributeItem(CPU_arch_profile, MicroControllerProfile, false);
87406f32e7eSjoerg     setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
87506f32e7eSjoerg     break;
87606f32e7eSjoerg 
87706f32e7eSjoerg   case ARM::ArchKind::ARMV8A:
87806f32e7eSjoerg   case ARM::ArchKind::ARMV8_1A:
87906f32e7eSjoerg   case ARM::ArchKind::ARMV8_2A:
88006f32e7eSjoerg   case ARM::ArchKind::ARMV8_3A:
88106f32e7eSjoerg   case ARM::ArchKind::ARMV8_4A:
88206f32e7eSjoerg   case ARM::ArchKind::ARMV8_5A:
883*da58b97aSjoerg   case ARM::ArchKind::ARMV8_6A:
88406f32e7eSjoerg     setAttributeItem(CPU_arch_profile, ApplicationProfile, false);
88506f32e7eSjoerg     setAttributeItem(ARM_ISA_use, Allowed, false);
88606f32e7eSjoerg     setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
88706f32e7eSjoerg     setAttributeItem(MPextension_use, Allowed, false);
88806f32e7eSjoerg     setAttributeItem(Virtualization_use, AllowTZVirtualization, false);
88906f32e7eSjoerg     break;
89006f32e7eSjoerg 
89106f32e7eSjoerg   case ARM::ArchKind::ARMV8MBaseline:
89206f32e7eSjoerg   case ARM::ArchKind::ARMV8MMainline:
89306f32e7eSjoerg     setAttributeItem(THUMB_ISA_use, AllowThumbDerived, false);
89406f32e7eSjoerg     setAttributeItem(CPU_arch_profile, MicroControllerProfile, false);
89506f32e7eSjoerg     break;
89606f32e7eSjoerg 
89706f32e7eSjoerg   case ARM::ArchKind::IWMMXT:
89806f32e7eSjoerg     setAttributeItem(ARM_ISA_use, Allowed, false);
89906f32e7eSjoerg     setAttributeItem(THUMB_ISA_use, Allowed, false);
90006f32e7eSjoerg     setAttributeItem(WMMX_arch, AllowWMMXv1, false);
90106f32e7eSjoerg     break;
90206f32e7eSjoerg 
90306f32e7eSjoerg   case ARM::ArchKind::IWMMXT2:
90406f32e7eSjoerg     setAttributeItem(ARM_ISA_use, Allowed, false);
90506f32e7eSjoerg     setAttributeItem(THUMB_ISA_use, Allowed, false);
90606f32e7eSjoerg     setAttributeItem(WMMX_arch, AllowWMMXv2, false);
90706f32e7eSjoerg     break;
90806f32e7eSjoerg 
90906f32e7eSjoerg   default:
91006f32e7eSjoerg     report_fatal_error("Unknown Arch: " + Twine(ARM::getArchName(Arch)));
91106f32e7eSjoerg     break;
91206f32e7eSjoerg   }
91306f32e7eSjoerg }
91406f32e7eSjoerg 
emitFPU(unsigned Value)91506f32e7eSjoerg void ARMTargetELFStreamer::emitFPU(unsigned Value) {
91606f32e7eSjoerg   FPU = Value;
91706f32e7eSjoerg }
91806f32e7eSjoerg 
emitFPUDefaultAttributes()91906f32e7eSjoerg void ARMTargetELFStreamer::emitFPUDefaultAttributes() {
92006f32e7eSjoerg   switch (FPU) {
92106f32e7eSjoerg   case ARM::FK_VFP:
92206f32e7eSjoerg   case ARM::FK_VFPV2:
92306f32e7eSjoerg     setAttributeItem(ARMBuildAttrs::FP_arch,
92406f32e7eSjoerg                      ARMBuildAttrs::AllowFPv2,
92506f32e7eSjoerg                      /* OverwriteExisting= */ false);
92606f32e7eSjoerg     break;
92706f32e7eSjoerg 
92806f32e7eSjoerg   case ARM::FK_VFPV3:
92906f32e7eSjoerg     setAttributeItem(ARMBuildAttrs::FP_arch,
93006f32e7eSjoerg                      ARMBuildAttrs::AllowFPv3A,
93106f32e7eSjoerg                      /* OverwriteExisting= */ false);
93206f32e7eSjoerg     break;
93306f32e7eSjoerg 
93406f32e7eSjoerg   case ARM::FK_VFPV3_FP16:
93506f32e7eSjoerg     setAttributeItem(ARMBuildAttrs::FP_arch,
93606f32e7eSjoerg                      ARMBuildAttrs::AllowFPv3A,
93706f32e7eSjoerg                      /* OverwriteExisting= */ false);
93806f32e7eSjoerg     setAttributeItem(ARMBuildAttrs::FP_HP_extension,
93906f32e7eSjoerg                      ARMBuildAttrs::AllowHPFP,
94006f32e7eSjoerg                      /* OverwriteExisting= */ false);
94106f32e7eSjoerg     break;
94206f32e7eSjoerg 
94306f32e7eSjoerg   case ARM::FK_VFPV3_D16:
94406f32e7eSjoerg     setAttributeItem(ARMBuildAttrs::FP_arch,
94506f32e7eSjoerg                      ARMBuildAttrs::AllowFPv3B,
94606f32e7eSjoerg                      /* OverwriteExisting= */ false);
94706f32e7eSjoerg     break;
94806f32e7eSjoerg 
94906f32e7eSjoerg   case ARM::FK_VFPV3_D16_FP16:
95006f32e7eSjoerg     setAttributeItem(ARMBuildAttrs::FP_arch,
95106f32e7eSjoerg                      ARMBuildAttrs::AllowFPv3B,
95206f32e7eSjoerg                      /* OverwriteExisting= */ false);
95306f32e7eSjoerg     setAttributeItem(ARMBuildAttrs::FP_HP_extension,
95406f32e7eSjoerg                      ARMBuildAttrs::AllowHPFP,
95506f32e7eSjoerg                      /* OverwriteExisting= */ false);
95606f32e7eSjoerg     break;
95706f32e7eSjoerg 
95806f32e7eSjoerg   case ARM::FK_VFPV3XD:
95906f32e7eSjoerg     setAttributeItem(ARMBuildAttrs::FP_arch,
96006f32e7eSjoerg                      ARMBuildAttrs::AllowFPv3B,
96106f32e7eSjoerg                      /* OverwriteExisting= */ false);
96206f32e7eSjoerg     break;
96306f32e7eSjoerg   case ARM::FK_VFPV3XD_FP16:
96406f32e7eSjoerg     setAttributeItem(ARMBuildAttrs::FP_arch,
96506f32e7eSjoerg                      ARMBuildAttrs::AllowFPv3B,
96606f32e7eSjoerg                      /* OverwriteExisting= */ false);
96706f32e7eSjoerg     setAttributeItem(ARMBuildAttrs::FP_HP_extension,
96806f32e7eSjoerg                      ARMBuildAttrs::AllowHPFP,
96906f32e7eSjoerg                      /* OverwriteExisting= */ false);
97006f32e7eSjoerg     break;
97106f32e7eSjoerg 
97206f32e7eSjoerg   case ARM::FK_VFPV4:
97306f32e7eSjoerg     setAttributeItem(ARMBuildAttrs::FP_arch,
97406f32e7eSjoerg                      ARMBuildAttrs::AllowFPv4A,
97506f32e7eSjoerg                      /* OverwriteExisting= */ false);
97606f32e7eSjoerg     break;
97706f32e7eSjoerg 
97806f32e7eSjoerg   // ABI_HardFP_use is handled in ARMAsmPrinter, so _SP_D16 is treated the same
97906f32e7eSjoerg   // as _D16 here.
98006f32e7eSjoerg   case ARM::FK_FPV4_SP_D16:
98106f32e7eSjoerg   case ARM::FK_VFPV4_D16:
98206f32e7eSjoerg     setAttributeItem(ARMBuildAttrs::FP_arch,
98306f32e7eSjoerg                      ARMBuildAttrs::AllowFPv4B,
98406f32e7eSjoerg                      /* OverwriteExisting= */ false);
98506f32e7eSjoerg     break;
98606f32e7eSjoerg 
98706f32e7eSjoerg   case ARM::FK_FP_ARMV8:
98806f32e7eSjoerg     setAttributeItem(ARMBuildAttrs::FP_arch,
98906f32e7eSjoerg                      ARMBuildAttrs::AllowFPARMv8A,
99006f32e7eSjoerg                      /* OverwriteExisting= */ false);
99106f32e7eSjoerg     break;
99206f32e7eSjoerg 
99306f32e7eSjoerg   // FPV5_D16 is identical to FP_ARMV8 except for the number of D registers, so
99406f32e7eSjoerg   // uses the FP_ARMV8_D16 build attribute.
99506f32e7eSjoerg   case ARM::FK_FPV5_SP_D16:
99606f32e7eSjoerg   case ARM::FK_FPV5_D16:
99706f32e7eSjoerg     setAttributeItem(ARMBuildAttrs::FP_arch,
99806f32e7eSjoerg                      ARMBuildAttrs::AllowFPARMv8B,
99906f32e7eSjoerg                      /* OverwriteExisting= */ false);
100006f32e7eSjoerg     break;
100106f32e7eSjoerg 
100206f32e7eSjoerg   case ARM::FK_NEON:
100306f32e7eSjoerg     setAttributeItem(ARMBuildAttrs::FP_arch,
100406f32e7eSjoerg                      ARMBuildAttrs::AllowFPv3A,
100506f32e7eSjoerg                      /* OverwriteExisting= */ false);
100606f32e7eSjoerg     setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
100706f32e7eSjoerg                      ARMBuildAttrs::AllowNeon,
100806f32e7eSjoerg                      /* OverwriteExisting= */ false);
100906f32e7eSjoerg     break;
101006f32e7eSjoerg 
101106f32e7eSjoerg   case ARM::FK_NEON_FP16:
101206f32e7eSjoerg     setAttributeItem(ARMBuildAttrs::FP_arch,
101306f32e7eSjoerg                      ARMBuildAttrs::AllowFPv3A,
101406f32e7eSjoerg                      /* OverwriteExisting= */ false);
101506f32e7eSjoerg     setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
101606f32e7eSjoerg                      ARMBuildAttrs::AllowNeon,
101706f32e7eSjoerg                      /* OverwriteExisting= */ false);
101806f32e7eSjoerg     setAttributeItem(ARMBuildAttrs::FP_HP_extension,
101906f32e7eSjoerg                      ARMBuildAttrs::AllowHPFP,
102006f32e7eSjoerg                      /* OverwriteExisting= */ false);
102106f32e7eSjoerg     break;
102206f32e7eSjoerg 
102306f32e7eSjoerg   case ARM::FK_NEON_VFPV4:
102406f32e7eSjoerg     setAttributeItem(ARMBuildAttrs::FP_arch,
102506f32e7eSjoerg                      ARMBuildAttrs::AllowFPv4A,
102606f32e7eSjoerg                      /* OverwriteExisting= */ false);
102706f32e7eSjoerg     setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
102806f32e7eSjoerg                      ARMBuildAttrs::AllowNeon2,
102906f32e7eSjoerg                      /* OverwriteExisting= */ false);
103006f32e7eSjoerg     break;
103106f32e7eSjoerg 
103206f32e7eSjoerg   case ARM::FK_NEON_FP_ARMV8:
103306f32e7eSjoerg   case ARM::FK_CRYPTO_NEON_FP_ARMV8:
103406f32e7eSjoerg     setAttributeItem(ARMBuildAttrs::FP_arch,
103506f32e7eSjoerg                      ARMBuildAttrs::AllowFPARMv8A,
103606f32e7eSjoerg                      /* OverwriteExisting= */ false);
103706f32e7eSjoerg     // 'Advanced_SIMD_arch' must be emitted not here, but within
103806f32e7eSjoerg     // ARMAsmPrinter::emitAttributes(), depending on hasV8Ops() and hasV8_1a()
103906f32e7eSjoerg     break;
104006f32e7eSjoerg 
104106f32e7eSjoerg   case ARM::FK_SOFTVFP:
104206f32e7eSjoerg   case ARM::FK_NONE:
104306f32e7eSjoerg     break;
104406f32e7eSjoerg 
104506f32e7eSjoerg   default:
104606f32e7eSjoerg     report_fatal_error("Unknown FPU: " + Twine(FPU));
104706f32e7eSjoerg     break;
104806f32e7eSjoerg   }
104906f32e7eSjoerg }
105006f32e7eSjoerg 
calculateContentSize() const105106f32e7eSjoerg size_t ARMTargetELFStreamer::calculateContentSize() const {
105206f32e7eSjoerg   size_t Result = 0;
105306f32e7eSjoerg   for (size_t i = 0; i < Contents.size(); ++i) {
105406f32e7eSjoerg     AttributeItem item = Contents[i];
105506f32e7eSjoerg     switch (item.Type) {
105606f32e7eSjoerg     case AttributeItem::HiddenAttribute:
105706f32e7eSjoerg       break;
105806f32e7eSjoerg     case AttributeItem::NumericAttribute:
105906f32e7eSjoerg       Result += getULEB128Size(item.Tag);
106006f32e7eSjoerg       Result += getULEB128Size(item.IntValue);
106106f32e7eSjoerg       break;
106206f32e7eSjoerg     case AttributeItem::TextAttribute:
106306f32e7eSjoerg       Result += getULEB128Size(item.Tag);
106406f32e7eSjoerg       Result += item.StringValue.size() + 1; // string + '\0'
106506f32e7eSjoerg       break;
106606f32e7eSjoerg     case AttributeItem::NumericAndTextAttributes:
106706f32e7eSjoerg       Result += getULEB128Size(item.Tag);
106806f32e7eSjoerg       Result += getULEB128Size(item.IntValue);
106906f32e7eSjoerg       Result += item.StringValue.size() + 1; // string + '\0';
107006f32e7eSjoerg       break;
107106f32e7eSjoerg     }
107206f32e7eSjoerg   }
107306f32e7eSjoerg   return Result;
107406f32e7eSjoerg }
107506f32e7eSjoerg 
finishAttributeSection()107606f32e7eSjoerg void ARMTargetELFStreamer::finishAttributeSection() {
107706f32e7eSjoerg   // <format-version>
107806f32e7eSjoerg   // [ <section-length> "vendor-name"
107906f32e7eSjoerg   // [ <file-tag> <size> <attribute>*
108006f32e7eSjoerg   //   | <section-tag> <size> <section-number>* 0 <attribute>*
108106f32e7eSjoerg   //   | <symbol-tag> <size> <symbol-number>* 0 <attribute>*
108206f32e7eSjoerg   //   ]+
108306f32e7eSjoerg   // ]*
108406f32e7eSjoerg 
108506f32e7eSjoerg   if (FPU != ARM::FK_INVALID)
108606f32e7eSjoerg     emitFPUDefaultAttributes();
108706f32e7eSjoerg 
108806f32e7eSjoerg   if (Arch != ARM::ArchKind::INVALID)
108906f32e7eSjoerg     emitArchDefaultAttributes();
109006f32e7eSjoerg 
109106f32e7eSjoerg   if (Contents.empty())
109206f32e7eSjoerg     return;
109306f32e7eSjoerg 
109406f32e7eSjoerg   llvm::sort(Contents, AttributeItem::LessTag);
109506f32e7eSjoerg 
109606f32e7eSjoerg   ARMELFStreamer &Streamer = getStreamer();
109706f32e7eSjoerg 
109806f32e7eSjoerg   // Switch to .ARM.attributes section
109906f32e7eSjoerg   if (AttributeSection) {
110006f32e7eSjoerg     Streamer.SwitchSection(AttributeSection);
110106f32e7eSjoerg   } else {
110206f32e7eSjoerg     AttributeSection = Streamer.getContext().getELFSection(
110306f32e7eSjoerg         ".ARM.attributes", ELF::SHT_ARM_ATTRIBUTES, 0);
110406f32e7eSjoerg     Streamer.SwitchSection(AttributeSection);
110506f32e7eSjoerg 
110606f32e7eSjoerg     // Format version
1107*da58b97aSjoerg     Streamer.emitInt8(0x41);
110806f32e7eSjoerg   }
110906f32e7eSjoerg 
111006f32e7eSjoerg   // Vendor size + Vendor name + '\0'
111106f32e7eSjoerg   const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1;
111206f32e7eSjoerg 
111306f32e7eSjoerg   // Tag + Tag Size
111406f32e7eSjoerg   const size_t TagHeaderSize = 1 + 4;
111506f32e7eSjoerg 
111606f32e7eSjoerg   const size_t ContentsSize = calculateContentSize();
111706f32e7eSjoerg 
1118*da58b97aSjoerg   Streamer.emitInt32(VendorHeaderSize + TagHeaderSize + ContentsSize);
1119*da58b97aSjoerg   Streamer.emitBytes(CurrentVendor);
1120*da58b97aSjoerg   Streamer.emitInt8(0); // '\0'
112106f32e7eSjoerg 
1122*da58b97aSjoerg   Streamer.emitInt8(ARMBuildAttrs::File);
1123*da58b97aSjoerg   Streamer.emitInt32(TagHeaderSize + ContentsSize);
112406f32e7eSjoerg 
112506f32e7eSjoerg   // Size should have been accounted for already, now
112606f32e7eSjoerg   // emit each field as its type (ULEB or String)
112706f32e7eSjoerg   for (size_t i = 0; i < Contents.size(); ++i) {
112806f32e7eSjoerg     AttributeItem item = Contents[i];
1129*da58b97aSjoerg     Streamer.emitULEB128IntValue(item.Tag);
113006f32e7eSjoerg     switch (item.Type) {
113106f32e7eSjoerg     default: llvm_unreachable("Invalid attribute type");
113206f32e7eSjoerg     case AttributeItem::NumericAttribute:
1133*da58b97aSjoerg       Streamer.emitULEB128IntValue(item.IntValue);
113406f32e7eSjoerg       break;
113506f32e7eSjoerg     case AttributeItem::TextAttribute:
1136*da58b97aSjoerg       Streamer.emitBytes(item.StringValue);
1137*da58b97aSjoerg       Streamer.emitInt8(0); // '\0'
113806f32e7eSjoerg       break;
113906f32e7eSjoerg     case AttributeItem::NumericAndTextAttributes:
1140*da58b97aSjoerg       Streamer.emitULEB128IntValue(item.IntValue);
1141*da58b97aSjoerg       Streamer.emitBytes(item.StringValue);
1142*da58b97aSjoerg       Streamer.emitInt8(0); // '\0'
114306f32e7eSjoerg       break;
114406f32e7eSjoerg     }
114506f32e7eSjoerg   }
114606f32e7eSjoerg 
114706f32e7eSjoerg   Contents.clear();
114806f32e7eSjoerg   FPU = ARM::FK_INVALID;
114906f32e7eSjoerg }
115006f32e7eSjoerg 
emitLabel(MCSymbol * Symbol)115106f32e7eSjoerg void ARMTargetELFStreamer::emitLabel(MCSymbol *Symbol) {
115206f32e7eSjoerg   ARMELFStreamer &Streamer = getStreamer();
115306f32e7eSjoerg   if (!Streamer.IsThumb)
115406f32e7eSjoerg     return;
115506f32e7eSjoerg 
115606f32e7eSjoerg   Streamer.getAssembler().registerSymbol(*Symbol);
115706f32e7eSjoerg   unsigned Type = cast<MCSymbolELF>(Symbol)->getType();
115806f32e7eSjoerg   if (Type == ELF::STT_FUNC || Type == ELF::STT_GNU_IFUNC)
1159*da58b97aSjoerg     Streamer.emitThumbFunc(Symbol);
116006f32e7eSjoerg }
116106f32e7eSjoerg 
116206f32e7eSjoerg void
AnnotateTLSDescriptorSequence(const MCSymbolRefExpr * S)116306f32e7eSjoerg ARMTargetELFStreamer::AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *S) {
116406f32e7eSjoerg   getStreamer().EmitFixup(S, FK_Data_4);
116506f32e7eSjoerg }
116606f32e7eSjoerg 
emitThumbSet(MCSymbol * Symbol,const MCExpr * Value)116706f32e7eSjoerg void ARMTargetELFStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) {
116806f32e7eSjoerg   if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Value)) {
116906f32e7eSjoerg     const MCSymbol &Sym = SRE->getSymbol();
117006f32e7eSjoerg     if (!Sym.isDefined()) {
1171*da58b97aSjoerg       getStreamer().emitAssignment(Symbol, Value);
117206f32e7eSjoerg       return;
117306f32e7eSjoerg     }
117406f32e7eSjoerg   }
117506f32e7eSjoerg 
1176*da58b97aSjoerg   getStreamer().emitThumbFunc(Symbol);
1177*da58b97aSjoerg   getStreamer().emitAssignment(Symbol, Value);
117806f32e7eSjoerg }
117906f32e7eSjoerg 
emitInst(uint32_t Inst,char Suffix)118006f32e7eSjoerg void ARMTargetELFStreamer::emitInst(uint32_t Inst, char Suffix) {
118106f32e7eSjoerg   getStreamer().emitInst(Inst, Suffix);
118206f32e7eSjoerg }
118306f32e7eSjoerg 
reset()118406f32e7eSjoerg void ARMTargetELFStreamer::reset() { AttributeSection = nullptr; }
118506f32e7eSjoerg 
finishImpl()1186*da58b97aSjoerg void ARMELFStreamer::finishImpl() {
118706f32e7eSjoerg   MCTargetStreamer &TS = *getTargetStreamer();
118806f32e7eSjoerg   ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
118906f32e7eSjoerg   ATS.finishAttributeSection();
119006f32e7eSjoerg 
1191*da58b97aSjoerg   MCELFStreamer::finishImpl();
119206f32e7eSjoerg }
119306f32e7eSjoerg 
reset()119406f32e7eSjoerg void ARMELFStreamer::reset() {
119506f32e7eSjoerg   MCTargetStreamer &TS = *getTargetStreamer();
119606f32e7eSjoerg   ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
119706f32e7eSjoerg   ATS.reset();
119806f32e7eSjoerg   MappingSymbolCounter = 0;
119906f32e7eSjoerg   MCELFStreamer::reset();
120006f32e7eSjoerg   LastMappingSymbols.clear();
120106f32e7eSjoerg   LastEMSInfo.reset();
120206f32e7eSjoerg   // MCELFStreamer clear's the assembler's e_flags. However, for
120306f32e7eSjoerg   // arm we manually set the ABI version on streamer creation, so
120406f32e7eSjoerg   // do the same here
120506f32e7eSjoerg   getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5);
120606f32e7eSjoerg }
120706f32e7eSjoerg 
SwitchToEHSection(StringRef Prefix,unsigned Type,unsigned Flags,SectionKind Kind,const MCSymbol & Fn)120806f32e7eSjoerg inline void ARMELFStreamer::SwitchToEHSection(StringRef Prefix,
120906f32e7eSjoerg                                               unsigned Type,
121006f32e7eSjoerg                                               unsigned Flags,
121106f32e7eSjoerg                                               SectionKind Kind,
121206f32e7eSjoerg                                               const MCSymbol &Fn) {
121306f32e7eSjoerg   const MCSectionELF &FnSection =
121406f32e7eSjoerg     static_cast<const MCSectionELF &>(Fn.getSection());
121506f32e7eSjoerg 
121606f32e7eSjoerg   // Create the name for new section
1217*da58b97aSjoerg   StringRef FnSecName(FnSection.getName());
121806f32e7eSjoerg   SmallString<128> EHSecName(Prefix);
121906f32e7eSjoerg   if (FnSecName != ".text") {
122006f32e7eSjoerg     EHSecName += FnSecName;
122106f32e7eSjoerg   }
122206f32e7eSjoerg 
122306f32e7eSjoerg   // Get .ARM.extab or .ARM.exidx section
122406f32e7eSjoerg   const MCSymbolELF *Group = FnSection.getGroup();
122506f32e7eSjoerg   if (Group)
122606f32e7eSjoerg     Flags |= ELF::SHF_GROUP;
122706f32e7eSjoerg   MCSectionELF *EHSection = getContext().getELFSection(
1228*da58b97aSjoerg       EHSecName, Type, Flags, 0, Group, /*IsComdat=*/true,
1229*da58b97aSjoerg       FnSection.getUniqueID(),
1230*da58b97aSjoerg       static_cast<const MCSymbolELF *>(FnSection.getBeginSymbol()));
123106f32e7eSjoerg 
123206f32e7eSjoerg   assert(EHSection && "Failed to get the required EH section");
123306f32e7eSjoerg 
123406f32e7eSjoerg   // Switch to .ARM.extab or .ARM.exidx section
123506f32e7eSjoerg   SwitchSection(EHSection);
1236*da58b97aSjoerg   emitCodeAlignment(4);
123706f32e7eSjoerg }
123806f32e7eSjoerg 
SwitchToExTabSection(const MCSymbol & FnStart)123906f32e7eSjoerg inline void ARMELFStreamer::SwitchToExTabSection(const MCSymbol &FnStart) {
124006f32e7eSjoerg   SwitchToEHSection(".ARM.extab", ELF::SHT_PROGBITS, ELF::SHF_ALLOC,
124106f32e7eSjoerg                     SectionKind::getData(), FnStart);
124206f32e7eSjoerg }
124306f32e7eSjoerg 
SwitchToExIdxSection(const MCSymbol & FnStart)124406f32e7eSjoerg inline void ARMELFStreamer::SwitchToExIdxSection(const MCSymbol &FnStart) {
124506f32e7eSjoerg   SwitchToEHSection(".ARM.exidx", ELF::SHT_ARM_EXIDX,
124606f32e7eSjoerg                     ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER,
124706f32e7eSjoerg                     SectionKind::getData(), FnStart);
124806f32e7eSjoerg }
124906f32e7eSjoerg 
EmitFixup(const MCExpr * Expr,MCFixupKind Kind)125006f32e7eSjoerg void ARMELFStreamer::EmitFixup(const MCExpr *Expr, MCFixupKind Kind) {
125106f32e7eSjoerg   MCDataFragment *Frag = getOrCreateDataFragment();
125206f32e7eSjoerg   Frag->getFixups().push_back(MCFixup::create(Frag->getContents().size(), Expr,
125306f32e7eSjoerg                                               Kind));
125406f32e7eSjoerg }
125506f32e7eSjoerg 
EHReset()125606f32e7eSjoerg void ARMELFStreamer::EHReset() {
125706f32e7eSjoerg   ExTab = nullptr;
125806f32e7eSjoerg   FnStart = nullptr;
125906f32e7eSjoerg   Personality = nullptr;
126006f32e7eSjoerg   PersonalityIndex = ARM::EHABI::NUM_PERSONALITY_INDEX;
126106f32e7eSjoerg   FPReg = ARM::SP;
126206f32e7eSjoerg   FPOffset = 0;
126306f32e7eSjoerg   SPOffset = 0;
126406f32e7eSjoerg   PendingOffset = 0;
126506f32e7eSjoerg   UsedFP = false;
126606f32e7eSjoerg   CantUnwind = false;
126706f32e7eSjoerg 
126806f32e7eSjoerg   Opcodes.clear();
126906f32e7eSjoerg   UnwindOpAsm.Reset();
127006f32e7eSjoerg }
127106f32e7eSjoerg 
emitFnStart()127206f32e7eSjoerg void ARMELFStreamer::emitFnStart() {
127306f32e7eSjoerg   assert(FnStart == nullptr);
127406f32e7eSjoerg   FnStart = getContext().createTempSymbol();
1275*da58b97aSjoerg   emitLabel(FnStart);
127606f32e7eSjoerg }
127706f32e7eSjoerg 
emitFnEnd()127806f32e7eSjoerg void ARMELFStreamer::emitFnEnd() {
127906f32e7eSjoerg   assert(FnStart && ".fnstart must precedes .fnend");
128006f32e7eSjoerg 
128106f32e7eSjoerg   // Emit unwind opcodes if there is no .handlerdata directive
128206f32e7eSjoerg   if (!ExTab && !CantUnwind)
128306f32e7eSjoerg     FlushUnwindOpcodes(true);
128406f32e7eSjoerg 
128506f32e7eSjoerg   // Emit the exception index table entry
128606f32e7eSjoerg   SwitchToExIdxSection(*FnStart);
128706f32e7eSjoerg 
1288*da58b97aSjoerg   // The EHABI requires a dependency preserving R_ARM_NONE relocation to the
1289*da58b97aSjoerg   // personality routine to protect it from an arbitrary platform's static
1290*da58b97aSjoerg   // linker garbage collection. We disable this for Android where the unwinder
1291*da58b97aSjoerg   // is either dynamically linked or directly references the personality
1292*da58b97aSjoerg   // routine.
1293*da58b97aSjoerg   if (PersonalityIndex < ARM::EHABI::NUM_PERSONALITY_INDEX && !IsAndroid)
129406f32e7eSjoerg     EmitPersonalityFixup(GetAEABIUnwindPersonalityName(PersonalityIndex));
129506f32e7eSjoerg 
129606f32e7eSjoerg   const MCSymbolRefExpr *FnStartRef =
129706f32e7eSjoerg     MCSymbolRefExpr::create(FnStart,
129806f32e7eSjoerg                             MCSymbolRefExpr::VK_ARM_PREL31,
129906f32e7eSjoerg                             getContext());
130006f32e7eSjoerg 
1301*da58b97aSjoerg   emitValue(FnStartRef, 4);
130206f32e7eSjoerg 
130306f32e7eSjoerg   if (CantUnwind) {
1304*da58b97aSjoerg     emitInt32(ARM::EHABI::EXIDX_CANTUNWIND);
130506f32e7eSjoerg   } else if (ExTab) {
130606f32e7eSjoerg     // Emit a reference to the unwind opcodes in the ".ARM.extab" section.
130706f32e7eSjoerg     const MCSymbolRefExpr *ExTabEntryRef =
130806f32e7eSjoerg       MCSymbolRefExpr::create(ExTab,
130906f32e7eSjoerg                               MCSymbolRefExpr::VK_ARM_PREL31,
131006f32e7eSjoerg                               getContext());
1311*da58b97aSjoerg     emitValue(ExTabEntryRef, 4);
131206f32e7eSjoerg   } else {
131306f32e7eSjoerg     // For the __aeabi_unwind_cpp_pr0, we have to emit the unwind opcodes in
131406f32e7eSjoerg     // the second word of exception index table entry.  The size of the unwind
131506f32e7eSjoerg     // opcodes should always be 4 bytes.
131606f32e7eSjoerg     assert(PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0 &&
131706f32e7eSjoerg            "Compact model must use __aeabi_unwind_cpp_pr0 as personality");
131806f32e7eSjoerg     assert(Opcodes.size() == 4u &&
131906f32e7eSjoerg            "Unwind opcode size for __aeabi_unwind_cpp_pr0 must be equal to 4");
132006f32e7eSjoerg     uint64_t Intval = Opcodes[0] |
132106f32e7eSjoerg                       Opcodes[1] << 8 |
132206f32e7eSjoerg                       Opcodes[2] << 16 |
132306f32e7eSjoerg                       Opcodes[3] << 24;
1324*da58b97aSjoerg     emitIntValue(Intval, Opcodes.size());
132506f32e7eSjoerg   }
132606f32e7eSjoerg 
132706f32e7eSjoerg   // Switch to the section containing FnStart
132806f32e7eSjoerg   SwitchSection(&FnStart->getSection());
132906f32e7eSjoerg 
133006f32e7eSjoerg   // Clean exception handling frame information
133106f32e7eSjoerg   EHReset();
133206f32e7eSjoerg }
133306f32e7eSjoerg 
emitCantUnwind()133406f32e7eSjoerg void ARMELFStreamer::emitCantUnwind() { CantUnwind = true; }
133506f32e7eSjoerg 
133606f32e7eSjoerg // Add the R_ARM_NONE fixup at the same position
EmitPersonalityFixup(StringRef Name)133706f32e7eSjoerg void ARMELFStreamer::EmitPersonalityFixup(StringRef Name) {
133806f32e7eSjoerg   const MCSymbol *PersonalitySym = getContext().getOrCreateSymbol(Name);
133906f32e7eSjoerg 
134006f32e7eSjoerg   const MCSymbolRefExpr *PersonalityRef = MCSymbolRefExpr::create(
134106f32e7eSjoerg       PersonalitySym, MCSymbolRefExpr::VK_ARM_NONE, getContext());
134206f32e7eSjoerg 
134306f32e7eSjoerg   visitUsedExpr(*PersonalityRef);
134406f32e7eSjoerg   MCDataFragment *DF = getOrCreateDataFragment();
134506f32e7eSjoerg   DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
134606f32e7eSjoerg                                             PersonalityRef,
134706f32e7eSjoerg                                             MCFixup::getKindForSize(4, false)));
134806f32e7eSjoerg }
134906f32e7eSjoerg 
FlushPendingOffset()135006f32e7eSjoerg void ARMELFStreamer::FlushPendingOffset() {
135106f32e7eSjoerg   if (PendingOffset != 0) {
135206f32e7eSjoerg     UnwindOpAsm.EmitSPOffset(-PendingOffset);
135306f32e7eSjoerg     PendingOffset = 0;
135406f32e7eSjoerg   }
135506f32e7eSjoerg }
135606f32e7eSjoerg 
FlushUnwindOpcodes(bool NoHandlerData)135706f32e7eSjoerg void ARMELFStreamer::FlushUnwindOpcodes(bool NoHandlerData) {
135806f32e7eSjoerg   // Emit the unwind opcode to restore $sp.
135906f32e7eSjoerg   if (UsedFP) {
136006f32e7eSjoerg     const MCRegisterInfo *MRI = getContext().getRegisterInfo();
136106f32e7eSjoerg     int64_t LastRegSaveSPOffset = SPOffset - PendingOffset;
136206f32e7eSjoerg     UnwindOpAsm.EmitSPOffset(LastRegSaveSPOffset - FPOffset);
136306f32e7eSjoerg     UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg));
136406f32e7eSjoerg   } else {
136506f32e7eSjoerg     FlushPendingOffset();
136606f32e7eSjoerg   }
136706f32e7eSjoerg 
136806f32e7eSjoerg   // Finalize the unwind opcode sequence
136906f32e7eSjoerg   UnwindOpAsm.Finalize(PersonalityIndex, Opcodes);
137006f32e7eSjoerg 
137106f32e7eSjoerg   // For compact model 0, we have to emit the unwind opcodes in the .ARM.exidx
137206f32e7eSjoerg   // section.  Thus, we don't have to create an entry in the .ARM.extab
137306f32e7eSjoerg   // section.
137406f32e7eSjoerg   if (NoHandlerData && PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0)
137506f32e7eSjoerg     return;
137606f32e7eSjoerg 
137706f32e7eSjoerg   // Switch to .ARM.extab section.
137806f32e7eSjoerg   SwitchToExTabSection(*FnStart);
137906f32e7eSjoerg 
138006f32e7eSjoerg   // Create .ARM.extab label for offset in .ARM.exidx
138106f32e7eSjoerg   assert(!ExTab);
138206f32e7eSjoerg   ExTab = getContext().createTempSymbol();
1383*da58b97aSjoerg   emitLabel(ExTab);
138406f32e7eSjoerg 
138506f32e7eSjoerg   // Emit personality
138606f32e7eSjoerg   if (Personality) {
138706f32e7eSjoerg     const MCSymbolRefExpr *PersonalityRef =
138806f32e7eSjoerg       MCSymbolRefExpr::create(Personality,
138906f32e7eSjoerg                               MCSymbolRefExpr::VK_ARM_PREL31,
139006f32e7eSjoerg                               getContext());
139106f32e7eSjoerg 
1392*da58b97aSjoerg     emitValue(PersonalityRef, 4);
139306f32e7eSjoerg   }
139406f32e7eSjoerg 
139506f32e7eSjoerg   // Emit unwind opcodes
139606f32e7eSjoerg   assert((Opcodes.size() % 4) == 0 &&
139706f32e7eSjoerg          "Unwind opcode size for __aeabi_cpp_unwind_pr0 must be multiple of 4");
139806f32e7eSjoerg   for (unsigned I = 0; I != Opcodes.size(); I += 4) {
139906f32e7eSjoerg     uint64_t Intval = Opcodes[I] |
140006f32e7eSjoerg                       Opcodes[I + 1] << 8 |
140106f32e7eSjoerg                       Opcodes[I + 2] << 16 |
140206f32e7eSjoerg                       Opcodes[I + 3] << 24;
1403*da58b97aSjoerg     emitInt32(Intval);
140406f32e7eSjoerg   }
140506f32e7eSjoerg 
140606f32e7eSjoerg   // According to ARM EHABI section 9.2, if the __aeabi_unwind_cpp_pr1() or
140706f32e7eSjoerg   // __aeabi_unwind_cpp_pr2() is used, then the handler data must be emitted
140806f32e7eSjoerg   // after the unwind opcodes.  The handler data consists of several 32-bit
140906f32e7eSjoerg   // words, and should be terminated by zero.
141006f32e7eSjoerg   //
141106f32e7eSjoerg   // In case that the .handlerdata directive is not specified by the
141206f32e7eSjoerg   // programmer, we should emit zero to terminate the handler data.
141306f32e7eSjoerg   if (NoHandlerData && !Personality)
1414*da58b97aSjoerg     emitInt32(0);
141506f32e7eSjoerg }
141606f32e7eSjoerg 
emitHandlerData()141706f32e7eSjoerg void ARMELFStreamer::emitHandlerData() { FlushUnwindOpcodes(false); }
141806f32e7eSjoerg 
emitPersonality(const MCSymbol * Per)141906f32e7eSjoerg void ARMELFStreamer::emitPersonality(const MCSymbol *Per) {
142006f32e7eSjoerg   Personality = Per;
142106f32e7eSjoerg   UnwindOpAsm.setPersonality(Per);
142206f32e7eSjoerg }
142306f32e7eSjoerg 
emitPersonalityIndex(unsigned Index)142406f32e7eSjoerg void ARMELFStreamer::emitPersonalityIndex(unsigned Index) {
142506f32e7eSjoerg   assert(Index < ARM::EHABI::NUM_PERSONALITY_INDEX && "invalid index");
142606f32e7eSjoerg   PersonalityIndex = Index;
142706f32e7eSjoerg }
142806f32e7eSjoerg 
emitSetFP(unsigned NewFPReg,unsigned NewSPReg,int64_t Offset)142906f32e7eSjoerg void ARMELFStreamer::emitSetFP(unsigned NewFPReg, unsigned NewSPReg,
143006f32e7eSjoerg                                int64_t Offset) {
143106f32e7eSjoerg   assert((NewSPReg == ARM::SP || NewSPReg == FPReg) &&
143206f32e7eSjoerg          "the operand of .setfp directive should be either $sp or $fp");
143306f32e7eSjoerg 
143406f32e7eSjoerg   UsedFP = true;
143506f32e7eSjoerg   FPReg = NewFPReg;
143606f32e7eSjoerg 
143706f32e7eSjoerg   if (NewSPReg == ARM::SP)
143806f32e7eSjoerg     FPOffset = SPOffset + Offset;
143906f32e7eSjoerg   else
144006f32e7eSjoerg     FPOffset += Offset;
144106f32e7eSjoerg }
144206f32e7eSjoerg 
emitMovSP(unsigned Reg,int64_t Offset)144306f32e7eSjoerg void ARMELFStreamer::emitMovSP(unsigned Reg, int64_t Offset) {
144406f32e7eSjoerg   assert((Reg != ARM::SP && Reg != ARM::PC) &&
144506f32e7eSjoerg          "the operand of .movsp cannot be either sp or pc");
144606f32e7eSjoerg   assert(FPReg == ARM::SP && "current FP must be SP");
144706f32e7eSjoerg 
144806f32e7eSjoerg   FlushPendingOffset();
144906f32e7eSjoerg 
145006f32e7eSjoerg   FPReg = Reg;
145106f32e7eSjoerg   FPOffset = SPOffset + Offset;
145206f32e7eSjoerg 
145306f32e7eSjoerg   const MCRegisterInfo *MRI = getContext().getRegisterInfo();
145406f32e7eSjoerg   UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg));
145506f32e7eSjoerg }
145606f32e7eSjoerg 
emitPad(int64_t Offset)145706f32e7eSjoerg void ARMELFStreamer::emitPad(int64_t Offset) {
145806f32e7eSjoerg   // Track the change of the $sp offset
145906f32e7eSjoerg   SPOffset -= Offset;
146006f32e7eSjoerg 
146106f32e7eSjoerg   // To squash multiple .pad directives, we should delay the unwind opcode
146206f32e7eSjoerg   // until the .save, .vsave, .handlerdata, or .fnend directives.
146306f32e7eSjoerg   PendingOffset -= Offset;
146406f32e7eSjoerg }
146506f32e7eSjoerg 
emitRegSave(const SmallVectorImpl<unsigned> & RegList,bool IsVector)146606f32e7eSjoerg void ARMELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
146706f32e7eSjoerg                                  bool IsVector) {
146806f32e7eSjoerg   // Collect the registers in the register list
146906f32e7eSjoerg   unsigned Count = 0;
147006f32e7eSjoerg   uint32_t Mask = 0;
147106f32e7eSjoerg   const MCRegisterInfo *MRI = getContext().getRegisterInfo();
147206f32e7eSjoerg   for (size_t i = 0; i < RegList.size(); ++i) {
147306f32e7eSjoerg     unsigned Reg = MRI->getEncodingValue(RegList[i]);
147406f32e7eSjoerg     assert(Reg < (IsVector ? 32U : 16U) && "Register out of range");
147506f32e7eSjoerg     unsigned Bit = (1u << Reg);
147606f32e7eSjoerg     if ((Mask & Bit) == 0) {
147706f32e7eSjoerg       Mask |= Bit;
147806f32e7eSjoerg       ++Count;
147906f32e7eSjoerg     }
148006f32e7eSjoerg   }
148106f32e7eSjoerg 
148206f32e7eSjoerg   // Track the change the $sp offset: For the .save directive, the
148306f32e7eSjoerg   // corresponding push instruction will decrease the $sp by (4 * Count).
148406f32e7eSjoerg   // For the .vsave directive, the corresponding vpush instruction will
148506f32e7eSjoerg   // decrease $sp by (8 * Count).
148606f32e7eSjoerg   SPOffset -= Count * (IsVector ? 8 : 4);
148706f32e7eSjoerg 
148806f32e7eSjoerg   // Emit the opcode
148906f32e7eSjoerg   FlushPendingOffset();
149006f32e7eSjoerg   if (IsVector)
149106f32e7eSjoerg     UnwindOpAsm.EmitVFPRegSave(Mask);
149206f32e7eSjoerg   else
149306f32e7eSjoerg     UnwindOpAsm.EmitRegSave(Mask);
149406f32e7eSjoerg }
149506f32e7eSjoerg 
emitUnwindRaw(int64_t Offset,const SmallVectorImpl<uint8_t> & Opcodes)149606f32e7eSjoerg void ARMELFStreamer::emitUnwindRaw(int64_t Offset,
149706f32e7eSjoerg                                    const SmallVectorImpl<uint8_t> &Opcodes) {
149806f32e7eSjoerg   FlushPendingOffset();
149906f32e7eSjoerg   SPOffset = SPOffset - Offset;
150006f32e7eSjoerg   UnwindOpAsm.EmitRaw(Opcodes);
150106f32e7eSjoerg }
150206f32e7eSjoerg 
150306f32e7eSjoerg namespace llvm {
150406f32e7eSjoerg 
createARMTargetAsmStreamer(MCStreamer & S,formatted_raw_ostream & OS,MCInstPrinter * InstPrint,bool isVerboseAsm)150506f32e7eSjoerg MCTargetStreamer *createARMTargetAsmStreamer(MCStreamer &S,
150606f32e7eSjoerg                                              formatted_raw_ostream &OS,
150706f32e7eSjoerg                                              MCInstPrinter *InstPrint,
150806f32e7eSjoerg                                              bool isVerboseAsm) {
150906f32e7eSjoerg   return new ARMTargetAsmStreamer(S, OS, *InstPrint, isVerboseAsm);
151006f32e7eSjoerg }
151106f32e7eSjoerg 
createARMNullTargetStreamer(MCStreamer & S)151206f32e7eSjoerg MCTargetStreamer *createARMNullTargetStreamer(MCStreamer &S) {
151306f32e7eSjoerg   return new ARMTargetStreamer(S);
151406f32e7eSjoerg }
151506f32e7eSjoerg 
createARMObjectTargetStreamer(MCStreamer & S,const MCSubtargetInfo & STI)151606f32e7eSjoerg MCTargetStreamer *createARMObjectTargetStreamer(MCStreamer &S,
151706f32e7eSjoerg                                                 const MCSubtargetInfo &STI) {
151806f32e7eSjoerg   const Triple &TT = STI.getTargetTriple();
151906f32e7eSjoerg   if (TT.isOSBinFormatELF())
152006f32e7eSjoerg     return new ARMTargetELFStreamer(S);
152106f32e7eSjoerg   return new ARMTargetStreamer(S);
152206f32e7eSjoerg }
152306f32e7eSjoerg 
createARMELFStreamer(MCContext & Context,std::unique_ptr<MCAsmBackend> TAB,std::unique_ptr<MCObjectWriter> OW,std::unique_ptr<MCCodeEmitter> Emitter,bool RelaxAll,bool IsThumb,bool IsAndroid)152406f32e7eSjoerg MCELFStreamer *createARMELFStreamer(MCContext &Context,
152506f32e7eSjoerg                                     std::unique_ptr<MCAsmBackend> TAB,
152606f32e7eSjoerg                                     std::unique_ptr<MCObjectWriter> OW,
152706f32e7eSjoerg                                     std::unique_ptr<MCCodeEmitter> Emitter,
1528*da58b97aSjoerg                                     bool RelaxAll, bool IsThumb,
1529*da58b97aSjoerg                                     bool IsAndroid) {
1530*da58b97aSjoerg   ARMELFStreamer *S =
1531*da58b97aSjoerg       new ARMELFStreamer(Context, std::move(TAB), std::move(OW),
1532*da58b97aSjoerg                          std::move(Emitter), IsThumb, IsAndroid);
153306f32e7eSjoerg   // FIXME: This should eventually end up somewhere else where more
153406f32e7eSjoerg   // intelligent flag decisions can be made. For now we are just maintaining
153506f32e7eSjoerg   // the status quo for ARM and setting EF_ARM_EABI_VER5 as the default.
153606f32e7eSjoerg   S->getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5);
153706f32e7eSjoerg 
153806f32e7eSjoerg   if (RelaxAll)
153906f32e7eSjoerg     S->getAssembler().setRelaxAll(true);
154006f32e7eSjoerg   return S;
154106f32e7eSjoerg }
154206f32e7eSjoerg 
154306f32e7eSjoerg } // end namespace llvm
1544