• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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