diff options
author | Neal H. Walfield <neal@gnu.org> | 2008-02-11 17:19:59 +0000 |
---|---|---|
committer | Thomas Schwinge <tschwinge@gnu.org> | 2009-04-07 23:13:47 +0200 |
commit | 8c337b1f1366ee29dbab6f1ce531957a4674b00c (patch) | |
tree | 892aa1bc9d89fd52a06621a37b9c69df67f9405e | |
parent | fda6f4190a3429d588e46e4931764a971f567375 (diff) |
2008-02-11 Neal H. Walfield <neal@gnu.org>
* sysdeps/l4/hurd/ia32/pt-setup.c (_pthread_entry_point): New
assembly function.
(stack_setup): Take additional argument entry_point. Push it on
the stack.
(__pthread_setup): Set thread->mcontext.pc to
&_pthread_entry_point. Pass ENTRY_POINT to stack_setup.
-rw-r--r-- | sysdeps/l4/hurd/ia32/pt-setup.c | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/sysdeps/l4/hurd/ia32/pt-setup.c b/sysdeps/l4/hurd/ia32/pt-setup.c index 800d5b1b..9a3812fd 100644 --- a/sysdeps/l4/hurd/ia32/pt-setup.c +++ b/sysdeps/l4/hurd/ia32/pt-setup.c @@ -1,5 +1,5 @@ /* Setup thread stack. Hurd/i386 version. - Copyright (C) 2000, 2002 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 2008 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -30,8 +30,33 @@ ----------------- | START_ROUTINE | ----------------- - | 0 | - ----------------- */ + | Return address | + ----------------- <- %ebp + | Frame pointer | + ----------------- + + We do the following: setup the stack to return to the entry routine. + + +*/ + +/* The stack contains: + + arg + start_routine + 0 <- fake return address + C entry_point +*/ +extern uintptr_t _pthread_entry_point; +__asm__ ("\t\n\ + .globl _pthread_entry_point, __pthread_entry_point\t\n\ +_pthread_entry_point:\t\n\ +__pthread_entry_point:\t\n\ + pushl $0\t\n\ + popf\t\n\ +\t\n\ + xor %ebp, %ebp\t\n\ + ret\t\n"); /* Set up the stack for THREAD, such that it appears as if START_ROUTINE and ARG were passed to the new thread's entry-point. @@ -39,7 +64,8 @@ opportunity to install THREAD in our utcb. */ static void * stack_setup (struct __pthread *thread, - void *(*start_routine)(void *), void *arg) + void *(*start_routine)(void *), void *arg, + void (*entry_point)(void *(*)(void *), void *)) { l4_word_t *top; @@ -52,6 +78,7 @@ stack_setup (struct __pthread *thread, *--top = (l4_word_t) arg; /* Argument to START_ROUTINE. */ *--top = (l4_word_t) start_routine; *--top = 0; /* Fake return address. */ + *--top = entry_point; } return top; @@ -62,8 +89,9 @@ __pthread_setup (struct __pthread *thread, void (*entry_point)(void *(*)(void *), void *), void *(*start_routine)(void *), void *arg) { - thread->mcontext.pc = entry_point; - thread->mcontext.sp = stack_setup (thread, start_routine, arg); + thread->mcontext.pc = (uintptr_t) &_pthread_entry_point; + thread->mcontext.sp = (uintptr_t) stack_setup (thread, start_routine, arg, + entry_point); if (__pthread_num_threads == 1) return 0; |