Home | History | Annotate | Download | only in src
      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 
     37   virtual void writeBytes(llvm::StringRef Bytes) {
     38     for (char c : Bytes) {
     39       write8(c);
     40     }
     41   }
     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 
     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:
     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); }
    102 
    103 private:
    104   Fdstream &Out;
    105 };
    106 
    107 } // end of namespace Ice
    108 
    109 #endif // SUBZERO_SRC_ICEELFSTREAMER_H