* PATCH: Make i386 signal delivery work with -mregparm
@ 2004-08-26 21:14 H. Peter Anvin
0 siblings, 0 replies; only message in thread
From: H. Peter Anvin @ 2004-08-26 21:14 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-kernel
[-- Attachment #1: Type: text/plain, Size: 512 bytes --]
This patch allows i386 signal delivery to work correctly when userspace
is compiled with -mregparm. This is somewhat hacky: it passes the
arguments *both* on the stack and in registers, but it works because
there are only one or three (depending on SA_SIGINFO) official
arguments. If you're relying on the unofficial arguments then you're
doing something nonportable anyway and can put in the
__attribute__((cdecl,regparm(0))) in the correct place.
Patch against current top of tree (2.6.9-rc1).
-hpa
[-- Attachment #2: signal-regparm.diff --]
[-- Type: text/x-patch, Size: 2619 bytes --]
Index: linux-2.5/arch/i386/kernel/signal.c
===================================================================
RCS file: /home/hpa/kernel/bkcvs/linux-2.5/arch/i386/kernel/signal.c,v
retrieving revision 1.42
diff -u -r1.42 signal.c
--- linux-2.5/arch/i386/kernel/signal.c 13 Jul 2004 18:02:33 -0000 1.42
+++ linux-2.5/arch/i386/kernel/signal.c 26 Aug 2004 06:50:40 -0000
@@ -345,18 +345,20 @@
void __user *restorer;
struct sigframe __user *frame;
int err = 0;
+ int usig;
frame = get_sigframe(ka, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
goto give_sigsegv;
- err |= __put_user((current_thread_info()->exec_domain
- && current_thread_info()->exec_domain->signal_invmap
- && sig < 32
- ? current_thread_info()->exec_domain->signal_invmap[sig]
- : sig),
- &frame->sig);
+ usig = current_thread_info()->exec_domain
+ && current_thread_info()->exec_domain->signal_invmap
+ && sig < 32
+ ? current_thread_info()->exec_domain->signal_invmap[sig]
+ : sig;
+
+ err |= __put_user(usig, &frame->sig);
if (err)
goto give_sigsegv;
@@ -395,6 +397,9 @@
/* Set up registers for signal handler */
regs->esp = (unsigned long) frame;
regs->eip = (unsigned long) ka->sa.sa_handler;
+ regs->eax = (unsigned long) sig;
+ regs->edx = (unsigned long) 0;
+ regs->ecx = (unsigned long) 0;
set_fs(USER_DS);
regs->xds = __USER_DS;
@@ -422,18 +427,20 @@
void __user *restorer;
struct rt_sigframe __user *frame;
int err = 0;
+ int usig;
frame = get_sigframe(ka, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
goto give_sigsegv;
- err |= __put_user((current_thread_info()->exec_domain
- && current_thread_info()->exec_domain->signal_invmap
- && sig < 32
- ? current_thread_info()->exec_domain->signal_invmap[sig]
- : sig),
- &frame->sig);
+ usig = current_thread_info()->exec_domain
+ && current_thread_info()->exec_domain->signal_invmap
+ && sig < 32
+ ? current_thread_info()->exec_domain->signal_invmap[sig]
+ : sig;
+
+ err |= __put_user(usig, &frame->sig);
err |= __put_user(&frame->info, &frame->pinfo);
err |= __put_user(&frame->uc, &frame->puc);
err |= copy_siginfo_to_user(&frame->info, info);
@@ -476,6 +483,9 @@
/* Set up registers for signal handler */
regs->esp = (unsigned long) frame;
regs->eip = (unsigned long) ka->sa.sa_handler;
+ regs->eax = (unsigned long) usig;
+ regs->edx = (unsigned long) &frame->info;
+ regs->ecx = (unsigned long) &frame->uc;
set_fs(USER_DS);
regs->xds = __USER_DS;
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2004-08-26 21:18 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-08-26 21:14 PATCH: Make i386 signal delivery work with -mregparm H. Peter Anvin
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.