]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/compat/posix/v2_0/tests/signal2.c
Initial revision
[karo-tx-redboot.git] / packages / compat / posix / v2_0 / tests / signal2.c
1 //==========================================================================
2 //
3 //        signal2.cxx
4 //
5 //        POSIX signal test 2
6 //
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.
12 //
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.
16 //
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
20 // for more details.
21 //
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.
25 //
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.
32 //
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.
35 //
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####
42 //
43 // Author(s):     nickg
44 // Contributors:  jlarmour
45 // Date:          2000-04-10
46 // Description:   Tests POSIX signal functionality.
47 //
48 //####DESCRIPTIONEND####
49 //==========================================================================
50
51 #include <pkgconf/isoinfra.h>
52 #include <cyg/hal/hal_intr.h>   // For exception codes
53
54 #include <sys/types.h>
55 #include <pthread.h>
56 #include <signal.h>
57 #include <semaphore.h>
58
59 #include <setjmp.h>
60
61 #include <cyg/infra/testcase.h>
62
63 #if CYGINT_ISO_SETJMP == 0
64 # define NA_MSG "Requires setjmp/longjmp implementation"
65 #elif !defined(CYGPKG_POSIX_SIGNALS)
66 # define NA_MSG "POSIX signals not enabled"
67 #endif
68
69 #ifdef NA_MSG
70 void
71 cyg_start(void)
72 {
73     CYG_TEST_INIT();
74     CYG_TEST_NA( NA_MSG );
75 }
76 #else
77
78 //--------------------------------------------------------------------------
79 // Local variables
80
81 static jmp_buf jbuf;
82
83 //--------------------------------------------------------------------------
84
85 // PowerPC is a special case as it has the alignment exception, but it
86 // doesn't trigger for this function unless in little-endian mode (although
87 // the exception exists for other instructions not used by this function so
88 // CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS will still be defined
89
90 #if defined(CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS) && !(defined(CYGPKG_HAL_POWERPC) && (CYG_BYTEORDER==CYG_MSBFIRST))
91
92 static void
93 cause_unaligned_access(void)
94 {
95     volatile int x;
96     volatile CYG_ADDRESS p=(CYG_ADDRESS) &jbuf;
97
98     x = *(volatile int *)(p+1);
99
100 } // cause_unaligned_access()
101
102 #endif
103
104 //--------------------------------------------------------------------------
105
106 #ifdef CYGNUM_HAL_EXCEPTION_DATA_ACCESS
107
108 static void
109 cause_illegal_access(void)
110 {
111 #ifdef CYGPKG_HAL_I386
112
113     // In the x86 architecture, although we have the DATA_ACCESS
114     // exception available, it is not possible to provoke it using the
115     // normal code of this test. This is because the normal segments we
116     // have installed in the segment registers cover all of memory. Instead we
117     // set GS to a descriptor that does not cover 0xF0000000-0xFFFFFFFF and
118     // poke at that.
119
120     __asm__ ( "movw     $0x20,%%ax\n"
121               "movw     %%ax,%%gs\n"
122               "movl     %%gs:0xF0000000,%%eax\n"
123               :
124               :
125               : "eax"
126             );
127     
128 #else    
129     volatile int x;
130     volatile CYG_ADDRESS p=(CYG_ADDRESS) &jbuf;
131
132     do
133     {
134         x = *(volatile int *)(p);
135         p += (CYG_ADDRESS)0x100000;
136     } while( p != (CYG_ADDRESS)&jbuf );
137
138 #endif    
139 } // cause_illegal_access()
140
141 #endif
142
143 //--------------------------------------------------------------------------
144
145 #ifdef CYGNUM_HAL_EXCEPTION_FPU_DIV_BY_ZERO
146
147 // num must always be 0 - do it this way in case the optimizer tries to
148 // get smart
149
150 static int
151 cause_fpe(int num)
152 {
153     double a;
154
155     a = 1.0/num;                        // Depending on FPU emulation and/or
156                                         // the FPU architecture, this may
157                                         // cause an exception.
158                                         // (float division by zero)
159
160     return ((int)a)/num;                // This may cause an exception if
161                                         // the architecture supports it.
162                                         // (integer division by zero).
163 } // cause_fpe()
164
165 #endif
166
167 //--------------------------------------------------------------------------
168 // Signal handler functions
169
170 static void sigsegv( int signo )
171 {
172     CYG_TEST_INFO( "sigsegv() handler called" );
173     CYG_TEST_CHECK( signo == SIGSEGV, "Signal not SIGSEGV");
174
175     longjmp( jbuf, 1 );
176 }
177
178 static void sigbus( int signo )
179 {
180     CYG_TEST_INFO( "sigbus() handler called" );
181     CYG_TEST_CHECK( signo == SIGBUS, "Signal not SIGBUS");
182
183     longjmp( jbuf, 1 );
184 }
185
186 static void sigfpe( int signo )
187 {
188     CYG_TEST_INFO( "sigfpe() handler called" );
189     CYG_TEST_CHECK( signo == SIGFPE, "Signal not SIGFPE");
190
191     longjmp( jbuf, 1 );
192 }
193
194
195 //--------------------------------------------------------------------------
196
197 int main(int argc, char **argv)
198 {
199     int ret;
200     sigset_t mask;
201     struct sigaction sa;
202     
203     CYG_TEST_INIT();
204
205     // Make a full signal set
206     sigfillset( &mask );
207
208    
209     // Install signal handlers
210
211     sa.sa_mask = mask;
212     sa.sa_flags = 0;
213
214     sa.sa_handler = sigsegv;
215     ret = sigaction( SIGSEGV, &sa, NULL );
216     CYG_TEST_CHECK( ret == 0 , "sigaction returned error");
217
218     sa.sa_handler = sigbus;
219     ret = sigaction( SIGBUS, &sa, NULL );
220     CYG_TEST_CHECK( ret == 0 , "sigaction returned error");
221
222     sa.sa_handler = sigfpe;
223     ret = sigaction( SIGFPE, &sa, NULL );
224     CYG_TEST_CHECK( ret == 0 , "sigaction returned error");
225
226     // now make an empty signal set
227     sigemptyset( &mask );
228     
229 // Now reset the various exception handlers to eCos handlers so that we
230 // have control; this is the target side equivalent of the CYG_TEST_GDBCMD
231 // lines above:
232 #ifdef HAL_VSR_SET_TO_ECOS_HANDLER
233     // Reclaim the VSR off CygMon possibly
234 #ifdef CYGNUM_HAL_EXCEPTION_DATA_ACCESS
235     HAL_VSR_SET_TO_ECOS_HANDLER( CYGNUM_HAL_EXCEPTION_DATA_ACCESS, NULL );
236 #endif
237 #ifdef CYGNUM_HAL_EXCEPTION_DATA_TLBMISS_ACCESS
238     HAL_VSR_SET_TO_ECOS_HANDLER( CYGNUM_HAL_EXCEPTION_DATA_TLBMISS_ACCESS, NULL );
239 #endif
240 #ifdef CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS
241     HAL_VSR_SET_TO_ECOS_HANDLER( CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS, NULL );
242 #endif
243 #ifdef CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION
244     HAL_VSR_SET_TO_ECOS_HANDLER( CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION, NULL );
245 #endif
246 #ifdef CYGNUM_HAL_EXCEPTION_FPU_DIV_BY_ZERO
247     HAL_VSR_SET_TO_ECOS_HANDLER( CYGNUM_HAL_EXCEPTION_FPU_DIV_BY_ZERO, NULL );
248 #endif
249 #endif
250
251     // PowerPC is a special case as it has the alignment exception, but it
252     // doesn't trigger for this function unless in little-endian mode (although
253     // the exception exists for other instructions not used by this function so
254     // CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS will still be defined
255
256 #if defined(CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS) && !(defined(CYGPKG_HAL_POWERPC) && (CYG_BYTEORDER==CYG_MSBFIRST))
257     
258     CYG_TEST_INFO("Test 1 - provoke unaligned access");
259     
260     if( setjmp( jbuf ) == 0 )
261     {
262         pthread_sigmask( SIG_SETMASK, &mask, NULL );
263         cause_unaligned_access();
264         CYG_TEST_FAIL("Didn't cause exception");        
265     }
266
267 #else
268
269     CYG_TEST_INFO("Test 1 - provoke unaligned access - not supported");
270
271 #endif    
272
273 #ifdef CYGNUM_HAL_EXCEPTION_DATA_ACCESS
274     
275     CYG_TEST_INFO("Test 2 - provoke illegal access");
276     
277     if( setjmp( jbuf ) == 0 )
278     {
279         pthread_sigmask( SIG_SETMASK, &mask, NULL );
280         cause_illegal_access();
281         CYG_TEST_FAIL("Didn't cause exception");        
282     }
283
284 #else
285
286     CYG_TEST_INFO("Test 1 - provoke illegal access - not supported");
287
288 #endif    
289     
290 #ifdef CYGNUM_HAL_EXCEPTION_FPU_DIV_BY_ZERO
291     
292     CYG_TEST_INFO("Test 3 - provoke FP error");    
293
294     if( setjmp( jbuf ) == 0 )
295     {
296         pthread_sigmask( SIG_SETMASK, &mask, NULL );
297         cause_fpe(0);
298         CYG_TEST_FAIL("Didn't cause exception");        
299     }
300
301 #else
302
303     CYG_TEST_INFO("Test 3 - provoke FP error - not supported");    
304     
305 #endif    
306
307     CYG_TEST_PASS_FINISH( "signal2" );
308 }
309
310 #endif // ifndef NA_MSG
311
312 //--------------------------------------------------------------------------
313 // end of signal1.c