* elf32-arm.h (struct elf32_arm_relocs_copied): Remove pc_count.
authorDaniel Jacobowitz <drow@false.org>
Fri, 9 Jan 2004 16:53:45 +0000 (16:53 +0000)
committerDaniel Jacobowitz <drow@false.org>
Fri, 9 Jan 2004 16:53:45 +0000 (16:53 +0000)
(elf32_arm_copy_indirect_symbol): Don't copy pc_count.
(elf32_arm_final_link_relocate): Handle PLT32 and PC24 relocs
identically.  Do not emit PC24 relocations for shared libraries.
(elf32_arm_gc_sweep_hook): Handle PLT32 and PC24 relocs
identically.  Don't adjust pc_count.
(elf32_arm_check_relocs): Handle PLT32 and PC24 relocs identically.
Set ELF_LINK_HASH_NEEDS_PLT for both.  Don't adjust pc_count; don't
adjust count for branch relocations.
(allocate_dynrelocs): Correct typo in call to
WILL_CALL_FINISH_DYNAMIC_SYMBOL.  Never allocate space for
PC24 or PLT32 relocs when linking.

bfd/ChangeLog
bfd/elf32-arm.h

index 1fada0c1c8bf8a5fa4c80bb9b230f02840f60d87..110f28a089a67a06a1276d5833c6f3239f553bbc 100644 (file)
@@ -1,3 +1,18 @@
+2004-01-09  Daniel Jacobowitz  <drow@mvista.com>
+
+       * elf32-arm.h (struct elf32_arm_relocs_copied): Remove pc_count.
+       (elf32_arm_copy_indirect_symbol): Don't copy pc_count.
+       (elf32_arm_final_link_relocate): Handle PLT32 and PC24 relocs
+       identically.  Do not emit PC24 relocations for shared libraries.
+       (elf32_arm_gc_sweep_hook): Handle PLT32 and PC24 relocs
+       identically.  Don't adjust pc_count.
+       (elf32_arm_check_relocs): Handle PLT32 and PC24 relocs identically.
+       Set ELF_LINK_HASH_NEEDS_PLT for both.  Don't adjust pc_count; don't
+       adjust count for branch relocations.
+       (allocate_dynrelocs): Correct typo in call to
+       WILL_CALL_FINISH_DYNAMIC_SYMBOL.  Never allocate space for
+       PC24 or PLT32 relocs when linking.
+
 2004-01-09  Dmitry Semyonov  <Dmitry.Semyonov@oktet.ru>
 
        * coff-arm.c (aoutarm_std_reloc_howto): [ARM_WINCE] Synchronize ARM_26D
index d42eb27f5a5af064cea4f5e937e46449e5f55671..a684546eb2687aaeb988b157528d53a9fdeb3354 100644 (file)
@@ -205,8 +205,6 @@ struct elf32_arm_relocs_copied
     asection * section;
     /* Number of relocs copied in this section.  */
     bfd_size_type count;
-    /* Number of relocs copied in this section.  */
-    bfd_size_type pc_count;
   };
 
 /* Arm ELF linker hash entry.  */
