//===- lib/MC/ARMELFStreamer.cpp - ELF Object Output for ARM --------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file assembles .s files and emits ARM ELF .o object files. Different
// from generic ELF streamer in emitting mapping symbols ($a, $t and $d) to
// delimit regions of data and code.
//
//===----------------------------------------------------------------------===//

#include "ARMRegisterInfo.h"
#include "ARMUnwindOpAsm.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/Twine.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCELFStreamer.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCFragment.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCSymbolELF.h"
#include "llvm/MC/SectionKind.h"
#include "llvm/Support/ARMBuildAttributes.h"
#include "llvm/Support/ARMEHABI.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/TargetParser.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
#include <climits>
#include <cstddef>
#include <cstdint>
#include <string>

using namespace llvm;

static std::string GetAEABIUnwindPersonalityName(unsigned Index) {
  assert(Index < ARM::EHABI::NUM_PERSONALITY_INDEX &&
         "Invalid personality index");
  return (Twine("__aeabi_unwind_cpp_pr") + Twine(Index)).str();
}

namespace {

class ARMELFStreamer;

class ARMTargetAsmStreamer : public ARMTargetStreamer {
  formatted_raw_ostream &OS;
  MCInstPrinter &InstPrinter;
  bool IsVerboseAsm;

  void emitFnStart() override;
  void emitFnEnd() override;
  void emitCantUnwind() override;
  void emitPersonality(const MCSymbol *Personality) override;
  void emitPersonalityIndex(unsigned Index) override;
  void emitHandlerData() override;
  void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0) override;
  void emitMovSP(unsigned Reg, int64_t Offset = 0) override;
  void emitPad(int64_t Offset) override;
  void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
                   bool isVector) override;
  void emitUnwindRaw(int64_t Offset,
                     const SmallVectorImpl<uint8_t> &Opcodes) override;

  void switchVendor(StringRef Vendor) override;
  void emitAttribute(unsigned Attribute, unsigned Value) override;
  void emitTextAttribute(unsigned Attribute, StringRef String) override;
  void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
                            StringRef StringValue) override;
  void emitArch(ARM::ArchKind Arch) override;
  void emitArchExtension(uint64_t ArchExt) override;
  void emitObjectArch(ARM::ArchKind Arch) override;
  void emitFPU(unsigned FPU) override;
  void emitInst(uint32_t Inst, char Suffix = '\0') override;
  void finishAttributeSection() override;

  void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override;
  void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override;

public:
  ARMTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS,
                       MCInstPrinter &InstPrinter, bool VerboseAsm);
};

ARMTargetAsmStreamer::ARMTargetAsmStreamer(MCStreamer &S,
                                           formatted_raw_ostream &OS,
                                           MCInstPrinter &InstPrinter,
                                           bool VerboseAsm)
    : ARMTargetStreamer(S), OS(OS), InstPrinter(InstPrinter),
      IsVerboseAsm(VerboseAsm) {}

void ARMTargetAsmStreamer::emitFnStart() { OS << "\t.fnstart\n"; }
void ARMTargetAsmStreamer::emitFnEnd() { OS << "\t.fnend\n"; }
void ARMTargetAsmStreamer::emitCantUnwind() { OS << "\t.cantunwind\n"; }

void ARMTargetAsmStreamer::emitPersonality(const MCSymbol *Personality) {
  OS << "\t.personality " << Personality->getName() << '\n';
}

void ARMTargetAsmStreamer::emitPersonalityIndex(unsigned Index) {
  OS << "\t.personalityindex " << Index << '\n';
}

void ARMTargetAsmStreamer::emitHandlerData() { OS << "\t.handlerdata\n"; }

void ARMTargetAsmStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
                                     int64_t Offset) {
  OS << "\t.setfp\t";
  InstPrinter.printRegName(OS, FpReg);
  OS << ", ";
  InstPrinter.printRegName(OS, SpReg);
  if (Offset)
    OS << ", #" << Offset;
  OS << '\n';
}

void ARMTargetAsmStreamer::emitMovSP(unsigned Reg, int64_t Offset) {
  assert((Reg != ARM::SP && Reg != ARM::PC) &&
         "the operand of .movsp cannot be either sp or pc");

  OS << "\t.movsp\t";
  InstPrinter.printRegName(OS, Reg);
  if (Offset)
    OS << ", #" << Offset;
  OS << '\n';
}

void ARMTargetAsmStreamer::emitPad(int64_t Offset) {
  OS << "\t.pad\t#" << Offset << '\n';
}

void ARMTargetAsmStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
                                       bool isVector) {
  assert(RegList.size() && "RegList should not be empty");
  if (isVector)
    OS << "\t.vsave\t{";
  else
    OS << "\t.save\t{";

  InstPrinter.printRegName(OS, RegList[0]);

  for (unsigned i = 1, e = RegList.size(); i != e; ++i) {
    OS << ", ";
    InstPrinter.printRegName(OS, RegList[i]);
  }

  OS << "}\n";
}

void ARMTargetAsmStreamer::switchVendor(StringRef Vendor) {}

void ARMTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
  OS << "\t.eabi_attribute\t" << Attribute << ", " << Twine(Value);
  if (IsVerboseAsm) {
    StringRef Name =
        ELFAttrs::attrTypeAsString(Attribute, ARMBuildAttrs::ARMAttributeTags);
    if (!Name.empty())
      OS << "\t@ " << Name;
  }
  OS << "\n";
}

void ARMTargetAsmStreamer::emitTextAttribute(unsigned Attribute,
                                             StringRef String) {
  switch (Attribute) {
  case ARMBuildAttrs::CPU_name:
    OS << "\t.cpu\t" << String.lower();
    break;
  default:
    OS << "\t.eabi_attribute\t" << Attribute << ", \"" << String << "\"";
    if (IsVerboseAsm) {
      StringRef Name = ELFAttrs::attrTypeAsString(
          Attribute, ARMBuildAttrs::ARMAttributeTags);
      if (!Name.empty())
        OS << "\t@ " << Name;
    }
    break;
  }
  OS << "\n";
}

void ARMTargetAsmStreamer::emitIntTextAttribute(unsigned Attribute,
                                                unsigned IntValue,
                                                StringRef StringValue) {
  switch (Attribute) {
  default: llvm_unreachable("unsupported multi-value attribute in asm mode");
  case ARMBuildAttrs::compatibility:
    OS << "\t.eabi_attribute\t" << Attribute << ", " << IntValue;
    if (!StringValue.empty())
      OS << ", \"" << StringValue << "\"";
    if (IsVerboseAsm)
      OS << "\t@ "
         << ELFAttrs::attrTypeAsString(Attribute,
                                       ARMBuildAttrs::ARMAttributeTags);
    break;
  }
  OS << "\n";
}

void ARMTargetAsmStreamer::emitArch(ARM::ArchKind Arch) {
  OS << "\t.arch\t" << ARM::getArchName(Arch) << "\n";
}

