2 * Copyright 2008, Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * NaCl Service Runtime. I/O Descriptor / Handle abstraction. Memory
34 * mapping using descriptors.
39 #include "native_client/include/portability.h"
41 #include "native_client/service_runtime/nacl_config.h"
42 #include "native_client/service_runtime/nacl_log.h"
43 #include "native_client/service_runtime/nacl_desc_base.h"
44 #include "native_client/service_runtime/nacl_sync_checked.h"
45 #include "native_client/service_runtime/sel_util.h"
48 * This file contains base class code for NaClDesc.
50 * The implementation for following subclasses are elsewhere, but here
51 * is an enumeration of them with a brief description:
53 * NaClDescIoDesc is the subclass that wraps host-OS descriptors
54 * provided by NaClHostDesc (which gives an OS-independent abstraction
55 * for host-OS descriptors).
57 * NaClDescImcDesc is the subclass that wraps IMC descriptors.
59 * NaClDescMutex and NaClDescCondVar are the subclasses that
60 * wrap the non-transferrable synchronization objects.
62 * These NaClDesc objects are impure in that they know about the
63 * virtual memory subsystem restriction of requiring mappings to occur
64 * in NACL_MAP_PAGESIZE (64KB) chunks, so the Map and Unmap virtual
65 * functions, at least, will enforce this restriction.
68 int NaClDescCtor(struct NaClDesc
*ndp
)
70 /* this should be a compile-time test */
71 if (0 != (sizeof(struct NaClInternalHeader
) & 0xf)) {
73 "Internal error. NaClInternalHeader size not a"
77 return NaClMutexCtor(&ndp
->mu
);
80 void NaClDescDtor(struct NaClDesc
*ndp
)
82 if (0 != ndp
->ref_count
) {
83 NaClLog(LOG_FATAL
, ("NaClDescDtor invoked on a generic descriptor"
84 " at 0x%08"PRIxPTR
" with non-zero"
85 " reference count (%d)\n"),
89 NaClLog(4, "NaClDescDtor(0x%08"PRIxPTR
"), refcount 0, destroying.\n",
91 NaClMutexDtor(&ndp
->mu
);
94 struct NaClDesc
*NaClDescRef(struct NaClDesc
*ndp
)
96 NaClLog(4, "NaClDescRef(0x%08"PRIxPTR
").\n",
98 NaClXMutexLock(&ndp
->mu
);
99 if (0 == ++ndp
->ref_count
) {
100 NaClLog(LOG_FATAL
, "NaClDescRef integer overflow\n");
102 NaClXMutexUnlock(&ndp
->mu
);
106 void NaClDescUnref(struct NaClDesc
*ndp
)
110 NaClLog(4, "NaClDescUnref(0x%08"PRIxPTR
").\n",
112 NaClXMutexLock(&ndp
->mu
);
113 if (0 == ndp
->ref_count
) {
115 "NaClDescUnref on 0x%08"PRIxPTR
", refcount already zero!\n",
118 destroy
= (0 == --ndp
->ref_count
);
119 NaClXMutexUnlock(&ndp
->mu
);
121 (*ndp
->vtbl
->Dtor
)(ndp
);
126 int (*NaClDescInternalize
[NACL_DESC_TYPE_MAX
])(struct NaClDesc
**,
127 struct NaClDescXferState
*) = {
128 NaClDescDirInternalize
,
129 NaClDescIoInternalize
,
130 NaClDescConnCapInternalize
,
131 NaClDescImcBoundDescInternalize
,
132 NaClDescImcDescInternalize
,
133 NaClDescImcShmInternalize
,
134 NaClDescMutexInternalize
,
135 NaClDescCondVarInternalize
,
138 char const *NaClDescTypeString(enum NaClDescTypeTag type_tag
)
140 /* default functions for the vtable - return NOT_IMPLEMENTED */
142 #define MAP(E) case E: do { return #E; } while (0)
144 MAP(NACL_DESC_HOST_IO
);
145 MAP(NACL_DESC_CONN_CAP
);
146 MAP(NACL_DESC_BOUND_SOCKET
);
147 MAP(NACL_DESC_CONNECTED_SOCKET
);
149 MAP(NACL_DESC_MUTEX
);
150 MAP(NACL_DESC_CONDVAR
);
151 MAP(NACL_DESC_SEMAPHORE
);
153 return "BAD TYPE TAG";
155 void NaClDescDtorNotImplemented(struct NaClDesc
*vself
)
157 NaClLog(LOG_FATAL
, "Must implement a destructor!\n");
160 int NaClDescMapNotImplemented(struct NaClDesc
*vself
,
161 struct NaClDescEffector
*effp
,
169 "Map method is not implemented for object of type %s\n",
170 NaClDescTypeString(vself
->vtbl
->typeTag
));
171 return -NACL_ABI_EINVAL
;
174 int NaClDescUnmapUnsafeNotImplemented(struct NaClDesc
*vself
,
175 struct NaClDescEffector
*effp
,
180 "Map method is not implemented for object of type %s\n",
181 NaClDescTypeString(vself
->vtbl
->typeTag
));
182 return -NACL_ABI_EINVAL
;
185 int NaClDescUnmapNotImplemented(struct NaClDesc
*vself
,
186 struct NaClDescEffector
*effp
,
191 "Unmap method is not implemented for object of type %s\n",
192 NaClDescTypeString(vself
->vtbl
->typeTag
));
193 return -NACL_ABI_EINVAL
;
196 ssize_t
NaClDescReadNotImplemented(struct NaClDesc
*vself
,
197 struct NaClDescEffector
*effp
,
202 "Read method is not implemented for object of type %s\n",
203 NaClDescTypeString(vself
->vtbl
->typeTag
));
204 return -NACL_ABI_EINVAL
;
207 ssize_t
NaClDescWriteNotImplemented(struct NaClDesc
*vself
,
208 struct NaClDescEffector
*effp
,
213 "Write method is not implemented for object of type %s\n",
214 NaClDescTypeString(vself
->vtbl
->typeTag
));
215 return -NACL_ABI_EINVAL
;
218 int NaClDescSeekNotImplemented(struct NaClDesc
*vself
,
219 struct NaClDescEffector
*effp
,
224 "Seek method is not implemented for object of type %s\n",
225 NaClDescTypeString(vself
->vtbl
->typeTag
));
226 return -NACL_ABI_EINVAL
;
229 int NaClDescIoctlNotImplemented(struct NaClDesc
*vself
,
230 struct NaClDescEffector
*effp
,
235 "Ioctl method is not implemented for object of type %s\n",
236 NaClDescTypeString(vself
->vtbl
->typeTag
));
237 return -NACL_ABI_EINVAL
;
240 int NaClDescFstatNotImplemented(struct NaClDesc
*vself
,
241 struct NaClDescEffector
*effp
,
242 struct nacl_abi_stat
*statbuf
)
245 "Fstat method is not implemented for object of type %s\n",
246 NaClDescTypeString(vself
->vtbl
->typeTag
));
247 return -NACL_ABI_EINVAL
;
250 int NaClDescCloseNotImplemented(struct NaClDesc
*vself
,
251 struct NaClDescEffector
*effp
)
254 "Close method is not implemented for object of type %s\n",
255 NaClDescTypeString(vself
->vtbl
->typeTag
));
256 return -NACL_ABI_EINVAL
;
259 ssize_t
NaClDescGetdentsNotImplemented(struct NaClDesc
*vself
,
260 struct NaClDescEffector
*effp
,
265 "Getdents method is not implemented for object of type %s\n",
266 NaClDescTypeString(vself
->vtbl
->typeTag
));
267 return -NACL_ABI_EINVAL
;
270 int NaClDescExternalizeSizeNotImplemented(struct NaClDesc
*vself
,
275 "ExternalizeSize method is not implemented for object of type %s\n",
276 NaClDescTypeString(vself
->vtbl
->typeTag
));
277 return -NACL_ABI_EINVAL
;
280 int NaClDescExternalizeNotImplemented(struct NaClDesc
*vself
,
281 struct NaClDescXferState
*xfer
)
284 "Externalize method is not implemented for object of type %s\n",
285 NaClDescTypeString(vself
->vtbl
->typeTag
));
286 return -NACL_ABI_EINVAL
;
289 int NaClDescLockNotImplemented(struct NaClDesc
*vself
,
290 struct NaClDescEffector
*effp
)
293 "Lock method is not implemented for object of type %s\n",
294 NaClDescTypeString(vself
->vtbl
->typeTag
));
295 return -NACL_ABI_EINVAL
;
298 int NaClDescTryLockNotImplemented(struct NaClDesc
*vself
,
299 struct NaClDescEffector
*effp
)
302 "TryLock method is not implemented for object of type %s\n",
303 NaClDescTypeString(vself
->vtbl
->typeTag
));
304 return -NACL_ABI_EINVAL
;
307 int NaClDescUnlockNotImplemented(struct NaClDesc
*vself
,
308 struct NaClDescEffector
*effp
)
311 "Unlock method is not implemented for object of type %s\n",
312 NaClDescTypeString(vself
->vtbl
->typeTag
));
313 return -NACL_ABI_EINVAL
;
316 int NaClDescWaitNotImplemented(struct NaClDesc
*vself
,
317 struct NaClDescEffector
*effp
,
318 struct NaClDesc
*mutex
)
321 "Wait method is not implemented for object of type %s\n",
322 NaClDescTypeString(vself
->vtbl
->typeTag
));
323 return -NACL_ABI_EINVAL
;
326 int NaClDescTimedWaitAbsNotImplemented(struct NaClDesc
*vself
,
327 struct NaClDescEffector
*effp
,
328 struct NaClDesc
*mutex
,
329 struct nacl_abi_timespec
*ts
)
332 "TimedWaitAbs method is not implemented for object of type %s\n",
333 NaClDescTypeString(vself
->vtbl
->typeTag
));
334 return -NACL_ABI_EINVAL
;
337 int NaClDescSignalNotImplemented(struct NaClDesc
*vself
,
338 struct NaClDescEffector
*effp
)
341 "Signal method is not implemented for object of type %s\n",
342 NaClDescTypeString(vself
->vtbl
->typeTag
));
343 return -NACL_ABI_EINVAL
;
346 int NaClDescBroadcastNotImplemented(struct NaClDesc
*vself
,
347 struct NaClDescEffector
*effp
)
350 "Broadcast method is not implemented for object of type %s\n",
351 NaClDescTypeString(vself
->vtbl
->typeTag
));
352 return -NACL_ABI_EINVAL
;
355 int NaClDescSendMsgNotImplemented(struct NaClDesc
*vself
,
356 struct NaClDescEffector
*effp
,
357 struct NaClMessageHeader
*dgram
,
361 "SendMsg method is not implemented for object of type %s\n",
362 NaClDescTypeString(vself
->vtbl
->typeTag
));
363 return -NACL_ABI_EINVAL
;
366 int NaClDescRecvMsgNotImplemented(struct NaClDesc
*vself
,
367 struct NaClDescEffector
*effp
,
368 struct NaClMessageHeader
*dgram
,
372 "RecvMsg method is not implemented for object of type %s\n",
373 NaClDescTypeString(vself
->vtbl
->typeTag
));
374 return -NACL_ABI_EINVAL
;
377 int NaClDescConnectAddrNotImplemented(struct NaClDesc
*vself
,
378 struct NaClDescEffector
*effp
)
381 "ConnectAddr method is not implemented for object of type %s\n",
382 NaClDescTypeString(vself
->vtbl
->typeTag
));
383 return -NACL_ABI_EINVAL
;
386 int NaClDescAcceptConnNotImplemented(struct NaClDesc
*vself
,
387 struct NaClDescEffector
*effp
)
390 "AcceptConn method is not implemented for object of type %s\n",
391 NaClDescTypeString(vself
->vtbl
->typeTag
));
392 return -NACL_ABI_EINVAL
;
395 int NaClDescPostNotImplemented(struct NaClDesc
*vself
,
396 struct NaClDescEffector
*effp
)
399 "Post method is not implemented for object of type %s\n",
400 NaClDescTypeString(vself
->vtbl
->typeTag
));
401 return -NACL_ABI_EINVAL
;
404 int NaClDescSemWaitNotImplemented(struct NaClDesc
*vself
,
405 struct NaClDescEffector
*effp
)
408 "SemWait method is not implemented for object of type %s\n",
409 NaClDescTypeString(vself
->vtbl
->typeTag
));
410 return -NACL_ABI_EINVAL
;
413 int NaClDescGetValueNotImplemented(struct NaClDesc
*vself
,
414 struct NaClDescEffector
*effp
)
417 "GetValue method is not implemented for object of type %s\n",
418 NaClDescTypeString(vself
->vtbl
->typeTag
));
419 return -NACL_ABI_EINVAL
;