1 //===- subzero/src/IceFixups.h - Assembler fixup kinds ----------*- C++ -*-===// 2 // 3 // The Subzero Code Generator 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// 10 /// \file 11 /// \brief Declares generic fixup types. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #ifndef SUBZERO_SRC_ICEFIXUPS_H 16 #define SUBZERO_SRC_ICEFIXUPS_H 17 18 #include "IceClFlags.h" 19 #include "IceDefs.h" 20 #include "IceStringPool.h" 21 22 namespace Ice { 23 24 /// Each target and container format has a different namespace of relocations. 25 /// This holds the specific target+container format's relocation number. 26 using FixupKind = uint32_t; 27 28 struct ELFSym; 29 30 /// Assembler fixups are positions in generated code/data that hold relocation 31 /// information that needs to be processed before finalizing the code/data. 32 class AssemblerFixup { 33 AssemblerFixup &operator=(const AssemblerFixup &) = delete; 34 35 public: 36 AssemblerFixup() = default; 37 AssemblerFixup(const AssemblerFixup &) = default; 38 virtual ~AssemblerFixup() = default; position()39 intptr_t position() const { return position_; } set_position(intptr_t Position)40 void set_position(intptr_t Position) { position_ = Position; } 41 kind()42 FixupKind kind() const { return kind_; } set_kind(FixupKind Kind)43 void set_kind(FixupKind Kind) { kind_ = Kind; } 44 45 RelocOffsetT offset() const; 46 GlobalString symbol() const; 47 48 static const Constant *NullSymbol; isNullSymbol()49 bool isNullSymbol() const { return ConstValue == NullSymbol; } 50 51 static constexpr AssemblerFixup *NoFixup = nullptr; 52 valueIsSymbol()53 bool valueIsSymbol() const { return ValueIsSymbol; } set_value(const Constant * Value)54 void set_value(const Constant *Value) { 55 ValueIsSymbol = false; 56 ConstValue = Value; 57 } set_value(const ELFSym * Value)58 void set_value(const ELFSym *Value) { 59 ValueIsSymbol = true; 60 SymbolValue = Value; 61 } getSymbolValue()62 const ELFSym *getSymbolValue() const { 63 assert(ValueIsSymbol); 64 return SymbolValue; 65 } 66 set_addend(RelocOffsetT Addend)67 void set_addend(RelocOffsetT Addend) { addend_ = Addend; } get_addend()68 RelocOffsetT get_addend() const { return addend_; } 69 70 /// Emits fixup, then returns the number of bytes to skip. 71 virtual size_t emit(GlobalContext *Ctx, const Assembler &Asm) const; 72 73 /// Emits offset() (little endian) in position_. If your fixup requires 74 /// something smarter, you must create your own fixup type. 75 virtual void emitOffset(Assembler *Asm) const; 76 77 private: 78 intptr_t position_ = 0; 79 FixupKind kind_ = 0; 80 // An offset addend to the fixup offset (as returned by offset()), in case the 81 // assembler needs to adjust it. 82 RelocOffsetT addend_ = 0; 83 84 // Tagged union that holds either a Constant or ELFSym pointer, depending on 85 // the ValueIsSymbol tag. 86 bool ValueIsSymbol = false; 87 union { 88 const Constant *ConstValue; 89 const ELFSym *SymbolValue; 90 }; 91 }; 92 93 /// Extends a fixup to be textual. That is, it emits text instead of a sequence 94 /// of bytes. This class is used as a fallback for unimplemented emitIAS 95 /// methods, allowing them to generate compilable assembly code. 96 class AssemblerTextFixup : public AssemblerFixup { 97 AssemblerTextFixup() = delete; 98 AssemblerTextFixup(const AssemblerTextFixup &) = delete; 99 AssemblerTextFixup &operator=(const AssemblerTextFixup &) = delete; 100 101 public: AssemblerTextFixup(const std::string & Message,size_t NumBytes)102 AssemblerTextFixup(const std::string &Message, size_t NumBytes) 103 : AssemblerFixup(), Message(Message), NumBytes(NumBytes) {} 104 ~AssemblerTextFixup() = default; 105 size_t emit(GlobalContext *Ctx, const Assembler &Asm) const override; 106 107 private: 108 const std::string Message; 109 const size_t NumBytes; 110 }; 111 112 using FixupList = std::vector<AssemblerFixup>; 113 using FixupRefList = std::vector<AssemblerFixup *>; 114 115 } // end of namespace Ice 116 117 #endif // SUBZERO_SRC_ICEFIXUPS_H 118