Commit e14304ef by Ian Lance Taylor Committed by Ian Lance Taylor

generic-morestack.c: Include <string.h>.

libgcc/:
	* generic-morestack.c: Include <string.h>.
	(uintptr_type): Define.
	(struct initial_sp): Add dont_block_signals field.  Reduce size of
	extra array by 1.
	(allocate_segment): Set prev field to NULL.  Don't set
	__morestack_current_segment or __morestack_segments.
	(__generic_morestack): Update current->prev and *pp after calling
	allocate_segment.
	(__morestack_block_signals): Don't do anything if
	dont_block_signals is set.
	(__morestack_unblock_signals): Likewise.
	(__generic_findstack): Check for initial_sp == NULL.  Add casts to
	uintptr_type.
	(__splitstack_block_signals): New function.
	(enum __splitstack_content_offsets): Define.
	(__splitstack_getcontext, __splitstack_setcontext): New functions.
	(__splitstack_makecontext): New function.
	(__splitstack_block_signals_context): New function.
	(__splitstack_find_context): New function.
	* config/i386/morestack.S (__morestack_get_guard): New function.
	(__morestack_set_guard, __morestack_make_guard): New functions.
	* libgcc-std.ver.in: Add new functions to GCC_4.7.0.

gcc/testsuite/:
	* lib/target-supports.exp (check_effective_target_ucontext_h): New
	procedure.
	* gcc.dg/split-5.c: New test.

