📄 siginit.cxx
字号:
//========================================================================//// siginit.cxx//// ISO C and POSIX 1003.1 signals implementation////========================================================================//####COPYRIGHTBEGIN####// // ------------------------------------------- // The contents of this file are subject to the Red Hat eCos Public License // Version 1.1 (the "License"); you may not use this file except in // compliance with the License. You may obtain a copy of the License at // http://www.redhat.com/ // // Software distributed under the License is distributed on an "AS IS" // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the // License for the specific language governing rights and limitations under // the License. // // The Original Code is eCos - Embedded Configurable Operating System, // released September 30, 1998. // // The Initial Developer of the Original Code is Red Hat. // Portions created by Red Hat are // Copyright (C) 1998, 1999, 2000 Red Hat, Inc. // All Rights Reserved. // ------------------------------------------- // //####COPYRIGHTEND####//========================================================================//#####DESCRIPTIONBEGIN####//// Author(s): jlarmour// Contributors: jlarmour// Date: 1999-02-12// Purpose: Provide implementation of ISO C and POSIX 1003.1 signals// Description: This file initializes all hardware exceptions,// initializes the signal handler table and provides the// default action function for signals// Usage: ////####DESCRIPTIONEND####////========================================================================// CONFIGURATION#include <pkgconf/libc.h> // C library configuration#ifdef CYGPKG_LIBC_SIGNALS// INCLUDES#include <cyg/infra/cyg_type.h> // Common type definitions and support#include <signal.h> // Main signals definitions#include <cyg/infra/cyg_ass.h> // Assertion infrastructure#include <cyg/infra/cyg_trac.h> // Tracing infrastructure#include <stdlib.h> // exit()#ifdef CYGSEM_LIBC_SIGNALS_HWEXCEPTIONS# include <pkgconf/kernel.h> // required for kernel includes# include <cyg/kernel/except.hxx> // Kernel exception API# include <cyg/kernel/thread.hxx> // Cyg_Thread::self()# include <cyg/kernel/thread.inl> // inline definitions for above# include <cyg/kernel/intr.hxx> // Interrupt enable# include <cyg/hal/hal_intr.h> // HAL interrupt control#endif#ifdef CYGSEM_LIBC_SIGNALS_THREAD_SAFE# include <pkgconf/kernel.h> // required for kernel includes# include <cyg/kernel/mutex.hxx>#endif// TYPE DEFINITIONS// define dummy class to allow initialization of cyg_libc_signal_handlersclass Cyg_libc_signals_dummy_init_class {public: Cyg_libc_signals_dummy_init_class();};#ifdef CYGSEM_LIBC_SIGNALS_HWEXCEPTIONSstruct exception_signal_mapping_t { cyg_code exception; int signal;}; // EXTERNSextern cyg_exception_handler cyg_null_exception_handler;#endif // ifdef CYGSEM_LIBC_SIGNALS_HWEXCEPTIONS// GLOBALS// main signal handlers__sighandler_t cyg_libc_signal_handlers[CYGNUM_LIBC_SIGNALS];#ifdef CYGSEM_LIBC_SIGNALS_THREAD_SAFECyg_Mutex cyg_libc_signal_handlers_mutex CYG_INIT_PRIORITY(LIBC);#endif// STATICS// dummy object to invoke constructorstatic Cyg_libc_signals_dummy_init_classcyg_libc_signals_dummy_init_obj CYG_INIT_PRIORITY(LIBC);#ifdef CYGSEM_LIBC_SIGNALS_HWEXCEPTIONS# ifdef CYGDBG_USE_TRACINGstatic cyg_uint8 cyg_libc_signals_hwhandler_trace_level = CYGNUM_LIBC_SIGNALS_HWHANDLER_TRACE_LEVEL;# define TL1 (0 < cyg_libc_signals_hwhandler_trace_level)# endif# ifdef CYGSEM_LIBC_SIGNALS_CHAIN_HWEXCEPTIONS// old exception info so we can chain// FIXME: consider malloced linked list config optionstatic struct { cyg_exception_handler *old_handler; CYG_ADDRWORD old_data;} exception_chain_data[CYGNUM_HAL_EXCEPTION_COUNT];# endif// struct that maps exceptions to signalsstatic const struct exception_signal_mapping_texception_signal_mapping[] = {#ifdef CYGNUM_HAL_EXCEPTION_DATA_ACCESS {CYGNUM_HAL_EXCEPTION_DATA_ACCESS, SIGBUS},#endif#ifdef CYGNUM_HAL_EXCEPTION_DATA_WRITE {CYGNUM_HAL_EXCEPTION_DATA_WRITE, SIGBUS},#endif#ifdef CYGNUM_HAL_EXCEPTION_CODE_ACCESS {CYGNUM_HAL_EXCEPTION_CODE_ACCESS, SIGBUS},#endif #ifdef CYGNUM_HAL_EXCEPTION_CODE_WRITE {CYGNUM_HAL_EXCEPTION_CODE_WRITE, SIGBUS},#endif #ifdef CYGNUM_HAL_EXCEPTION_CODE_EXECUTE {CYGNUM_HAL_EXCEPTION_CODE_EXECUTE, SIGBUS},#endif #ifdef CYGNUM_HAL_EXCEPTION_IO_ACCESS {CYGNUM_HAL_EXCEPTION_IO_ACCESS, SIGBUS},#endif #ifdef CYGNUM_HAL_EXCEPTION_IO_WRITE {CYGNUM_HAL_EXCEPTION_IO_ACCESS, SIGBUS},#endif #ifdef CYGNUM_HAL_EXCEPTION_DATA_TLBMISS_ACCESS {CYGNUM_HAL_EXCEPTION_DATA_TLBMISS_ACCESS, SIGSEGV},#endif #ifdef CYGNUM_HAL_EXCEPTION_DATA_TLBMISS_WRITE {CYGNUM_HAL_EXCEPTION_DATA_TLBMISS_WRITE, SIGSEGV},#endif #ifdef CYGNUM_HAL_EXCEPTION_CODE_TLBMISS_ACCESS {CYGNUM_HAL_EXCEPTION_CODE_TLBMISS_ACCESS, SIGSEGV},#endif #ifdef CYGNUM_HAL_EXCEPTION_CODE_TLBMISS_WRITE {CYGNUM_HAL_EXCEPTION_CODE_TLBMISS_WRITE, SIGSEGV},#endif #ifdef CYGNUM_HAL_EXCEPTION_DATA_TLBERROR_ACCESS {CYGNUM_HAL_EXCEPTION_DATA_TLBERROR_ACCESS, SIGSEGV},#endif #ifdef CYGNUM_HAL_EXCEPTION_DATA_TLBERROR_WRITE {CYGNUM_HAL_EXCEPTION_DATA_TLBERROR_WRITE, SIGSEGV},#endif #ifdef CYGNUM_HAL_EXCEPTION_CODE_TLBERROR_ACCESS {CYGNUM_HAL_EXCEPTION_CODE_TLBERROR_ACCESS, SIGSEGV},#endif #ifdef CYGNUM_HAL_EXCEPTION_CODE_TLBERROR_WRITE {CYGNUM_HAL_EXCEPTION_CODE_TLBERROR_WRITE, SIGSEGV},#endif #ifdef CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS {CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS, SIGBUS},#endif #ifdef CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_WRITE {CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_WRITE, SIGBUS},#endif #ifdef CYGNUM_HAL_EXCEPTION_IO_UNALIGNED_ACCESS {CYGNUM_HAL_EXCEPTION_IO_UNALIGNED_ACCESS, SIGBUS},#endif #ifdef CYGNUM_HAL_EXCEPTION_IO_UNALIGNED_WRITE {CYGNUM_HAL_EXCEPTION_IO_UNALIGNED_WRITE, SIGBUS},#endif #ifdef CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION {CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION, SIGILL},#endif #ifdef CYGNUM_HAL_EXCEPTION_INTERRUPT {CYGNUM_HAL_EXCEPTION_INTERRUPT, SIGINT},#endif #ifdef CYGNUM_HAL_EXCEPTION_TRAP {CYGNUM_HAL_EXCEPTION_TRAP, SIGTRAP},#endif #ifdef CYGNUM_HAL_EXCEPTION_DIV_BY_ZERO {CYGNUM_HAL_EXCEPTION_DIV_BY_ZERO, SIGFPE},#endif #ifdef CYGNUM_HAL_EXCEPTION_OVERFLOW {CYGNUM_HAL_EXCEPTION_OVERFLOW, SIGFPE},#endif #ifdef CYGNUM_HAL_EXCEPTION_BOUNDS {CYGNUM_HAL_EXCEPTION_BOUNDS, SIGSEGV},#endif#ifdef CYGNUM_HAL_EXCEPTION_SINGLE_STEP {CYGNUM_HAL_EXCEPTION_SINGLE_STEP, SIGTRAP},#endif#ifdef CYGNUM_HAL_EXCEPTION_INSTRUCTION_BP {CYGNUM_HAL_EXCEPTION_INSTRUCTION_BP, SIGTRAP},#endif#ifdef CYGNUM_HAL_EXCEPTION_PERIPHERAL_BP {CYGNUM_HAL_EXCEPTION_PERIPHERAL_BP, SIGTRAP},#endif#ifdef CYGNUM_HAL_EXCEPTION_DATA_BP {CYGNUM_HAL_EXCEPTION_DATA_BP, SIGTRAP},#endif#ifdef CYGNUM_HAL_EXCEPTION_DEVELOPMENT_BP {CYGNUM_HAL_EXCEPTION_DEVELOPMENT_BP, SIGTRAP},#endif#ifdef CYGNUM_HAL_EXCEPTION_STACK_OVERFLOW {CYGNUM_HAL_EXCEPTION_STACK_OVERFLOW, SIGSEGV},#endif#ifdef CYGNUM_HAL_EXCEPTION_STACK_FAULT {CYGNUM_HAL_EXCEPTION_STACK_FAULT, SIGSEGV},#endif#ifdef CYGNUM_HAL_EXCEPTION_PARITY {CYGNUM_HAL_EXCEPTION_PARITY, SIGBUS},#endif#ifdef CYGNUM_HAL_EXCEPTION_FPU {CYGNUM_HAL_EXCEPTION_FPU, SIGFPE},#endif#ifdef CYGNUM_HAL_EXCEPTION_FPU_NOT_AVAIL {CYGNUM_HAL_EXCEPTION_FPU_NOT_AVAIL, SIGFPE},#endif#ifdef CYGNUM_HAL_EXCEPTION_FPU_OVERFLOW {CYGNUM_HAL_EXCEPTION_FPU_OVERFLOW, SIGFPE},#endif#ifdef CYGNUM_HAL_EXCEPTION_FPU_UNDERFLOW {CYGNUM_HAL_EXCEPTION_FPU_UNDERFLOW, SIGFPE},#endif#ifdef CYGNUM_HAL_EXCEPTION_FPU_DIV_BY_ZERO {CYGNUM_HAL_EXCEPTION_FPU_DIV_BY_ZERO, SIGFPE},#endif#ifdef CYGNUM_HAL_EXCEPTION_SYSTEM_CALL {CYGNUM_HAL_EXCEPTION_SYSTEM_CALL, SIGSYS},#endif {0, 0} // dummy value to ensure compiler is happy}; // FUNCTIONS/////////////////////////////////////////// cyg_libc_signals_hwexcept_handler() ///////////////////////////////////////////// FIXME: should be able to get this work with// CYGSEM_KERNEL_EXCEPTIONS_DECODE disabled as well as enabledstatic voidcyg_libc_signals_hwexcept_handler( CYG_ADDRWORD data, cyg_code exception, CYG_ADDRWORD info){ int signal = (int)data; int ret; CYG_REPORT_FUNCNAME("cyg_libc_signals_hwexcept_handler"); CYG_REPORT_FUNCARG3( "data = %08x, exception = %d, info = %08x", data, exception, info );#ifdef CYGSEM_LIBC_SIGNALS_BAD_SIGNAL_FATAL CYG_PRECONDITION((signal > 0) && (signal < CYGNUM_LIBC_SIGNALS), "Signal number not valid!");#endif// chain first as it may be more useful more low-level stuff needed#ifdef CYGSEM_LIBC_SIGNALS_CHAIN_HWEXCEPTIONS // map exception to 0..CYGNUM_HAL_EXCEPTION_COUNT exception -= CYGNUM_HAL_EXCEPTION_MIN; // special case for null handler since it is only for uncaught exceptions if (exception_chain_data[exception].old_handler != cyg_null_exception_handler) { (*exception_chain_data[exception].old_handler)( exception_chain_data[exception].old_data, exception, info); CYG_TRACE0(TL1, "Chained exception handler returned"); } // if#endif#ifndef CYGSEM_LIBC_SIGNALS_BAD_SIGNAL_FATAL // if not fatal, silently return if ((signal <= 0) || (signal >= CYGNUM_LIBC_SIGNALS)) { CYG_REPORT_RETURN(); return; }#endif CYG_TRACE0(TL1, "Enabling interrupts"); HAL_ENABLE_INTERRUPTS(); CYG_TRACE0(TL1, "Raising signal"); ret = raise(signal); if (ret) { CYG_TRACE1(TL1, "raise() returned non-zero value %d!!!", ret); } // if CYG_REPORT_RETURN();} // cyg_libc_signals_hwexcept_handler()//////////////////// reg_except() ////////////////////static void inlinereg_except( cyg_code exception, int signal ){ Cyg_Thread::self()->register_exception( exception, &cyg_libc_signals_hwexcept_handler, (CYG_ADDRWORD)signal,#ifdef CYGSEM_LIBC_SIGNALS_CHAIN_HWEXCEPTIONS &exception_chain_data[exception - CYGNUM_HAL_EXCEPTION_MIN].old_handler, &exception_chain_data[exception - CYGNUM_HAL_EXCEPTION_MIN].old_data#else NULL, NULL#endif );} // reg_except();#endif // ifdef CYGSEM_LIBC_SIGNALS_HWEXCEPTIONS///////////////////////////////////////////////////// Cyg_libc_signals_dummy_init_class constructor /////////////////////////////////////////////////////Cyg_libc_signals_dummy_init_class::Cyg_libc_signals_dummy_init_class(){ cyg_ucount8 i; CYG_REPORT_FUNCNAME("Cyg_libc_signals_dummy_init_class constructor"); // FIXME: some should be SIG_IGN? for (i=0; i<CYGNUM_LIBC_SIGNALS; i++) cyg_libc_signal_handlers[i] = SIG_DFL;#ifdef CYGSEM_LIBC_SIGNALS_HWEXCEPTIONS // go through the entire array of exceptions, _but_ subtract 1 for // the dummy at the end for (i=0; i < (sizeof(exception_signal_mapping) / sizeof(exception_signal_mapping_t) - 1); i++) { CYG_ASSERT( (exception_signal_mapping[i].exception <= CYGNUM_HAL_EXCEPTION_MAX) && (exception_signal_mapping[i].exception >= CYGNUM_HAL_EXCEPTION_MIN), "Asked to register bad exception"); CYG_ASSERT( (exception_signal_mapping[i].signal > 0) && (exception_signal_mapping[i].signal < CYGNUM_LIBC_SIGNALS), "Asked to register bad signal" ); reg_except( exception_signal_mapping[i].exception, exception_signal_mapping[i].signal); }#endif CYG_REPORT_RETURN();} // Cyg_libc_signals_dummy_init_class() constructor////////////////////////////////////////// cyg_libc_signals_default_handler() //////////////////////////////////////////// Default signal handler - SIG_DFLexternC voidcyg_libc_signals_default_handler(int sig){ CYG_REPORT_FUNCNAME( "cyg_libc_signals_default_handler" ); CYG_REPORT_FUNCARG1( "signal number = %d", sig ); exit(1000 + sig); // FIXME CYG_REPORT_RETURN();} // cyg_libc_signals_default_handler()#ifdef CYGSEM_LIBC_SIGNALS_THREAD_SAFE/////////////////////////////////////// cyg_libc_signals_lock_do_lock() ///////////////////////////////////////externC cyg_boolcyg_libc_signals_lock_do_lock(void){ cyg_bool ret; CYG_REPORT_FUNCNAMETYPE("cyg_libc_signals_lock_do_lock", "returning %d"); ret = cyg_libc_signal_handlers_mutex.lock(); CYG_REPORT_RETVAL(ret); return ret;} // cyg_libc_signals_lock_do_lock()///////////////////////////////////////// cyg_libc_signals_lock_do_unlock() /////////////////////////////////////////externC voidcyg_libc_signals_lock_do_unlock(void){ CYG_REPORT_FUNCNAME("cyg_libc_signals_lock_do_unlock"); cyg_libc_signal_handlers_mutex.unlock(); CYG_REPORT_RETURN();} // cyg_libc_signals_lock_do_unlock()#endif // ifdef CYGSEM_LIBC_SIGNALS_THREAD_SAFE#endif // ifdef CYGPKG_LIBC_SIGNALS// EOF siginit.cxx
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -