2003-04-24 Jakub Jelinek <jakub@redhat.com>
authorRoland McGrath <roland@gnu.org>
Thu, 24 Apr 2003 17:10:52 +0000 (17:10 +0000)
committerRoland McGrath <roland@gnu.org>
Thu, 24 Apr 2003 17:10:52 +0000 (17:10 +0000)
* elf/dl-reloc.c (allocate_static_tls): Rename to...
(_dl_allocate_static_tls): ... this function.  No longer static.
(CHECK_STATIC_TLS): Adjust.
* sysdeps/generic/ldsodefs.h (_dl_allocate_static_tls): New prototype.
* sysdeps/powerpc/powerpc32/dl-machine.h (__process_machine_rela):
Add SYM_MAP argument.
(elf_machine_rela): Adjust caller.  Declare SYM_MAP unconditionally.
Check if SYM_MAP != NULL for R_PPC_DTPREL32.  Only handle 32-bit
TLS relocs here.  #ifdef out relocs which never appear in
.gnu.conflict section from dl-conflict.c processing.
* sysdeps/powerpc/powerpc32/dl-machine.c (__process_machine_rela):
Add SYM_MAP argument.  Handle 16-bit TLS relocs here.

elf/dl-reloc.c
sysdeps/generic/ldsodefs.h
sysdeps/powerpc/powerpc32/dl-machine.c
sysdeps/powerpc/powerpc32/dl-machine.h

index ad6c00c..e8e56c8 100644 (file)
@@ -41,8 +41,8 @@
    the static TLS area already allocated for each running thread.  If this
    object's TLS segment is too big to fit, we fail.  If it fits,
    we set MAP->l_tls_offset and return.  */
-static void __attribute_noinline__
-allocate_static_tls (struct link_map *map)
+void __attribute_noinline__
+_dl_allocate_static_tls (struct link_map *map)
 {
   size_t offset, used, check;
 
@@ -209,7 +209,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
 #define CHECK_STATIC_TLS(map, sym_map)                                       \
     do {                                                                     \
       if (__builtin_expect ((sym_map)->l_tls_offset == 0, 0))                \
-       allocate_static_tls (sym_map);                                        \
+       _dl_allocate_static_tls (sym_map);                                    \
     } while (0)
 
 #include "dynamic-link.h"
index 8be15b1..12151ce 100644 (file)
@@ -795,6 +795,9 @@ rtld_hidden_proto (_dl_allocate_tls)
 extern void _dl_get_tls_static_info (size_t *sizep, size_t *alignp)
      internal_function;
 
+extern void _dl_allocate_static_tls (struct link_map *map)
+     internal_function attribute_hidden;
+
 /* These are internal entry points to the two halves of _dl_allocate_tls,
    only used within rtld.c itself at startup time.  */
 extern void *_dl_allocate_tls_storage (void)
index 866380a..2e071c8 100644 (file)
@@ -397,6 +397,7 @@ _dl_reloc_overflow (struct link_map *map,
 void
 __process_machine_rela (struct link_map *map,
                        const Elf32_Rela *reloc,
+                       struct link_map *sym_map,
                        const Elf32_Sym *sym,
                        const Elf32_Sym *refsym,
                        Elf32_Addr *const reloc_addr,
@@ -541,6 +542,53 @@ __process_machine_rela (struct link_map *map,
       }
       break;
 
+#ifdef USE_TLS
+#define CHECK_STATIC_TLS(map, sym_map)                                       \
+    do {                                                                     \
+      if (__builtin_expect ((sym_map)->l_tls_offset == NO_TLS_OFFSET, 0))     \
+       _dl_allocate_static_tls (sym_map);                                    \
+    } while (0)
+# define DO_TLS_RELOC(suffix)                                                \
+    case R_PPC_DTPREL##suffix:                                               \
+      /* During relocation all TLS symbols are defined and used.             \
+        Therefore the offset is already correct.  */                         \
+      if (sym_map != NULL)                                                   \
+       do_reloc##suffix ("R_PPC_DTPREL"#suffix,                              \
+                         TLS_DTPREL_VALUE (sym, reloc));                     \
+      break;                                                                 \
+    case R_PPC_TPREL##suffix:                                                \
+      if (sym_map != NULL)                                                   \
+       {                                                                     \
+         CHECK_STATIC_TLS (map, sym_map);                                    \
+         do_reloc##suffix ("R_PPC_TPREL"#suffix,                             \
+                           TLS_TPREL_VALUE (sym_map, sym, reloc));           \
+       }                                                                     \
+      break;
+
+    inline void do_reloc16 (const char *r_name, Elf32_Addr value)
+      {
+       if (__builtin_expect (value > 0x7fff && value < 0xffff8000, 0))
+         _dl_reloc_overflow (map, r_name, reloc_addr, sym, refsym);
+       *(Elf32_Half *) reloc_addr = value;
+      }
+    inline void do_reloc16_LO (const char *r_name, Elf32_Addr value)
+      {
+       *(Elf32_Half *) reloc_addr = value;
+      }
+    inline void do_reloc16_HI (const char *r_name, Elf32_Addr value)
+      {
+       *(Elf32_Half *) reloc_addr = value >> 16;
+      }
+    inline void do_reloc16_HA (const char *r_name, Elf32_Addr value)
+      {
+       *(Elf32_Half *) reloc_addr = (value + 0x8000) >> 16;
+      }
+    DO_TLS_RELOC (16)
+    DO_TLS_RELOC (16_LO)
+    DO_TLS_RELOC (16_HI)
+    DO_TLS_RELOC (16_HA)
+#endif
+
     default:
       _dl_reloc_bad_type (map, rinfo, 0);
       return;
index 2f35275..e26c2d5 100644 (file)
@@ -336,6 +336,7 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
    has been determined.  */
 extern void __process_machine_rela (struct link_map *map,
                                    const Elf32_Rela *reloc,
+                                   struct link_map *sym_map,
                                    const Elf32_Sym *sym,
                                    const Elf32_Sym *refsym,
                                    Elf32_Addr *const reloc_addr,
@@ -361,9 +362,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
   const Elf32_Sym *const refsym = sym;
   Elf32_Addr value;
   const int r_type = ELF32_R_TYPE (reloc->r_info);
-#if defined USE_TLS && !defined RTLD_BOOTSTRAP
-  struct link_map *sym_map;
-#endif
+  struct link_map *sym_map = NULL;
 
 #ifndef RESOLVE_CONFLICT_FIND_MAP
   if (r_type == R_PPC_RELATIVE)
@@ -411,71 +410,37 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
       *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;
-
+#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) \
+    && !defined RESOLVE_CONFLICT_FIND_MAP
 # ifdef RTLD_BOOTSTRAP
 #  define NOT_BOOTSTRAP 0
 # else
 #  define NOT_BOOTSTRAP 1
 # endif
-# define DO_TLS_RELOC(suffix)                                                \
-    case R_PPC_DTPREL##suffix:                                               \
-      /* During relocation all TLS symbols are defined and used.             \
-        Therefore the offset is already correct.  */                         \
-      if (NOT_BOOTSTRAP)                                                     \
-       do_reloc##suffix ("R_PPC_DTPREL"#suffix,                              \
-                         TLS_DTPREL_VALUE (sym, reloc));                     \
-      break;                                                                 \
-    case R_PPC_TPREL##suffix:                                                \
-      if (!NOT_BOOTSTRAP || sym_map)                                         \
-       {                                                                     \
-         if (NOT_BOOTSTRAP)                                                  \
-           CHECK_STATIC_TLS (map, sym_map);                                  \
-         do_reloc##suffix ("R_PPC_TPREL"#suffix,                             \
-                           TLS_TPREL_VALUE (sym_map, sym, reloc));           \
-       }                                                                     \
-      break;
 
