Skip to contentSkip to conversation

- UML - make signal frame construction more resemble x86

PATCH New Jeff Dike 1 participant 1 message Nov 13, 2004 User-mode Linux (UML)

lore
Share & tools
lore

Jeff Dike

author
#0 lore raw

PATCH 8/11 - UML - make signal frame construction more resemble x86

Quoted 1 line

From Bodo Stroesser - This makes the UML signal frame construction interface

somewhat more similar to x86 than before. Also, some small code cleanup, and checking for errors before changing the signal mask in the SA_NODEFER case.

arch/um/include/frame_kern.h +2 -4
Index: 2.6.9/arch/um/include/frame_kern.h
===================================================================
@@ -10,13 +10,11 @@
 #include "sysdep/frame_kern.h"
 
 extern int setup_signal_stack_sc(unsigned long stack_top, int sig, 
-				 unsigned long handler,
-				 void (*restorer)(void), 
+				 struct k_sigaction *ka,
 				 struct pt_regs *regs, 
 				 sigset_t *mask);
 extern int setup_signal_stack_si(unsigned long stack_top, int sig, 
-				 unsigned long handler, 
-				 void (*restorer)(void), 
+				 struct k_sigaction *ka,
 				 struct pt_regs *regs, siginfo_t *info, 
 				 sigset_t *mask);
 
arch/um/kernel/frame_kern.c +16 -7
Index: 2.6.9/arch/um/kernel/frame_kern.c
===================================================================
@@ -56,11 +56,11 @@
 }
 
 int setup_signal_stack_si(unsigned long stack_top, int sig, 
-			  unsigned long handler, void (*restorer)(void), 
-			  struct pt_regs *regs, siginfo_t *info, 
-			  sigset_t *mask)
+			  struct k_sigaction *ka, struct pt_regs *regs, 
+			  siginfo_t *info, sigset_t *mask)
 {
 	unsigned long start;
+	void *restorer;
 	void *sip, *ucp, *fp;
 
 	start = stack_top - signal_frame_si.common.len;
@@ -68,6 +68,10 @@
 	ucp = (void *) (start + signal_frame_si.uc_index);
 	fp = (void *) (((unsigned long) ucp) + sizeof(struct ucontext));
 
+	restorer = NULL;
+	if(ka->sa.sa_flags & SA_RESTORER)
+		restorer = ka->sa.sa_restorer;
+
 	if(restorer == NULL)
 		panic("setup_signal_stack_si - no restorer");
 
@@ -85,21 +89,26 @@
 			 signal_frame_si.common.sr_relative))
 		return(1);
 	
-	PT_REGS_IP(regs) = handler;
+	PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler;
 	PT_REGS_SP(regs) = start + signal_frame_si.common.sp_index;
 	return(0);
 }
 
 int setup_signal_stack_sc(unsigned long stack_top, int sig, 
-			  unsigned long handler, void (*restorer)(void), 
-			  struct pt_regs *regs, sigset_t *mask)
+			  struct k_sigaction *ka, struct pt_regs *regs, 
+			  sigset_t *mask)
 {
 	struct frame_common *frame = &signal_frame_sc_sr.common;
+	void *restorer;
 	void *user_sc;
 	int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
 	unsigned long sigs, sr;
 	unsigned long start = stack_top - frame->len - sig_size;
 
+	restorer = NULL;
+	if(ka->sa.sa_flags & SA_RESTORER)
+		restorer = ka->sa.sa_restorer;
+
 	user_sc = (void *) (start + signal_frame_sc_sr.sc_index);
 	if(restorer == NULL){
 		frame = &signal_frame_sc.common;
@@ -121,7 +130,7 @@
 	   copy_restorer(restorer, start, frame->sr_index, frame->sr_relative))
 		return(1);
 
-	PT_REGS_IP(regs) = handler;
+	PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler;
 	PT_REGS_SP(regs) = start + frame->sp_index;
 
 	return(0);
arch/um/kernel/signal_kern.c +4 -16
Index: 2.6.9/arch/um/kernel/signal_kern.c
===================================================================
@@ -42,7 +42,6 @@
 			  struct k_sigaction *ka, siginfo_t *info,
 			  sigset_t *oldset)
 {
-	void (*restorer)(void);
 	unsigned long sp;
 	int err;
 
@@ -75,20 +74,12 @@
 	if((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0))
 		sp = current->sas_ss_sp + current->sas_ss_size;
 
-	if (ka->sa.sa_flags & SA_RESTORER) 
-		restorer = ka->sa.sa_restorer;
-	else restorer = NULL;
-
 	if(ka->sa.sa_flags & SA_SIGINFO)
-		err = setup_signal_stack_si(sp, signr, 
-					    (unsigned long) ka->sa.sa_handler,
-					    restorer, regs, info, oldset);
+		err = setup_signal_stack_si(sp, signr, ka, regs, info, oldset);
 	else
-		err = setup_signal_stack_sc(sp, signr, 
-					    (unsigned long) ka->sa.sa_handler,
-					    restorer, regs, oldset);
+		err = setup_signal_stack_sc(sp, signr, ka, regs, oldset);
 
-	if (!(ka->sa.sa_flags & SA_NODEFER)) {
+	if (!err && !(ka->sa.sa_flags & SA_NODEFER)) {
 		spin_lock_irq(&current->sighand->siglock);
 		sigorsets(&current->blocked, &current->blocked, 
 			  &ka->sa.sa_mask);
@@ -107,9 +98,6 @@
 	siginfo_t info;
 	int sig;
 
-	if (!oldset)
-		oldset = &current->blocked;
-
 	sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL);
 	if(sig > 0){
 		/* Whee!  Actually deliver the signal.  */
@@ -147,7 +135,7 @@
 
 int do_signal(void)
 {
-	return(kern_do_signal(&current->thread.regs, NULL));
+	return(kern_do_signal(&current->thread.regs, &current->blocked));
 }
 
 /*