From 40215fde031482b484d993a91b9e64c6081c96eb Mon Sep 17 00:00:00 2001 From: Carlos O'Donell Date: Tue, 2 Feb 2010 16:36:48 -0500 Subject: [PATCH] Add unlimited argument support to makecontext() The initial implementation of makecontext() supported only 8 arguments. This change adds support for unlimited argument processing given a large enough stack. --- ChangeLog.hppa | 5 +++ sysdeps/unix/sysv/linux/hppa/makecontext.c | 61 ++++++++++++++---------------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/ChangeLog.hppa b/ChangeLog.hppa index 28a3c44..ef38909 100644 --- a/ChangeLog.hppa +++ b/ChangeLog.hppa @@ -1,3 +1,8 @@ +2010-02-02 Carlos O'Donell + + * sysdeps/unix/sysv/linux/hppa/makecontext.c (__makecontext): + Support more than 8 arguments. + 2010-02-01 Kyle McMartin * sysdeps/unix/sysv/linux/hppa/bits/socket.h: Fix value of diff --git a/sysdeps/unix/sysv/linux/hppa/makecontext.c b/sysdeps/unix/sysv/linux/hppa/makecontext.c index 69a1813..cb036d0 100644 --- a/sysdeps/unix/sysv/linux/hppa/makecontext.c +++ b/sysdeps/unix/sysv/linux/hppa/makecontext.c @@ -1,5 +1,5 @@ /* Create new context. - Copyright (C) 2008 Free Software Foundation, Inc. + Copyright (C) 2008, 2010 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Helge Deller , 2008. @@ -25,24 +25,21 @@ #include #include -/* XXX: This implementation only handles integer arguments. */ +/* POSIX only supports integer arguments. */ +#define STACK_ALIGN 64 +#define FRAME_SIZE 8 void __makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...) { - unsigned int *sp; + unsigned long *sp; va_list ap; int i; - if (argc > 8) - { - fprintf (stderr, _("\ -makecontext: does not know how to handle more than 8 arguments\n")); - exit (-1); - } - - /* Get stack pointer. */ - sp = (unsigned int *) ucp->uc_stack.ss_sp; + /* Get stack pointer (64-byte aligned). */ + sp = (unsigned long *)((((unsigned long) ucp->uc_stack.ss_sp) + + FRAME_SIZE + argc + STACK_ALIGN) + & ~(STACK_ALIGN - 1)); /* Store address to jump to. */ ucp->uc_mcontext.sc_gr[2] = (unsigned long) func; @@ -50,29 +47,27 @@ makecontext: does not know how to handle more than 8 arguments\n")); va_start (ap, argc); /* Handle arguments. */ for (i = 0; i < argc; ++i) - switch (i) - { - case 0: - case 1: - case 2: - case 3: - ucp->uc_mcontext.sc_gr[26-i] = va_arg (ap, int); - break; - case 4: - case 5: - case 6: - case 7: - if (sizeof(unsigned long) == 4) { - /* 32bit: put arg7-arg4 on stack. */ - sp[7-i] = va_arg (ap, int); - } else { - /* 64bit: r19-r22 are arg7-arg4. */ - ucp->uc_mcontext.sc_gr[22+4-i] = va_arg (ap, int); + { + if (i < 4) + { + ucp->uc_mcontext.sc_gr[26-i] = va_arg (ap, int); + continue; } - break; - } - va_end (ap); + if ((i < 8) && (sizeof(unsigned long) == 8)) + { + /* 64bit: r19-r22 are arg7-arg4. */ + ucp->uc_mcontext.sc_gr[22+4-i] = va_arg (ap, int); + continue; + } + + /* All other arguments go on the stack. */ + sp[-1 * (FRAME_SIZE + 1 + i)] = va_arg (ap, int); + } + va_end (ap); + + /* Adjust the stack pointer to last used argument. */ + ucp->uc_mcontext.sc_gr[30] = (unsigned long) sp; } -- 2.7.4