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 |
| 11 | /// Interface for serializing bits for common ELF types (words, extended words, |
| 12 | /// etc.), based on the ELF Class. |
| 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 | 9612d32 | 2015-07-06 14:53:25 -0700 | [diff] [blame] | 23 | /// Low level writer that can that can handle ELFCLASS32/64. |
| 24 | /// Little endian only 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() = delete; |
| 27 | ELFStreamer(const ELFStreamer &) = delete; |
| 28 | ELFStreamer &operator=(const ELFStreamer &) = delete; |
| 29 | |
Jan Voung | 08c3bcd | 2014-12-01 17:55:16 -0800 | [diff] [blame] | 30 | public: |
| 31 | explicit ELFStreamer(Fdstream &Out) : Out(Out) {} |
| 32 | |
| 33 | void write8(uint8_t Value) { Out << char(Value); } |
| 34 | |
| 35 | void writeLE16(uint16_t Value) { |
| 36 | write8(uint8_t(Value)); |
| 37 | write8(uint8_t(Value >> 8)); |
| 38 | } |
| 39 | |
| 40 | void writeLE32(uint32_t Value) { |
| 41 | writeLE16(uint16_t(Value)); |
| 42 | writeLE16(uint16_t(Value >> 16)); |
| 43 | } |
| 44 | |
| 45 | void writeLE64(uint64_t Value) { |
| 46 | writeLE32(uint32_t(Value)); |
| 47 | writeLE32(uint32_t(Value >> 32)); |
| 48 | } |
| 49 | |
| 50 | template <bool IsELF64, typename T> void writeAddrOrOffset(T Value) { |
| 51 | if (IsELF64) |
| 52 | writeLE64(Value); |
| 53 | else |
| 54 | writeLE32(Value); |
| 55 | } |
| 56 | |
| 57 | template <bool IsELF64, typename T> void writeELFWord(T Value) { |
| 58 | writeLE32(Value); |
| 59 | } |
| 60 | |
| 61 | template <bool IsELF64, typename T> void writeELFXword(T Value) { |
| 62 | if (IsELF64) |
| 63 | writeLE64(Value); |
| 64 | else |
| 65 | writeLE32(Value); |
| 66 | } |
| 67 | |
| 68 | void writeBytes(llvm::StringRef Bytes) { Out << Bytes; } |
| 69 | |
| 70 | void writeZeroPadding(SizeT N) { |
| 71 | static const char Zeros[16] = {0}; |
| 72 | |
| 73 | for (SizeT i = 0, e = N / 16; i != e; ++i) |
| 74 | Out << llvm::StringRef(Zeros, 16); |
| 75 | |
| 76 | Out << llvm::StringRef(Zeros, N % 16); |
| 77 | } |
| 78 | |
| 79 | uint64_t tell() const { return Out.tell(); } |
| 80 | |
| 81 | void seek(uint64_t Off) { Out.seek(Off); } |
| 82 | |
| 83 | private: |
| 84 | Fdstream &Out; |
| 85 | }; |
| 86 | |
| 87 | } // end of namespace Ice |
| 88 | |
| 89 | #endif // SUBZERO_SRC_ICEELFSTREAMER_H |