mirror of
https://github.com/apache/nuttx.git
synced 2026-06-01 07:45:16 +08:00
arch/: Fix an interlock that was broken by commit 641a98a434 in all implementations of up_sigdeliver.
This commit is contained in:
@@ -1065,7 +1065,7 @@ o Kernel/Protected Build
|
|||||||
Linux, applications do not have separate user and supervisor
|
Linux, applications do not have separate user and supervisor
|
||||||
stacks; everything is done on the user stack.
|
stacks; everything is done on the user stack.
|
||||||
|
|
||||||
In the implementation of up_sigdeliver, a copy of the
|
In the implementation of up_sigdeliver(), a copy of the
|
||||||
register contents that will be restored is present on the
|
register contents that will be restored is present on the
|
||||||
stack and could be modified by the user application. Thus,
|
stack and could be modified by the user application. Thus,
|
||||||
if the user mucks with the return stack, problems could
|
if the user mucks with the return stack, problems could
|
||||||
@@ -1077,6 +1077,12 @@ o Kernel/Protected Build
|
|||||||
return address and switch to supervisor mode. Other register
|
return address and switch to supervisor mode. Other register
|
||||||
are still modifiable and there is other possible mayhem that
|
are still modifiable and there is other possible mayhem that
|
||||||
could be done.
|
could be done.
|
||||||
|
|
||||||
|
A better solution, in lieu of a kernel stack, would be to
|
||||||
|
eliminate the stack-based register save area and, instead,
|
||||||
|
save the registers in another, dedicated state save area in
|
||||||
|
the TCB. The only hesitation to this option is that it would
|
||||||
|
significantly increase the size of the TCB structure.
|
||||||
Status: Open
|
Status: Open
|
||||||
Priority: Medium-ish if are attempting to make a secure environment that
|
Priority: Medium-ish if are attempting to make a secure environment that
|
||||||
may host malicious code. Very low for the typical FLAT build,
|
may host malicious code. Very low for the typical FLAT build,
|
||||||
|
|||||||
@@ -73,7 +73,6 @@ void up_sigdeliver(void)
|
|||||||
{
|
{
|
||||||
struct tcb_s *rtcb = this_task();
|
struct tcb_s *rtcb = this_task();
|
||||||
uint32_t regs[XCPTCONTEXT_REGS];
|
uint32_t regs[XCPTCONTEXT_REGS];
|
||||||
sig_deliver_t sigdeliver;
|
|
||||||
|
|
||||||
/* Save the errno. This must be preserved throughout the signal handling
|
/* Save the errno. This must be preserved throughout the signal handling
|
||||||
* so that the user code final gets the correct errno value (probably
|
* so that the user code final gets the correct errno value (probably
|
||||||
@@ -92,14 +91,6 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
up_copyfullstate(regs, rtcb->xcp.regs);
|
up_copyfullstate(regs, rtcb->xcp.regs);
|
||||||
|
|
||||||
/* Get a local copy of the sigdeliver function pointer. we do this so that
|
|
||||||
* we can nullify the sigdeliver function pointer in the TCB and accept
|
|
||||||
* more signal deliveries while processing the current pending signals.
|
|
||||||
*/
|
|
||||||
|
|
||||||
sigdeliver = rtcb->xcp.sigdeliver;
|
|
||||||
rtcb->xcp.sigdeliver = NULL;
|
|
||||||
|
|
||||||
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
||||||
/* Then make sure that interrupts are enabled. Signal handlers must always
|
/* Then make sure that interrupts are enabled. Signal handlers must always
|
||||||
* run with interrupts enabled.
|
* run with interrupts enabled.
|
||||||
@@ -108,9 +99,9 @@ void up_sigdeliver(void)
|
|||||||
up_irq_enable();
|
up_irq_enable();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Deliver the signals */
|
/* Deliver the signal */
|
||||||
|
|
||||||
sigdeliver(rtcb);
|
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
|
||||||
|
|
||||||
/* Output any debug messages BEFORE restoring errno (because they may
|
/* Output any debug messages BEFORE restoring errno (because they may
|
||||||
* alter errno), then disable interrupts again and restore the original
|
* alter errno), then disable interrupts again and restore the original
|
||||||
@@ -119,7 +110,7 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
sinfo("Resuming\n");
|
sinfo("Resuming\n");
|
||||||
(void)up_irq_save();
|
(void)up_irq_save();
|
||||||
rtcb->pterrno = saved_errno;
|
rtcb->pterrno = saved_errno;
|
||||||
|
|
||||||
/* Modify the saved return state with the actual saved values in the
|
/* Modify the saved return state with the actual saved values in the
|
||||||
* TCB. This depends on the fact that nested signal handling is
|
* TCB. This depends on the fact that nested signal handling is
|
||||||
@@ -131,8 +122,9 @@ void up_sigdeliver(void)
|
|||||||
* could be modified by a hostile program.
|
* could be modified by a hostile program.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
regs[REG_PC] = rtcb->xcp.saved_pc;
|
regs[REG_PC] = rtcb->xcp.saved_pc;
|
||||||
regs[REG_CPSR] = rtcb->xcp.saved_cpsr;
|
regs[REG_CPSR] = rtcb->xcp.saved_cpsr;
|
||||||
|
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
|
||||||
|
|
||||||
/* Then restore the correct state for this thread of execution. */
|
/* Then restore the correct state for this thread of execution. */
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,6 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
struct tcb_s *rtcb = this_task();
|
struct tcb_s *rtcb = this_task();
|
||||||
uint32_t regs[XCPTCONTEXT_REGS + 4];
|
uint32_t regs[XCPTCONTEXT_REGS + 4];
|
||||||
sig_deliver_t sigdeliver;
|
|
||||||
|
|
||||||
/* Save the errno. This must be preserved throughout the signal handling
|
/* Save the errno. This must be preserved throughout the signal handling
|
||||||
* so that the user code final gets the correct errno value (probably
|
* so that the user code final gets the correct errno value (probably
|
||||||
@@ -96,14 +95,6 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
up_copyfullstate(regs, rtcb->xcp.regs);
|
up_copyfullstate(regs, rtcb->xcp.regs);
|
||||||
|
|
||||||
/* Get a local copy of the sigdeliver function pointer. We do this so that
|
|
||||||
* we can nullify the sigdeliver function pointer in the TCB and accept
|
|
||||||
* more signal deliveries while processing the current pending signals.
|
|
||||||
*/
|
|
||||||
|
|
||||||
sigdeliver = rtcb->xcp.sigdeliver;
|
|
||||||
rtcb->xcp.sigdeliver = NULL;
|
|
||||||
|
|
||||||
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
||||||
/* Then make sure that interrupts are enabled. Signal handlers must always
|
/* Then make sure that interrupts are enabled. Signal handlers must always
|
||||||
* run with interrupts enabled.
|
* run with interrupts enabled.
|
||||||
@@ -114,7 +105,7 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
/* Deliver the signal */
|
/* Deliver the signal */
|
||||||
|
|
||||||
sigdeliver(rtcb);
|
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
|
||||||
|
|
||||||
/* Output any debug messages BEFORE restoring errno (because they may
|
/* Output any debug messages BEFORE restoring errno (because they may
|
||||||
* alter errno), then disable interrupts again and restore the original
|
* alter errno), then disable interrupts again and restore the original
|
||||||
@@ -135,12 +126,13 @@ void up_sigdeliver(void)
|
|||||||
* could be modified by a hostile program.
|
* could be modified by a hostile program.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
regs[REG_PC] = rtcb->xcp.saved_pc;
|
regs[REG_PC] = rtcb->xcp.saved_pc;
|
||||||
regs[REG_PRIMASK] = rtcb->xcp.saved_primask;
|
regs[REG_PRIMASK] = rtcb->xcp.saved_primask;
|
||||||
regs[REG_XPSR] = rtcb->xcp.saved_xpsr;
|
regs[REG_XPSR] = rtcb->xcp.saved_xpsr;
|
||||||
#ifdef CONFIG_BUILD_PROTECTED
|
#ifdef CONFIG_BUILD_PROTECTED
|
||||||
regs[REG_LR] = rtcb->xcp.saved_lr;
|
regs[REG_LR] = rtcb->xcp.saved_lr;
|
||||||
#endif
|
#endif
|
||||||
|
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
|
||||||
|
|
||||||
/* Then restore the correct state for this thread of
|
/* Then restore the correct state for this thread of
|
||||||
* execution.
|
* execution.
|
||||||
|
|||||||
@@ -73,7 +73,6 @@ void up_sigdeliver(void)
|
|||||||
{
|
{
|
||||||
struct tcb_s *rtcb = this_task();
|
struct tcb_s *rtcb = this_task();
|
||||||
uint32_t regs[XCPTCONTEXT_REGS];
|
uint32_t regs[XCPTCONTEXT_REGS];
|
||||||
sig_deliver_t sigdeliver;
|
|
||||||
|
|
||||||
/* Save the errno. This must be preserved throughout the signal handling
|
/* Save the errno. This must be preserved throughout the signal handling
|
||||||
* so that the user code final gets the correct errno value (probably
|
* so that the user code final gets the correct errno value (probably
|
||||||
@@ -101,14 +100,6 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
up_copyfullstate(regs, rtcb->xcp.regs);
|
up_copyfullstate(regs, rtcb->xcp.regs);
|
||||||
|
|
||||||
/* Get a local copy of the sigdeliver function pointer. we do this so that
|
|
||||||
* we can nullify the sigdeliver function pointer in the TCB and accept
|
|
||||||
* more signal deliveries while processing the current pending signals.
|
|
||||||
*/
|
|
||||||
|
|
||||||
sigdeliver = rtcb->xcp.sigdeliver;
|
|
||||||
rtcb->xcp.sigdeliver = NULL;
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
/* In the SMP case, up_schedule_sigaction(0) will have incremented
|
/* In the SMP case, up_schedule_sigaction(0) will have incremented
|
||||||
* 'irqcount' in order to force us into a critical section. Save the
|
* 'irqcount' in order to force us into a critical section. Save the
|
||||||
@@ -139,7 +130,7 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
/* Deliver the signal */
|
/* Deliver the signal */
|
||||||
|
|
||||||
sigdeliver(rtcb);
|
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
|
||||||
|
|
||||||
/* Output any debug messages BEFORE restoring errno (because they may
|
/* Output any debug messages BEFORE restoring errno (because they may
|
||||||
* alter errno), then disable interrupts again and restore the original
|
* alter errno), then disable interrupts again and restore the original
|
||||||
@@ -160,7 +151,7 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
/* Restore the saved errno value */
|
/* Restore the saved errno value */
|
||||||
|
|
||||||
rtcb->pterrno = saved_errno;
|
rtcb->pterrno = saved_errno;
|
||||||
|
|
||||||
/* Modify the saved return state with the actual saved values in the
|
/* Modify the saved return state with the actual saved values in the
|
||||||
* TCB. This depends on the fact that nested signal handling is
|
* TCB. This depends on the fact that nested signal handling is
|
||||||
@@ -172,8 +163,9 @@ void up_sigdeliver(void)
|
|||||||
* could be modified by a hostile program.
|
* could be modified by a hostile program.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
regs[REG_PC] = rtcb->xcp.saved_pc;
|
regs[REG_PC] = rtcb->xcp.saved_pc;
|
||||||
regs[REG_CPSR] = rtcb->xcp.saved_cpsr;
|
regs[REG_CPSR] = rtcb->xcp.saved_cpsr;
|
||||||
|
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
/* Restore the saved 'irqcount' and recover the critical section
|
/* Restore the saved 'irqcount' and recover the critical section
|
||||||
|
|||||||
@@ -73,7 +73,6 @@ void up_sigdeliver(void)
|
|||||||
{
|
{
|
||||||
struct tcb_s *rtcb = this_task();
|
struct tcb_s *rtcb = this_task();
|
||||||
uint32_t regs[XCPTCONTEXT_REGS];
|
uint32_t regs[XCPTCONTEXT_REGS];
|
||||||
sig_deliver_t sigdeliver;
|
|
||||||
|
|
||||||
/* Save the errno. This must be preserved throughout the signal handling
|
/* Save the errno. This must be preserved throughout the signal handling
|
||||||
* so that the user code final gets the correct errno value (probably
|
* so that the user code final gets the correct errno value (probably
|
||||||
@@ -101,14 +100,6 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
up_copyfullstate(regs, rtcb->xcp.regs);
|
up_copyfullstate(regs, rtcb->xcp.regs);
|
||||||
|
|
||||||
/* Get a local copy of the sigdeliver function pointer. We do this so that
|
|
||||||
* we can nullify the sigdeliver function pointer in the TCB and accept
|
|
||||||
* more signal deliveries while processing the current pending signals.
|
|
||||||
*/
|
|
||||||
|
|
||||||
sigdeliver = (sig_deliver_t)rtcb->xcp.sigdeliver;
|
|
||||||
rtcb->xcp.sigdeliver = NULL;
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
/* In the SMP case, up_schedule_sigaction(0) will have incremented
|
/* In the SMP case, up_schedule_sigaction(0) will have incremented
|
||||||
* 'irqcount' in order to force us into a critical section. Save the
|
* 'irqcount' in order to force us into a critical section. Save the
|
||||||
@@ -143,7 +134,7 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
/* Deliver the signal */
|
/* Deliver the signal */
|
||||||
|
|
||||||
sigdeliver(rtcb);
|
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
|
||||||
|
|
||||||
/* Output any debug messages BEFORE restoring errno (because they may
|
/* Output any debug messages BEFORE restoring errno (because they may
|
||||||
* alter errno), then disable interrupts again and restore the original
|
* alter errno), then disable interrupts again and restore the original
|
||||||
@@ -164,7 +155,7 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
/* Restore the saved errno value */
|
/* Restore the saved errno value */
|
||||||
|
|
||||||
rtcb->pterrno = saved_errno;
|
rtcb->pterrno = saved_errno;
|
||||||
|
|
||||||
/* Modify the saved return state with the actual saved values in the
|
/* Modify the saved return state with the actual saved values in the
|
||||||
* TCB. This depends on the fact that nested signal handling is
|
* TCB. This depends on the fact that nested signal handling is
|
||||||
@@ -176,16 +167,17 @@ void up_sigdeliver(void)
|
|||||||
* could be modified by a hostile program.
|
* could be modified by a hostile program.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
regs[REG_PC] = rtcb->xcp.saved_pc;
|
regs[REG_PC] = rtcb->xcp.saved_pc;
|
||||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||||
regs[REG_BASEPRI] = rtcb->xcp.saved_basepri;
|
regs[REG_BASEPRI] = rtcb->xcp.saved_basepri;
|
||||||
#else
|
#else
|
||||||
regs[REG_PRIMASK] = rtcb->xcp.saved_primask;
|
regs[REG_PRIMASK] = rtcb->xcp.saved_primask;
|
||||||
#endif
|
#endif
|
||||||
regs[REG_XPSR] = rtcb->xcp.saved_xpsr;
|
regs[REG_XPSR] = rtcb->xcp.saved_xpsr;
|
||||||
#ifdef CONFIG_BUILD_PROTECTED
|
#ifdef CONFIG_BUILD_PROTECTED
|
||||||
regs[REG_LR] = rtcb->xcp.saved_lr;
|
regs[REG_LR] = rtcb->xcp.saved_lr;
|
||||||
#endif
|
#endif
|
||||||
|
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
/* Restore the saved 'irqcount' and recover the critical section
|
/* Restore the saved 'irqcount' and recover the critical section
|
||||||
|
|||||||
@@ -72,7 +72,6 @@ void up_sigdeliver(void)
|
|||||||
{
|
{
|
||||||
struct tcb_s *rtcb = this_task();
|
struct tcb_s *rtcb = this_task();
|
||||||
uint32_t regs[XCPTCONTEXT_REGS];
|
uint32_t regs[XCPTCONTEXT_REGS];
|
||||||
sig_deliver_t sigdeliver;
|
|
||||||
|
|
||||||
/* Save the errno. This must be preserved throughout the signal handling
|
/* Save the errno. This must be preserved throughout the signal handling
|
||||||
* so that the user code final gets the correct errno value (probably
|
* so that the user code final gets the correct errno value (probably
|
||||||
@@ -91,14 +90,6 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
up_copyfullstate(regs, rtcb->xcp.regs);
|
up_copyfullstate(regs, rtcb->xcp.regs);
|
||||||
|
|
||||||
/* Get a local copy of the sigdeliver function pointer. we do this so that
|
|
||||||
* we can nullify the sigdeliver function pointer in the TCB and accept
|
|
||||||
* more signal deliveries while processing the current pending signals.
|
|
||||||
*/
|
|
||||||
|
|
||||||
sigdeliver = rtcb->xcp.sigdeliver;
|
|
||||||
rtcb->xcp.sigdeliver = NULL;
|
|
||||||
|
|
||||||
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
||||||
/* Then make sure that interrupts are enabled. Signal handlers must always
|
/* Then make sure that interrupts are enabled. Signal handlers must always
|
||||||
* run with interrupts enabled.
|
* run with interrupts enabled.
|
||||||
@@ -107,9 +98,9 @@ void up_sigdeliver(void)
|
|||||||
up_irq_enable();
|
up_irq_enable();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Deliver the signals */
|
/* Deliver the signal */
|
||||||
|
|
||||||
sigdeliver(rtcb);
|
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
|
||||||
|
|
||||||
/* Output any debug messages BEFORE restoring errno (because they may
|
/* Output any debug messages BEFORE restoring errno (because they may
|
||||||
* alter errno), then disable interrupts again and restore the original
|
* alter errno), then disable interrupts again and restore the original
|
||||||
@@ -132,6 +123,7 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
regs[REG_PC] = rtcb->xcp.saved_pc;
|
regs[REG_PC] = rtcb->xcp.saved_pc;
|
||||||
regs[REG_CPSR] = rtcb->xcp.saved_cpsr;
|
regs[REG_CPSR] = rtcb->xcp.saved_cpsr;
|
||||||
|
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
|
||||||
|
|
||||||
/* Then restore the correct state for this thread of execution. */
|
/* Then restore the correct state for this thread of execution. */
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,6 @@ void up_sigdeliver(void)
|
|||||||
{
|
{
|
||||||
struct tcb_s *rtcb = this_task();
|
struct tcb_s *rtcb = this_task();
|
||||||
uint8_t regs[XCPTCONTEXT_REGS];
|
uint8_t regs[XCPTCONTEXT_REGS];
|
||||||
sig_deliver_t sigdeliver;
|
|
||||||
|
|
||||||
/* Save the errno. This must be preserved throughout the signal handling
|
/* Save the errno. This must be preserved throughout the signal handling
|
||||||
* so that the user code final gets the correct errno value (probably EINTR).
|
* so that the user code final gets the correct errno value (probably EINTR).
|
||||||
@@ -90,14 +89,6 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
up_copystate(regs, rtcb->xcp.regs);
|
up_copystate(regs, rtcb->xcp.regs);
|
||||||
|
|
||||||
/* Get a local copy of the sigdeliver function pointer. We do this so that
|
|
||||||
* we can nullify the sigdeliver function pointer in the TCB and accept
|
|
||||||
* more signal deliveries while processing the current pending signals.
|
|
||||||
*/
|
|
||||||
|
|
||||||
sigdeliver = rtcb->xcp.sigdeliver;
|
|
||||||
rtcb->xcp.sigdeliver = NULL;
|
|
||||||
|
|
||||||
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
||||||
/* Then make sure that interrupts are enabled. Signal handlers must always
|
/* Then make sure that interrupts are enabled. Signal handlers must always
|
||||||
* run with interrupts enabled.
|
* run with interrupts enabled.
|
||||||
@@ -106,9 +97,9 @@ void up_sigdeliver(void)
|
|||||||
up_irq_enable();
|
up_irq_enable();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Deliver the signals */
|
/* Deliver the signal */
|
||||||
|
|
||||||
sigdeliver(rtcb);
|
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
|
||||||
|
|
||||||
/* Output any debug messages BEFORE restoring errno (because they may
|
/* Output any debug messages BEFORE restoring errno (because they may
|
||||||
* alter errno), then disable interrupts again and restore the original
|
* alter errno), then disable interrupts again and restore the original
|
||||||
@@ -117,7 +108,7 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
sinfo("Resuming\n");
|
sinfo("Resuming\n");
|
||||||
(void)up_irq_save();
|
(void)up_irq_save();
|
||||||
rtcb->pterrno = saved_errno;
|
rtcb->pterrno = saved_errno;
|
||||||
|
|
||||||
/* Modify the saved return state with the actual saved values in the
|
/* Modify the saved return state with the actual saved values in the
|
||||||
* TCB. This depends on the fact that nested signal handling is
|
* TCB. This depends on the fact that nested signal handling is
|
||||||
@@ -129,12 +120,13 @@ void up_sigdeliver(void)
|
|||||||
* could be modified by a hostile program.
|
* could be modified by a hostile program.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
regs[REG_PC0] = rtcb->xcp.saved_pc0;
|
regs[REG_PC0] = rtcb->xcp.saved_pc0;
|
||||||
regs[REG_PC1] = rtcb->xcp.saved_pc1;
|
regs[REG_PC1] = rtcb->xcp.saved_pc1;
|
||||||
#if defined(REG_PC2)
|
#if defined(REG_PC2)
|
||||||
regs[REG_PC2] = rtcb->xcp.saved_pc2;
|
regs[REG_PC2] = rtcb->xcp.saved_pc2;
|
||||||
#endif
|
#endif
|
||||||
regs[REG_SREG] = rtcb->xcp.saved_sreg;
|
regs[REG_SREG] = rtcb->xcp.saved_sreg;
|
||||||
|
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
|
||||||
|
|
||||||
/* Then restore the correct state for this thread of execution. This is an
|
/* Then restore the correct state for this thread of execution. This is an
|
||||||
* unusual case that must be handled by up_fullcontextresore. This case is
|
* unusual case that must be handled by up_fullcontextresore. This case is
|
||||||
|
|||||||
@@ -76,7 +76,6 @@ void up_sigdeliver(void)
|
|||||||
#else
|
#else
|
||||||
uint32_t regs[XCPTCONTEXT_REGS];
|
uint32_t regs[XCPTCONTEXT_REGS];
|
||||||
#endif
|
#endif
|
||||||
sig_deliver_t sigdeliver;
|
|
||||||
|
|
||||||
/* Save the errno. This must be preserved throughout the signal handling
|
/* Save the errno. This must be preserved throughout the signal handling
|
||||||
* so that the user code final gets the correct errno value (probably EINTR).
|
* so that the user code final gets the correct errno value (probably EINTR).
|
||||||
@@ -94,14 +93,6 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
up_copystate(regs, rtcb->xcp.regs);
|
up_copystate(regs, rtcb->xcp.regs);
|
||||||
|
|
||||||
/* Get a local copy of the sigdeliver function pointer. We do this so that
|
|
||||||
* we can nullify the sigdeliver function pointer in the TCB and accept
|
|
||||||
* more signal deliveries while processing the current pending signals.
|
|
||||||
*/
|
|
||||||
|
|
||||||
sigdeliver = rtcb->xcp.sigdeliver;
|
|
||||||
rtcb->xcp.sigdeliver = NULL;
|
|
||||||
|
|
||||||
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
||||||
/* Then make sure that interrupts are enabled. Signal handlers must always
|
/* Then make sure that interrupts are enabled. Signal handlers must always
|
||||||
* run with interrupts enabled.
|
* run with interrupts enabled.
|
||||||
@@ -110,9 +101,9 @@ void up_sigdeliver(void)
|
|||||||
up_irq_enable();
|
up_irq_enable();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Deliver the signals */
|
/* Deliver the signal */
|
||||||
|
|
||||||
sigdeliver(rtcb);
|
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
|
||||||
|
|
||||||
/* Output any debug messages BEFORE restoring errno (because they may
|
/* Output any debug messages BEFORE restoring errno (because they may
|
||||||
* alter errno), then disable interrupts again and restore the original
|
* alter errno), then disable interrupts again and restore the original
|
||||||
@@ -121,7 +112,7 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
sinfo("Resuming\n");
|
sinfo("Resuming\n");
|
||||||
(void)up_irq_save();
|
(void)up_irq_save();
|
||||||
rtcb->pterrno = saved_errno;
|
rtcb->pterrno = saved_errno;
|
||||||
|
|
||||||
/* Modify the saved return state with the actual saved values in the
|
/* Modify the saved return state with the actual saved values in the
|
||||||
* TCB. This depends on the fact that nested signal handling is
|
* TCB. This depends on the fact that nested signal handling is
|
||||||
@@ -133,8 +124,9 @@ void up_sigdeliver(void)
|
|||||||
* could be modified by a hostile program.
|
* could be modified by a hostile program.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
regs[REG_PC] = rtcb->xcp.saved_pc;
|
regs[REG_PC] = rtcb->xcp.saved_pc;
|
||||||
regs[REG_SR] = rtcb->xcp.saved_sr;
|
regs[REG_SR] = rtcb->xcp.saved_sr;
|
||||||
|
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
|
||||||
|
|
||||||
/* Then restore the correct state for this thread of execution. This is an
|
/* Then restore the correct state for this thread of execution. This is an
|
||||||
* unusual case that must be handled by up_fullcontextresore. This case is
|
* unusual case that must be handled by up_fullcontextresore. This case is
|
||||||
|
|||||||
@@ -73,7 +73,6 @@ void up_sigdeliver(void)
|
|||||||
{
|
{
|
||||||
struct tcb_s *rtcb = this_task();
|
struct tcb_s *rtcb = this_task();
|
||||||
uint32_t regs[XCPTCONTEXT_REGS];
|
uint32_t regs[XCPTCONTEXT_REGS];
|
||||||
sig_deliver_t sigdeliver;
|
|
||||||
|
|
||||||
/* Save the errno. This must be preserved throughout the signal handling
|
/* Save the errno. This must be preserved throughout the signal handling
|
||||||
* so that the user code final gets the correct errno value (probably
|
* so that the user code final gets the correct errno value (probably
|
||||||
@@ -92,14 +91,6 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
up_copystate(regs, rtcb->xcp.regs);
|
up_copystate(regs, rtcb->xcp.regs);
|
||||||
|
|
||||||
/* Get a local copy of the sigdeliver function pointer. We do this so that
|
|
||||||
* we can nullify the sigdeliver function pointer in the TCB and accept
|
|
||||||
* more signal deliveries while processing the current pending signals.
|
|
||||||
*/
|
|
||||||
|
|
||||||
sigdeliver = rtcb->xcp.sigdeliver;
|
|
||||||
rtcb->xcp.sigdeliver = NULL;
|
|
||||||
|
|
||||||
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
||||||
/* Then make sure that interrupts are enabled. Signal handlers must always
|
/* Then make sure that interrupts are enabled. Signal handlers must always
|
||||||
* run with interrupts enabled.
|
* run with interrupts enabled.
|
||||||
@@ -108,9 +99,9 @@ void up_sigdeliver(void)
|
|||||||
up_irq_enable();
|
up_irq_enable();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Deliver the signals */
|
/* Deliver the signal */
|
||||||
|
|
||||||
sigdeliver(rtcb);
|
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
|
||||||
|
|
||||||
/* Output any debug messages BEFORE restoring errno (because they may
|
/* Output any debug messages BEFORE restoring errno (because they may
|
||||||
* alter errno), then disable interrupts again and restore the original
|
* alter errno), then disable interrupts again and restore the original
|
||||||
@@ -120,7 +111,7 @@ void up_sigdeliver(void)
|
|||||||
sinfo("Resuming EPC: %08x STATUS: %08x\n", regs[REG_EPC], regs[REG_STATUS]);
|
sinfo("Resuming EPC: %08x STATUS: %08x\n", regs[REG_EPC], regs[REG_STATUS]);
|
||||||
|
|
||||||
(void)up_irq_save();
|
(void)up_irq_save();
|
||||||
rtcb->pterrno = saved_errno;
|
rtcb->pterrno = saved_errno;
|
||||||
|
|
||||||
/* Modify the saved return state with the actual saved values in the
|
/* Modify the saved return state with the actual saved values in the
|
||||||
* TCB. This depends on the fact that nested signal handling is
|
* TCB. This depends on the fact that nested signal handling is
|
||||||
@@ -132,8 +123,9 @@ void up_sigdeliver(void)
|
|||||||
* could be modified by a hostile program.
|
* could be modified by a hostile program.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
regs[REG_EPC] = rtcb->xcp.saved_epc;
|
regs[REG_EPC] = rtcb->xcp.saved_epc;
|
||||||
regs[REG_STATUS] = rtcb->xcp.saved_status;
|
regs[REG_STATUS] = rtcb->xcp.saved_status;
|
||||||
|
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
|
||||||
|
|
||||||
/* Then restore the correct state for this thread of
|
/* Then restore the correct state for this thread of
|
||||||
* execution.
|
* execution.
|
||||||
|
|||||||
@@ -72,7 +72,6 @@ void lm32_sigdeliver(void)
|
|||||||
{
|
{
|
||||||
struct tcb_s *rtcb = this_task();
|
struct tcb_s *rtcb = this_task();
|
||||||
uint32_t regs[XCPTCONTEXT_REGS];
|
uint32_t regs[XCPTCONTEXT_REGS];
|
||||||
sig_deliver_t sigdeliver;
|
|
||||||
|
|
||||||
/* Save the errno. This must be preserved throughout the signal handling
|
/* Save the errno. This must be preserved throughout the signal handling
|
||||||
* so that the user code final gets the correct errno value (probably
|
* so that the user code final gets the correct errno value (probably
|
||||||
@@ -91,14 +90,6 @@ void lm32_sigdeliver(void)
|
|||||||
|
|
||||||
up_copystate(regs, rtcb->xcp.regs);
|
up_copystate(regs, rtcb->xcp.regs);
|
||||||
|
|
||||||
/* Get a local copy of the sigdeliver function pointer. We do this so that
|
|
||||||
* we can nullify the sigdeliver function pointer in the TCB and accept
|
|
||||||
* more signal deliveries while processing the current pending signals.
|
|
||||||
*/
|
|
||||||
|
|
||||||
sigdeliver = rtcb->xcp.sigdeliver;
|
|
||||||
rtcb->xcp.sigdeliver = NULL;
|
|
||||||
|
|
||||||
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
||||||
/* Then make sure that interrupts are enabled. Signal handlers must always
|
/* Then make sure that interrupts are enabled. Signal handlers must always
|
||||||
* run with interrupts enabled.
|
* run with interrupts enabled.
|
||||||
@@ -107,9 +98,9 @@ void lm32_sigdeliver(void)
|
|||||||
up_irq_enable();
|
up_irq_enable();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Deliver the signals */
|
/* Deliver the signal */
|
||||||
|
|
||||||
sigdeliver(rtcb);
|
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
|
||||||
|
|
||||||
/* Output any debug messages BEFORE restoring errno (because they may
|
/* Output any debug messages BEFORE restoring errno (because they may
|
||||||
* alter errno), then disable interrupts again and restore the original
|
* alter errno), then disable interrupts again and restore the original
|
||||||
@@ -119,7 +110,7 @@ void lm32_sigdeliver(void)
|
|||||||
sinfo("Resuming EPC: %08x INT_CTX: %08x\n", regs[REG_EPC], regs[REG_INT_CTX]);
|
sinfo("Resuming EPC: %08x INT_CTX: %08x\n", regs[REG_EPC], regs[REG_INT_CTX]);
|
||||||
|
|
||||||
(void)up_irq_save();
|
(void)up_irq_save();
|
||||||
rtcb->pterrno = saved_errno;
|
rtcb->pterrno = saved_errno;
|
||||||
|
|
||||||
/* Modify the saved return state with the actual saved values in the
|
/* Modify the saved return state with the actual saved values in the
|
||||||
* TCB. This depends on the fact that nested signal handling is
|
* TCB. This depends on the fact that nested signal handling is
|
||||||
@@ -131,8 +122,9 @@ void lm32_sigdeliver(void)
|
|||||||
* could be modified by a hostile program.
|
* could be modified by a hostile program.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
regs[REG_EPC] = rtcb->xcp.saved_epc;
|
regs[REG_EPC] = rtcb->xcp.saved_epc;
|
||||||
regs[REG_INT_CTX] = rtcb->xcp.saved_int_ctx;
|
regs[REG_INT_CTX] = rtcb->xcp.saved_int_ctx;
|
||||||
|
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
|
||||||
|
|
||||||
/* Then restore the correct state for this thread of
|
/* Then restore the correct state for this thread of
|
||||||
* execution.
|
* execution.
|
||||||
|
|||||||
@@ -73,7 +73,6 @@ void up_sigdeliver(void)
|
|||||||
#ifndef CONFIG_DISABLE_SIGNALS
|
#ifndef CONFIG_DISABLE_SIGNALS
|
||||||
struct tcb_s *rtcb = this_task();
|
struct tcb_s *rtcb = this_task();
|
||||||
uint8_t regs[XCPTCONTEXT_SIZE];
|
uint8_t regs[XCPTCONTEXT_SIZE];
|
||||||
sig_deliver_t sigdeliver;
|
|
||||||
|
|
||||||
/* Save the errno. This must be preserved throughout the signal handling
|
/* Save the errno. This must be preserved throughout the signal handling
|
||||||
* so that the user code final gets the correct errno value (probably
|
* so that the user code final gets the correct errno value (probably
|
||||||
@@ -92,15 +91,6 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
up_copystate(regs, rtcb->xcp.regs);
|
up_copystate(regs, rtcb->xcp.regs);
|
||||||
|
|
||||||
/* Get a local copy of the sigdeliver function pointer. We do this so
|
|
||||||
* that we can nullify the sigdeliver function pointer in the TCB and
|
|
||||||
* accept more signal deliveries while processing the current pending
|
|
||||||
* signals.
|
|
||||||
*/
|
|
||||||
|
|
||||||
sigdeliver = rtcb->xcp.sigdeliver;
|
|
||||||
rtcb->xcp.sigdeliver = NULL;
|
|
||||||
|
|
||||||
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
||||||
/* Then make sure that interrupts are enabled. Signal handlers must always
|
/* Then make sure that interrupts are enabled. Signal handlers must always
|
||||||
* run with interrupts enabled.
|
* run with interrupts enabled.
|
||||||
@@ -109,9 +99,9 @@ void up_sigdeliver(void)
|
|||||||
up_irq_enable();
|
up_irq_enable();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Deliver the signals */
|
/* Deliver the signal */
|
||||||
|
|
||||||
sigdeliver(rtcb);
|
((sig_deliver_t)sig_rtcb->xcp.sigdeliver)(rtcb);
|
||||||
|
|
||||||
/* Output any debug messages BEFORE restoring errno (because they may
|
/* Output any debug messages BEFORE restoring errno (because they may
|
||||||
* alter errno), then disable interrupts again and restore the original
|
* alter errno), then disable interrupts again and restore the original
|
||||||
@@ -120,7 +110,7 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
sinfo("Resuming\n");
|
sinfo("Resuming\n");
|
||||||
(void)up_irq_save();
|
(void)up_irq_save();
|
||||||
rtcb->pterrno = saved_errno;
|
rtcb->pterrno = saved_errno;
|
||||||
|
|
||||||
/* Modify the saved return state with the actual saved values in the
|
/* Modify the saved return state with the actual saved values in the
|
||||||
* TCB. This depends on the fact that nested signal handling is
|
* TCB. This depends on the fact that nested signal handling is
|
||||||
@@ -132,9 +122,10 @@ void up_sigdeliver(void)
|
|||||||
* could be modified by a hostile program.
|
* could be modified by a hostile program.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
regs[REG_PC] = rtcb->xcp.saved_pc[0];
|
regs[REG_PC] = rtcb->xcp.saved_pc[0];
|
||||||
regs[REG_PC+1] = rtcb->xcp.saved_pc[1];
|
regs[REG_PC + 1] = rtcb->xcp.saved_pc[1];
|
||||||
regs[REG_FLG] = rtcb->xcp.saved_flg;
|
regs[REG_FLG] = rtcb->xcp.saved_flg;
|
||||||
|
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
|
||||||
|
|
||||||
/* Then restore the correct state for this thread of
|
/* Then restore the correct state for this thread of
|
||||||
* execution.
|
* execution.
|
||||||
|
|||||||
@@ -73,7 +73,6 @@ void up_sigdeliver(void)
|
|||||||
#ifndef CONFIG_DISABLE_SIGNALS
|
#ifndef CONFIG_DISABLE_SIGNALS
|
||||||
struct tcb_s *rtcb = this_task();
|
struct tcb_s *rtcb = this_task();
|
||||||
uint32_t regs[XCPTCONTEXT_REGS];
|
uint32_t regs[XCPTCONTEXT_REGS];
|
||||||
sig_deliver_t sigdeliver;
|
|
||||||
|
|
||||||
/* Save the errno. This must be preserved throughout the signal handling
|
/* Save the errno. This must be preserved throughout the signal handling
|
||||||
* so that the user code final gets the correct errno value (probably
|
* so that the user code final gets the correct errno value (probably
|
||||||
@@ -92,15 +91,6 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
up_copystate(regs, rtcb->xcp.regs);
|
up_copystate(regs, rtcb->xcp.regs);
|
||||||
|
|
||||||
/* Get a local copy of the sigdeliver function pointer. We do this so
|
|
||||||
* that we can nullify the sigdeliver function pointer in the TCB and
|
|
||||||
* accept more signal deliveries while processing the current pending
|
|
||||||
* signals.
|
|
||||||
*/
|
|
||||||
|
|
||||||
sigdeliver = rtcb->xcp.sigdeliver;
|
|
||||||
rtcb->xcp.sigdeliver = NULL;
|
|
||||||
|
|
||||||
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
||||||
/* Then make sure that interrupts are enabled. Signal handlers must always
|
/* Then make sure that interrupts are enabled. Signal handlers must always
|
||||||
* run with interrupts enabled.
|
* run with interrupts enabled.
|
||||||
@@ -109,9 +99,9 @@ void up_sigdeliver(void)
|
|||||||
up_irq_enable();
|
up_irq_enable();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Deliver the signals */
|
/* Deliver the signal */
|
||||||
|
|
||||||
sigdeliver(rtcb);
|
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
|
||||||
|
|
||||||
/* Output any debug messages BEFORE restoring errno (because they may
|
/* Output any debug messages BEFORE restoring errno (because they may
|
||||||
* alter errno), then disable interrupts again and restore the original
|
* alter errno), then disable interrupts again and restore the original
|
||||||
@@ -120,7 +110,7 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
sinfo("Resuming\n");
|
sinfo("Resuming\n");
|
||||||
(void)up_irq_save();
|
(void)up_irq_save();
|
||||||
rtcb->pterrno = saved_errno;
|
rtcb->pterrno = saved_errno;
|
||||||
|
|
||||||
/* Modify the saved return state with the actual saved values in the
|
/* Modify the saved return state with the actual saved values in the
|
||||||
* TCB. This depends on the fact that nested signal handling is
|
* TCB. This depends on the fact that nested signal handling is
|
||||||
@@ -132,8 +122,9 @@ void up_sigdeliver(void)
|
|||||||
* could be modified by a hostile program.
|
* could be modified by a hostile program.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
regs[REG_PC] = rtcb->xcp.saved_pc;
|
regs[REG_PC] = rtcb->xcp.saved_pc;
|
||||||
regs[REG_SR] = rtcb->xcp.saved_sr;
|
regs[REG_SR] = rtcb->xcp.saved_sr;
|
||||||
|
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
|
||||||
|
|
||||||
/* Then restore the correct state for this thread of execution. */
|
/* Then restore the correct state for this thread of execution. */
|
||||||
|
|
||||||
|
|||||||
@@ -78,7 +78,6 @@ void up_sigdeliver(void)
|
|||||||
{
|
{
|
||||||
struct tcb_s *rtcb = this_task();
|
struct tcb_s *rtcb = this_task();
|
||||||
uint32_t regs[XCPTCONTEXT_REGS];
|
uint32_t regs[XCPTCONTEXT_REGS];
|
||||||
sig_deliver_t sigdeliver;
|
|
||||||
|
|
||||||
/* Save the errno. This must be preserved throughout the signal handling
|
/* Save the errno. This must be preserved throughout the signal handling
|
||||||
* so that the user code final gets the correct errno value (probably
|
* so that the user code final gets the correct errno value (probably
|
||||||
@@ -97,14 +96,6 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
up_copystate(regs, rtcb->xcp.regs);
|
up_copystate(regs, rtcb->xcp.regs);
|
||||||
|
|
||||||
/* Get a local copy of the sigdeliver function pointer. We do this so that
|
|
||||||
* we can nullify the sigdeliver function pointer in the TCB and accept
|
|
||||||
* more signal deliveries while processing the current pending signals.
|
|
||||||
*/
|
|
||||||
|
|
||||||
sigdeliver = rtcb->xcp.sigdeliver;
|
|
||||||
rtcb->xcp.sigdeliver = NULL;
|
|
||||||
|
|
||||||
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
||||||
/* Then make sure that interrupts are enabled. Signal handlers must always
|
/* Then make sure that interrupts are enabled. Signal handlers must always
|
||||||
* run with interrupts enabled.
|
* run with interrupts enabled.
|
||||||
@@ -115,7 +106,7 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
/* Deliver the signals */
|
/* Deliver the signals */
|
||||||
|
|
||||||
sigdeliver(rtcb);
|
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
|
||||||
|
|
||||||
/* Output any debug messages BEFORE restoring errno (because they may
|
/* Output any debug messages BEFORE restoring errno (because they may
|
||||||
* alter errno), then disable interrupts again and restore the original
|
* alter errno), then disable interrupts again and restore the original
|
||||||
@@ -125,7 +116,7 @@ void up_sigdeliver(void)
|
|||||||
sinfo("Resuming EPC: %08x INT_CTX: %08x\n", regs[REG_EPC], regs[REG_INT_CTX]);
|
sinfo("Resuming EPC: %08x INT_CTX: %08x\n", regs[REG_EPC], regs[REG_INT_CTX]);
|
||||||
|
|
||||||
(void)up_irq_save();
|
(void)up_irq_save();
|
||||||
rtcb->pterrno = saved_errno;
|
rtcb->pterrno = saved_errno;
|
||||||
|
|
||||||
/* Modify the saved return state with the actual saved values in the
|
/* Modify the saved return state with the actual saved values in the
|
||||||
* TCB. This depends on the fact that nested signal handling is
|
* TCB. This depends on the fact that nested signal handling is
|
||||||
@@ -137,8 +128,9 @@ void up_sigdeliver(void)
|
|||||||
* could be modified by a hostile program.
|
* could be modified by a hostile program.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
regs[REG_EPC] = rtcb->xcp.saved_epc;
|
regs[REG_EPC] = rtcb->xcp.saved_epc;
|
||||||
regs[REG_INT_CTX] = rtcb->xcp.saved_int_ctx;
|
regs[REG_INT_CTX] = rtcb->xcp.saved_int_ctx;
|
||||||
|
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
|
||||||
|
|
||||||
/* Then restore the correct state for this thread of
|
/* Then restore the correct state for this thread of
|
||||||
* execution.
|
* execution.
|
||||||
|
|||||||
@@ -72,7 +72,6 @@ void up_sigdeliver(void)
|
|||||||
{
|
{
|
||||||
struct tcb_s *rtcb = this_task();
|
struct tcb_s *rtcb = this_task();
|
||||||
uint32_t regs[XCPTCONTEXT_REGS];
|
uint32_t regs[XCPTCONTEXT_REGS];
|
||||||
sig_deliver_t sigdeliver;
|
|
||||||
|
|
||||||
/* Save the errno. This must be preserved throughout the signal handling
|
/* Save the errno. This must be preserved throughout the signal handling
|
||||||
* so that the user code final gets the correct errno value (probably
|
* so that the user code final gets the correct errno value (probably
|
||||||
@@ -91,14 +90,6 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
up_copystate(regs, rtcb->xcp.regs);
|
up_copystate(regs, rtcb->xcp.regs);
|
||||||
|
|
||||||
/* Get a local copy of the sigdeliver function pointer. we do this so that
|
|
||||||
* we can nullify the sigdeliver function pointer in the TCB and accept
|
|
||||||
* more signal deliveries while processing the current pending signals.
|
|
||||||
*/
|
|
||||||
|
|
||||||
sigdeliver = rtcb->xcp.sigdeliver;
|
|
||||||
rtcb->xcp.sigdeliver = NULL;
|
|
||||||
|
|
||||||
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
||||||
/* Then make sure that interrupts are enabled. Signal handlers must always
|
/* Then make sure that interrupts are enabled. Signal handlers must always
|
||||||
* run with interrupts enabled.
|
* run with interrupts enabled.
|
||||||
@@ -109,7 +100,7 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
/* Deliver the signals */
|
/* Deliver the signals */
|
||||||
|
|
||||||
sigdeliver(rtcb);
|
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
|
||||||
|
|
||||||
/* Output any debug messages BEFORE restoring errno (because they may
|
/* Output any debug messages BEFORE restoring errno (because they may
|
||||||
* alter errno), then disable interrupts again and restore the original
|
* alter errno), then disable interrupts again and restore the original
|
||||||
@@ -118,7 +109,7 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
sinfo("Resuming\n");
|
sinfo("Resuming\n");
|
||||||
(void)up_irq_save();
|
(void)up_irq_save();
|
||||||
rtcb->pterrno = saved_errno;
|
rtcb->pterrno = saved_errno;
|
||||||
|
|
||||||
/* Modify the saved return state with the actual saved values in the
|
/* Modify the saved return state with the actual saved values in the
|
||||||
* TCB. This depends on the fact that nested signal handling is
|
* TCB. This depends on the fact that nested signal handling is
|
||||||
@@ -130,8 +121,9 @@ void up_sigdeliver(void)
|
|||||||
* could be modified by a hostile program.
|
* could be modified by a hostile program.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
regs[REG_EIP] = rtcb->xcp.saved_eip;
|
regs[REG_EIP] = rtcb->xcp.saved_eip;
|
||||||
regs[REG_EFLAGS] = rtcb->xcp.saved_eflags;
|
regs[REG_EFLAGS] = rtcb->xcp.saved_eflags;
|
||||||
|
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
|
||||||
|
|
||||||
/* Then restore the correct state for this thread of execution. */
|
/* Then restore the correct state for this thread of execution. */
|
||||||
|
|
||||||
|
|||||||
@@ -69,9 +69,8 @@
|
|||||||
|
|
||||||
void xtensa_sig_deliver(void)
|
void xtensa_sig_deliver(void)
|
||||||
{
|
{
|
||||||
struct tcb_s *rtcb = this_task();
|
struct tcb_s *rtcb = this_task();
|
||||||
uint32_t regs[XCPTCONTEXT_REGS];
|
uint32_t regs[XCPTCONTEXT_REGS];
|
||||||
sig_deliver_t sigdeliver;
|
|
||||||
|
|
||||||
/* Save the errno. This must be preserved throughout the signal handling
|
/* Save the errno. This must be preserved throughout the signal handling
|
||||||
* so that the user code final gets the correct errno value (probably
|
* so that the user code final gets the correct errno value (probably
|
||||||
@@ -99,14 +98,6 @@ void xtensa_sig_deliver(void)
|
|||||||
|
|
||||||
xtensa_copystate(regs, rtcb->xcp.regs);
|
xtensa_copystate(regs, rtcb->xcp.regs);
|
||||||
|
|
||||||
/* Get a local copy of the sigdeliver function pointer. we do this so that
|
|
||||||
* we can nullify the sigdeliver function pointer in the TCB and accept
|
|
||||||
* more signal deliveries while processing the current pending signals.
|
|
||||||
*/
|
|
||||||
|
|
||||||
sigdeliver = rtcb->xcp.sigdeliver;
|
|
||||||
rtcb->xcp.sigdeliver = NULL;
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
/* In the SMP case, up_schedule_sigaction(0) will have incremented
|
/* In the SMP case, up_schedule_sigaction(0) will have incremented
|
||||||
* 'irqcount' in order to force us into a critical section. Save the
|
* 'irqcount' in order to force us into a critical section. Save the
|
||||||
@@ -137,7 +128,7 @@ void xtensa_sig_deliver(void)
|
|||||||
|
|
||||||
/* Deliver the signals */
|
/* Deliver the signals */
|
||||||
|
|
||||||
sigdeliver(rtcb);
|
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
|
||||||
|
|
||||||
/* Output any debug messages BEFORE restoring errno (because they may
|
/* Output any debug messages BEFORE restoring errno (because they may
|
||||||
* alter errno), then disable interrupts again and restore the original
|
* alter errno), then disable interrupts again and restore the original
|
||||||
@@ -149,7 +140,7 @@ void xtensa_sig_deliver(void)
|
|||||||
|
|
||||||
/* Restore the saved errno value */
|
/* Restore the saved errno value */
|
||||||
|
|
||||||
rtcb->pterrno = saved_errno;
|
rtcb->pterrno = saved_errno;
|
||||||
|
|
||||||
/* Modify the saved return state with the actual saved values in the
|
/* Modify the saved return state with the actual saved values in the
|
||||||
* TCB. This depends on the fact that nested signal handling is
|
* TCB. This depends on the fact that nested signal handling is
|
||||||
@@ -161,8 +152,9 @@ void xtensa_sig_deliver(void)
|
|||||||
* could be modified by a hostile program.
|
* could be modified by a hostile program.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
regs[REG_PC] = rtcb->xcp.saved_pc;
|
regs[REG_PC] = rtcb->xcp.saved_pc;
|
||||||
regs[REG_PS] = rtcb->xcp.saved_ps;
|
regs[REG_PS] = rtcb->xcp.saved_ps;
|
||||||
|
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
/* Restore the saved 'irqcount' and recover the critical section
|
/* Restore the saved 'irqcount' and recover the critical section
|
||||||
|
|||||||
@@ -74,7 +74,6 @@ void up_sigdeliver(void)
|
|||||||
FAR struct tcb_s *rtcb = this_task();
|
FAR struct tcb_s *rtcb = this_task();
|
||||||
chipreg_t regs[XCPTCONTEXT_REGS];
|
chipreg_t regs[XCPTCONTEXT_REGS];
|
||||||
FAR uint32_t *regs32 = (FAR uint32_t*)regs;
|
FAR uint32_t *regs32 = (FAR uint32_t*)regs;
|
||||||
sig_deliver_t sigdeliver;
|
|
||||||
|
|
||||||
/* Save the errno. This must be preserved throughout the signal handling
|
/* Save the errno. This must be preserved throughout the signal handling
|
||||||
* so that the user code final gets the correct errno value (probably
|
* so that the user code final gets the correct errno value (probably
|
||||||
@@ -93,15 +92,6 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
up_copystate(regs, rtcb->xcp.regs);
|
up_copystate(regs, rtcb->xcp.regs);
|
||||||
|
|
||||||
/* Get a local copy of the sigdeliver function pointer. We do this so
|
|
||||||
* that we can nullify the sigdeliver function point in the TCB and
|
|
||||||
* accept more signal deliveries while processing the current pending
|
|
||||||
* signals.
|
|
||||||
*/
|
|
||||||
|
|
||||||
sigdeliver = (sig_deliver_t)rtcb->xcp.sigdeliver;
|
|
||||||
rtcb->xcp.sigdeliver = NULL;
|
|
||||||
|
|
||||||
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
||||||
/* Then make sure that interrupts are enabled. Signal handlers must always
|
/* Then make sure that interrupts are enabled. Signal handlers must always
|
||||||
* run with interrupts enabled.
|
* run with interrupts enabled.
|
||||||
@@ -112,7 +102,7 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
/* Deliver the signals */
|
/* Deliver the signals */
|
||||||
|
|
||||||
sigdeliver(rtcb);
|
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
|
||||||
|
|
||||||
/* Output any debug messages BEFORE restoring errno (because they may
|
/* Output any debug messages BEFORE restoring errno (because they may
|
||||||
* alter errno), then disable interrupts again and restore the original
|
* alter errno), then disable interrupts again and restore the original
|
||||||
@@ -121,7 +111,7 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
sinfo("Resuming\n");
|
sinfo("Resuming\n");
|
||||||
(void)up_irq_save();
|
(void)up_irq_save();
|
||||||
rtcb->pterrno = saved_errno;
|
rtcb->pterrno = saved_errno;
|
||||||
|
|
||||||
/* Modify the saved return state with the actual saved values in the
|
/* Modify the saved return state with the actual saved values in the
|
||||||
* TCB. This depends on the fact that nested signal handling is
|
* TCB. This depends on the fact that nested signal handling is
|
||||||
@@ -133,8 +123,9 @@ void up_sigdeliver(void)
|
|||||||
* could be modified by a hostile program.
|
* could be modified by a hostile program.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
regs32[REG_PC / 2] = rtcb->xcp.saved_pc;
|
regs32[REG_PC / 2] = rtcb->xcp.saved_pc;
|
||||||
regs[REG_FLAGS] = rtcb->xcp.saved_i;
|
regs[REG_FLAGS] = rtcb->xcp.saved_i;
|
||||||
|
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
|
||||||
|
|
||||||
/* Then restore the correct state for this thread of execution. */
|
/* Then restore the correct state for this thread of execution. */
|
||||||
|
|
||||||
|
|||||||
@@ -73,7 +73,6 @@ void up_sigdeliver(void)
|
|||||||
#ifndef CONFIG_DISABLE_SIGNALS
|
#ifndef CONFIG_DISABLE_SIGNALS
|
||||||
FAR struct tcb_s *rtcb = this_task();
|
FAR struct tcb_s *rtcb = this_task();
|
||||||
chipreg_t regs[XCPTCONTEXT_REGS];
|
chipreg_t regs[XCPTCONTEXT_REGS];
|
||||||
sig_deliver_t sigdeliver;
|
|
||||||
|
|
||||||
/* Save the errno. This must be preserved throughout the signal handling
|
/* Save the errno. This must be preserved throughout the signal handling
|
||||||
* so that the user code final gets the correct errno value (probably
|
* so that the user code final gets the correct errno value (probably
|
||||||
@@ -92,15 +91,6 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
ez80_copystate(regs, rtcb->xcp.regs);
|
ez80_copystate(regs, rtcb->xcp.regs);
|
||||||
|
|
||||||
/* Get a local copy of the sigdeliver function pointer. We do this so
|
|
||||||
* that we can nullify the sigdeliver function pointer in the TCB and
|
|
||||||
* accept more signal deliveries while processing the current pending
|
|
||||||
* signals.
|
|
||||||
*/
|
|
||||||
|
|
||||||
sigdeliver = rtcb->xcp.sigdeliver;
|
|
||||||
rtcb->xcp.sigdeliver = NULL;
|
|
||||||
|
|
||||||
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
||||||
/* Then make sure that interrupts are enabled. Signal handlers must always
|
/* Then make sure that interrupts are enabled. Signal handlers must always
|
||||||
* run with interrupts enabled.
|
* run with interrupts enabled.
|
||||||
@@ -111,7 +101,7 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
/* Deliver the signals */
|
/* Deliver the signals */
|
||||||
|
|
||||||
sigdeliver(rtcb);
|
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
|
||||||
|
|
||||||
/* Output any debug messages BEFORE restoring errno (because they may
|
/* Output any debug messages BEFORE restoring errno (because they may
|
||||||
* alter errno), then disable interrupts again and restore the original
|
* alter errno), then disable interrupts again and restore the original
|
||||||
@@ -120,10 +110,21 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
sinfo("Resuming\n");
|
sinfo("Resuming\n");
|
||||||
(void)up_irq_save();
|
(void)up_irq_save();
|
||||||
rtcb->pterrno = saved_errno;
|
rtcb->pterrno = saved_errno;
|
||||||
|
|
||||||
regs[XCPT_PC] = rtcb->xcp.saved_pc;
|
/* Modify the saved return state with the actual saved values in the
|
||||||
regs[XCPT_I] = rtcb->xcp.saved_i;
|
* TCB. This depends on the fact that nested signal handling is
|
||||||
|
* not supported. Therefore, these values will persist throughout the
|
||||||
|
* signal handling action.
|
||||||
|
*
|
||||||
|
* Keeping this data in the TCB resolves a security problem in protected
|
||||||
|
* and kernel mode: The regs[] array is visible on the user stack and
|
||||||
|
* could be modified by a hostile program.
|
||||||
|
*/
|
||||||
|
|
||||||
|
regs[XCPT_PC] = rtcb->xcp.saved_pc;
|
||||||
|
regs[XCPT_I] = rtcb->xcp.saved_i;
|
||||||
|
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
|
||||||
|
|
||||||
/* Modify the saved return state with the actual saved values in the
|
/* Modify the saved return state with the actual saved values in the
|
||||||
* TCB. This depends on the fact that nested signal handling is
|
* TCB. This depends on the fact that nested signal handling is
|
||||||
|
|||||||
@@ -71,7 +71,6 @@ void up_sigdeliver(void)
|
|||||||
#ifndef CONFIG_DISABLE_SIGNALS
|
#ifndef CONFIG_DISABLE_SIGNALS
|
||||||
FAR struct tcb_s *rtcb = this_task();
|
FAR struct tcb_s *rtcb = this_task();
|
||||||
chipreg_t regs[XCPTCONTEXT_REGS];
|
chipreg_t regs[XCPTCONTEXT_REGS];
|
||||||
sig_deliver_t sigdeliver;
|
|
||||||
|
|
||||||
/* Save the errno. This must be preserved throughout the signal handling
|
/* Save the errno. This must be preserved throughout the signal handling
|
||||||
* so that the user code final gets the correct errno value (probably
|
* so that the user code final gets the correct errno value (probably
|
||||||
@@ -90,15 +89,6 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
z180_copystate(regs, rtcb->xcp.regs);
|
z180_copystate(regs, rtcb->xcp.regs);
|
||||||
|
|
||||||
/* Get a local copy of the sigdeliver function pointer. We do this so
|
|
||||||
* that we can nullify the sigdeliver function pointer in the TCB and
|
|
||||||
* accept more signal deliveries while processing the current pending
|
|
||||||
* signals.
|
|
||||||
*/
|
|
||||||
|
|
||||||
sigdeliver = rtcb->xcp.sigdeliver;
|
|
||||||
rtcb->xcp.sigdeliver = NULL;
|
|
||||||
|
|
||||||
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
||||||
/* Then make sure that interrupts are enabled. Signal handlers must always
|
/* Then make sure that interrupts are enabled. Signal handlers must always
|
||||||
* run with interrupts enabled.
|
* run with interrupts enabled.
|
||||||
@@ -109,7 +99,7 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
/* Deliver the signals */
|
/* Deliver the signals */
|
||||||
|
|
||||||
sigdeliver(rtcb);
|
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
|
||||||
|
|
||||||
/* Output any debug messages BEFORE restoring errno (because they may
|
/* Output any debug messages BEFORE restoring errno (because they may
|
||||||
* alter errno), then disable interrupts again and restore the original
|
* alter errno), then disable interrupts again and restore the original
|
||||||
@@ -118,7 +108,7 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
sinfo("Resuming\n");
|
sinfo("Resuming\n");
|
||||||
(void)up_irq_save();
|
(void)up_irq_save();
|
||||||
rtcb->pterrno = saved_errno;
|
rtcb->pterrno = saved_errno;
|
||||||
|
|
||||||
/* Modify the saved return state with the actual saved values in the
|
/* Modify the saved return state with the actual saved values in the
|
||||||
* TCB. This depends on the fact that nested signal handling is
|
* TCB. This depends on the fact that nested signal handling is
|
||||||
@@ -130,8 +120,9 @@ void up_sigdeliver(void)
|
|||||||
* could be modified by a hostile program.
|
* could be modified by a hostile program.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
regs[XCPT_PC] = rtcb->xcp.saved_pc;
|
regs[XCPT_PC] = rtcb->xcp.saved_pc;
|
||||||
regs[XCPT_I] = rtcb->xcp.saved_i;
|
regs[XCPT_I] = rtcb->xcp.saved_i;
|
||||||
|
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
|
||||||
|
|
||||||
/* Then restore the correct state for this thread of execution. */
|
/* Then restore the correct state for this thread of execution. */
|
||||||
|
|
||||||
|
|||||||
@@ -91,7 +91,6 @@ void up_sigdeliver(void)
|
|||||||
#ifndef CONFIG_DISABLE_SIGNALS
|
#ifndef CONFIG_DISABLE_SIGNALS
|
||||||
FAR struct tcb_s *rtcb = this_task();
|
FAR struct tcb_s *rtcb = this_task();
|
||||||
chipreg_t regs[XCPTCONTEXT_REGS];
|
chipreg_t regs[XCPTCONTEXT_REGS];
|
||||||
sig_deliver_t sigdeliver;
|
|
||||||
|
|
||||||
/* Save the errno. This must be preserved throughout the signal handling
|
/* Save the errno. This must be preserved throughout the signal handling
|
||||||
* so that the user code final gets the correct errno value (probably
|
* so that the user code final gets the correct errno value (probably
|
||||||
@@ -110,15 +109,6 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
z8_copystate(regs, rtcb->xcp.regs);
|
z8_copystate(regs, rtcb->xcp.regs);
|
||||||
|
|
||||||
/* Get a local copy of the sigdeliver function pointer. We do this so
|
|
||||||
* that we can nullify the sigdeliver function pointer in the TCB and
|
|
||||||
* accept more signal deliveries while processing the current pending
|
|
||||||
* signals.
|
|
||||||
*/
|
|
||||||
|
|
||||||
sigdeliver = rtcb->xcp.sigdeliver;
|
|
||||||
rtcb->xcp.sigdeliver = NULL;
|
|
||||||
|
|
||||||
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
||||||
/* Then make sure that interrupts are enabled. Signal handlers must always
|
/* Then make sure that interrupts are enabled. Signal handlers must always
|
||||||
* run with interrupts enabled.
|
* run with interrupts enabled.
|
||||||
@@ -129,7 +119,7 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
/* Deliver the signals */
|
/* Deliver the signals */
|
||||||
|
|
||||||
sigdeliver(rtcb);
|
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
|
||||||
|
|
||||||
/* Output any debug messages BEFORE restoring errno (because they may
|
/* Output any debug messages BEFORE restoring errno (because they may
|
||||||
* alter errno), then disable interrupts again and restore the original
|
* alter errno), then disable interrupts again and restore the original
|
||||||
@@ -138,7 +128,7 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
sinfo("Resuming\n");
|
sinfo("Resuming\n");
|
||||||
(void)up_irq_save();
|
(void)up_irq_save();
|
||||||
rtcb->pterrno = saved_errno;
|
rtcb->pterrno = saved_errno;
|
||||||
|
|
||||||
/* Modify the saved return state with the actual saved values in the
|
/* Modify the saved return state with the actual saved values in the
|
||||||
* TCB. This depends on the fact that nested signal handling is
|
* TCB. This depends on the fact that nested signal handling is
|
||||||
@@ -150,8 +140,9 @@ void up_sigdeliver(void)
|
|||||||
* could be modified by a hostile program.
|
* could be modified by a hostile program.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
regs[XCPT_PC] = rtcb->xcp.saved_pc;
|
regs[XCPT_PC] = rtcb->xcp.saved_pc;
|
||||||
regs[XCPT_IRQCTL] = rtcb->xcp.saved_irqctl;
|
regs[XCPT_IRQCTL] = rtcb->xcp.saved_irqctl;
|
||||||
|
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
|
||||||
|
|
||||||
/* Then restore the correct state for this thread of execution. */
|
/* Then restore the correct state for this thread of execution. */
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,6 @@ void up_sigdeliver(void)
|
|||||||
#ifndef CONFIG_DISABLE_SIGNALS
|
#ifndef CONFIG_DISABLE_SIGNALS
|
||||||
FAR struct tcb_s *rtcb = this_task();
|
FAR struct tcb_s *rtcb = this_task();
|
||||||
chipreg_t regs[XCPTCONTEXT_REGS];
|
chipreg_t regs[XCPTCONTEXT_REGS];
|
||||||
sig_deliver_t sigdeliver;
|
|
||||||
|
|
||||||
/* Save the errno. This must be preserved throughout the signal handling
|
/* Save the errno. This must be preserved throughout the signal handling
|
||||||
* so that the user code final gets the correct errno value (probably
|
* so that the user code final gets the correct errno value (probably
|
||||||
@@ -91,15 +90,6 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
z80_copystate(regs, rtcb->xcp.regs);
|
z80_copystate(regs, rtcb->xcp.regs);
|
||||||
|
|
||||||
/* Get a local copy of the sigdeliver function pointer. We do this so
|
|
||||||
* that we can nullify the sigdeliver function pointer in the TCB and
|
|
||||||
* accept more signal deliveries while processing the current pending
|
|
||||||
* signals.
|
|
||||||
*/
|
|
||||||
|
|
||||||
sigdeliver = rtcb->xcp.sigdeliver;
|
|
||||||
rtcb->xcp.sigdeliver = NULL;
|
|
||||||
|
|
||||||
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
||||||
/* Then make sure that interrupts are enabled. Signal handlers must always
|
/* Then make sure that interrupts are enabled. Signal handlers must always
|
||||||
* run with interrupts enabled.
|
* run with interrupts enabled.
|
||||||
@@ -110,7 +100,7 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
/* Deliver the signals */
|
/* Deliver the signals */
|
||||||
|
|
||||||
sigdeliver(rtcb);
|
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
|
||||||
|
|
||||||
/* Output any debug messages BEFORE restoring errno (because they may
|
/* Output any debug messages BEFORE restoring errno (because they may
|
||||||
* alter errno), then disable interrupts again and restore the original
|
* alter errno), then disable interrupts again and restore the original
|
||||||
@@ -119,7 +109,7 @@ void up_sigdeliver(void)
|
|||||||
|
|
||||||
sinfo("Resuming\n");
|
sinfo("Resuming\n");
|
||||||
(void)up_irq_save();
|
(void)up_irq_save();
|
||||||
rtcb->pterrno = saved_errno;
|
rtcb->pterrno = saved_errno;
|
||||||
|
|
||||||
/* Modify the saved return state with the actual saved values in the
|
/* Modify the saved return state with the actual saved values in the
|
||||||
* TCB. This depends on the fact that nested signal handling is
|
* TCB. This depends on the fact that nested signal handling is
|
||||||
@@ -131,8 +121,9 @@ void up_sigdeliver(void)
|
|||||||
* could be modified by a hostile program.
|
* could be modified by a hostile program.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
regs[XCPT_PC] = rtcb->xcp.saved_pc;
|
regs[XCPT_PC] = rtcb->xcp.saved_pc;
|
||||||
regs[XCPT_I] = rtcb->xcp.saved_i;
|
regs[XCPT_I] = rtcb->xcp.saved_i;
|
||||||
|
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
|
||||||
|
|
||||||
/* Then restore the correct state for this thread of execution. */
|
/* Then restore the correct state for this thread of execution. */
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user