From-SVN: r181234
parent 8ee9fac2
2011-11-09 Ian Lance Taylor <iant@google.com>
* lib/target-supports.exp (check_effective_target_ucontext_h): New
procedure.
* gcc.dg/split-5.c: New test.
2011-11-09 Patrick Marlier <patrick.marlier@gmail.com>
* gcc.dg/tm/memopt-1.c: Adjust regexp.
......
/* { dg-do run } */
/* { dg-require-effective-target split_stack } */
/* { dg-require-effective-target pthread_h } */
/* { dg-require-effective-target ucontext_h } */
/* { dg-options "-pthread -fsplit-stack" } */
#include <stdlib.h>
#include <pthread.h>
#include <ucontext.h>
extern void __splitstack_getcontext (void *context[10]);
extern void __splitstack_setcontext (void *context[10]);
extern void *__splitstack_makecontext (size_t, void *context[10], size_t *);
extern void __splitstack_block_signals (int *, int *);
extern void __splitstack_block_signals_context (void *context[10], int *,
int *);
extern void *__splitstack_find (void *, void *, size_t *, void **, void **,
void **);
extern void *__splitstack_find_context (void *context[10], size_t *, void **,
void **, void **);
static ucontext_t c1;
static void *s1[10];
static ucontext_t c2;
static void *s2[10];
static void swap (ucontext_t *, void *fs[10], ucontext_t *, void *ts[10])
__attribute__ ((no_split_stack));
static void
swap (ucontext_t *fu, void *fs[10], ucontext_t *tu, void *ts[10])
{
__splitstack_getcontext (fs);
__splitstack_setcontext (ts);
swapcontext (fu, tu);
__splitstack_setcontext (fs);
}
/* Use a noinline function to ensure that the buffer is not removed
from the stack. */
static void use_buffer (char *buf) __attribute__ ((noinline));
static void
use_buffer (char *buf)
{
buf[0] = '\0';
}
static void
down (int i, const char *msg, ucontext_t *me, void *mes[10],
ucontext_t *other, void *others[10])
{
char buf[10000];
if (i > 0)
{
use_buffer (buf);
swap (me, mes, other, others);
down (i - 1, msg, me, mes, other, others);
}
else
{
int c = 0;
void *stack;
size_t stack_size;
void *next_segment = NULL;
void *next_sp = NULL;
void *initial_sp = NULL;
stack = __splitstack_find_context (mes, &stack_size, &next_segment,
&next_sp, &initial_sp);
if (stack != NULL)
{
++c;
while (__splitstack_find (next_segment, next_sp, &stack_size,
&next_segment, &next_sp, &initial_sp)
!= NULL)
++c;
}
}
}
static void
go1 (void)
{
down (1000, "go1", &c1, s1, &c2, s2);
pthread_exit (NULL);
}
static void
go2 (void)
{
down (1000, "go2", &c2, s2, &c1, s1);
pthread_exit (NULL);
}
struct thread_context
{
ucontext_t *u;
void **s;
};
static void *start_thread (void *) __attribute__ ((no_split_stack));
static void *
start_thread (void *context)
{
struct thread_context *tc = (struct thread_context *) context;
int block;
block = 0;
__splitstack_block_signals (&block, NULL);
__splitstack_setcontext (tc->s);
setcontext (tc->u);
abort ();
}
int
main (int argc __attribute__ ((unused)), char **argv __attribute__ ((unused)))
{
pthread_t tid;
int err;
size_t size;
struct thread_context tc;
int block;
if (getcontext (&c1) < 0)
abort ();
c2 = c1;
c1.uc_stack.ss_sp = __splitstack_makecontext (8192, &s1[0], &size);
if (c1.uc_stack.ss_sp == NULL)
abort ();
c1.uc_stack.ss_flags = 0;
c1.uc_stack.ss_size = size;
c1.uc_link = NULL;
block = 0;
__splitstack_block_signals_context (&s1[0], &block, NULL);
makecontext (&c1, go1, 0);
c2.uc_stack.ss_sp = __splitstack_makecontext (8192, &s2[0], &size);
if (c2.uc_stack.ss_sp == NULL)
abort ();
c2.uc_stack.ss_flags = 0;
c2.uc_stack.ss_size = size;
c2.uc_link = NULL;
__splitstack_block_signals_context (&s2[0], &block, NULL);
makecontext (&c2, go2, 0);
block = 0;
__splitstack_block_signals (&block, NULL);
tc.u = &c1;
tc.s = &s1[0];
err = pthread_create (&tid, NULL, start_thread, &tc);
if (err != 0)
abort ();
err = pthread_join (tid, NULL);
if (err != 0)
abort ();
return 0;
}
......@@ -4401,3 +4401,11 @@ proc check_effective_target_non_strict_align {} {
void foo(void) { z = (c *) y; }
} "-Wcast-align"]
}
# Return 1 if the target has <ucontext.h>.
proc check_effective_target_ucontext_h { } {
return [check_no_compiler_messages ucontext_h assembly {
#include <ucontext.h>
}]
}
2011-11-09 Ian Lance Taylor <iant@google.com>
* generic-morestack.c: Include <string.h>.
(uintptr_type): Define.
(struct initial_sp): Add dont_block_signals field. Reduce size of
extra array by 1.
(allocate_segment): Set prev field to NULL. Don't set
__morestack_current_segment or __morestack_segments.
(__generic_morestack): Update current->prev and *pp after calling
allocate_segment.
(__morestack_block_signals): Don't do anything if
dont_block_signals is set.
(__morestack_unblock_signals): Likewise.
(__generic_findstack): Check for initial_sp == NULL. Add casts to
uintptr_type.
(__splitstack_block_signals): New function.
(enum __splitstack_content_offsets): Define.
(__splitstack_getcontext, __splitstack_setcontext): New functions.
(__splitstack_makecontext): New function.
(__splitstack_block_signals_context): New function.
(__splitstack_find_context): New function.
* config/i386/morestack.S (__morestack_get_guard): New function.
(__morestack_set_guard, __morestack_make_guard): New functions.
* libgcc-std.ver.in: Add new functions to GCC_4.7.0.
2011-11-09 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* config.host (i[34567]86-*-cygwin*): Move i386/t-mingw-pthread ...
......
# x86/x86_64 support for -fsplit-stack.
# Copyright (C) 2009, 2010 Free Software Foundation, Inc.
# Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
# Contributed by Ian Lance Taylor <iant@google.com>.
# This file is part of GCC.
......@@ -620,6 +620,82 @@ __stack_split_initialize:
.size __stack_split_initialize, . - __stack_split_initialize
#endif
# Routines to get and set the guard, for __splitstack_getcontext,
# __splitstack_setcontext, and __splitstack_makecontext.
# void *__morestack_get_guard (void) returns the current stack guard.
.text
.global __morestack_get_guard
.hidden __morestack_get_guard
#ifdef __ELF__
.type __morestack_get_guard,@function
#endif
__morestack_get_guard:
#ifndef __x86_64__
movl %gs:0x30,%eax
#else
#ifdef __LP64__
movq %fs:0x70,%rax
#else
movl %fs:0x40,%eax
#endif
#endif
ret
#ifdef __ELF__
.size __morestack_get_guard, . - __morestack_get_guard
#endif
# void __morestack_set_guard (void *) sets the stack guard.
.global __morestack_set_guard
.hidden __morestack_set_guard
#ifdef __ELF__
.type __morestack_set_guard,@function
#endif
__morestack_set_guard:
#ifndef __x86_64__
movl 4(%esp),%eax
movl %eax,%gs:0x30
#else
X86_64_SAVE_NEW_STACK_BOUNDARY (di)
#endif
ret
#ifdef __ELF__
.size __morestack_set_guard, . - __morestack_set_guard
#endif
# void *__morestack_make_guard (void *, size_t) returns the stack
# guard value for a stack.
.global __morestack_make_guard
.hidden __morestack_make_guard
#ifdef __ELF__
.type __morestack_make_guard,@function
#endif
__morestack_make_guard:
#ifndef __x86_64__
movl 4(%esp),%eax
subl 8(%esp),%eax
addl $BACKOFF,%eax
#else
subq %rsi,%rdi
addq $BACKOFF,%rdi
movq %rdi,%rax
#endif
ret
#ifdef __ELF__
.size __morestack_make_guard, . - __morestack_make_guard
#endif
# Make __stack_split_initialize a high priority constructor. FIXME:
# This is ELF specific.
......
# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
# 2008, 2010 Free Software Foundation, Inc.
# 2008, 2010, 2011 Free Software Foundation, Inc.
#
# This file is part of GCC.
#
......@@ -1926,4 +1926,10 @@ GCC_4.7.0 {
__PFX__clrsbsi2
__PFX__clrsbdi2
__PFX__clrsbti2
__splitstack_block_signals
__splitstack_getcontext
__splitstack_setcontext
__splitstack_makecontext
__splitstack_block_signals_context
__splitstack_find_context
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment