brintos

brintos / llvm-project-archived public Read only

0
0
Text · 49.5 KiB · 94b511a Raw
1512 lines · cpp
1//===- lib/MC/ARMELFStreamer.cpp - ELF Object Output for ARM --------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file assembles .s files and emits ARM ELF .o object files. Different10// from generic ELF streamer in emitting mapping symbols ($a, $t and $d) to11// delimit regions of data and code.12//13//===----------------------------------------------------------------------===//14 15#include "ARMMCTargetDesc.h"16#include "ARMUnwindOpAsm.h"17#include "MCTargetDesc/ARMMCAsmInfo.h"18#include "Utils/ARMBaseInfo.h"19#include "llvm/ADT/DenseMap.h"20#include "llvm/ADT/SmallString.h"21#include "llvm/ADT/SmallVector.h"22#include "llvm/ADT/StringExtras.h"23#include "llvm/ADT/StringRef.h"24#include "llvm/ADT/Twine.h"25#include "llvm/BinaryFormat/ELF.h"26#include "llvm/MC/MCAsmBackend.h"27#include "llvm/MC/MCAsmInfo.h"28#include "llvm/MC/MCAssembler.h"29#include "llvm/MC/MCCodeEmitter.h"30#include "llvm/MC/MCContext.h"31#include "llvm/MC/MCELFObjectWriter.h"32#include "llvm/MC/MCELFStreamer.h"33#include "llvm/MC/MCExpr.h"34#include "llvm/MC/MCFixup.h"35#include "llvm/MC/MCInst.h"36#include "llvm/MC/MCInstPrinter.h"37#include "llvm/MC/MCObjectFileInfo.h"38#include "llvm/MC/MCObjectWriter.h"39#include "llvm/MC/MCRegisterInfo.h"40#include "llvm/MC/MCSection.h"41#include "llvm/MC/MCSectionELF.h"42#include "llvm/MC/MCStreamer.h"43#include "llvm/MC/MCSubtargetInfo.h"44#include "llvm/MC/MCSymbol.h"45#include "llvm/MC/MCSymbolELF.h"46#include "llvm/MC/SectionKind.h"47#include "llvm/Support/ARMBuildAttributes.h"48#include "llvm/Support/ARMEHABI.h"49#include "llvm/Support/Casting.h"50#include "llvm/Support/ErrorHandling.h"51#include "llvm/Support/FormattedStream.h"52#include "llvm/Support/raw_ostream.h"53#include <cassert>54#include <climits>55#include <cstdint>56#include <string>57 58using namespace llvm;59 60static std::string GetAEABIUnwindPersonalityName(unsigned Index) {61  assert(Index < ARM::EHABI::NUM_PERSONALITY_INDEX &&62         "Invalid personality index");63  return (Twine("__aeabi_unwind_cpp_pr") + Twine(Index)).str();64}65 66namespace {67 68class ARMELFStreamer;69 70class ARMTargetAsmStreamer : public ARMTargetStreamer {71  formatted_raw_ostream &OS;72  MCInstPrinter &InstPrinter;73  bool IsVerboseAsm;74 75  void emitFnStart() override;76  void emitFnEnd() override;77  void emitCantUnwind() override;78  void emitPersonality(const MCSymbol *Personality) override;79  void emitPersonalityIndex(unsigned Index) override;80  void emitHandlerData() override;81  void emitSetFP(MCRegister FpReg, MCRegister SpReg,82                 int64_t Offset = 0) override;83  void emitMovSP(MCRegister Reg, int64_t Offset = 0) override;84  void emitPad(int64_t Offset) override;85  void emitRegSave(const SmallVectorImpl<MCRegister> &RegList,86                   bool isVector) override;87  void emitUnwindRaw(int64_t Offset,88                     const SmallVectorImpl<uint8_t> &Opcodes) override;89 90  void switchVendor(StringRef Vendor) override;91  void emitAttribute(unsigned Attribute, unsigned Value) override;92  void emitTextAttribute(unsigned Attribute, StringRef String) override;93  void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,94                            StringRef StringValue) override;95  void emitArch(ARM::ArchKind Arch) override;96  void emitArchExtension(uint64_t ArchExt) override;97  void emitObjectArch(ARM::ArchKind Arch) override;98  void emitFPU(ARM::FPUKind FPU) override;99  void emitInst(uint32_t Inst, char Suffix = '\0') override;100  void finishAttributeSection() override;101 102  void annotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override;103  void emitSyntaxUnified() override;104  void emitCode16() override;105  void emitCode32() override;106  void emitThumbFunc(MCSymbol *Symbol) override;107  void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override;108 109  void emitARMWinCFIAllocStack(unsigned Size, bool Wide) override;110  void emitARMWinCFISaveRegMask(unsigned Mask, bool Wide) override;111  void emitARMWinCFISaveSP(unsigned Reg) override;112  void emitARMWinCFISaveFRegs(unsigned First, unsigned Last) override;113  void emitARMWinCFISaveLR(unsigned Offset) override;114  void emitARMWinCFIPrologEnd(bool Fragment) override;115  void emitARMWinCFINop(bool Wide) override;116  void emitARMWinCFIEpilogStart(unsigned Condition) override;117  void emitARMWinCFIEpilogEnd() override;118  void emitARMWinCFICustom(unsigned Opcode) override;119 120public:121  ARMTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS,122                       MCInstPrinter &InstPrinter);123};124 125ARMTargetAsmStreamer::ARMTargetAsmStreamer(MCStreamer &S,126                                           formatted_raw_ostream &OS,127                                           MCInstPrinter &InstPrinter)128    : ARMTargetStreamer(S), OS(OS), InstPrinter(InstPrinter),129      IsVerboseAsm(S.isVerboseAsm()) {}130 131void ARMTargetAsmStreamer::emitFnStart() { OS << "\t.fnstart\n"; }132void ARMTargetAsmStreamer::emitFnEnd() { OS << "\t.fnend\n"; }133void ARMTargetAsmStreamer::emitCantUnwind() { OS << "\t.cantunwind\n"; }134 135void ARMTargetAsmStreamer::emitPersonality(const MCSymbol *Personality) {136  OS << "\t.personality " << Personality->getName() << '\n';137}138 139void ARMTargetAsmStreamer::emitPersonalityIndex(unsigned Index) {140  OS << "\t.personalityindex " << Index << '\n';141}142 143void ARMTargetAsmStreamer::emitHandlerData() { OS << "\t.handlerdata\n"; }144 145void ARMTargetAsmStreamer::emitSetFP(MCRegister FpReg, MCRegister SpReg,146                                     int64_t Offset) {147  OS << "\t.setfp\t";148  InstPrinter.printRegName(OS, FpReg);149  OS << ", ";150  InstPrinter.printRegName(OS, SpReg);151  if (Offset)152    OS << ", #" << Offset;153  OS << '\n';154}155 156void ARMTargetAsmStreamer::emitMovSP(MCRegister Reg, int64_t Offset) {157  assert((Reg != ARM::SP && Reg != ARM::PC) &&158         "the operand of .movsp cannot be either sp or pc");159 160  OS << "\t.movsp\t";161  InstPrinter.printRegName(OS, Reg);162  if (Offset)163    OS << ", #" << Offset;164  OS << '\n';165}166 167void ARMTargetAsmStreamer::emitPad(int64_t Offset) {168  OS << "\t.pad\t#" << Offset << '\n';169}170 171void ARMTargetAsmStreamer::emitRegSave(172    const SmallVectorImpl<MCRegister> &RegList, bool isVector) {173  assert(RegList.size() && "RegList should not be empty");174  if (isVector)175    OS << "\t.vsave\t{";176  else177    OS << "\t.save\t{";178 179  InstPrinter.printRegName(OS, RegList[0]);180 181  for (unsigned i = 1, e = RegList.size(); i != e; ++i) {182    OS << ", ";183    InstPrinter.printRegName(OS, RegList[i]);184  }185 186  OS << "}\n";187}188 189void ARMTargetAsmStreamer::switchVendor(StringRef Vendor) {}190 191void ARMTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) {192  OS << "\t.eabi_attribute\t" << Attribute << ", " << Twine(Value);193  if (IsVerboseAsm) {194    StringRef Name = ELFAttrs::attrTypeAsString(195        Attribute, ARMBuildAttrs::getARMAttributeTags());196    if (!Name.empty())197      OS << "\t@ " << Name;198  }199  OS << "\n";200}201 202void ARMTargetAsmStreamer::emitTextAttribute(unsigned Attribute,203                                             StringRef String) {204  switch (Attribute) {205  case ARMBuildAttrs::CPU_name:206    OS << "\t.cpu\t" << String.lower();207    break;208  default:209    OS << "\t.eabi_attribute\t" << Attribute << ", \"";210    if (Attribute == ARMBuildAttrs::also_compatible_with)211      OS.write_escaped(String);212    else213      OS << String;214    OS << "\"";215    if (IsVerboseAsm) {216      StringRef Name = ELFAttrs::attrTypeAsString(217          Attribute, ARMBuildAttrs::getARMAttributeTags());218      if (!Name.empty())219        OS << "\t@ " << Name;220    }221    break;222  }223  OS << "\n";224}225 226void ARMTargetAsmStreamer::emitIntTextAttribute(unsigned Attribute,227                                                unsigned IntValue,228                                                StringRef StringValue) {229  switch (Attribute) {230  default: llvm_unreachable("unsupported multi-value attribute in asm mode");231  case ARMBuildAttrs::compatibility:232    OS << "\t.eabi_attribute\t" << Attribute << ", " << IntValue;233    if (!StringValue.empty())234      OS << ", \"" << StringValue << "\"";235    if (IsVerboseAsm)236      OS << "\t@ "237         << ELFAttrs::attrTypeAsString(Attribute,238                                       ARMBuildAttrs::getARMAttributeTags());239    break;240  }241  OS << "\n";242}243 244void ARMTargetAsmStreamer::emitArch(ARM::ArchKind Arch) {245  OS << "\t.arch\t" << ARM::getArchName(Arch) << "\n";246}247 248void ARMTargetAsmStreamer::emitArchExtension(uint64_t ArchExt) {249  OS << "\t.arch_extension\t" << ARM::getArchExtName(ArchExt) << "\n";250}251 252void ARMTargetAsmStreamer::emitObjectArch(ARM::ArchKind Arch) {253  OS << "\t.object_arch\t" << ARM::getArchName(Arch) << '\n';254}255 256void ARMTargetAsmStreamer::emitFPU(ARM::FPUKind FPU) {257  OS << "\t.fpu\t" << ARM::getFPUName(FPU) << "\n";258}259 260void ARMTargetAsmStreamer::finishAttributeSection() {}261 262void ARMTargetAsmStreamer::annotateTLSDescriptorSequence(263    const MCSymbolRefExpr *S) {264  OS << "\t.tlsdescseq\t" << S->getSymbol().getName() << "\n";265}266 267void ARMTargetAsmStreamer::emitSyntaxUnified() { OS << "\t.syntax\tunified\n"; }268 269void ARMTargetAsmStreamer::emitCode16() { OS << "\t.code\t16\n"; }270 271void ARMTargetAsmStreamer::emitCode32() { OS << "\t.code\t32\n"; }272 273void ARMTargetAsmStreamer::emitThumbFunc(MCSymbol *Symbol) {274  const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();275  OS << "\t.thumb_func";276  // Only Mach-O hasSubsectionsViaSymbols()277  if (MAI->hasSubsectionsViaSymbols()) {278    OS << '\t';279    Symbol->print(OS, MAI);280  }281  OS << '\n';282}283 284void ARMTargetAsmStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) {285  const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();286 287  OS << "\t.thumb_set\t";288  Symbol->print(OS, MAI);289  OS << ", ";290  MAI->printExpr(OS, *Value);291  OS << '\n';292}293 294void ARMTargetAsmStreamer::emitInst(uint32_t Inst, char Suffix) {295  OS << "\t.inst";296  if (Suffix)297    OS << "." << Suffix;298  OS << "\t0x" << Twine::utohexstr(Inst) << "\n";299}300 301void ARMTargetAsmStreamer::emitUnwindRaw(int64_t Offset,302                                      const SmallVectorImpl<uint8_t> &Opcodes) {303  OS << "\t.unwind_raw " << Offset;304  for (uint8_t Opcode : Opcodes)305    OS << ", 0x" << Twine::utohexstr(Opcode);306  OS << '\n';307}308 309void ARMTargetAsmStreamer::emitARMWinCFIAllocStack(unsigned Size, bool Wide) {310  if (Wide)311    OS << "\t.seh_stackalloc_w\t" << Size << "\n";312  else313    OS << "\t.seh_stackalloc\t" << Size << "\n";314}315 316static void printRegs(formatted_raw_ostream &OS, ListSeparator &LS, int First,317                      int Last) {318  if (First != Last)319    OS << LS << "r" << First << "-r" << Last;320  else321    OS << LS << "r" << First;322}323 324void ARMTargetAsmStreamer::emitARMWinCFISaveRegMask(unsigned Mask, bool Wide) {325  if (Wide)326    OS << "\t.seh_save_regs_w\t";327  else328    OS << "\t.seh_save_regs\t";329  ListSeparator LS;330  int First = -1;331  OS << "{";332  for (int I = 0; I <= 12; I++) {333    if (Mask & (1 << I)) {334      if (First < 0)335        First = I;336    } else {337      if (First >= 0) {338        printRegs(OS, LS, First, I - 1);339        First = -1;340      }341    }342  }343  if (First >= 0)344    printRegs(OS, LS, First, 12);345  if (Mask & (1 << 14))346    OS << LS << "lr";347  OS << "}\n";348}349 350void ARMTargetAsmStreamer::emitARMWinCFISaveSP(unsigned Reg) {351  OS << "\t.seh_save_sp\tr" << Reg << "\n";352}353 354void ARMTargetAsmStreamer::emitARMWinCFISaveFRegs(unsigned First,355                                                  unsigned Last) {356  if (First != Last)357    OS << "\t.seh_save_fregs\t{d" << First << "-d" << Last << "}\n";358  else359    OS << "\t.seh_save_fregs\t{d" << First << "}\n";360}361 362void ARMTargetAsmStreamer::emitARMWinCFISaveLR(unsigned Offset) {363  OS << "\t.seh_save_lr\t" << Offset << "\n";364}365 366void ARMTargetAsmStreamer::emitARMWinCFIPrologEnd(bool Fragment) {367  if (Fragment)368    OS << "\t.seh_endprologue_fragment\n";369  else370    OS << "\t.seh_endprologue\n";371}372 373void ARMTargetAsmStreamer::emitARMWinCFINop(bool Wide) {374  if (Wide)375    OS << "\t.seh_nop_w\n";376  else377    OS << "\t.seh_nop\n";378}379 380void ARMTargetAsmStreamer::emitARMWinCFIEpilogStart(unsigned Condition) {381  if (Condition == ARMCC::AL)382    OS << "\t.seh_startepilogue\n";383  else384    OS << "\t.seh_startepilogue_cond\t"385       << ARMCondCodeToString(static_cast<ARMCC::CondCodes>(Condition)) << "\n";386}387 388void ARMTargetAsmStreamer::emitARMWinCFIEpilogEnd() {389  OS << "\t.seh_endepilogue\n";390}391 392void ARMTargetAsmStreamer::emitARMWinCFICustom(unsigned Opcode) {393  int I;394  for (I = 3; I > 0; I--)395    if (Opcode & (0xffu << (8 * I)))396      break;397  ListSeparator LS;398  OS << "\t.seh_custom\t";399  for (; I >= 0; I--)400    OS << LS << ((Opcode >> (8 * I)) & 0xff);401  OS << "\n";402}403 404class ARMTargetELFStreamer : public ARMTargetStreamer {405private:406  StringRef CurrentVendor;407  ARM::FPUKind FPU = ARM::FK_INVALID;408  ARM::ArchKind Arch = ARM::ArchKind::INVALID;409  ARM::ArchKind EmittedArch = ARM::ArchKind::INVALID;410 411  MCSection *AttributeSection = nullptr;412 413  void emitArchDefaultAttributes();414  void emitFPUDefaultAttributes();415 416  ARMELFStreamer &getStreamer();417 418  void emitFnStart() override;419  void emitFnEnd() override;420  void emitCantUnwind() override;421  void emitPersonality(const MCSymbol *Personality) override;422  void emitPersonalityIndex(unsigned Index) override;423  void emitHandlerData() override;424  void emitSetFP(MCRegister FpReg, MCRegister SpReg,425                 int64_t Offset = 0) override;426  void emitMovSP(MCRegister Reg, int64_t Offset = 0) override;427  void emitPad(int64_t Offset) override;428  void emitRegSave(const SmallVectorImpl<MCRegister> &RegList,429                   bool isVector) override;430  void emitUnwindRaw(int64_t Offset,431                     const SmallVectorImpl<uint8_t> &Opcodes) override;432 433  void switchVendor(StringRef Vendor) override;434  void emitAttribute(unsigned Attribute, unsigned Value) override;435  void emitTextAttribute(unsigned Attribute, StringRef String) override;436  void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,437                            StringRef StringValue) override;438  void emitArch(ARM::ArchKind Arch) override;439  void emitObjectArch(ARM::ArchKind Arch) override;440  void emitFPU(ARM::FPUKind FPU) override;441  void emitInst(uint32_t Inst, char Suffix = '\0') override;442  void finishAttributeSection() override;443  void emitLabel(MCSymbol *Symbol) override;444 445  void annotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override;446  void emitCode16() override;447  void emitCode32() override;448  void emitThumbFunc(MCSymbol *Symbol) override;449  void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override;450 451  // Reset state between object emissions452  void reset() override;453 454  void finish() override;455 456public:457  ARMTargetELFStreamer(MCStreamer &S)458    : ARMTargetStreamer(S), CurrentVendor("aeabi") {}459};460 461/// Extend the generic ELFStreamer class so that it can emit mapping symbols at462/// the appropriate points in the object files. These symbols are defined in the463/// ARM ELF ABI: infocenter.arm.com/help/topic/com.arm.../IHI0044D_aaelf.pdf.464///465/// In brief: $a, $t or $d should be emitted at the start of each contiguous466/// region of ARM code, Thumb code or data in a section. In practice, this467/// emission does not rely on explicit assembler directives but on inherent468/// properties of the directives doing the emission (e.g. ".byte" is data, "add469/// r0, r0, r0" an instruction).470///471/// As a result this system is orthogonal to the DataRegion infrastructure used472/// by MachO. Beware!473class ARMELFStreamer : public MCELFStreamer {474public:475  friend class ARMTargetELFStreamer;476 477  ARMELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,478                 std::unique_ptr<MCObjectWriter> OW,479                 std::unique_ptr<MCCodeEmitter> Emitter, bool IsThumb,480                 bool IsAndroid)481      : MCELFStreamer(Context, std::move(TAB), std::move(OW),482                      std::move(Emitter)),483        IsThumb(IsThumb), IsAndroid(IsAndroid) {484    EHReset();485  }486 487  ~ARMELFStreamer() override = default;488 489  // ARM exception handling directives490  void emitFnStart();491  void emitFnEnd();492  void emitCantUnwind();493  void emitPersonality(const MCSymbol *Per);494  void emitPersonalityIndex(unsigned index);495  void emitHandlerData();496  void emitSetFP(MCRegister NewFpReg, MCRegister NewSpReg, int64_t Offset = 0);497  void emitMovSP(MCRegister Reg, int64_t Offset = 0);498  void emitPad(int64_t Offset);499  void emitRegSave(const SmallVectorImpl<MCRegister> &RegList, bool isVector);500  void emitUnwindRaw(int64_t Offset, const SmallVectorImpl<uint8_t> &Opcodes);501  void emitFill(const MCExpr &NumBytes, uint64_t FillValue,502                SMLoc Loc) override {503    emitDataMappingSymbol();504    MCObjectStreamer::emitFill(NumBytes, FillValue, Loc);505  }506 507  void changeSection(MCSection *Section, uint32_t Subsection) override {508    LastMappingSymbols[getCurrentSection().first] = std::move(LastEMSInfo);509    MCELFStreamer::changeSection(Section, Subsection);510    auto LastMappingSymbol = LastMappingSymbols.find(Section);511    if (LastMappingSymbol != LastMappingSymbols.end()) {512      LastEMSInfo = std::move(LastMappingSymbol->second);513      return;514    }515    LastEMSInfo.reset(new ElfMappingSymbolInfo);516  }517 518  /// This function is the one used to emit instruction data into the ELF519  /// streamer. We override it to add the appropriate mapping symbol if520  /// necessary.521  void emitInstruction(const MCInst &Inst,522                       const MCSubtargetInfo &STI) override {523    if (IsThumb)524      EmitThumbMappingSymbol();525    else526      EmitARMMappingSymbol();527 528    MCELFStreamer::emitInstruction(Inst, STI);529  }530 531  void emitInst(uint32_t Inst, char Suffix) {532    unsigned Size;533    char Buffer[4];534    const bool LittleEndian = getContext().getAsmInfo()->isLittleEndian();535 536    switch (Suffix) {537    case '\0':538      Size = 4;539 540      assert(!IsThumb);541      EmitARMMappingSymbol();542      for (unsigned II = 0, IE = Size; II != IE; II++) {543        const unsigned I = LittleEndian ? (Size - II - 1) : II;544        Buffer[Size - II - 1] = uint8_t(Inst >> I * CHAR_BIT);545      }546 547      break;548    case 'n':549    case 'w':550      Size = (Suffix == 'n' ? 2 : 4);551 552      assert(IsThumb);553      EmitThumbMappingSymbol();554      // Thumb wide instructions are emitted as a pair of 16-bit words of the555      // appropriate endianness.556      for (unsigned II = 0, IE = Size; II != IE; II = II + 2) {557        const unsigned I0 = LittleEndian ? II + 0 : II + 1;558        const unsigned I1 = LittleEndian ? II + 1 : II + 0;559        Buffer[Size - II - 2] = uint8_t(Inst >> I0 * CHAR_BIT);560        Buffer[Size - II - 1] = uint8_t(Inst >> I1 * CHAR_BIT);561      }562 563      break;564    default:565      llvm_unreachable("Invalid Suffix");566    }567 568    MCELFStreamer::emitBytes(StringRef(Buffer, Size));569  }570 571  /// This is one of the functions used to emit data into an ELF section, so the572  /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if573  /// necessary.574  void emitBytes(StringRef Data) override {575    emitDataMappingSymbol();576    MCELFStreamer::emitBytes(Data);577  }578 579  void FlushPendingMappingSymbol() {580    if (!LastEMSInfo->hasInfo())581      return;582    ElfMappingSymbolInfo *EMS = LastEMSInfo.get();583    emitMappingSymbol("$d", *EMS->F, EMS->Offset);584    EMS->resetInfo();585  }586 587  /// This is one of the functions used to emit data into an ELF section, so the588  /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if589  /// necessary.590  void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override {591    if (const MCSymbolRefExpr *SRE = dyn_cast_or_null<MCSymbolRefExpr>(Value)) {592      if (SRE->getSpecifier() == ARM::S_SBREL && !(Size == 4)) {593        getContext().reportError(Loc, "relocated expression must be 32-bit");594        return;595      }596      getCurrentFragment();597    }598 599    emitDataMappingSymbol();600    MCELFStreamer::emitValueImpl(Value, Size, Loc);601  }602 603  /// If a label is defined before the .type directive sets the label's type604  /// then the label can't be recorded as thumb function when the label is605  /// defined. We override emitSymbolAttribute() which is called as part of the606  /// parsing of .type so that if the symbol has already been defined we can607  /// record the label as Thumb. FIXME: there is a corner case where the state608  /// is changed in between the label definition and the .type directive, this609  /// is not expected to occur in practice and handling it would require the610  /// backend to track IsThumb for every label.611  bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override {612    bool Val = MCELFStreamer::emitSymbolAttribute(Symbol, Attribute);613 614    if (!IsThumb)615      return Val;616 617    unsigned Type = static_cast<MCSymbolELF *>(Symbol)->getType();618    if ((Type == ELF::STT_FUNC || Type == ELF::STT_GNU_IFUNC) &&619        Symbol->isDefined())620      getAssembler().setIsThumbFunc(Symbol);621 622    return Val;623  };624 625  void setIsThumb(bool Val) { IsThumb = Val; }626 627private:628  enum ElfMappingSymbol {629    EMS_None,630    EMS_ARM,631    EMS_Thumb,632    EMS_Data633  };634 635  struct ElfMappingSymbolInfo {636    void resetInfo() {637      F = nullptr;638      Offset = 0;639    }640    bool hasInfo() { return F != nullptr; }641    MCFragment *F = nullptr;642    uint64_t Offset = 0;643    ElfMappingSymbol State = EMS_None;644  };645 646  void emitDataMappingSymbol() {647    if (LastEMSInfo->State == EMS_Data)648      return;649    else if (LastEMSInfo->State == EMS_None) {650      // This is a tentative symbol, it won't really be emitted until it's651      // actually needed.652      ElfMappingSymbolInfo *EMS = LastEMSInfo.get();653      auto *DF = getCurrentFragment();654      if (DF->getKind() != MCFragment::FT_Data)655        return;656      EMS->F = DF;657      EMS->Offset = DF->getFixedSize();658      LastEMSInfo->State = EMS_Data;659      return;660    }661    EmitMappingSymbol("$d");662    LastEMSInfo->State = EMS_Data;663  }664 665  void EmitThumbMappingSymbol() {666    if (LastEMSInfo->State == EMS_Thumb)667      return;668    FlushPendingMappingSymbol();669    EmitMappingSymbol("$t");670    LastEMSInfo->State = EMS_Thumb;671  }672 673  void EmitARMMappingSymbol() {674    if (LastEMSInfo->State == EMS_ARM)675      return;676    FlushPendingMappingSymbol();677    EmitMappingSymbol("$a");678    LastEMSInfo->State = EMS_ARM;679  }680 681  void EmitMappingSymbol(StringRef Name) {682    auto *Symbol =683        static_cast<MCSymbolELF *>(getContext().createLocalSymbol(Name));684    emitLabel(Symbol);685 686    Symbol->setType(ELF::STT_NOTYPE);687    Symbol->setBinding(ELF::STB_LOCAL);688  }689 690  void emitMappingSymbol(StringRef Name, MCFragment &F, uint64_t Offset) {691    auto *Symbol =692        static_cast<MCSymbolELF *>(getContext().createLocalSymbol(Name));693    emitLabelAtPos(Symbol, SMLoc(), F, Offset);694    Symbol->setType(ELF::STT_NOTYPE);695    Symbol->setBinding(ELF::STB_LOCAL);696  }697 698  // Helper functions for ARM exception handling directives699  void EHReset();700 701  // Reset state between object emissions702  void reset() override;703 704  void EmitPersonalityFixup(StringRef Name);705  void FlushPendingOffset();706  void FlushUnwindOpcodes(bool NoHandlerData);707 708  void SwitchToEHSection(StringRef Prefix, unsigned Type, unsigned Flags,709                         SectionKind Kind, const MCSymbol &Fn);710  void SwitchToExTabSection(const MCSymbol &FnStart);711  void SwitchToExIdxSection(const MCSymbol &FnStart);712 713  bool IsThumb;714  bool IsAndroid;715 716  DenseMap<const MCSection *, std::unique_ptr<ElfMappingSymbolInfo>>717      LastMappingSymbols;718 719  std::unique_ptr<ElfMappingSymbolInfo> LastEMSInfo;720 721  // ARM Exception Handling Frame Information722  MCSymbol *ExTab;723  MCSymbol *FnStart;724  const MCSymbol *Personality;725  unsigned PersonalityIndex;726  MCRegister FPReg; // Frame pointer register727  int64_t FPOffset; // Offset: (final frame pointer) - (initial $sp)728  int64_t SPOffset; // Offset: (final $sp) - (initial $sp)729  int64_t PendingOffset; // Offset: (final $sp) - (emitted $sp)730  bool UsedFP;731  bool CantUnwind;732  SmallVector<uint8_t, 64> Opcodes;733  UnwindOpcodeAssembler UnwindOpAsm;734};735 736} // end anonymous namespace737 738ARMELFStreamer &ARMTargetELFStreamer::getStreamer() {739  return static_cast<ARMELFStreamer &>(Streamer);740}741 742void ARMTargetELFStreamer::emitFnStart() { getStreamer().emitFnStart(); }743void ARMTargetELFStreamer::emitFnEnd() { getStreamer().emitFnEnd(); }744void ARMTargetELFStreamer::emitCantUnwind() { getStreamer().emitCantUnwind(); }745 746void ARMTargetELFStreamer::emitPersonality(const MCSymbol *Personality) {747  getStreamer().emitPersonality(Personality);748}749 750void ARMTargetELFStreamer::emitPersonalityIndex(unsigned Index) {751  getStreamer().emitPersonalityIndex(Index);752}753 754void ARMTargetELFStreamer::emitHandlerData() {755  getStreamer().emitHandlerData();756}757 758void ARMTargetELFStreamer::emitSetFP(MCRegister FpReg, MCRegister SpReg,759                                     int64_t Offset) {760  getStreamer().emitSetFP(FpReg, SpReg, Offset);761}762 763void ARMTargetELFStreamer::emitMovSP(MCRegister Reg, int64_t Offset) {764  getStreamer().emitMovSP(Reg, Offset);765}766 767void ARMTargetELFStreamer::emitPad(int64_t Offset) {768  getStreamer().emitPad(Offset);769}770 771void ARMTargetELFStreamer::emitRegSave(772    const SmallVectorImpl<MCRegister> &RegList, bool isVector) {773  getStreamer().emitRegSave(RegList, isVector);774}775 776void ARMTargetELFStreamer::emitUnwindRaw(int64_t Offset,777                                      const SmallVectorImpl<uint8_t> &Opcodes) {778  getStreamer().emitUnwindRaw(Offset, Opcodes);779}780 781void ARMTargetELFStreamer::switchVendor(StringRef Vendor) {782  assert(!Vendor.empty() && "Vendor cannot be empty.");783 784  if (CurrentVendor == Vendor)785    return;786 787  if (!CurrentVendor.empty())788    finishAttributeSection();789 790  assert(getStreamer().Contents.empty() &&791         ".ARM.attributes should be flushed before changing vendor");792  CurrentVendor = Vendor;793 794}795 796void ARMTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) {797  getStreamer().setAttributeItem(Attribute, Value,798                                 /* OverwriteExisting= */ true);799}800 801void ARMTargetELFStreamer::emitTextAttribute(unsigned Attribute,802                                             StringRef Value) {803  getStreamer().setAttributeItem(Attribute, Value,804                                 /* OverwriteExisting= */ true);805}806 807void ARMTargetELFStreamer::emitIntTextAttribute(unsigned Attribute,808                                                unsigned IntValue,809                                                StringRef StringValue) {810  getStreamer().setAttributeItems(Attribute, IntValue, StringValue,811                                  /* OverwriteExisting= */ true);812}813 814void ARMTargetELFStreamer::emitArch(ARM::ArchKind Value) {815  Arch = Value;816}817 818void ARMTargetELFStreamer::emitObjectArch(ARM::ArchKind Value) {819  EmittedArch = Value;820}821 822void ARMTargetELFStreamer::emitArchDefaultAttributes() {823  using namespace ARMBuildAttrs;824  ARMELFStreamer &S = getStreamer();825 826  S.setAttributeItem(CPU_name, ARM::getCPUAttr(Arch), false);827 828  if (EmittedArch == ARM::ArchKind::INVALID)829    S.setAttributeItem(CPU_arch, ARM::getArchAttr(Arch), false);830  else831    S.setAttributeItem(CPU_arch, ARM::getArchAttr(EmittedArch), false);832 833  switch (Arch) {834  case ARM::ArchKind::ARMV4:835    S.setAttributeItem(ARM_ISA_use, Allowed, false);836    break;837 838  case ARM::ArchKind::ARMV4T:839  case ARM::ArchKind::ARMV5T:840  case ARM::ArchKind::XSCALE:841  case ARM::ArchKind::ARMV5TE:842  case ARM::ArchKind::ARMV6:843    S.setAttributeItem(ARM_ISA_use, Allowed, false);844    S.setAttributeItem(THUMB_ISA_use, Allowed, false);845    break;846 847  case ARM::ArchKind::ARMV6T2:848    S.setAttributeItem(ARM_ISA_use, Allowed, false);849    S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false);850    break;851 852  case ARM::ArchKind::ARMV6K:853  case ARM::ArchKind::ARMV6KZ:854    S.setAttributeItem(ARM_ISA_use, Allowed, false);855    S.setAttributeItem(THUMB_ISA_use, Allowed, false);856    S.setAttributeItem(Virtualization_use, AllowTZ, false);857    break;858 859  case ARM::ArchKind::ARMV6M:860    S.setAttributeItem(THUMB_ISA_use, Allowed, false);861    break;862 863  case ARM::ArchKind::ARMV7A:864    S.setAttributeItem(CPU_arch_profile, ApplicationProfile, false);865    S.setAttributeItem(ARM_ISA_use, Allowed, false);866    S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false);867    break;868 869  case ARM::ArchKind::ARMV7R:870    S.setAttributeItem(CPU_arch_profile, RealTimeProfile, false);871    S.setAttributeItem(ARM_ISA_use, Allowed, false);872    S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false);873    break;874 875  case ARM::ArchKind::ARMV7EM:876  case ARM::ArchKind::ARMV7M:877    S.setAttributeItem(CPU_arch_profile, MicroControllerProfile, false);878    S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false);879    break;880 881  case ARM::ArchKind::ARMV8A:882  case ARM::ArchKind::ARMV8_1A:883  case ARM::ArchKind::ARMV8_2A:884  case ARM::ArchKind::ARMV8_3A:885  case ARM::ArchKind::ARMV8_4A:886  case ARM::ArchKind::ARMV8_5A:887  case ARM::ArchKind::ARMV8_6A:888  case ARM::ArchKind::ARMV8_7A:889  case ARM::ArchKind::ARMV8_8A:890  case ARM::ArchKind::ARMV8_9A:891  case ARM::ArchKind::ARMV9A:892  case ARM::ArchKind::ARMV9_1A:893  case ARM::ArchKind::ARMV9_2A:894  case ARM::ArchKind::ARMV9_3A:895  case ARM::ArchKind::ARMV9_4A:896  case ARM::ArchKind::ARMV9_5A:897  case ARM::ArchKind::ARMV9_6A:898  case ARM::ArchKind::ARMV9_7A:899    S.setAttributeItem(CPU_arch_profile, ApplicationProfile, false);900    S.setAttributeItem(ARM_ISA_use, Allowed, false);901    S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false);902    S.setAttributeItem(MPextension_use, Allowed, false);903    S.setAttributeItem(Virtualization_use, AllowTZVirtualization, false);904    break;905 906  case ARM::ArchKind::ARMV8MBaseline:907  case ARM::ArchKind::ARMV8MMainline:908  case ARM::ArchKind::ARMV8_1MMainline:909    S.setAttributeItem(THUMB_ISA_use, AllowThumbDerived, false);910    S.setAttributeItem(CPU_arch_profile, MicroControllerProfile, false);911    break;912 913  case ARM::ArchKind::IWMMXT:914    S.setAttributeItem(ARM_ISA_use, Allowed, false);915    S.setAttributeItem(THUMB_ISA_use, Allowed, false);916    S.setAttributeItem(WMMX_arch, AllowWMMXv1, false);917    break;918 919  case ARM::ArchKind::IWMMXT2:920    S.setAttributeItem(ARM_ISA_use, Allowed, false);921    S.setAttributeItem(THUMB_ISA_use, Allowed, false);922    S.setAttributeItem(WMMX_arch, AllowWMMXv2, false);923    break;924 925  default:926    report_fatal_error("Unknown Arch: " + Twine(ARM::getArchName(Arch)));927    break;928  }929}930 931void ARMTargetELFStreamer::emitFPU(ARM::FPUKind Value) { FPU = Value; }932 933void ARMTargetELFStreamer::emitFPUDefaultAttributes() {934  ARMELFStreamer &S = getStreamer();935 936  switch (FPU) {937  case ARM::FK_VFP:938  case ARM::FK_VFPV2:939    S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv2,940                       /* OverwriteExisting= */ false);941    break;942 943  case ARM::FK_VFPV3:944    S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv3A,945                       /* OverwriteExisting= */ false);946    break;947 948  case ARM::FK_VFPV3_FP16:949    S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv3A,950                       /* OverwriteExisting= */ false);951    S.setAttributeItem(ARMBuildAttrs::FP_HP_extension, ARMBuildAttrs::AllowHPFP,952                       /* OverwriteExisting= */ false);953    break;954 955  case ARM::FK_VFPV3_D16:956    S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv3B,957                       /* OverwriteExisting= */ false);958    break;959 960  case ARM::FK_VFPV3_D16_FP16:961    S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv3B,962                       /* OverwriteExisting= */ false);963    S.setAttributeItem(ARMBuildAttrs::FP_HP_extension, ARMBuildAttrs::AllowHPFP,964                       /* OverwriteExisting= */ false);965    break;966 967  case ARM::FK_VFPV3XD:968    S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv3B,969                       /* OverwriteExisting= */ false);970    break;971  case ARM::FK_VFPV3XD_FP16:972    S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv3B,973                       /* OverwriteExisting= */ false);974    S.setAttributeItem(ARMBuildAttrs::FP_HP_extension, ARMBuildAttrs::AllowHPFP,975                       /* OverwriteExisting= */ false);976    break;977 978  case ARM::FK_VFPV4:979    S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv4A,980                       /* OverwriteExisting= */ false);981    break;982 983  // ABI_HardFP_use is handled in ARMAsmPrinter, so _SP_D16 is treated the same984  // as _D16 here.985  case ARM::FK_FPV4_SP_D16:986  case ARM::FK_VFPV4_D16:987    S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv4B,988                       /* OverwriteExisting= */ false);989    break;990 991  case ARM::FK_FP_ARMV8:992    S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPARMv8A,993                       /* OverwriteExisting= */ false);994    break;995 996  // FPV5_D16 is identical to FP_ARMV8 except for the number of D registers, so997  // uses the FP_ARMV8_D16 build attribute.998  case ARM::FK_FPV5_SP_D16:999  case ARM::FK_FPV5_D16:1000  // FPv5 and FP-ARMv8 have the same instructions, so are modeled as one1001  // FPU, but there are two different names for it depending on the CPU.1002  case ARM::FK_FP_ARMV8_FULLFP16_SP_D16:1003  case ARM::FK_FP_ARMV8_FULLFP16_D16:1004    S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPARMv8B,1005                       /* OverwriteExisting= */ false);1006    break;1007 1008  case ARM::FK_NEON:1009    S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv3A,1010                       /* OverwriteExisting= */ false);1011    S.setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,1012                       ARMBuildAttrs::AllowNeon,1013                       /* OverwriteExisting= */ false);1014    break;1015 1016  case ARM::FK_NEON_FP16:1017    S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv3A,1018                       /* OverwriteExisting= */ false);1019    S.setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,1020                       ARMBuildAttrs::AllowNeon,1021                       /* OverwriteExisting= */ false);1022    S.setAttributeItem(ARMBuildAttrs::FP_HP_extension, ARMBuildAttrs::AllowHPFP,1023                       /* OverwriteExisting= */ false);1024    break;1025 1026  case ARM::FK_NEON_VFPV4:1027    S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv4A,1028                       /* OverwriteExisting= */ false);1029    S.setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,1030                       ARMBuildAttrs::AllowNeon2,1031                       /* OverwriteExisting= */ false);1032    break;1033 1034  case ARM::FK_NEON_FP_ARMV8:1035  case ARM::FK_CRYPTO_NEON_FP_ARMV8:1036    S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPARMv8A,1037                       /* OverwriteExisting= */ false);1038    // 'Advanced_SIMD_arch' must be emitted not here, but within1039    // ARMAsmPrinter::emitAttributes(), depending on hasV8Ops() and hasV8_1a()1040    break;1041 1042  case ARM::FK_SOFTVFP:1043  case ARM::FK_NONE:1044    break;1045 1046  default:1047    report_fatal_error("Unknown FPU: " + Twine(FPU));1048    break;1049  }1050}1051 1052void ARMTargetELFStreamer::finishAttributeSection() {1053  ARMELFStreamer &S = getStreamer();1054 1055  if (FPU != ARM::FK_INVALID)1056    emitFPUDefaultAttributes();1057 1058  if (Arch != ARM::ArchKind::INVALID)1059    emitArchDefaultAttributes();1060 1061  if (S.Contents.empty())1062    return;1063 1064  auto LessTag = [](const MCELFStreamer::AttributeItem &LHS,1065                    const MCELFStreamer::AttributeItem &RHS) -> bool {1066    // The conformance tag must be emitted first when serialised into an1067    // object file. Specifically, the addenda to the ARM ABI states that1068    // (2.3.7.4):1069    //1070    // "To simplify recognition by consumers in the common case of claiming1071    // conformity for the whole file, this tag should be emitted first in a1072    // file-scope sub-subsection of the first public subsection of the1073    // attributes section."1074    //1075    // So it is special-cased in this comparison predicate when the1076    // attributes are sorted in finishAttributeSection().1077    return (RHS.Tag != ARMBuildAttrs::conformance) &&1078           ((LHS.Tag == ARMBuildAttrs::conformance) || (LHS.Tag < RHS.Tag));1079  };1080  llvm::sort(S.Contents, LessTag);1081 1082  S.emitAttributesSection(CurrentVendor, ".ARM.attributes",1083                          ELF::SHT_ARM_ATTRIBUTES, AttributeSection);1084 1085  FPU = ARM::FK_INVALID;1086}1087 1088void ARMTargetELFStreamer::emitLabel(MCSymbol *Symbol) {1089  ARMELFStreamer &Streamer = getStreamer();1090  if (!Streamer.IsThumb)1091    return;1092 1093  Streamer.getAssembler().registerSymbol(*Symbol);1094  unsigned Type = static_cast<MCSymbolELF *>(Symbol)->getType();1095  if (Type == ELF::STT_FUNC || Type == ELF::STT_GNU_IFUNC)1096    emitThumbFunc(Symbol);1097}1098 1099void ARMTargetELFStreamer::annotateTLSDescriptorSequence(1100    const MCSymbolRefExpr *Expr) {1101  getStreamer().addFixup(Expr, FK_Data_4);1102}1103 1104void ARMTargetELFStreamer::emitCode16() { getStreamer().setIsThumb(true); }1105 1106void ARMTargetELFStreamer::emitCode32() { getStreamer().setIsThumb(false); }1107 1108void ARMTargetELFStreamer::emitThumbFunc(MCSymbol *Symbol) {1109  getStreamer().getAssembler().setIsThumbFunc(Symbol);1110  getStreamer().emitSymbolAttribute(Symbol, MCSA_ELF_TypeFunction);1111}1112 1113void ARMTargetELFStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) {1114  if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Value)) {1115    const MCSymbol &Sym = SRE->getSymbol();1116    if (!Sym.isDefined()) {1117      getStreamer().emitAssignment(Symbol, Value);1118      return;1119    }1120  }1121 1122  emitThumbFunc(Symbol);1123  getStreamer().emitAssignment(Symbol, Value);1124}1125 1126void ARMTargetELFStreamer::emitInst(uint32_t Inst, char Suffix) {1127  getStreamer().emitInst(Inst, Suffix);1128}1129 1130void ARMTargetELFStreamer::reset() { AttributeSection = nullptr; }1131 1132void ARMTargetELFStreamer::finish() {1133  ARMTargetStreamer::finish();1134  finishAttributeSection();1135 1136  // The mix of execute-only and non-execute-only at link time is1137  // non-execute-only. To avoid the empty implicitly created .text1138  // section from making the whole .text section non-execute-only, we1139  // mark it execute-only if it is empty and there is at least one1140  // execute-only section in the object.1141  MCContext &Ctx = getContext();1142  auto &Asm = getStreamer().getAssembler();1143  if (any_of(Asm, [](const MCSection &Sec) {1144        return static_cast<const MCSectionELF &>(Sec).getFlags() &1145               ELF::SHF_ARM_PURECODE;1146      })) {1147    auto *Text =1148        static_cast<MCSectionELF *>(Ctx.getObjectFileInfo()->getTextSection());1149    for (auto &F : *Text)1150      if (F.getSize())1151        return;1152    Text->setFlags(Text->getFlags() | ELF::SHF_ARM_PURECODE);1153  }1154}1155 1156void ARMELFStreamer::reset() {1157  MCTargetStreamer &TS = *getTargetStreamer();1158  ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);1159  ATS.reset();1160  MCELFStreamer::reset();1161  LastMappingSymbols.clear();1162  LastEMSInfo.reset();1163  // MCELFStreamer clear's the assembler's e_flags. However, for1164  // arm we manually set the ABI version on streamer creation, so1165  // do the same here1166  getWriter().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5);1167}1168 1169inline void ARMELFStreamer::SwitchToEHSection(StringRef Prefix,1170                                              unsigned Type,1171                                              unsigned Flags,1172                                              SectionKind Kind,1173                                              const MCSymbol &Fn) {1174  const MCSectionELF &FnSection =1175    static_cast<const MCSectionELF &>(Fn.getSection());1176 1177  // Create the name for new section1178  StringRef FnSecName(FnSection.getName());1179  SmallString<128> EHSecName(Prefix);1180  if (FnSecName != ".text") {1181    EHSecName += FnSecName;1182  }1183 1184  // Get .ARM.extab or .ARM.exidx section1185  const MCSymbolELF *Group = FnSection.getGroup();1186  if (Group)1187    Flags |= ELF::SHF_GROUP;1188  MCSectionELF *EHSection = getContext().getELFSection(1189      EHSecName, Type, Flags, 0, Group, /*IsComdat=*/true,1190      FnSection.getUniqueID(),1191      static_cast<const MCSymbolELF *>(FnSection.getBeginSymbol()));1192 1193  assert(EHSection && "Failed to get the required EH section");1194 1195  // Switch to .ARM.extab or .ARM.exidx section1196  switchSection(EHSection);1197  emitValueToAlignment(Align(4), 0, 1, 0);1198}1199 1200inline void ARMELFStreamer::SwitchToExTabSection(const MCSymbol &FnStart) {1201  SwitchToEHSection(".ARM.extab", ELF::SHT_PROGBITS, ELF::SHF_ALLOC,1202                    SectionKind::getData(), FnStart);1203}1204 1205inline void ARMELFStreamer::SwitchToExIdxSection(const MCSymbol &FnStart) {1206  SwitchToEHSection(".ARM.exidx", ELF::SHT_ARM_EXIDX,1207                    ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER,1208                    SectionKind::getData(), FnStart);1209}1210 1211void ARMELFStreamer::EHReset() {1212  ExTab = nullptr;1213  FnStart = nullptr;1214  Personality = nullptr;1215  PersonalityIndex = ARM::EHABI::NUM_PERSONALITY_INDEX;1216  FPReg = ARM::SP;1217  FPOffset = 0;1218  SPOffset = 0;1219  PendingOffset = 0;1220  UsedFP = false;1221  CantUnwind = false;1222 1223  Opcodes.clear();1224  UnwindOpAsm.Reset();1225}1226 1227void ARMELFStreamer::emitFnStart() {1228  assert(FnStart == nullptr);1229  FnStart = getContext().createTempSymbol();1230  emitLabel(FnStart);1231}1232 1233void ARMELFStreamer::emitFnEnd() {1234  assert(FnStart && ".fnstart must precedes .fnend");1235 1236  // Emit unwind opcodes if there is no .handlerdata directive1237  if (!ExTab && !CantUnwind)1238    FlushUnwindOpcodes(true);1239 1240  // Emit the exception index table entry1241  SwitchToExIdxSection(*FnStart);1242 1243  // The EHABI requires a dependency preserving R_ARM_NONE relocation to the1244  // personality routine to protect it from an arbitrary platform's static1245  // linker garbage collection. We disable this for Android where the unwinder1246  // is either dynamically linked or directly references the personality1247  // routine.1248  if (PersonalityIndex < ARM::EHABI::NUM_PERSONALITY_INDEX && !IsAndroid)1249    EmitPersonalityFixup(GetAEABIUnwindPersonalityName(PersonalityIndex));1250 1251  const MCSymbolRefExpr *FnStartRef =1252      MCSymbolRefExpr::create(FnStart, ARM::S_PREL31, getContext());1253 1254  emitValue(FnStartRef, 4);1255 1256  if (CantUnwind) {1257    emitInt32(ARM::EHABI::EXIDX_CANTUNWIND);1258  } else if (ExTab) {1259    // Emit a reference to the unwind opcodes in the ".ARM.extab" section.1260    const MCSymbolRefExpr *ExTabEntryRef =1261        MCSymbolRefExpr::create(ExTab, ARM::S_PREL31, getContext());1262    emitValue(ExTabEntryRef, 4);1263  } else {1264    // For the __aeabi_unwind_cpp_pr0, we have to emit the unwind opcodes in1265    // the second word of exception index table entry.  The size of the unwind1266    // opcodes should always be 4 bytes.1267    assert(PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0 &&1268           "Compact model must use __aeabi_unwind_cpp_pr0 as personality");1269    assert(Opcodes.size() == 4u &&1270           "Unwind opcode size for __aeabi_unwind_cpp_pr0 must be equal to 4");1271    uint64_t Intval = Opcodes[0] |1272                      Opcodes[1] << 8 |1273                      Opcodes[2] << 16 |1274                      Opcodes[3] << 24;1275    emitIntValue(Intval, Opcodes.size());1276  }1277 1278  // Switch to the section containing FnStart1279  switchSection(&FnStart->getSection());1280 1281  // Clean exception handling frame information1282  EHReset();1283}1284 1285void ARMELFStreamer::emitCantUnwind() { CantUnwind = true; }1286 1287// Add the R_ARM_NONE fixup at the same position1288void ARMELFStreamer::EmitPersonalityFixup(StringRef Name) {1289  const MCSymbol *PersonalitySym = getContext().getOrCreateSymbol(Name);1290  visitUsedSymbol(*PersonalitySym);1291 1292  const MCSymbolRefExpr *PersonalityRef =1293      MCSymbolRefExpr::create(PersonalitySym, ARM::S_ARM_NONE, getContext());1294  addFixup(PersonalityRef, FK_Data_4);1295}1296 1297void ARMELFStreamer::FlushPendingOffset() {1298  if (PendingOffset != 0) {1299    UnwindOpAsm.EmitSPOffset(-PendingOffset);1300    PendingOffset = 0;1301  }1302}1303 1304void ARMELFStreamer::FlushUnwindOpcodes(bool NoHandlerData) {1305  // Emit the unwind opcode to restore $sp.1306  if (UsedFP) {1307    const MCRegisterInfo *MRI = getContext().getRegisterInfo();1308    int64_t LastRegSaveSPOffset = SPOffset - PendingOffset;1309    UnwindOpAsm.EmitSPOffset(LastRegSaveSPOffset - FPOffset);1310    UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg));1311  } else {1312    FlushPendingOffset();1313  }1314 1315  // Finalize the unwind opcode sequence1316  UnwindOpAsm.Finalize(PersonalityIndex, Opcodes);1317 1318  // For compact model 0, we have to emit the unwind opcodes in the .ARM.exidx1319  // section.  Thus, we don't have to create an entry in the .ARM.extab1320  // section.1321  if (NoHandlerData && PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0)1322    return;1323 1324  // Switch to .ARM.extab section.1325  SwitchToExTabSection(*FnStart);1326 1327  // Create .ARM.extab label for offset in .ARM.exidx1328  assert(!ExTab);1329  ExTab = getContext().createTempSymbol();1330  emitLabel(ExTab);1331 1332  // Emit personality1333  if (Personality) {1334    const MCSymbolRefExpr *PersonalityRef = MCSymbolRefExpr::create(1335        Personality, uint16_t(ARM::S_PREL31), getContext());1336 1337    emitValue(PersonalityRef, 4);1338  }1339 1340  // Emit unwind opcodes1341  assert((Opcodes.size() % 4) == 0 &&1342         "Unwind opcode size for __aeabi_cpp_unwind_pr0 must be multiple of 4");1343  for (unsigned I = 0; I != Opcodes.size(); I += 4) {1344    uint64_t Intval = Opcodes[I] |1345                      Opcodes[I + 1] << 8 |1346                      Opcodes[I + 2] << 16 |1347                      Opcodes[I + 3] << 24;1348    emitInt32(Intval);1349  }1350 1351  // According to ARM EHABI section 9.2, if the __aeabi_unwind_cpp_pr1() or1352  // __aeabi_unwind_cpp_pr2() is used, then the handler data must be emitted1353  // after the unwind opcodes.  The handler data consists of several 32-bit1354  // words, and should be terminated by zero.1355  //1356  // In case that the .handlerdata directive is not specified by the1357  // programmer, we should emit zero to terminate the handler data.1358  if (NoHandlerData && !Personality)1359    emitInt32(0);1360}1361 1362void ARMELFStreamer::emitHandlerData() { FlushUnwindOpcodes(false); }1363 1364void ARMELFStreamer::emitPersonality(const MCSymbol *Per) {1365  Personality = Per;1366  UnwindOpAsm.setPersonality(Per);1367}1368 1369void ARMELFStreamer::emitPersonalityIndex(unsigned Index) {1370  assert(Index < ARM::EHABI::NUM_PERSONALITY_INDEX && "invalid index");1371  PersonalityIndex = Index;1372}1373 1374void ARMELFStreamer::emitSetFP(MCRegister NewFPReg, MCRegister NewSPReg,1375                               int64_t Offset) {1376  assert((NewSPReg == ARM::SP || NewSPReg == FPReg) &&1377         "the operand of .setfp directive should be either $sp or $fp");1378 1379  UsedFP = true;1380  FPReg = NewFPReg;1381 1382  if (NewSPReg == ARM::SP)1383    FPOffset = SPOffset + Offset;1384  else1385    FPOffset += Offset;1386}1387 1388void ARMELFStreamer::emitMovSP(MCRegister Reg, int64_t Offset) {1389  assert((Reg != ARM::SP && Reg != ARM::PC) &&1390         "the operand of .movsp cannot be either sp or pc");1391  assert(FPReg == ARM::SP && "current FP must be SP");1392 1393  FlushPendingOffset();1394 1395  FPReg = Reg;1396  FPOffset = SPOffset + Offset;1397 1398  const MCRegisterInfo *MRI = getContext().getRegisterInfo();1399  UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg));1400}1401 1402void ARMELFStreamer::emitPad(int64_t Offset) {1403  // Track the change of the $sp offset1404  SPOffset -= Offset;1405 1406  // To squash multiple .pad directives, we should delay the unwind opcode1407  // until the .save, .vsave, .handlerdata, or .fnend directives.1408  PendingOffset -= Offset;1409}1410 1411static std::pair<unsigned, unsigned>1412collectHWRegs(const MCRegisterInfo &MRI, unsigned Idx,1413              const SmallVectorImpl<MCRegister> &RegList, bool IsVector,1414              uint32_t &Mask_) {1415  uint32_t Mask = 0;1416  unsigned Count = 0;1417  while (Idx > 0) {1418    MCRegister Reg = RegList[Idx - 1];1419    if (Reg == ARM::RA_AUTH_CODE)1420      break;1421    unsigned RegEnc = MRI.getEncodingValue(Reg);1422    assert(RegEnc < (IsVector ? 32U : 16U) && "Register out of range");1423    unsigned Bit = (1u << RegEnc);1424    if ((Mask & Bit) == 0) {1425      Mask |= Bit;1426      ++Count;1427    }1428    --Idx;1429  }1430 1431  Mask_ = Mask;1432  return {Idx, Count};1433}1434 1435void ARMELFStreamer::emitRegSave(const SmallVectorImpl<MCRegister> &RegList,1436                                 bool IsVector) {1437  uint32_t Mask;1438  unsigned Idx, Count;1439  const MCRegisterInfo &MRI = *getContext().getRegisterInfo();1440 1441  // Collect the registers in the register list. Issue unwinding instructions in1442  // three parts: ordinary hardware registers, return address authentication1443  // code pseudo register, the rest of the registers. The RA PAC is kept in an1444  // architectural register (usually r12), but we treat it as a special case in1445  // order to distinguish between that register containing RA PAC or a general1446  // value.1447  Idx = RegList.size();1448  while (Idx > 0) {1449    std::tie(Idx, Count) = collectHWRegs(MRI, Idx, RegList, IsVector, Mask);1450    if (Count) {1451      // Track the change the $sp offset: For the .save directive, the1452      // corresponding push instruction will decrease the $sp by (4 * Count).1453      // For the .vsave directive, the corresponding vpush instruction will1454      // decrease $sp by (8 * Count).1455      SPOffset -= Count * (IsVector ? 8 : 4);1456 1457      // Emit the opcode1458      FlushPendingOffset();1459      if (IsVector)1460        UnwindOpAsm.EmitVFPRegSave(Mask);1461      else1462        UnwindOpAsm.EmitRegSave(Mask);1463    } else if (Idx > 0 && RegList[Idx - 1] == ARM::RA_AUTH_CODE) {1464      --Idx;1465      SPOffset -= 4;1466      FlushPendingOffset();1467      UnwindOpAsm.EmitRegSave(0);1468    }1469  }1470}1471 1472void ARMELFStreamer::emitUnwindRaw(int64_t Offset,1473                                   const SmallVectorImpl<uint8_t> &Opcodes) {1474  FlushPendingOffset();1475  SPOffset = SPOffset - Offset;1476  UnwindOpAsm.EmitRaw(Opcodes);1477}1478 1479namespace llvm {1480 1481MCTargetStreamer *createARMTargetAsmStreamer(MCStreamer &S,1482                                             formatted_raw_ostream &OS,1483                                             MCInstPrinter *InstPrint) {1484  return new ARMTargetAsmStreamer(S, OS, *InstPrint);1485}1486 1487MCTargetStreamer *createARMNullTargetStreamer(MCStreamer &S) {1488  return new ARMTargetStreamer(S);1489}1490 1491MCTargetStreamer *createARMObjectTargetELFStreamer(MCStreamer &S) {1492  return new ARMTargetELFStreamer(S);1493}1494 1495MCELFStreamer *createARMELFStreamer(MCContext &Context,1496                                    std::unique_ptr<MCAsmBackend> TAB,1497                                    std::unique_ptr<MCObjectWriter> OW,1498                                    std::unique_ptr<MCCodeEmitter> Emitter,1499                                    bool IsThumb, bool IsAndroid) {1500  ARMELFStreamer *S =1501      new ARMELFStreamer(Context, std::move(TAB), std::move(OW),1502                         std::move(Emitter), IsThumb, IsAndroid);1503  // FIXME: This should eventually end up somewhere else where more1504  // intelligent flag decisions can be made. For now we are just maintaining1505  // the status quo for ARM and setting EF_ARM_EABI_VER5 as the default.1506  S->getWriter().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5);1507 1508  return S;1509}1510 1511} // end namespace llvm1512