genericopenlibs/liboil/src/liboilfault.c
branchRCL_3
changeset 56 acd3cd4aaceb
equal deleted inserted replaced
54:4332f0f7be53 56:acd3cd4aaceb
       
     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