void ARMTargetAsmStreamer::emitArchExtension(uint64_t ArchExt) {
  OS << "\t.arch_extension\t" << ARM::getArchExtName(ArchExt) << "\n";
}

void ARMTargetAsmStreamer::emitObjectArch(ARM::ArchKind Arch) {
  OS << "\t.object_arch\t" << ARM::getArchName(Arch) << '\n';
}

void ARMTargetAsmStreamer::emitFPU(unsigned FPU) {
  OS << "\t.fpu\t" << ARM::getFPUName(FPU) << "\n";
}

void ARMTargetAsmStreamer::finishAttributeSection() {}

void
ARMTargetAsmStreamer::AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *S) {
  OS << "\t.tlsdescseq\t" << S->getSymbol().getName() << "\n";
}

void ARMTargetAsmStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) {
  const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();

  OS << "\t.thumb_set\t";
  Symbol->print(OS, MAI);
  OS << ", ";
  Value->print(OS, MAI);
  OS << '\n';
}

void ARMTargetAsmStreamer::emitInst(uint32_t Inst, char Suffix) {
  OS << "\t.inst";
  if (Suffix)
    OS << "." << Suffix;
  OS << "\t0x" << Twine::utohexstr(Inst) << "\n";
}

void ARMTargetAsmStreamer::emitUnwindRaw(int64_t Offset,
                                      const SmallVectorImpl<uint8_t> &Opcodes) {
  OS << "\t.unwind_raw " << Offset;
  for (SmallVectorImpl<uint8_t>::const_iterator OCI = Opcodes.begin(),
                                                OCE = Opcodes.end();
       OCI != OCE; ++OCI)
    OS << ", 0x" << Twine::utohexstr(*OCI);
  OS << '\n';
}

class ARMTargetELFStreamer : public ARMTargetStreamer {
private:
  // This structure holds all attributes, accounting for
  // their string/numeric value, so we can later emit them
  // in declaration order, keeping all in the same vector
  struct AttributeItem {
    enum {
      HiddenAttribute = 0,
      NumericAttribute,
      TextAttribute,
      NumericAndTextAttributes
    } Type;
    unsigned Tag;
    unsigned IntValue;
    std::string StringValue;

    static bool LessTag(const AttributeItem &LHS, const AttributeItem &RHS) {
      // The conformance tag must be emitted first when serialised
      // into an object file. Specifically, the addenda to the ARM ABI
      // states that (2.3.7.4):
      //
      // "To simplify recognition by consumers in the common case of
      // claiming conformity for the whole file, this tag should be
      // emitted first in a file-scope sub-subsection of the first
      // public subsection of the attributes section."
      //
      // So it is special-cased in this comparison predicate when the
      // attributes are sorted in finishAttributeSection().
      return (RHS.Tag != ARMBuildAttrs::conformance) &&
             ((LHS.Tag == ARMBuildAttrs::conformance) || (LHS.Tag < RHS.Tag));
    }
  };

  StringRef CurrentVendor;
  unsigned FPU = ARM::FK_INVALID;
  ARM::ArchKind Arch = ARM::ArchKind::INVALID;
  ARM::ArchKind EmittedArch = ARM::ArchKind::INVALID;
  SmallVector<AttributeItem, 64> Contents;

  MCSection *AttributeSection = nullptr;

  AttributeItem *getAttributeItem(unsigned Attribute) {
    for (size_t i = 0; i < Contents.size(); ++i)
      if (Contents[i].Tag == Attribute)
        return &Contents[i];
    return nullptr;
  }

  void setAttributeItem(unsigned Attribute, unsigned Value,
                        bool OverwriteExisting) {
    // Look for existing attribute item
    if (AttributeItem *Item = getAttributeItem(Attribute)) {
      if (!OverwriteExisting)
        return;
      Item->Type = AttributeItem::NumericAttribute;
      Item->IntValue = Value;
      return;
    }

    // Create new attribute item
    AttributeItem Item = {AttributeItem::NumericAttribute, Attribute, Value,
                          std::string(StringRef(""))};
    Contents.push_back(Item);
  }

  void setAttributeItem(unsigned Attribute, StringRef Value,
                        bool OverwriteExisting) {
    // Look for existing attribute item
    if (AttributeItem *Item = getAttributeItem(Attribute)) {
      if (!OverwriteExisting)
        return;
      Item->Type = AttributeItem::TextAttribute;
      Item->StringValue = std::string(Value);
      return;
    }

    // Create new attribute item
    AttributeItem Item = {AttributeItem::TextAttribute, Attribute, 0,
                          std::string(Value)};
    Contents.push_back(Item);
  }

  void setAttributeItems(unsigned Attribute, unsigned IntValue,
                         StringRef StringValue, bool OverwriteExisting) {
    // Look for existing attribute item
    if (AttributeItem *Item = getAttributeItem(Attribute)) {
      if (!OverwriteExisting)
        return;
      Item->Type = AttributeItem::NumericAndTextAttributes;
      Item->IntValue = IntValue;
      Item->StringValue = std::string(StringValue);
      return;
    }

    // Create new attribute item
    AttributeItem Item = {AttributeItem::NumericAndTextAttributes, Attribute,
                          IntValue, std::string(StringValue)};
    Contents.push_back(Item);
  }

  void emitArchDefaultAttributes();
  void emitFPUDefaultAttributes();

  ARMELFStreamer &getStreamer();

  void emitFnStart() override;
  void emitFnEnd() override;
  void emitCantUnwind() override;
  void emitPersonality(const MCSymbol *Personality) override;
  void emitPersonalityIndex(unsigned Index) override;
  void emitHandlerData() override;
  void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0) override;
  void emitMovSP(unsigned Reg, int64_t Offset = 0) override;
  void emitPad(int64_t Offset) override;
  void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
                   bool isVector) override;
  void emitUnwindRaw(int64_t Offset,
                     const SmallVectorImpl<uint8_t> &Opcodes) override;

  void switchVendor(StringRef Vendor) override;
  void emitAttribute(unsigned Attribute, unsigned Value) override;
  void emitTextAttribute(unsigned Attribute, StringRef String) override;
  void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
                            StringRef StringValue) override;
  void emitArch(ARM::ArchKind Arch) override;
  void emitObjectArch(ARM::ArchKind Arch) override;
  void emitFPU(unsigned FPU) override;
  void emitInst(uint32_t Inst, char Suffix = '\0') override;
  void finishAttributeSection() override;
  void emitLabel(MCSymbol *Symbol) override;

  void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override;
  void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override;

  size_t calculateContentSize() const;

  // Reset state between object emissions
  void reset() override;

public:
  ARMTargetELFStreamer(MCStreamer &S)
    : ARMTargetStreamer(S), CurrentVendor("aeabi") {}
};

