Re: MacOSX signal handling
Re: MacOSX signal handling
- Subject: Re: MacOSX signal handling
- From: Peter Andersen <email@hidden>
- Date: Sat, 06 Apr 2002 02:45:16 +0200
>
The program is attached.
Sorry,
I now learned, that one cannot use attachments in these forums.
The code follows below.
---
Sincerely,
Peter Andersen,
Mjxlner Informatics A/S <email@hidden> and
University of Aarhus, Denmark <email@hidden>
======================================================
#include <signal.h>
#include <stdio.h>
/* Compile with e.g.
cc --save-temps -O3 -o sigcontext sigcontext.c
Please ignore "ANSI C forbids newline in string constant" warning.
*/
static long signal_number;
static unsigned long pc_at_signal;
/* Home made signal context struct. Filled out by assembler routine */
typedef struct
{
int signal_number;
unsigned long pc_at_signal;
/* register state */
long GPR[32]; /* General registers (SP = GPR[1]) */
double FR[32]; /* Floating point registers */
double FPSCR; /* Floating point status register */
long XER; /* Fixed point exception register */
long CR; /* Condition register */
long LR; /* Link register (!=pc_at_signal) */
long CTR; /* Count register */
} signal_context;
void MySignalHandler(signal_context *ctx)
{ char ch;
printf( "\nMySignalHandler:\n");
printf( " Signal number from signal_context: %d\n",
(int)ctx->signal_number);
printf( " PC from signal_context: 0x%x\n", (int)ctx->pc_at_signal);
printf( " The stack pointer at signal time: 0x%x\n", (int)ctx->GPR[1]);
printf( "Type 'q' to quit; anything else to continue: ");
ch = getchar();
if (ch=='q'){
exit(0);
} else {
printf("Returning from signal handler. Will continue infinite loop. Send
more signals!\n");
return; /* To MySignalWrapper */
}
}
void MySignalWrapper(); /* written in assembler - see below */
void MySignalCatcher (long sig, /*siginfo_t*/ void *info, struct sigcontext
*scp)
{
printf( "\nMySignalCatcher:\n");
printf( " Signal %d caught at PC=0x%x\n", (int)sig, (int)scp->sc_ir);
/* Save signal number and PC in global variables */
signal_number = sig;
pc_at_signal = scp->sc_ir;
printf( " [returning through MySignalWrapper]\n");
scp->sc_ir = (long)&MySignalWrapper; /* go to MySignalWrapper upon return
*/
return; /* via system signal handler to MySignalWrapper */
}
void InstallMySignalCatcher(void)
{
struct sigaction sa;
sa.sa_flags = 0; /* SA_SIGINFO */
sigemptyset(&sa.sa_mask);
sa.sa_handler = MySignalCatcher;
sigaction( SIGFPE, &sa, 0);
sigaction( SIGILL, &sa, 0);
sigaction( SIGBUS, &sa, 0);
sigaction( SIGEMT, &sa, 0);
sigaction( SIGINT, &sa, 0);
sigaction( SIGSEGV, &sa, 0);
sigaction( SIGTRAP, &sa, 0);
}
int main()
{
register int sp;
InstallMySignalCatcher();
__asm__ __volatile("mr %0,r1" : "=r" (sp)); /* read SP with some inline
assembler */
printf("Stack in main: 0x%x\n", (int)sp);
printf("Going into infinite loop. Send me a signal using 'kill' (or simply
^C).\n");
while (1) {};
}
/* The assembler routine: */
asm("
.set linkagesize, (6*4)
.set paramsize, (2*4) ; actually only one used (2 to ensure double align
of FR)
.set localsize, (2*4) ; signal_number, pc_at_signal
.set registersize, (32*4 + 32*8 + 8 + 4 + 4 + 4 + 4) ;
sizeof(signal_context)
.set framesize, (((linkagesize + paramsize + localsize +
registersize)+15)&-16)
.set linkageoff, 0
.set paramoff, linkageoff+linkagesize
.set localoff, paramoff+paramsize
.set registeroff, localoff+localsize
.set froff, registeroff + 4*32
.set fpscroff, froff + 8*32
.set xeroff, froff + 8
.set croff, xeroff + 4
.set lroff, croff + 4
.set ctroff, lroff + 4
.globl _MySignalWrapper
_MySignalWrapper:
; entered upon return from UNIX signal handler
; Machine state is completely as when signal was raised, except for
; the instruction pointer (PC), whose original value is stored in
; global variable pc_at_signal
; create frame
stwu r1,-framesize(r1)
; save registers
; general registers
stw r0, registeroff+4*0(r1)
; r1 already changed. Fetch from saved location in linkage field (saved
by stwu above)
lwz r0, 0(r1)
stw r0, registeroff+4*1(r1) ; r1 = SP
stw r2, registeroff+4*2(r1)
stw r3, registeroff+4*3(r1)
stw r4, registeroff+4*4(r1)
stw r5, registeroff+4*5(r1)
stw r6, registeroff+4*6(r1)
stw r7, registeroff+4*7(r1)
stw r8, registeroff+4*8(r1)
stw r9, registeroff+4*9(r1)
stw r10, registeroff+4*10(r1)
stw r11, registeroff+4*11(r1)
stw r12, registeroff+4*12(r1)
stw r13, registeroff+4*13(r1)
stw r14, registeroff+4*14(r1)
stw r15, registeroff+4*15(r1)
stw r16, registeroff+4*16(r1)
stw r17, registeroff+4*17(r1)
stw r18, registeroff+4*18(r1)
stw r19, registeroff+4*19(r1)
stw r20, registeroff+4*20(r1)
stw r21, registeroff+4*21(r1)
stw r22, registeroff+4*22(r1)
stw r23, registeroff+4*23(r1)
stw r24, registeroff+4*24(r1)
stw r25, registeroff+4*25(r1)
stw r26, registeroff+4*26(r1)
stw r27, registeroff+4*27(r1)
stw r28, registeroff+4*28(r1)
stw r29, registeroff+4*29(r1)
stw r30, registeroff+4*30(r1)
stw r31, registeroff+4*31(r1)
; Condition register
mfcr r0
stw r0, croff(r1)
; Fixed point exception register
mfxer r0
stw r0, xeroff(r1)
; Link register
mflr r0
stw r0, lroff(r1)
; Count register
mfctr r0
stw r0, ctroff(r1)
; Floating point registers - 8 byte aligned */
stfd f0, froff+8*0(r1)
stfd f1, froff+8*1(r1)
stfd f2, froff+8*2(r1)
stfd f3, froff+8*3(r1)
stfd f4, froff+8*4(r1)
stfd f5, froff+8*5(r1)
stfd f6, froff+8*6(r1)
stfd f7, froff+8*7(r1)
stfd f8, froff+8*8(r1)
stfd f9, froff+8*9(r1)
stfd f10, froff+8*10(r1)
stfd f11, froff+8*11(r1)
stfd f12, froff+8*12(r1)
stfd f13, froff+8*13(r1)
stfd f14, froff+8*14(r1)
stfd f15, froff+8*15(r1)
stfd f16, froff+8*16(r1)
stfd f17, froff+8*17(r1)
stfd f18, froff+8*18(r1)
stfd f19, froff+8*19(r1)
stfd f20, froff+8*20(r1)
stfd f21, froff+8*21(r1)
stfd f22, froff+8*22(r1)
stfd f23, froff+8*23(r1)
stfd f24, froff+8*24(r1)
stfd f25, froff+8*25(r1)
stfd f26, froff+8*26(r1)
stfd f27, froff+8*27(r1)
stfd f28, froff+8*28(r1)
stfd f29, froff+8*29(r1)
stfd f30, froff+8*30(r1)
stfd f31, froff+8*31(r1)
; Floating point status register
mffs f0
stfd f0, fpscroff(r1)
; save global variables signal_number and pc_at_signal on stack
; (in local variable section) to allow for nested signals
bcl 20,31,L1$MySignalWrapper
L1$MySignalWrapper:
mflr r13
addis r3,r13,ha16(_signal_number-L1$MySignalWrapper)
lwz r3,lo16(_signal_number-L1$MySignalWrapper)(r3)
stw r3,localoff(r1)
addis r3,r13,ha16(_pc_at_signal-L1$MySignalWrapper)
lwz r3,lo16(_pc_at_signal-L1$MySignalWrapper)(r3)
stw r3,localoff+4(r1)
; call actual handler
la r3,linkagesize+paramsize(r1) ; address of signal_context on stack
bl _MySignalHandler
; [we only get here if MySignalHandler returns after handling the
signal]
; set link register (return address) to original pc_at_signal
lwz r0,localoff+4(r1)
mtlr r0
; restore state (except link register) from stack
; general registers
; do not yet restore r0 and r1
lwz r2, registeroff+4*2(r1)
lwz r3, registeroff+4*3(r1)
lwz r4, registeroff+4*4(r1)
lwz r5, registeroff+4*5(r1)
lwz r6, registeroff+4*6(r1)
lwz r7, registeroff+4*7(r1)
lwz r8, registeroff+4*8(r1)
lwz r9, registeroff+4*9(r1)
lwz r10, registeroff+4*10(r1)
lwz r11, registeroff+4*11(r1)
lwz r12, registeroff+4*12(r1)
lwz r13, registeroff+4*13(r1)
lwz r14, registeroff+4*14(r1)
lwz r15, registeroff+4*15(r1)
lwz r16, registeroff+4*16(r1)
lwz r17, registeroff+4*17(r1)
lwz r18, registeroff+4*18(r1)
lwz r19, registeroff+4*19(r1)
lwz r20, registeroff+4*20(r1)
lwz r21, registeroff+4*21(r1)
lwz r22, registeroff+4*22(r1)
lwz r23, registeroff+4*23(r1)
lwz r24, registeroff+4*24(r1)
lwz r25, registeroff+4*25(r1)
lwz r26, registeroff+4*26(r1)
lwz r27, registeroff+4*27(r1)
lwz r28, registeroff+4*28(r1)
lwz r29, registeroff+4*29(r1)
lwz r30, registeroff+4*30(r1)
lwz r31, registeroff+4*31(r1)
; Floating point registers - 8 byte aligned */
lfd f0, froff+8*0(r1)
lfd f1, froff+8*1(r1)
lfd f2, froff+8*2(r1)
lfd f3, froff+8*3(r1)
lfd f4, froff+8*4(r1)
lfd f5, froff+8*5(r1)
lfd f6, froff+8*6(r1)
lfd f7, froff+8*7(r1)
lfd f8, froff+8*8(r1)
lfd f9, froff+8*9(r1)
lfd f10, froff+8*10(r1)
lfd f11, froff+8*11(r1)
lfd f12, froff+8*12(r1)
lfd f13, froff+8*13(r1)
lfd f14, froff+8*14(r1)
lfd f15, froff+8*15(r1)
lfd f16, froff+8*16(r1)
lfd f17, froff+8*17(r1)
lfd f18, froff+8*18(r1)
lfd f19, froff+8*19(r1)
lfd f20, froff+8*20(r1)
lfd f21, froff+8*21(r1)
lfd f22, froff+8*22(r1)
lfd f23, froff+8*23(r1)
lfd f24, froff+8*24(r1)
lfd f25, froff+8*25(r1)
lfd f26, froff+8*26(r1)
lfd f27, froff+8*27(r1)
lfd f28, froff+8*28(r1)
lfd f29, froff+8*29(r1)
lfd f30, froff+8*30(r1)
lfd f31, froff+8*31(r1)
; Floating point status register
lfd f0, fpscroff(r1)
mtfs f0
; Fixed point exception register
lwz r0, xeroff(r1)
mtxer r0
; Link register already set above
; Count register
lwz r0, ctroff(r1)
mtctr r0
; Condition register
lwz r0, croff(r1)
mtcr r0
; Finally restore r1 and r0
lwz r0, registeroff+4*0(r1)
la r1, framesize(r1)
; return (to where signal was raised)
blr
");
_______________________________________________
darwin-kernel mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/darwin-kernel
Do not post admin requests to the list. They will be ignored.