diff options
author | Kyle McMartin <kyle@parisc-linux.org> | 2006-01-15 14:10:29 -0500 |
---|---|---|
committer | Kyle McMartin <kyle@duet.int.mcmartin.ca> | 2006-01-22 20:57:42 -0500 |
commit | f671c45df23005692daa200aba768c642fb14ef2 (patch) | |
tree | fbc882669f06171cd1a8be2ad7b99f062a6e1e57 /arch/parisc/kernel/signal32.h | |
parent | 16541c8745e28f62b3dcb6cb354b73c9c01ea178 (diff) | |
download | blackbird-op-linux-f671c45df23005692daa200aba768c642fb14ef2.tar.gz blackbird-op-linux-f671c45df23005692daa200aba768c642fb14ef2.zip |
[PARISC] Arch-specific compat signals
Add enough arch-specific compat signals code to enable parisc64
to compile and boot out of the mainline tree. There are likely still
many dragons here, but this is a start to squashing the last
big difference between the mainline tree and the parisc-linux tree.
The remaining bugs can be squashed as they come up.
Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
Diffstat (limited to 'arch/parisc/kernel/signal32.h')
-rw-r--r-- | arch/parisc/kernel/signal32.h | 127 |
1 files changed, 125 insertions, 2 deletions
diff --git a/arch/parisc/kernel/signal32.h b/arch/parisc/kernel/signal32.h index 4d1569e717cc..e39b38a67a87 100644 --- a/arch/parisc/kernel/signal32.h +++ b/arch/parisc/kernel/signal32.h @@ -20,8 +20,34 @@ #define _PARISC64_KERNEL_SIGNAL32_H #include <linux/compat.h> -#include <asm/compat_signal.h> -#include <asm/compat_rt_sigframe.h> + +typedef compat_uptr_t compat_sighandler_t; + +typedef struct compat_sigaltstack { + compat_uptr_t ss_sp; + compat_int_t ss_flags; + compat_size_t ss_size; +} compat_stack_t; + +/* Most things should be clean enough to redefine this at will, if care + is taken to make libc match. */ + +struct compat_sigaction { + compat_sighandler_t sa_handler; + compat_uint_t sa_flags; + compat_sigset_t sa_mask; /* mask last for extensibility */ +}; + +/* 32-bit ucontext as seen from an 64-bit kernel */ +struct compat_ucontext { + compat_uint_t uc_flags; + compat_uptr_t uc_link; + compat_stack_t uc_stack; /* struct compat_sigaltstack (12 bytes)*/ + /* FIXME: Pad out to get uc_mcontext to start at an 8-byte aligned boundary */ + compat_uint_t pad[1]; + struct compat_sigcontext uc_mcontext; + compat_sigset_t uc_sigmask; /* mask last for extensibility */ +}; /* ELF32 signal handling */ @@ -29,6 +55,103 @@ struct k_sigaction32 { struct compat_sigaction sa; }; +typedef struct compat_siginfo { + int si_signo; + int si_errno; + int si_code; + + union { + int _pad[((128/sizeof(int)) - 3)]; + + /* kill() */ + struct { + unsigned int _pid; /* sender's pid */ + unsigned int _uid; /* sender's uid */ + } _kill; + + /* POSIX.1b timers */ + struct { + compat_timer_t _tid; /* timer id */ + int _overrun; /* overrun count */ + char _pad[sizeof(unsigned int) - sizeof(int)]; + compat_sigval_t _sigval; /* same as below */ + int _sys_private; /* not to be passed to user */ + } _timer; + + /* POSIX.1b signals */ + struct { + unsigned int _pid; /* sender's pid */ + unsigned int _uid; /* sender's uid */ + compat_sigval_t _sigval; + } _rt; + + /* SIGCHLD */ + struct { + unsigned int _pid; /* which child */ + unsigned int _uid; /* sender's uid */ + int _status; /* exit code */ + compat_clock_t _utime; + compat_clock_t _stime; + } _sigchld; + + /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ + struct { + unsigned int _addr; /* faulting insn/memory ref. */ + } _sigfault; + + /* SIGPOLL */ + struct { + int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ + int _fd; + } _sigpoll; + } _sifields; +} compat_siginfo_t; + +int copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from); +int copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from); + +/* In a deft move of uber-hackery, we decide to carry the top half of all + * 64-bit registers in a non-portable, non-ABI, hidden structure. + * Userspace can read the hidden structure if it *wants* but is never + * guaranteed to be in the same place. Infact the uc_sigmask from the + * ucontext_t structure may push the hidden register file downards + */ +struct compat_regfile { + /* Upper half of all the 64-bit registers that were truncated + on a copy to a 32-bit userspace */ + compat_int_t rf_gr[32]; + compat_int_t rf_iasq[2]; + compat_int_t rf_iaoq[2]; + compat_int_t rf_sar; +}; + +#define COMPAT_SIGRETURN_TRAMP 4 +#define COMPAT_SIGRESTARTBLOCK_TRAMP 5 +#define COMPAT_TRAMP_SIZE (COMPAT_SIGRETURN_TRAMP + \ + COMPAT_SIGRESTARTBLOCK_TRAMP) + +struct compat_rt_sigframe { + /* XXX: Must match trampoline size in arch/parisc/kernel/signal.c + Secondary to that it must protect the ERESTART_RESTARTBLOCK + trampoline we left on the stack (we were bad and didn't + change sp so we could run really fast.) */ + compat_uint_t tramp[COMPAT_TRAMP_SIZE]; + compat_siginfo_t info; + struct compat_ucontext uc; + /* Hidden location of truncated registers, *must* be last. */ + struct compat_regfile regs; +}; + +/* + * The 32-bit ABI wants at least 48 bytes for a function call frame: + * 16 bytes for arg0-arg3, and 32 bytes for magic (the only part of + * which Linux/parisc uses is sp-20 for the saved return pointer...) + * Then, the stack pointer must be rounded to a cache line (64 bytes). + */ +#define SIGFRAME32 64 +#define FUNCTIONCALLFRAME32 48 +#define PARISC_RT_SIGFRAME_SIZE32 (((sizeof(struct compat_rt_sigframe) + FUNCTIONCALLFRAME32) + SIGFRAME32) & -SIGFRAME32) + void sigset_32to64(sigset_t *s64, compat_sigset_t *s32); void sigset_64to32(compat_sigset_t *s32, sigset_t *s64); int do_sigaltstack32 (const compat_stack_t __user *uss32, |