Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(537)

Unified Diff: components/nacl/loader/nonsfi/nonsfi_main.cc

Issue 100373005: Initial implementation of Bare Metal Mode for NaCl. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/nacl/loader/nonsfi/nonsfi_main.cc
diff --git a/components/nacl/loader/nonsfi/nonsfi_main.cc b/components/nacl/loader/nonsfi/nonsfi_main.cc
new file mode 100644
index 0000000000000000000000000000000000000000..545c1adedfd13de7fa5d7ff475a084f054a8e9db
--- /dev/null
+++ b/components/nacl/loader/nonsfi/nonsfi_main.cc
@@ -0,0 +1,232 @@
+// Copyright 2013 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 "components/nacl/loader/nonsfi/nonsfi_main.h"
+
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "components/nacl/loader/nonsfi/elf_loader.h"
+#include "components/nacl/loader/nonsfi/nonsfi_error_code.h"
+#include "native_client/src/include/elf_auxv.h"
+#include "native_client/src/include/nacl_macros.h"
+#include "native_client/src/public/secure_service.h"
+#include "native_client/src/shared/srpc/nacl_srpc.h"
+#include "native_client/src/trusted/desc/nacl_desc_base.h"
+#include "native_client/src/trusted/desc/nacl_desc_imc.h"
+#include "native_client/src/trusted/desc/nrd_all_modules.h"
+#include "native_client/src/trusted/desc/nrd_xfer.h"
+#include "native_client/src/trusted/fault_injection/fault_injection.h"
Mark Seaborn 2013/12/12 04:49:48 This one is not needed (see below)
hidehiko 2013/12/12 09:26:04 Done.
+
+namespace nacl {
+namespace nonsfi {
+namespace {
+
+struct NaClDescUnrefer {
+ void operator()(struct NaClDesc* desc) const {
+ NaClDescUnref(desc);
+ }
+};
+
+void LoadModuleRpc(struct NaClSrpcRpc *rpc,
Mark Seaborn 2013/12/12 04:49:48 Nit: use Chromium's "* " spacing style
hidehiko 2013/12/12 09:26:04 Done.
+ struct NaClSrpcArg **in_args,
+ struct NaClSrpcArg **out_args,
+ struct NaClSrpcClosure *done_cls) {
+ UNREFERENCED_PARAMETER(out_args);
Mark Seaborn 2013/12/12 04:49:48 UNREFERENCED_PARAMETER isn't needed in Chromium co
hidehiko 2013/12/12 09:26:04 So, sometimes I'm a bit confused what style I shou
Mark Seaborn 2013/12/17 21:18:55 Yes, since this is in the Chromium tree, please ig
+ VLOG(4) << "LoadModuleRpc: loading module.";
Mark Seaborn 2013/12/12 04:49:48 As with the other file, can you remove the VLOGs,
hidehiko 2013/12/12 09:26:04 Done.
+
+ rpc->result = NACL_SRPC_RESULT_INTERNAL;
+
+ ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> desc(in_args[0]->u.hval);
+ ElfImage image;
+ if (image.Read(desc.get()) != LOAD_OK) {
+ LOG(ERROR) << "LoadModuleRpc: Failed to read binary.";
+ return;
+ }
+
+ if (image.Load(desc.get()) != LOAD_OK) {
+ LOG(ERROR) << "LoadModuleRpc: Failed to load the image";
+ return;
+ }
+
+ uintptr_t entry_point = image.entry_point();
+ VLOG(4) << "LoadModuleRpc: Load is done " << entry_point;
+ rpc->result = NACL_SRPC_RESULT_OK;
+
+ // Run for testing. TODO(hidehiko): Remove this.
+ uintptr_t* info = static_cast<uintptr_t*>(alloca(sizeof(uintptr_t) * 7));
Mark Seaborn 2013/12/12 04:49:48 Nit: it would be simpler to use an array: uintptr_
hidehiko 2013/12/12 09:26:04 Good point. Fixed.
+ int i = 0;
+ info[i++] = 0; // Do not use fini.
+ info[i++] = 0; // envc.
+ info[i++] = 0; // argc.
+ info[i++] = 0; // Null terminate for argv.
+ info[i++] = 0; // Null terminate for envv.
+ info[i++] = AT_NULL;
+ info[i++] = 0; // Null terminate for auxv.
+ reinterpret_cast<void (*)(uintptr_t *)>(entry_point)(info);
+}
+
+void ReverseSetupRpc(struct NaClSrpcRpc *rpc,
+ struct NaClSrpcArg **in_args,
+ struct NaClSrpcArg **out_args,
+ struct NaClSrpcClosure *done_cls) {
+ VLOG(4) << "ReverseSetupRpc";
+ NOTIMPLEMENTED();
+}
+
+void StartModuleRpc(struct NaClSrpcRpc *rpc,
+ struct NaClSrpcArg **in_args,
+ struct NaClSrpcArg **out_args,
+ struct NaClSrpcClosure *done_cls) {
+ VLOG(4) << "StartModuleRpc\n";
+ NOTIMPLEMENTED();
+}
+
+void LogRpc(struct NaClSrpcRpc *rpc,
+ struct NaClSrpcArg **in_args,
+ struct NaClSrpcArg **out_args,
+ struct NaClSrpcClosure *done_cls) {
+ int severity = in_args[0]->u.ival;
+ char *msg = in_args[1]->arrays.str;
+ UNREFERENCED_PARAMETER(out_args);
+
+ VLOG(5) << "LogRpc";
+ VLOG(severity) << msg;
+ VLOG(5) << "LogRpc";
+ rpc->result = NACL_SRPC_RESULT_OK;
+ (*done_cls->Run)(done_cls);
+}
+
+void ShutdownRpc(struct NaClSrpcRpc *rpc,
+ struct NaClSrpcArg **in_args,
+ struct NaClSrpcArg **out_args,
+ struct NaClSrpcClosure *done_cls) {
+ VLOG(4) << "ShutdownRpc";
+ NOTIMPLEMENTED();
+}
+
+const static struct NaClSrpcHandlerDesc kNonSfiServiceHandlers[] = {
+ { NACL_SECURE_SERVICE_LOAD_MODULE, LoadModuleRpc, },
Mark Seaborn 2013/12/12 04:49:48 "load" is the only method handler that's needed at
hidehiko 2013/12/12 09:26:04 Done.
+ { NACL_SECURE_SERVICE_REVERSE_SETUP, ReverseSetupRpc, },
+ { NACL_SECURE_SERVICE_START_MODULE, StartModuleRpc, },
+ { NACL_SECURE_SERVICE_LOG, LogRpc, },
+ { NACL_SECURE_SERVICE_HARD_SHUTDOWN, ShutdownRpc, },
+ { (char const *) NULL, (NaClSrpcMethod) NULL, },
+};
+
+// Creates two socketpairs to communicate with the host process.
+void CreateSecureSocketPair(struct NaClDesc *secure_pair[2],
+ struct NaClDesc *pair[2]) {
+ // Set up a secure pair.
+ VLOG(3) << "Entered CreateSecureSocketPair";
+ if (NaClCommonDescMakeBoundSock(secure_pair)) {
+ LOG(FATAL) << "Cound not create secure service socket\n";
+ }
+ VLOG(4) << "Got bound socket at " << secure_pair[0]
+ << ", addr at " << secure_pair[1];
+
+ // Set up a service pair.
+ if (NaClCommonDescMakeBoundSock(pair)) {
+ LOG(FATAL) << "Could not create service socket";
+ }
+ VLOG(4) << "Got bound socket at " << pair[0] << ", addr at " << pair[1];
+}
+
+// Wraps handle by NaClDesc, and sends sercure_service_address and
+// service_address via the created descriptor.
+struct NaClDesc *SetUpBootstrapChannel(NaClHandle handle,
+ struct NaClDesc *secure_service_address,
+ struct NaClDesc *service_address) {
+ VLOG(3) << "Entered NaClBareMetalSetUpBootstrapChannel\n";
+ if (secure_service_address == NULL) {
+ LOG(FATAL) << "SetUpBootstrapChannel: secure_service_address is not set";
+ }
+
+ if (service_address == NULL) {
+ LOG(FATAL) << "SetUpBootstrapChannel: secure_service_address is not set";
+ }
+
+ struct NaClDescImcDesc* channel =
+ static_cast<struct NaClDescImcDesc *>(malloc(sizeof *channel));
+ if (channel == NULL) {
+ LOG(FATAL) << "SetUpBootstrapChannel: no memory";
+ }
+
+ if (!NaClDescImcDescCtor(channel, handle)) {
+ LOG(FATAL) << "SetUpBootstrapChannel: cannot construct IMC descriptor "
+ << "object for inherited descriptor: " << handle;
+ }
+
+ // Send the descriptors to the host.
+ struct NaClDesc* descs[2] = {
+ secure_service_address,
+ service_address,
+ };
+
+ struct NaClImcTypedMsgHdr hdr;
+ hdr.iov = static_cast<struct NaClImcMsgIoVec *>(NULL);
+ hdr.iov_length = 0;
+ hdr.ndescv = descs;
+ hdr.ndesc_length = NACL_ARRAY_SIZE(descs);
+
+ ssize_t error = (*NACL_VTBL(NaClDesc, channel)->SendMsg)(
+ reinterpret_cast<struct NaClDesc *>(channel), &hdr, 0);
+ VLOG(1) << "SetUpBootstrapChannel: descriptor " << handle
+ << ", error " << error;
+ if (error) {
+ LOG(FATAL) << "SetUpBootstrapChannel: SendMsg failed, error = " << error;
+ }
+ return (struct NaClDesc *) channel;
Mark Seaborn 2013/12/12 04:49:48 Nit: use "NaClDesc*" spacing (Chromium style)
hidehiko 2013/12/12 09:26:04 Done.
+}
+
+// Starts to listend the port and runs the server loop.
Mark Seaborn 2013/12/12 04:49:48 "listen to" or "listen on"?
hidehiko 2013/12/12 09:26:04 Done.
+void ServiceAccept(struct NaClDesc *port) {
+ VLOG(3) << "Entered ServiceAccept";
+ struct NaClDesc *connected_desc = NULL;
+ int status = (*NACL_VTBL(NaClDesc, port)->AcceptConn)(port, &connected_desc);
+ if (status) {
+ VLOG(4) << "ServiceAccept: Failed to accept " << status;
+ return;
+ }
+
+ VLOG(4) << "ServiceAccept: Start server loop.";
+ NaClSrpcServerLoop(connected_desc, kNonSfiServiceHandlers, NULL);
+}
+
+void NonSfiAllModulesInit(void) {
Mark Seaborn 2013/12/12 04:49:48 Nit: "(void)" is not needed in C++
hidehiko 2013/12/12 09:26:04 acknowledged.
+ NaClNrdAllModulesInit();
Mark Seaborn 2013/12/12 04:49:48 Calling this makes this fail with the following er
hidehiko 2013/12/12 09:26:04 I see. Done.
+ NaClFaultInjectionModuleInit();
Mark Seaborn 2013/12/12 04:49:48 This one is not needed
hidehiko 2013/12/12 09:26:04 I thought this was needed otherwise FaultInjection
+ NaClSrpcModuleInit();
+}
+
+} // namespace
+
+void MainStart(NaClHandle imc_bootstrap_handle) {
+ VLOG(3) << "MainStart";
+
+ NonSfiAllModulesInit();
+
+ struct NaClDesc *secure_pair[2] = { NULL, NULL };
+ struct NaClDesc *pair[2] = { NULL, NULL };
+ CreateSecureSocketPair(secure_pair, pair);
+ ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> secure_port(secure_pair[0]);
+ ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> secure_address(
+ secure_pair[1]);
+ ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> service_port(pair[0]);
+ ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> service_address(pair[1]);
+
+ ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> channel(
+ SetUpBootstrapChannel(imc_bootstrap_handle,
+ secure_address.get(), service_address.get()));
+ if (!channel) {
+ LOG(ERROR) << "MainStart: Failed to set up bootstrap channel.";
+ return;
+ }
+
+ // Start the SRPC server loop.
+ VLOG(4) << "MainStart: Start server loop.";
+ ServiceAccept(secure_port.get());
+}
+
+} // namespace nonsfi
+} // namespace nacl

Powered by Google App Engine
This is Rietveld 408576698