Index: src/nonsfi/linux/irt_exception_handling.c |
diff --git a/src/nonsfi/linux/irt_exception_handling.c b/src/nonsfi/linux/irt_exception_handling.c |
index 752e674a1d58f0a1c496fe30c27b5e1a3c251a55..d89d707ffcc6d2485b47a3b2cbec8ab219361fad 100644 |
--- a/src/nonsfi/linux/irt_exception_handling.c |
+++ b/src/nonsfi/linux/irt_exception_handling.c |
@@ -14,91 +14,12 @@ |
#include "native_client/src/include/elf_constants.h" |
#include "native_client/src/include/nacl/nacl_exception.h" |
#include "native_client/src/include/nacl_macros.h" |
+#include "native_client/src/nonsfi/linux/nonsfi_signal.h" |
Mark Seaborn
2015/08/12 01:43:07
Nit: sort #includes
Luis Héctor Chávez
2015/08/12 22:14:26
Done.
|
#include "native_client/src/nonsfi/linux/linux_sys_private.h" |
#include "native_client/src/nonsfi/linux/linux_syscall_defines.h" |
#include "native_client/src/nonsfi/linux/linux_syscall_structs.h" |
-#include "native_client/src/public/nonsfi/irt_exception_handling.h" |
#include "native_client/src/untrusted/irt/irt.h" |
-typedef struct compat_sigaltstack { |
- uint32_t ss_sp; |
- int32_t ss_flags; |
- uint32_t ss_size; |
-} linux_stack_t; |
- |
-#if defined(__i386__) |
- |
-/* From linux/arch/x86/include/uapi/asm/sigcontext32.h */ |
-struct sigcontext_ia32 { |
- unsigned short gs, __gsh; |
- unsigned short fs, __fsh; |
- unsigned short es, __esh; |
- unsigned short ds, __dsh; |
- unsigned int di; |
- unsigned int si; |
- unsigned int bp; |
- unsigned int sp; |
- unsigned int bx; |
- unsigned int dx; |
- unsigned int cx; |
- unsigned int ax; |
- unsigned int trapno; |
- unsigned int err; |
- unsigned int ip; |
- unsigned short cs, __csh; |
- unsigned int flags; |
- unsigned int sp_at_signal; |
- unsigned short ss, __ssh; |
- unsigned int fpstate; |
- unsigned int oldmask; |
- unsigned int cr2; |
-}; |
- |
-typedef struct sigcontext_ia32 linux_mcontext_t; |
- |
-#elif defined(__arm__) |
- |
-/* From linux/arch/arm/include/uapi/asm/sigcontext.h */ |
-struct sigcontext_arm { |
- uint32_t trap_no; |
- uint32_t error_code; |
- uint32_t oldmask; |
- uint32_t arm_r0; |
- uint32_t arm_r1; |
- uint32_t arm_r2; |
- uint32_t arm_r3; |
- uint32_t arm_r4; |
- uint32_t arm_r5; |
- uint32_t arm_r6; |
- uint32_t arm_r7; |
- uint32_t arm_r8; |
- uint32_t arm_r9; |
- uint32_t arm_r10; |
- uint32_t arm_r11; /* fp */ |
- uint32_t arm_r12; /* ip */ |
- uint32_t arm_sp; |
- uint32_t arm_lr; |
- uint32_t arm_pc; |
- uint32_t arm_cpsr; |
- uint32_t fault_address; |
-}; |
- |
-typedef struct sigcontext_arm linux_mcontext_t; |
- |
-#else |
-#error "unsupported architecture" |
-#endif |
- |
-/* From linux/arch/arm/include/asm/ucontext.h */ |
-struct linux_ucontext_t { |
- uint32_t uc_flags; |
- uint32_t uc_link; |
- linux_stack_t uc_stack; |
- linux_mcontext_t uc_mcontext; |
- linux_sigset_t uc_sigmask; |
- /* More data follows which we don't care about. */ |
-}; |
- |
/* |
* Crash signals to handle. The differences from SFI NaCl are that |
* NonSFI NaCl does not use NACL_THREAD_SUSPEND_SIGNAL (==SIGUSR1), |
@@ -111,100 +32,25 @@ static const int kSignals[] = { |
LINUX_SIGABRT, |
}; |
-static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; |
-static NaClExceptionHandler g_signal_handler_function_pointer = NULL; |
-static int g_signal_handler_initialized = 0; |
- |
-struct NonSfiExceptionFrame { |
- struct NaClExceptionContext context; |
- struct NaClExceptionPortableContext portable; |
-}; |
+extern pthread_mutex_t g_signal_handler_mutex; |
Mark Seaborn
2015/08/12 01:43:07
Not needed? Use the header file's decl instead.
Luis Héctor Chávez
2015/08/12 22:14:26
Done.
|
+static NaClExceptionHandler g_exception_handler_function_pointer = NULL; |
-static void machine_context_to_register(const linux_mcontext_t *mctx, |
- NaClUserRegisterState *dest) { |
-#if defined(__i386__) |
-#define COPY_REG(A) dest->e##A = mctx->A |
- COPY_REG(ax); |
- COPY_REG(cx); |
- COPY_REG(dx); |
- COPY_REG(bx); |
- COPY_REG(bp); |
- COPY_REG(si); |
- COPY_REG(di); |
-#undef COPY_REG |
- dest->stack_ptr = mctx->sp; |
- dest->prog_ctr = mctx->ip; |
- dest->flags = mctx->flags; |
-#elif defined(__arm__) |
-#define COPY_REG(A) dest->A = mctx->arm_##A |
- COPY_REG(r0); |
- COPY_REG(r1); |
- COPY_REG(r2); |
- COPY_REG(r3); |
- COPY_REG(r4); |
- COPY_REG(r5); |
- COPY_REG(r6); |
- COPY_REG(r7); |
- COPY_REG(r8); |
- COPY_REG(r9); |
- COPY_REG(r10); |
- COPY_REG(r11); |
- COPY_REG(r12); |
-#undef COPY_REG |
- dest->stack_ptr = mctx->arm_sp; |
- dest->lr = mctx->arm_lr; |
- dest->prog_ctr = mctx->arm_pc; |
- dest->cpsr = mctx->arm_cpsr; |
-#else |
-# error Unsupported architecture |
-#endif |
-} |
- |
-static void exception_frame_from_signal_context( |
- struct NonSfiExceptionFrame *frame, |
- const void *raw_ctx) { |
- const struct linux_ucontext_t *uctx = (struct linux_ucontext_t *) raw_ctx; |
- const linux_mcontext_t *mctx = &uctx->uc_mcontext; |
- frame->context.size = (((uintptr_t) (&frame->portable + 1)) |
- - (uintptr_t) &frame->context); |
- frame->context.portable_context_offset = ((uintptr_t) &frame->portable |
- - (uintptr_t) &frame->context); |
- frame->context.portable_context_size = sizeof(frame->portable); |
- frame->context.regs_size = sizeof(frame->context.regs); |
- |
- memset(frame->context.reserved, 0, sizeof(frame->context.reserved)); |
- machine_context_to_register(mctx, &frame->context.regs); |
- frame->portable.prog_ctr = frame->context.regs.prog_ctr; |
- frame->portable.stack_ptr = frame->context.regs.stack_ptr; |
- |
-#if defined(__i386__) |
- frame->context.arch = EM_386; |
- frame->portable.frame_ptr = frame->context.regs.ebp; |
-#elif defined(__arm__) |
- frame->context.arch = EM_ARM; |
- /* R11 is frame pointer in ARM mode, R8 is frame pointer in thumb mode. */ |
- frame->portable.frame_ptr = frame->context.regs.r11; |
-#else |
-# error Unsupported architecture |
-#endif |
-} |
- |
-/* Signal handler, responsible for calling the registered handler. */ |
-static void signal_catch(int sig, linux_siginfo_t *info, void *uc) { |
- if (g_signal_handler_function_pointer) { |
+/* Signal handlers, responsible for calling the registered handlers. */ |
Mark Seaborn
2015/08/12 01:43:07
Use singular "handler", in both cases?
Luis Héctor Chávez
2015/08/12 22:14:26
Done.
|
+static void exception_catch(int sig, linux_siginfo_t *info, void *uc) { |
+ if (g_exception_handler_function_pointer) { |
struct NonSfiExceptionFrame exception_frame; |
exception_frame_from_signal_context(&exception_frame, uc); |
- g_signal_handler_function_pointer(&exception_frame.context); |
+ g_exception_handler_function_pointer(&exception_frame.context); |
} |
_exit(-sig); |
} |
-static void nonsfi_initialize_signal_handler_locked() { |
+void nonsfi_install_exception_handler_locked() { |
struct linux_sigaction sa; |
unsigned int a; |
memset(&sa, 0, sizeof(sa)); |
- sa.sa_sigaction = signal_catch; |
+ sa.sa_sigaction = exception_catch; |
sa.sa_flags = LINUX_SA_SIGINFO | LINUX_SA_ONSTACK; |
/* |
@@ -226,29 +72,15 @@ static void nonsfi_initialize_signal_handler_locked() { |
} |
} |
-/* |
- * Initialize signal handlers before entering sandbox. |
- */ |
-void nonsfi_initialize_signal_handler() { |
- if (pthread_mutex_lock(&g_mutex) != 0) |
- abort(); |
- if (!g_signal_handler_initialized) { |
- nonsfi_initialize_signal_handler_locked(); |
- g_signal_handler_initialized = 1; |
- } |
- if (pthread_mutex_unlock(&g_mutex) != 0) |
- abort(); |
-} |
- |
int nacl_exception_get_and_set_handler(NaClExceptionHandler handler, |
NaClExceptionHandler *old_handler) { |
- nonsfi_initialize_signal_handler(); |
- if (pthread_mutex_lock(&g_mutex) != 0) |
+ if (pthread_mutex_lock(&g_signal_handler_mutex) != 0) |
abort(); |
+ nonsfi_initialize_signal_handler_locked(); |
if (old_handler) |
- *old_handler = g_signal_handler_function_pointer; |
- g_signal_handler_function_pointer = handler; |
- if (pthread_mutex_unlock(&g_mutex) != 0) |
+ *old_handler = g_exception_handler_function_pointer; |
+ g_exception_handler_function_pointer = handler; |
+ if (pthread_mutex_unlock(&g_signal_handler_mutex) != 0) |
abort(); |
return 0; |
} |