[BZ #17075] ARM: Fix immediate calculation of R_ARM_TLS_DESC
authorMaciej W. Rozycki <macro@codesourcery.com>
Fri, 20 Jun 2014 19:08:03 +0000 (20:08 +0100)
committerMaciej W. Rozycki <macro@codesourcery.com>
Fri, 20 Jun 2014 19:22:42 +0000 (20:22 +0100)
This fixes the calculation of R_ARM_TLS_DESC relocations for lazy global
symbol references, i.e. created with `-z lazy' in effect with the static
linker, where immediate resolution is requested with LD_BIND_NOW.

12 files changed:
ChangeLog
NEWS
sysdeps/arm/Makefile
sysdeps/arm/configure
sysdeps/arm/configure.ac
sysdeps/arm/dl-machine.h
sysdeps/arm/tst-armtlsdescextlazy.c [new file with mode: 0644]
sysdeps/arm/tst-armtlsdescextlazymod.c [new file with mode: 0644]
sysdeps/arm/tst-armtlsdescextnow.c [new file with mode: 0644]
sysdeps/arm/tst-armtlsdescextnowmod.c [new file with mode: 0644]
sysdeps/arm/tst-armtlsdescloc.c [new file with mode: 0644]
sysdeps/arm/tst-armtlsdesclocmod.c [new file with mode: 0644]

index 84f07d2048c2a9347ad791febc2e6c5c10e235a2..fbbd5d268925e0380d9eab1a20433b2223438af3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+2014-06-20  Maciej W. Rozycki  <macro@codesourcery.com>
+
+       [BZ #17075]
+       * sysdeps/arm/dl-machine.h (elf_machine_rel) <R_ARM_TLS_DESC>:
+       Fix calculation of the symbol's value.
+       * sysdeps/arm/tst-armtlsdescloc.c: New file.
+       * sysdeps/arm/tst-armtlsdesclocmod.c: New file.
+       * sysdeps/arm/tst-armtlsdescextnow.c: New file.
+       * sysdeps/arm/tst-armtlsdescextlazymod.c: New file.
+       * sysdeps/arm/tst-armtlsdescextlazy.c: New file.
+       * sysdeps/arm/tst-armtlsdescextnowmod.c: New file.
+       * sysdeps/arm/Makefile (tests): Add `tst-armtlsdesc',
+       `tst-armtlsdescextnow' and `tst-armtlsdescextlazy'.
+       (modules-names): Add `tst-armtlsdescmod',
+       `tst-armtlsdescextlazymod' and `tst-armtlsdescextnowmod'.
+       (CPPFLAGS-tst-armtlsdescextnowmod.c): New variable.
+       (CPPFLAGS-tst-armtlsdescextlazymod.c): Likewise.
+       (CFLAGS-tst-armtlsdesclocmod.c): Likewise.
+       (CFLAGS-tst-armtlsdescextnowmod.c): Likewise.
+       (CFLAGS-tst-armtlsdescextlazymod.c): Likewise.
+       (LDFLAGS-tst-armtlsdescextnowmod.so): Likewise.
+       ($(objpfx)tst-armtlsdescloc): New dependency.
+       ($(objpfx)tst-armtlsdescextnow): Likewise.
+       ($(objpfx)tst-armtlsdescextlazy): Likewise.
+       * sysdeps/arm/configure.ac: Add a check for tools' GNU descriptor
+       TLS scheme support.
+       * sysdeps/arm/configure: Regenerate.
+
 2014-06-20  Joseph Myers  <joseph@codesourcery.com>
 
        * include/fcntl.h (__atfct_seterrno): Remove prototype.
diff --git a/NEWS b/NEWS
index 9c2ba43ab49055af4f311d3f55d83b4f7d09d9a0..170aed2edb5b4e07a9eed77f791d584e18f9a87e 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -20,7 +20,7 @@ Version 2.20
   16854, 16876, 16877, 16878, 16882, 16885, 16888, 16890, 16912, 16915,
   16916, 16917, 16922, 16927, 16928, 16932, 16943, 16958, 16965, 16966,
   16967, 16977, 16978, 16984, 16990, 16996, 17009, 17022, 17031, 17042,
-  17048, 17058, 17062, 17069.
+  17048, 17058, 17062, 17069, 17075.
 
 * Optimized strchr implementation for AArch64.  Contributed by ARM Ltd.
 
index daaf4aa922a9297704a3e5c0945c0e650668eb98..a1380487b13498ac8f3abdc4aa8db466e312beeb 100644 (file)
@@ -11,6 +11,26 @@ $(objpfx)libgcc-stubs.a: $(objpfx)aeabi_unwind_cpp_pr1.os
        $(build-extra-lib)
 
 lib-noranlib: $(objpfx)libgcc-stubs.a
+
+ifeq ($(build-shared),yes)
+ifeq ($(have-arm-tls-desc),yes)
+tests += tst-armtlsdescloc tst-armtlsdescextnow tst-armtlsdescextlazy
+modules-names += tst-armtlsdesclocmod
+modules-names += tst-armtlsdescextlazymod tst-armtlsdescextnowmod
+CPPFLAGS-tst-armtlsdescextnowmod.c += -Dstatic=
+CPPFLAGS-tst-armtlsdescextlazymod.c += -Dstatic=
+CFLAGS-tst-armtlsdesclocmod.c += -mtls-dialect=gnu2
+CFLAGS-tst-armtlsdescextnowmod.c += -mtls-dialect=gnu2
+CFLAGS-tst-armtlsdescextlazymod.c += -mtls-dialect=gnu2
+LDFLAGS-tst-armtlsdescextnowmod.so += -Wl,-z,now
+tst-armtlsdescloc-ENV = LD_BIND_NOW=1
+tst-armtlsdescextnow-ENV = LD_BIND_NOW=1
+tst-armtlsdescextlazy-ENV = LD_BIND_NOW=1
+$(objpfx)tst-armtlsdescloc: $(objpfx)tst-armtlsdesclocmod.so
+$(objpfx)tst-armtlsdescextnow: $(objpfx)tst-armtlsdescextnowmod.so
+$(objpfx)tst-armtlsdescextlazy: $(objpfx)tst-armtlsdescextlazymod.so
+endif
+endif
 endif
 
 ifeq ($(subdir),csu)
index d79ef76ec91083d2c7725f88c35141a3b561736d..953ef4406dfadc1c04abfbba20687789c65b9424 100644 (file)
@@ -203,3 +203,39 @@ else
   config_vars="$config_vars
 default-abi = soft"
 fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the build tools support the GNU descriptor TLS scheme" >&5
+$as_echo_n "checking whether the build tools support the GNU descriptor TLS scheme... " >&6; }
+if ${libc_cv_arm_tls_desc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  old_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -mtls-dialect=gnu2"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+asm (".word\tfoo(tlsdesc)");
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  libc_cv_arm_tls_desc=yes
+else
+  libc_cv_arm_tls_desc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS="$old_CFLAGS"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_arm_tls_desc" >&5
+$as_echo "$libc_cv_arm_tls_desc" >&6; }
+if test $libc_cv_arm_tls_desc = yes; then
+  config_vars="$config_vars
+have-arm-tls-desc = yes"
+else
+  config_vars="$config_vars
+have-arm-tls-desc = no"
+fi
index d66500b3fd8fea809d483fb60380c8e3277888ee..fdc52c04082a0b931cb643cfe7646d0b1f2e574f 100644 (file)
@@ -44,3 +44,16 @@ if test $libc_cv_arm_pcs_vfp = yes; then
 else
   LIBC_CONFIG_VAR([default-abi], [soft])
 fi
