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 166 : int32_t NaClSysExceptionHandler(struct NaClAppThread *natp,
18 : uint32_t handler_addr,
19 : uint32_t old_handler) {
20 166 : struct NaClApp *nap = natp->nap;
21 166 : int32_t rv = -NACL_ABI_EINVAL;
22 :
23 166 : if (!nap->enable_exception_handling) {
24 2 : rv = -NACL_ABI_ENOSYS;
25 2 : goto no_lock_exit;
26 : }
27 164 : if (!NaClIsValidJumpTarget(nap, handler_addr)) {
28 2 : rv = -NACL_ABI_EFAULT;
29 2 : goto no_lock_exit;
30 : }
31 162 : 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 162 : if (handler_addr != 0) {
38 104 : if (!NaClDebugExceptionHandlerEnsureAttached(nap)) {
39 0 : rv = -NACL_ABI_ENOSYS;
40 0 : goto unlock_exit;
41 : }
42 : }
43 :
44 164 : if (0 != old_handler &&
45 2 : !NaClCopyOutToUser(nap, (uintptr_t) old_handler,
46 2 : &nap->exception_handler,
47 : sizeof nap->exception_handler)) {
48 0 : rv = -NACL_ABI_EFAULT;
49 0 : goto unlock_exit;
50 : }
51 162 : nap->exception_handler = handler_addr;
52 162 : rv = 0;
53 : unlock_exit:
54 162 : NaClXMutexUnlock(&nap->exception_mu);
55 : no_lock_exit:
56 166 : return rv;
57 : }
58 :
59 41 : int32_t NaClSysExceptionStack(struct NaClAppThread *natp,
60 : uint32_t stack_addr,
61 : uint32_t stack_size) {
62 41 : if (!natp->nap->enable_exception_handling) {
63 2 : return -NACL_ABI_ENOSYS;
64 : }
65 39 : if (kNaClBadAddress == NaClUserToSysAddrNullOkay(natp->nap,
66 : stack_addr + stack_size)) {
67 0 : return -NACL_ABI_EINVAL;
68 : }
69 39 : natp->exception_stack = stack_addr + stack_size;
70 39 : return 0;
71 : }
72 :
73 115345 : int32_t NaClSysExceptionClearFlag(struct NaClAppThread *natp) {
74 115345 : if (!natp->nap->enable_exception_handling) {
75 2 : return -NACL_ABI_ENOSYS;
76 : }
77 115343 : natp->exception_flag = 0;
78 115343 : return 0;
79 : }
|