linuxthreads/ChangeLog

2003-02-25  Roland McGrath  <roland@redhat.com>


	* sysdeps/powerpc/powerpc64/dl-machine.h: Support new TLS relocs.
	* sysdeps/powerpc/powerpc64/dl-tls.h: New file.
This commit is contained in:
Roland McGrath 2003-02-25 23:45:16 +00:00
parent fec4171904
commit 1d02f71fe4
18 changed files with 474 additions and 48 deletions

View File

@ -1,3 +1,6 @@
2003-02-25 Roland McGrath <roland@redhat.com>
2003-02-25 Steven Munroe <sjmunroe@us.ibm.com> 2003-02-25 Steven Munroe <sjmunroe@us.ibm.com>
* elf/elf.h: Add new R_PPC64_* relocs for TLS. * elf/elf.h: Add new R_PPC64_* relocs for TLS.
@ -5,6 +8,8 @@
(TLS_LE, TLS_IE, TLS_LD, TLS_GD): Define. (TLS_LE, TLS_IE, TLS_LD, TLS_GD): Define.
* sysdeps/powerpc/powerpc64/elf/configure.in: New file. * sysdeps/powerpc/powerpc64/elf/configure.in: New file.
* sysdeps/powerpc/powerpc64/elf/configure: New file (generated). * sysdeps/powerpc/powerpc64/elf/configure: New file (generated).
* sysdeps/powerpc/powerpc64/dl-machine.h: Support new TLS relocs.
* sysdeps/powerpc/powerpc64/dl-tls.h: New file.
* sysdeps/powerpc/elf/libc-start.c (__libc_start_main): * sysdeps/powerpc/elf/libc-start.c (__libc_start_main):
Do DL_SYSDEP_OSCHECK here, matching 2002-12-01 change to generic file. Do DL_SYSDEP_OSCHECK here, matching 2002-12-01 change to generic file.

View File

@ -1111,7 +1111,7 @@ EOF
int bar __attribute__ ((visibility ("protected"))) = 1; int bar __attribute__ ((visibility ("protected"))) = 1;
EOF EOF
libc_cv_visibility_attribute=no libc_cv_visibility_attribute=no
if ${CC-cc} -Werror -S conftest.c -o conftest.s >/dev/null 2>&1; then if AC_TRY_COMMAND[${CC-cc} -Werror -S conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD]; then
if grep '\.hidden.*foo' conftest.s >/dev/null; then if grep '\.hidden.*foo' conftest.s >/dev/null; then
if grep '\.protected.*bar' conftest.s >/dev/null; then if grep '\.protected.*bar' conftest.s >/dev/null; then
libc_cv_visibility_attribute=yes libc_cv_visibility_attribute=yes
@ -1134,7 +1134,7 @@ EOF
int bar (int x) { return x; } int bar (int x) { return x; }
EOF EOF
libc_cv_broken_visibility_attribute=yes libc_cv_broken_visibility_attribute=yes
if ${CC-cc} -Werror -S conftest.c -o conftest.s >/dev/null 2>&1; then if ${CC-cc} -Werror -S conftest.c -o conftest.s >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD; then
changequote(,)dnl changequote(,)dnl
if grep '\.hidden[ _]foo' conftest.s >/dev/null; then if grep '\.hidden[ _]foo' conftest.s >/dev/null; then
changequote([,])dnl changequote([,])dnl

View File

@ -37,7 +37,7 @@ libdl-shared-only-routines += eval
ifeq (yes,$(build-shared)) ifeq (yes,$(build-shared))
tests = glrefmain failtest tst-dladdr default errmsg1 tstcxaatexit \ tests = glrefmain failtest tst-dladdr default errmsg1 tstcxaatexit \
bug-dlopen1 bug-dlsym1 bug-dlopen1 bug-dlsym1 bug-dlopen-leak
ifeq (yes,$(have-protected)) ifeq (yes,$(have-protected))
tests += tstatexit tests += tstatexit
endif endif
@ -99,6 +99,14 @@ $(objpfx)modstatic.so: $(common-objpfx)libc.so $(common-objpfx)libc_nonshared.a
$(objpfx)bug-dlopen1: $(libdl) $(objpfx)bug-dlopen1: $(libdl)
$(objpfx)bug-dlopen-leak: $(libdl)
bug-dlopen-leak-ENV = MALLOC_TRACE=$(objpfx)bug-dlopen-leak.mtrace
$(objpfx)mtrace-bug-dlopen-leak: $(objpfx)bug-dlopen-leak.out
$(common-objpfx)malloc/mtrace $(objpfx)bug-dlopen-leak.mtrace > $@
ifneq (no,$(PERL))
tests: $(objpfx)mtrace-bug-dlopen-leak
endif
$(objpfx)bug-dlsym1: $(libdl) $(objpfx)bug-dlsym1-lib2.so $(objpfx)bug-dlsym1: $(libdl) $(objpfx)bug-dlsym1-lib2.so
$(objpfx)bug-dlsym1.out: $(objpfx)bug-dlsym1-lib1.so \ $(objpfx)bug-dlsym1.out: $(objpfx)bug-dlsym1-lib1.so \
$(objpfx)bug-dlsym1-lib2.so $(objpfx)bug-dlsym1-lib2.so

