patch-2.4.8 linux/arch/ia64/kernel/gate.S
Next file: linux/arch/ia64/kernel/head.S
Previous file: linux/arch/ia64/kernel/fw-emu.c
Back to the patch index
Back to the overall index
- Lines: 182
- Date:
Tue Jul 31 10:30:08 2001
- Orig file:
v2.4.7/linux/arch/ia64/kernel/gate.S
- Orig date:
Thu Apr 5 12:51:47 2001
diff -u --recursive --new-file v2.4.7/linux/arch/ia64/kernel/gate.S linux/arch/ia64/kernel/gate.S
@@ -15,15 +15,23 @@
.section .text.gate,"ax"
- .align PAGE_SIZE
+# define ARG0_OFF (16 + IA64_SIGFRAME_ARG0_OFFSET)
+# define ARG1_OFF (16 + IA64_SIGFRAME_ARG1_OFFSET)
+# define ARG2_OFF (16 + IA64_SIGFRAME_ARG2_OFFSET)
+# define RBS_BASE_OFF (16 + IA64_SIGFRAME_RBS_BASE_OFFSET)
+# define SIGHANDLER_OFF (16 + IA64_SIGFRAME_HANDLER_OFFSET)
+# define SIGCONTEXT_OFF (16 + IA64_SIGFRAME_SIGCONTEXT_OFFSET)
-# define SIGINFO_OFF 16
-# define SIGCONTEXT_OFF (SIGINFO_OFF + ((IA64_SIGINFO_SIZE + 15) & ~15))
# define FLAGS_OFF IA64_SIGCONTEXT_FLAGS_OFFSET
# define CFM_OFF IA64_SIGCONTEXT_CFM_OFFSET
# define FR6_OFF IA64_SIGCONTEXT_FR6_OFFSET
# define BSP_OFF IA64_SIGCONTEXT_AR_BSP_OFFSET
# define RNAT_OFF IA64_SIGCONTEXT_AR_RNAT_OFFSET
+# define UNAT_OFF IA64_SIGCONTEXT_AR_UNAT_OFFSET
+# define FPSR_OFF IA64_SIGCONTEXT_AR_FPSR_OFFSET
+# define PR_OFF IA64_SIGCONTEXT_PR_OFFSET
+# define RP_OFF IA64_SIGCONTEXT_B0_OFFSET
+# define SP_OFF IA64_SIGCONTEXT_R12_OFFSET
# define base0 r2
# define base1 r3
/*
@@ -31,17 +39,9 @@
*
* +===============================+
* | |
- * // struct sigcontext //
+ * // struct sigframe //
* | |
- * +===============================+ <-- sp+SIGCONTEXT_OFF
- * | |
- * // rest of siginfo //
- * | |
- * + +---------------+
- * | | siginfo.code |
- * +---------------+---------------+
- * | siginfo.errno | siginfo.signo |
- * +-------------------------------+ <-- sp+SIGINFO_OFF
+ * +-------------------------------+ <-- sp+16
* | 16 byte of scratch |
* | space |
* +-------------------------------+ <-- sp
@@ -51,46 +51,60 @@
* incoming general register may be a NaT value (including sp, in which case the
* process ends up dying with a SIGSEGV).
*
- * The first need to do is a cover to get the registers onto the backing store.
- * Once that is done, we invoke the signal handler which may modify some of the
- * machine state. After returning from the signal handler, we return control to
- * the previous context by executing a sigreturn system call. A signal handler
- * may call the rt_sigreturn() function to directly return to a given sigcontext.
- * However, the user-level sigreturn() needs to do much more than calling the
- * rt_sigreturn() system call as it needs to unwind the stack to restore preserved
- * registers that may have been saved on the signal handler's call stack.
- *
- * On entry:
- * r2 = signal number
- * r3 = plabel of signal handler
- * r15 = new register backing store
- * [sp+16] = sigframe
+ * The first thing need to do is a cover to get the registers onto the backing
+ * store. Once that is done, we invoke the signal handler which may modify some
+ * of the machine state. After returning from the signal handler, we return
+ * control to the previous context by executing a sigreturn system call. A signal
+ * handler may call the rt_sigreturn() function to directly return to a given
+ * sigcontext. However, the user-level sigreturn() needs to do much more than
+ * calling the rt_sigreturn() system call as it needs to unwind the stack to
+ * restore preserved registers that may have been saved on the signal handler's
+ * call stack.
*/
GLOBAL_ENTRY(ia64_sigtramp)
- ld8 r10=[r3],8 // get signal handler entry point
- br.call.sptk.many rp=invoke_sighandler
-END(ia64_sigtramp)
-
-ENTRY(invoke_sighandler)
- ld8 gp=[r3] // get signal handler's global pointer
- mov b6=r10
+ // describe the state that is active when we get here:
+ .prologue
+ .unwabi @svr4, 's' // mark this as a sigtramp handler (saves scratch regs)
+ .savesp ar.unat, UNAT_OFF+SIGCONTEXT_OFF
+ .savesp ar.fpsr, FPSR_OFF+SIGCONTEXT_OFF
+ .savesp pr, PR_OFF+SIGCONTEXT_OFF
+ .savesp rp, RP_OFF+SIGCONTEXT_OFF
+ .vframesp SP_OFF+SIGCONTEXT_OFF
+ .body
+
+ .prologue
+ adds base0=SIGHANDLER_OFF,sp
+ adds base1=RBS_BASE_OFF,sp
+ br.call.sptk.many rp=1f
+1:
+ ld8 r17=[base0],(ARG0_OFF-SIGHANDLER_OFF) // get pointer to signal handler's plabel
+ ld8 r15=[base1],(ARG1_OFF-RBS_BASE_OFF) // get address of new RBS base (or NULL)
cover // push args in interrupted frame onto backing store
;;
+ .save ar.pfs, r8
alloc r8=ar.pfs,0,0,3,0 // get CFM0, EC0, and CPL0 into r8
+ ld8 out0=[base0],16 // load arg0 (signum)
;;
- mov r17=ar.bsp // fetch ar.bsp
+ ld8 out1=[base1] // load arg1 (siginfop)
+ ld8 r10=[r17],8 // get signal handler entry point
+ ;;
+ ld8 out2=[base0] // load arg2 (sigcontextp)
+ ld8 gp=[r17] // get signal handler's global pointer
cmp.ne p8,p0=r15,r0 // do we need to switch the rbs?
- mov out0=r2 // signal number
+
+ mov.m r17=ar.bsp // fetch ar.bsp
+ .spillsp.p p8, ar.rnat, RNAT_OFF+SIGCONTEXT_OFF
(p8) br.cond.spnt.few setup_rbs // yup -> (clobbers r14 and r16)
back_from_setup_rbs:
adds base0=(BSP_OFF+SIGCONTEXT_OFF),sp
;;
+ .spillsp ar.bsp, BSP_OFF+SIGCONTEXT_OFF
st8 [base0]=r17,(CFM_OFF-BSP_OFF) // save sc_ar_bsp
- dep r8=0,r8,38,26 // clear EC0, CPL0 and reserved bits
+ dep r8=0,r8,38,26 // clear EC0, CPL0 and reserved bits
adds base1=(FR6_OFF+16+SIGCONTEXT_OFF),sp
;;
-
+ .spillsp ar.pfs, CFM_OFF
st8 [base0]=r8 // save CFM0
adds base0=(FR6_OFF+SIGCONTEXT_OFF),sp
;;
@@ -99,14 +113,13 @@
;;
stf.spill [base0]=f8,32
stf.spill [base1]=f9,32
+ mov b6=r10
;;
stf.spill [base0]=f10,32
stf.spill [base1]=f11,32
- adds out1=SIGINFO_OFF,sp // siginfo pointer
;;
stf.spill [base0]=f12,32
stf.spill [base1]=f13,32
- adds out2=SIGCONTEXT_OFF,sp // sigcontext pointer
;;
stf.spill [base0]=f14,32
stf.spill [base1]=f15,32
@@ -140,9 +153,8 @@
ldf.fill f15=[base1],32
mov r15=__NR_rt_sigreturn
break __BREAK_SYSCALL
-END(invoke_sighandler)
-ENTRY(setup_rbs)
+setup_rbs:
flushrs // must be first in insn
mov ar.rsc=0 // put RSE into enforced lazy mode
adds r16=(RNAT_OFF+SIGCONTEXT_OFF),sp
@@ -150,13 +162,13 @@
mov r14=ar.rnat // get rnat as updated by flushrs
mov ar.bspstore=r15 // set new register backing store area
;;
+ .spillsp ar.rnat, RNAT_OFF+SIGCONTEXT_OFF
st8 [r16]=r14 // save sc_ar_rnat
mov ar.rsc=0xf // set RSE into eager mode, pl 3
invala // invalidate ALAT
br.cond.sptk.many back_from_setup_rbs
-END(setup_rbs)
-ENTRY(restore_rbs)
+restore_rbs:
flushrs
mov ar.rsc=0 // put RSE into enforced lazy mode
adds r16=(RNAT_OFF+SIGCONTEXT_OFF),sp
@@ -168,4 +180,4 @@
mov ar.rsc=0xf // (will be restored later on from sc_ar_rsc)
// invala not necessary as that will happen when returning to user-mode
br.cond.sptk.many back_from_restore_rbs
-END(restore_rbs)
+END(ia64_sigtramp)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)