about summary refs log tree commit diff
path: root/sysdeps
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/powerpc/powerpc32/dl-machine.h117
-rwxr-xr-xsysdeps/powerpc/powerpc32/elf/configure57
-rw-r--r--sysdeps/powerpc/powerpc32/elf/configure.in42
-rw-r--r--sysdeps/powerpc/powerpc64/dl-machine.h220
4 files changed, 242 insertions, 194 deletions
diff --git a/sysdeps/powerpc/powerpc32/dl-machine.h b/sysdeps/powerpc/powerpc32/dl-machine.h
index 88408a4287..39dbbb412c 100644
--- a/sysdeps/powerpc/powerpc32/dl-machine.h
+++ b/sysdeps/powerpc/powerpc32/dl-machine.h
@@ -23,6 +23,7 @@
 #define ELF_MACHINE_NAME "powerpc"
 
 #include <assert.h>
+#include <dl-tls.h>
 
 /* Return nonzero iff ELF header is compatible with the running host.  */
 static inline int
@@ -275,11 +276,22 @@ __elf_preferred_address(struct link_map *loader, size_t maplength,
 /* We never want to use a PLT entry as the destination of a
    reloc, when what is being relocated is a branch. This is
    partly for efficiency, but mostly so we avoid loops.  */
+#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
+#define elf_machine_type_class(type)			\
+  ((((type) == R_PPC_JMP_SLOT				\
+    || (type) == R_PPC_REL24				\
+    || (type) == R_PPC_DTPMOD32				\
+    || (type) == R_PPC_DTPREL32				\
+    || (type) == R_PPC_TPREL32				\
+    || (type) == R_PPC_ADDR24) * ELF_RTYPE_CLASS_PLT)	\
+   | (((type) == R_PPC_COPY) * ELF_RTYPE_CLASS_COPY))
+#else
 #define elf_machine_type_class(type) \
   ((((type) == R_PPC_JMP_SLOT				\
     || (type) == R_PPC_REL24				\
     || (type) == R_PPC_ADDR24) * ELF_RTYPE_CLASS_PLT)	\
    | (((type) == R_PPC_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_PPC_JMP_SLOT
@@ -341,44 +353,29 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 		  Elf32_Addr *const reloc_addr)
 {
   const Elf32_Sym *const refsym = sym;
-  Elf32_Word finaladdr;
-  const int rinfo = ELF32_R_TYPE (reloc->r_info);
-
-#ifndef RESOLVE_CONFLICT_FIND_MAP
-  if (__builtin_expect (rinfo == R_PPC_NONE, 0))
-    return;
+  Elf32_Addr value;
+  const int r_type = ELF32_R_TYPE (reloc->r_info);
 
-  /* The condition on the next two lines is a hack around a bug in Solaris
-     tools on Sparc.  It's not clear whether it should really be here at all,
-     but if not the binutils need to be changed.  */
-  if (rinfo == R_PPC_RELATIVE
-      || (sym->st_shndx != SHN_UNDEF
-	  && ELF32_ST_BIND (sym->st_info) == STB_LOCAL))
+  if (r_type == R_PPC_RELATIVE)
     {
-      /* Has already been relocated.  */
-      Elf32_Word loadbase = map->l_addr;
-      finaladdr = loadbase + reloc->r_addend;
-    }
-  else
-    {
-      Elf32_Word loadbase
-	= (Elf32_Word) (char *) (RESOLVE (&sym, version,
-					  ELF32_R_TYPE(reloc->r_info)));
-      if (sym == NULL)
-	{
-	  /* Weak symbol that wasn't actually defined anywhere.  */
-	  assert (loadbase == 0);
-	  finaladdr = reloc->r_addend;
-	}
-      else
-	finaladdr = (loadbase + (Elf32_Word) (char *) sym->st_value
-		     + reloc->r_addend);
+      *reloc_addr = map->l_addr + reloc->r_addend;
+      return;
     }
+
+  if (__builtin_expect (r_type == R_PPC_NONE, 0))
+    return;
+
+#if defined USE_TLS && !defined RTLD_BOOTSTRAP
+  struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+  value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value;
 #else
-  finaladdr = reloc->r_addend;
-  if (rinfo == R_PPC_JMP_SLOT)
-    RESOLVE_CONFLICT_FIND_MAP (map, reloc_addr);
+  value = RESOLVE (&sym, version, r_type);
+# ifndef RTLD_BOOTSTRAP
+  if (sym != NULL)
+# endif
+    value += sym->st_value;
 #endif
+  value += reloc->r_addend;
 
   /* A small amount of code is duplicated here for speed.  In libc,
      more than 90% of the relocs are R_PPC_RELATIVE; in the X11 shared
@@ -386,15 +383,55 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
      R_PPC_ADDR32, and 16% are R_PPC_JMP_SLOT (which this routine
      wouldn't usually handle).  As an bonus, doing this here allows
      the switch statement in __process_machine_rela to work.  */
-  if (rinfo == R_PPC_RELATIVE
-      || rinfo == R_PPC_GLOB_DAT
-      || rinfo == R_PPC_ADDR32)
+  switch (r_type)
     {
-      *reloc_addr = finaladdr;
+    case R_PPC_GLOB_DAT:
+    case R_PPC_ADDR32:
+      *reloc_addr = value;
+      break;
+
+#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
+    case R_PPC_DTPMOD32:
+# 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
+	 RESOLVE_MAP function.  */
+      if (sym_map != NULL)
+	*reloc_addr = sym_map->l_tls_modid;
+# endif
+      break;
+    case R_PPC_DTPREL32:
+      /* During relocation all TLS symbols are defined and used.
+	 Therefore the offset is already correct.  */
+# ifndef RTLD_BOOTSTRAP
+      *reloc_addr = TLS_DTPREL_VALUE (sym, reloc);
+# endif
+      break;
+    case R_PPC_TPREL32:
+# ifndef RTLD_BOOTSTRAP
+      if (sym_map)
+	{
+	  CHECK_STATIC_TLS (map, sym_map);
+# endif
+	  *reloc_addr = TLS_TPREL_VALUE (sym_map, sym, reloc);
+# ifndef RTLD_BOOTSTRAP
+	}
+# endif
+      break;
+#endif /* USE_TLS etc. */
+
+#ifdef RESOLVE_CONFLICT_FIND_MAP
+    case R_PPC_JMP_SLOT:
+      RESOLVE_CONFLICT_FIND_MAP (map, reloc_addr);
+      /* FALLTHROUGH */
+#endif
+
+    default:
+      __process_machine_rela (map, reloc, sym, refsym,
+			      reloc_addr, value, r_type);
     }
-  else
-    __process_machine_rela (map, reloc, sym, refsym,
-			    reloc_addr, finaladdr, rinfo);
 }
 
 static inline void
diff --git a/sysdeps/powerpc/powerpc32/elf/configure b/sysdeps/powerpc/powerpc32/elf/configure
new file mode 100755
index 0000000000..c4bed2b8d5
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/elf/configure
@@ -0,0 +1,57 @@
+# This file is generated from configure.in by Autoconf.  DO NOT EDIT!
+ # Local configure fragment for sysdeps/powerpc32/elf.
+
+if test "$usetls" != no; then
+# Check for support of thread-local storage handling in assembler and
+# linker.
+echo "$as_me:$LINENO: checking for powerpc32 TLS support" >&5
+echo $ECHO_N "checking for powerpc32 TLS support... $ECHO_C" >&6
+if test "${libc_cv_powerpc32_tls+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat > conftest.s <<\EOF
+	.section ".tdata","awT",@progbits
+x:	.long	1
+x1:	.long	1
+x2:	.long	1
+	.text
+	addi	3,31,x@got@tlsgd
+	addi	3,31,x1@got@tlsld
+	addi	9,3,x1@dtprel
+	addis	9,3,x2@dtprel@ha
+	addi	9,9,x2@dtprel@l
+	lwz	0,x1@dtprel(3)
+	addis	9,3,x2@dtprel@ha
+	lwz	0,x2@dtprel@l(9)
+	lwz	9,x3@got@tprel(31)
+	add	9,9,x@tls
+	addi	9,2,x1@tprel
+	addis	9,2,x2@tprel@ha
+	addi	9,9,x2@tprel@l
+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_powerpc32_tls=yes
+else
+  libc_cv_powerpc32_tls=no
+fi
+rm -f conftest*
+fi
+echo "$as_me:$LINENO: result: $libc_cv_powerpc32_tls" >&5
+echo "${ECHO_T}$libc_cv_powerpc32_tls" >&6
+if test $libc_cv_powerpc32_tls = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_TLS_SUPPORT 1
+_ACEOF
+
+fi
+fi
+
+cat >>confdefs.h <<\_ACEOF
+#define PI_STATIC_AND_HIDDEN 1
+_ACEOF
+
diff --git a/sysdeps/powerpc/powerpc32/elf/configure.in b/sysdeps/powerpc/powerpc32/elf/configure.in
new file mode 100644
index 0000000000..97c300c20b
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/elf/configure.in
@@ -0,0 +1,42 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local configure fragment for sysdeps/powerpc32/elf.
+
+if test "$usetls" != no; then
+# Check for support of thread-local storage handling in assembler and
+# linker.
+AC_CACHE_CHECK(for powerpc32 TLS support, libc_cv_powerpc32_tls, [dnl
+cat > conftest.s <<\EOF
+	.section ".tdata","awT",@progbits
+x:	.long	1
+x1:	.long	1
+x2:	.long	1
+	.text
+	addi	3,31,x@got@tlsgd
+	addi	3,31,x1@got@tlsld
+	addi	9,3,x1@dtprel
+	addis	9,3,x2@dtprel@ha
+	addi	9,9,x2@dtprel@l
+	lwz	0,x1@dtprel(3)
+	addis	9,3,x2@dtprel@ha
+	lwz	0,x2@dtprel@l(9)
+	lwz	9,x3@got@tprel(31)
+	add	9,9,x@tls
+	addi	9,2,x1@tprel
+	addis	9,2,x2@tprel@ha
+	addi	9,9,x2@tprel@l
+EOF
+dnl
+if AC_TRY_COMMAND(${CC-cc} -c $CFLAGS conftest.s 1>&AS_MESSAGE_LOG_FD); then
+  libc_cv_powerpc32_tls=yes
+else
+  libc_cv_powerpc32_tls=no
+fi
+rm -f conftest*])
+if test $libc_cv_powerpc32_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.
+AC_DEFINE(PI_STATIC_AND_HIDDEN)
diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h
index e9cb54b685..87982638ee 100644
--- a/sysdeps/powerpc/powerpc64/dl-machine.h
+++ b/sysdeps/powerpc/powerpc64/dl-machine.h
@@ -330,12 +330,12 @@ elf_machine_dynamic (void)
    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))
+#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) \
   ((((type) == R_PPC64_ADDR24) * ELF_RTYPE_CLASS_PLT)	\
@@ -472,9 +472,6 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t sym_map,
   Elf64_FuncDesc *plt = (Elf64_FuncDesc *) reloc_addr;
   Elf64_FuncDesc *rel = (Elf64_FuncDesc *) finaladdr;
   Elf64_Addr offset = 0;
-#ifndef RTLD_BOOTSTRAP
-  weak_extern (GL(dl_rtld_map));
-#endif
 
   /* If sym_map is NULL, it's a weak undefined sym;  Leave the plt zero.  */
   if (sym_map == NULL)
@@ -483,7 +480,7 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t sym_map,
   /* If the opd entry is not yet relocated (because it's from a shared
      object that hasn't been processed yet), then manually reloc it.  */
   if (map != sym_map && !sym_map->l_relocated
-#ifndef RTLD_BOOTSTRAP
+#if !defined RTLD_BOOTSTRAP && defined SHARED
       /* Bootstrap map doesn't have l_relocated set for it.  */
       && sym_map != &GL(dl_rtld_map)
 #endif
@@ -528,7 +525,8 @@ elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
 #define PPC_HIGHERA(v) PPC_HIGHER ((v) + 0x8000)
 #define PPC_HIGHEST(v) (((v) >> 48) & 0xffff)
 #define PPC_HIGHESTA(v) PPC_HIGHEST ((v) + 0x8000)
-#define BIT_INSERT(old, val, mask) ((old & ~(Elf64_Addr) mask) | (val & mask))
+#define BIT_INSERT(var, val, mask) \
+  ((var) = ((var) & ~(Elf64_Addr) (mask) | ((val) & (mask))))
 
 #define dont_expect(X) __builtin_expect ((X), 0)
 
@@ -555,9 +553,9 @@ elf_machine_rela (struct link_map *map,
 		  const struct r_found_version *version,
 		  Elf64_Addr *const reloc_addr)
 {
-  int r_type = ELF64_R_TYPE (reloc->r_info);
+  const int r_type = ELF64_R_TYPE (reloc->r_info);
   struct link_map *sym_map;
-  Elf64_Addr value, raw_value;
+  Elf64_Addr value;
 #ifndef RTLD_BOOTSTRAP
   const Elf64_Sym *const refsym = sym;
 #endif
@@ -568,17 +566,23 @@ elf_machine_rela (struct link_map *map,
       return;
     }
 
-  if (r_type == R_PPC64_NONE)
+  if (__builtin_expect (r_type == R_PPC64_NONE, 0))
     return;
 
-  sym_map = RESOLVE_MAP (&sym, version, r_type);
-  value = raw_value = reloc->r_addend;
-  if (sym_map)
-    {
-      raw_value += sym->st_value;
-      value = raw_value + sym_map->l_addr;
-    }
+#if defined USE_TLS && !defined RTLD_BOOTSTRAP
+  struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+  value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value;
+#else
+  value = RESOLVE (&sym, version, r_type);
+# ifndef RTLD_BOOTSTRAP
+  if (sym != NULL)
+# endif
+    value += sym->st_value;
+#endif
+  value += reloc->r_addend;
 
+  /* For relocs that don't edit code, return.
+     For relocs that might edit instructions, break from the switch.  */
   switch (r_type)
     {
     case R_PPC64_ADDR64:
@@ -586,112 +590,63 @@ elf_machine_rela (struct link_map *map,
       *reloc_addr = value;
       return;
 
-#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
+    case R_PPC64_JMP_SLOT:
+#ifdef RESOLVE_CONFLICT_FIND_MAP
+      RESOLVE_CONFLICT_FIND_MAP (map, reloc_addr);
+#endif
+      elf_machine_fixup_plt (map, sym_map, reloc, reloc_addr, value);
+      return;
 
+#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
     case R_PPC64_DTPMOD64:
-#ifdef RTLD_BOOTSTRAP
+# ifdef RTLD_BOOTSTRAP
     /* During startup the dynamic linker is always index 1.  */
       *reloc_addr = 1;
-#else
+# else
     /* Get the information from the link map returned by the
        resolve function.  */
       if (sym_map != NULL)
 	*reloc_addr = sym_map->l_tls_modid;
-#endif
+# endif
       return;
 
-    case R_PPC64_TPREL64:
-#ifdef RTLD_BOOTSTRAP
-      *reloc_addr = (sym_map->l_tls_offset - TLS_TCB_SIZE
-		     + raw_value - TLS_TP_OFFSET);
-#else
+    case R_PPC_DTPREL64:
+      /* During relocation all TLS symbols are defined and used.
+	 Therefore the offset is already correct.  */
+# ifndef RTLD_BOOTSTRAP
+      *reloc_addr = TLS_DTPREL_VALUE (sym, reloc);
+# endif
+      break;
+    case R_PPC_TPREL64:
+# ifndef RTLD_BOOTSTRAP
       if (sym_map)
 	{
 	  CHECK_STATIC_TLS (map, sym_map);
-	  *reloc_addr = (sym_map->l_tls_offset - TLS_TCB_SIZE
-			 + raw_value - TLS_TP_OFFSET);
+# endif
+	  *reloc_addr = TLS_TPREL_VALUE (sym_map, sym, reloc);
+# ifndef RTLD_BOOTSTRAP
 	}
-#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 - TLS_DTV_OFFSET;
-#endif
-      return;
-#endif
-
-    case R_PPC64_JMP_SLOT:
-
-      elf_machine_fixup_plt (map, sym_map, reloc, reloc_addr, value);
-      return;
+# endif
+      break;
+#endif /* USE_TLS etc. */
 
 #ifndef RTLD_BOOTSTRAP /* None of the following appear in ld.so */
     case R_PPC64_ADDR16_LO_DS:
       if (dont_expect ((value & 3) != 0))
         _dl_reloc_overflow (map, "R_PPC64_ADDR16_LO_DS",
                             reloc_addr, sym, refsym);
-      *(Elf64_Half *) reloc_addr = BIT_INSERT (*(Elf64_Half *) reloc_addr,
-					       value, 0xfffc);
-      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);
+      BIT_INSERT (*(Elf64_Half *) reloc_addr, value, 0xfffc);
       break;
 
     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);
       break;
 
     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);
       break;
 
     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);
       break;
 
@@ -700,8 +655,7 @@ elf_machine_rela (struct link_map *map,
         Elf64_Addr delta = value - (Elf64_Xword) reloc_addr;
         if (dont_expect ((delta + 0x2000000) >= 0x4000000 || (delta & 3) != 0))
           _dl_reloc_overflow (map, "R_PPC64_REL24", reloc_addr, sym, refsym);
-        *(Elf64_Word *) reloc_addr = BIT_INSERT (*(Elf64_Word *) reloc_addr,
-                                                delta, 0x3fffffc);
+        BIT_INSERT (*(Elf64_Word *) reloc_addr, delta, 0x3fffffc);
       }
       break;
 
@@ -747,8 +701,7 @@ elf_machine_rela (struct link_map *map,
     case R_PPC64_ADDR24:
       if (dont_expect ((value + 0x2000000) >= 0x4000000 || (value & 3) != 0))
         _dl_reloc_overflow (map, "R_PPC64_ADDR24", reloc_addr, sym, refsym);
-      *(Elf64_Word *) reloc_addr = BIT_INSERT (*(Elf64_Word *) reloc_addr,
-					       value, 0x3fffffc);
+      BIT_INSERT (*(Elf64_Word *) reloc_addr, value, 0x3fffffc);
       break;
 
     case R_PPC64_ADDR16:
@@ -768,63 +721,22 @@ elf_machine_rela (struct link_map *map,
     case R_PPC64_ADDR16_DS:
       if (dont_expect ((value + 0x8000) >= 0x10000 || (value & 3) != 0))
         _dl_reloc_overflow (map, "R_PPC64_ADDR16_DS", reloc_addr, sym, refsym);
-      *(Elf64_Half *) reloc_addr = BIT_INSERT (*(Elf64_Half *) reloc_addr,
-					       value, 0xfffc);
-      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);
+      BIT_INSERT (*(Elf64_Half *) reloc_addr, value, 0xfffc);
       break;
 
     case R_PPC64_ADDR16_HIGHER:
-    case R_PPC64_TPREL16_HIGHER:
-    case R_PPC64_DTPREL16_HIGHER:
       *(Elf64_Half *) reloc_addr = PPC_HIGHER (value);
       break;
 
     case R_PPC64_ADDR16_HIGHEST:
-    case R_PPC64_TPREL16_HIGHEST:
-    case R_PPC64_DTPREL16_HIGHEST:
       *(Elf64_Half *) reloc_addr = PPC_HIGHEST (value);
       break;
 
     case R_PPC64_ADDR16_HIGHERA:
-    case R_PPC64_TPREL16_HIGHERA:
-    case R_PPC64_DTPREL16_HIGHERA:
       *(Elf64_Half *) reloc_addr = PPC_HIGHERA (value);
       break;
 
     case R_PPC64_ADDR16_HIGHESTA:
-    case R_PPC64_TPREL16_HIGHESTA:
-    case R_PPC64_DTPREL16_HIGHESTA:
       *(Elf64_Half *) reloc_addr = PPC_HIGHESTA (value);
       break;
 
@@ -832,20 +744,20 @@ elf_machine_rela (struct link_map *map,
     case R_PPC64_ADDR14_BRTAKEN:
     case R_PPC64_ADDR14_BRNTAKEN:
       {
-        Elf64_Word insn;
         if (dont_expect ((value + 0x8000) >= 0x10000 || (value & 3) != 0))
-	        _dl_reloc_overflow (map, "R_PPC64_ADDR14", reloc_addr, sym, refsym);
-        insn = BIT_INSERT (*(Elf64_Word *) reloc_addr, value, 0xfffc);
+	  _dl_reloc_overflow (map, "R_PPC64_ADDR14", reloc_addr, sym, refsym);
+        Elf64_Word insn = *(Elf64_Word *) reloc_addr;
+        BIT_INSERT (insn, value, 0xfffc);
         if (r_type != R_PPC64_ADDR14)
-	        {
-	          insn &= ~(1 << 21);
-	          if (r_type == R_PPC64_ADDR14_BRTAKEN)
-	            insn |= 1 << 21;
-	          if ((insn & (0x14 << 21)) == (0x04 << 21))
-	            insn |= 0x02 << 21;
-	          else if ((insn & (0x14 << 21)) == (0x10 << 21))
-	            insn |= 0x08 << 21;
-	        }
+	  {
+	    insn &= ~(1 << 21);
+	    if (r_type == R_PPC64_ADDR14_BRTAKEN)
+	      insn |= 1 << 21;
+	    if ((insn & (0x14 << 21)) == (0x04 << 21))
+	      insn |= 0x02 << 21;
+	    else if ((insn & (0x14 << 21)) == (0x10 << 21))
+	      insn |= 0x08 << 21;
+	  }
         *(Elf64_Word *) reloc_addr = insn;
       }
       break;