View File

@ -1,3 +1,8 @@
2003-01-31 Steven Munroe <sjmunroe@us.ibm.com>
* sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S [SHARED]:
Conditionalize .toc section magic on this.
2003-02-21 Roland McGrath <roland@redhat.com> 2003-02-21 Roland McGrath <roland@redhat.com>
* cancel.c (__pthread_perform_cleanup): Call __libc_thread_freeres * cancel.c (__pthread_perform_cleanup): Call __libc_thread_freeres

View File

@ -33,7 +33,8 @@ extern int __compare_and_swap (long int *p, long int oldval, long int newval);
/* Get some notion of the current stack. Need not be exactly the top /* Get some notion of the current stack. Need not be exactly the top
of the stack, just something somewhere in the current frame. */ of the stack, just something somewhere in the current frame. */
#define CURRENT_STACK_FRAME __builtin_frame_address (0) #define CURRENT_STACK_FRAME __stack_pointer_register__
register char *__stack_pointer_register__ __asm__ ("%esp");
/* Spinlock implementation; required. */ /* Spinlock implementation; required. */

View File

@ -32,7 +32,8 @@ extern int __compare_and_swap (long int *p, long int oldval, long int newval);
/* Get some notion of the current stack. Need not be exactly the top /* Get some notion of the current stack. Need not be exactly the top
of the stack, just something somewhere in the current frame. */ of the stack, just something somewhere in the current frame. */
#define CURRENT_STACK_FRAME __builtin_frame_address (0) #define CURRENT_STACK_FRAME __stack_pointer_register__
register char *__stack_pointer_register__ __asm__ ("%esp");
/* Spinlock implementation; required. */ /* Spinlock implementation; required. */

View File

@ -58,7 +58,7 @@ typedef struct
We need USE_TLS to be consistently defined, for ldsodefs.h conditionals. We need USE_TLS to be consistently defined, for ldsodefs.h conditionals.
But some of the code below can cause problems in building libpthread But some of the code below can cause problems in building libpthread
(e.g. useldt.h will defined FLOATING_STACKS when it shouldn't). */ (e.g. useldt.h will define FLOATING_STACKS when it shouldn't). */
#if defined HAVE_TLS_SUPPORT \ #if defined HAVE_TLS_SUPPORT \
&& (defined FLOATING_STACKS || !defined IS_IN_libpthread) && (defined FLOATING_STACKS || !defined IS_IN_libpthread)

View File

