* elf64-alpha.c (elf64_alpha_check_relocs): No dynamic reloc for
authorRichard Henderson <rth@redhat.com>
Wed, 22 Jun 2011 16:18:24 +0000 (16:18 +0000)
committerRichard Henderson <rth@redhat.com>
Wed, 22 Jun 2011 16:18:24 +0000 (16:18 +0000)
        TPREL in a PIE image.
        (alpha_dynamic_entries_for_reloc): Likewise.
        (elf64_alpha_relocate_section): Allow TPREL in PIE images.
        (elf64_alpha_relax_got_load): Likewise.

bfd/ChangeLog
bfd/elf64-alpha.c

index 5084b7d..59cfd13 100644 (file)
@@ -1,3 +1,11 @@
+2011-06-22  Richard Henderson  <rth@redhat.com>
+
+       * elf64-alpha.c (elf64_alpha_check_relocs): No dynamic reloc for
+       TPREL in a PIE image.
+       (alpha_dynamic_entries_for_reloc): Likewise.
+       (elf64_alpha_relocate_section): Allow TPREL in PIE images.
+       (elf64_alpha_relax_got_load): Likewise.
+
 2011-06-22  Ramana Radhakrishnan  <ramana.radhakrishnan@linaro.org>
 
        * elf32-arm.c (elf32_arm_final_link_relocate): Allow R_ARM_TLS_LE32
index ee8ce5a..46078ea 100644 (file)
@@ -1882,10 +1882,13 @@ elf64_alpha_check_relocs (bfd *abfd, struct bfd_link_info *info,
          break;
 
        case R_ALPHA_TPREL64:
-         if (info->shared || maybe_dynamic)
+         if (info->shared && !info->pie)
+           {
+             info->flags |= DF_STATIC_TLS;
+             need = NEED_DYNREL;
+           }
+         else if (maybe_dynamic)
            need = NEED_DYNREL;
-         if (info->shared)
-           info->flags |= DF_STATIC_TLS;
          break;
        }
 
@@ -2651,7 +2654,7 @@ elf64_alpha_always_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
 /* The number of dynamic relocations required by a static relocation.  */
 
 static int
-alpha_dynamic_entries_for_reloc (int r_type, int dynamic, int shared)
+alpha_dynamic_entries_for_reloc (int r_type, int dynamic, int shared, int pie)
 {
   switch (r_type)
     {
@@ -2661,16 +2664,18 @@ alpha_dynamic_entries_for_reloc (int r_type, int dynamic, int shared)
     case R_ALPHA_TLSLDM:
       return shared;
     case R_ALPHA_LITERAL:
-    case R_ALPHA_GOTTPREL:
       return dynamic || shared;
+    case R_ALPHA_GOTTPREL:
+      return dynamic || (shared && !pie);
     case R_ALPHA_GOTDTPREL:
       return dynamic;
 
     /* May appear in data sections.  */
     case R_ALPHA_REFLONG:
     case R_ALPHA_REFQUAD:
-    case R_ALPHA_TPREL64:
       return dynamic || shared;
+    case R_ALPHA_TPREL64:
+      return dynamic || (shared && !pie);
 
     /* Everything else is illegal.  We'll issue an error during
        relocate_section.  */
@@ -2718,7 +2723,7 @@ elf64_alpha_calc_dynrel_sizes (struct alpha_elf_link_hash_entry *h,
   for (relent = h->reloc_entries; relent; relent = relent->next)
     {
       entries = alpha_dynamic_entries_for_reloc (relent->rtype, dynamic,
-                                                info->shared);
+                                                info->shared, info->pie);
       if (entries)
        {
          relent->srel->size +=
@@ -2761,8 +2766,8 @@ elf64_alpha_size_rela_got_1 (struct alpha_elf_link_hash_entry *h,
   entries = 0;
   for (gotent = h->got_entries; gotent ; gotent = gotent->next)
     if (gotent->use_count > 0)
-      entries += alpha_dynamic_entries_for_reloc (gotent->reloc_type,
-                                                 dynamic, info->shared);
+      entries += alpha_dynamic_entries_for_reloc (gotent->reloc_type, dynamic,
+                                                 info->shared, info->pie);
 
   if (entries > 0)
     {
@@ -2812,7 +2817,7 @@ elf64_alpha_size_rela_got_section (struct bfd_link_info *info)
                 gotent ; gotent = gotent->next)
              if (gotent->use_count > 0)
                entries += (alpha_dynamic_entries_for_reloc
-                           (gotent->reloc_type, 0, info->shared));
+                           (gotent->reloc_type, 0, info->shared, info->pie));
        }
     }
 
@@ -3044,7 +3049,8 @@ elf64_alpha_relax_got_load (struct alpha_relax_info *info, bfd_vma symval,
     return TRUE;
 
   /* Can't use local-exec relocations in shared libraries.  */
-  if (r_type == R_ALPHA_GOTTPREL && info->link_info->shared)
+  if (r_type == R_ALPHA_GOTTPREL
+      && (info->link_info->shared && !info->link_info->pie))
     return TRUE;
 
   if (r_type == R_ALPHA_LITERAL)
@@ -4509,7 +4515,7 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
            else if (r_type == R_ALPHA_TPREL64)
              {
                BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
-               if (!info->shared)
+               if (!info->shared || info->pie)
                  {
                    value -= tp_base;
                    goto default_reloc;
@@ -4630,7 +4636,7 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
        case R_ALPHA_TPRELHI:
        case R_ALPHA_TPRELLO:
        case R_ALPHA_TPREL16:
-         if (info->shared)
+         if (info->shared && !info->pie)
            {
              (*_bfd_error_handler)
                (_("%B: TLS local exec code cannot be linked into shared objects"),