/// Extend the generic ELFStreamer class so that it can emit mapping symbols at
/// the appropriate points in the object files. These symbols are defined in the
/// ARM ELF ABI: infocenter.arm.com/help/topic/com.arm.../IHI0044D_aaelf.pdf.
///
/// In brief: $a, $t or $d should be emitted at the start of each contiguous
/// region of ARM code, Thumb code or data in a section. In practice, this
/// emission does not rely on explicit assembler directives but on inherent
/// properties of the directives doing the emission (e.g. ".byte" is data, "add
/// r0, r0, r0" an instruction).
///
/// As a result this system is orthogonal to the DataRegion infrastructure used
/// by MachO. Beware!
class ARMELFStreamer : public MCELFStreamer {
public:
  friend class ARMTargetELFStreamer;

  ARMELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
                 std::unique_ptr<MCObjectWriter> OW,
                 std::unique_ptr<MCCodeEmitter> Emitter, bool IsThumb,
                 bool IsAndroid)
      : MCELFStreamer(Context, std::move(TAB), std::move(OW),
                      std::move(Emitter)),
        IsThumb(IsThumb), IsAndroid(IsAndroid) {
    EHReset();
  }

  ~ARMELFStreamer() override = default;

  void finishImpl() override;

  // ARM exception handling directives
  void emitFnStart();
  void emitFnEnd();
  void emitCantUnwind();
  void emitPersonality(const MCSymbol *Per);
  void emitPersonalityIndex(unsigned index);
  void emitHandlerData();
  void emitSetFP(unsigned NewFpReg, unsigned NewSpReg, int64_t Offset = 0);
  void emitMovSP(unsigned Reg, int64_t Offset = 0);
  void emitPad(int64_t Offset);
  void emitRegSave(const SmallVectorImpl<unsigned> &RegList, bool isVector);
  void emitUnwindRaw(int64_t Offset, const SmallVectorImpl<uint8_t> &Opcodes);
  void emitFill(const MCExpr &NumBytes, uint64_t FillValue,
                SMLoc Loc) override {
    emitDataMappingSymbol();
    MCObjectStreamer::emitFill(NumBytes, FillValue, Loc);
  }

  void changeSection(MCSection *Section, const MCExpr *Subsection) override {
    LastMappingSymbols[getCurrentSection().first] = std::move(LastEMSInfo);
    MCELFStreamer::changeSection(Section, Subsection);
    auto LastMappingSymbol = LastMappingSymbols.find(Section);
    if (LastMappingSymbol != LastMappingSymbols.end()) {
      LastEMSInfo = std::move(LastMappingSymbol->second);
      return;
    }
    LastEMSInfo.reset(new ElfMappingSymbolInfo(SMLoc(), nullptr, 0));
  }

  /// This function is the one used to emit instruction data into the ELF
  /// streamer. We override it to add the appropriate mapping symbol if
  /// necessary.
  void emitInstruction(const MCInst &Inst,
                       const MCSubtargetInfo &STI) override {
    if (IsThumb)
      EmitThumbMappingSymbol();
    else
      EmitARMMappingSymbol();

    MCELFStreamer::emitInstruction(Inst, STI);
  }

  void emitInst(uint32_t Inst, char Suffix) {
    unsigned Size;
    char Buffer[4];
    const bool LittleEndian = getContext().getAsmInfo()->isLittleEndian();

    switch (Suffix) {
    case '\0':
      Size = 4;

      assert(!IsThumb);
      EmitARMMappingSymbol();
      for (unsigned II = 0, IE = Size; II != IE; II++) {
        const unsigned I = LittleEndian ? (Size - II - 1) : II;
        Buffer[Size - II - 1] = uint8_t(Inst >> I * CHAR_BIT);
      }

      break;
    case 'n':
    case 'w':
      Size = (Suffix == 'n' ? 2 : 4);

      assert(IsThumb);
      EmitThumbMappingSymbol();
      // Thumb wide instructions are emitted as a pair of 16-bit words of the
      // appropriate endianness.
      for (unsigned II = 0, IE = Size; II != IE; II = II + 2) {
        const unsigned I0 = LittleEndian ? II + 0 : II + 1;
        const unsigned I1 = LittleEndian ? II + 1 : II + 0;
        Buffer[Size - II - 2] = uint8_t(Inst >> I0 * CHAR_BIT);
        Buffer[Size - II - 1] = uint8_t(Inst >> I1 * CHAR_BIT);
      }

      break;
    default:
      llvm_unreachable("Invalid Suffix");
    }

    MCELFStreamer::emitBytes(StringRef(Buffer, Size));
  }

  /// This is one of the functions used to emit data into an ELF section, so the
  /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if
  /// necessary.
  void emitBytes(StringRef Data) override {
    emitDataMappingSymbol();
    MCELFStreamer::emitBytes(Data);
  }

  void FlushPendingMappingSymbol() {
    if (!LastEMSInfo->hasInfo())
      return;
    ElfMappingSymbolInfo *EMS = LastEMSInfo.get();
    EmitMappingSymbol("$d", EMS->Loc, EMS->F, EMS->Offset);
    EMS->resetInfo();
  }

  /// This is one of the functions used to emit data into an ELF section, so the
  /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if
  /// necessary.
  void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override {
    if (const MCSymbolRefExpr *SRE = dyn_cast_or_null<MCSymbolRefExpr>(Value)) {
      if (SRE->getKind() == MCSymbolRefExpr::VK_ARM_SBREL && !(Size == 4)) {
        getContext().reportError(Loc, "relocated expression must be 32-bit");
        return;
      }
      getOrCreateDataFragment();
    }

    emitDataMappingSymbol();
    MCELFStreamer::emitValueImpl(Value, Size, Loc);
  }

  void emitAssemblerFlag(MCAssemblerFlag Flag) override {
    MCELFStreamer::emitAssemblerFlag(Flag);

    switch (Flag) {
    case MCAF_SyntaxUnified:
      return; // no-op here.
    case MCAF_Code16:
      IsThumb = true;
      return; // Change to Thumb mode
    case MCAF_Code32:
      IsThumb = false;
      return; // Change to ARM mode
    case MCAF_Code64:
      return;
    case MCAF_SubsectionsViaSymbols:
      return;
    }
  }

  /// If a label is defined before the .type directive sets the label's type
  /// then the label can't be recorded as thumb function when the label is
  /// defined. We override emitSymbolAttribute() which is called as part of the
  /// parsing of .type so that if the symbol has already been defined we can
  /// record the label as Thumb. FIXME: there is a corner case where the state
  /// is changed in between the label definition and the .type directive, this
  /// is not expected to occur in practice and handling it would require the
  /// backend to track IsThumb for every label.
  bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override {
    bool Val = MCELFStreamer::emitSymbolAttribute(Symbol, Attribute);

    if (!IsThumb)
      return Val;

    unsigned Type = cast<MCSymbolELF>(Symbol)->getType();
    if ((Type == ELF::STT_FUNC || Type == ELF::STT_GNU_IFUNC) &&
        Symbol->isDefined())
      getAssembler().setIsThumbFunc(Symbol);

    return Val;
  };

