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