xref: /aosp_15_r20/external/swiftshader/third_party/subzero/src/IceELFStreamer.h (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
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