1 : /*
2 : * Copyright (c) 2012 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 : /*
8 : * NaCl Service Runtime. I/O Descriptor / Handle abstraction. Memory
9 : * mapping using descriptors.
10 : */
11 : #include <errno.h>
12 :
13 : #include "native_client/src/include/nacl_platform.h"
14 : #include "native_client/src/include/portability.h"
15 :
16 : #include "native_client/src/shared/platform/nacl_host_desc.h"
17 : #include "native_client/src/shared/platform/nacl_log.h"
18 :
19 : #include "native_client/src/trusted/service_runtime/include/bits/mman.h"
20 : #include "native_client/src/trusted/service_runtime/include/sys/errno.h"
21 :
22 : /*
23 : * If you are using this as a kernel-style return, remember that you
24 : * should negate its return value.
25 : */
26 0 : int NaClXlateErrno(int errnum) {
27 0 : switch (errnum) {
28 : /*
29 : * Unfortunately a macro cannot expand to contain #ifdef....
30 : *
31 : * TODO(bsy): All host-OS conditional errnos should map into a
32 : * generic errno.
33 : */
34 0 : case 0: return 0;
35 : #define MAP(E) case E: do { return NACL_ABI_ ## E; } while (0)
36 0 : MAP(EPERM);
37 0 : MAP(ENOENT);
38 0 : MAP(ESRCH);
39 0 : MAP(EINTR);
40 0 : MAP(EIO);
41 0 : MAP(ENXIO);
42 0 : MAP(E2BIG);
43 0 : MAP(ENOEXEC);
44 0 : MAP(EBADF);
45 0 : MAP(ECHILD);
46 0 : MAP(EAGAIN);
47 0 : MAP(ENOMEM);
48 0 : MAP(EACCES);
49 0 : MAP(EFAULT);
50 0 : MAP(EBUSY);
51 0 : MAP(EEXIST);
52 0 : MAP(EXDEV);
53 0 : MAP(ENODEV);
54 0 : MAP(ENOTDIR);
55 0 : MAP(EISDIR);
56 0 : MAP(EINVAL);
57 0 : MAP(ENFILE);
58 0 : MAP(EMFILE);
59 0 : MAP(ENOTTY);
60 0 : MAP(EFBIG);
61 0 : MAP(ENOSPC);
62 0 : MAP(ESPIPE);
63 0 : MAP(EROFS);
64 0 : MAP(EMLINK);
65 0 : MAP(EPIPE);
66 0 : MAP(ENAMETOOLONG);
67 0 : MAP(ENOSYS);
68 : #ifdef EDQUOT
69 : MAP(EDQUOT);
70 : #endif
71 0 : MAP(EDOM);
72 0 : MAP(ERANGE);
73 : #ifdef ENOMSG
74 : MAP(ENOMSG);
75 : #endif
76 : #ifdef ECHRNG
77 : MAP(ECHRNG);
78 : #endif
79 : #ifdef EL3HLT
80 : MAP(EL3HLT); /* not in osx */
81 : #endif
82 : #ifdef EL3RST
83 : MAP(EL3RST); /* not in osx */
84 : #endif
85 : #ifdef EL3RNG
86 : MAP(ELNRNG); /* not in osx */
87 : #endif
88 : #ifdef EUNATCH
89 : MAP(EUNATCH);
90 : #endif
91 : #ifdef ENOCSI
92 : MAP(ENOCSI);
93 : #endif
94 : #ifdef EL2HLT
95 : MAP(EL2HLT);
96 : #endif
97 0 : MAP(EDEADLK);
98 0 : MAP(ENOLCK);
99 : #ifdef EBADE
100 : MAP(EBADE);
101 : #endif
102 : #ifdef EBADR
103 : MAP(EBADR);
104 : #endif
105 : #ifdef EXFULL
106 : MAP(EXFULL);
107 : #endif
108 : #ifdef ENOANO
109 : MAP(ENOANO);
110 : #endif
111 : #ifdef EBADRQC
112 : MAP(EBADRQC);
113 : #endif
114 : #ifdef EBADSLT
115 : MAP(EBADSLT);
116 : #endif
117 : #if defined(EDEADLOCK) && EDEADLK != EDEADLOCK
118 : MAP(EDEADLOCK);
119 : #endif
120 : #ifdef EBFONT
121 : MAP(EBFONT);
122 : #endif
123 : #ifdef ENOSTR
124 : MAP(ENOSTR);
125 : #endif
126 : #ifdef ENODATA
127 : MAP(ENODATA);
128 : #endif
129 : #ifdef ETIME
130 : MAP(ETIME);
131 : #endif
132 : #ifdef ENOSR
133 : MAP(ENOSR);
134 : #endif
135 : #ifdef ENONET
136 : MAP(ENONET);
137 : #endif
138 : #ifdef ENOPKG
139 : MAP(ENOPKG);
140 : #endif
141 : #ifdef EREMOTE
142 : MAP(EREMOTE);
143 : #endif
144 : #ifdef ENOLINK
145 : MAP(ENOLINK);
146 : #endif
147 : #ifdef EADV
148 : MAP(EADV);
149 : #endif
150 : #ifdef ESRMNT
151 : MAP(ESRMNT);
152 : #endif
153 : #ifdef ECOMM
154 : MAP(ECOMM);
155 : #endif
156 : #ifdef EPROTO
157 : MAP(EPROTO);
158 : #endif
159 : #ifdef EMULTIHOP
160 : MAP(EMULTIHOP);
161 : #endif
162 : #ifdef ELBIN
163 : MAP(ELBIN); /* newlib only? */
164 : #endif
165 : #ifdef EDOTDOT
166 : MAP(EDOTDOT);
167 : #endif
168 : #ifdef EBADMSG
169 : MAP(EBADMSG);
170 : #endif
171 : #ifdef EFTYPE
172 : MAP(EFTYPE); /* osx has it; linux doesn't */
173 : #endif
174 : #ifdef ENOTUNIQ
175 : MAP(ENOTUNIQ);
176 : #endif
177 : #ifdef EBADFD
178 : MAP(EBADFD);
179 : #endif
180 : #ifdef EREMCHG
181 : MAP(EREMCHG);
182 : #endif
183 : #ifdef ELIBACC
184 : MAP(ELIBACC);
185 : #endif
186 : #ifdef ELIBBAD
187 : MAP(ELIBBAD);
188 : #endif
189 : #ifdef ELIBSCN
190 : MAP(ELIBSCN);
191 : #endif
192 : #ifdef ELIBMAX
193 : MAP(ELIBMAX);
194 : #endif
195 : #ifdef ELIBEXEC
196 : MAP(ELIBEXEC);
197 : #endif
198 : #ifdef ENMFILE
199 : MAP(ENMFILE); /* newlib only? */
200 : #endif
201 0 : MAP(ENOTEMPTY);
202 : #ifdef ELOOP
203 : MAP(ELOOP);
204 : #endif
205 : #ifdef EOPNOTSUPP
206 : MAP(EOPNOTSUPP);
207 : #endif
208 : #ifdef EPFNOSUPPORT
209 : MAP(EPFNOSUPPORT);
210 : #endif
211 : #ifdef ECONNRESET
212 : MAP(ECONNRESET);
213 : #endif
214 : #ifdef ENOBUFS
215 : MAP(ENOBUFS);
216 : #endif
217 : #ifdef EAFNOSUPPORT
218 : MAP(EAFNOSUPPORT);
219 : #endif
220 : #ifdef EPROTOTYPE
221 : MAP(EPROTOTYPE);
222 : #endif
223 : #ifdef ENOTSOCK
224 : MAP(ENOTSOCK);
225 : #endif
226 : #ifdef ENOPROTOOPT
227 : MAP(ENOPROTOOPT);
228 : #endif
229 : #ifdef ESHUTDOWN
230 : MAP(ESHUTDOWN);
231 : #endif
232 : #ifdef ECONNREFUSED
233 : MAP(ECONNREFUSED);
234 : #endif
235 : #ifdef EADDRINUSE
236 : MAP(EADDRINUSE);
237 : #endif
238 : #ifdef ECONNABORTED
239 : MAP(ECONNABORTED);
240 : #endif
241 : #ifdef ENETUNREACH
242 : MAP(ENETUNREACH);
243 : #endif
244 : #ifdef ENETDOWN
245 : MAP(ENETDOWN);
246 : #endif
247 : #ifdef ETIMEDOUT
248 : MAP(ETIMEDOUT);
249 : #endif
250 : #ifdef EHOSTDOWN
251 : MAP(EHOSTDOWN);
252 : #endif
253 : #ifdef EHOSTUNREACH
254 : MAP(EHOSTUNREACH);
255 : #endif
256 : #ifdef EINPROGRESS
257 : MAP(EINPROGRESS);
258 : #endif
259 : #ifdef EALREADY
260 : MAP(EALREADY);
261 : #endif
262 : #ifdef EDESTADDRREQ
263 : MAP(EDESTADDRREQ);
264 : #endif
265 : #ifdef EPROTONOSUPPORT
266 : MAP(EPROTONOSUPPORT);
267 : #endif
268 : #ifdef ESOCKTNOSUPPORT
269 : MAP(ESOCKTNOSUPPORT);
270 : #endif
271 : #ifdef EADDRNOTAVAIL
272 : MAP(EADDRNOTAVAIL);
273 : #endif
274 : #ifdef ENETRESET
275 : MAP(ENETRESET);
276 : #endif
277 : #ifdef EISCONN
278 : MAP(EISCONN);
279 : #endif
280 : #ifdef ENOTCONN
281 : MAP(ENOTCONN);
282 : #endif
283 : #ifdef ETOOMANYREFS
284 : MAP(ETOOMANYREFS);
285 : #endif
286 : #ifdef EPROCLIM
287 : MAP(EPROCLIM); /* osx has this; linux does not */
288 : /*
289 : * if we allow fork, we will need to map EAGAIN from fork to EPROCLIM,
290 : * so NaClXlateErrno would not be stateless.
291 : */
292 : #endif
293 : #ifdef EUSERS
294 : MAP(EUSERS);
295 : #endif
296 : #ifdef ESTALE
297 : MAP(ESTALE);
298 : #endif
299 : #if ENOTSUP != EOPNOTSUPP
300 : MAP(ENOTSUP);
301 : #endif
302 : #ifdef ENOMEDIUM
303 : MAP(ENOMEDIUM);
304 : #endif
305 : #ifdef ENOSHARE
306 : MAP(ENOSHARE); /* newlib only? */
307 : #endif
308 : #ifdef ECASECLASH
309 : MAP(ECASECLASH); /* newlib only? */
310 : #endif
311 0 : MAP(EILSEQ);
312 : #ifdef EOVERFLOW
313 : MAP(EOVERFLOW);
314 : #endif
315 : #ifdef ECANCELED
316 : MAP(ECANCELED);
317 : #endif
318 : #ifdef EL2NSYNC
319 : MAP(EL2NSYNC);
320 : #endif
321 : #ifdef EIDRM
322 : MAP(EIDRM);
323 : #endif
324 : #ifdef EMSGSIZE
325 : MAP(EMSGSIZE);
326 : #endif
327 : #undef MAP
328 : }
329 0 : return NACL_ABI_EINVAL; /* catch all */
330 0 : }
331 :
332 : /*
333 : * If you are using this as a kernel-style return, remember that you
334 : * should negate its return value.
335 : */
336 0 : int NaClXlateNaClSyncStatus(NaClSyncStatus status) {
337 0 : switch (status) {
338 : #define MAP(S, E) case S: do { return E; } while (0)
339 0 : MAP(NACL_SYNC_OK, 0);
340 : case NACL_SYNC_INTERNAL_ERROR:
341 : NaClLog(LOG_FATAL,
342 0 : "NaClXlateNaClSyncStatus: NACL_SYNC_INTERNAL_ERROR\n");
343 0 : MAP(NACL_SYNC_BUSY, NACL_ABI_EBUSY);
344 0 : MAP(NACL_SYNC_MUTEX_INVALID, NACL_ABI_EINVAL);
345 0 : MAP(NACL_SYNC_MUTEX_DEADLOCK, NACL_ABI_EDEADLK);
346 0 : MAP(NACL_SYNC_MUTEX_PERMISSION, NACL_ABI_EPERM);
347 0 : MAP(NACL_SYNC_MUTEX_INTERRUPTED, NACL_ABI_EINTR);
348 0 : MAP(NACL_SYNC_CONDVAR_TIMEDOUT, NACL_ABI_ETIMEDOUT);
349 0 : MAP(NACL_SYNC_CONDVAR_INTR, NACL_ABI_EINTR);
350 0 : MAP(NACL_SYNC_SEM_INTERRUPTED, NACL_ABI_EINTR);
351 0 : MAP(NACL_SYNC_SEM_RANGE_ERROR, NACL_ABI_ERANGE);
352 : #undef MAP
353 : }
354 : NaClLog(LOG_FATAL,
355 0 : "NaClXlateNaClSyncStatus: status %d\n", (int) status);
356 0 : return NACL_ABI_EINVAL; /* catch all */
357 0 : }
358 :
359 :
360 : struct NaClHostDesc *NaClHostDescPosixMake(int posix_d,
361 1 : int flags) {
362 : struct NaClHostDesc *nhdp;
363 : int error;
364 :
365 1 : nhdp = malloc(sizeof *nhdp);
366 1 : if (NULL == nhdp) {
367 : NaClLog(LOG_FATAL, "NaClHostDescPosixMake(%d,0x%x): malloc failed\n",
368 0 : posix_d, flags);
369 : }
370 1 : if (0 != (error = NaClHostDescPosixTake(nhdp, posix_d, flags))) {
371 : NaClLog(LOG_FATAL,
372 : "NaClHostDescPosixMake(%d,0x%x): Take failed, error %da\n",
373 0 : posix_d, flags, error);
374 : }
375 1 : return nhdp;
376 1 : }
377 :
378 :
379 0 : int NaClProtMap(int abi_prot) {
380 : int host_os_prot;
381 :
382 0 : host_os_prot = 0;
383 : #define M(H) do { \
384 : if (0 != (abi_prot & NACL_ABI_ ## H)) { \
385 : host_os_prot |= H; \
386 : } \
387 : } while (0)
388 0 : M(PROT_READ);
389 0 : M(PROT_WRITE);
390 0 : M(PROT_EXEC);
391 : #if PROT_NONE != 0
392 : # error "NaClProtMap: PROT_NONE is not zero -- are mprotect flags bit values?"
393 : #endif
394 0 : return host_os_prot;
395 : #undef M
396 0 : }
397 :
398 : void NaClHostDescCheckValidity(char const *fn_name,
399 6 : struct NaClHostDesc *d) {
400 6 : if (NULL == d) {
401 0 : NaClLog(LOG_FATAL, "%s: 'this' is NULL\n", fn_name);
402 : }
403 6 : if (-1 == d->d) {
404 0 : NaClLog(LOG_FATAL, "%s: already closed\n", fn_name);
405 : }
406 6 : }
|