| Index: mojo/nacl/nonsfi/irt_pnacl_translator_compile.cc
|
| diff --git a/mojo/nacl/nonsfi/irt_pnacl_translator_compile.cc b/mojo/nacl/nonsfi/irt_pnacl_translator_compile.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..081534f96883b0a09f990477585b76abdbc5b358
|
| --- /dev/null
|
| +++ b/mojo/nacl/nonsfi/irt_pnacl_translator_compile.cc
|
| @@ -0,0 +1,106 @@
|
| +// Copyright 2015 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include <fcntl.h>
|
| +
|
| +#include "base/files/file_util.h"
|
| +#include "base/logging.h"
|
| +#include "mojo/nacl/nonsfi/irt_mojo_nonsfi.h"
|
| +#include "mojo/public/cpp/bindings/string.h"
|
| +#include "mojo/public/cpp/bindings/strong_binding.h"
|
| +#include "mojo/public/cpp/utility/run_loop.h"
|
| +#include "native_client/src/untrusted/irt/irt_dev.h"
|
| +#include "services/nacl/pnacl_compile.mojom.h"
|
| +
|
| +namespace {
|
| +
|
| +// Implements a mojom interface which allows the content handler to communicate
|
| +// with the nexe compiler service.
|
| +class PexeCompilerImpl : public mojo::nacl::PexeCompiler {
|
| + public:
|
| + PexeCompilerImpl(mojo::ScopedMessagePipeHandle handle,
|
| + const struct nacl_irt_pnacl_compile_funcs* funcs)
|
| + : funcs_(funcs), strong_binding_(this, handle.Pass()) {}
|
| + void PexeCompile(const mojo::String& pexe_file_name,
|
| + const mojo::Callback<void(mojo::String)>& callback)
|
| + override {
|
| + base::FilePath obj_file_name;
|
| + if (!CreateTemporaryFile(&obj_file_name))
|
| + LOG(FATAL) << "Could not make temporary object file";
|
| + // TODO(smklein): Use multiple object files to increase parallelism.
|
| + int obj_file_fd = open(obj_file_name.value().c_str(), O_RDWR, O_TRUNC);
|
| +
|
| + if (obj_file_fd < 0)
|
| + LOG(FATAL) << "Could not create temp file for compiled pexe";
|
| +
|
| + // TODO(smklein): Is there a less arbitrary number to choose?
|
| + uint32_t num_threads = 8;
|
| + size_t obj_file_fd_count = 1;
|
| + // Non-SFI mode requries PIC.
|
| + char relocation_model[] = "-relocation-model=pic";
|
| + // Since we are compiling pexes, the bitcode format is 'pnacl'.
|
| + char bitcode_format[] = "-bitcode-format=pnacl";
|
| + char* args[] = { relocation_model, bitcode_format, nullptr };
|
| + size_t argc = 2;
|
| + funcs_->init_callback(num_threads, &obj_file_fd, obj_file_fd_count,
|
| + args, argc);
|
| +
|
| + // Read the pexe using fread, and write the pexe into the callback function.
|
| + size_t buf_size = 0x100000;
|
| + scoped_ptr<char[]> buf(new char[buf_size]);
|
| + FILE* pexe_file_stream = fopen(pexe_file_name.get().c_str(), "r");
|
| + // Once the pexe has been opened, it is no longer needed, so we unlink it.
|
| + if (unlink(pexe_file_name.get().c_str()))
|
| + LOG(FATAL) << "Could not unlink temporary pexe file";
|
| + if (pexe_file_stream == nullptr)
|
| + LOG(FATAL) << "Could not open pexe for reading";
|
| + for (;;) {
|
| + size_t num_bytes_from_pexe = fread(buf.get(), 1, buf_size,
|
| + pexe_file_stream);
|
| + if (ferror(pexe_file_stream)) {
|
| + LOG(FATAL) << "Error reading from pexe file stream";
|
| + }
|
| + if (num_bytes_from_pexe == 0) {
|
| + break;
|
| + }
|
| + funcs_->data_callback(buf.get(), num_bytes_from_pexe);
|
| + }
|
| + buf.reset();
|
| +
|
| + if (fclose(pexe_file_stream))
|
| + LOG(FATAL) << "Failed to close pexe file stream from compiler nexe";
|
| + funcs_->end_callback();
|
| +
|
| + // Return the name of the object file.
|
| + callback.Run(mojo::String(obj_file_name.value()));
|
| + }
|
| + private:
|
| + const struct nacl_irt_pnacl_compile_funcs* funcs_;
|
| + mojo::StrongBinding<mojo::nacl::PexeCompiler> strong_binding_;
|
| +};
|
| +
|
| +void ServeTranslateRequest(const struct nacl_irt_pnacl_compile_funcs* funcs) {
|
| + // Acquire the handle -- this is our mechanism to contact the
|
| + // content handler which called us.
|
| + MojoHandle handle;
|
| + nacl::MojoGetInitialHandle(&handle);
|
| +
|
| + // Convert the MojoHandle into a ScopedMessagePipeHandle, and use that to
|
| + // implement the PexeCompiler interface.
|
| + PexeCompilerImpl impl(
|
| + mojo::ScopedMessagePipeHandle(mojo::MessagePipeHandle(handle)).Pass(),
|
| + funcs);
|
| + mojo::RunLoop::current()->RunUntilIdle();
|
| +}
|
| +
|
| +} // namespace anonymous
|
| +
|
| +namespace nacl {
|
| +
|
| +const struct nacl_irt_private_pnacl_translator_compile
|
| + nacl_irt_private_pnacl_translator_compile = {
|
| + ServeTranslateRequest
|
| +};
|
| +
|
| +} // namespace nacl
|
|
|