Home | History | Annotate | Download | only in src
      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;
     39   intptr_t position() const { return position_; }
     40   void set_position(intptr_t Position) { position_ = Position; }
     41 
     42   FixupKind kind() const { return kind_; }
     43   void set_kind(FixupKind Kind) { kind_ = Kind; }
     44 
     45   RelocOffsetT offset() const;
     46   GlobalString symbol() const;
     47 
     48   static const Constant *NullSymbol;
     49   bool isNullSymbol() const { return ConstValue == NullSymbol; }
     50 
     51   static constexpr AssemblerFixup *NoFixup = nullptr;
     52 
     53   bool valueIsSymbol() const { return ValueIsSymbol; }
     54   void set_value(const Constant *Value) {
     55     ValueIsSymbol = false;
     56     ConstValue = Value;
     57   }
     58   void set_value(const ELFSym *Value) {
     59     ValueIsSymbol = true;
     60     SymbolValue = Value;
     61   }
     62   const ELFSym *getSymbolValue() const {
     63     assert(ValueIsSymbol);
     64     return SymbolValue;
     65   }
     66 
     67   void set_addend(RelocOffsetT Addend) { addend_ = 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:
    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