mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-27 05:44:15 +08:00
generic-morestack.c (__splitstack_find): Check for NULL old stack value.
* generic-morestack.c (__splitstack_find): Check for NULL old stack value. (__splitstack_resetcontext): New function. (__splitstack_releasecontext): New function. * libgcc-std.ver.in: Add new functions to GCC_4.7.0. From-SVN: r181771
This commit is contained in:
parent
8ce3007a90
commit
a01207c473
@ -1,3 +1,11 @@
|
|||||||
|
2011-11-27 Ian Lance Taylor <iant@google.com>
|
||||||
|
|
||||||
|
* generic-morestack.c (__splitstack_find): Check for NULL old
|
||||||
|
stack value.
|
||||||
|
(__splitstack_resetcontext): New function.
|
||||||
|
(__splitstack_releasecontext): New function.
|
||||||
|
* libgcc-std.ver.in: Add new functions to GCC_4.7.0.
|
||||||
|
|
||||||
2011-11-27 Iain Sandoe <iains@gcc.gnu.org>
|
2011-11-27 Iain Sandoe <iains@gcc.gnu.org>
|
||||||
|
|
||||||
* config/darwin-crt-tm.c: Correct comments, use correct licence.
|
* config/darwin-crt-tm.c: Correct comments, use correct licence.
|
||||||
|
@ -115,6 +115,14 @@ extern void *
|
|||||||
__splitstack_makecontext (size_t, void *context[10], size_t *)
|
__splitstack_makecontext (size_t, void *context[10], size_t *)
|
||||||
__attribute__ ((visibility ("default")));
|
__attribute__ ((visibility ("default")));
|
||||||
|
|
||||||
|
extern void *
|
||||||
|
__splitstack_resetcontext (void *context[10], size_t *)
|
||||||
|
__attribute__ ((visibility ("default")));
|
||||||
|
|
||||||
|
extern void
|
||||||
|
__splitstack_releasecontext (void *context[10])
|
||||||
|
__attribute__ ((visibility ("default")));
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
__splitstack_block_signals_context (void *context[10], int *, int *)
|
__splitstack_block_signals_context (void *context[10], int *, int *)
|
||||||
__attribute__ ((visibility ("default")));
|
__attribute__ ((visibility ("default")));
|
||||||
@ -911,15 +919,23 @@ __splitstack_find (void *segment_arg, void *sp, size_t *len,
|
|||||||
|
|
||||||
nsp = (char *) segment->old_stack;
|
nsp = (char *) segment->old_stack;
|
||||||
|
|
||||||
|
if (nsp == NULL)
|
||||||
|
{
|
||||||
|
/* We've reached the top of the stack. */
|
||||||
|
*next_segment = (void *) (uintptr_type) 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
#if defined (__x86_64__)
|
#if defined (__x86_64__)
|
||||||
nsp -= 12 * sizeof (void *);
|
nsp -= 12 * sizeof (void *);
|
||||||
#elif defined (__i386__)
|
#elif defined (__i386__)
|
||||||
nsp -= 6 * sizeof (void *);
|
nsp -= 6 * sizeof (void *);
|
||||||
#else
|
#else
|
||||||
#error "unrecognized target"
|
#error "unrecognized target"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
*next_sp = (void *) nsp;
|
*next_sp = (void *) nsp;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef STACK_GROWS_DOWNWARD
|
#ifdef STACK_GROWS_DOWNWARD
|
||||||
*len = (char *) (segment + 1) + segment->size - (char *) sp;
|
*len = (char *) (segment + 1) + segment->size - (char *) sp;
|
||||||
@ -1037,6 +1053,60 @@ __splitstack_makecontext (size_t stack_size, void *context[NUMBER_OFFSETS],
|
|||||||
return (void *) (segment + 1);
|
return (void *) (segment + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Given an existing split stack context, reset it back to the start
|
||||||
|
of the stack. Return the stack pointer and size, appropriate for
|
||||||
|
use with makecontext. This may be used if a coroutine exits, in
|
||||||
|
order to reuse the stack segments for a new coroutine. */
|
||||||
|
|
||||||
|
void *
|
||||||
|
__splitstack_resetcontext (void *context[10], size_t *size)
|
||||||
|
{
|
||||||
|
struct stack_segment *segment;
|
||||||
|
void *initial_sp;
|
||||||
|
size_t initial_size;
|
||||||
|
void *ret;
|
||||||
|
|
||||||
|
/* Reset the context assuming that MORESTACK_SEGMENTS, INITIAL_SP
|
||||||
|
and INITIAL_SP_LEN are correct. */
|
||||||
|
|
||||||
|
segment = context[MORESTACK_SEGMENTS];
|
||||||
|
context[CURRENT_SEGMENT] = segment;
|
||||||
|
context[CURRENT_STACK] = NULL;
|
||||||
|
if (segment == NULL)
|
||||||
|
{
|
||||||
|
initial_sp = context[INITIAL_SP];
|
||||||
|
initial_size = (uintptr_type) context[INITIAL_SP_LEN];
|
||||||
|
ret = initial_sp;
|
||||||
|
#ifdef STACK_GROWS_DOWNWARD
|
||||||
|
ret = (void *) ((char *) ret - initial_size);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef STACK_GROWS_DOWNWARD
|
||||||
|
initial_sp = (void *) ((char *) (segment + 1) + segment->size);
|
||||||
|
#else
|
||||||
|
initial_sp = (void *) (segment + 1);
|
||||||
|
#endif
|
||||||
|
initial_size = segment->size;
|
||||||
|
ret = (void *) (segment + 1);
|
||||||
|
}
|
||||||
|
context[STACK_GUARD] = __morestack_make_guard (initial_sp, initial_size);
|
||||||
|
context[BLOCK_SIGNALS] = NULL;
|
||||||
|
*size = initial_size;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release all the memory associated with a splitstack context. This
|
||||||
|
may be used if a coroutine exits and the associated stack should be
|
||||||
|
freed. */
|
||||||
|
|
||||||
|
void
|
||||||
|
__splitstack_releasecontext (void *context[10])
|
||||||
|
{
|
||||||
|
__morestack_release_segments (context[MORESTACK_SEGMENTS], 1);
|
||||||
|
}
|
||||||
|
|
||||||
/* Like __splitstack_block_signals, but operating on CONTEXT, rather
|
/* Like __splitstack_block_signals, but operating on CONTEXT, rather
|
||||||
than on the current state. */
|
than on the current state. */
|
||||||
|
|
||||||
|
@ -1932,4 +1932,6 @@ GCC_4.7.0 {
|
|||||||
__splitstack_makecontext
|
__splitstack_makecontext
|
||||||
__splitstack_block_signals_context
|
__splitstack_block_signals_context
|
||||||
__splitstack_find_context
|
__splitstack_find_context
|
||||||
|
__splitstack_resetcontext
|
||||||
|
__splitstack_releasecontext
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user