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.
This commit is contained in:
Carlos O'Donell 2010-02-02 16:36:48 -05:00
parent ee0c4dd1cc
commit 40215fde03
2 changed files with 33 additions and 33 deletions

View File

@ -1,3 +1,8 @@
2010-02-02 Carlos O'Donell <carlos@codesourcery.com>
* sysdeps/unix/sysv/linux/hppa/makecontext.c (__makecontext):
Support more than 8 arguments.
2010-02-01 Kyle McMartin <kyle@redhat.com> 2010-02-01 Kyle McMartin <kyle@redhat.com>
* sysdeps/unix/sysv/linux/hppa/bits/socket.h: Fix value of * sysdeps/unix/sysv/linux/hppa/bits/socket.h: Fix value of

View File

@ -1,5 +1,5 @@
/* Create new context. /* 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. This file is part of the GNU C Library.
Contributed by Helge Deller <deller@gmx.de>, 2008. Contributed by Helge Deller <deller@gmx.de>, 2008.
@ -25,24 +25,21 @@
#include <sysdep.h> #include <sysdep.h>
#include <ucontext.h> #include <ucontext.h>
/* XXX: This implementation only handles integer arguments. */ /* POSIX only supports integer arguments. */
#define STACK_ALIGN 64
#define FRAME_SIZE 8
void void
__makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...) __makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
{ {
unsigned int *sp; unsigned long *sp;
va_list ap; va_list ap;
int i; int i;
if (argc > 8) /* Get stack pointer (64-byte aligned). */
{ sp = (unsigned long *)((((unsigned long) ucp->uc_stack.ss_sp)
fprintf (stderr, _("\ + FRAME_SIZE + argc + STACK_ALIGN)
makecontext: does not know how to handle more than 8 arguments\n")); & ~(STACK_ALIGN - 1));
exit (-1);
}
/* Get stack pointer. */
sp = (unsigned int *) ucp->uc_stack.ss_sp;
/* Store address to jump to. */ /* Store address to jump to. */
ucp->uc_mcontext.sc_gr[2] = (unsigned long) func; 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); va_start (ap, argc);
/* Handle arguments. */ /* Handle arguments. */
for (i = 0; i < argc; ++i) for (i = 0; i < argc; ++i)
switch (i)
{ {
case 0: if (i < 4)
case 1: {
case 2:
case 3:
ucp->uc_mcontext.sc_gr[26-i] = va_arg (ap, int); ucp->uc_mcontext.sc_gr[26-i] = va_arg (ap, int);
break; continue;
case 4: }
case 5:
case 6: if ((i < 8) && (sizeof(unsigned long) == 8))
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. */ /* 64bit: r19-r22 are arg7-arg4. */
ucp->uc_mcontext.sc_gr[22+4-i] = va_arg (ap, int); ucp->uc_mcontext.sc_gr[22+4-i] = va_arg (ap, int);
continue;
} }
break;
/* All other arguments go on the stack. */
sp[-1 * (FRAME_SIZE + 1 + i)] = va_arg (ap, int);
} }
va_end (ap); va_end (ap);
/* Adjust the stack pointer to last used argument. */
ucp->uc_mcontext.sc_gr[30] = (unsigned long) sp;
} }