1 //===- llvm/MC/MCAsmBackend.h - MC Asm Backend ------------------*- 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_MC_MCASMBACKEND_H 10 #define LLVM_MC_MCASMBACKEND_H 11 12 #include "llvm/ADT/ArrayRef.h" 13 #include "llvm/MC/MCDirectives.h" 14 #include "llvm/MC/MCFixup.h" 15 #include "llvm/Support/Endian.h" 16 #include <cstdint> 17 18 namespace llvm { 19 20 class MCAlignFragment; 21 class MCDwarfCallFrameFragment; 22 class MCDwarfLineAddrFragment; 23 class MCFragment; 24 class MCLEBFragment; 25 class MCRelaxableFragment; 26 class MCSymbol; 27 class MCAssembler; 28 class MCContext; 29 struct MCDwarfFrameInfo; 30 struct MCFixupKindInfo; 31 class MCInst; 32 class MCObjectStreamer; 33 class MCObjectTargetWriter; 34 class MCObjectWriter; 35 class MCSubtargetInfo; 36 class MCValue; 37 class raw_pwrite_stream; 38 class StringRef; 39 class raw_ostream; 40 41 /// Generic interface to target specific assembler backends. 42 class MCAsmBackend { 43 protected: // Can only create subclasses. 44 MCAsmBackend(llvm::endianness Endian, unsigned RelaxFixupKind = MaxFixupKind); 45 46 public: 47 MCAsmBackend(const MCAsmBackend &) = delete; 48 MCAsmBackend &operator=(const MCAsmBackend &) = delete; 49 virtual ~MCAsmBackend(); 50 51 const llvm::endianness Endian; 52 53 /// Fixup kind used for linker relaxation. Currently only used by RISC-V. 54 const unsigned RelaxFixupKind; 55 56 /// Return true if this target might automatically pad instructions and thus 57 /// need to emit padding enable/disable directives around sensative code. allowAutoPadding()58 virtual bool allowAutoPadding() const { return false; } 59 /// Return true if this target allows an unrelaxable instruction to be 60 /// emitted into RelaxableFragment and then we can increase its size in a 61 /// tricky way for optimization. allowEnhancedRelaxation()62 virtual bool allowEnhancedRelaxation() const { return false; } 63 64 /// lifetime management reset()65 virtual void reset() {} 66 67 /// Create a new MCObjectWriter instance for use by the assembler backend to 68 /// emit the final object file. 69 std::unique_ptr<MCObjectWriter> 70 createObjectWriter(raw_pwrite_stream &OS) const; 71 72 /// Create an MCObjectWriter that writes two object files: a .o file which is 73 /// linked into the final program and a .dwo file which is used by debuggers. 74 /// This function is only supported with ELF targets. 75 std::unique_ptr<MCObjectWriter> 76 createDwoObjectWriter(raw_pwrite_stream &OS, raw_pwrite_stream &DwoOS) const; 77 78 virtual std::unique_ptr<MCObjectTargetWriter> 79 createObjectTargetWriter() const = 0; 80 81 /// \name Target Fixup Interfaces 82 /// @{ 83 84 /// Get the number of target specific fixup kinds. 85 virtual unsigned getNumFixupKinds() const = 0; 86 87 /// Map a relocation name used in .reloc to a fixup kind. 88 virtual std::optional<MCFixupKind> getFixupKind(StringRef Name) const; 89 90 /// Get information on a fixup kind. 91 virtual const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const; 92 93 /// Hook to check if a relocation is needed for some target specific reason. shouldForceRelocation(const MCAssembler & Asm,const MCFixup & Fixup,const MCValue & Target,const MCSubtargetInfo * STI)94 virtual bool shouldForceRelocation(const MCAssembler &Asm, 95 const MCFixup &Fixup, 96 const MCValue &Target, 97 const MCSubtargetInfo *STI) { 98 return false; 99 } 100 101 /// Hook to check if extra nop bytes must be inserted for alignment directive. 102 /// For some targets this may be necessary in order to support linker 103 /// relaxation. The number of bytes to insert are returned in Size. shouldInsertExtraNopBytesForCodeAlign(const MCAlignFragment & AF,unsigned & Size)104 virtual bool shouldInsertExtraNopBytesForCodeAlign(const MCAlignFragment &AF, 105 unsigned &Size) { 106 return false; 107 } 108 109 /// Hook which indicates if the target requires a fixup to be generated when 110 /// handling an align directive in an executable section shouldInsertFixupForCodeAlign(MCAssembler & Asm,MCAlignFragment & AF)111 virtual bool shouldInsertFixupForCodeAlign(MCAssembler &Asm, 112 MCAlignFragment &AF) { 113 return false; 114 } 115 evaluateTargetFixup(const MCAssembler & Asm,const MCFixup & Fixup,const MCFragment * DF,const MCValue & Target,const MCSubtargetInfo * STI,uint64_t & Value,bool & WasForced)116 virtual bool evaluateTargetFixup(const MCAssembler &Asm, 117 const MCFixup &Fixup, const MCFragment *DF, 118 const MCValue &Target, 119 const MCSubtargetInfo *STI, uint64_t &Value, 120 bool &WasForced) { 121 llvm_unreachable("Need to implement hook if target has custom fixups"); 122 } 123 handleAddSubRelocations(const MCAssembler & Asm,const MCFragment & F,const MCFixup & Fixup,const MCValue & Target,uint64_t & FixedValue)124 virtual bool handleAddSubRelocations(const MCAssembler &Asm, 125 const MCFragment &F, 126 const MCFixup &Fixup, 127 const MCValue &Target, 128 uint64_t &FixedValue) const { 129 return false; 130 } 131 132 /// Apply the \p Value for given \p Fixup into the provided data fragment, at 133 /// the offset specified by the fixup and following the fixup kind as 134 /// appropriate. Errors (such as an out of range fixup value) should be 135 /// reported via \p Ctx. 136 /// The \p STI is present only for fragments of type MCRelaxableFragment and 137 /// MCDataFragment with hasInstructions() == true. 138 virtual void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, 139 const MCValue &Target, MutableArrayRef<char> Data, 140 uint64_t Value, bool IsResolved, 141 const MCSubtargetInfo *STI) const = 0; 142 143 /// @} 144 145 /// \name Target Relaxation Interfaces 146 /// @{ 147 148 /// Check whether the given instruction may need relaxation. 149 /// 150 /// \param Inst - The instruction to test. 151 /// \param STI - The MCSubtargetInfo in effect when the instruction was 152 /// encoded. mayNeedRelaxation(const MCInst & Inst,const MCSubtargetInfo & STI)153 virtual bool mayNeedRelaxation(const MCInst &Inst, 154 const MCSubtargetInfo &STI) const { 155 return false; 156 } 157 158 /// Target specific predicate for whether a given fixup requires the 159 /// associated instruction to be relaxed. 160 virtual bool fixupNeedsRelaxationAdvanced(const MCAssembler &Asm, 161 const MCFixup &Fixup, bool Resolved, 162 uint64_t Value, 163 const MCRelaxableFragment *DF, 164 const bool WasForced) const; 165 166 /// Simple predicate for targets where !Resolved implies requiring relaxation fixupNeedsRelaxation(const MCFixup & Fixup,uint64_t Value)167 virtual bool fixupNeedsRelaxation(const MCFixup &Fixup, 168 uint64_t Value) const { 169 llvm_unreachable("Needed if mayNeedRelaxation may return true"); 170 } 171 172 /// Relax the instruction in the given fragment to the next wider instruction. 173 /// 174 /// \param [out] Inst The instruction to relax, which is also the relaxed 175 /// instruction. 176 /// \param STI the subtarget information for the associated instruction. relaxInstruction(MCInst & Inst,const MCSubtargetInfo & STI)177 virtual void relaxInstruction(MCInst &Inst, 178 const MCSubtargetInfo &STI) const {}; 179 relaxDwarfLineAddr(const MCAssembler & Asm,MCDwarfLineAddrFragment & DF,bool & WasRelaxed)180 virtual bool relaxDwarfLineAddr(const MCAssembler &Asm, 181 MCDwarfLineAddrFragment &DF, 182 bool &WasRelaxed) const { 183 return false; 184 } 185 relaxDwarfCFA(const MCAssembler & Asm,MCDwarfCallFrameFragment & DF,bool & WasRelaxed)186 virtual bool relaxDwarfCFA(const MCAssembler &Asm, 187 MCDwarfCallFrameFragment &DF, 188 bool &WasRelaxed) const { 189 return false; 190 } 191 192 // Defined by linker relaxation targets to possibly emit LEB128 relocations 193 // and set Value at the relocated location. 194 virtual std::pair<bool, bool> relaxLEB128(const MCAssembler & Asm,MCLEBFragment & LF,int64_t & Value)195 relaxLEB128(const MCAssembler &Asm, MCLEBFragment &LF, int64_t &Value) const { 196 return std::make_pair(false, false); 197 } 198 199 /// @} 200 201 /// Returns the minimum size of a nop in bytes on this target. The assembler 202 /// will use this to emit excess padding in situations where the padding 203 /// required for simple alignment would be less than the minimum nop size. 204 /// getMinimumNopSize()205 virtual unsigned getMinimumNopSize() const { return 1; } 206 207 /// Returns the maximum size of a nop in bytes on this target. 208 /// getMaximumNopSize(const MCSubtargetInfo & STI)209 virtual unsigned getMaximumNopSize(const MCSubtargetInfo &STI) const { 210 return 0; 211 } 212 213 /// Write an (optimal) nop sequence of Count bytes to the given output. If the 214 /// target cannot generate such a sequence, it should return an error. 215 /// 216 /// \return - True on success. 217 virtual bool writeNopData(raw_ostream &OS, uint64_t Count, 218 const MCSubtargetInfo *STI) const = 0; 219 220 /// Give backend an opportunity to finish layout after relaxation finishLayout(MCAssembler const & Asm)221 virtual void finishLayout(MCAssembler const &Asm) const {} 222 223 /// Handle any target-specific assembler flags. By default, do nothing. handleAssemblerFlag(MCAssemblerFlag Flag)224 virtual void handleAssemblerFlag(MCAssemblerFlag Flag) {} 225 226 /// Generate the compact unwind encoding for the CFI instructions. generateCompactUnwindEncoding(const MCDwarfFrameInfo * FI,const MCContext * Ctxt)227 virtual uint64_t generateCompactUnwindEncoding(const MCDwarfFrameInfo *FI, 228 const MCContext *Ctxt) const { 229 return 0; 230 } 231 232 /// Check whether a given symbol has been flagged with MICROMIPS flag. isMicroMips(const MCSymbol * Sym)233 virtual bool isMicroMips(const MCSymbol *Sym) const { 234 return false; 235 } 236 237 bool isDarwinCanonicalPersonality(const MCSymbol *Sym) const; 238 }; 239 240 } // end namespace llvm 241 242 #endif // LLVM_MC_MCASMBACKEND_H 243