Abstract the ELFStreamer class. This enables other implementations, such as streaming to memory instead of a file. BUG=swiftshader:9 Change-Id: I2a780ee67e9bccd157c120b7a0895d9764117464 Reviewed-on: https://chromium-review.googlesource.com/384911 Reviewed-by: Jim Stichnoth <stichnot@chromium.org> Tested-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/IceBrowserCompileServer.cpp b/src/IceBrowserCompileServer.cpp index ab2d69f..5fd1ab1 100644 --- a/src/IceBrowserCompileServer.cpp +++ b/src/IceBrowserCompileServer.cpp
@@ -303,7 +303,7 @@ EmitStream->SetBufferSize(1 << 14); std::unique_ptr<StringStream> ErrStrm(new StringStream()); ErrorStream = std::move(ErrStrm); - ELFStream.reset(new ELFStreamer(*EmitStream.get())); + ELFStream.reset(new ELFFileStreamer(*EmitStream.get())); Ctx.reset(new GlobalContext(LogStream.get(), EmitStream.get(), &ErrorStream->getStream(), ELFStream.get())); CompileThread = std::thread([this]() {
diff --git a/src/IceCompileServer.cpp b/src/IceCompileServer.cpp index 994eae2..f4dacb8 100644 --- a/src/IceCompileServer.cpp +++ b/src/IceCompileServer.cpp
@@ -208,7 +208,7 @@ << ":\n" << EC.message() << "\n"; return transferErrorCode(getReturnValue(Ice::EC_Args)); } - ELFStr.reset(new ELFStreamer(*FdOs.get())); + ELFStr.reset(new ELFFileStreamer(*FdOs.get())); Os.reset(FdOs.release()); // NaCl sets st_blksize to 0, and LLVM uses that to pick the default // preferred buffer size. Set to something non-zero.
diff --git a/src/IceDefs.h b/src/IceDefs.h index 75a69d5..bffbd2d 100644 --- a/src/IceDefs.h +++ b/src/IceDefs.h
@@ -57,6 +57,7 @@ class Cfg; class CfgNode; class Constant; +class ELFFileStreamer; class ELFObjectWriter; class ELFStreamer; class FunctionDeclaration;
diff --git a/src/IceELFStreamer.h b/src/IceELFStreamer.h index a1c9b94..ad6feb9 100644 --- a/src/IceELFStreamer.h +++ b/src/IceELFStreamer.h
@@ -23,14 +23,22 @@ /// Low level writer that can that can handle ELFCLASS32/64. Little endian only /// for now. class ELFStreamer { - ELFStreamer() = delete; ELFStreamer(const ELFStreamer &) = delete; ELFStreamer &operator=(const ELFStreamer &) = delete; public: - explicit ELFStreamer(Fdstream &Out) : Out(Out) {} + ELFStreamer() = default; + virtual ~ELFStreamer() = default; - void write8(uint8_t Value) { Out << char(Value); } + virtual void write8(uint8_t Value) = 0; + virtual uint64_t tell() const = 0; + virtual void seek(uint64_t Off) = 0; + + virtual void writeBytes(llvm::StringRef Bytes) { + for (char c : Bytes) { + write8(c); + } + } void writeLE16(uint16_t Value) { write8(uint8_t(Value)); @@ -65,20 +73,32 @@ writeLE32(Value); } - void writeBytes(llvm::StringRef Bytes) { Out << Bytes; } - void writeZeroPadding(SizeT N) { static const char Zeros[16] = {0}; for (SizeT i = 0, e = N / 16; i != e; ++i) - Out << llvm::StringRef(Zeros, 16); + writeBytes(llvm::StringRef(Zeros, 16)); - Out << llvm::StringRef(Zeros, N % 16); + writeBytes(llvm::StringRef(Zeros, N % 16)); } +}; - uint64_t tell() const { return Out.tell(); } +/// Implementation of ELFStreamer writing to a file. +class ELFFileStreamer : public ELFStreamer { + ELFFileStreamer() = delete; + ELFFileStreamer(const ELFFileStreamer &) = delete; + ELFFileStreamer &operator=(const ELFFileStreamer &) = delete; - void seek(uint64_t Off) { Out.seek(Off); } +public: + explicit ELFFileStreamer(Fdstream &Out) : Out(Out) {} + + void write8(uint8_t Value) override { Out << char(Value); } + + void writeBytes(llvm::StringRef Bytes) override { Out << Bytes; } + + uint64_t tell() const override { return Out.tell(); } + + void seek(uint64_t Off) override { Out.seek(Off); } private: Fdstream &Out; @@ -86,4 +106,4 @@ } // end of namespace Ice -#endif // SUBZERO_SRC_ICEELFSTREAMER_H +#endif // SUBZERO_SRC_ICEELFSTREAMER_H \ No newline at end of file