private:
  enum ElfMappingSymbol {
    EMS_None,
    EMS_ARM,
    EMS_Thumb,
    EMS_Data
  };

  struct ElfMappingSymbolInfo {
    explicit ElfMappingSymbolInfo(SMLoc Loc, MCFragment *F, uint64_t O)
        : Loc(Loc), F(F), Offset(O), State(EMS_None) {}
    void resetInfo() {
      F = nullptr;
      Offset = 0;
    }
    bool hasInfo() { return F != nullptr; }
    SMLoc Loc;
    MCFragment *F;
    uint64_t Offset;
    ElfMappingSymbol State;
  };

  void emitDataMappingSymbol() {
    if (LastEMSInfo->State == EMS_Data)
      return;
    else if (LastEMSInfo->State == EMS_None) {
      // This is a tentative symbol, it won't really be emitted until it's
      // actually needed.
      ElfMappingSymbolInfo *EMS = LastEMSInfo.get();
      auto *DF = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
      if (!DF)
        return;
      EMS->Loc = SMLoc();
      EMS->F = getCurrentFragment();
      EMS->Offset = DF->getContents().size();
      LastEMSInfo->State = EMS_Data;
      return;
    }
    EmitMappingSymbol("$d");
    LastEMSInfo->State = EMS_Data;
  }

  void EmitThumbMappingSymbol() {
    if (LastEMSInfo->State == EMS_Thumb)
      return;
    FlushPendingMappingSymbol();
    EmitMappingSymbol("$t");
    LastEMSInfo->State = EMS_Thumb;
  }

  void EmitARMMappingSymbol() {
    if (LastEMSInfo->State == EMS_ARM)
      return;
    FlushPendingMappingSymbol();
    EmitMappingSymbol("$a");
    LastEMSInfo->State = EMS_ARM;
  }

  void EmitMappingSymbol(StringRef Name) {
    auto *Symbol = cast<MCSymbolELF>(getContext().getOrCreateSymbol(
        Name + "." + Twine(MappingSymbolCounter++)));
    emitLabel(Symbol);

    Symbol->setType(ELF::STT_NOTYPE);
    Symbol->setBinding(ELF::STB_LOCAL);
  }

  void EmitMappingSymbol(StringRef Name, SMLoc Loc, MCFragment *F,
                         uint64_t Offset) {
    auto *Symbol = cast<MCSymbolELF>(getContext().getOrCreateSymbol(
        Name + "." + Twine(MappingSymbolCounter++)));
    emitLabelAtPos(Symbol, Loc, F, Offset);
    Symbol->setType(ELF::STT_NOTYPE);
    Symbol->setBinding(ELF::STB_LOCAL);
  }

  void emitThumbFunc(MCSymbol *Func) override {
    getAssembler().setIsThumbFunc(Func);
    emitSymbolAttribute(Func, MCSA_ELF_TypeFunction);
  }

  // Helper functions for ARM exception handling directives
  void EHReset();

  // Reset state between object emissions
  void reset() override;

  void EmitPersonalityFixup(StringRef Name);
  void FlushPendingOffset();
  void FlushUnwindOpcodes(bool NoHandlerData);

  void SwitchToEHSection(StringRef Prefix, unsigned Type, unsigned Flags,
                         SectionKind Kind, const MCSymbol &Fn);
  void SwitchToExTabSection(const MCSymbol &FnStart);
  void SwitchToExIdxSection(const MCSymbol &FnStart);

  void EmitFixup(const MCExpr *Expr, MCFixupKind Kind);

  bool IsThumb;
  bool IsAndroid;
  int64_t MappingSymbolCounter = 0;

  DenseMap<const MCSection *, std::unique_ptr<ElfMappingSymbolInfo>>
      LastMappingSymbols;

  std::unique_ptr<ElfMappingSymbolInfo> LastEMSInfo;

  // ARM Exception Handling Frame Information
  MCSymbol *ExTab;
  MCSymbol *FnStart;
  const MCSymbol *Personality;
  unsigned PersonalityIndex;
  unsigned FPReg; // Frame pointer register
  int64_t FPOffset; // Offset: (final frame pointer) - (initial $sp)
  int64_t SPOffset; // Offset: (final $sp) - (initial $sp)
  int64_t PendingOffset; // Offset: (final $sp) - (emitted $sp)
  bool UsedFP;
  bool CantUnwind;
  SmallVector<uint8_t, 64> Opcodes;
  UnwindOpcodeAssembler UnwindOpAsm;
};

} // end anonymous namespace

ARMELFStreamer &ARMTargetELFStreamer::getStreamer() {
  return static_cast<ARMELFStreamer &>(Streamer);
}

void ARMTargetELFStreamer::emitFnStart() { getStreamer().emitFnStart(); }
void ARMTargetELFStreamer::emitFnEnd() { getStreamer().emitFnEnd(); }
void ARMTargetELFStreamer::emitCantUnwind() { getStreamer().emitCantUnwind(); }

void ARMTargetELFStreamer::emitPersonality(const MCSymbol *Personality) {
  getStreamer().emitPersonality(Personality);
}

void ARMTargetELFStreamer::emitPersonalityIndex(unsigned Index) {
  getStreamer().emitPersonalityIndex(Index);
}

void ARMTargetELFStreamer::emitHandlerData() {
  getStreamer().emitHandlerData();
}

void ARMTargetELFStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
                                     int64_t Offset) {
  getStreamer().emitSetFP(FpReg, SpReg, Offset);
}

void ARMTargetELFStreamer::emitMovSP(unsigned Reg, int64_t Offset) {
  getStreamer().emitMovSP(Reg, Offset);
}

void ARMTargetELFStreamer::emitPad(int64_t Offset) {
  getStreamer().emitPad(Offset);
}

void ARMTargetELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
                                       bool isVector) {
  getStreamer().emitRegSave(RegList, isVector);
}

void ARMTargetELFStreamer::emitUnwindRaw(int64_t Offset,
                                      const SmallVectorImpl<uint8_t> &Opcodes) {
  getStreamer().emitUnwindRaw(Offset, Opcodes);
}

void ARMTargetELFStreamer::switchVendor(StringRef Vendor) {
  assert(!Vendor.empty() && "Vendor cannot be empty.");

  if (CurrentVendor == Vendor)
    return;

  if (!CurrentVendor.empty())
    finishAttributeSection();

  assert(Contents.empty() &&
         ".ARM.attributes should be flushed before changing vendor");
  CurrentVendor = Vendor;

}

void ARMTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
  setAttributeItem(Attribute, Value, /* OverwriteExisting= */ true);
}

void ARMTargetELFStreamer::emitTextAttribute(unsigned Attribute,
                                             StringRef Value) {
  setAttributeItem(Attribute, Value, /* OverwriteExisting= */ true);
}

void ARMTargetELFStreamer::emitIntTextAttribute(unsigned Attribute,
                                                unsigned IntValue,
                                                StringRef StringValue) {
  setAttributeItems(Attribute, IntValue, StringValue,
                    /* OverwriteExisting= */ true);
}

