Commit 3e376471 by Nicolas Capens Committed by Nicolas Capens

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/384911Reviewed-by: 's avatarJim Stichnoth <stichnot@chromium.org> Tested-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 8fbddc6b
...@@ -303,7 +303,7 @@ void BrowserCompileServer::startCompileThread(int ObjFD) { ...@@ -303,7 +303,7 @@ void BrowserCompileServer::startCompileThread(int ObjFD) {
EmitStream->SetBufferSize(1 << 14); EmitStream->SetBufferSize(1 << 14);
std::unique_ptr<StringStream> ErrStrm(new StringStream()); std::unique_ptr<StringStream> ErrStrm(new StringStream());
ErrorStream = std::move(ErrStrm); ErrorStream = std::move(ErrStrm);
ELFStream.reset(new ELFStreamer(*EmitStream.get())); ELFStream.reset(new ELFFileStreamer(*EmitStream.get()));
Ctx.reset(new GlobalContext(LogStream.get(), EmitStream.get(), Ctx.reset(new GlobalContext(LogStream.get(), EmitStream.get(),
&ErrorStream->getStream(), ELFStream.get())); &ErrorStream->getStream(), ELFStream.get()));
CompileThread = std::thread([this]() { CompileThread = std::thread([this]() {
......
...@@ -208,7 +208,7 @@ void CLCompileServer::run() { ...@@ -208,7 +208,7 @@ void CLCompileServer::run() {
<< ":\n" << EC.message() << "\n"; << ":\n" << EC.message() << "\n";
return transferErrorCode(getReturnValue(Ice::EC_Args)); return transferErrorCode(getReturnValue(Ice::EC_Args));
} }
ELFStr.reset(new ELFStreamer(*FdOs.get())); ELFStr.reset(new ELFFileStreamer(*FdOs.get()));
Os.reset(FdOs.release()); Os.reset(FdOs.release());
// NaCl sets st_blksize to 0, and LLVM uses that to pick the default // NaCl sets st_blksize to 0, and LLVM uses that to pick the default
// preferred buffer size. Set to something non-zero. // preferred buffer size. Set to something non-zero.
......
...@@ -57,6 +57,7 @@ template <template <typename> class> class BitVectorTmpl; ...@@ -57,6 +57,7 @@ template <template <typename> class> class BitVectorTmpl;
class Cfg; class Cfg;
class CfgNode; class CfgNode;
class Constant; class Constant;
class ELFFileStreamer;
class ELFObjectWriter; class ELFObjectWriter;
class ELFStreamer; class ELFStreamer;
class FunctionDeclaration; class FunctionDeclaration;
......
...@@ -23,14 +23,22 @@ namespace Ice { ...@@ -23,14 +23,22 @@ namespace Ice {
/// Low level writer that can that can handle ELFCLASS32/64. Little endian only /// Low level writer that can that can handle ELFCLASS32/64. Little endian only
/// for now. /// for now.
class ELFStreamer { class ELFStreamer {
ELFStreamer() = delete;
ELFStreamer(const ELFStreamer &) = delete; ELFStreamer(const ELFStreamer &) = delete;
ELFStreamer &operator=(const ELFStreamer &) = delete; ELFStreamer &operator=(const ELFStreamer &) = delete;
public: 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) { void writeLE16(uint16_t Value) {
write8(uint8_t(Value)); write8(uint8_t(Value));
...@@ -65,20 +73,32 @@ public: ...@@ -65,20 +73,32 @@ public:
writeLE32(Value); writeLE32(Value);
} }
void writeBytes(llvm::StringRef Bytes) { Out << Bytes; }
void writeZeroPadding(SizeT N) { void writeZeroPadding(SizeT N) {
static const char Zeros[16] = {0}; static const char Zeros[16] = {0};
for (SizeT i = 0, e = N / 16; i != e; ++i) 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));
} }
};
/// Implementation of ELFStreamer writing to a file.
class ELFFileStreamer : public ELFStreamer {
ELFFileStreamer() = delete;
ELFFileStreamer(const ELFFileStreamer &) = delete;
ELFFileStreamer &operator=(const ELFFileStreamer &) = delete;
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 { return Out.tell(); } uint64_t tell() const override { return Out.tell(); }
void seek(uint64_t Off) { Out.seek(Off); } void seek(uint64_t Off) override { Out.seek(Off); }
private: private:
Fdstream &Out; Fdstream &Out;
...@@ -86,4 +106,4 @@ private: ...@@ -86,4 +106,4 @@ private:
} // end of namespace Ice } // end of namespace Ice
#endif // SUBZERO_SRC_ICEELFSTREAMER_H #endif // SUBZERO_SRC_ICEELFSTREAMER_H
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment