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