Jan Voung | 08c3bcd | 2014-12-01 17:55:16 -0800 | [diff] [blame] | 1 | //===- subzero/src/IceELFStreamer.h - Low level ELF writing -----*- 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 Interface for serializing bits for common ELF types (words, extended |
| 12 | /// words, etc.), based on the ELF class. |
Andrew Scull | 9612d32 | 2015-07-06 14:53:25 -0700 | [diff] [blame] | 13 | /// |
Jan Voung | 08c3bcd | 2014-12-01 17:55:16 -0800 | [diff] [blame] | 14 | //===----------------------------------------------------------------------===// |
| 15 | |
| 16 | #ifndef SUBZERO_SRC_ICEELFSTREAMER_H |
| 17 | #define SUBZERO_SRC_ICEELFSTREAMER_H |
| 18 | |
| 19 | #include "IceDefs.h" |
| 20 | |
| 21 | namespace Ice { |
| 22 | |
Andrew Scull | 57e1268 | 2015-09-16 11:30:19 -0700 | [diff] [blame] | 23 | /// Low level writer that can that can handle ELFCLASS32/64. Little endian only |
| 24 | /// for now. |
Jan Voung | 08c3bcd | 2014-12-01 17:55:16 -0800 | [diff] [blame] | 25 | class ELFStreamer { |
Jim Stichnoth | c6ead20 | 2015-02-24 09:30:30 -0800 | [diff] [blame] | 26 | ELFStreamer(const ELFStreamer &) = delete; |
| 27 | ELFStreamer &operator=(const ELFStreamer &) = delete; |
| 28 | |
Jan Voung | 08c3bcd | 2014-12-01 17:55:16 -0800 | [diff] [blame] | 29 | public: |
Nicolas Capens | 3e37647 | 2016-09-13 11:35:57 -0400 | [diff] [blame] | 30 | ELFStreamer() = default; |
| 31 | virtual ~ELFStreamer() = default; |
Jan Voung | 08c3bcd | 2014-12-01 17:55:16 -0800 | [diff] [blame] | 32 | |
Nicolas Capens | 3e37647 | 2016-09-13 11:35:57 -0400 | [diff] [blame] | 33 | virtual void write8(uint8_t Value) = 0; |
| 34 | virtual uint64_t tell() const = 0; |
| 35 | virtual void seek(uint64_t Off) = 0; |
| 36 | |
| 37 | virtual void writeBytes(llvm::StringRef Bytes) { |
| 38 | for (char c : Bytes) { |
| 39 | write8(c); |
| 40 | } |
| 41 | } |
Jan Voung | 08c3bcd | 2014-12-01 17:55:16 -0800 | [diff] [blame] | 42 | |
| 43 | void writeLE16(uint16_t Value) { |
| 44 | write8(uint8_t(Value)); |
| 45 | write8(uint8_t(Value >> 8)); |
| 46 | } |
| 47 | |
| 48 | void writeLE32(uint32_t Value) { |
| 49 | writeLE16(uint16_t(Value)); |
| 50 | writeLE16(uint16_t(Value >> 16)); |
| 51 | } |
| 52 | |
| 53 | void writeLE64(uint64_t Value) { |
| 54 | writeLE32(uint32_t(Value)); |
| 55 | writeLE32(uint32_t(Value >> 32)); |
| 56 | } |
| 57 | |
| 58 | template <bool IsELF64, typename T> void writeAddrOrOffset(T Value) { |
| 59 | if (IsELF64) |
| 60 | writeLE64(Value); |
| 61 | else |
| 62 | writeLE32(Value); |
| 63 | } |
| 64 | |
| 65 | template <bool IsELF64, typename T> void writeELFWord(T Value) { |
| 66 | writeLE32(Value); |
| 67 | } |
| 68 | |
| 69 | template <bool IsELF64, typename T> void writeELFXword(T Value) { |
| 70 | if (IsELF64) |
| 71 | writeLE64(Value); |
| 72 | else |
| 73 | writeLE32(Value); |
| 74 | } |
| 75 | |
Jan Voung | 08c3bcd | 2014-12-01 17:55:16 -0800 | [diff] [blame] | 76 | void writeZeroPadding(SizeT N) { |
| 77 | static const char Zeros[16] = {0}; |
| 78 | |
| 79 | for (SizeT i = 0, e = N / 16; i != e; ++i) |
Nicolas Capens | 3e37647 | 2016-09-13 11:35:57 -0400 | [diff] [blame] | 80 | writeBytes(llvm::StringRef(Zeros, 16)); |
Jan Voung | 08c3bcd | 2014-12-01 17:55:16 -0800 | [diff] [blame] | 81 | |
Nicolas Capens | 3e37647 | 2016-09-13 11:35:57 -0400 | [diff] [blame] | 82 | writeBytes(llvm::StringRef(Zeros, N % 16)); |
Jan Voung | 08c3bcd | 2014-12-01 17:55:16 -0800 | [diff] [blame] | 83 | } |
Nicolas Capens | 3e37647 | 2016-09-13 11:35:57 -0400 | [diff] [blame] | 84 | }; |
Jan Voung | 08c3bcd | 2014-12-01 17:55:16 -0800 | [diff] [blame] | 85 | |
Nicolas Capens | 3e37647 | 2016-09-13 11:35:57 -0400 | [diff] [blame] | 86 | /// Implementation of ELFStreamer writing to a file. |
| 87 | class ELFFileStreamer : public ELFStreamer { |
| 88 | ELFFileStreamer() = delete; |
| 89 | ELFFileStreamer(const ELFFileStreamer &) = delete; |
| 90 | ELFFileStreamer &operator=(const ELFFileStreamer &) = delete; |
Jan Voung | 08c3bcd | 2014-12-01 17:55:16 -0800 | [diff] [blame] | 91 | |
Nicolas Capens | 3e37647 | 2016-09-13 11:35:57 -0400 | [diff] [blame] | 92 | public: |
| 93 | explicit ELFFileStreamer(Fdstream &Out) : Out(Out) {} |
| 94 | |
| 95 | void write8(uint8_t Value) override { Out << char(Value); } |
| 96 | |
| 97 | void writeBytes(llvm::StringRef Bytes) override { Out << Bytes; } |
| 98 | |
| 99 | uint64_t tell() const override { return Out.tell(); } |
| 100 | |
| 101 | void seek(uint64_t Off) override { Out.seek(Off); } |
Jan Voung | 08c3bcd | 2014-12-01 17:55:16 -0800 | [diff] [blame] | 102 | |
| 103 | private: |
| 104 | Fdstream &Out; |
| 105 | }; |
| 106 | |
| 107 | } // end of namespace Ice |
| 108 | |
Nicolas Capens | 3e37647 | 2016-09-13 11:35:57 -0400 | [diff] [blame] | 109 | #endif // SUBZERO_SRC_ICEELFSTREAMER_H |