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 |