void ARMTargetELFStreamer::emitArch(ARM::ArchKind Value) {
  Arch = Value;
}

void ARMTargetELFStreamer::emitObjectArch(ARM::ArchKind Value) {
  EmittedArch = Value;
}

void ARMTargetELFStreamer::emitArchDefaultAttributes() {
  using namespace ARMBuildAttrs;

  setAttributeItem(CPU_name,
                   ARM::getCPUAttr(Arch),
                   false);

  if (EmittedArch == ARM::ArchKind::INVALID)
    setAttributeItem(CPU_arch,
                     ARM::getArchAttr(Arch),
                     false);
  else
    setAttributeItem(CPU_arch,
                     ARM::getArchAttr(EmittedArch),
                     false);

  switch (Arch) {
  case ARM::ArchKind::ARMV2:
  case ARM::ArchKind::ARMV2A:
  case ARM::ArchKind::ARMV3:
  case ARM::ArchKind::ARMV3M:
  case ARM::ArchKind::ARMV4:
    setAttributeItem(ARM_ISA_use, Allowed, false);
    break;

  case ARM::ArchKind::ARMV4T:
  case ARM::ArchKind::ARMV5T:
  case ARM::ArchKind::ARMV5TE:
  case ARM::ArchKind::ARMV6:
    setAttributeItem(ARM_ISA_use, Allowed, false);
    setAttributeItem(THUMB_ISA_use, Allowed, false);
    break;

  case ARM::ArchKind::ARMV6T2:
    setAttributeItem(ARM_ISA_use, Allowed, false);
    setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
    break;

  case ARM::ArchKind::ARMV6K:
  case ARM::ArchKind::ARMV6KZ:
    setAttributeItem(ARM_ISA_use, Allowed, false);
    setAttributeItem(THUMB_ISA_use, Allowed, false);
    setAttributeItem(Virtualization_use, AllowTZ, false);
    break;

  case ARM::ArchKind::ARMV6M:
    setAttributeItem(THUMB_ISA_use, Allowed, false);
    break;

  case ARM::ArchKind::ARMV7A:
    setAttributeItem(CPU_arch_profile, ApplicationProfile, false);
    setAttributeItem(ARM_ISA_use, Allowed, false);
    setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
    break;

  case ARM::ArchKind::ARMV7R:
    setAttributeItem(CPU_arch_profile, RealTimeProfile, false);
    setAttributeItem(ARM_ISA_use, Allowed, false);
    setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
    break;

  case ARM::ArchKind::ARMV7EM:
  case ARM::ArchKind::ARMV7M:
    setAttributeItem(CPU_arch_profile, MicroControllerProfile, false);
    setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
    break;

  case ARM::ArchKind::ARMV8A:
  case ARM::ArchKind::ARMV8_1A:
  case ARM::ArchKind::ARMV8_2A:
  case ARM::ArchKind::ARMV8_3A:
  case ARM::ArchKind::ARMV8_4A:
  case ARM::ArchKind::ARMV8_5A:
  case ARM::ArchKind::ARMV8_6A:
    setAttributeItem(CPU_arch_profile, ApplicationProfile, false);
    setAttributeItem(ARM_ISA_use, Allowed, false);
    setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
    setAttributeItem(MPextension_use, Allowed, false);
    setAttributeItem(Virtualization_use, AllowTZVirtualization, false);
    break;

  case ARM::ArchKind::ARMV8MBaseline:
  case ARM::ArchKind::ARMV8MMainline:
    setAttributeItem(THUMB_ISA_use, AllowThumbDerived, false);
    setAttributeItem(CPU_arch_profile, MicroControllerProfile, false);
    break;

  case ARM::ArchKind::IWMMXT:
    setAttributeItem(ARM_ISA_use, Allowed, false);
    setAttributeItem(THUMB_ISA_use, Allowed, false);
    setAttributeItem(WMMX_arch, AllowWMMXv1, false);
    break;

  case ARM::ArchKind::IWMMXT2:
    setAttributeItem(ARM_ISA_use, Allowed, false);
    setAttributeItem(THUMB_ISA_use, Allowed, false);
    setAttributeItem(WMMX_arch, AllowWMMXv2, false);
    break;

  default:
    report_fatal_error("Unknown Arch: " + Twine(ARM::getArchName(Arch)));
    break;
  }
}

void ARMTargetELFStreamer::emitFPU(unsigned Value) {
  FPU = Value;
}