@ -0,0 +1,134 @@
/* Definitions for thread-local data handling. linuxthreads/PowerPC64 version.
Copyright (C) 2003 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
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#ifndef _TLS_H
#define _TLS_H
#ifndef __ASSEMBLER__
# include <pt-machine.h>
# include <stddef.h>
/* Type for the dtv. */
typedef union dtv
{
size_t counter;
void *pointer;
} dtv_t;
typedef struct
{
dtv_t *dtv;
/* Reserved for the thread implementation. Unused in LinuxThreads. */
void *private;
} tcbhead_t;
#endif
#ifdef HAVE_TLS_SUPPORT
/* Signal that TLS support is available. */
# define USE_TLS 1
# ifndef __ASSEMBLER__
/* Get system call information. */
# include <sysdep.h>
/* This is the size of the initial TCB. */
# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
/* Alignment requirements for the initial TCB. */
# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
/* This is the size of the TCB. */
# define TLS_TCB_SIZE sizeof (tcbhead_t)
/* Alignment requirements for the TCB. */
# define TLS_TCB_ALIGN __alignof__ (tcbhead_t)
/* This is the size we need before TCB. */
# define TLS_PRE_TCB_SIZE sizeof (struct _pthread_descr_struct)
/* the following assumes that TP (R13) is points to the end of the tcb
+ 0x7000 (per the ABI). This implies that tcb address is
R13-(TLS_TCB_SIZE + 0x7000). As we define TLS_DTV_AT_TP we can
assume that the pthread_descr is allocate immediately ahead of the
tcb. This implies that the pthread_descr address is
R13-(TLS_PRE_TCB_SIZE + TLS_TCB_SIZE + 0x7000). */
# define TLS_TCB_OFFSET 0x7000
/* The DTV is allocated at the TP; the TCB is placed elsewhere. */
/* This is not really true for powerpc64. We are following alpha
where the DTV pointer is first doubleword in the TCB. */
# define TLS_DTV_AT_TP 1
/* Install the dtv pointer. The pointer passed is to the element with
index -1 which contain the length. */
# define INSTALL_DTV(TCBP, DTVP) \
(((tcbhead_t *) (TCBP))->dtv = (DTVP) + 1)
/* Install new dtv for current thread. */
# define INSTALL_NEW_DTV(DTV) (THREAD_DTV() = (DTV))
/* Return dtv of given thread descriptor. */
# define GET_DTV(TCBP) (((tcbhead_t *) (TCBP))->dtv)
/* Code to initially initialize the thread pointer. This might need
special attention since 'errno' is not yet available and if the
operation can cause a failure 'errno' must not be touched. */
# define TLS_INIT_TP(TCBP, SECONDCALL) \
(__thread_self = (uintptr_t) (TCBP) + TLS_TCB_OFFSET + TLS_TCB_SIZE, 0)
/* Return the address of the dtv for the current thread. */
# define THREAD_DTV() \
(((tcbhead_t *) (__thread_register - (TLS_TCB_OFFSET + TLS_TCB_SIZE)))->dtv)
/* Return the thread descriptor for the current thread. */
# undef THREAD_SELF
# define THREAD_SELF \
((pthread_descr) (__thread_register \
- (TLS_TCB_OFFSET + TLS_TCB_SIZE + TLS_PRE_TCB_SIZE)))
# undef INIT_THREAD_SELF
# define INIT_THREAD_SELF(DESCR, NR) \
(__thread_self = (pthread_descr) (((char *)(DESCR)) \
+ (TLS_TCB_OFFSET + TLS_TCB_SIZE + TLS_PRE_TCB_SIZE)))
/* Get the thread descriptor definition. */
# include <linuxthreads/descr.h>
/* Generic bits of LinuxThreads may call these macros with
DESCR set to NULL. We are expected to be able to reference
the "current" value. */
#define THREAD_GETMEM(descr, member) \
((void) sizeof (descr), THREAD_SELF->member)
#define THREAD_GETMEM_NC(descr, member) \
((void) sizeof (descr), THREAD_SELF->member)
#define THREAD_SETMEM(descr, member, value) \
((void) sizeof (descr), THREAD_SELF->member = (value))
#define THREAD_SETMEM_NC(descr, member, value) \
((void) sizeof (descr), THREAD_SELF->member = (value))
# endif /* HAVE_TLS_SUPPORT */
#endif /* __ASSEMBLER__ */
#endif /* tls.h */

View File

@ -26,11 +26,13 @@
replaced by a call to `execve'. Return -1 for errors, 0 to the new process, replaced by a call to `execve'. Return -1 for errors, 0 to the new process,
and the process ID of the new process to the old process. */ and the process ID of the new process to the old process. */
#ifdef SHARED
.section ".toc","aw" .section ".toc","aw"
.LC0: .LC0:
.tc __libc_pthread_functions[TC],__libc_pthread_functions .tc __libc_pthread_functions[TC],__libc_pthread_functions
.section ".text" .section ".text"
.align 2 .align 2
#endif
ENTRY (__vfork) ENTRY (__vfork)

View File

