1 //========================================================================
5 // ISO C signal handling test
7 //========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //========================================================================
41 //#####DESCRIPTIONBEGIN####
43 // Author(s): jlarmour
46 // Purpose: Test hardware signal functionality
47 // Description: This file contains a number of tests for ISO C signal
48 // handling when used with hardware exceptions
51 //####DESCRIPTIONEND####
53 //========================================================================
57 #include <pkgconf/system.h>
58 #include <pkgconf/libc_signals.h> // C library signals configuration
62 #include <cyg/infra/cyg_type.h> // Common type definitions and support
63 #include <cyg/infra/testcase.h> // Test infrastructure
65 #ifdef CYGSEM_LIBC_SIGNALS_HWEXCEPTIONS
67 #include <cyg/hal/hal_intr.h> // exception ranges &
68 // HAL_VSR_SET_TO_ECOS_HANDLER
70 #include <signal.h> // Signal functions
71 #include <setjmp.h> // setjmp(), longjmp()
81 #ifdef CYGSEM_LIBC_SIGNALS_HWEXCEPTIONS
86 __sighandler_t handler1;
88 CYG_TEST_INFO("myhandler() called");
91 handler1 = signal(sig, &myhandler);
93 CYG_TEST_PASS_FAIL(handler1 == SIG_DFL,
94 "handler reset itself to default");
102 #ifdef CYGPKG_HAL_I386
104 // In the x86 architecture, although we have the DATA_ACCESS
105 // exception available, it is not possible to provoke it using the
106 // normal code of this test. This is because the normal segments we
107 // have installed in the segment registers cover all of memory. Instead we
108 // set GS to a descriptor that does not cover 0xF0000000-0xFFFFFFFF and
111 __asm__ ( "movw $0x20,%%ax\n"
113 "movl %%gs:0xF0000000,%%eax\n"
121 volatile CYG_ADDRESS p=(CYG_ADDRESS) &state;
124 // do a read which prevents us accidentally writing over something
125 // important. Make it misaligned to increase the chances of an
126 // exception happening
127 x = *(volatile int *)(p+1);
128 p += (CYG_ADDRESS)0x100000;
131 } // cause_memerror()
133 // num must always be 0 - do it this way in case the optimizer tries to
140 a = 1.0/num; // Depending on FPU emulation and/or
141 // the FPU architecture, this may
142 // cause an exception.
143 // (float division by zero)
145 return ((int)a)/num; // This may cause an exception if
146 // the architecture supports it.
147 // (integer division by zero).
156 main( int argc, char *argv[] )
158 #ifdef CYGSEM_LIBC_SIGNALS_HWEXCEPTIONS
159 __sighandler_t handler1;
161 // special callout to request GDB to alter its handling of signals
162 CYG_TEST_GDBCMD("handle SIGBUS nostop");
163 CYG_TEST_GDBCMD("handle SIGSEGV nostop");
164 CYG_TEST_GDBCMD("handle SIGILL nostop");
165 CYG_TEST_GDBCMD("handle SIGFPE nostop");
166 CYG_TEST_GDBCMD("handle SIGSYS nostop");
167 #endif // ifdef CYGSEM_LIBC_SIGNALS_HWEXCEPTIONS
171 #ifdef CYGSEM_LIBC_SIGNALS_HWEXCEPTIONS
172 // Avoid compiler warnings if tests are not applicable.
173 if (0) cause_memerror();
177 CYG_TEST_INFO("Starting tests from testcase " __FILE__ " for C "
178 "library signal functions");
180 // Now reset the exception handlers various to eCos handlers so that we
181 // have control; this is the target side equivalent of the CYG_TEST_GDBCMD
183 #ifdef HAL_VSR_SET_TO_ECOS_HANDLER
184 // Reclaim the VSR off CygMon possibly
185 #ifdef CYGNUM_HAL_EXCEPTION_DATA_ACCESS
186 HAL_VSR_SET_TO_ECOS_HANDLER( CYGNUM_HAL_EXCEPTION_DATA_ACCESS, NULL );
188 #ifdef CYGNUM_HAL_EXCEPTION_DATA_TLBMISS_ACCESS
189 HAL_VSR_SET_TO_ECOS_HANDLER( CYGNUM_HAL_EXCEPTION_DATA_TLBMISS_ACCESS, NULL );
191 #ifdef CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS
192 HAL_VSR_SET_TO_ECOS_HANDLER( CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS, NULL );
194 #ifdef CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION
195 HAL_VSR_SET_TO_ECOS_HANDLER( CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION, NULL );
197 #ifdef CYGNUM_HAL_EXCEPTION_DIV_BY_ZERO
198 HAL_VSR_SET_TO_ECOS_HANDLER( CYGNUM_HAL_EXCEPTION_DIV_BY_ZERO, NULL );
200 #ifdef CYGNUM_HAL_EXCEPTION_FPU
201 HAL_VSR_SET_TO_ECOS_HANDLER( CYGNUM_HAL_EXCEPTION_FPU, NULL );
203 #ifdef CYGNUM_HAL_EXCEPTION_FPU_DIV_BY_ZERO
204 HAL_VSR_SET_TO_ECOS_HANDLER( CYGNUM_HAL_EXCEPTION_FPU_DIV_BY_ZERO, NULL );
208 #ifdef CYGSEM_LIBC_SIGNALS_HWEXCEPTIONS
213 CYG_TEST_INFO("Test 1");
215 handler1 = signal(SIGSEGV, &myhandler);
217 CYG_TEST_PASS_FAIL(handler1 == SIG_DFL,
218 "SIGSEGV handler initialized to default");
221 handler1 = signal(SIGBUS, &myhandler);
223 CYG_TEST_PASS_FAIL(handler1 == SIG_DFL,
224 "SIGBUS handler initialized to default");
227 handler1 = signal(SIGILL, &myhandler);
229 CYG_TEST_PASS_FAIL(handler1 == SIG_DFL,
230 "SIGILL handler initialized to default");
232 handler1 = signal(SIGSYS, &myhandler);
234 CYG_TEST_PASS_FAIL(handler1 == SIG_DFL,
235 "SIGSYS handler initialized to default");
237 handler1 = signal(SIGTRAP, &myhandler);
239 CYG_TEST_PASS_FAIL(handler1 == SIG_DFL,
240 "SIGTRAP handler initialized to default");
242 handler1 = signal(SIGFPE, &myhandler);
244 CYG_TEST_PASS_FAIL(handler1 == SIG_DFL,
245 "SIGFPE handler initialized to default");
249 CYG_TEST_INFO("Test 2");
253 #if defined(CYGPKG_HAL_POWERPC_SIM)
254 // The exception generated by the SIM is not recognized by GDB.
255 // PR 19945 workaround.
256 CYG_TEST_PASS("Test 2 not applicable to PowerPC SIM");
258 if (0==setjmp(jbuf)) {
260 CYG_TEST_FAIL("Didn't cause exception");
263 CYG_TEST_PASS_FAIL(3==state, "handler returned correctly");
268 CYG_TEST_INFO("Test 3");
272 #ifdef CYGNUM_HAL_EXCEPTION_FPU_DIV_BY_ZERO
274 if (0==setjmp(jbuf)) {
275 // It is necessary to save the return value in a volatile
276 // variable, or GCC will get rid of the call.
278 CYG_TEST_FAIL("Didn't cause exception");
281 CYG_TEST_PASS_FAIL(4==state, "handler returned correctly");
285 CYG_TEST_INFO("Test 3 - provoke FP error - not supported");
290 CYG_TEST_NA("Testing not applicable to this configuration");
293 CYG_TEST_FINISH("Finished tests from testcase " __FILE__ " for C "
294 "library signal functions");