void ARMTargetELFStreamer::emitFPUDefaultAttributes() {
  switch (FPU) {
  case ARM::FK_VFP:
  case ARM::FK_VFPV2:
    setAttributeItem(ARMBuildAttrs::FP_arch,
                     ARMBuildAttrs::AllowFPv2,
                     /* OverwriteExisting= */ false);
    break;

  case ARM::FK_VFPV3:
    setAttributeItem(ARMBuildAttrs::FP_arch,
                     ARMBuildAttrs::AllowFPv3A,
                     /* OverwriteExisting= */ false);
    break;

  case ARM::FK_VFPV3_FP16:
    setAttributeItem(ARMBuildAttrs::FP_arch,
                     ARMBuildAttrs::AllowFPv3A,
                     /* OverwriteExisting= */ false);
    setAttributeItem(ARMBuildAttrs::FP_HP_extension,
                     ARMBuildAttrs::AllowHPFP,
                     /* OverwriteExisting= */ false);
    break;

  case ARM::FK_VFPV3_D16:
    setAttributeItem(ARMBuildAttrs::FP_arch,
                     ARMBuildAttrs::AllowFPv3B,
                     /* OverwriteExisting= */ false);
    break;

  case ARM::FK_VFPV3_D16_FP16:
    setAttributeItem(ARMBuildAttrs::FP_arch,
                     ARMBuildAttrs::AllowFPv3B,
                     /* OverwriteExisting= */ false);
    setAttributeItem(ARMBuildAttrs::FP_HP_extension,
                     ARMBuildAttrs::AllowHPFP,
                     /* OverwriteExisting= */ false);
    break;

  case ARM::FK_VFPV3XD:
    setAttributeItem(ARMBuildAttrs::FP_arch,
                     ARMBuildAttrs::AllowFPv3B,
                     /* OverwriteExisting= */ false);
    break;
  case ARM::FK_VFPV3XD_FP16:
    setAttributeItem(ARMBuildAttrs::FP_arch,
                     ARMBuildAttrs::AllowFPv3B,
                     /* OverwriteExisting= */ false);
    setAttributeItem(ARMBuildAttrs::FP_HP_extension,
                     ARMBuildAttrs::AllowHPFP,
                     /* OverwriteExisting= */ false);
    break;

  case ARM::FK_VFPV4:
    setAttributeItem(ARMBuildAttrs::FP_arch,
                     ARMBuildAttrs::AllowFPv4A,
                     /* OverwriteExisting= */ false);
    break;

  // ABI_HardFP_use is handled in ARMAsmPrinter, so _SP_D16 is treated the same
  // as _D16 here.
  case ARM::FK_FPV4_SP_D16:
  case ARM::FK_VFPV4_D16:
    setAttributeItem(ARMBuildAttrs::FP_arch,
                     ARMBuildAttrs::AllowFPv4B,
                     /* OverwriteExisting= */ false);
    break;

  case ARM::FK_FP_ARMV8:
    setAttributeItem(ARMBuildAttrs::FP_arch,
                     ARMBuildAttrs::AllowFPARMv8A,
                     /* OverwriteExisting= */ false);
    break;

  // FPV5_D16 is identical to FP_ARMV8 except for the number of D registers, so
  // uses the FP_ARMV8_D16 build attribute.
  case ARM::FK_FPV5_SP_D16:
  case ARM::FK_FPV5_D16:
    setAttributeItem(ARMBuildAttrs::FP_arch,
                     ARMBuildAttrs::AllowFPARMv8B,
                     /* OverwriteExisting= */ false);
    break;

  case ARM::FK_NEON:
    setAttributeItem(ARMBuildAttrs::FP_arch,
                     ARMBuildAttrs::AllowFPv3A,
                     /* OverwriteExisting= */ false);
    setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
                     ARMBuildAttrs::AllowNeon,
                     /* OverwriteExisting= */ false);
    break;

  case ARM::FK_NEON_FP16:
    setAttributeItem(ARMBuildAttrs::FP_arch,
                     ARMBuildAttrs::AllowFPv3A,
                     /* OverwriteExisting= */ false);
    setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
                     ARMBuildAttrs::AllowNeon,
                     /* OverwriteExisting= */ false);
    setAttributeItem(ARMBuildAttrs::FP_HP_extension,
                     ARMBuildAttrs::AllowHPFP,
                     /* OverwriteExisting= */ false);
    break;

  case ARM::FK_NEON_VFPV4:
    setAttributeItem(ARMBuildAttrs::FP_arch,
                     ARMBuildAttrs::AllowFPv4A,
                     /* OverwriteExisting= */ false);
    setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
                     ARMBuildAttrs::AllowNeon2,
                     /* OverwriteExisting= */ false);
    break;

  case ARM::FK_NEON_FP_ARMV8:
  case ARM::FK_CRYPTO_NEON_FP_ARMV8:
    setAttributeItem(ARMBuildAttrs::FP_arch,
                     ARMBuildAttrs::AllowFPARMv8A,
                     /* OverwriteExisting= */ false);
    // 'Advanced_SIMD_arch' must be emitted not here, but within
    // ARMAsmPrinter::emitAttributes(), depending on hasV8Ops() and hasV8_1a()
    break;

  case ARM::FK_SOFTVFP:
  case ARM::FK_NONE:
    break;

  default:
    report_fatal_error("Unknown FPU: " + Twine(FPU));
    break;
  }
}

size_t ARMTargetELFStreamer::calculateContentSize() const {
  size_t Result = 0;
  for (size_t i = 0; i < Contents.size(); ++i) {
    AttributeItem item = Contents[i];
    switch (item.Type) {
    case AttributeItem::HiddenAttribute:
      break;
    case AttributeItem::NumericAttribute:
      Result += getULEB128Size(item.Tag);
      Result += getULEB128Size(item.IntValue);
      break;
    case AttributeItem::TextAttribute:
      Result += getULEB128Size(item.Tag);
      Result += item.StringValue.size() + 1; // string + '\0'
      break;
    case AttributeItem::NumericAndTextAttributes:
      Result += getULEB128Size(item.Tag);
      Result += getULEB128Size(item.IntValue);
      Result += item.StringValue.size() + 1; // string + '\0';
      break;
    }
  }
  return Result;
}

void ARMTargetELFStreamer::finishAttributeSection() {
  // <format-version>
  // [ <section-length> "vendor-name"
  // [ <file-tag> <size> <attribute>*
  //   | <section-tag> <size> <section-number>* 0 <attribute>*
  //   | <symbol-tag> <size> <symbol-number>* 0 <attribute>*
  //   ]+
  // ]*

  if (FPU != ARM::FK_INVALID)
    emitFPUDefaultAttributes();

  if (Arch != ARM::ArchKind::INVALID)
    emitArchDefaultAttributes();

  if (Contents.empty())
    return;

  llvm::sort(Contents, AttributeItem::LessTag);

  ARMELFStreamer &Streamer = getStreamer();

  // Switch to .ARM.attributes section
  if (AttributeSection) {
    Streamer.SwitchSection(AttributeSection);
  } else {
    AttributeSection = Streamer.getContext().getELFSection(
        ".ARM.attributes", ELF::SHT_ARM_ATTRIBUTES, 0);
    Streamer.SwitchSection(AttributeSection);

    // Format version
    Streamer.emitInt8(0x41);
  }

  // Vendor size + Vendor name + '\0'
  const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1;

  // Tag + Tag Size
  const size_t TagHeaderSize = 1 + 4;

  const size_t ContentsSize = calculateContentSize();

  Streamer.emitInt32(VendorHeaderSize + TagHeaderSize + ContentsSize);
  Streamer.emitBytes(CurrentVendor);
  Streamer.emitInt8(0); // '\0'

  Streamer.emitInt8(ARMBuildAttrs::File);
  Streamer.emitInt32(TagHeaderSize + ContentsSize);

  // Size should have been accounted for already, now
  // emit each field as its type (ULEB or String)
  for (size_t i = 0; i < Contents.size(); ++i) {
    AttributeItem item = Contents[i];
    Streamer.emitULEB128IntValue(item.Tag);
    switch (item.Type) {
    default: llvm_unreachable("Invalid attribute type");
    case AttributeItem::NumericAttribute:
      Streamer.emitULEB128IntValue(item.IntValue);
      break;
    case AttributeItem::TextAttribute:
      Streamer.emitBytes(item.StringValue);
      Streamer.emitInt8(0); // '\0'
      break;
    case AttributeItem::NumericAndTextAttributes:
      Streamer.emitULEB128IntValue(item.IntValue);
      Streamer.emitBytes(item.StringValue);
      Streamer.emitInt8(0); // '\0'
      break;
    }
  }

  Contents.clear();
  FPU = ARM::FK_INVALID;
}

void ARMTargetELFStreamer::emitLabel(MCSymbol *Symbol) {
  ARMELFStreamer &Streamer = getStreamer();
  if (!Streamer.IsThumb)
    return;

  Streamer.getAssembler().registerSymbol(*Symbol);
  unsigned Type = cast<MCSymbolELF>(Symbol)->getType();
  if (Type == ELF::STT_FUNC || Type == ELF::STT_GNU_IFUNC)
    Streamer.emitThumbFunc(Symbol);
}

void
ARMTargetELFStreamer::AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *S) {
  getStreamer().EmitFixup(S, FK_Data_4);
}

void ARMTargetELFStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) {
  if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Value)) {
    const MCSymbol &Sym = SRE->getSymbol();
    if (!Sym.isDefined()) {
      getStreamer().emitAssignment(Symbol, Value);
      return;
    }
  }

  getStreamer().emitThumbFunc(Symbol);
  getStreamer().emitAssignment(Symbol, Value);
}

