1 //===-- AArch64TargetStreamer.h - AArch64 Target Streamer ------*- C++ -*--===// 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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_LIB_TARGET_AARCH64_MCTARGETDESC_AARCH64TARGETSTREAMER_H 10 #define LLVM_LIB_TARGET_AARCH64_MCTARGETDESC_AARCH64TARGETSTREAMER_H 11 12 #include "AArch64MCExpr.h" 13 #include "llvm/ADT/StringRef.h" 14 #include "llvm/IR/Instructions.h" 15 #include "llvm/MC/MCELFStreamer.h" 16 #include "llvm/MC/MCStreamer.h" 17 #include "llvm/Support/AArch64BuildAttributes.h" 18 #include <cstdint> 19 20 namespace { 21 class AArch64ELFStreamer; 22 } 23 24 namespace llvm { 25 26 class AArch64TargetStreamer : public MCTargetStreamer { 27 public: 28 AArch64TargetStreamer(MCStreamer &S); 29 ~AArch64TargetStreamer() override; 30 31 void finish() override; 32 void emitConstantPools() override; 33 34 /// Callback used to implement the ldr= pseudo. 35 /// Add a new entry to the constant pool for the current section and return an 36 /// MCExpr that can be used to refer to the constant pool location. 37 const MCExpr *addConstantPoolEntry(const MCExpr *, unsigned Size, SMLoc Loc); 38 39 /// Callback used to implement the .ltorg directive. 40 /// Emit contents of constant pool for the current section. 41 void emitCurrentConstantPool(); 42 43 /// Callback used to implement the .note.gnu.property section. 44 void emitNoteSection(unsigned Flags, uint64_t PAuthABIPlatform = -1, 45 uint64_t PAuthABIVersion = -1); 46 47 /// Callback used to emit AUTH expressions (e.g. signed 48 /// personality function pointer). 49 void emitAuthValue(const MCExpr *Expr, uint16_t Discriminator, 50 AArch64PACKey::ID Key, bool HasAddressDiversity); 51 52 /// Callback used to implement the .inst directive. 53 virtual void emitInst(uint32_t Inst); 54 55 /// Callback used to implement the .variant_pcs directive. 56 virtual void emitDirectiveVariantPCS(MCSymbol *Symbol) {}; 57 58 virtual void emitARM64WinCFIAllocStack(unsigned Size) {} 59 virtual void emitARM64WinCFISaveR19R20X(int Offset) {} 60 virtual void emitARM64WinCFISaveFPLR(int Offset) {} 61 virtual void emitARM64WinCFISaveFPLRX(int Offset) {} 62 virtual void emitARM64WinCFISaveReg(unsigned Reg, int Offset) {} 63 virtual void emitARM64WinCFISaveRegX(unsigned Reg, int Offset) {} 64 virtual void emitARM64WinCFISaveRegP(unsigned Reg, int Offset) {} 65 virtual void emitARM64WinCFISaveRegPX(unsigned Reg, int Offset) {} 66 virtual void emitARM64WinCFISaveLRPair(unsigned Reg, int Offset) {} 67 virtual void emitARM64WinCFISaveFReg(unsigned Reg, int Offset) {} 68 virtual void emitARM64WinCFISaveFRegX(unsigned Reg, int Offset) {} 69 virtual void emitARM64WinCFISaveFRegP(unsigned Reg, int Offset) {} 70 virtual void emitARM64WinCFISaveFRegPX(unsigned Reg, int Offset) {} 71 virtual void emitARM64WinCFISetFP() {} 72 virtual void emitARM64WinCFIAddFP(unsigned Size) {} 73 virtual void emitARM64WinCFINop() {} 74 virtual void emitARM64WinCFISaveNext() {} 75 virtual void emitARM64WinCFIPrologEnd() {} 76 virtual void emitARM64WinCFIEpilogStart() {} 77 virtual void emitARM64WinCFIEpilogEnd() {} 78 virtual void emitARM64WinCFITrapFrame() {} 79 virtual void emitARM64WinCFIMachineFrame() {} 80 virtual void emitARM64WinCFIContext() {} 81 virtual void emitARM64WinCFIECContext() {} 82 virtual void emitARM64WinCFIClearUnwoundToCall() {} 83 virtual void emitARM64WinCFIPACSignLR() {} 84 virtual void emitARM64WinCFISaveAnyRegI(unsigned Reg, int Offset) {} 85 virtual void emitARM64WinCFISaveAnyRegIP(unsigned Reg, int Offset) {} 86 virtual void emitARM64WinCFISaveAnyRegD(unsigned Reg, int Offset) {} 87 virtual void emitARM64WinCFISaveAnyRegDP(unsigned Reg, int Offset) {} 88 virtual void emitARM64WinCFISaveAnyRegQ(unsigned Reg, int Offset) {} 89 virtual void emitARM64WinCFISaveAnyRegQP(unsigned Reg, int Offset) {} 90 virtual void emitARM64WinCFISaveAnyRegIX(unsigned Reg, int Offset) {} 91 virtual void emitARM64WinCFISaveAnyRegIPX(unsigned Reg, int Offset) {} 92 virtual void emitARM64WinCFISaveAnyRegDX(unsigned Reg, int Offset) {} 93 virtual void emitARM64WinCFISaveAnyRegDPX(unsigned Reg, int Offset) {} 94 virtual void emitARM64WinCFISaveAnyRegQX(unsigned Reg, int Offset) {} 95 virtual void emitARM64WinCFISaveAnyRegQPX(unsigned Reg, int Offset) {} 96 97 /// Build attributes implementation 98 virtual void 99 emitAtributesSubsection(StringRef VendorName, 100 AArch64BuildAttrs::SubsectionOptional IsOptional, 101 AArch64BuildAttrs::SubsectionType ParameterType); 102 virtual void emitAttribute(StringRef VendorName, unsigned Tag, unsigned Value, 103 std::string String, bool Override); 104 void activateAtributesSubsection(StringRef VendorName); 105 std::unique_ptr<MCELFStreamer::AttributeSubSection> 106 getActiveAtributesSubsection(); 107 std::unique_ptr<MCELFStreamer::AttributeSubSection> 108 getAtributesSubsectionByName(StringRef Name); 109 void 110 insertAttributeInPlace(const MCELFStreamer::AttributeItem &Attr, 111 MCELFStreamer::AttributeSubSection &AttSubSection); 112 113 SmallVector<MCELFStreamer::AttributeSubSection, 64> AttributeSubSections; 114 115 private: 116 std::unique_ptr<AssemblerConstantPools> ConstantPools; 117 }; 118 119 class AArch64TargetELFStreamer : public AArch64TargetStreamer { 120 private: 121 AArch64ELFStreamer &getStreamer(); 122 123 MCSection *AttributeSection = nullptr; 124 125 /// Build attributes implementation 126 void emitAtributesSubsection( 127 StringRef VendorName, AArch64BuildAttrs::SubsectionOptional IsOptional, 128 AArch64BuildAttrs::SubsectionType ParameterType) override; 129 void emitAttribute(StringRef VendorName, unsigned Tag, unsigned Value, 130 std::string String, bool Override = false) override; 131 void emitInst(uint32_t Inst) override; 132 void emitDirectiveVariantPCS(MCSymbol *Symbol) override; 133 void finish() override; 134 135 public: 136 AArch64TargetELFStreamer(MCStreamer &S) : AArch64TargetStreamer(S) {} 137 }; 138 139 class AArch64TargetWinCOFFStreamer : public llvm::AArch64TargetStreamer { 140 private: 141 // True if we are processing SEH directives in an epilogue. 142 bool InEpilogCFI = false; 143 144 // Symbol of the current epilog for which we are processing SEH directives. 145 MCSymbol *CurrentEpilog = nullptr; 146 public: 147 AArch64TargetWinCOFFStreamer(llvm::MCStreamer &S) 148 : AArch64TargetStreamer(S) {} 149 150 // The unwind codes on ARM64 Windows are documented at 151 // https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling 152 void emitARM64WinCFIAllocStack(unsigned Size) override; 153 void emitARM64WinCFISaveR19R20X(int Offset) override; 154 void emitARM64WinCFISaveFPLR(int Offset) override; 155 void emitARM64WinCFISaveFPLRX(int Offset) override; 156 void emitARM64WinCFISaveReg(unsigned Reg, int Offset) override; 157 void emitARM64WinCFISaveRegX(unsigned Reg, int Offset) override; 158 void emitARM64WinCFISaveRegP(unsigned Reg, int Offset) override; 159 void emitARM64WinCFISaveRegPX(unsigned Reg, int Offset) override; 160 void emitARM64WinCFISaveLRPair(unsigned Reg, int Offset) override; 161 void emitARM64WinCFISaveFReg(unsigned Reg, int Offset) override; 162 void emitARM64WinCFISaveFRegX(unsigned Reg, int Offset) override; 163 void emitARM64WinCFISaveFRegP(unsigned Reg, int Offset) override; 164 void emitARM64WinCFISaveFRegPX(unsigned Reg, int Offset) override; 165 void emitARM64WinCFISetFP() override; 166 void emitARM64WinCFIAddFP(unsigned Size) override; 167 void emitARM64WinCFINop() override; 168 void emitARM64WinCFISaveNext() override; 169 void emitARM64WinCFIPrologEnd() override; 170 void emitARM64WinCFIEpilogStart() override; 171 void emitARM64WinCFIEpilogEnd() override; 172 void emitARM64WinCFITrapFrame() override; 173 void emitARM64WinCFIMachineFrame() override; 174 void emitARM64WinCFIContext() override; 175 void emitARM64WinCFIECContext() override; 176 void emitARM64WinCFIClearUnwoundToCall() override; 177 void emitARM64WinCFIPACSignLR() override; 178 void emitARM64WinCFISaveAnyRegI(unsigned Reg, int Offset) override; 179 void emitARM64WinCFISaveAnyRegIP(unsigned Reg, int Offset) override; 180 void emitARM64WinCFISaveAnyRegD(unsigned Reg, int Offset) override; 181 void emitARM64WinCFISaveAnyRegDP(unsigned Reg, int Offset) override; 182 void emitARM64WinCFISaveAnyRegQ(unsigned Reg, int Offset) override; 183 void emitARM64WinCFISaveAnyRegQP(unsigned Reg, int Offset) override; 184 void emitARM64WinCFISaveAnyRegIX(unsigned Reg, int Offset) override; 185 void emitARM64WinCFISaveAnyRegIPX(unsigned Reg, int Offset) override; 186 void emitARM64WinCFISaveAnyRegDX(unsigned Reg, int Offset) override; 187 void emitARM64WinCFISaveAnyRegDPX(unsigned Reg, int Offset) override; 188 void emitARM64WinCFISaveAnyRegQX(unsigned Reg, int Offset) override; 189 void emitARM64WinCFISaveAnyRegQPX(unsigned Reg, int Offset) override; 190 191 private: 192 void emitARM64WinUnwindCode(unsigned UnwindCode, int Reg, int Offset); 193 }; 194 195 MCTargetStreamer * 196 createAArch64ObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI); 197 198 MCTargetStreamer *createAArch64NullTargetStreamer(MCStreamer &S); 199 200 } // end namespace llvm 201 202 #endif 203