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 char relocation_model[] = "-relocation-model=pic"; | |
Mark Seaborn
2015/10/28 18:31:43
How about some comments on these options? For thi
Sean Klein
2015/10/28 21:39:59
Done.
| |
41 char force_tls[] = "-force-tls-non-pic"; | |
Mark Seaborn
2015/10/28 18:31:43
This is copied from pnacl-translate.py but I suspe
Sean Klein
2015/10/28 21:39:59
Removed.
| |
42 char bitcode_format[] = "-bitcode-format=pnacl"; | |
43 char sentinel[] = "\0"; | |
Mark Seaborn
2015/10/28 18:31:43
The sentinel is supposed to be NULL, not an empty
Sean Klein
2015/10/28 21:39:59
Updated to nullptr in args.
| |
44 char *args[] = { relocation_model, force_tls, bitcode_format, sentinel }; | |
Mark Seaborn
2015/10/28 18:31:43
Spacing: "char*"
Sean Klein
2015/10/28 21:39:59
Done.
| |
45 size_t argc = 3; | |
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; | |
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[0], 1, buf_size, | |
Mark Seaborn
2015/10/28 18:31:43
buf.get() is probably more idiomatic for scoped_pt
Sean Klein
2015/10/28 21:39:59
Done.
| |
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[0], num_bytes_from_pexe); | |
68 } | |
69 | |
Mark Seaborn
2015/10/28 18:31:43
You could replace the original "delete[] buf;" wit
Sean Klein
2015/10/28 21:39:59
Done.
| |
70 if (fclose(pexe_file_stream)) | |
71 LOG(FATAL) << "Failed to close pexe file stream from compiler nexe"; | |
72 funcs_->end_callback(); | |
73 | |
74 // Return the name of the object file. | |
75 callback.Run(mojo::String(obj_file_name.value())); | |
76 } | |
77 private: | |
78 const struct nacl_irt_pnacl_compile_funcs* funcs_; | |
79 mojo::StrongBinding<mojo::nacl::PexeCompiler> strong_binding_; | |
80 }; | |
81 | |
82 void ServeTranslateRequest(const struct nacl_irt_pnacl_compile_funcs* funcs) { | |
83 // Acquire the handle -- this is our mechanism to contact the | |
84 // content handler which called us. | |
85 MojoHandle handle; | |
86 nacl::MojoGetInitialHandle(&handle); | |
87 | |
88 // Convert the MojoHandle into a ScopedMessagePipeHandle, and use that to | |
89 // implement the PexeCompiler interface. | |
90 PexeCompilerImpl impl( | |
91 mojo::ScopedMessagePipeHandle(mojo::MessagePipeHandle(handle)).Pass(), | |
92 funcs); | |
93 mojo::RunLoop::current()->RunUntilIdle(); | |
94 } | |
95 | |
96 } // namespace anonymous | |
97 | |
98 namespace nacl { | |
99 | |
100 const struct nacl_irt_private_pnacl_translator_compile | |
101 nacl_irt_private_pnacl_translator_compile = { | |
102 ServeTranslateRequest | |
103 }; | |
104 | |
105 } // namespace nacl | |
OLD | NEW |