Make ncval-annotate and ncval-stubout executable
[nativeclient.git] / service_runtime / nacl_syscall_hook.c
blobb5a00d5bb00df2b7d14c8e2e0bda5ef5beb26801
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 run-time.
36 #include "native_client/include/portability.h"
37 #include "native_client/include/nacl_platform.h"
39 #include <stdlib.h>
40 #include <errno.h>
41 #if NACL_WINDOWS
42 /* TODO: IS THIS STILL NEEDED FOR WINDOWS ??? */
43 #include <sys/timeb.h>
44 #endif
45 #include <fcntl.h>
46 #include <time.h>
48 #include "native_client/service_runtime/nacl_globals.h"
49 #include "native_client/service_runtime/nacl_config.h"
50 #include "native_client/service_runtime/nacl_log.h"
51 #include "native_client/service_runtime/sel_ldr.h"
52 #include "native_client/service_runtime/nacl_switch_to_app.h"
53 #include "native_client/service_runtime/nacl_syscall_handlers.h"
55 #include "native_client/service_runtime/include/sys/errno.h"
56 #include "native_client/service_runtime/include/bits/nacl_syscalls.h"
59 * Simple RPC support. The default socket file descriptor is invalid.
61 int NaClSrpcFileDescriptor = -1;
65 NORETURN void NaClSyscallCSegHook(int32_t ldt_ix)
67 struct NaClAppThread *natp = nacl_thread[ldt_ix];
68 struct NaClApp *nap = natp->nap;
69 struct NaClThreadContext *user = &natp->user;
70 uintptr_t tramp_addr;
71 uint32_t tramp_ret;
72 uint32_t aligned_tramp_ret;
73 uint32_t sysnum;
75 /* esp must be okay for control to have gotten here */
76 #if !BENCHMARK
77 NaClLog(4, "Entered NaClSyscallCSegHook\n");
78 NaClLog(4, "user esp 0x%08x\n", user->esp);
79 #endif
81 * on user stack:
82 * esp+0: retaddr from lcall
83 * esp+4: code seg from lcall
84 * esp+8: retaddr from syscall wrapper
85 * esp+c: ...
87 tramp_addr = NaClUserToSys(nap, user->esp);
88 tramp_ret = *(uint32_t *) tramp_addr;
90 * return addr could have been tampered with by another thread, but
91 * the only result would be a bad sysnum.
93 sysnum = (tramp_ret - NACL_SYSCALL_START_ADDR)
94 >> NACL_SYSCALL_BLOCK_SHIFT;
96 #if !BENCHMARK
97 NaClLog(4, "system call %d\n", sysnum);
98 #endif
100 * keep tramp_ret in user addr; do not bother to ensure tramp_addr +
101 * 8 is valid, since even if we loaded two NaClApps next to each
102 * other this would just load the trampoline code, or hit the
103 * inaccessible page for NULL pointer detection (once we get that
104 * implemented). if it is not a valid address, we would just crash.
106 tramp_ret = *(uint32_t *) (tramp_addr + 8);
107 if (0 != nap->xlate_base) {
109 * ensure that tramp_ret value is ok. no need to ensure that this
110 * is in the app's address space, since the syscall return will
111 * just result in a fault after we reconstitute the sandbox and
112 * attempt to pass control to this address.
114 aligned_tramp_ret = tramp_ret & ~(nap->align_boundary - 1);
115 if (tramp_ret != aligned_tramp_ret) {
116 NaClLog(LOG_FATAL, ("NaClSyscallCSegHook: tramp_ret infinite loop:"
117 " %08x != %08x\nMake sure NaCl SDK and sel_ldr"
118 " agree on alignment (ELF header of NaCl app"
119 " claims alignment is %d).\n"),
120 tramp_ret, aligned_tramp_ret, nap->align_boundary);
122 tramp_ret = aligned_tramp_ret;
125 user->esp += 0xc; /* call, lcall */
126 if (sysnum >= NACL_MAX_SYSCALLS) {
127 NaClLog(2, "INVALID system call %d\n", sysnum);
128 natp->sysret = -NACL_ABI_EINVAL;
129 } else {
130 #if !BENCHMARK
131 NaClLog(4, "making system call %d, handler 0x%08x\n",
132 sysnum, (uintptr_t) nacl_syscall[sysnum].handler);
133 #endif
135 natp->x_esp = (uint32_t *) (tramp_addr + 0xc);
136 natp->sysret = (*nacl_syscall[sysnum].handler)(natp);
138 #if !BENCHMARK
139 NaClLog(4, "returning from system call %d, return value %d (0x%x)\n",
140 sysnum, natp->sysret, natp->sysret);
142 NaClLog(4, "return target 0x%08x\n", tramp_ret);
143 NaClLog(4, "user esp 0x%08x\n", user->esp);
144 #endif
145 NaClSwitchToApp(natp, tramp_ret);
146 /* NOTREACHED */
148 fprintf(stderr, "NORETURN NaClSwitchToApp returned!?!\n");
149 abort();