+
+AC_CACHE_CHECK([whether the build tools support the GNU descriptor TLS scheme],
+  [libc_cv_arm_tls_desc],
+  [old_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -mtls-dialect=gnu2"
+  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([asm (".word\tfoo(tlsdesc)");], [])],
+    [libc_cv_arm_tls_desc=yes], [libc_cv_arm_tls_desc=no])
+  CFLAGS="$old_CFLAGS"])
+if test $libc_cv_arm_tls_desc = yes; then
+  LIBC_CONFIG_VAR([have-arm-tls-desc], [yes])
+else
+  LIBC_CONFIG_VAR([have-arm-tls-desc], [no])
+fi
index 899b2568f3c27dd46f7fbb5bd2ba036d199aad5c..c5ffc9304cff11ec2b6e212057ab39257b149466 100644 (file)
@@ -452,7 +452,10 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
            else
 # endif
              {
-               value = sym->st_value + td->argument.value;
+               if (ELF32_R_SYM (reloc->r_info) == STN_UNDEF)
+                 value = td->argument.value;
+               else
+                 value = sym->st_value;
 
 # ifndef RTLD_BOOTSTRAP
 #  ifndef SHARED
diff --git a/sysdeps/arm/tst-armtlsdescextlazy.c b/sysdeps/arm/tst-armtlsdescextlazy.c
new file mode 100644 (file)
index 0000000..36ae999
--- /dev/null
@@ -0,0 +1 @@
+#include "tst-armtlsdescloc.c"
diff --git a/sysdeps/arm/tst-armtlsdescextlazymod.c b/sysdeps/arm/tst-armtlsdescextlazymod.c
new file mode 100644 (file)
index 0000000..2cb8f8c
--- /dev/null
@@ -0,0 +1 @@
+#include "tst-armtlsdesclocmod.c"
diff --git a/sysdeps/arm/tst-armtlsdescextnow.c b/sysdeps/arm/tst-armtlsdescextnow.c
new file mode 100644 (file)
index 0000000..36ae999
--- /dev/null
@@ -0,0 +1 @@
+#include "tst-armtlsdescloc.c"
diff --git a/sysdeps/arm/tst-armtlsdescextnowmod.c b/sysdeps/arm/tst-armtlsdescextnowmod.c
new file mode 100644 (file)
index 0000000..2cb8f8c
--- /dev/null
@@ -0,0 +1 @@
+#include "tst-armtlsdesclocmod.c"
diff --git a/sysdeps/arm/tst-armtlsdescloc.c b/sysdeps/arm/tst-armtlsdescloc.c
new file mode 100644 (file)
index 0000000..730f1ba
--- /dev/null
@@ -0,0 +1,28 @@
+/* ARM immediate binding GNU TLS descriptor relocation test.
+   Copyright (C) 2014 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+int getfoo (void);
+
+int
+do_test (void)
+{
+  return getfoo ();
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/sysdeps/arm/tst-armtlsdesclocmod.c b/sysdeps/arm/tst-armtlsdesclocmod.c
new file mode 100644 (file)
index 0000000..a2d7eaf
--- /dev/null
@@ -0,0 +1,44 @@
+/* DSO used for ARM immediate binding GNU TLS descriptor relocation test.
+   Copyright (C) 2014 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+static int __thread bar = 1;
+static int __thread foo;
+
+int
+getfoo (void)
+{
+  return foo;
+}
+
+void
+setfoo (int i)
+{
+  foo = 1;
+}
+
+int
+getbar (void)
+{
+  return bar;
+}
+
+void
+setbar (int i)
+{
+  bar = 1;
+}