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