Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include <fcntl.h> | |
| 6 | |
| 7 #include "base/files/file_util.h" | |
| 8 #include "base/logging.h" | |
| 9 #include "mojo/nacl/nonsfi/irt_mojo_nonsfi.h" | |
| 10 #include "mojo/public/cpp/bindings/string.h" | |
| 11 #include "mojo/public/cpp/bindings/strong_binding.h" | |
| 12 #include "mojo/public/cpp/utility/run_loop.h" | |
| 13 #include "native_client/src/untrusted/irt/irt_dev.h" | |
| 14 #include "services/nacl/pnacl_compile.mojom.h" | |
| 15 | |
| 16 namespace { | |
| 17 | |
| 18 // Implements a mojom interface which allows the content handler to communicate | |
| 19 // with the nexe compiler service. | |
| 20 class PexeCompilerImpl : public mojo::nacl::PexeCompiler { | |
| 21 public: | |
| 22 PexeCompilerImpl(mojo::ScopedMessagePipeHandle handle, | |
| 23 const struct nacl_irt_pnacl_compile_funcs* funcs) | |
| 24 : funcs_(funcs), strong_binding_(this, handle.Pass()) {} | |
| 25 void PexeCompile(const mojo::String& pexe_file_name, | |
| 26 const mojo::Callback<void(mojo::String)>& callback) | |
| 27 override { | |
| 28 base::FilePath obj_file_name; | |
| 29 if (!CreateTemporaryFile(&obj_file_name)) | |
| 30 LOG(FATAL) << "Could not make temporary object file"; | |
| 31 // TODO(smklein): Use multiple object files to increase parallelism. | |
| 32 int obj_file_fd = open(obj_file_name.value().c_str(), O_RDWR, O_TRUNC); | |
| 33 | |
| 34 if (obj_file_fd < 0) | |
| 35 LOG(FATAL) << "Could not create temp file for compiled pexe"; | |
| 36 | |
| 37 // TODO(smklein): Is there a less arbitrary number to choose? | |
| 38 uint32_t num_threads = 8; | |
| 39 size_t obj_file_fd_count = 1; | |
| 40 // Non-SFI mode requries PIC. | |
| 41 char relocation_model[] = "-relocation-model=pic"; | |
| 42 // Since we are compiling pexes, the bitcode format is 'pnacl'. | |
| 43 char bitcode_format[] = "-bitcode-format=pnacl"; | |
| 44 char* args[] = { relocation_model, bitcode_format, nullptr }; | |
| 45 size_t argc = 2; | |
| 46 funcs_->init_callback(num_threads, &obj_file_fd, obj_file_fd_count, | |
| 47 args, argc); | |
| 48 | |
| 49 // Read the pexe using fread, and write the pexe into the callback function. | |
| 50 size_t buf_size = 0x100000; | |
|
Petr Hosek
2015/10/28 23:06:09
Shouldn't this be a global constant i.e. kBufferSi
Sean Klein
2015/10/28 23:21:48
Updated to "static const k_buffer_size"
Petr Hosek
2015/10/28 23:24:00
Chromium style for naming constants is kCamelCase.
Sean Klein
2015/10/28 23:26:35
Ah. I was just trying to match the rest of the var
| |
| 51 scoped_ptr<char[]> buf(new char[buf_size]); | |
| 52 FILE* pexe_file_stream = fopen(pexe_file_name.get().c_str(), "r"); | |
| 53 // Once the pexe has been opened, it is no longer needed, so we unlink it. | |
| 54 if (unlink(pexe_file_name.get().c_str())) | |
| 55 LOG(FATAL) << "Could not unlink temporary pexe file"; | |
| 56 if (pexe_file_stream == nullptr) | |
| 57 LOG(FATAL) << "Could not open pexe for reading"; | |
| 58 for (;;) { | |
| 59 size_t num_bytes_from_pexe = fread(buf.get(), 1, buf_size, | |
| 60 pexe_file_stream); | |
| 61 if (ferror(pexe_file_stream)) { | |
| 62 LOG(FATAL) << "Error reading from pexe file stream"; | |
| 63 } | |
| 64 if (num_bytes_from_pexe == 0) { | |
| 65 break; | |
| 66 } | |
| 67 funcs_->data_callback(buf.get(), num_bytes_from_pexe); | |
| 68 } | |
| 69 buf.reset(); | |
| 70 | |
| 71 if (fclose(pexe_file_stream)) | |
| 72 LOG(FATAL) << "Failed to close pexe file stream from compiler nexe"; | |
| 73 funcs_->end_callback(); | |
| 74 | |
| 75 // Return the name of the object file. | |
| 76 callback.Run(mojo::String(obj_file_name.value())); | |
| 77 } | |
| 78 private: | |
| 79 const struct nacl_irt_pnacl_compile_funcs* funcs_; | |
| 80 mojo::StrongBinding<mojo::nacl::PexeCompiler> strong_binding_; | |
| 81 }; | |
| 82 | |
| 83 void ServeTranslateRequest(const struct nacl_irt_pnacl_compile_funcs* funcs) { | |
| 84 // Acquire the handle -- this is our mechanism to contact the | |
| 85 // content handler which called us. | |
| 86 MojoHandle handle; | |
| 87 nacl::MojoGetInitialHandle(&handle); | |
| 88 | |
| 89 // Convert the MojoHandle into a ScopedMessagePipeHandle, and use that to | |
| 90 // implement the PexeCompiler interface. | |
| 91 PexeCompilerImpl impl( | |
| 92 mojo::ScopedMessagePipeHandle(mojo::MessagePipeHandle(handle)).Pass(), | |
| 93 funcs); | |
| 94 mojo::RunLoop::current()->RunUntilIdle(); | |
| 95 } | |
| 96 | |
| 97 } // namespace anonymous | |
| 98 | |
| 99 namespace nacl { | |
| 100 | |
| 101 const struct nacl_irt_private_pnacl_translator_compile | |
| 102 nacl_irt_private_pnacl_translator_compile = { | |
| 103 ServeTranslateRequest | |
| 104 }; | |
| 105 | |
| 106 } // namespace nacl | |
| OLD | NEW |