os/ossrv/genericopenlibs/liboil/src/liboilfault.c
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /*
     2  * LIBOIL - Library of Optimized Inner Loops
     3  * Copyright (c) 2003,2004 David A. Schleef <ds@schleef.org>
     4  * All rights reserved.
     5  *
     6  * Redistribution and use in source and binary forms, with or without
     7  * modification, are permitted provided that the following conditions
     8  * are met:
     9  * 1. Redistributions of source code must retain the above copyright
    10  *    notice, this list of conditions and the following disclaimer.
    11  * 2. Redistributions in binary form must reproduce the above copyright
    12  *    notice, this list of conditions and the following disclaimer in the
    13  *    documentation and/or other materials provided with the distribution.
    14  * 
    15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
    19  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    20  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    21  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
    23  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
    24  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    25  * POSSIBILITY OF SUCH DAMAGE.
    26  */
    27 
    28 //Portions Copyright (c)  2006-2008 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. 
    29 
    30 
    31 #ifdef HAVE_CONFIG_H
    32 #include "config.h"
    33 #endif
    34 
    35 #include <liboil/liboilfunction.h>
    36 #include <liboil/liboildebug.h>
    37 #include <liboil/liboilfault.h>
    38 
    39 #include <stdlib.h>
    40 #include <string.h>
    41 #include <setjmp.h>
    42 #include <signal.h>
    43 
    44 #ifndef __SYMBIAN32__
    45 #ifndef _WIN32 
    46 #include <windows.h>
    47 #endif
    48 #endif
    49 
    50 static jmp_buf jump_env;
    51 #ifdef HAVE_SIGACTION
    52 static struct sigaction action;
    53 static struct sigaction oldaction;
    54 #else
    55 static void * oldhandler;
    56 #endif
    57 static int in_try_block;
    58 static int enable_level;
    59 
    60 #ifdef __SYMBIAN32__
    61 #ifdef __WINSCW__
    62 #pragma warn_unusedarg off 
    63 #endif//__WINSCW__
    64 #endif//__SYMBIAN32__
    65 
    66 #if 0
    67 #ifndef _WIN32                
    68 static LONG __stdcall
    69 illegal_instruction_handler (EXCEPTION_POINTERS *e)
    70 {
    71   if (in_try_block) {
    72     /* according to the laws of win32, this isn't allowed.
    73      * It does, however, work. */
    74     longjmp (jump_env, 1);
    75   }
    76   /* kill the process */
    77   return EXCEPTION_EXECUTE_HANDLER;
    78 }
    79 #endif
    80 #endif
    81 //#else
    82 static void
    83 illegal_instruction_handler (int num)
    84 {
    85   if (in_try_block) {
    86 #ifdef HAVE_SIGPROCMASK                     
    87     sigset_t set;
    88     sigemptyset (&set);
    89     sigaddset (&set, SIGILL);
    90     sigprocmask (SIG_UNBLOCK, &set, NULL);
    91     longjmp (jump_env, 1);
    92   } else {
    93     abort ();
    94 #endif    
    95   }
    96 }
    97 
    98 /**
    99  * oil_fault_check_enable:
   100  *
   101  * Enables fault checking mode.  This function may be called multiple times.
   102  * Each call to this function must be paired with a corresponding call
   103  * to oil_fault_check_disable().
   104  *
   105  * This function sets a signal handler for SIGILL.
   106  */
   107 #ifdef __SYMBIAN32__
   108 EXPORT_C
   109 #endif
   110 void
   111 oil_fault_check_enable (void)
   112 {
   113 #ifndef __SYMBIAN32__
   114 if (enable_level == 0) {
   115   
   116 
   117 #ifndef _WIN32                
   118 #ifdef HAVE_SIGACTION
   119     memset (&action, 0, sizeof(action));
   120     action.sa_handler = &illegal_instruction_handler;
   121     sigaction (SIGILL, &action, &oldaction);
   122 #else
   123     oldhandler = signal (SIGILL, illegal_instruction_handler);
   124 #endif
   125 #else
   126     oldhandler = SetUnhandledExceptionFilter(illegal_instruction_handler);
   127 #endif
   128 
   129     in_try_block = 0;
   130     OIL_INFO("enabling SIGILL handler.  Make sure to continue past "
   131         "any SIGILL signals caught by gdb."); 
   132   }
   133   enable_level++;
   134 #endif
   135 }
   136 
   137 /**
   138  * oil_fault_check_try:
   139  * @func: the function to attempt
   140  * @priv: a value to pass to the function
   141  *
   142  * Calls to this
   143  * function must be preceded by a call to oil_fault_check_enable()
   144  * to enable fault checking mode.  This function sets up recovery
   145  * information and then calls the function @func with the parameter
   146  * @priv.  If @func or any other functions it calls attempt to execute
   147  * an illegal instruction, the exception will be caught and recovered from.
   148  *
   149  * Returns: 1 if the function was executed sucessfully, 0 if the
   150  * function attempted to execute an illegal instruction.
   151  */
   152 #ifdef __SYMBIAN32__
   153 EXPORT_C
   154 #endif
   155 int
   156 oil_fault_check_try (void (*func) (void *), void *priv)
   157 {
   158   int ret;
   159 
   160   in_try_block = 1;
   161   ret = setjmp (jump_env);
   162   if (!ret) {
   163     func (priv);
   164   }
   165   in_try_block = 0;
   166 
   167   return (ret == 0);
   168 }
   169 
   170 /**
   171  * oil_fault_check_disable:
   172  *
   173  * Disables fault checking mode.  See oil_fault_check_enable()
   174  * for details.
   175  */
   176 #ifdef __SYMBIAN32__
   177 EXPORT_C 
   178 #endif
   179 void
   180 oil_fault_check_disable (void)
   181 {
   182 #ifndef __SYMBIAN32__
   183 enable_level--;
   184   
   185   if (enable_level == 0) {
   186 #ifndef _WIN32
   187 #ifdef HAVE_SIGACTION
   188     sigaction (SIGILL, &oldaction, NULL);
   189 #else
   190     signal (SIGILL, oldhandler);
   191 #endif
   192 #else
   193     SetUnhandledExceptionFilter(oldhandler);
   194 #endif
   195     OIL_INFO("disabling SIGILL handler");
   196   }
   197 #endif  
   198 }
   199