void ARMTargetELFStreamer::emitInst(uint32_t Inst, char Suffix) {
  getStreamer().emitInst(Inst, Suffix);
}

void ARMTargetELFStreamer::reset() { AttributeSection = nullptr; }

void ARMELFStreamer::finishImpl() {
  MCTargetStreamer &TS = *getTargetStreamer();
  ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
  ATS.finishAttributeSection();

  MCELFStreamer::finishImpl();
}

void ARMELFStreamer::reset() {
  MCTargetStreamer &TS = *getTargetStreamer();
  ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
  ATS.reset();
  MappingSymbolCounter = 0;
  MCELFStreamer::reset();
  LastMappingSymbols.clear();
  LastEMSInfo.reset();
  // MCELFStreamer clear's the assembler's e_flags. However, for
  // arm we manually set the ABI version on streamer creation, so
  // do the same here
  getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5);
}

inline void ARMELFStreamer::SwitchToEHSection(StringRef Prefix,
                                              unsigned Type,
                                              unsigned Flags,
                                              SectionKind Kind,
                                              const MCSymbol &Fn) {
  const MCSectionELF &FnSection =
    static_cast<const MCSectionELF &>(Fn.getSection());

  // Create the name for new section
  StringRef FnSecName(FnSection.getName());
  SmallString<128> EHSecName(Prefix);
  if (FnSecName != ".text") {
    EHSecName += FnSecName;
  }

  // Get .ARM.extab or .ARM.exidx section
  const MCSymbolELF *Group = FnSection.getGroup();
  if (Group)
    Flags |= ELF::SHF_GROUP;
  MCSectionELF *EHSection = getContext().getELFSection(
      EHSecName, Type, Flags, 0, Group, /*IsComdat=*/true,
      FnSection.getUniqueID(),
      static_cast<const MCSymbolELF *>(FnSection.getBeginSymbol()));

  assert(EHSection && "Failed to get the required EH section");

  // Switch to .ARM.extab or .ARM.exidx section
  SwitchSection(EHSection);
  emitCodeAlignment(4);
}

inline void ARMELFStreamer::SwitchToExTabSection(const MCSymbol &FnStart) {
  SwitchToEHSection(".ARM.extab", ELF::SHT_PROGBITS, ELF::SHF_ALLOC,
                    SectionKind::getData(), FnStart);
}

inline void ARMELFStreamer::SwitchToExIdxSection(const MCSymbol &FnStart) {
  SwitchToEHSection(".ARM.exidx", ELF::SHT_ARM_EXIDX,
                    ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER,
                    SectionKind::getData(), FnStart);
}

void ARMELFStreamer::EmitFixup(const MCExpr *Expr, MCFixupKind Kind) {
  MCDataFragment *Frag = getOrCreateDataFragment();
  Frag->getFixups().push_back(MCFixup::create(Frag->getContents().size(), Expr,
                                              Kind));
}

void ARMELFStreamer::EHReset() {
  ExTab = nullptr;
  FnStart = nullptr;
  Personality = nullptr;
  PersonalityIndex = ARM::EHABI::NUM_PERSONALITY_INDEX;
  FPReg = ARM::SP;
  FPOffset = 0;
  SPOffset = 0;
  PendingOffset = 0;
  UsedFP = false;
  CantUnwind = false;

  Opcodes.clear();
  UnwindOpAsm.Reset();
}

void ARMELFStreamer::emitFnStart() {
  assert(FnStart == nullptr);
  FnStart = getContext().createTempSymbol();
  emitLabel(FnStart);
}

void ARMELFStreamer::emitFnEnd() {
  assert(FnStart && ".fnstart must precedes .fnend");

  // Emit unwind opcodes if there is no .handlerdata directive
  if (!ExTab && !CantUnwind)
    FlushUnwindOpcodes(true);

  // Emit the exception index table entry
  SwitchToExIdxSection(*FnStart);

  // The EHABI requires a dependency preserving R_ARM_NONE relocation to the
  // personality routine to protect it from an arbitrary platform's static
  // linker garbage collection. We disable this for Android where the unwinder
  // is either dynamically linked or directly references the personality
  // routine.
  if (PersonalityIndex < ARM::EHABI::NUM_PERSONALITY_INDEX && !IsAndroid)
    EmitPersonalityFixup(GetAEABIUnwindPersonalityName(PersonalityIndex));

  const MCSymbolRefExpr *FnStartRef =
    MCSymbolRefExpr::create(FnStart,
                            MCSymbolRefExpr::VK_ARM_PREL31,
                            getContext());

  emitValue(FnStartRef, 4);

  if (CantUnwind) {
    emitInt32(ARM::EHABI::EXIDX_CANTUNWIND);
  } else if (ExTab) {
    // Emit a reference to the unwind opcodes in the ".ARM.extab" section.
    const MCSymbolRefExpr *ExTabEntryRef =
      MCSymbolRefExpr::create(ExTab,
                              MCSymbolRefExpr::VK_ARM_PREL31,
                              getContext());
    emitValue(ExTabEntryRef, 4);
  } else {
    // For the __aeabi_unwind_cpp_pr0, we have to emit the unwind opcodes in
    // the second word of exception index table entry.  The size of the unwind
    // opcodes should always be 4 bytes.
    assert(PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0 &&
           "Compact model must use __aeabi_unwind_cpp_pr0 as personality");
    assert(Opcodes.size() == 4u &&
           "Unwind opcode size for __aeabi_unwind_cpp_pr0 must be equal to 4");
    uint64_t Intval = Opcodes[0] |
                      Opcodes[1] << 8 |
                      Opcodes[2] << 16 |
                      Opcodes[3] << 24;
    emitIntValue(Intval, Opcodes.size());
  }

  // Switch to the section containing FnStart
  SwitchSection(&FnStart->getSection());

  // Clean exception handling frame information
  EHReset();
}

void ARMELFStreamer::emitCantUnwind() { CantUnwind = true; }

// Add the R_ARM_NONE fixup at the same position
void ARMELFStreamer::EmitPersonalityFixup(StringRef Name) {
  const MCSymbol *PersonalitySym = getContext().getOrCreateSymbol(Name);

  const MCSymbolRefExpr *PersonalityRef = MCSymbolRefExpr::create(
      PersonalitySym, MCSymbolRefExpr::VK_ARM_NONE, getContext());

  visitUsedExpr(*PersonalityRef);
  MCDataFragment *DF = getOrCreateDataFragment();
  DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
                                            PersonalityRef,
                                            MCFixup::getKindForSize(4, false)));
}

void ARMELFStreamer::FlushPendingOffset() {
  if (PendingOffset != 0) {
    UnwindOpAsm.EmitSPOffset(-PendingOffset);
    PendingOffset = 0;
  }
}

