blob: ad6feb951af4b045c07590d53ac749085117fd09 [file] [log] [blame]
Jan Voung08c3bcd2014-12-01 17:55:16 -08001//===- 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//===----------------------------------------------------------------------===//
Andrew Scull9612d322015-07-06 14:53:25 -07009///
10/// \file
Jim Stichnoth92a6e5b2015-12-02 16:52:44 -080011/// \brief Interface for serializing bits for common ELF types (words, extended
12/// words, etc.), based on the ELF class.
Andrew Scull9612d322015-07-06 14:53:25 -070013///
Jan Voung08c3bcd2014-12-01 17:55:16 -080014//===----------------------------------------------------------------------===//
15
16#ifndef SUBZERO_SRC_ICEELFSTREAMER_H
17#define SUBZERO_SRC_ICEELFSTREAMER_H
18
19#include "IceDefs.h"
20
21namespace Ice {
22
Andrew Scull57e12682015-09-16 11:30:19 -070023/// Low level writer that can that can handle ELFCLASS32/64. Little endian only
24/// for now.
Jan Voung08c3bcd2014-12-01 17:55:16 -080025class ELFStreamer {
Jim Stichnothc6ead202015-02-24 09:30:30 -080026 ELFStreamer(const ELFStreamer &) = delete;
27 ELFStreamer &operator=(const ELFStreamer &) = delete;
28
Jan Voung08c3bcd2014-12-01 17:55:16 -080029public:
Nicolas Capens3e376472016-09-13 11:35:57 -040030 ELFStreamer() = default;
31 virtual ~ELFStreamer() = default;
Jan Voung08c3bcd2014-12-01 17:55:16 -080032
Nicolas Capens3e376472016-09-13 11:35:57 -040033 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 }
Jan Voung08c3bcd2014-12-01 17:55:16 -080042
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
Jan Voung08c3bcd2014-12-01 17:55:16 -080076 void writeZeroPadding(SizeT N) {
77 static const char Zeros[16] = {0};
78
79 for (SizeT i = 0, e = N / 16; i != e; ++i)
Nicolas Capens3e376472016-09-13 11:35:57 -040080 writeBytes(llvm::StringRef(Zeros, 16));
Jan Voung08c3bcd2014-12-01 17:55:16 -080081
Nicolas Capens3e376472016-09-13 11:35:57 -040082 writeBytes(llvm::StringRef(Zeros, N % 16));
Jan Voung08c3bcd2014-12-01 17:55:16 -080083 }
Nicolas Capens3e376472016-09-13 11:35:57 -040084};
Jan Voung08c3bcd2014-12-01 17:55:16 -080085
Nicolas Capens3e376472016-09-13 11:35:57 -040086/// Implementation of ELFStreamer writing to a file.
87class ELFFileStreamer : public ELFStreamer {
88 ELFFileStreamer() = delete;
89 ELFFileStreamer(const ELFFileStreamer &) = delete;
90 ELFFileStreamer &operator=(const ELFFileStreamer &) = delete;
Jan Voung08c3bcd2014-12-01 17:55:16 -080091
Nicolas Capens3e376472016-09-13 11:35:57 -040092public:
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); }
Jan Voung08c3bcd2014-12-01 17:55:16 -0800102
103private:
104 Fdstream &Out;
105};
106
107} // end of namespace Ice
108
Nicolas Capens3e376472016-09-13 11:35:57 -0400109#endif // SUBZERO_SRC_ICEELFSTREAMER_H