| OLD | NEW | 
 | (Empty) | 
|    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 |  | 
|    3 // found in the LICENSE file. |  | 
|    4  |  | 
|    5 #include <errno.h> |  | 
|    6 #include <pthread.h> |  | 
|    7 #include <signal.h> |  | 
|    8  |  | 
|    9 #include "components/nacl/loader/nonsfi/irt_interfaces.h" |  | 
|   10 #include "native_client/src/include/nacl_macros.h" |  | 
|   11 #include "native_client/src/shared/platform/nacl_log.h" |  | 
|   12 #include "native_client/src/trusted/service_runtime/nacl_exception.h" |  | 
|   13 #include "native_client/src/trusted/service_runtime/nacl_signal.h" |  | 
|   14  |  | 
|   15 namespace nacl { |  | 
|   16 namespace nonsfi { |  | 
|   17 namespace { |  | 
|   18  |  | 
|   19 // This is NonSFI version of exception handling codebase, NaCl side of |  | 
|   20 // things resides in: |  | 
|   21 // native_client/src/trusted/service_runtime/linux/nacl_signal.c |  | 
|   22 // native_client/src/trusted/service_runtime/sys_exception.c |  | 
|   23  |  | 
|   24 // Crash signals to handle.  The differences from SFI NaCl are that |  | 
|   25 // NonSFI NaCl does not use NACL_THREAD_SUSPEND_SIGNAL (==SIGUSR1), |  | 
|   26 // and SIGSYS is reserved for seccomp-bpf. |  | 
|   27 const int kSignals[] = { |  | 
|   28 #if !defined(__mips__) |  | 
|   29   // This signal does not exist on MIPS. |  | 
|   30   SIGSTKFLT, |  | 
|   31 #endif |  | 
|   32   SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGBUS, SIGFPE, SIGSEGV, |  | 
|   33   // Handle SIGABRT in case someone sends it asynchronously using kill(). |  | 
|   34   SIGABRT |  | 
|   35 }; |  | 
|   36  |  | 
|   37 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; |  | 
|   38 NaClExceptionHandler signal_handler_function_pointer = NULL; |  | 
|   39  |  | 
|   40 // Signal handler, responsible for calling the registered handler. |  | 
|   41 void SignalCatch(int sig, siginfo_t* info, void* uc) { |  | 
|   42   if (signal_handler_function_pointer) { |  | 
|   43     NaClSignalContext signal_context; |  | 
|   44     NaClSignalContextFromHandler(&signal_context, uc); |  | 
|   45     NaClExceptionFrame exception_frame; |  | 
|   46     NaClSignalSetUpExceptionFrame(&exception_frame, |  | 
|   47                                   &signal_context, |  | 
|   48                                   0 /* context_user_addr, |  | 
|   49                                        not useful for NonSFI NaCl. */); |  | 
|   50     signal_handler_function_pointer(&exception_frame.context); |  | 
|   51   } |  | 
|   52   _exit(-sig); |  | 
|   53 } |  | 
|   54  |  | 
|   55 int IrtExceptionHandler(NaClExceptionHandler handler, |  | 
|   56                                NaClExceptionHandler* old_handler) { |  | 
|   57   pthread_mutex_lock(&mutex); |  | 
|   58   if (old_handler) |  | 
|   59     *old_handler = signal_handler_function_pointer; |  | 
|   60   signal_handler_function_pointer = handler; |  | 
|   61   pthread_mutex_unlock(&mutex); |  | 
|   62   return 0; |  | 
|   63 } |  | 
|   64  |  | 
|   65 int IrtExceptionStack(void* stack, size_t size) { |  | 
|   66   // TODO(uekawa): Implement this function so that the exception stack |  | 
|   67   // actually gets used for running an exception handler.  Currently |  | 
|   68   // we don't switch stack, which means we can't handle stack overflow |  | 
|   69   // exceptions. |  | 
|   70   return 0; |  | 
|   71 } |  | 
|   72  |  | 
|   73 int IrtExceptionClearFlag(void) { |  | 
|   74   // TODO(uekawa): Implement clear_flag() to behave like SFI NaCl's |  | 
|   75   // implementation, so that a thread can handle a second exception |  | 
|   76   // after handling a first exception |  | 
|   77   return ENOSYS; |  | 
|   78 } |  | 
|   79  |  | 
|   80 }  // namespace |  | 
|   81  |  | 
|   82 const struct nacl_irt_exception_handling kIrtExceptionHandling = { |  | 
|   83   IrtExceptionHandler, |  | 
|   84   IrtExceptionStack, |  | 
|   85   IrtExceptionClearFlag, |  | 
|   86 }; |  | 
|   87  |  | 
|   88 void InitializeSignalHandler() { |  | 
|   89   struct sigaction sa; |  | 
|   90   unsigned int a; |  | 
|   91  |  | 
|   92   memset(&sa, 0, sizeof(sa)); |  | 
|   93   sigemptyset(&sa.sa_mask); |  | 
|   94   sa.sa_sigaction = SignalCatch; |  | 
|   95   sa.sa_flags = SA_ONSTACK | SA_SIGINFO; |  | 
|   96  |  | 
|   97   // Mask all signals we catch to prevent re-entry. |  | 
|   98   for (a = 0; a < NACL_ARRAY_SIZE(kSignals); a++) { |  | 
|   99     sigaddset(&sa.sa_mask, kSignals[a]); |  | 
|  100   } |  | 
|  101  |  | 
|  102   // Install all handlers. |  | 
|  103   for (a = 0; a < NACL_ARRAY_SIZE(kSignals); a++) { |  | 
|  104     if (sigaction(kSignals[a], &sa, NULL) != 0) |  | 
|  105       NaClLog(LOG_FATAL, "sigaction to register signals failed.\n"); |  | 
|  106   } |  | 
|  107 } |  | 
|  108  |  | 
|  109 }  // namespace nonsfi |  | 
|  110 }  // namespace nacl |  | 
| OLD | NEW |