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