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%08x with non-zero reference count (%d)\n"),
88 NaClLog(4, "NaClDescDtor(0x%08x), refcount 0, destroying.\n",
90 NaClMutexDtor(&ndp
->mu
);
93 struct NaClDesc
*NaClDescRef(struct NaClDesc
*ndp
)
95 NaClLog(4, "NaClDescRef(0x%08x).\n",
97 NaClXMutexLock(&ndp
->mu
);
98 if (0 == ++ndp
->ref_count
) {
99 NaClLog(LOG_FATAL
, "NaClDescRef integer overflow\n");
101 NaClXMutexUnlock(&ndp
->mu
);
105 void NaClDescUnref(struct NaClDesc
*ndp
)
109 NaClLog(4, "NaClDescUnref(0x%08x).\n",
111 NaClXMutexLock(&ndp
->mu
);
112 if (0 == ndp
->ref_count
) {
113 NaClLog(LOG_FATAL
, "NaClDescUnref on 0x%08x, refcount already zero!\n",
116 destroy
= (0 == --ndp
->ref_count
);
117 NaClXMutexUnlock(&ndp
->mu
);
119 (*ndp
->vtbl
->Dtor
)(ndp
);
124 int (*NaClDescInternalize
[NACL_DESC_TYPE_MAX
])(struct NaClDesc
**,
125 struct NaClDescXferState
*) = {
126 NaClDescDirInternalize
,
127 NaClDescIoInternalize
,
128 NaClDescConnCapInternalize
,
129 NaClDescImcBoundDescInternalize
,
130 NaClDescImcDescInternalize
,
131 NaClDescImcShmInternalize
,
132 NaClDescMutexInternalize
,
133 NaClDescCondVarInternalize
,
136 char const *NaClDescTypeString(enum NaClDescTypeTag type_tag
)
138 /* default functions for the vtable - return NOT_IMPLEMENTED */
140 #define MAP(E) case E: do { return #E; } while (0)
142 MAP(NACL_DESC_HOST_IO
);
143 MAP(NACL_DESC_CONN_CAP
);
144 MAP(NACL_DESC_BOUND_SOCKET
);
145 MAP(NACL_DESC_CONNECTED_SOCKET
);
147 MAP(NACL_DESC_MUTEX
);
148 MAP(NACL_DESC_CONDVAR
);
149 MAP(NACL_DESC_SEMAPHORE
);
151 return "BAD TYPE TAG";
153 void NaClDescDtorNotImplemented(struct NaClDesc
*vself
)
155 NaClLog(LOG_FATAL
, "Must implement a destructor!\n");
158 int NaClDescMapNotImplemented(struct NaClDesc
*vself
,
159 struct NaClDescEffector
*effp
,
167 "Map method is not implemented for object of type %s\n",
168 NaClDescTypeString(vself
->vtbl
->typeTag
));
169 return -NACL_ABI_EINVAL
;
172 int NaClDescUnmapUnsafeNotImplemented(struct NaClDesc
*vself
,
173 struct NaClDescEffector
*effp
,
178 "Map method is not implemented for object of type %s\n",
179 NaClDescTypeString(vself
->vtbl
->typeTag
));
180 return -NACL_ABI_EINVAL
;
183 int NaClDescUnmapNotImplemented(struct NaClDesc
*vself
,
184 struct NaClDescEffector
*effp
,
189 "Unmap method is not implemented for object of type %s\n",
190 NaClDescTypeString(vself
->vtbl
->typeTag
));
191 return -NACL_ABI_EINVAL
;
194 ssize_t
NaClDescReadNotImplemented(struct NaClDesc
*vself
,
195 struct NaClDescEffector
*effp
,
200 "Read method is not implemented for object of type %s\n",
201 NaClDescTypeString(vself
->vtbl
->typeTag
));
202 return -NACL_ABI_EINVAL
;
205 ssize_t
NaClDescWriteNotImplemented(struct NaClDesc
*vself
,
206 struct NaClDescEffector
*effp
,
211 "Write method is not implemented for object of type %s\n",
212 NaClDescTypeString(vself
->vtbl
->typeTag
));
213 return -NACL_ABI_EINVAL
;
216 int NaClDescSeekNotImplemented(struct NaClDesc
*vself
,
217 struct NaClDescEffector
*effp
,
222 "Seek method is not implemented for object of type %s\n",
223 NaClDescTypeString(vself
->vtbl
->typeTag
));
224 return -NACL_ABI_EINVAL
;
227 int NaClDescIoctlNotImplemented(struct NaClDesc
*vself
,
228 struct NaClDescEffector
*effp
,
233 "Ioctl method is not implemented for object of type %s\n",
234 NaClDescTypeString(vself
->vtbl
->typeTag
));
235 return -NACL_ABI_EINVAL
;
238 int NaClDescFstatNotImplemented(struct NaClDesc
*vself
,
239 struct NaClDescEffector
*effp
,
240 struct nacl_abi_stat
*statbuf
)
243 "Fstat method is not implemented for object of type %s\n",
244 NaClDescTypeString(vself
->vtbl
->typeTag
));
245 return -NACL_ABI_EINVAL
;
248 int NaClDescCloseNotImplemented(struct NaClDesc
*vself
,
249 struct NaClDescEffector
*effp
)
252 "Close method is not implemented for object of type %s\n",
253 NaClDescTypeString(vself
->vtbl
->typeTag
));
254 return -NACL_ABI_EINVAL
;
257 ssize_t
NaClDescGetdentsNotImplemented(struct NaClDesc
*vself
,
258 struct NaClDescEffector
*effp
,
263 "Getdents method is not implemented for object of type %s\n",
264 NaClDescTypeString(vself
->vtbl
->typeTag
));
265 return -NACL_ABI_EINVAL
;
268 int NaClDescExternalizeSizeNotImplemented(struct NaClDesc
*vself
,
273 "ExternalizeSize method is not implemented for object of type %s\n",
274 NaClDescTypeString(vself
->vtbl
->typeTag
));
275 return -NACL_ABI_EINVAL
;
278 int NaClDescExternalizeNotImplemented(struct NaClDesc
*vself
,
279 struct NaClDescXferState
*xfer
)
282 "Externalize method is not implemented for object of type %s\n",
283 NaClDescTypeString(vself
->vtbl
->typeTag
));
284 return -NACL_ABI_EINVAL
;
287 int NaClDescLockNotImplemented(struct NaClDesc
*vself
,
288 struct NaClDescEffector
*effp
)
291 "Lock method is not implemented for object of type %s\n",
292 NaClDescTypeString(vself
->vtbl
->typeTag
));
293 return -NACL_ABI_EINVAL
;
296 int NaClDescTryLockNotImplemented(struct NaClDesc
*vself
,
297 struct NaClDescEffector
*effp
)
300 "TryLock method is not implemented for object of type %s\n",
301 NaClDescTypeString(vself
->vtbl
->typeTag
));
302 return -NACL_ABI_EINVAL
;
305 int NaClDescUnlockNotImplemented(struct NaClDesc
*vself
,
306 struct NaClDescEffector
*effp
)
309 "Unlock method is not implemented for object of type %s\n",
310 NaClDescTypeString(vself
->vtbl
->typeTag
));
311 return -NACL_ABI_EINVAL
;
314 int NaClDescWaitNotImplemented(struct NaClDesc
*vself
,
315 struct NaClDescEffector
*effp
,
316 struct NaClDesc
*mutex
)
319 "Wait method is not implemented for object of type %s\n",
320 NaClDescTypeString(vself
->vtbl
->typeTag
));
321 return -NACL_ABI_EINVAL
;
324 int NaClDescTimedWaitAbsNotImplemented(struct NaClDesc
*vself
,
325 struct NaClDescEffector
*effp
,
326 struct NaClDesc
*mutex
,
327 struct nacl_abi_timespec
*ts
)
330 "TimedWaitAbs method is not implemented for object of type %s\n",
331 NaClDescTypeString(vself
->vtbl
->typeTag
));
332 return -NACL_ABI_EINVAL
;
335 int NaClDescSignalNotImplemented(struct NaClDesc
*vself
,
336 struct NaClDescEffector
*effp
)
339 "Signal method is not implemented for object of type %s\n",
340 NaClDescTypeString(vself
->vtbl
->typeTag
));
341 return -NACL_ABI_EINVAL
;
344 int NaClDescBroadcastNotImplemented(struct NaClDesc
*vself
,
345 struct NaClDescEffector
*effp
)
348 "Broadcast method is not implemented for object of type %s\n",
349 NaClDescTypeString(vself
->vtbl
->typeTag
));
350 return -NACL_ABI_EINVAL
;
353 int NaClDescSendMsgNotImplemented(struct NaClDesc
*vself
,
354 struct NaClDescEffector
*effp
,
355 struct NaClMessageHeader
*dgram
,
359 "SendMsg method is not implemented for object of type %s\n",
360 NaClDescTypeString(vself
->vtbl
->typeTag
));
361 return -NACL_ABI_EINVAL
;
364 int NaClDescRecvMsgNotImplemented(struct NaClDesc
*vself
,
365 struct NaClDescEffector
*effp
,
366 struct NaClMessageHeader
*dgram
,
370 "RecvMsg method is not implemented for object of type %s\n",
371 NaClDescTypeString(vself
->vtbl
->typeTag
));
372 return -NACL_ABI_EINVAL
;
375 int NaClDescConnectAddrNotImplemented(struct NaClDesc
*vself
,
376 struct NaClDescEffector
*effp
)
379 "ConnectAddr method is not implemented for object of type %s\n",
380 NaClDescTypeString(vself
->vtbl
->typeTag
));
381 return -NACL_ABI_EINVAL
;
384 int NaClDescAcceptConnNotImplemented(struct NaClDesc
*vself
,
385 struct NaClDescEffector
*effp
)
388 "AcceptConn method is not implemented for object of type %s\n",
389 NaClDescTypeString(vself
->vtbl
->typeTag
));
390 return -NACL_ABI_EINVAL
;
393 int NaClDescPostNotImplemented(struct NaClDesc
*vself
,
394 struct NaClDescEffector
*effp
)
397 "Post method is not implemented for object of type %s\n",
398 NaClDescTypeString(vself
->vtbl
->typeTag
));
399 return -NACL_ABI_EINVAL
;
402 int NaClDescSemWaitNotImplemented(struct NaClDesc
*vself
,
403 struct NaClDescEffector
*effp
)
406 "SemWait method is not implemented for object of type %s\n",
407 NaClDescTypeString(vself
->vtbl
->typeTag
));
408 return -NACL_ABI_EINVAL
;
411 int NaClDescGetValueNotImplemented(struct NaClDesc
*vself
,
412 struct NaClDescEffector
*effp
)
415 "GetValue method is not implemented for object of type %s\n",
416 NaClDescTypeString(vself
->vtbl
->typeTag
));
417 return -NACL_ABI_EINVAL
;