@ -70,6 +70,9 @@ libc {
# This was always there, but not exported as it should have been. # This was always there, but not exported as it should have been.
mig_strncpy; mig_strncpy;
} }
GLIBC_2.3 {
NDR_record;
}
%if !SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2) %if !SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
HURD_CTHREADS_0.3 { HURD_CTHREADS_0.3 {

View File

@ -1,5 +1,5 @@
/* Machine-specific definition for spin locks. Alpha version. /* Machine-specific definition for spin locks. Alpha version.
Copyright (C) 1994, 1997 Free Software Foundation, Inc. Copyright (C) 1994,97,2002 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -38,8 +38,8 @@ typedef __volatile long int __spin_lock_t;
_EXTERN_INLINE void _EXTERN_INLINE void
__spin_unlock (__spin_lock_t *__lock) __spin_unlock (__spin_lock_t *__lock)
{ {
__asm__ __volatile__ ("mb; stq $31, %0; mb" __asm__ __volatile__ ("mb");
: "=m" (__lock)); *__lock = 0;
} }
/* Try to lock LOCK; return nonzero if we locked it, zero if another has. */ /* Try to lock LOCK; return nonzero if we locked it, zero if another has. */
@ -47,6 +47,9 @@ __spin_unlock (__spin_lock_t *__lock)
_EXTERN_INLINE int _EXTERN_INLINE int
__spin_try_lock (register __spin_lock_t *__lock) __spin_try_lock (register __spin_lock_t *__lock)
{ {
#if 1
return 1;
#else
register long int __rtn, __tmp; register long int __rtn, __tmp;
do do
@ -66,6 +69,7 @@ __spin_try_lock (register __spin_lock_t *__lock)
} while (! __rtn); } while (! __rtn);
/* RTN is now nonzero; we have the lock. */ /* RTN is now nonzero; we have the lock. */
return __rtn; return __rtn;
#endif
} }
/* Return nonzero if LOCK is locked. */ /* Return nonzero if LOCK is locked. */

View File

