 Chromium Code Reviews
 Chromium Code Reviews Issue 1382713002:
  Creating a pexe content handler to translate and run pexes.  (Closed) 
  Base URL: https://github.com/domokit/mojo.git@master
    
  
    Issue 1382713002:
  Creating a pexe content handler to translate and run pexes.  (Closed) 
  Base URL: https://github.com/domokit/mojo.git@master| 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..52e767c1d4b00d1c6ede173292e9c35cb062e075 | 
| --- /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 "native_client/src/untrusted/irt/irt_dev.h" | 
| + | 
| +void serve_translate_request(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); | 
| + | 
| + // Read / Wait until we can get the pexe file name. | 
| + MojoResult result; | 
| + char pexe_file_name[PATH_MAX]; | 
| + uint32_t path_size = sizeof(pexe_file_name); | 
| + do { | 
| + result = MojoReadMessage(handle, | 
| 
Mark Seaborn
2015/10/20 21:32:40
I don't think you should be using raw Mojo IPC.  C
 
Sean Klein
2015/10/22 21:50:00
I think this is somewhere that vtl should get invo
 | 
| + pexe_file_name, | 
| + &path_size, | 
| + nullptr, | 
| + nullptr, | 
| + MOJO_READ_MESSAGE_FLAG_NONE); | 
| + if (result == MOJO_RESULT_SHOULD_WAIT) { | 
| + result = MojoWait(handle, | 
| + MOJO_HANDLE_SIGNAL_READABLE, | 
| + MOJO_DEADLINE_INDEFINITE, | 
| + nullptr); | 
| + if (result != MOJO_RESULT_OK) | 
| + LOG(FATAL) << "Pexe translator could not wait for pexe name"; | 
| + } else { | 
| + break; | 
| + } | 
| + } while (true); | 
| + if (result != MOJO_RESULT_OK) | 
| + LOG(FATAL) << "Pexe translator could not read pexe name"; | 
| + pexe_file_name[path_size] = '\0'; | 
| 
Mark Seaborn
2015/10/20 21:32:40
Couldn't path_size be sizeof(pexe_file_name)?  In
 
Sean Klein
2015/10/22 21:50:00
Using "PATH_MAX + 1" to allow room for null termin
 | 
| + | 
| + // Now that we have the pexe file name, make an object file. This is necessary | 
| + // for the callback into LLVM through 'funcs'. Open the object file, and | 
| + // prepare to pass the nexe through the compiler callback. | 
| + base::FilePath obj_file_name; | 
| + if (!CreateTemporaryFile(&obj_file_name)) | 
| + LOG(FATAL) << "Could not make temporary object file"; | 
| + int obj_file_fds[] = { open(obj_file_name.value().c_str(), O_RDWR, O_TRUNC) }; | 
| 
Mark Seaborn
2015/10/20 21:32:40
This looks a bit quirky. :-)
You could just do:
i
 
Sean Klein
2015/10/22 21:50:00
The "quirky" version was there so the type of obj_
 | 
| + | 
| + if (obj_file_fds[0] < 0) | 
| + LOG(FATAL) << "Could not create temp file for compiled pexe"; | 
| + | 
| + // TODO(smklein): Is there a less arbitrary number to choose? | 
| 
Mark Seaborn
2015/10/20 21:32:40
What is Chromium using for the thread count?
This
 
Sean Klein
2015/10/22 21:50:00
It's passed in as an argument, so I'm not entirely
 | 
| + uint32_t num_threads = 8; | 
| + size_t obj_file_fd_count = 1; | 
| + char relocation_model[] = "-relocation-model=pic"; | 
| + char force_tls[] = "-force-tls-non-pic"; | 
| + char bitcode_format[] = "-bitcode-format=pnacl"; | 
| + char *args[] = { relocation_model, force_tls, bitcode_format }; | 
| + size_t argc = 3; | 
| + funcs->init_callback(num_threads, obj_file_fds, obj_file_fd_count, | 
| + args, argc); | 
| + | 
| + // Read the pexe using fread, and write the pexe into the callback function. | 
| + char buf[0x100000]; | 
| 
Mark Seaborn
2015/10/20 21:32:40
That's a lot to stack-allocate.  Can you heap-allo
 
Sean Klein
2015/10/22 21:50:00
Done with new / delete[].
 | 
| + FILE* pexe_file_stream = fopen(pexe_file_name, "r"); | 
| + // Once the pexe has been opened, it is no longer needed, so we unlink it. | 
| + if (unlink(pexe_file_name)) | 
| + 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, 1, sizeof(buf), 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, num_bytes_from_pexe); | 
| + } | 
| + | 
| + if (fclose(pexe_file_stream)) | 
| + LOG(FATAL) << "Failed to close pexe file stream from compiler nexe"; | 
| + funcs->end_callback(); | 
| + | 
| + // Write the name of the object file back to the content handler | 
| + // to signify that we are done compiling (and to provide information | 
| + // for the linking stage). | 
| + result = MojoWriteMessage(handle, | 
| + obj_file_name.value().c_str(), | 
| + obj_file_name.value().size(), | 
| + nullptr, | 
| + 0, | 
| + MOJO_WRITE_MESSAGE_FLAG_NONE); | 
| + if (result != MOJO_RESULT_OK) | 
| + LOG(FATAL) << "Could not write message to content handler: " << result; | 
| +} | 
| + | 
| +const struct nacl_irt_private_pnacl_translator_compile | 
| + nacl_irt_private_pnacl_translator_compile = { | 
| + serve_translate_request | 
| +}; |