sel_ldr: Remove support for rodata segment at start of executable
[nativeclient.git] / service_runtime / nacl_desc_base.c
blobb699fbdd38bde9303122b0550a4f370c8482c637
1 /*
2 * Copyright 2008, Google Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
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
14 * distribution.
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.
37 #include <stdlib.h>
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)) {
72 NaClLog(LOG_FATAL,
73 "Internal error. NaClInternalHeader size not a"
74 " multiple of 16\n");
76 ndp->ref_count = 1;
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"),
86 (uintptr_t) ndp,
87 ndp->ref_count);
89 NaClLog(4, "NaClDescDtor(0x%08"PRIxPTR"), refcount 0, destroying.\n",
90 (uintptr_t) ndp);
91 NaClMutexDtor(&ndp->mu);
94 struct NaClDesc *NaClDescRef(struct NaClDesc *ndp)
96 NaClLog(4, "NaClDescRef(0x%08"PRIxPTR").\n",
97 (uintptr_t) ndp);
98 NaClXMutexLock(&ndp->mu);
99 if (0 == ++ndp->ref_count) {
100 NaClLog(LOG_FATAL, "NaClDescRef integer overflow\n");
102 NaClXMutexUnlock(&ndp->mu);
103 return ndp;
106 void NaClDescUnref(struct NaClDesc *ndp)
108 int destroy;
110 NaClLog(4, "NaClDescUnref(0x%08"PRIxPTR").\n",
111 (uintptr_t) ndp);
112 NaClXMutexLock(&ndp->mu);
113 if (0 == ndp->ref_count) {
114 NaClLog(LOG_FATAL,
115 "NaClDescUnref on 0x%08"PRIxPTR", refcount already zero!\n",
116 (uintptr_t) ndp);
118 destroy = (0 == --ndp->ref_count);
119 NaClXMutexUnlock(&ndp->mu);
120 if (destroy) {
121 (*ndp->vtbl->Dtor)(ndp);
122 free(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 */
141 switch (type_tag) {
142 #define MAP(E) case E: do { return #E; } while (0)
143 MAP(NACL_DESC_DIR);
144 MAP(NACL_DESC_HOST_IO);
145 MAP(NACL_DESC_CONN_CAP);
146 MAP(NACL_DESC_BOUND_SOCKET);
147 MAP(NACL_DESC_CONNECTED_SOCKET);
148 MAP(NACL_DESC_SHM);
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,
162 void *start_addr,
163 size_t len,
164 int prot,
165 int flags,
166 off_t offset)
168 NaClLog(LOG_ERROR,
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,
176 void *start_addr,
177 size_t len)
179 NaClLog(LOG_ERROR,
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,
187 void *start_addr,
188 size_t len)
190 NaClLog(LOG_ERROR,
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,
198 void *buf,
199 size_t len)
201 NaClLog(LOG_ERROR,
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,
209 void const *buf,
210 size_t len)
212 NaClLog(LOG_ERROR,
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,
220 off_t offset,
221 int whence)
223 NaClLog(LOG_ERROR,
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,
231 int request,
232 void *arg)
234 NaClLog(LOG_ERROR,
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)
244 NaClLog(LOG_ERROR,
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)
253 NaClLog(LOG_ERROR,
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,
261 void *dirp,
262 size_t count)
264 NaClLog(LOG_ERROR,
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,
271 size_t *nbytes,
272 size_t *nhandles)
274 NaClLog(LOG_ERROR,
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)
283 NaClLog(LOG_ERROR,
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)
292 NaClLog(LOG_ERROR,
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)
301 NaClLog(LOG_ERROR,
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)
310 NaClLog(LOG_ERROR,
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)
320 NaClLog(LOG_ERROR,
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)
331 NaClLog(LOG_ERROR,
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)
340 NaClLog(LOG_ERROR,
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)
349 NaClLog(LOG_ERROR,
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,
358 int flags)
360 NaClLog(LOG_ERROR,
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,
369 int flags)
371 NaClLog(LOG_ERROR,
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)
380 NaClLog(LOG_ERROR,
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)
389 NaClLog(LOG_ERROR,
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)
398 NaClLog(LOG_ERROR,
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)
407 NaClLog(LOG_ERROR,
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)
416 NaClLog(LOG_ERROR,
417 "GetValue method is not implemented for object of type %s\n",
418 NaClDescTypeString(vself->vtbl->typeTag));
419 return -NACL_ABI_EINVAL;