diff -r -u --new-file glibc-2.3.2.orig/Makeconfig glibc-2.3.2/Makeconfig --- glibc-2.3.2.orig/Makeconfig 2003-01-06 00:31:36.000000000 -0500 +++ glibc-2.3.2/Makeconfig 2004-09-07 12:35:14.000000000 -0400 @@ -711,7 +711,7 @@ # Must build the routines as PIC, though, because they can end up in (users') # shared objects. We don't want to use CFLAGS-os because users may, for # example, make that processor-specific. -CFLAGS-.oS = $(CFLAGS-.o) $(pic-ccflag) +CFLAGS-.oS = $(CFLAGS-.o) -fPIC CPPFLAGS-.oS = $(CPPFLAGS-.o) -DPIC -DLIBC_NONSHARED=1 libtype.oS = lib%_nonshared.a endif diff -r -u --new-file glibc-2.3.2.orig/linuxthreads/sysdeps/s390/tls.h glibc-2.3.2/linuxthreads/sysdeps/s390/tls.h --- glibc-2.3.2.orig/linuxthreads/sysdeps/s390/tls.h 2003-01-30 13:33:59.000000000 -0500 +++ glibc-2.3.2/linuxthreads/sysdeps/s390/tls.h 2004-09-07 12:35:14.000000000 -0400 @@ -124,7 +124,7 @@ # ifndef __ASSEMBLER__ /* Get the thread descriptor definition. */ -# include +//# include # define NONTLS_INIT_TP \ do { \ diff -r -u --new-file glibc-2.3.2.orig/sysdeps/generic/unwind.h glibc-2.3.2/sysdeps/generic/unwind.h --- glibc-2.3.2.orig/sysdeps/generic/unwind.h 2001-11-15 18:09:20.000000000 -0500 +++ glibc-2.3.2/sysdeps/generic/unwind.h 2004-09-07 12:35:14.000000000 -0400 @@ -114,6 +114,14 @@ e.g. executing cleanup code, and not to implement rethrowing. */ extern void _Unwind_Resume (struct _Unwind_Exception *); +/* @@@ Use unwind data to perform a stack backtrace. The trace callback + is called for every stack frame in the call chain, but no cleanup + actions are performed. */ +typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn) + (struct _Unwind_Context *, void *); + +extern _Unwind_Reason_Code _Unwind_Backtrace (_Unwind_Trace_Fn, void *); + /* These functions are used for communicating information about the unwind context (i.e. the unwind descriptors and the user register state) between the unwind library and the personality routine and landing pad. Only diff -r -u --new-file glibc-2.3.2.orig/sysdeps/s390/s390-32/backtrace.c glibc-2.3.2/sysdeps/s390/s390-32/backtrace.c --- glibc-2.3.2.orig/sysdeps/s390/s390-32/backtrace.c 2001-07-07 15:21:28.000000000 -0400 +++ glibc-2.3.2/sysdeps/s390/s390-32/backtrace.c 2004-09-07 12:35:14.000000000 -0400 @@ -1,5 +1,5 @@ /* Return backtrace of current program state. - Copyright (C) 2000, 2001 Free Software Foundation, Inc. + Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU C Library. @@ -18,8 +18,12 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include +#include #include #include +#include +#include /* This is a global variable set at program start time. It marks the highest used stack address. */ @@ -51,10 +55,31 @@ int empty[2]; }; -int -__backtrace (array, size) - void **array; - int size; +struct trace_arg +{ + void **array; + int cnt, size; +}; + +static _Unwind_Reason_Code (*unwind_backtrace) (_Unwind_Trace_Fn, void *); +static _Unwind_Ptr (*unwind_getip) (struct _Unwind_Context *); + +static void +init (void) +{ + void *handle = __libc_dlopen ("libgcc_s.so.1"); + + if (handle == NULL) + return; + + unwind_backtrace = __libc_dlsym (handle, "_Unwind_Backtrace"); + unwind_getip = __libc_dlsym (handle, "_Unwind_GetIP"); + if (unwind_getip == NULL) + unwind_backtrace = NULL; +} + +static int +__backchain_backtrace (void **array, int size) { /* We assume that all the code is generated with frame pointers set. */ struct layout *stack; @@ -71,11 +96,42 @@ out of range. */ break; - array[cnt++] = stack->save_grps[8]; + array[cnt++] = (void *) (stack->save_grps[8] & 0x7fffffff); stack = (struct layout *) stack->back_chain; } return cnt; } + +static _Unwind_Reason_Code +backtrace_helper (struct _Unwind_Context *ctx, void *a) +{ + struct trace_arg *arg = a; + + /* We are first called with address in the __backtrace function. + Skip it. */ + if (arg->cnt != -1) + arg->array[arg->cnt] = (void *) unwind_getip (ctx); + if (++arg->cnt == arg->size) + return _URC_END_OF_STACK; + return _URC_NO_REASON; +} + +int +__backtrace (void **array, int size) +{ + struct trace_arg arg = { .array = array, .size = size, .cnt = -1 }; + __libc_once_define (static, once); + + __libc_once (once, init); + if (unwind_backtrace == NULL) + return __backchain_backtrace (array, size); + + if (size >= 1) + unwind_backtrace (backtrace_helper, &arg); + + return arg.cnt != -1 ? arg.cnt : 0; +} + weak_alias (__backtrace, backtrace) diff -r -u --new-file glibc-2.3.2.orig/sysdeps/s390/s390-64/backtrace.c glibc-2.3.2/sysdeps/s390/s390-64/backtrace.c --- glibc-2.3.2.orig/sysdeps/s390/s390-64/backtrace.c 2001-07-07 15:21:28.000000000 -0400 +++ glibc-2.3.2/sysdeps/s390/s390-64/backtrace.c 2004-09-07 12:35:14.000000000 -0400 @@ -1,5 +1,5 @@ /* Return backtrace of current program state. 64 bit S/390 version. - Copyright (C) 2001 Free Software Foundation, Inc. + Copyright (C) 2001, 2003 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU C Library. @@ -18,8 +18,12 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include +#include #include #include +#include +#include /* This is a global variable set at program start time. It marks the @@ -50,10 +54,31 @@ long empty[2]; }; +struct trace_arg +{ + void **array; + int cnt, size; +}; + +static _Unwind_Reason_Code (*unwind_backtrace) (_Unwind_Trace_Fn, void *); +static _Unwind_Ptr (*unwind_getip) (struct _Unwind_Context *); + +static void +init (void) +{ + void *handle = __libc_dlopen ("libgcc_s.so.1"); + + if (handle == NULL) + return; + + unwind_backtrace = __libc_dlsym (handle, "_Unwind_Backtrace"); + unwind_getip = __libc_dlsym (handle, "_Unwind_GetIP"); + if (unwind_getip == NULL) + unwind_backtrace = NULL; +} + int -__backtrace (array, size) - void **array; - int size; +__backchain_backtrace (void **array, int size) { /* We assume that all the code is generated with frame pointers set. */ struct layout *stack; @@ -77,4 +102,35 @@ return cnt; } + +static _Unwind_Reason_Code +backtrace_helper (struct _Unwind_Context *ctx, void *a) +{ + struct trace_arg *arg = a; + + /* We are first called with address in the __backtrace function. + Skip it. */ + if (arg->cnt != -1) + arg->array[arg->cnt] = (void *) unwind_getip (ctx); + if (++arg->cnt == arg->size) + return _URC_END_OF_STACK; + return _URC_NO_REASON; +} + +int +__backtrace (void **array, int size) +{ + struct trace_arg arg = { .array = array, .size = size, .cnt = -1 }; + __libc_once_define (static, once); + + __libc_once (once, init); + if (unwind_backtrace == NULL) + return __backchain_backtrace (array, size); + + if (size >= 1) + unwind_backtrace (backtrace_helper, &arg); + + return arg.cnt != -1 ? arg.cnt : 0; +} + weak_alias (__backtrace, backtrace)