Jan Voung | 8acded0 | 2014-09-22 18:02:25 -0700 | [diff] [blame] | 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 | //===----------------------------------------------------------------------===// |
Andrew Scull | 9612d32 | 2015-07-06 14:53:25 -0700 | [diff] [blame] | 9 | /// |
| 10 | /// \file |
Jim Stichnoth | 92a6e5b | 2015-12-02 16:52:44 -0800 | [diff] [blame] | 11 | /// \brief Declares generic fixup types. |
Andrew Scull | 9612d32 | 2015-07-06 14:53:25 -0700 | [diff] [blame] | 12 | /// |
Jan Voung | 8acded0 | 2014-09-22 18:02:25 -0700 | [diff] [blame] | 13 | //===----------------------------------------------------------------------===// |
| 14 | |
| 15 | #ifndef SUBZERO_SRC_ICEFIXUPS_H |
| 16 | #define SUBZERO_SRC_ICEFIXUPS_H |
| 17 | |
Karl Schimpf | d469994 | 2016-04-02 09:55:31 -0700 | [diff] [blame] | 18 | #include "IceClFlags.h" |
Jan Voung | ec27073 | 2015-01-12 17:00:22 -0800 | [diff] [blame] | 19 | #include "IceDefs.h" |
Jim Stichnoth | 467ffe5 | 2016-03-29 15:01:06 -0700 | [diff] [blame] | 20 | #include "IceStringPool.h" |
Jan Voung | 8acded0 | 2014-09-22 18:02:25 -0700 | [diff] [blame] | 21 | |
| 22 | namespace Ice { |
| 23 | |
Andrew Scull | 9612d32 | 2015-07-06 14:53:25 -0700 | [diff] [blame] | 24 | /// Each target and container format has a different namespace of relocations. |
| 25 | /// This holds the specific target+container format's relocation number. |
Andrew Scull | 8072bae | 2015-09-14 16:01:26 -0700 | [diff] [blame] | 26 | using FixupKind = uint32_t; |
Jan Voung | 8acded0 | 2014-09-22 18:02:25 -0700 | [diff] [blame] | 27 | |
Jim Stichnoth | 3e32400 | 2016-03-08 16:18:40 -0800 | [diff] [blame] | 28 | struct ELFSym; |
| 29 | |
Andrew Scull | 9612d32 | 2015-07-06 14:53:25 -0700 | [diff] [blame] | 30 | /// Assembler fixups are positions in generated code/data that hold relocation |
| 31 | /// information that needs to be processed before finalizing the code/data. |
John Porto | d1bd1d3 | 2016-01-26 11:44:01 -0800 | [diff] [blame] | 32 | class AssemblerFixup { |
Jim Stichnoth | c6ead20 | 2015-02-24 09:30:30 -0800 | [diff] [blame] | 33 | AssemblerFixup &operator=(const AssemblerFixup &) = delete; |
| 34 | |
Jan Voung | ec27073 | 2015-01-12 17:00:22 -0800 | [diff] [blame] | 35 | public: |
Jim Stichnoth | eafb56c | 2015-06-22 10:35:22 -0700 | [diff] [blame] | 36 | AssemblerFixup() = default; |
Jim Stichnoth | c6ead20 | 2015-02-24 09:30:30 -0800 | [diff] [blame] | 37 | AssemblerFixup(const AssemblerFixup &) = default; |
Sean Klein | fc707ff | 2016-02-29 16:44:07 -0800 | [diff] [blame] | 38 | virtual ~AssemblerFixup() = default; |
Jim Stichnoth | 3e32400 | 2016-03-08 16:18:40 -0800 | [diff] [blame] | 39 | intptr_t position() const { return position_; } |
| 40 | void set_position(intptr_t Position) { position_ = Position; } |
Jan Voung | ec27073 | 2015-01-12 17:00:22 -0800 | [diff] [blame] | 41 | |
| 42 | FixupKind kind() const { return kind_; } |
| 43 | void set_kind(FixupKind Kind) { kind_ = Kind; } |
| 44 | |
| 45 | RelocOffsetT offset() const; |
Jim Stichnoth | 467ffe5 | 2016-03-29 15:01:06 -0700 | [diff] [blame] | 46 | GlobalString symbol() const; |
Jan Voung | f644a4b | 2015-03-19 11:57:52 -0700 | [diff] [blame] | 47 | |
| 48 | static const Constant *NullSymbol; |
Jim Stichnoth | 3e32400 | 2016-03-08 16:18:40 -0800 | [diff] [blame] | 49 | bool isNullSymbol() const { return ConstValue == NullSymbol; } |
Jan Voung | f644a4b | 2015-03-19 11:57:52 -0700 | [diff] [blame] | 50 | |
David Sehr | aa0b1a1 | 2015-10-27 16:55:40 -0700 | [diff] [blame] | 51 | static constexpr AssemblerFixup *NoFixup = nullptr; |
| 52 | |
Jim Stichnoth | 3e32400 | 2016-03-08 16:18:40 -0800 | [diff] [blame] | 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 | } |
Jan Voung | ec27073 | 2015-01-12 17:00:22 -0800 | [diff] [blame] | 66 | |
John Porto | d1bd1d3 | 2016-01-26 11:44:01 -0800 | [diff] [blame] | 67 | void set_addend(RelocOffsetT Addend) { addend_ = Addend; } |
John Porto | 6e8d3fa | 2016-02-04 10:35:20 -0800 | [diff] [blame] | 68 | RelocOffsetT get_addend() const { return addend_; } |
John Porto | d1bd1d3 | 2016-01-26 11:44:01 -0800 | [diff] [blame] | 69 | |
Karl Schimpf | 2fee2a2 | 2015-10-22 08:19:26 -0700 | [diff] [blame] | 70 | /// Emits fixup, then returns the number of bytes to skip. |
Karl Schimpf | e4289e2 | 2015-10-27 15:16:27 -0700 | [diff] [blame] | 71 | virtual size_t emit(GlobalContext *Ctx, const Assembler &Asm) const; |
Jan Voung | ec27073 | 2015-01-12 17:00:22 -0800 | [diff] [blame] | 72 | |
John Porto | 6e8d3fa | 2016-02-04 10:35:20 -0800 | [diff] [blame] | 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 | |
Jan Voung | ec27073 | 2015-01-12 17:00:22 -0800 | [diff] [blame] | 77 | private: |
Jim Stichnoth | eafb56c | 2015-06-22 10:35:22 -0700 | [diff] [blame] | 78 | intptr_t position_ = 0; |
| 79 | FixupKind kind_ = 0; |
John Porto | d1bd1d3 | 2016-01-26 11:44:01 -0800 | [diff] [blame] | 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; |
Jim Stichnoth | 3e32400 | 2016-03-08 16:18:40 -0800 | [diff] [blame] | 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 | }; |
Jan Voung | 8acded0 | 2014-09-22 18:02:25 -0700 | [diff] [blame] | 91 | }; |
| 92 | |
Karl Schimpf | 2fee2a2 | 2015-10-22 08:19:26 -0700 | [diff] [blame] | 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; |
Karl Schimpf | e4289e2 | 2015-10-27 15:16:27 -0700 | [diff] [blame] | 105 | size_t emit(GlobalContext *Ctx, const Assembler &Asm) const override; |
Karl Schimpf | 2fee2a2 | 2015-10-22 08:19:26 -0700 | [diff] [blame] | 106 | |
| 107 | private: |
| 108 | const std::string Message; |
| 109 | const size_t NumBytes; |
| 110 | }; |
| 111 | |
Andrew Scull | 8072bae | 2015-09-14 16:01:26 -0700 | [diff] [blame] | 112 | using FixupList = std::vector<AssemblerFixup>; |
| 113 | using FixupRefList = std::vector<AssemblerFixup *>; |
Jan Voung | ec27073 | 2015-01-12 17:00:22 -0800 | [diff] [blame] | 114 | |
Jan Voung | 8acded0 | 2014-09-22 18:02:25 -0700 | [diff] [blame] | 115 | } // end of namespace Ice |
| 116 | |
| 117 | #endif // SUBZERO_SRC_ICEFIXUPS_H |