@@ -383,7 +381,6 @@ elf32_arm_copy_indirect_symbol (const struct elf_backend_data *bed,
              for (q = edir->relocs_copied; q != NULL; q = q->next)
                if (q->section == p->section)
                  {
-                   q->pc_count += p->pc_count;
                    q->count += p->count;
                    *pp = p->next;
                    break;
@@ -1307,21 +1304,41 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
 #ifndef OLD_ARM_ABI
     case R_ARM_XPC25:
 #endif
+    case R_ARM_PLT32:
       /* r_symndx will be zero only for relocs against symbols
         from removed linkonce sections, or sections discarded by
         a linker script.  */
       if (r_symndx == 0)
        return bfd_reloc_ok;
 
+      /* Handle relocations which should use the PLT entry.  ABS32/REL32
+        will use the symbol's value, which may point to a PLT entry, but we
+        don't need to handle that here.  If we created a PLT entry, all
+        branches in this object should go to it.  */
+      if ((r_type != R_ARM_ABS32 && r_type != R_ARM_REL32)
+         && h != NULL
+         && h->plt.offset != (bfd_vma) -1)
+       {
+         BFD_ASSERT (splt != NULL);
+         BFD_ASSERT (!SYMBOL_CALLS_LOCAL (info, h));
+
+         value = (splt->output_section->vma
+                  + splt->output_offset
+                  + h->plt.offset);
+         return _bfd_final_link_relocate (howto, input_bfd, input_section,
+                                          contents, rel->r_offset, value,
+                                          (bfd_vma) 0);
+       }
+
       /* When generating a shared object, these relocations are copied
         into the output file to be resolved at run time.  */
-      if ((info->shared
-          && (input_section->flags & SEC_ALLOC)
-          && (h == NULL
-              || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
-              || h->root.type != bfd_link_hash_undefweak)
-          && (r_type != R_ARM_PC24
-              || !SYMBOL_CALLS_LOCAL (info, h))))
+      if (info->shared
+         && (input_section->flags & SEC_ALLOC)
+         && (h == NULL
+             || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+             || h->root.type != bfd_link_hash_undefweak)
+         && r_type != R_ARM_PC24
+         && r_type != R_ARM_PLT32)
        {
          Elf_Internal_Rela outrel;
          bfd_byte *loc;
@@ -1364,8 +1381,7 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
            memset (&outrel, 0, sizeof outrel);
          else if (h != NULL
                   && h->dynindx != -1
-                  && (r_type == R_ARM_PC24
-                      || !info->shared
+                  && (!info->shared
                       || !info->symbolic
                       || (h->elf_link_hash_flags
                           & ELF_LINK_HASH_DEF_REGULAR) == 0))
@@ -1397,6 +1413,7 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
        case R_ARM_XPC25:         /* Arm BLX instruction.  */
 #endif
        case R_ARM_PC24:          /* Arm B/BL instruction */
+       case R_ARM_PLT32:
 #ifndef OLD_ARM_ABI
          if (r_type == R_ARM_XPC25)
            {
@@ -1869,37 +1886,6 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
                                       contents, rel->r_offset, value,
                                       (bfd_vma) 0);
 
-    case R_ARM_PLT32:
-      /* Relocation is to the entry for this symbol in the
-         procedure linkage table.  */
-
-      /* Resolve a PLT32 reloc against a local symbol directly,
-         without using the procedure linkage table.  */
-      if (h == NULL)
-        return _bfd_final_link_relocate (howto, input_bfd, input_section,
-                                contents, rel->r_offset, value,
-                                (bfd_vma) 0);
-
-      if (h->plt.offset == (bfd_vma) -1
-         || globals->splt == NULL)
-        /* We didn't make a PLT entry for this symbol.  This
-           happens when statically linking PIC code, or when
-           using -Bsymbolic.  */
-       return _bfd_final_link_relocate (howto, input_bfd, input_section,
-                                        contents, rel->r_offset, value,
-                                        (bfd_vma) 0);
-
-      BFD_ASSERT(splt != NULL);
-      if (splt == NULL)
-        return bfd_reloc_notsupported;
-
-      value = (splt->output_section->vma
-              + splt->output_offset
-              + h->plt.offset);
-      return _bfd_final_link_relocate (howto, input_bfd, input_section,
-                              contents, rel->r_offset, value,
-                              (bfd_vma) 0);
-
     case R_ARM_SBREL32:
       return bfd_reloc_notsupported;
 
@@ -2808,6 +2794,7 @@ elf32_arm_gc_sweep_hook (abfd, info, sec, relocs)
       case R_ARM_ABS32:
       case R_ARM_REL32:
       case R_ARM_PC24:
+      case R_ARM_PLT32:
        r_symndx = ELF32_R_SYM (rel->r_info);
        if (r_symndx >= symtab_hdr->sh_info)
          {
@@ -2817,31 +2804,24 @@ elf32_arm_gc_sweep_hook (abfd, info, sec, relocs)
 
            h = sym_hashes[r_symndx - symtab_hdr->sh_info];
 
-           if (!info->shared && h->plt.refcount > 0)
+           if (h->plt.refcount > 0)
              h->plt.refcount -= 1;
 
-           eh = (struct elf32_arm_link_hash_entry *) h;
-
-           for (pp = &eh->relocs_copied; (p = *pp) != NULL; pp = &p->next)
-             if (p->section == sec)
-               {
-                 if (ELF32_R_TYPE (rel->r_info) == R_ARM_PC24)
-                   p->pc_count -= 1;
-                 p->count -= 1;
-                 if (p->count == 0)
-                   *pp = p->next;
-                 break;
-               }
-         }
-       break;
+           if (ELF32_R_TYPE (rel->r_info) == R_ARM_ABS32
+               || ELF32_R_TYPE (rel->r_info) == R_ARM_REL32)
+             {
+               eh = (struct elf32_arm_link_hash_entry *) h;
 
-      case R_ARM_PLT32:
-       r_symndx = ELF32_R_SYM (rel->r_info);
-       if (r_symndx >= symtab_hdr->sh_info)
-         {
-           h = sym_hashes[r_symndx - symtab_hdr->sh_info];
-           if (h->plt.refcount > 0)
-             h->plt.refcount -= 1;
+               for (pp = &eh->relocs_copied; (p = *pp) != NULL;
+                    pp = &p->next)
+               if (p->section == sec)
+                 {
+                   p->count -= 1;
+                   if (p->count == 0)
+                     *pp = p->next;
+                   break;
+                 }
+             }
          }
        break;
 
@@ -2902,23 +2882,6 @@ elf32_arm_check_relocs (abfd, info, sec, relocs)
 
       switch (ELF32_R_TYPE (rel->r_info))
         {
-         case R_ARM_PLT32:
-           /* This symbol requires a procedure linkage table entry.  We
-               actually build the entry in adjust_dynamic_symbol,
-               because this might be a case of linking PIC code which is
-               never referenced by a dynamic object, in which case we
-               don't need to generate a procedure linkage table entry
-               after all.  */
-
-           /* If this is a local symbol, we resolve it directly without
-               creating a procedure linkage table entry.  */
-           if (h == NULL)
-             continue;
-
-           h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
-           h->plt.refcount++;
-           break;
-
          case R_ARM_GOT32:
            /* This symbol requires a global offset table entry.  */
            if (h != NULL)
@@ -2961,7 +2924,8 @@ elf32_arm_check_relocs (abfd, info, sec, relocs)
          case R_ARM_ABS32:
          case R_ARM_REL32:
          case R_ARM_PC24:
-           if (h != NULL && !info->shared)
+         case R_ARM_PLT32:
+           if (h != NULL)
              {
                /* If this reloc is in a read-only section, we might
                   need a copy reloc.  We can't check reliably at this
@@ -2969,10 +2933,15 @@ elf32_arm_check_relocs (abfd, info, sec, relocs)
                   sections have not yet been mapped to output sections.
                   Tentatively set the flag for now, and correct in
                   adjust_dynamic_symbol.  */
-               h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF;
-               
+               if (!info->shared)
+                 h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF;
+
                /* We may need a .plt entry if the function this reloc
-                  refers to is in a shared lib.  */
+                  refers to is in a different object.  */
+               if (ELF32_R_TYPE (rel->r_info) == R_ARM_PC24
+                   || ELF32_R_TYPE (rel->r_info) == R_ARM_PLT32)
+                 h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+
                h->plt.refcount += 1;
              }
 
@@ -2990,7 +2959,8 @@ elf32_arm_check_relocs (abfd, info, sec, relocs)
                relocs_copied field of the hash table entry.  */
            if (info->shared
                && (sec->flags & SEC_ALLOC) != 0
-               && (ELF32_R_TYPE (rel->r_info) != R_ARM_PC24
+               && ((ELF32_R_TYPE (rel->r_info) != R_ARM_PC24
+                    && ELF32_R_TYPE (rel->r_info) != R_ARM_PLT32)
                    || (h != NULL
                        && (! info->symbolic
                            || (h->elf_link_hash_flags
@@ -3068,12 +3038,11 @@ elf32_arm_check_relocs (abfd, info, sec, relocs)
                    *head = p;
                    p->section = sec;
                    p->count = 0;
-                   p->pc_count = 0;
                  }
                
-               p->count += 1;
-               if (ELF32_R_TYPE (rel->r_info) == R_ARM_PC24)
-                 p->pc_count += 1;
+               if (ELF32_R_TYPE (rel->r_info) == R_ARM_ABS32
+                   || ELF32_R_TYPE (rel->r_info) == R_ARM_REL32)
+                 p->count += 1;
              }
            break;
 
@@ -3348,7 +3317,7 @@ allocate_dynrelocs (h, inf)
        }
 
       if (info->shared
-         || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info, h))
+         || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
        {
          asection *s = htab->splt;
 
@@ -3432,29 +3401,8 @@ allocate_dynrelocs (h, inf)
 
   if (info->shared)
     {
-      /* The only reloc that uses pc_count is R_ARM_PC24, which will
-        appear on a call or on something like ".long foo - .".  We
-        want calls to protected symbols to resolve directly to the
-        function rather than going via the plt.  If people want
-        function pointer comparisons to work as expected then they
-        should avoid writing assembly like ".long foo - .".  */
-      if (SYMBOL_CALLS_LOCAL (info, h))
-       {
-         struct elf32_arm_relocs_copied **pp;
-
-         for (pp = &eh->relocs_copied; (p = *pp) != NULL; )
-           {
-             p->count -= p->pc_count;
-             p->pc_count = 0;
-             if (p->count == 0)
-               *pp = p->next;
-             else
-               pp = &p->next;
-           }
-       }
-
-      /* Also discard relocs on undefined weak syms with non-default
-        visibility.  */
+      /* Discard relocs on undefined weak syms with non-default
+         visibility.  */
       if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
          && h->root.type == bfd_link_hash_undefweak)
        eh->relocs_copied = NULL;