@ -102,7 +102,7 @@ _ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
ac_status=$? ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err egrep -v '^ *\+' conftest.er1 >conftest.err
rm -f conftest.er1 rm -f conftest.er1
cat conftest.err >&5 cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5
@ -148,7 +148,7 @@ _ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
ac_status=$? ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err egrep -v '^ *\+' conftest.er1 >conftest.err
rm -f conftest.er1 rm -f conftest.er1
cat conftest.err >&5 cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5
@ -193,6 +193,12 @@ else
#line $LINENO "configure" #line $LINENO "configure"
#include "confdefs.h" #include "confdefs.h"
#include <mach/mach_types.h> #include <mach/mach_types.h>
#ifdef F77_DUMMY_MAIN
# ifdef __cplusplus
extern "C"
# endif
int F77_DUMMY_MAIN() { return 1; }
#endif
int int
main () main ()
{ {
@ -235,6 +241,12 @@ else
#line $LINENO "configure" #line $LINENO "configure"
#include "confdefs.h" #include "confdefs.h"
#include <mach/mach_types.h> #include <mach/mach_types.h>
#ifdef F77_DUMMY_MAIN
# ifdef __cplusplus
extern "C"
# endif
int F77_DUMMY_MAIN() { return 1; }
#endif
int int
main () main ()
{ {
@ -278,6 +290,12 @@ else
#line $LINENO "configure" #line $LINENO "configure"
#include "confdefs.h" #include "confdefs.h"
#include <mach/task_info.h> #include <mach/task_info.h>
#ifdef F77_DUMMY_MAIN
# ifdef __cplusplus
extern "C"
# endif
int F77_DUMMY_MAIN() { return 1; }
#endif
int int
main () main ()
{ {
@ -336,7 +354,7 @@ _ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
ac_status=$? ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err egrep -v '^ *\+' conftest.er1 >conftest.err
rm -f conftest.er1 rm -f conftest.er1
cat conftest.err >&5 cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5
@ -372,21 +390,6 @@ echo "$as_me: error: what manner of Mach is this?" >&2;}
{ (exit 1); exit 1; }; } { (exit 1); exit 1; }; }
fi fi
echo "$as_me:$LINENO: checking for egrep" >&5
echo $ECHO_N "checking for egrep... $ECHO_C" >&6
if test "${ac_cv_prog_egrep+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
if echo a | (grep -E '(a|b)') >/dev/null 2>&1
then ac_cv_prog_egrep='grep -E'
else ac_cv_prog_egrep='egrep'
fi
fi
echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
echo "${ECHO_T}$ac_cv_prog_egrep" >&6
EGREP=$ac_cv_prog_egrep
echo "$as_me:$LINENO: checking for host_page_size in mach_host.defs" >&5 echo "$as_me:$LINENO: checking for host_page_size in mach_host.defs" >&5
echo $ECHO_N "checking for host_page_size in mach_host.defs... $ECHO_C" >&6 echo $ECHO_N "checking for host_page_size in mach_host.defs... $ECHO_C" >&6
if test "${libc_cv_mach_host_page_size+set}" = set; then if test "${libc_cv_mach_host_page_size+set}" = set; then
@ -399,7 +402,7 @@ else
_ACEOF _ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
$EGREP "host_page_size" >/dev/null 2>&1; then egrep "host_page_size" >/dev/null 2>&1; then
libc_cv_mach_host_page_size=yes libc_cv_mach_host_page_size=yes
else else
libc_cv_mach_host_page_size=no libc_cv_mach_host_page_size=no
@ -429,7 +432,7 @@ _ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
ac_status=$? ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err egrep -v '^ *\+' conftest.er1 >conftest.err
rm -f conftest.er1 rm -f conftest.er1
cat conftest.err >&5 cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5
@ -469,7 +472,7 @@ _ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
ac_status=$? ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err egrep -v '^ *\+' conftest.er1 >conftest.err
rm -f conftest.er1 rm -f conftest.er1
cat conftest.err >&5 cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5
@ -514,7 +517,7 @@ else
_ACEOF _ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
$EGREP "i386_io_perm_modify" >/dev/null 2>&1; then egrep "i386_io_perm_modify" >/dev/null 2>&1; then
libc_cv_mach_i386_ioports=yes libc_cv_mach_i386_ioports=yes
else else
libc_cv_mach_i386_ioports=no libc_cv_mach_i386_ioports=no
@ -543,7 +546,7 @@ else
_ACEOF _ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
$EGREP "i386_set_gdt" >/dev/null 2>&1; then egrep "i386_set_gdt" >/dev/null 2>&1; then
libc_cv_mach_i386_gdt=yes libc_cv_mach_i386_gdt=yes
else else
libc_cv_mach_i386_gdt=no libc_cv_mach_i386_gdt=no

View File

@ -0,0 +1,53 @@
/* Definition for thread-local data handling. Hurd/Alpha version.
Copyright (C) 2002 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
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#ifndef _TLS_H
#define _TLS_H
#if defined HAVE_TLS_SUPPORT && 0
/* Signal that TLS support is available. */
# define USE_TLS 1
/* Code to initially initialize the thread pointer. This might need
special attention since 'errno' is not yet available and if the
operation can cause a failure 'errno' must not be touched. */
# define TLS_INIT_TP(descr) \
do \
{ \
register tcbhead_t *_a0 __asm__ ("$16") = (descr); \
__asm__ ("call_pal %0" : : "i" (PAL_wruniq), "r" (_a0)); \
} while (0)
# define THREAD_TCB() \
({ \
register tcbhead_t *_rv __asm__ ("$0"); \
__asm__ ("call_pal %0" : "=r" (rv) : "i" (PAL_rduniq)); \
_rv; \
})
/* Install new dtv for current thread. */
# define INSTALL_NEW_DTV(dtv) (THREAD_DTV () = (dtv))
/* Return the address of the dtv for the current thread. */
# define THREAD_DTV() (THREAD_TCB ()->dtv)
#endif /* HAVE_TLS_SUPPORT */
#endif /* tls.h */

View File

@ -27,16 +27,22 @@ case "$machine" in
;; ;;
esac esac
echo "$as_me:$LINENO: checking Hurd header version" >&5 echo "$as_me:$LINENO: checking Hurd header version" >&5
echo $ECHO_N "checking Hurd header version... $ECHO_C" >&6 echo $ECHO_N "checking Hurd header version... $ECHO_C" >&6
if test "${libc_cv_hurd_version+set}" = set; then if test "${libc_cv_hurd_version+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6 echo $ECHO_N "(cached) $ECHO_C" >&6
else else
cat >conftest.$ac_ext <<_ACEOF
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure" #line $LINENO "configure"
#include "confdefs.h" #include "confdefs.h"
#include <hurd/version.h> #include <hurd/version.h>
#ifdef F77_DUMMY_MAIN
# ifdef __cplusplus
extern "C"
# endif
int F77_DUMMY_MAIN() { return 1; }
#endif
int int
main () main ()
{ {

View File

@ -328,9 +328,19 @@ elf_machine_dynamic (void)
PLT entries should not be allowed to define the value. PLT entries should not be allowed to define the value.
ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
of the main executable's symbols, as for a COPY reloc. */ of the main executable's symbols, as for a COPY reloc. */
#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
#define elf_machine_type_class(type) \
( (((type) == R_PPC64_DTPMOD64 \
|| (type) == R_PPC64_DTPREL64 \
|| (type) == R_PPC64_TPREL64 \
|| (type) == R_PPC64_ADDR24) * ELF_RTYPE_CLASS_PLT) \
| (((type) == R_PPC64_COPY) * ELF_RTYPE_CLASS_COPY))
#else
#define elf_machine_type_class(type) \ #define elf_machine_type_class(type) \
((((type) == R_PPC64_ADDR24) * ELF_RTYPE_CLASS_PLT) \ ((((type) == R_PPC64_ADDR24) * ELF_RTYPE_CLASS_PLT) \
| (((type) == R_PPC64_COPY) * ELF_RTYPE_CLASS_COPY)) | (((type) == R_PPC64_COPY) * ELF_RTYPE_CLASS_COPY))
#endif
/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
#define ELF_MACHINE_JMP_SLOT R_PPC64_JMP_SLOT #define ELF_MACHINE_JMP_SLOT R_PPC64_JMP_SLOT
@ -547,7 +557,7 @@ elf_machine_rela (struct link_map *map,
{ {
int r_type = ELF64_R_TYPE (reloc->r_info); int r_type = ELF64_R_TYPE (reloc->r_info);
struct link_map *sym_map; struct link_map *sym_map;
Elf64_Addr value; Elf64_Addr value, raw_value;
#ifndef RTLD_BOOTSTRAP #ifndef RTLD_BOOTSTRAP
const Elf64_Sym *const refsym = sym; const Elf64_Sym *const refsym = sym;
/* This is defined in rtld.c, but nowhere in the static libc.a; make the /* This is defined in rtld.c, but nowhere in the static libc.a; make the
@ -564,21 +574,36 @@ elf_machine_rela (struct link_map *map,
/* Already done in dynamic linker. */ /* Already done in dynamic linker. */
if (map != &GL(dl_rtld_map)) if (map != &GL(dl_rtld_map))
#endif #endif
*reloc_addr = map->l_addr + reloc->r_addend; *reloc_addr = map->l_addr + reloc->r_addend;
return; return;
} }
if (r_type == R_PPC64_NONE) if (r_type == R_PPC64_NONE)
return; return;
sym_map = RESOLVE_MAP (&sym, version, r_type);
value = 0; value = 0;
raw_value = 0;
#if defined USE_TLS && !defined RTLD_BOOTSTRAP
sym_map = RESOLVE_MAP (&sym, version, r_type);
raw_value = value = reloc->r_addend;
if (sym_map) if (sym_map)
if (sym)
{ {
if (sym) raw_value += sym->st_value;
value = sym_map->l_addr + sym->st_value; value = raw_value + sym_map->l_addr;
value += reloc->r_addend;
} }
#else
sym_map = RESOLVE_MAP (&sym, version, r_type);
if (sym_map)
{
if (sym)
{
raw_value = sym->st_value + sym_map->l_addr;
}
value = raw_value + reloc->r_addend;
}
#endif
switch (r_type) switch (r_type)
{ {
@ -587,6 +612,43 @@ elf_machine_rela (struct link_map *map,
*reloc_addr = value; *reloc_addr = value;
return; return;
#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
case R_PPC64_DTPMOD64:
#ifdef RTLD_BOOTSTRAP
/* During startup the dynamic linker is always index 1. */
*reloc_addr = 1;
#else
/* Get the information from the link map returned by the
resolv function. */
if (sym_map != NULL)
{
*reloc_addr = sym_map->l_tls_modid;
}
#endif
return;
case R_PPC64_TPREL64:
#ifdef RTLD_BOOTSTRAP
*reloc_addr = raw_value + map->l_tls_offset - 0x7010;
#else
if (sym_map)
{
CHECK_STATIC_TLS (map, sym_map);
*reloc_addr = raw_value + sym_map->l_tls_offset - 0x7010;
}
#endif
return;
case R_PPC64_DTPREL64:
#ifndef RTLD_BOOTSTRAP
/* During relocation all TLS symbols are defined and used.
Therefore the offset is already correct. */
*reloc_addr = raw_value - 0x8000;
#endif
return;
#endif
case R_PPC64_JMP_SLOT: case R_PPC64_JMP_SLOT:
elf_machine_fixup_plt (map, sym_map, reloc, reloc_addr, value); elf_machine_fixup_plt (map, sym_map, reloc, reloc_addr, value);
@ -601,15 +663,61 @@ elf_machine_rela (struct link_map *map,
value, 0xfffc); value, 0xfffc);
break; break;
case R_PPC64_TPREL16_LO_DS:
if (dont_expect ((value & 3) != 0))
_dl_reloc_overflow (map, "R_PPC64_TPREL16_LO_DS",
reloc_addr, sym, refsym);
*(Elf64_Half *) reloc_addr = BIT_INSERT (*(Elf64_Half *) reloc_addr,
value, 0xfffc);
break;
case R_PPC64_DTPREL16_LO_DS:
if (dont_expect ((value & 3) != 0))
_dl_reloc_overflow (map, "R_PPC64_DTPREL16_LO_DS",
reloc_addr, sym, refsym);
*(Elf64_Half *) reloc_addr = BIT_INSERT (*(Elf64_Half *) reloc_addr,
value, 0xfffc);
break;
case R_PPC64_GOT_TPREL16_LO_DS:
if (dont_expect ((value & 3) != 0))
_dl_reloc_overflow (map, "R_PPC64_GOT_TPREL16_LO_DS",
reloc_addr, sym, refsym);
*(Elf64_Half *) reloc_addr = BIT_INSERT (*(Elf64_Half *) reloc_addr,
value, 0xfffc);
break;
case R_PPC64_GOT_DTPREL16_LO_DS:
if (dont_expect ((value & 3) != 0))
_dl_reloc_overflow (map, "R_PPC64_GOT_DTPREL16_LO_DS",
reloc_addr, sym, refsym);
*(Elf64_Half *) reloc_addr = BIT_INSERT (*(Elf64_Half *) reloc_addr,
value, 0xfffc);
break;
case R_PPC64_ADDR16_LO: case R_PPC64_ADDR16_LO:
case R_PPC64_TPREL16_LO:
case R_PPC64_DTPREL16_LO:
case R_PPC64_GOT_TLSGD16_LO:
case R_PPC64_GOT_TLSLD16_LO:
*(Elf64_Half *) reloc_addr = PPC_LO (value); *(Elf64_Half *) reloc_addr = PPC_LO (value);
break; break;
case R_PPC64_ADDR16_HI: case R_PPC64_ADDR16_HI:
case R_PPC64_TPREL16_HI:
case R_PPC64_DTPREL16_HI:
case R_PPC64_GOT_TPREL16_HI:
case R_PPC64_GOT_DTPREL16_HI:
case R_PPC64_GOT_TLSGD16_HI:
case R_PPC64_GOT_TLSLD16_HI:
*(Elf64_Half *) reloc_addr = PPC_HI (value); *(Elf64_Half *) reloc_addr = PPC_HI (value);
break; break;
case R_PPC64_ADDR16_HA: case R_PPC64_ADDR16_HA:
case R_PPC64_TPREL16_HA:
case R_PPC64_DTPREL16_HA:
case R_PPC64_GOT_TLSGD16_HA:
case R_PPC64_GOT_TLSLD16_HA:
*(Elf64_Half *) reloc_addr = PPC_HA (value); *(Elf64_Half *) reloc_addr = PPC_HA (value);
break; break;
@ -690,19 +798,59 @@ elf_machine_rela (struct link_map *map,
value, 0xfffc); value, 0xfffc);
break; break;
case R_PPC64_TPREL16_DS:
if (dont_expect ((value + 0x8000) >= 0x10000 || (value & 3) != 0))
_dl_reloc_overflow (map, "R_PPC64_TPREL16_DS", reloc_addr,
sym, refsym);
*(Elf64_Half *) reloc_addr = BIT_INSERT (*(Elf64_Half *) reloc_addr,
value, 0xfffc);
break;
case R_PPC64_DTPREL16_DS:
if (dont_expect ((value + 0x8000) >= 0x10000 || (value & 3) != 0))
_dl_reloc_overflow (map, "R_PPC64_DTPREL16_DS", reloc_addr,
sym, refsym);
*(Elf64_Half *) reloc_addr = BIT_INSERT (*(Elf64_Half *) reloc_addr,
value, 0xfffc);
break;
case R_PPC64_GOT_TPREL16_DS:
if (dont_expect ((value + 0x8000) >= 0x10000 || (value & 3) != 0))
_dl_reloc_overflow (map, "R_PPC64_GOT_TPREL16_DS", reloc_addr,
sym, refsym);
*(Elf64_Half *) reloc_addr = BIT_INSERT (*(Elf64_Half *) reloc_addr,
value, 0xfffc);
break;
case R_PPC64_GOT_DTPREL16_DS:
if (dont_expect ((value + 0x8000) >= 0x10000 || (value & 3) != 0))
_dl_reloc_overflow (map, "R_PPC64_GOT_DTPREL16_DS",
reloc_addr, sym, refsym);
*(Elf64_Half *) reloc_addr = BIT_INSERT (*(Elf64_Half *) reloc_addr,
value, 0xfffc);
break;
case R_PPC64_ADDR16_HIGHER: case R_PPC64_ADDR16_HIGHER:
case R_PPC64_TPREL16_HIGHER:
case R_PPC64_DTPREL16_HIGHER:
*(Elf64_Half *) reloc_addr = PPC_HIGHER (value); *(Elf64_Half *) reloc_addr = PPC_HIGHER (value);
break; break;
case R_PPC64_ADDR16_HIGHEST: case R_PPC64_ADDR16_HIGHEST:
case R_PPC64_TPREL16_HIGHEST:
case R_PPC64_DTPREL16_HIGHEST:
*(Elf64_Half *) reloc_addr = PPC_HIGHEST (value); *(Elf64_Half *) reloc_addr = PPC_HIGHEST (value);
break; break;
case R_PPC64_ADDR16_HIGHERA: case R_PPC64_ADDR16_HIGHERA:
case R_PPC64_TPREL16_HIGHERA:
case R_PPC64_DTPREL16_HIGHERA:
*(Elf64_Half *) reloc_addr = PPC_HIGHERA (value); *(Elf64_Half *) reloc_addr = PPC_HIGHERA (value);
break; break;
case R_PPC64_ADDR16_HIGHESTA: case R_PPC64_ADDR16_HIGHESTA:
case R_PPC64_TPREL16_HIGHESTA:
case R_PPC64_DTPREL16_HIGHESTA:
*(Elf64_Half *) reloc_addr = PPC_HIGHESTA (value); *(Elf64_Half *) reloc_addr = PPC_HIGHESTA (value);
break; break;

View File

@ -0,0 +1,40 @@
/* Thread-local storage handling in the ELF dynamic linker. PowerPC64 version.
Copyright (C) 2003 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
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
/* Type used for the representation of TLS information in the TOC. */
typedef struct
{
unsigned long int ti_module;
unsigned long int ti_offset;
} tls_index;
#ifdef SHARED
extern void *__tls_get_addr (tls_index *ti);
/* Dynamic thread vector pointers point 0x8000 past the start of each
TLS block. */
# define TLS_DTV_OFFSET 0x8000
# define GET_ADDR_OFFSET (ti->ti_offset + TLS_DTV_OFFSET)
# define __TLS_GET_ADDR(__ti) (__tls_get_addr (__ti) - TLS_DTV_OFFSET)
#endif

View File

@ -44,7 +44,11 @@ if test "${libc_cv_linux2010+set}" = set; then
else else
cat >conftest.$ac_ext <<_ACEOF cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure" #line $LINENO "configure"
#include "confdefs.h" /* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <linux/version.h> #include <linux/version.h>
#if !defined LINUX_VERSION_CODE || LINUX_VERSION_CODE < (2 *65536+ 0 *256+ 10) /* 2.0.10 */ #if !defined LINUX_VERSION_CODE || LINUX_VERSION_CODE < (2 *65536+ 0 *256+ 10) /* 2.0.10 */
eat flaming death eat flaming death
@ -165,7 +169,11 @@ echo $ECHO_N "checking for kernel header at least $minimum_kernel... $ECHO_C" >&
abinum=`echo "$minimum_kernel.0.0.0" | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\1,\2,\3/'`; abinum=`echo "$minimum_kernel.0.0.0" | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\1,\2,\3/'`;
cat >conftest.$ac_ext <<_ACEOF cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure" #line $LINENO "configure"
#include "confdefs.h" /* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <linux/version.h> #include <linux/version.h>
#if LINUX_VERSION_CODE < $decnum #if LINUX_VERSION_CODE < $decnum
eat flaming death eat flaming death

View File

@ -1,5 +1,5 @@
/* Optional code to distinguish library flavours. /* Optional code to distinguish library flavours.
Copyright (C) 2001, 2002 Free Software Foundation, Inc. Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2001. Contributed by Jakub Jelinek <jakub@redhat.com>, 2001.
@ -39,7 +39,12 @@ _dl_osversion_init (char *assume_kernel)
if (!*q) if (!*q)
break; break;
} }
#if __LINUX_KERNEL_VERSION > 0
if (osversion < __LINUX_KERNEL_VERSION)
osversion = __LINUX_KERNEL_VERSION;
#else
if (osversion) if (osversion)
#endif
GL(dl_osversion) = osversion; GL(dl_osversion) = osversion;
} }