1 : /*
2 : * Copyright (c) 2013 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 : #include "native_client/src/trusted/service_runtime/sys_exception.h"
8 :
9 : #include "native_client/src/shared/platform/nacl_sync_checked.h"
10 : #include "native_client/src/trusted/service_runtime/include/sys/errno.h"
11 : #include "native_client/src/trusted/service_runtime/nacl_app_thread.h"
12 : #include "native_client/src/trusted/service_runtime/nacl_copy.h"
13 : #include "native_client/src/trusted/service_runtime/sel_ldr.h"
14 : #include "native_client/src/trusted/service_runtime/win/debug_exception_handler.h"
15 :
16 :
17 163 : int32_t NaClSysExceptionHandler(struct NaClAppThread *natp,
18 163 : uint32_t handler_addr,
19 163 : uint32_t old_handler) {
20 163 : struct NaClApp *nap = natp->nap;
21 163 : int32_t rv = -NACL_ABI_EINVAL;
22 :
23 163 : if (!nap->enable_exception_handling) {
24 2 : rv = -NACL_ABI_ENOSYS;
25 2 : goto no_lock_exit;
26 : }
27 161 : if (!NaClIsValidJumpTarget(nap, handler_addr)) {
28 2 : rv = -NACL_ABI_EFAULT;
29 2 : goto no_lock_exit;
30 : }
31 159 : NaClXMutexLock(&nap->exception_mu);
32 :
33 : /*
34 : * This needs to be done while holding the lock so that we don't
35 : * start two Windows debug exception handlers.
36 : */
37 159 : if (handler_addr != 0) {
38 101 : if (!NaClDebugExceptionHandlerEnsureAttached(nap)) {
39 0 : rv = -NACL_ABI_ENOSYS;
40 0 : goto unlock_exit;
41 : }
42 101 : }
43 :
44 159 : if (0 != old_handler &&
45 2 : !NaClCopyOutToUser(nap, (uintptr_t) old_handler,
46 : &nap->exception_handler,
47 : sizeof nap->exception_handler)) {
48 0 : rv = -NACL_ABI_EFAULT;
49 0 : goto unlock_exit;
50 : }
51 159 : nap->exception_handler = handler_addr;
52 159 : rv = 0;
53 : unlock_exit:
54 159 : NaClXMutexUnlock(&nap->exception_mu);
55 : no_lock_exit:
56 163 : return rv;
57 : }
58 :
59 40 : int32_t NaClSysExceptionStack(struct NaClAppThread *natp,
60 40 : uint32_t stack_addr,
61 40 : uint32_t stack_size) {
62 40 : if (!natp->nap->enable_exception_handling) {
63 2 : return -NACL_ABI_ENOSYS;
64 : }
65 38 : if (kNaClBadAddress == NaClUserToSysAddrNullOkay(natp->nap,
66 : stack_addr + stack_size)) {
67 0 : return -NACL_ABI_EINVAL;
68 : }
69 38 : natp->exception_stack = stack_addr + stack_size;
70 38 : return 0;
71 40 : }
72 :
73 14920 : int32_t NaClSysExceptionClearFlag(struct NaClAppThread *natp) {
74 14920 : if (!natp->nap->enable_exception_handling) {
75 2 : return -NACL_ABI_ENOSYS;
76 : }
77 14918 : natp->exception_flag = 0;
78 14918 : return 0;
79 14920 : }
|