-      inline void do_reloc32 (const char *r_name, Elf32_Addr value)
+    case R_PPC_DTPMOD32:
+      if (!NOT_BOOTSTRAP)
+       /* During startup the dynamic linker is always index 1.  */
+       *reloc_addr = 1;
+      else if (sym_map != NULL)
+       /* Get the information from the link map returned by the
+          RESOLVE_MAP function.  */
+       *reloc_addr = sym_map->l_tls_modid;
+      break;
+    case R_PPC_DTPREL32:
+      /* During relocation all TLS symbols are defined and used.
+        Therefore the offset is already correct.  */
+      if (NOT_BOOTSTRAP && sym_map != NULL)
+       *reloc_addr = TLS_DTPREL_VALUE (sym, reloc);
+      break;
+    case R_PPC_TPREL32:
+      if (!NOT_BOOTSTRAP || sym_map != NULL)
        {
-         *reloc_addr = value;
+         if (NOT_BOOTSTRAP)
+           CHECK_STATIC_TLS (map, sym_map);
+         *reloc_addr = TLS_TPREL_VALUE (sym_map, sym, reloc);
        }
-    DO_TLS_RELOC (32)
-# ifndef RTLD_BOOTSTRAP                /* PIC code like ld.so doesn't use these.  */
-    inline void do_reloc16 (const char *r_name, Elf32_Addr value)
-      {
-       if (__builtin_expect (value > 0x7fff && value < 0xffff8000, 0))
-         _dl_reloc_overflow (map,  "R_PPC_ADDR16", reloc_addr, sym, refsym);
-       *(Elf32_Half *) reloc_addr = value;
-      }
-    inline void do_reloc16_LO (const char *r_name, Elf32_Addr value)
-      {
-       *(Elf32_Half *) reloc_addr = value;
-      }
-    inline void do_reloc16_HI (const char *r_name, Elf32_Addr value)
-      {
-       *(Elf32_Half *) reloc_addr = value >> 16;
-      }
-    inline void do_reloc16_HA (const char *r_name, Elf32_Addr value)
-      {
-       *(Elf32_Half *) reloc_addr = (value + 0x8000) >> 16;
-      }
-    DO_TLS_RELOC (16)
-    DO_TLS_RELOC (16_LO)
-    DO_TLS_RELOC (16_HI)
-    DO_TLS_RELOC (16_HA)
-# endif
+      break;
 #endif /* USE_TLS etc. */
 
 #ifdef RESOLVE_CONFLICT_FIND_MAP
@@ -485,7 +450,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 #endif
 
     default:
-      __process_machine_rela (map, reloc, sym, refsym,
+      __process_machine_rela (map, reloc, sym_map, sym, refsym,
                              reloc_addr, value, r_type);
     }
 }