aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Eric Andersen <andersen@codepoet.org>2007-02-02 02:15:09 +0000
committerGravatar Eric Andersen <andersen@codepoet.org>2007-02-02 02:15:09 +0000
commit9056025f8498652fffa9a76548946d58abbe22ae (patch)
tree423eaf0843e7af728b60cbbf63603432d291c569
parent8f1c3ccfc08e43c228d8655d5ab05794b03a1117 (diff)
downloaduClibc-9056025f8498652fffa9a76548946d58abbe22ae.tar.gz
uClibc-9056025f8498652fffa9a76548946d58abbe22ae.tar.bz2
backport fix from svn trunk.
Do not set SA_RESTORER when the application did not request it.
-rw-r--r--libc/sysdeps/linux/mips/sigaction.c55
1 files changed, 49 insertions, 6 deletions
diff --git a/libc/sysdeps/linux/mips/sigaction.c b/libc/sysdeps/linux/mips/sigaction.c
index 79bbdae5e..770ac9426 100644
--- a/libc/sysdeps/linux/mips/sigaction.c
+++ b/libc/sysdeps/linux/mips/sigaction.c
@@ -27,8 +27,19 @@
#define SA_RESTORER 0x04000000
+extern __typeof(sigaction) __libc_sigaction;
-#if defined __NR_rt_sigaction
+#ifdef __NR_rt_sigaction
+
+#if _MIPS_SIM != _ABIO32
+
+# ifdef __NR_rt_sigreturn
+static void restore_rt (void) asm ("__restore_rt");
+# endif
+# ifdef __NR_sigreturn
+static void restore (void) asm ("__restore");
+# endif
+#endif
/* If ACT is not NULL, change the action for SIG to *ACT.
If OACT is not NULL, put the old action for SIG in *OACT. */
@@ -48,10 +59,12 @@ int __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oa
kact.k_sa_handler = act->sa_handler;
memcpy (&kact.sa_mask, &act->sa_mask, sizeof (kact.sa_mask));
kact.sa_flags = act->sa_flags;
-
- kact.sa_flags = act->sa_flags | SA_RESTORER;
#ifdef HAVE_SA_RESTORER
+# if _MIPS_SIM == _ABIO32
kact.sa_restorer = act->sa_restorer;
+# else
+ kact.sa_restorer = &restore_rt;
+# endif
#endif
}
@@ -73,8 +86,7 @@ int __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oa
#else
-#warning "Yes there is a warning here. Don't worry about it."
-static void restore (void) asm ("__restore");
+extern void restore (void) asm ("__restore") attribute_hidden;
/* If ACT is not NULL, change the action for SIG to *ACT.
If OACT is not NULL, put the old action for SIG in *OACT. */
@@ -93,9 +105,12 @@ int __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oa
if (act) {
kact.k_sa_handler = act->sa_handler;
kact.sa_mask = act->sa_mask.__val[0];
- kact.sa_flags = act->sa_flags | SA_RESTORER;
#ifdef HAVE_SA_RESTORER
+# if _MIPS_SIM == _ABIO32
kact.sa_restorer = act->sa_restorer;
+# else
+ kact.sa_restorer = &restore_rt;
+# endif
#endif
}
@@ -121,3 +136,31 @@ int __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oa
#endif
weak_alias (__libc_sigaction, sigaction)
+
+/* NOTE: Please think twice before making any changes to the bits of
+ code below. GDB needs some intimate knowledge about it to
+ recognize them as signal trampolines, and make backtraces through
+ signal handlers work right. Important are both the names
+ (__restore_rt) and the exact instruction sequence.
+ If you ever feel the need to make any changes, please notify the
+ appropriate GDB maintainer. */
+
+#define RESTORE(name, syscall) RESTORE2 (name, syscall)
+#define RESTORE2(name, syscall) \
+asm \
+ ( \
+ ".align 4\n" \
+ "__" #name ":\n" \
+ " li $2, " #syscall "\n" \
+ " syscall\n" \
+ );
+
+/* The return code for realtime-signals. */
+#if _MIPS_SIM != _ABIO32
+# ifdef __NR_rt_sigreturn
+RESTORE (restore_rt, __NR_rt_sigreturn)
+# endif
+# ifdef __NR_sigreturn
+RESTORE (restore, __NR_sigreturn)
+# endif
+#endif