Hello, The attached patch fixes stack switching in init-first.c when cthreads are used (this is for code compiled with a cross-GCC 4.5.1 for i586-pc-gnu; Debian GNU/Hurd uses an older GCC and is not affected.)
With this compiler, ‘data[-1]’ does not point to the return address. Thus, ‘switch_stacks’ would never be called, which breaks TLS. It seems to me that using ‘data[-1]’ here was fragile in the presence of nested functions, inlining, and tail-call optimizations. Thanks, Ludo’.
>From efa6d7e310b1d8918054222483f100d43525ba66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= <[email protected]> Date: Fri, 22 Jul 2011 15:46:11 +0200 Subject: [PATCH] Hurd: Fix stack switching at initialization time when using cthreads. --- ChangeLog | 7 +++++++ sysdeps/mach/hurd/i386/init-first.c | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 606bc22..6239986 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-07-22 Ludovic Courtès <[email protected]> + + * sysdeps/mach/hurd/i386/init-first.c (init): Use + `__builtin_return_address' and `__builtin_frame_address' instead + of making assumptions about the location of the return address + relative to DATA. + 2010-04-09 Ulrich Drepper <[email protected]> * nscd/aicache.c (addhstaiX): Correct passing memory to address diff --git a/sysdeps/mach/hurd/i386/init-first.c b/sysdeps/mach/hurd/i386/init-first.c index 7d93638..09af037 100644 --- a/sysdeps/mach/hurd/i386/init-first.c +++ b/sysdeps/mach/hurd/i386/init-first.c @@ -257,8 +257,8 @@ init (int *data) /* Push the user code address on the top of the new stack. It will be the return address for `init1'; we will jump there with NEWSP as the stack pointer. */ - *--newsp = data[-1]; - data[-1] = (int) &switch_stacks; + *--newsp = __builtin_return_address (0); + * ((void **) __builtin_frame_address (0) + 1) = &switch_stacks; /* Force NEWSP into %eax and &init1 into %ecx, which are not restored by function return. */ asm volatile ("# a %0 c %1" : : "a" (newsp), "c" (&init1)); -- 1.7.6
