Index: components/nacl/loader/bare_metal/bare_metal_main.c |
diff --git a/components/nacl/loader/bare_metal/bare_metal_main.c b/components/nacl/loader/bare_metal/bare_metal_main.c |
new file mode 100644 |
index 0000000000000000000000000000000000000000..65abff8d717fcef1e129e0ae25e0b60c8db999d7 |
--- /dev/null |
+++ b/components/nacl/loader/bare_metal/bare_metal_main.c |
@@ -0,0 +1,280 @@ |
+/* |
Mark Seaborn
2013/12/06 03:21:16
Can you make these .cc files rather than .c files?
hidehiko
2013/12/06 17:40:02
I see. I fully rewrote the code with C++. Along th
|
+ * Copyright 2013 The Native Client 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/bare_metal/bare_metal_main.h" |
+ |
+#include "components/nacl/loader/bare_metal/bare_metal_error_code.h" |
+#include "components/nacl/loader/bare_metal/elf_util.h" |
+#include "native_client/src/include/elf_auxv.h" |
+#include "native_client/src/public/secure_service.h" |
+#include "native_client/src/shared/platform/nacl_log.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/nrd_xfer.h" |
+#include "native_client/src/trusted/fault_injection/fault_injection.h" |
+#include "native_client/src/trusted/desc/nacl_desc_imc.h" |
+#include "native_client/src/include/nacl_macros.h" |
+#include "native_client/src/trusted/desc/nrd_all_modules.h" |
+ |
+/* Copied from native_client/src/trusted/service_runtime/include/sys/errno.h */ |
+#define NACL_ABI_EINVAL 22 |
+ |
+#define NOTIMPLEMENTED() NaClLog(LOG_FATAL, "%s: Not Implemented\n", __func__) |
+ |
+static void NaClBareMetalLoadModuleRpc( |
+ struct NaClSrpcRpc *rpc, |
+ struct NaClSrpcArg **in_args, |
+ struct NaClSrpcArg **out_args, |
+ struct NaClSrpcClosure *done_cls) { |
+ struct NaClDesc *desc = in_args[0]->u.hval; |
+ NaClBareMetalErrorCode error = BARE_METAL_LOAD_INTERNAL; |
+ struct NaClBareMetalElfImage *image = NULL; |
+ uintptr_t entry_point; |
+ uintptr_t *info; |
+ int j; |
+ UNREFERENCED_PARAMETER(out_args); |
+ |
+ NaClLog(4, "NaClBareMetalLoadModuleRpc: loading module\n"); |
+ rpc->result = NACL_SRPC_RESULT_INTERNAL; |
+ |
+ image = NaClBareMetalElfImageNew(desc, &error); |
+ if (NULL == image || BARE_METAL_LOAD_OK != error) { |
+ NaClLog(4, "NaClBareMetalLoadModuleRpc: Failed to read binary.\n"); |
+ goto cleanup; |
+ } |
+ |
+ if (NaClBareMetalElfImageLoad(image, desc) != BARE_METAL_LOAD_OK) { |
+ NaClLog(4, "NaClBareMetalLoadModuleRpc: Failed to load the image.\n"); |
+ goto cleanup; |
+ } |
+ |
+ entry_point = NaClBareMetalElfImageGetEntryPoint(image); |
+ NaClLog(4, "NaClBareMetalLoadModuleRpc: Load is done %"NACL_PRIuPTR"\n", |
+ entry_point); |
+ rpc->result = NACL_SRPC_RESULT_OK; |
+ |
+ /* Run for testing. TODO(hidehiko): Remove this */ |
+ info = (uintptr_t*) alloca(sizeof(uintptr_t) * 7); |
+ j = 0; |
+ info[j++] = 0; /* Do not use fini. */ |
+ info[j++] = 0; /* envc. */ |
+ info[j++] = 0; /* argc. */ |
+ info[j++] = 0; /* Null terminate for argv. */ |
+ info[j++] = 0; /* Null terminate for envv. */ |
+ info[j++] = AT_NULL; |
+ info[j++] = 0; /* Null terminate for auxv. */ |
+ ((void (*)(uintptr_t *info)) entry_point)(info); |
+ cleanup: |
+ NaClBareMetalElfImageDelete(image); |
+ NaClDescUnref(desc); |
+} |
+ |
+static void NaClBareMetalReverseSetupRpc( |
+ struct NaClSrpcRpc *rpc, |
+ struct NaClSrpcArg **in_args, |
+ struct NaClSrpcArg **out_args, |
+ struct NaClSrpcClosure *done_cls) { |
+ NaClLog(4, "NaClBareMetalReverseSetupRpc\n"); |
+ NOTIMPLEMENTED(); |
+} |
+ |
+static void NaClBareMetalStartModuleRpc( |
+ struct NaClSrpcRpc *rpc, |
+ struct NaClSrpcArg **in_args, |
+ struct NaClSrpcArg **out_args, |
+ struct NaClSrpcClosure *done_cls) { |
+ NaClLog(4, "NaClBareMetalStartModuleRpc\n"); |
+ NOTIMPLEMENTED(); |
+} |
+ |
+static void NaClBareMetalLogRpc( |
+ 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); |
+ |
+ NaClLog(5, "NaClSecureChannelLogRpc\n"); |
+ NaClLog(severity, "%s\n", msg); |
+ NaClLog(5, "NaClSecureChannelLogRpc\n"); |
+ rpc->result = NACL_SRPC_RESULT_OK; |
+ (*done_cls->Run)(done_cls); |
+} |
+ |
+static void NaClBareMetalShutdownRpc( |
+ struct NaClSrpcRpc *rpc, |
+ struct NaClSrpcArg **in_args, |
+ struct NaClSrpcArg **out_args, |
+ struct NaClSrpcClosure *done_cls) { |
+ NaClLog(4, "NaClBareMetalShutdownRpc\n"); |
+ NOTIMPLEMENTED(); |
+} |
+ |
+const static struct NaClSrpcHandlerDesc kBareMetalServiceHandlers[] = { |
+ { NACL_SECURE_SERVICE_LOAD_MODULE, NaClBareMetalLoadModuleRpc, }, |
+ { NACL_SECURE_SERVICE_REVERSE_SETUP, NaClBareMetalReverseSetupRpc, }, |
+ { NACL_SECURE_SERVICE_START_MODULE, NaClBareMetalStartModuleRpc, }, |
+ { NACL_SECURE_SERVICE_LOG, NaClBareMetalLogRpc, }, |
+ { NACL_SECURE_SERVICE_HARD_SHUTDOWN, NaClBareMetalShutdownRpc, }, |
+ { (char const *) NULL, (NaClSrpcMethod) NULL, }, |
+}; |
+ |
+/* Creates two socketpairs to communicate with the host process. */ |
+static void NaClBareMetalCreateSecureSocketPair( |
+ struct NaClDesc *secure_pair[2], |
+ struct NaClDesc *pair[2]) { |
+ NaClLog(3, "Entered NaClBareMetalCreateSecureSocketPair\n"); |
+ |
+ if (NACL_FI_ERROR_COND( |
+ "NaClBareMetalCreateSecureSocketPair__secure_boundsock", |
+ 0 != NaClCommonDescMakeBoundSock(secure_pair))) { |
+ NaClLog(LOG_FATAL, "Cound not create secure service socket\n"); |
+ } |
+ NaClLog(4, |
+ "got bound socket at 0x%08"NACL_PRIxPTR", " |
+ "addr at 0x%08"NACL_PRIxPTR"\n", |
+ (uintptr_t) secure_pair[0], |
+ (uintptr_t) secure_pair[1]); |
+ |
+ if (NACL_FI_ERROR_COND("NaClBareMetalCreateSecureSocketPair__boundsock", |
+ 0 != NaClCommonDescMakeBoundSock(pair))) { |
+ NaClLog(LOG_FATAL, "Cound not create service socket\n"); |
+ } |
+ NaClLog(4, |
+ "got bound socket at 0x%08"NACL_PRIxPTR", " |
+ "addr at 0x%08"NACL_PRIxPTR"\n", |
+ (uintptr_t) pair[0], |
+ (uintptr_t) pair[1]); |
+ NaClDescRef(pair[0]); |
+ NaClDescRef(pair[1]); |
+ |
+ NaClLog(4, "Leaving NaClCreateServiceSocket\n"); |
+} |
+ |
+ |
+static struct NaClDesc *NaClBareMetalSetUpBootstrapChannel( |
+ NaClHandle handle, |
+ struct NaClDesc *secure_service_address, |
+ struct NaClDesc *service_address) { |
+ struct NaClDescImcDesc *channel; |
+ struct NaClImcTypedMsgHdr hdr; |
+ struct NaClDesc *descs[2]; |
+ ssize_t error; |
+ |
+ NaClLog(3, "Entered NaClBareMetalSetUpBootstrapChannel\n"); |
+ |
+ if (NULL == secure_service_address) { |
+ NaClLog(LOG_FATAL, |
+ ("NaClBareMetalSetUpBootstrapChannel: secure_service_address" |
+ " is not set\n")); |
+ return NULL; |
+ } |
+ |
+ if (NULL == service_address) { |
+ NaClLog( |
+ LOG_FATAL, |
+ "NaClBareMetalSetUpBootstrapChannel: service_address is not set\n"); |
+ return NULL; |
+ } |
+ |
+ /* Create a NaClDesc by wrapping the given handle. */ |
+ channel = (struct NaClDescImcDesc *) malloc(sizeof *channel); |
+ if (NULL == channel) { |
+ NaClLog(LOG_FATAL, "NaClBareMetalSetUpBootstrapChannel: no memory\n"); |
+ return NULL; |
+ } |
+ if (!NaClDescImcDescCtor(channel, handle)) { |
+ NaClLog(LOG_FATAL, |
+ ("NaClBareMetalSetUpBootstrapChannel:" |
+ " cannot construct IMC descriptor" |
+ " object for inherited descriptor %"NACL_PRIdPTR"\n"), |
+ (uintptr_t) handle); |
+ free(channel); |
+ return NULL; |
+ } |
+ |
+ /* Send the descriptors to the host. */ |
+ descs[0] = secure_service_address; |
+ descs[1] = service_address; |
+ |
+ hdr.iov = (struct NaClImcMsgIoVec *) NULL; |
+ hdr.iov_length = 0; |
+ hdr.ndescv = descs; |
+ hdr.ndesc_length = NACL_ARRAY_SIZE(descs); |
+ |
+ error = (*NACL_VTBL(NaClDesc, channel)->SendMsg)( |
+ (struct NaClDesc *) channel, |
+ &hdr, |
+ 0); |
+ NaClLog(1, |
+ ("NaClBareMetalSetUpBootstrapChannel: descriptor %"NACL_PRIdPTR", " |
+ "error %"NACL_PRIdS"\n"), |
+ (uintptr_t) handle, |
+ error); |
+ if (NACL_FI_ERROR_COND("NaClBareMetalSetUpBootstrapChannel__SendMsg", |
+ 0 != error)) { |
+ NaClLog(LOG_FATAL, |
+ ("NaClBareMetalSetUpBootstrapChannel: SendMsg failed, " |
+ "error = %"NACL_PRIdS"\n"), |
+ error); |
+ } |
+ |
+ return (struct NaClDesc *) channel; |
+} |
+ |
+static void NaClBareMetalServiceAccept(struct NaClDesc *port) { |
+ int status = -NACL_ABI_EINVAL; |
+ struct NaClDesc *connected_desc = NULL; |
+ |
+ NaClLog(3, "Entered NaClBareMetalServiceAccept\n"); |
+ |
+ status = (*NACL_VTBL(NaClDesc, port)->AcceptConn)(port, &connected_desc); |
+ if (0 != status) { |
+ NaClLog(4, "NaClBareMetalServiceAccept: Failed to accept %d\n", status); |
+ return; |
+ } |
+ |
+ NaClLog(4, "NaClBareMetalServiceAccept: Start server loop.\n"); |
+ NaClSrpcServerLoop(connected_desc, kBareMetalServiceHandlers, NULL); |
+} |
+ |
+static void NaClBareMetalAllModulesInit(void) { |
+ NaClNrdAllModulesInit(); |
+ NaClFaultInjectionModuleInit(); |
+ NaClSrpcModuleInit(); |
+} |
+ |
+void NaClBareMetalMainStart(NaClHandle imc_bootstrap_handle) { |
Mark Seaborn
2013/12/06 03:21:16
Can you hook this up so that it's called by nacl_l
hidehiko
2013/12/06 17:40:02
Done. Note that the flag is added to content_switc
|
+ struct NaClDesc *secure_pair[2] = { NULL, NULL }; |
+ struct NaClDesc *pair[2] = { NULL, NULL }; |
+ struct NaClDesc *channel = NULL; |
+ |
+ NaClLog(3, "NaClBareMetalMainStart\n"); |
+ |
+ NaClBareMetalAllModulesInit(); |
+ NaClBareMetalCreateSecureSocketPair(secure_pair, pair); |
+ channel = NaClBareMetalSetUpBootstrapChannel( |
+ imc_bootstrap_handle, secure_pair[1], pair[1]); |
+ if (NULL == channel) { |
+ NaClLog(4, |
+ "NaClBareMetalMainStart: Failed to set up bootstrap channel.\n"); |
+ goto cleanup; |
+ } |
+ |
+ /* Start the SRPC server loop. */ |
+ NaClLog(4, "NaClBareMetalMainStart: Start server loop.\n"); |
+ NaClBareMetalServiceAccept(secure_pair[0]); |
+ |
+ cleanup: |
+ NaClLog(4, "NaClBareMetalMainStart: Clean up.\n"); |
+ NaClDescSafeUnref(channel); |
+ NaClDescSafeUnref(pair[0]); |
+ NaClDescSafeUnref(pair[1]); |
+ NaClDescSafeUnref(secure_pair[0]); |
+ NaClDescSafeUnref(secure_pair[1]); |
+} |