Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 /* | |
|
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
| |
| 2 * Copyright 2013 The Native Client Authors. All rights reserved. | |
| 3 * Use of this source code is governed by a BSD-style license that can be | |
| 4 * found in the LICENSE file. | |
| 5 */ | |
| 6 | |
| 7 #include "components/nacl/loader/bare_metal/bare_metal_main.h" | |
| 8 | |
| 9 #include "components/nacl/loader/bare_metal/bare_metal_error_code.h" | |
| 10 #include "components/nacl/loader/bare_metal/elf_util.h" | |
| 11 #include "native_client/src/include/elf_auxv.h" | |
| 12 #include "native_client/src/public/secure_service.h" | |
| 13 #include "native_client/src/shared/platform/nacl_log.h" | |
| 14 #include "native_client/src/shared/srpc/nacl_srpc.h" | |
| 15 #include "native_client/src/trusted/desc/nacl_desc_base.h" | |
| 16 #include "native_client/src/trusted/desc/nrd_xfer.h" | |
| 17 #include "native_client/src/trusted/fault_injection/fault_injection.h" | |
| 18 #include "native_client/src/trusted/desc/nacl_desc_imc.h" | |
| 19 #include "native_client/src/include/nacl_macros.h" | |
| 20 #include "native_client/src/trusted/desc/nrd_all_modules.h" | |
| 21 | |
| 22 /* Copied from native_client/src/trusted/service_runtime/include/sys/errno.h */ | |
| 23 #define NACL_ABI_EINVAL 22 | |
| 24 | |
| 25 #define NOTIMPLEMENTED() NaClLog(LOG_FATAL, "%s: Not Implemented\n", __func__) | |
| 26 | |
| 27 static void NaClBareMetalLoadModuleRpc( | |
| 28 struct NaClSrpcRpc *rpc, | |
| 29 struct NaClSrpcArg **in_args, | |
| 30 struct NaClSrpcArg **out_args, | |
| 31 struct NaClSrpcClosure *done_cls) { | |
| 32 struct NaClDesc *desc = in_args[0]->u.hval; | |
| 33 NaClBareMetalErrorCode error = BARE_METAL_LOAD_INTERNAL; | |
| 34 struct NaClBareMetalElfImage *image = NULL; | |
| 35 uintptr_t entry_point; | |
| 36 uintptr_t *info; | |
| 37 int j; | |
| 38 UNREFERENCED_PARAMETER(out_args); | |
| 39 | |
| 40 NaClLog(4, "NaClBareMetalLoadModuleRpc: loading module\n"); | |
| 41 rpc->result = NACL_SRPC_RESULT_INTERNAL; | |
| 42 | |
| 43 image = NaClBareMetalElfImageNew(desc, &error); | |
| 44 if (NULL == image || BARE_METAL_LOAD_OK != error) { | |
| 45 NaClLog(4, "NaClBareMetalLoadModuleRpc: Failed to read binary.\n"); | |
| 46 goto cleanup; | |
| 47 } | |
| 48 | |
| 49 if (NaClBareMetalElfImageLoad(image, desc) != BARE_METAL_LOAD_OK) { | |
| 50 NaClLog(4, "NaClBareMetalLoadModuleRpc: Failed to load the image.\n"); | |
| 51 goto cleanup; | |
| 52 } | |
| 53 | |
| 54 entry_point = NaClBareMetalElfImageGetEntryPoint(image); | |
| 55 NaClLog(4, "NaClBareMetalLoadModuleRpc: Load is done %"NACL_PRIuPTR"\n", | |
| 56 entry_point); | |
| 57 rpc->result = NACL_SRPC_RESULT_OK; | |
| 58 | |
| 59 /* Run for testing. TODO(hidehiko): Remove this */ | |
| 60 info = (uintptr_t*) alloca(sizeof(uintptr_t) * 7); | |
| 61 j = 0; | |
| 62 info[j++] = 0; /* Do not use fini. */ | |
| 63 info[j++] = 0; /* envc. */ | |
| 64 info[j++] = 0; /* argc. */ | |
| 65 info[j++] = 0; /* Null terminate for argv. */ | |
| 66 info[j++] = 0; /* Null terminate for envv. */ | |
| 67 info[j++] = AT_NULL; | |
| 68 info[j++] = 0; /* Null terminate for auxv. */ | |
| 69 ((void (*)(uintptr_t *info)) entry_point)(info); | |
| 70 cleanup: | |
| 71 NaClBareMetalElfImageDelete(image); | |
| 72 NaClDescUnref(desc); | |
| 73 } | |
| 74 | |
| 75 static void NaClBareMetalReverseSetupRpc( | |
| 76 struct NaClSrpcRpc *rpc, | |
| 77 struct NaClSrpcArg **in_args, | |
| 78 struct NaClSrpcArg **out_args, | |
| 79 struct NaClSrpcClosure *done_cls) { | |
| 80 NaClLog(4, "NaClBareMetalReverseSetupRpc\n"); | |
| 81 NOTIMPLEMENTED(); | |
| 82 } | |
| 83 | |
| 84 static void NaClBareMetalStartModuleRpc( | |
| 85 struct NaClSrpcRpc *rpc, | |
| 86 struct NaClSrpcArg **in_args, | |
| 87 struct NaClSrpcArg **out_args, | |
| 88 struct NaClSrpcClosure *done_cls) { | |
| 89 NaClLog(4, "NaClBareMetalStartModuleRpc\n"); | |
| 90 NOTIMPLEMENTED(); | |
| 91 } | |
| 92 | |
| 93 static void NaClBareMetalLogRpc( | |
| 94 struct NaClSrpcRpc *rpc, | |
| 95 struct NaClSrpcArg **in_args, | |
| 96 struct NaClSrpcArg **out_args, | |
| 97 struct NaClSrpcClosure *done_cls) { | |
| 98 int severity = in_args[0]->u.ival; | |
| 99 char *msg = in_args[1]->arrays.str; | |
| 100 UNREFERENCED_PARAMETER(out_args); | |
| 101 | |
| 102 NaClLog(5, "NaClSecureChannelLogRpc\n"); | |
| 103 NaClLog(severity, "%s\n", msg); | |
| 104 NaClLog(5, "NaClSecureChannelLogRpc\n"); | |
| 105 rpc->result = NACL_SRPC_RESULT_OK; | |
| 106 (*done_cls->Run)(done_cls); | |
| 107 } | |
| 108 | |
| 109 static void NaClBareMetalShutdownRpc( | |
| 110 struct NaClSrpcRpc *rpc, | |
| 111 struct NaClSrpcArg **in_args, | |
| 112 struct NaClSrpcArg **out_args, | |
| 113 struct NaClSrpcClosure *done_cls) { | |
| 114 NaClLog(4, "NaClBareMetalShutdownRpc\n"); | |
| 115 NOTIMPLEMENTED(); | |
| 116 } | |
| 117 | |
| 118 const static struct NaClSrpcHandlerDesc kBareMetalServiceHandlers[] = { | |
| 119 { NACL_SECURE_SERVICE_LOAD_MODULE, NaClBareMetalLoadModuleRpc, }, | |
| 120 { NACL_SECURE_SERVICE_REVERSE_SETUP, NaClBareMetalReverseSetupRpc, }, | |
| 121 { NACL_SECURE_SERVICE_START_MODULE, NaClBareMetalStartModuleRpc, }, | |
| 122 { NACL_SECURE_SERVICE_LOG, NaClBareMetalLogRpc, }, | |
| 123 { NACL_SECURE_SERVICE_HARD_SHUTDOWN, NaClBareMetalShutdownRpc, }, | |
| 124 { (char const *) NULL, (NaClSrpcMethod) NULL, }, | |
| 125 }; | |
| 126 | |
| 127 /* Creates two socketpairs to communicate with the host process. */ | |
| 128 static void NaClBareMetalCreateSecureSocketPair( | |
| 129 struct NaClDesc *secure_pair[2], | |
| 130 struct NaClDesc *pair[2]) { | |
| 131 NaClLog(3, "Entered NaClBareMetalCreateSecureSocketPair\n"); | |
| 132 | |
| 133 if (NACL_FI_ERROR_COND( | |
| 134 "NaClBareMetalCreateSecureSocketPair__secure_boundsock", | |
| 135 0 != NaClCommonDescMakeBoundSock(secure_pair))) { | |
| 136 NaClLog(LOG_FATAL, "Cound not create secure service socket\n"); | |
| 137 } | |
| 138 NaClLog(4, | |
| 139 "got bound socket at 0x%08"NACL_PRIxPTR", " | |
| 140 "addr at 0x%08"NACL_PRIxPTR"\n", | |
| 141 (uintptr_t) secure_pair[0], | |
| 142 (uintptr_t) secure_pair[1]); | |
| 143 | |
| 144 if (NACL_FI_ERROR_COND("NaClBareMetalCreateSecureSocketPair__boundsock", | |
| 145 0 != NaClCommonDescMakeBoundSock(pair))) { | |
| 146 NaClLog(LOG_FATAL, "Cound not create service socket\n"); | |
| 147 } | |
| 148 NaClLog(4, | |
| 149 "got bound socket at 0x%08"NACL_PRIxPTR", " | |
| 150 "addr at 0x%08"NACL_PRIxPTR"\n", | |
| 151 (uintptr_t) pair[0], | |
| 152 (uintptr_t) pair[1]); | |
| 153 NaClDescRef(pair[0]); | |
| 154 NaClDescRef(pair[1]); | |
| 155 | |
| 156 NaClLog(4, "Leaving NaClCreateServiceSocket\n"); | |
| 157 } | |
| 158 | |
| 159 | |
| 160 static struct NaClDesc *NaClBareMetalSetUpBootstrapChannel( | |
| 161 NaClHandle handle, | |
| 162 struct NaClDesc *secure_service_address, | |
| 163 struct NaClDesc *service_address) { | |
| 164 struct NaClDescImcDesc *channel; | |
| 165 struct NaClImcTypedMsgHdr hdr; | |
| 166 struct NaClDesc *descs[2]; | |
| 167 ssize_t error; | |
| 168 | |
| 169 NaClLog(3, "Entered NaClBareMetalSetUpBootstrapChannel\n"); | |
| 170 | |
| 171 if (NULL == secure_service_address) { | |
| 172 NaClLog(LOG_FATAL, | |
| 173 ("NaClBareMetalSetUpBootstrapChannel: secure_service_address" | |
| 174 " is not set\n")); | |
| 175 return NULL; | |
| 176 } | |
| 177 | |
| 178 if (NULL == service_address) { | |
| 179 NaClLog( | |
| 180 LOG_FATAL, | |
| 181 "NaClBareMetalSetUpBootstrapChannel: service_address is not set\n"); | |
| 182 return NULL; | |
| 183 } | |
| 184 | |
| 185 /* Create a NaClDesc by wrapping the given handle. */ | |
| 186 channel = (struct NaClDescImcDesc *) malloc(sizeof *channel); | |
| 187 if (NULL == channel) { | |
| 188 NaClLog(LOG_FATAL, "NaClBareMetalSetUpBootstrapChannel: no memory\n"); | |
| 189 return NULL; | |
| 190 } | |
| 191 if (!NaClDescImcDescCtor(channel, handle)) { | |
| 192 NaClLog(LOG_FATAL, | |
| 193 ("NaClBareMetalSetUpBootstrapChannel:" | |
| 194 " cannot construct IMC descriptor" | |
| 195 " object for inherited descriptor %"NACL_PRIdPTR"\n"), | |
| 196 (uintptr_t) handle); | |
| 197 free(channel); | |
| 198 return NULL; | |
| 199 } | |
| 200 | |
| 201 /* Send the descriptors to the host. */ | |
| 202 descs[0] = secure_service_address; | |
| 203 descs[1] = service_address; | |
| 204 | |
| 205 hdr.iov = (struct NaClImcMsgIoVec *) NULL; | |
| 206 hdr.iov_length = 0; | |
| 207 hdr.ndescv = descs; | |
| 208 hdr.ndesc_length = NACL_ARRAY_SIZE(descs); | |
| 209 | |
| 210 error = (*NACL_VTBL(NaClDesc, channel)->SendMsg)( | |
| 211 (struct NaClDesc *) channel, | |
| 212 &hdr, | |
| 213 0); | |
| 214 NaClLog(1, | |
| 215 ("NaClBareMetalSetUpBootstrapChannel: descriptor %"NACL_PRIdPTR", " | |
| 216 "error %"NACL_PRIdS"\n"), | |
| 217 (uintptr_t) handle, | |
| 218 error); | |
| 219 if (NACL_FI_ERROR_COND("NaClBareMetalSetUpBootstrapChannel__SendMsg", | |
| 220 0 != error)) { | |
| 221 NaClLog(LOG_FATAL, | |
| 222 ("NaClBareMetalSetUpBootstrapChannel: SendMsg failed, " | |
| 223 "error = %"NACL_PRIdS"\n"), | |
| 224 error); | |
| 225 } | |
| 226 | |
| 227 return (struct NaClDesc *) channel; | |
| 228 } | |
| 229 | |
| 230 static void NaClBareMetalServiceAccept(struct NaClDesc *port) { | |
| 231 int status = -NACL_ABI_EINVAL; | |
| 232 struct NaClDesc *connected_desc = NULL; | |
| 233 | |
| 234 NaClLog(3, "Entered NaClBareMetalServiceAccept\n"); | |
| 235 | |
| 236 status = (*NACL_VTBL(NaClDesc, port)->AcceptConn)(port, &connected_desc); | |
| 237 if (0 != status) { | |
| 238 NaClLog(4, "NaClBareMetalServiceAccept: Failed to accept %d\n", status); | |
| 239 return; | |
| 240 } | |
| 241 | |
| 242 NaClLog(4, "NaClBareMetalServiceAccept: Start server loop.\n"); | |
| 243 NaClSrpcServerLoop(connected_desc, kBareMetalServiceHandlers, NULL); | |
| 244 } | |
| 245 | |
| 246 static void NaClBareMetalAllModulesInit(void) { | |
| 247 NaClNrdAllModulesInit(); | |
| 248 NaClFaultInjectionModuleInit(); | |
| 249 NaClSrpcModuleInit(); | |
| 250 } | |
| 251 | |
| 252 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
| |
| 253 struct NaClDesc *secure_pair[2] = { NULL, NULL }; | |
| 254 struct NaClDesc *pair[2] = { NULL, NULL }; | |
| 255 struct NaClDesc *channel = NULL; | |
| 256 | |
| 257 NaClLog(3, "NaClBareMetalMainStart\n"); | |
| 258 | |
| 259 NaClBareMetalAllModulesInit(); | |
| 260 NaClBareMetalCreateSecureSocketPair(secure_pair, pair); | |
| 261 channel = NaClBareMetalSetUpBootstrapChannel( | |
| 262 imc_bootstrap_handle, secure_pair[1], pair[1]); | |
| 263 if (NULL == channel) { | |
| 264 NaClLog(4, | |
| 265 "NaClBareMetalMainStart: Failed to set up bootstrap channel.\n"); | |
| 266 goto cleanup; | |
| 267 } | |
| 268 | |
| 269 /* Start the SRPC server loop. */ | |
| 270 NaClLog(4, "NaClBareMetalMainStart: Start server loop.\n"); | |
| 271 NaClBareMetalServiceAccept(secure_pair[0]); | |
| 272 | |
| 273 cleanup: | |
| 274 NaClLog(4, "NaClBareMetalMainStart: Clean up.\n"); | |
| 275 NaClDescSafeUnref(channel); | |
| 276 NaClDescSafeUnref(pair[0]); | |
| 277 NaClDescSafeUnref(pair[1]); | |
| 278 NaClDescSafeUnref(secure_pair[0]); | |
| 279 NaClDescSafeUnref(secure_pair[1]); | |
| 280 } | |
| OLD | NEW |