2003-03-02 Roland McGrath <roland@redhat.com>
authorroland <roland>
Mon, 3 Mar 2003 01:04:53 +0000 (01:04 +0000)
committerroland <roland>
Mon, 3 Mar 2003 01:04:53 +0000 (01:04 +0000)
* sysdeps/powerpc/powerpc32/dl-machine.c (_dl_reloc_overflow): Renamed
from dl_reloc_overflow, make global.
(__process_machine_rela): Update callers.
* sysdeps/powerpc/powerpc32/dl-machine.h: Declare _dl_reloc_overflow.
Add attribute_hidden to __process_machine_rela decl.
(elf_machine_type_class, elf_machine_rela): Handle 16-bit TLS relocs.

sysdeps/powerpc/powerpc32/dl-machine.c
sysdeps/powerpc/powerpc32/dl-machine.h

index 065a1db..866380a 100644 (file)
@@ -1,5 +1,5 @@
 /* Machine-dependent ELF dynamic relocation functions.  PowerPC version.
-   Copyright (C) 1995-2001, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1995-2001,2002,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
@@ -368,12 +368,12 @@ __elf_machine_fixup_plt(struct link_map *map, const Elf32_Rela *reloc,
   return finaladdr;
 }
 
-static void
-dl_reloc_overflow (struct link_map *map,
-                  const char *name,
-                  Elf32_Addr *const reloc_addr,
-                  const Elf32_Sym *sym,
-                  const Elf32_Sym *refsym)
+void
+_dl_reloc_overflow (struct link_map *map,
+                   const char *name,
+                   Elf32_Addr *const reloc_addr,
+                   const Elf32_Sym *sym,
+                   const Elf32_Sym *refsym)
 {
   char buffer[128];
   char *t;
@@ -423,19 +423,19 @@ __process_machine_rela (struct link_map *map,
 
     case R_PPC_ADDR24:
       if (__builtin_expect (finaladdr > 0x01fffffc && finaladdr < 0xfe000000, 0))
-       dl_reloc_overflow (map,  "R_PPC_ADDR24", reloc_addr, sym, refsym);
+       _dl_reloc_overflow (map,  "R_PPC_ADDR24", reloc_addr, sym, refsym);
       *reloc_addr = (*reloc_addr & 0xfc000003) | (finaladdr & 0x3fffffc);
       break;
 
     case R_PPC_ADDR16:
       if (__builtin_expect (finaladdr > 0x7fff && finaladdr < 0xffff8000, 0))
-       dl_reloc_overflow (map,  "R_PPC_ADDR16", reloc_addr, sym, refsym);
+       _dl_reloc_overflow (map,  "R_PPC_ADDR16", reloc_addr, sym, refsym);
       *(Elf32_Half*) reloc_addr = finaladdr;
       break;
 
     case R_PPC_UADDR16:
       if (__builtin_expect (finaladdr > 0x7fff && finaladdr < 0xffff8000, 0))
-       dl_reloc_overflow (map,  "R_PPC_UADDR16", reloc_addr, sym, refsym);
+       _dl_reloc_overflow (map,  "R_PPC_UADDR16", reloc_addr, sym, refsym);
       ((char *) reloc_addr)[0] = finaladdr >> 8;
       ((char *) reloc_addr)[1] = finaladdr;
       break;
@@ -456,7 +456,7 @@ __process_machine_rela (struct link_map *map,
     case R_PPC_ADDR14_BRTAKEN:
     case R_PPC_ADDR14_BRNTAKEN:
       if (__builtin_expect (finaladdr > 0x7fff && finaladdr < 0xffff8000, 0))
-       dl_reloc_overflow (map,  "R_PPC_ADDR14", reloc_addr, sym, refsym);
+       _dl_reloc_overflow (map,  "R_PPC_ADDR14", reloc_addr, sym, refsym);
       *reloc_addr = (*reloc_addr & 0xffff0003) | (finaladdr & 0xfffc);
       if (rinfo != R_PPC_ADDR14)
        *reloc_addr = ((*reloc_addr & 0xffdfffff)
@@ -468,7 +468,7 @@ __process_machine_rela (struct link_map *map,
       {
        Elf32_Sword delta = finaladdr - (Elf32_Word) reloc_addr;
        if (delta << 6 >> 6 != delta)
-         dl_reloc_overflow (map,  "R_PPC_REL24", reloc_addr, sym, refsym);
+         _dl_reloc_overflow (map,  "R_PPC_REL24", reloc_addr, sym, refsym);
        *reloc_addr = (*reloc_addr & 0xfc000003) | (delta & 0x3fffffc);
       }
       break;
index 39dbbb4..4da239d 100644 (file)
@@ -280,9 +280,8 @@ __elf_preferred_address(struct link_map *loader, size_t maplength,
 #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_DTPMOD32 /* contiguous TLS */  \
+       && (type) <= R_PPC_DTPREL32)                    \
     || (type) == R_PPC_ADDR24) * ELF_RTYPE_CLASS_PLT)  \
    | (((type) == R_PPC_COPY) * ELF_RTYPE_CLASS_COPY))
 #else
@@ -341,7 +340,14 @@ extern void __process_machine_rela (struct link_map *map,
                                    const Elf32_Sym *refsym,
                                    Elf32_Addr *const reloc_addr,
                                    Elf32_Addr finaladdr,
-                                   int rinfo);
+                                   int rinfo) attribute_hidden;
+
+/* Call _dl_signal_error when a resolved value overflows a relocated area.  */
+extern void _dl_reloc_overflow (struct link_map *map,
+                               const char *name,
+                               Elf32_Addr *const reloc_addr,
+                               const Elf32_Sym *sym,
+                               const Elf32_Sym *refsym) attribute_hidden;
 
 /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
    LOADADDR is the load address of the object; INFO is an array indexed
@@ -402,24 +408,59 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
        *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);
+
+# 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;
-    case R_PPC_TPREL32:
-# ifndef RTLD_BOOTSTRAP
-      if (sym_map)
+
+      inline void do_reloc32 (const char *r_name, Elf32_Addr value)
        {
-         CHECK_STATIC_TLS (map, sym_map);
-# endif
-         *reloc_addr = TLS_TPREL_VALUE (sym_map, sym, reloc);
-# ifndef RTLD_BOOTSTRAP
+         *reloc_addr = value;
        }
+    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