| // 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/array.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/nonsfi/pnacl_link.mojom.h" |
| |
| namespace { |
| |
| typedef int (*LinkerCallback)(int, const int*, int); |
| |
| class PexeLinkerImpl : public mojo::nacl::PexeLinker { |
| public: |
| PexeLinkerImpl(mojo::ScopedMessagePipeHandle handle, LinkerCallback func) |
| : func_(func), strong_binding_(this, handle.Pass()) {} |
| void PexeLink(mojo::Array<mojo::String> obj_file_names, |
| const mojo::Callback<void(mojo::String)>& callback) |
| override { |
| // Create a temporary .nexe file which will be the result of calling our |
| // linker. |
| base::FilePath nexe_file_name; |
| CHECK(CreateTemporaryFile(&nexe_file_name)) |
| << "Could not create temporary nexe file"; |
| int nexe_file_fd = open(nexe_file_name.value().c_str(), O_RDWR); |
| CHECK_GE(nexe_file_fd, 0) << "Could not create temp file for linked nexe"; |
| |
| // Open our temporary object file. Additionally, unlink it, since it is a |
| // temporary file that is no longer needed after it is opened. |
| size_t obj_file_fd_count = obj_file_names.size(); |
| int obj_file_fds[obj_file_fd_count]; |
| for (size_t i = 0; i < obj_file_fd_count; i++) { |
| obj_file_fds[i] = open(obj_file_names[i].get().c_str(), O_RDONLY); |
| CHECK(!unlink(obj_file_names[i].get().c_str())) |
| << "Could not unlink temporary object file"; |
| CHECK_GE(obj_file_fds[i], 0) << "Could not open object file"; |
| } |
| |
| CHECK(!func_(nexe_file_fd, obj_file_fds, obj_file_fd_count)) |
| << "Error calling func on object file"; |
| |
| // Return the name of the nexe file. |
| callback.Run(mojo::String(nexe_file_name.value())); |
| mojo::RunLoop::current()->Quit(); |
| } |
| private: |
| LinkerCallback func_; |
| mojo::StrongBinding<mojo::nacl::PexeLinker> strong_binding_; |
| }; |
| |
| void ServeLinkRequest(LinkerCallback func) { |
| // 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 PexeLinker interface. |
| PexeLinkerImpl impl( |
| mojo::ScopedMessagePipeHandle(mojo::MessagePipeHandle(handle)).Pass(), |
| func); |
| mojo::RunLoop::current()->Run(); |
| } |
| |
| } // namespace anonymous |
| |
| namespace nacl { |
| |
| const struct nacl_irt_private_pnacl_translator_link |
| nacl_irt_private_pnacl_translator_link = { |
| ServeLinkRequest |
| }; |
| |
| } // namespace nacl |