OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 #include <elf.h> |
4 #include <errno.h> | 5 #include <errno.h> |
5 #include <signal.h> | 6 #include <signal.h> |
| 7 #include <sys/ucontext.h> |
6 | 8 |
7 #include <map> | 9 #include "base/logging.h" |
8 | |
9 #include "components/nacl/loader/nonsfi/irt_interfaces.h" | 10 #include "components/nacl/loader/nonsfi/irt_interfaces.h" |
| 11 #include "native_client/src/include/nacl/nacl_exception.h" |
10 #include "native_client/src/include/nacl_macros.h" | 12 #include "native_client/src/include/nacl_macros.h" |
11 #include "native_client/src/trusted/service_runtime/nacl_exception.h" | |
12 #include "native_client/src/trusted/service_runtime/nacl_signal.h" | |
13 | 13 |
14 namespace nacl { | 14 namespace nacl { |
15 namespace nonsfi { | 15 namespace nonsfi { |
16 namespace { | 16 namespace { |
17 | 17 |
18 /* This is NonSFI version of exception handling codebase, NaCl side of | 18 /* This is NonSFI version of exception handling codebase, NaCl side of |
19 * things resides in: | 19 * things resides in: |
20 * native_client/src/trusted/service_runtime/linux/nacl_signal.c | 20 * native_client/src/trusted/service_runtime/linux/nacl_signal.c |
21 * native_client/src/trusted/service_runtime/sys_exception.c | 21 * native_client/src/trusted/service_runtime/sys_exception.c |
22 */ | 22 */ |
23 | 23 |
24 // TODO(uekawa): The list of signals to be handled might need updating. | 24 // TODO(uekawa): The list of signals to be handled might need updating. |
25 // NonSFI NaCl does not use NACL_THREAD_SUSPEND_SIGNAL (==SIGUSR1) (??check??) | 25 // NonSFI NaCl does not use NACL_THREAD_SUSPEND_SIGNAL (==SIGUSR1) (??check??) |
26 // and SIGSYS is reserved for seccomp-bpf. | 26 // and SIGSYS is reserved for seccomp-bpf. |
27 static const int kSignals[] = { | 27 static const int kSignals[] = { |
28 SIGSTKFLT, | 28 SIGSTKFLT, |
29 SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGBUS, SIGFPE, SIGSEGV, | 29 SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGBUS, SIGFPE, SIGSEGV, |
30 /* Handle SIGABRT in case someone sends it asynchronously using kill(). */ | 30 /* Handle SIGABRT in case someone sends it asynchronously using kill(). */ |
31 SIGABRT | 31 SIGABRT |
32 }; | 32 }; |
33 | 33 |
34 NaClExceptionHandler signal_handler_function_pointer = NULL; | 34 NaClExceptionHandler signal_handler_function_pointer = NULL; |
35 | 35 |
| 36 struct NonSfiExceptionFrame { |
| 37 struct NaClExceptionContext context; |
| 38 struct NaClExceptionPortableContext portable; |
| 39 }; |
| 40 |
| 41 // Convert context reported by signal to NaClExceptionContext format. |
| 42 void MachineContextToRegister(const mcontext_t *mctx, |
| 43 // what is volatile about it? |
| 44 NaClUserRegisterState *dest) { |
| 45 |
| 46 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32 |
| 47 dest->eax = mctx->gregs[REG_EAX]; |
| 48 dest->ecx = mctx->gregs[REG_ECX]; |
| 49 dest->edx = mctx->gregs[REG_EDX]; |
| 50 dest->ebx = mctx->gregs[REG_EBX]; |
| 51 dest->stack_ptr = mctx->gregs[REG_ESP]; |
| 52 dest->ebp = mctx->gregs[REG_EBP]; |
| 53 dest->esi = mctx->gregs[REG_ESI]; |
| 54 dest->edi = mctx->gregs[REG_EDI]; |
| 55 dest->prog_ctr = mctx->gregs[REG_EIP]; |
| 56 dest->flags = mctx->gregs[REG_EFL]; |
| 57 |
| 58 #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_arm |
| 59 dest->r0 = mctx->arm_r0; |
| 60 dest->r1 = mctx->arm_r1; |
| 61 dest->r2 = mctx->arm_r2; |
| 62 dest->r3 = mctx->arm_r3; |
| 63 dest->r4 = mctx->arm_r4; |
| 64 dest->r5 = mctx->arm_r5; |
| 65 dest->r6 = mctx->arm_r6; |
| 66 dest->r7 = mctx->arm_r7; |
| 67 dest->r8 = mctx->arm_r8; |
| 68 // TODO(uekawa): We don't really use r9 for trusted thread pointer |
| 69 // for Non-SFI NaCl, do we? |
| 70 dest->r9 = mctx->arm_r9; |
| 71 dest->r10 = mctx->arm_r10; |
| 72 dest->r11 = mctx->arm_fp; |
| 73 dest->r12 = mctx->arm_ip; |
| 74 dest->stack_ptr = mctx->arm_sp; |
| 75 dest->lr = mctx->arm_lr; |
| 76 dest->prog_ctr = mctx->arm_pc; |
| 77 dest->cpsr = mctx->arm_cpsr; |
| 78 #else |
| 79 # error Unsupported architecture |
| 80 #endif |
| 81 } |
| 82 |
| 83 void ExceptionFrameFromSignalContext(NonSfiExceptionFrame* frame, |
| 84 const void* raw_ctx) { |
| 85 const ucontext_t *uctx = (ucontext_t *) raw_ctx; |
| 86 // mcontext_t is sigcontext in ARM. |
| 87 const mcontext_t *mctx = &uctx->uc_mcontext; |
| 88 frame->context.size = (((uintptr_t)&frame->portable + 1) |
| 89 - (uintptr_t)&frame->context); |
| 90 frame->context.portable_context_offset = ((uintptr_t)&frame->portable |
| 91 - (uintptr_t)&frame->context); |
| 92 frame->context.portable_context_size = sizeof(frame->portable); |
| 93 frame->context.regs_size = sizeof(frame->context.regs); |
| 94 |
| 95 for (size_t i = 0; i < NACL_ARRAY_SIZE(frame->context.reserved); i++) { |
| 96 frame->context.reserved[i] = 0; |
| 97 } |
| 98 |
| 99 MachineContextToRegister(mctx, &frame->context.regs); |
| 100 |
| 101 frame->portable.prog_ctr = frame->context.regs.prog_ctr; |
| 102 frame->portable.stack_ptr = frame->context.regs.stack_ptr; |
| 103 |
| 104 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32 |
| 105 frame->context.arch = EM_386; |
| 106 frame->portable.frame_ptr = frame->context.regs.ebp; |
| 107 #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_arm |
| 108 frame->context.arch = EM_ARM; |
| 109 // R11 is frame pointer in ARM mode, R8 is frame pointer in thumb mode. |
| 110 frame->portable.frame_ptr = frame->context.regs.r11; |
| 111 #else |
| 112 # error Unsupported architecture |
| 113 #endif |
| 114 } |
| 115 |
36 // Signal handler, responsible for calling the registered handlers. | 116 // Signal handler, responsible for calling the registered handlers. |
37 static void SignalCatch(int sig, siginfo_t *info, void *uc) { | 117 static void SignalCatch(int sig, siginfo_t *info, void *uc) { |
38 if (signal_handler_function_pointer) { | 118 if (signal_handler_function_pointer) { |
39 // TODO(uekawa): Whether to add dependency or copy the implementation? | 119 NonSfiExceptionFrame exception_frame; |
40 NaClSignalContext signal_context; | 120 ExceptionFrameFromSignalContext(&exception_frame, uc); |
41 NaClSignalContextFromHandler(&signal_context, uc); | |
42 // Is this safe to allocate this on stack ? | |
43 NaClExceptionFrame exception_frame; | |
44 NaClSignalSetUpExceptionFrame(&exception_frame, | |
45 &signal_context, | |
46 0 /* context_user_addr, what is this? */); | |
47 | |
48 signal_handler_function_pointer(&exception_frame.context); | 121 signal_handler_function_pointer(&exception_frame.context); |
49 } | 122 } |
50 // TODO(uekawa): Only exit on crash signals? | 123 // TODO(uekawa): Only exit on crash signals? |
51 _exit(-1); | 124 _exit(-1); |
52 } | 125 } |
53 | 126 |
54 static int IrtExceptionHandler(NaClExceptionHandler handler, | 127 static int IrtExceptionHandler(NaClExceptionHandler handler, |
55 NaClExceptionHandler *old_handler) { | 128 NaClExceptionHandler *old_handler) { |
56 // TODO(uekawa): Do I need to have a mutex lock? | 129 // TODO(uekawa): Do I need to have a mutex lock? |
57 if (old_handler) { | 130 if (old_handler) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 /* | 170 /* |
98 * Mask all signals we catch to prevent re-entry. | 171 * Mask all signals we catch to prevent re-entry. |
99 */ | 172 */ |
100 for (a = 0; a < NACL_ARRAY_SIZE(kSignals); a++) { | 173 for (a = 0; a < NACL_ARRAY_SIZE(kSignals); a++) { |
101 sigaddset(&sa.sa_mask, kSignals[a]); | 174 sigaddset(&sa.sa_mask, kSignals[a]); |
102 } | 175 } |
103 | 176 |
104 /* Install all handlers */ | 177 /* Install all handlers */ |
105 for (a = 0; a < NACL_ARRAY_SIZE(kSignals); a++) { | 178 for (a = 0; a < NACL_ARRAY_SIZE(kSignals); a++) { |
106 if (sigaction(kSignals[a], &sa, NULL) != 0) { | 179 if (sigaction(kSignals[a], &sa, NULL) != 0) { |
107 perror("sigaction"); | 180 PLOG(FATAL) << "Registering signal handlers failed"; |
108 } | 181 } |
109 } | 182 } |
110 } | 183 } |
111 | 184 |
112 } // namespace nonsfi | 185 } // namespace nonsfi |
113 } // namespace nacl | 186 } // namespace nacl |
OLD | NEW |