diff options
author | Chris Zankel <chris@zankel.net> | 2008-02-20 00:30:54 +0000 |
---|---|---|
committer | Chris Zankel <chris@zankel.net> | 2008-02-20 00:30:54 +0000 |
commit | d8f106289ffc338f15568f373b209f0c47755a54 (patch) | |
tree | 68d366e9f056bd36acb747c69cd02e5d595e2467 /libc/sysdeps/linux | |
parent | 5bb327a1dbe37208a812a9134763aa5adfa90e12 (diff) |
Xtensa: Provide an architecture specific sigaction and sa_restorer function in libc to avoid having to place executable code on stack.
Signed-off-by: Chris Zankel <chris@zankel.net>
Diffstat (limited to 'libc/sysdeps/linux')
-rw-r--r-- | libc/sysdeps/linux/xtensa/Makefile.arch | 6 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/sigaction.c | 59 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/sigrestorer.S | 19 |
3 files changed, 81 insertions, 3 deletions
diff --git a/libc/sysdeps/linux/xtensa/Makefile.arch b/libc/sysdeps/linux/xtensa/Makefile.arch index 74510c9f6..f54886444 100644 --- a/libc/sysdeps/linux/xtensa/Makefile.arch +++ b/libc/sysdeps/linux/xtensa/Makefile.arch @@ -1,14 +1,14 @@ # Makefile for uClibc # -# Copyright (C) 2007 Tensilica Inc. +# Copyright (C) 2007, 2008 Tensilica Inc. # # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. # CSRC := brk.c fork.c posix_fadvise.c posix_fadvise64.c pread_write.c \ - __syscall_error.c + sigaction.c __syscall_error.c SSRC := bsd-_setjmp.S bsd-setjmp.S setjmp.S clone.S \ - syscall.S mmap.S windowspill.S __longjmp.S vfork.S + sigrestorer.S syscall.S mmap.S windowspill.S __longjmp.S vfork.S include $(top_srcdir)libc/sysdeps/linux/Makefile.commonarch diff --git a/libc/sysdeps/linux/xtensa/sigaction.c b/libc/sysdeps/linux/xtensa/sigaction.c new file mode 100644 index 000000000..5ef40c36e --- /dev/null +++ b/libc/sysdeps/linux/xtensa/sigaction.c @@ -0,0 +1,59 @@ +/* vi: set sw=4 ts=4: */ +/* + * sigaction() for Xtensa uClibc + * + * Copyright (C) 2007, 2008 Tensilica Inc. + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#include <errno.h> +#include <signal.h> +#include <sys/syscall.h> +#include <string.h> +#include <bits/kernel_sigaction.h> + +#define SA_RESTORER 0x04000000 + +extern void __default_sa_restorer (void); + +libc_hidden_proto(memcpy) + +int __libc_sigaction (int signum, const struct sigaction *act, + struct sigaction *oldact) +{ + struct kernel_sigaction kact, koldact; + int result; + + if (act) { + kact.k_sa_handler = act->sa_handler; + memcpy(&kact.sa_mask, &act->sa_mask, sizeof (kact.sa_mask)); + kact.sa_flags = act->sa_flags; + + if (kact.sa_flags & SA_RESTORER) { + kact.sa_restorer = act->sa_restorer; + } else { + kact.sa_restorer = __default_sa_restorer; + kact.sa_flags |= SA_RESTORER; + } + } + + result = __syscall_rt_sigaction(signum, act ? __ptrvalue (&kact) : NULL, + oldact ? __ptrvalue (&koldact) : NULL, + _NSIG / 8); + + if (oldact && result >= 0) { + oldact->sa_handler = koldact.k_sa_handler; + memcpy(&oldact->sa_mask, &koldact.sa_mask, sizeof(oldact->sa_mask)); + oldact->sa_flags = koldact.sa_flags; + oldact->sa_restorer = koldact.sa_restorer; + } + + return result; +} + +#ifndef LIBC_SIGACTION +libc_hidden_proto (sigaction) +weak_alias (__libc_sigaction, sigaction) +libc_hidden_weak (sigaction) +#endif diff --git a/libc/sysdeps/linux/xtensa/sigrestorer.S b/libc/sysdeps/linux/xtensa/sigrestorer.S new file mode 100644 index 000000000..474a89319 --- /dev/null +++ b/libc/sysdeps/linux/xtensa/sigrestorer.S @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2008 Tensilica Inc. + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#include <sys/syscall.h> + +#if __NR_rt_sigreturn > 255 +# error value of __NR_rt_sigreturn is too big! +#endif + + .text + .align 4 + .global __default_sa_restorer + .type __default_sa_restorer, @function +__default_sa_restorer: + movi a2, __NR_rt_sigreturn + syscall |