mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-23 11:20:07 +00:00
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:
parent
ee0c4dd1cc
commit
40215fde03
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user