mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-29 08:11:08 +00:00
* sysdeps/arm/dl-machine.h: Include <tls.h>.
(elf_machine_type_class, elf_machine_rel, elf_machine_rela): Handle TLS relocations. * sysdeps/unix/sysv/linux/arm/Makefile: Build __aeabi_read_tp. * sysdeps/unix/sysv/linux/arm/sysdep.h (INTERNAL_SYSCALL_RAW): Renamed from INTERNAL_SYSCALL. (INTERNAL_SYSCALL, INTERNAL_SYSCALL_ARM): New macros. * sysdeps/arm/dl-tls.h, sysdeps/arm/elf/configure.in, sysdeps/arm/elf/configure, sysdeps/arm/libc-tls.c, sysdeps/arm/linuxthreads/tls.h, sysdeps/arm/tls-macros.h, sysdeps/unix/sysv/linux/arm/aeabi_read_tp.S, sysdeps/unix/sysv/linux/arm/libc-aeabi_read_tp.S: New files.
This commit is contained in:
parent
b4900b98dc
commit
485a9bb9f0
@ -1,3 +1,18 @@
|
||||
2005-10-05 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* sysdeps/arm/dl-machine.h: Include <tls.h>.
|
||||
(elf_machine_type_class, elf_machine_rel, elf_machine_rela): Handle
|
||||
TLS relocations.
|
||||
* sysdeps/unix/sysv/linux/arm/Makefile: Build __aeabi_read_tp.
|
||||
* sysdeps/unix/sysv/linux/arm/sysdep.h (INTERNAL_SYSCALL_RAW): Renamed
|
||||
from INTERNAL_SYSCALL.
|
||||
(INTERNAL_SYSCALL, INTERNAL_SYSCALL_ARM): New macros.
|
||||
* sysdeps/arm/dl-tls.h, sysdeps/arm/elf/configure.in,
|
||||
sysdeps/arm/elf/configure, sysdeps/arm/libc-tls.c,
|
||||
sysdeps/arm/linuxthreads/tls.h, sysdeps/arm/tls-macros.h,
|
||||
sysdeps/unix/sysv/linux/arm/aeabi_read_tp.S,
|
||||
sysdeps/unix/sysv/linux/arm/libc-aeabi_read_tp.S: New files.
|
||||
|
||||
2005-10-05 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* sysdeps/arm/atomicity.h: Delete.
|
||||
|
@ -24,6 +24,7 @@
|
||||
#define ELF_MACHINE_NAME "ARM"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <tls.h>
|
||||
|
||||
#define VALID_ELF_ABIVERSION(ver) (ver == 0)
|
||||
#define VALID_ELF_OSABI(osabi) \
|
||||
@ -193,13 +194,22 @@ _dl_start_user:\n\
|
||||
.previous\n\
|
||||
");
|
||||
|
||||
/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so
|
||||
PLT entries should not be allowed to define the value.
|
||||
/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or
|
||||
TLS variable, so undefined references should not be allowed to
|
||||
define the value.
|
||||
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. */
|
||||
#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
|
||||
# define elf_machine_type_class(type) \
|
||||
((((type) == R_ARM_JUMP_SLOT || (type) == R_ARM_TLS_DTPMOD32 \
|
||||
|| (type) == R_ARM_TLS_DTPOFF32 || (type) == R_ARM_TLS_TPOFF32) \
|
||||
* ELF_RTYPE_CLASS_PLT) \
|
||||
| (((type) == R_ARM_COPY) * ELF_RTYPE_CLASS_COPY))
|
||||
#else
|
||||
#define elf_machine_type_class(type) \
|
||||
((((type) == R_ARM_JUMP_SLOT) * ELF_RTYPE_CLASS_PLT) \
|
||||
| (((type) == R_ARM_COPY) * ELF_RTYPE_CLASS_COPY))
|
||||
#endif
|
||||
|
||||
/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
|
||||
#define ELF_MACHINE_JMP_SLOT R_ARM_JUMP_SLOT
|
||||
@ -400,6 +410,23 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
|
||||
*reloc_addr = value;
|
||||
}
|
||||
break;
|
||||
#if defined USE_TLS && !defined RTLD_BOOTSTRAP
|
||||
case R_ARM_TLS_DTPMOD32:
|
||||
/* Get the information from the link map returned by the
|
||||
resolv function. */
|
||||
if (sym_map != NULL)
|
||||
*reloc_addr = sym_map->l_tls_modid;
|
||||
break;
|
||||
|
||||
case R_ARM_TLS_DTPOFF32:
|
||||
*reloc_addr += sym->st_value;
|
||||
break;
|
||||
|
||||
case R_ARM_TLS_TPOFF32:
|
||||
CHECK_STATIC_TLS (map, sym_map);
|
||||
*reloc_addr += sym->st_value + sym_map->l_tls_offset;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
_dl_reloc_bad_type (map, r_type, 0);
|
||||
break;
|
||||
@ -480,6 +507,24 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
|
||||
*reloc_addr = value;
|
||||
}
|
||||
break;
|
||||
#if defined USE_TLS && !defined RTLD_BOOTSTRAP
|
||||
case R_ARM_TLS_DTPMOD32:
|
||||
/* Get the information from the link map returned by the
|
||||
resolv function. */
|
||||
if (sym_map != NULL)
|
||||
*reloc_addr = sym_map->l_tls_modid;
|
||||
break;
|
||||
|
||||
case R_ARM_TLS_DTPOFF32:
|
||||
*reloc_addr = sym->st_value + reloc->r_addend;
|
||||
break;
|
||||
|
||||
case R_ARM_TLS_TPOFF32:
|
||||
CHECK_STATIC_TLS (map, sym_map);
|
||||
*reloc_addr = (sym->st_value + sym_map->l_tls_offset
|
||||
+ reloc->r_addend);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
_dl_reloc_bad_type (map, r_type, 0);
|
||||
break;
|
||||
|
29
sysdeps/arm/dl-tls.h
Normal file
29
sysdeps/arm/dl-tls.h
Normal file
@ -0,0 +1,29 @@
|
||||
/* Thread-local storage handling in the ELF dynamic linker. ARM version.
|
||||
Copyright (C) 2005 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 GOT. */
|
||||
typedef struct
|
||||
{
|
||||
unsigned long int ti_module;
|
||||
unsigned long int ti_offset;
|
||||
} tls_index;
|
||||
|
||||
|
||||
extern void *__tls_get_addr (tls_index *ti);
|
45
sysdeps/arm/elf/configure
vendored
Normal file
45
sysdeps/arm/elf/configure
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
# This file is generated from configure.in by Autoconf. DO NOT EDIT!
|
||||
# Local configure fragment for sysdeps/arm/elf.
|
||||
|
||||
if test "$usetls" != no; then
|
||||
# Check for support of thread-local storage handling in assembler and
|
||||
# linker.
|
||||
echo "$as_me:$LINENO: checking for ARM TLS support" >&5
|
||||
echo $ECHO_N "checking for ARM TLS support... $ECHO_C" >&6
|
||||
if test "${libc_cv_arm_tls+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
cat > conftest.s <<\EOF
|
||||
.section ".tdata", "awT", %progbits
|
||||
.globl foo
|
||||
foo: .long 1
|
||||
.section ".tbss", "awT", %nobits
|
||||
.globl bar
|
||||
bar: .skip 4
|
||||
.text
|
||||
.word foo(tpoff)
|
||||
.word foo(tlsgd)
|
||||
EOF
|
||||
if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; }; then
|
||||
libc_cv_arm_tls=yes
|
||||
else
|
||||
libc_cv_arm_tls=no
|
||||
fi
|
||||
rm -f conftest*
|
||||
fi
|
||||
echo "$as_me:$LINENO: result: $libc_cv_arm_tls" >&5
|
||||
echo "${ECHO_T}$libc_cv_arm_tls" >&6
|
||||
if test $libc_cv_arm_tls = yes; then
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define HAVE_TLS_SUPPORT 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
fi
|
||||
|
||||
#AC_DEFINE(PI_STATIC_AND_HIDDEN)
|
35
sysdeps/arm/elf/configure.in
Normal file
35
sysdeps/arm/elf/configure.in
Normal file
@ -0,0 +1,35 @@
|
||||
GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
|
||||
# Local configure fragment for sysdeps/arm/elf.
|
||||
|
||||
if test "$usetls" != no; then
|
||||
# Check for support of thread-local storage handling in assembler and
|
||||
# linker.
|
||||
AC_CACHE_CHECK(for ARM TLS support, libc_cv_arm_tls, [dnl
|
||||
cat > conftest.s <<\EOF
|
||||
.section ".tdata", "awT", %progbits
|
||||
.globl foo
|
||||
foo: .long 1
|
||||
.section ".tbss", "awT", %nobits
|
||||
.globl bar
|
||||
bar: .skip 4
|
||||
.text
|
||||
.word foo(tpoff)
|
||||
.word foo(tlsgd)
|
||||
EOF
|
||||
dnl
|
||||
if AC_TRY_COMMAND(${CC-cc} -c $CFLAGS conftest.s 1>&AS_MESSAGE_LOG_FD); then
|
||||
libc_cv_arm_tls=yes
|
||||
else
|
||||
libc_cv_arm_tls=no
|
||||
fi
|
||||
rm -f conftest*])
|
||||
if test $libc_cv_arm_tls = yes; then
|
||||
AC_DEFINE(HAVE_TLS_SUPPORT)
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl It is always possible to access static and hidden symbols in an
|
||||
dnl position independent way.
|
||||
dnl NOTE: This feature was added by the GCC TLS patches. We should test for
|
||||
dnl it. Until we do, don't define it.
|
||||
#AC_DEFINE(PI_STATIC_AND_HIDDEN)
|
37
sysdeps/arm/libc-tls.c
Normal file
37
sysdeps/arm/libc-tls.c
Normal file
@ -0,0 +1,37 @@
|
||||
/* Thread-local storage handling in the ELF dynamic linker. ARM version.
|
||||
Copyright (C) 2005 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. */
|
||||
|
||||
#include <sysdeps/generic/libc-tls.c>
|
||||
#include <dl-tls.h>
|
||||
|
||||
#if USE_TLS
|
||||
|
||||
/* On ARM, linker optimizations are not required, so __tls_get_addr
|
||||
can be called even in statically linked binaries. In this case module
|
||||
must be always 1 and PT_TLS segment exist in the binary, otherwise it
|
||||
would not link. */
|
||||
|
||||
void *
|
||||
__tls_get_addr (tls_index *ti)
|
||||
{
|
||||
dtv_t *dtv = THREAD_DTV ();
|
||||
return (char *) dtv[1].pointer.val + ti->ti_offset;
|
||||
}
|
||||
|
||||
#endif
|
172
sysdeps/arm/linuxthreads/tls.h
Normal file
172
sysdeps/arm/linuxthreads/tls.h
Normal file
@ -0,0 +1,172 @@
|
||||
/* Definitions for thread-local data handling. linuxthreads/ARM version.
|
||||
Copyright (C) 2004 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 <stdbool.h>
|
||||
# include <pt-machine.h>
|
||||
# include <stddef.h>
|
||||
|
||||
/* Type for the dtv. */
|
||||
typedef union dtv
|
||||
{
|
||||
size_t counter;
|
||||
struct
|
||||
{
|
||||
void *val;
|
||||
bool is_static;
|
||||
} pointer;
|
||||
} dtv_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
dtv_t *dtv;
|
||||
|
||||
/* Reserved for the thread implementation. Unused in LinuxThreads. */
|
||||
void *private;
|
||||
} tcbhead_t;
|
||||
#endif
|
||||
|
||||
|
||||
/* We can support TLS only if the floating-stack support is available.
|
||||
However, we want to compile in the support and test at runtime whether
|
||||
the running kernel can support it or not. To avoid bothering with the
|
||||
TLS support code at all, use configure --without-tls.
|
||||
|
||||
We need USE_TLS to be consistently defined, for ldsodefs.h conditionals.
|
||||
But some of the code below can cause problems in building libpthread
|
||||
(e.g. useldt.h will defined FLOATING_STACKS when it shouldn't). */
|
||||
|
||||
/* LinuxThreads can only support TLS if both floating stacks and support
|
||||
from the tools are available.
|
||||
|
||||
We have to define USE_TLS consistently, or ldsodefs.h will lay out types
|
||||
differently between an NPTL build and a LinuxThreads build. It can be set
|
||||
for libc.so and not libpthread.so, but only if we provide appropriate padding
|
||||
in the _pthread_descr_struct.
|
||||
|
||||
Currently nothing defines FLOATING_STACKS. We could assume this based on
|
||||
kernel version once the TLS patches are available in kernel.org.
|
||||
|
||||
To avoid bothering with the TLS support code at all, use configure
|
||||
--without-tls. */
|
||||
|
||||
#if defined HAVE_TLS_SUPPORT \
|
||||
&& (defined FLOATING_STACKS || !defined IS_IN_libpthread)
|
||||
|
||||
/* Signal that TLS support is available. */
|
||||
# define USE_TLS 1
|
||||
|
||||
/* Include padding in _pthread_descr_struct so that libc can find p_errno,
|
||||
if libpthread will only include the padding because of the !IS_IN_libpthread
|
||||
check. */
|
||||
#ifndef FLOATING_STACKS
|
||||
# define INCLUDE_TLS_PADDING 1
|
||||
#endif
|
||||
|
||||
# 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 DTV is allocated at the TP; the TCB is placed elsewhere. */
|
||||
# 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) \
|
||||
(((tcbhead_t *)__builtin_thread_pointer ())->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) \
|
||||
({ INTERNAL_SYSCALL_DECL (err); \
|
||||
long result_var; \
|
||||
result_var = INTERNAL_SYSCALL_ARM (set_tls, err, 1, (TCBP)); \
|
||||
INTERNAL_SYSCALL_ERROR_P (result_var, err) \
|
||||
? "unknown error" : NULL; })
|
||||
|
||||
/* Return the address of the dtv for the current thread. */
|
||||
# define THREAD_DTV() \
|
||||
(((tcbhead_t *)__builtin_thread_pointer ())->dtv)
|
||||
|
||||
/* Return the thread descriptor for the current thread. */
|
||||
# undef THREAD_SELF
|
||||
# define THREAD_SELF \
|
||||
((pthread_descr)__builtin_thread_pointer () - 1)
|
||||
|
||||
# undef INIT_THREAD_SELF
|
||||
# define INIT_THREAD_SELF(DESCR, NR) \
|
||||
TLS_INIT_TP ((struct _pthread_descr_struct *)(DESCR) + 1, 0)
|
||||
|
||||
/* 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.
|
||||
|
||||
In our case, we'd really prefer to use DESCR, since lots of
|
||||
PAL_code calls would be expensive. We can only trust that
|
||||
the compiler does its job and unifies the multiple
|
||||
__builtin_thread_pointer instances. */
|
||||
|
||||
#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))
|
||||
|
||||
/* Initializing the thread pointer will generate a SIGILL if the syscall
|
||||
is not available. */
|
||||
#define TLS_INIT_TP_EXPENSIVE 1
|
||||
|
||||
# endif /* HAVE_TLS_SUPPORT */
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
#endif /* tls.h */
|
51
sysdeps/arm/tls-macros.h
Normal file
51
sysdeps/arm/tls-macros.h
Normal file
@ -0,0 +1,51 @@
|
||||
#define TLS_LE(x) \
|
||||
({ int *__result; \
|
||||
void *tp = __builtin_thread_pointer (); \
|
||||
asm ("ldr %0, 1f; " \
|
||||
"add %0, %1, %0; " \
|
||||
"b 2f; " \
|
||||
"1: .word " #x "(tpoff); " \
|
||||
"2: " \
|
||||
: "=&r" (__result) : "r" (tp)); \
|
||||
__result; })
|
||||
|
||||
#define TLS_IE(x) \
|
||||
({ int *__result; \
|
||||
void *tp = __builtin_thread_pointer (); \
|
||||
asm ("ldr %0, 1f; " \
|
||||
"3: ldr %0, [pc, %0];" \
|
||||
"add %0, %1, %0; " \
|
||||
"b 2f; " \
|
||||
"1: .word " #x "(gottpoff) + (. - 3b - 8); " \
|
||||
"2: " \
|
||||
: "=&r" (__result) : "r" (tp)); \
|
||||
__result; })
|
||||
|
||||
#define TLS_LD(x) \
|
||||
({ char *__result; \
|
||||
int __offset; \
|
||||
extern void *__tls_get_addr (void *); \
|
||||
asm ("ldr %0, 2f; " \
|
||||
"1: add %0, pc, %0; " \
|
||||
"b 3f; " \
|
||||
"2: .word " #x "(tlsldm) + (. - 1b - 8); " \
|
||||
"3: " \
|
||||
: "=r" (__result)); \
|
||||
__result = (char *)__tls_get_addr (__result); \
|
||||
asm ("ldr %0, 1f; " \
|
||||
"b 2f; " \
|
||||
"1: .word " #x "(tlsldo); " \
|
||||
"2: " \
|
||||
: "=r" (__offset)); \
|
||||
(int *) (__result + __offset); })
|
||||
|
||||
#define TLS_GD(x) \
|
||||
({ int *__result; \
|
||||
extern void *__tls_get_addr (void *); \
|
||||
asm ("ldr %0, 2f; " \
|
||||
"1: add %0, pc, %0; " \
|
||||
"b 3f; " \
|
||||
"2: .word " #x "(tlsgd) + (. - 1b - 8); " \
|
||||
"3: " \
|
||||
: "=r" (__result)); \
|
||||
(int *)__tls_get_addr (__result); })
|
@ -1,3 +1,13 @@
|
||||
ifeq ($(subdir),csu)
|
||||
sysdep_routines += aeabi_read_tp libc-aeabi_read_tp
|
||||
static-only-routines += aeabi_read_tp
|
||||
shared-only-routines += libc-aeabi_read_tp
|
||||
endif
|
||||
|
||||
ifeq ($(subdir),elf)
|
||||
sysdep-rtld-routines += aeabi_read_tp
|
||||
endif
|
||||
|
||||
ifeq ($(subdir),misc)
|
||||
sysdep_routines += ioperm
|
||||
sysdep_headers += sys/elf.h sys/io.h
|
||||
|
34
sysdeps/unix/sysv/linux/arm/aeabi_read_tp.S
Normal file
34
sysdeps/unix/sysv/linux/arm/aeabi_read_tp.S
Normal file
@ -0,0 +1,34 @@
|
||||
/* Copyright (C) 2005 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. */
|
||||
|
||||
#include <sysdep.h>
|
||||
|
||||
#ifdef HAVE_TLS_SUPPORT
|
||||
|
||||
/* GCC will emit calls to this routine under -mtp=soft. Linux has an
|
||||
equivalent helper function (which clobbers fewer registers than
|
||||
a normal function call) in a high page of memory; tail call to the
|
||||
helper. */
|
||||
|
||||
.hidden __aeabi_read_tp
|
||||
ENTRY (__aeabi_read_tp)
|
||||
mov r0, #0xffff0fff
|
||||
sub pc, r0, #31
|
||||
END (__aeabi_read_tp)
|
||||
|
||||
#endif
|
1
sysdeps/unix/sysv/linux/arm/libc-aeabi_read_tp.S
Normal file
1
sysdeps/unix/sysv/linux/arm/libc-aeabi_read_tp.S
Normal file
@ -0,0 +1 @@
|
||||
#include <aeabi_read_tp.S>
|
@ -179,20 +179,28 @@ __local_syscall_error: \
|
||||
#undef INTERNAL_SYSCALL_DECL
|
||||
#define INTERNAL_SYSCALL_DECL(err) do { } while (0)
|
||||
|
||||
#undef INTERNAL_SYSCALL
|
||||
#define INTERNAL_SYSCALL(name, err, nr, args...) \
|
||||
#undef INTERNAL_SYSCALL_RAW
|
||||
#define INTERNAL_SYSCALL_RAW(name, err, nr, args...) \
|
||||
({ unsigned int _sys_result; \
|
||||
{ \
|
||||
register int _a1 asm ("a1"); \
|
||||
LOAD_ARGS_##nr (args) \
|
||||
asm volatile ("swi %1 @ syscall " #name \
|
||||
: "=r" (_a1) \
|
||||
: "i" (SYS_ify(name)) ASM_ARGS_##nr \
|
||||
: "i" (name) ASM_ARGS_##nr \
|
||||
: "memory"); \
|
||||
_sys_result = _a1; \
|
||||
} \
|
||||
(int) _sys_result; })
|
||||
|
||||
#undef INTERNAL_SYSCALL
|
||||
#define INTERNAL_SYSCALL(name, err, nr, args...) \
|
||||
INTERNAL_SYSCALL_RAW(SYS_ify(name), err, nr, args)
|
||||
|
||||
#undef INTERNAL_SYSCALL_ARM
|
||||
#define INTERNAL_SYSCALL_ARM(name, err, nr, args...) \
|
||||
INTERNAL_SYSCALL_RAW(__ARM_NR_##name, err, nr, args)
|
||||
|
||||
#undef INTERNAL_SYSCALL_ERROR_P
|
||||
#define INTERNAL_SYSCALL_ERROR_P(val, err) \
|
||||
((unsigned int) (val) >= 0xfffff001u)
|
||||
|
Loading…
Reference in New Issue
Block a user