• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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