void ARMELFStreamer::FlushUnwindOpcodes(bool NoHandlerData) {
  // Emit the unwind opcode to restore $sp.
  if (UsedFP) {
    const MCRegisterInfo *MRI = getContext().getRegisterInfo();
    int64_t LastRegSaveSPOffset = SPOffset - PendingOffset;
    UnwindOpAsm.EmitSPOffset(LastRegSaveSPOffset - FPOffset);
    UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg));
  } else {
    FlushPendingOffset();
  }

  // Finalize the unwind opcode sequence
  UnwindOpAsm.Finalize(PersonalityIndex, Opcodes);

  // For compact model 0, we have to emit the unwind opcodes in the .ARM.exidx
  // section.  Thus, we don't have to create an entry in the .ARM.extab
  // section.
  if (NoHandlerData && PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0)
    return;

  // Switch to .ARM.extab section.
  SwitchToExTabSection(*FnStart);

  // Create .ARM.extab label for offset in .ARM.exidx
  assert(!ExTab);
  ExTab = getContext().createTempSymbol();
  emitLabel(ExTab);

  // Emit personality
  if (Personality) {
    const MCSymbolRefExpr *PersonalityRef =
      MCSymbolRefExpr::create(Personality,
                              MCSymbolRefExpr::VK_ARM_PREL31,
                              getContext());

    emitValue(PersonalityRef, 4);
  }

  // Emit unwind opcodes
  assert((Opcodes.size() % 4) == 0 &&
         "Unwind opcode size for __aeabi_cpp_unwind_pr0 must be multiple of 4");
  for (unsigned I = 0; I != Opcodes.size(); I += 4) {
    uint64_t Intval = Opcodes[I] |
                      Opcodes[I + 1] << 8 |
                      Opcodes[I + 2] << 16 |
                      Opcodes[I + 3] << 24;
    emitInt32(Intval);
  }

  // According to ARM EHABI section 9.2, if the __aeabi_unwind_cpp_pr1() or
  // __aeabi_unwind_cpp_pr2() is used, then the handler data must be emitted
  // after the unwind opcodes.  The handler data consists of several 32-bit
  // words, and should be terminated by zero.
  //
  // In case that the .handlerdata directive is not specified by the
  // programmer, we should emit zero to terminate the handler data.
  if (NoHandlerData && !Personality)
    emitInt32(0);
}

void ARMELFStreamer::emitHandlerData() { FlushUnwindOpcodes(false); }

void ARMELFStreamer::emitPersonality(const MCSymbol *Per) {
  Personality = Per;
  UnwindOpAsm.setPersonality(Per);
}

void ARMELFStreamer::emitPersonalityIndex(unsigned Index) {
  assert(Index < ARM::EHABI::NUM_PERSONALITY_INDEX && "invalid index");
  PersonalityIndex = Index;
}

void ARMELFStreamer::emitSetFP(unsigned NewFPReg, unsigned NewSPReg,
                               int64_t Offset) {
  assert((NewSPReg == ARM::SP || NewSPReg == FPReg) &&
         "the operand of .setfp directive should be either $sp or $fp");

  UsedFP = true;
  FPReg = NewFPReg;

  if (NewSPReg == ARM::SP)
    FPOffset = SPOffset + Offset;
  else
    FPOffset += Offset;
}

void ARMELFStreamer::emitMovSP(unsigned Reg, int64_t Offset) {
  assert((Reg != ARM::SP && Reg != ARM::PC) &&
         "the operand of .movsp cannot be either sp or pc");
  assert(FPReg == ARM::SP && "current FP must be SP");

  FlushPendingOffset();

  FPReg = Reg;
  FPOffset = SPOffset + Offset;

  const MCRegisterInfo *MRI = getContext().getRegisterInfo();
  UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg));
}

void ARMELFStreamer::emitPad(int64_t Offset) {
  // Track the change of the $sp offset
  SPOffset -= Offset;

  // To squash multiple .pad directives, we should delay the unwind opcode
  // until the .save, .vsave, .handlerdata, or .fnend directives.
  PendingOffset -= Offset;
}

void ARMELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
                                 bool IsVector) {
  // Collect the registers in the register list
  unsigned Count = 0;
  uint32_t Mask = 0;
  const MCRegisterInfo *MRI = getContext().getRegisterInfo();
  for (size_t i = 0; i < RegList.size(); ++i) {
    unsigned Reg = MRI->getEncodingValue(RegList[i]);
    assert(Reg < (IsVector ? 32U : 16U) && "Register out of range");
    unsigned Bit = (1u << Reg);
    if ((Mask & Bit) == 0) {
      Mask |= Bit;
      ++Count;
    }
  }

  // Track the change the $sp offset: For the .save directive, the
  // corresponding push instruction will decrease the $sp by (4 * Count).
  // For the .vsave directive, the corresponding vpush instruction will
  // decrease $sp by (8 * Count).
  SPOffset -= Count * (IsVector ? 8 : 4);

  // Emit the opcode
  FlushPendingOffset();
  if (IsVector)
    UnwindOpAsm.EmitVFPRegSave(Mask);
  else
    UnwindOpAsm.EmitRegSave(Mask);
}

void ARMELFStreamer::emitUnwindRaw(int64_t Offset,
                                   const SmallVectorImpl<uint8_t> &Opcodes) {
  FlushPendingOffset();
  SPOffset = SPOffset - Offset;
  UnwindOpAsm.EmitRaw(Opcodes);
}

namespace llvm {

MCTargetStreamer *createARMTargetAsmStreamer(MCStreamer &S,
                                             formatted_raw_ostream &OS,
                                             MCInstPrinter *InstPrint,
                                             bool isVerboseAsm) {
  return new ARMTargetAsmStreamer(S, OS, *InstPrint, isVerboseAsm);
}

MCTargetStreamer *createARMNullTargetStreamer(MCStreamer &S) {
  return new ARMTargetStreamer(S);
}

MCTargetStreamer *createARMObjectTargetStreamer(MCStreamer &S,
                                                const MCSubtargetInfo &STI) {
  const Triple &TT = STI.getTargetTriple();
  if (TT.isOSBinFormatELF())
    return new ARMTargetELFStreamer(S);
  return new ARMTargetStreamer(S);
}

MCELFStreamer *createARMELFStreamer(MCContext &Context,
                                    std::unique_ptr<MCAsmBackend> TAB,
                                    std::unique_ptr<MCObjectWriter> OW,
                                    std::unique_ptr<MCCodeEmitter> Emitter,
                                    bool RelaxAll, bool IsThumb,
                                    bool IsAndroid) {
  ARMELFStreamer *S =
      new ARMELFStreamer(Context, std::move(TAB), std::move(OW),
                         std::move(Emitter), IsThumb, IsAndroid);
  // FIXME: This should eventually end up somewhere else where more
  // intelligent flag decisions can be made. For now we are just maintaining
  // the status quo for ARM and setting EF_ARM_EABI_VER5 as the default.
  S->getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5);

  if (RelaxAll)
    S->getAssembler().setRelaxAll(true);
  return S;
}

} // end namespace llvm
