📄 except.cxx
字号:
//==========================================================================
//
// except.cxx
//
// POSIX exception translation
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): nickg
// Contributors: nickg
// Date: 2000-03-27
// Purpose: POSIX exception translation
// Description: This file contains code to translate eCos hardware
// exceptions into POSIX signals.
//
//
//
//####DESCRIPTIONEND####
//
//==========================================================================
#include <pkgconf/hal.h>
#include <pkgconf/kernel.h>
#include <pkgconf/posix.h>
#include <cyg/kernel/ktypes.h> // base kernel types
#include <cyg/infra/cyg_trac.h> // tracing macros
#include <cyg/infra/cyg_ass.h> // assertion macros
#include <cyg/infra/diag.h>
#include "pprivate.h" // POSIX private header
#include <signal.h> // our header
#include <cyg/kernel/thread.inl>
//==========================================================================
// Translation table from eCos exceptions to POSIX signals.
static const struct
{
cyg_code exception;
int signal;
} exception_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
};
//==========================================================================
// POSIX exception handler
static void cyg_posix_exception_handler(
CYG_ADDRWORD data, // user supplied data == signal number
cyg_code exception_number, // exception being raised
CYG_ADDRWORD exception_info // any exception specific info
)
{
int signo = 0;
pthread_info *self = pthread_self_info();
if( self == NULL )
{
// Not a POSIX thread, just return
return;
}
#ifdef CYGSEM_KERNEL_EXCEPTIONS_DECODE
signo = data;
#else
for( int i = 0; exception_signal_mapping[i].signal != 0; i++ )
{
if( exception_signal_mapping[i].exception == exception_number )
{
signo = exception_signal_mapping[i].signal;
break;
}
}
#endif
if( sigismember( &self->sigmask, signo ) )
{
// The signal is masked in the current thread. POSIX says that
// the behaviour is undefined here. We choose to ignore it.
return;
}
// The kernel exception handler may have disabled interrupts, so
// we (re-)enable them here. From this point on we are running in
// a context that is effectively just pushed onto the stack of the
// current thread. If we return we will unwind and resume
// execution from the excepting code. We can also, in theory,
// longjump out of the signal handler, and although that is
// deprecated, we make sure in cyg_deliver_signals() that it is
// possible to do it.
HAL_ENABLE_INTERRUPTS();
struct sigevent sev;
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = signo;
sev.sigev_value.sival_ptr = (void *)exception_info;
// Generate the signal
cyg_sigqueue( &sev, SI_EXCEPT );
// And try to deliver it
cyg_deliver_signals();
}
//==========================================================================
// Install all the exception handlers
static void install_handlers( Cyg_Thread *thread)
{
#ifdef CYGSEM_KERNEL_EXCEPTIONS_DECODE
// With decoded exceptions, we must install a separate exception
// handler for each supported exception.
for( int i = 0; exception_signal_mapping[i].signal != 0; i++ )
{
thread->register_exception( exception_signal_mapping[i].exception,
cyg_posix_exception_handler,
exception_signal_mapping[i].signal,,
NULL,
NULL);
}
#else
// Otherwise there is just one exception handler for all exceptions.
thread->register_exception( CYGNUM_HAL_EXCEPTION_MIN,
cyg_posix_exception_handler,
0,
NULL,
NULL);
#endif
}
//==========================================================================
// Initialization
externC void cyg_posix_exception_start()
{
#ifdef CYGSEM_KERNEL_EXCEPTIONS_GLOBAL
// With global exceptions, we only need to install a single static
// set of exception handlers. Note that by this point in system
// initialization the idle thread should be installed as the
// current thread, so we pass a pointer to that to
// install_handlers(). The identity of the thread passed is
// actually irrelevant in this case and is just used as a handle
// into the thread class.
install_handlers( Cyg_Thread::self() );
#endif
}
//==========================================================================
// Per thread exception initialization and destruction
externC void cyg_pthread_exception_init(pthread_info *thread)
{
#ifndef CYGSEM_KERNEL_EXCEPTIONS_GLOBAL
// With non-global exceptions we must install a new set of handlers
// for each thread.
install_handlers( thread->thread );
#endif
}
externC void cyg_pthread_exception_destroy(pthread_info *thread)
{
// Nothing to do at present.
}
// -------------------------------------------------------------------------
// EOF except.cxx
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -