PR ld/11458
authorHans-Peter Nilsson <hp@axis.com>
Wed, 31 Mar 2010 03:38:26 +0000 (03:38 +0000)
committerHans-Peter Nilsson <hp@axis.com>
Wed, 31 Mar 2010 03:38:26 +0000 (03:38 +0000)
* elf32-cris.c (elf_cris_copy_indirect_symbol): Remove invalid
assert of empty pcrel_relocs_copied on the direct symbol.  Instead
of moving the list from the indirect symbol to the direct symbol,
merge into any existing list.
(cris_elf_check_relocs): Store the original section in the
pcrel_relocs_copied list, not the relocation section.
(elf_cris_discard_excess_dso_dynamics): Adjust accordingly to find
the relocation section, for reducing its size.  Change the
BFD_ASSERT into a check for the section being read-only, and only
emit warnings and TEXTREL marker when there's an entry for a
read-only section.

bfd/ChangeLog
bfd/elf32-cris.c

index 770d00e..bdefe2a 100644 (file)
@@ -1,3 +1,18 @@
+2010-03-31  Hans-Peter Nilsson  <hp@axis.com>
+
+       PR ld/11458
+       * elf32-cris.c (elf_cris_copy_indirect_symbol): Remove invalid
+       assert of empty pcrel_relocs_copied on the direct symbol.  Instead
+       of moving the list from the indirect symbol to the direct symbol,
+       merge into any existing list.
+       (cris_elf_check_relocs): Store the original section in the
+       pcrel_relocs_copied list, not the relocation section.
+       (elf_cris_discard_excess_dso_dynamics): Adjust accordingly to find
+       the relocation section, for reducing its size.  Change the
+       BFD_ASSERT into a check for the section being read-only, and only
+       emit warnings and TEXTREL marker when there's an entry for a
+       read-only section.
+
 2010-03-29  Daniel Jacobowitz  <dan@codesourcery.com>
 
        * elf32-arm.c (using_thumb_only): Handle v6-M.
index 5fbaff6..83ef984 100644 (file)
@@ -3106,12 +3106,37 @@ elf_cris_copy_indirect_symbol (struct bfd_link_info *info,
       return;
     }
 
-  BFD_ASSERT (edir->pcrel_relocs_copied == NULL);
   BFD_ASSERT (edir->gotplt_offset == 0 || eind->gotplt_offset == 0);
 
 #define XMOVOPZ(F, OP, Z) edir->F OP eind->F; eind->F = Z
 #define XMOVE(F) XMOVOPZ (F, +=, 0)
-  XMOVOPZ (pcrel_relocs_copied, =, NULL);
+  if (eind->pcrel_relocs_copied != NULL)
+    {
+      if (edir->pcrel_relocs_copied != NULL)
+       {
+         struct elf_cris_pcrel_relocs_copied **pp;
+         struct elf_cris_pcrel_relocs_copied *p;
+
+         /* Add reloc counts against the indirect sym to the direct sym
+            list.  Merge any entries against the same section.  */
+         for (pp = &eind->pcrel_relocs_copied; *pp != NULL;)
+           {
+             struct elf_cris_pcrel_relocs_copied *q;
+             p = *pp;
+             for (q = edir->pcrel_relocs_copied; q != NULL; q = q->next)
+               if (q->section == p->section)
+                 {
+                   q->count += p->count;
+                   *pp = p->next;
+                   break;
+                 }
+             if (q == NULL)
+               pp = &p->next;
+           }
+         *pp = edir->pcrel_relocs_copied;
+       }
+      XMOVOPZ (pcrel_relocs_copied, =, NULL);
+    }
   XMOVE (gotplt_refcount);
   XMOVE (gotplt_offset);
   XMOVE (reg_got_refcount);
@@ -3682,7 +3707,7 @@ cris_elf_check_relocs (bfd *abfd,
            eh = elf_cris_hash_entry (h);
 
            for (p = eh->pcrel_relocs_copied; p != NULL; p = p->next)
-             if (p->section == sreloc)
+             if (p->section == sec)
                break;
 
            if (p == NULL)
@@ -3693,7 +3718,7 @@ cris_elf_check_relocs (bfd *abfd,
                  return FALSE;
                p->next = eh->pcrel_relocs_copied;
                eh->pcrel_relocs_copied = p;
-               p->section = sreloc;
+               p->section = sec;
                p->count = 0;
                p->r_type = r_type;
              }
@@ -3951,8 +3976,13 @@ elf_cris_discard_excess_dso_dynamics (h, inf)
          || info->symbolic))
     {
       for (s = h->pcrel_relocs_copied; s != NULL; s = s->next)
-       s->section->size -= s->count * sizeof (Elf32_External_Rela);
-
+       {
+         asection *sreloc
+           = _bfd_elf_get_dynamic_reloc_section (s->section->owner,
+                                                 s->section,
+                                                 /*rela?*/ TRUE);
+         sreloc->size -= s->count * sizeof (Elf32_External_Rela);
+       }
       return TRUE;
     }
 
@@ -3963,21 +3993,20 @@ elf_cris_discard_excess_dso_dynamics (h, inf)
      late).  */
 
   for (s = h->pcrel_relocs_copied; s != NULL; s = s->next)
-    {
-      BFD_ASSERT ((s->section->flags & SEC_READONLY) != 0);
-
-      /* FIXME: How do we make this optionally a warning only?  */
-      (*_bfd_error_handler)
-       (_("%B, section `%A', to symbol `%s':\n"
-          "  relocation %s should not be used"
-          " in a shared object; recompile with -fPIC"),
-        s->section->owner,
-        s->section,
-        h->root.root.root.string,
-        cris_elf_howto_table[s->r_type].name);
-
-      info->flags |= DF_TEXTREL;
-    }
+    if ((s->section->flags & SEC_READONLY) != 0)
+      {
+       /* FIXME: How do we make this optionally a warning only?  */
+       (*_bfd_error_handler)
+         (_("%B, section `%A', to symbol `%s':\n"
+            "  relocation %s should not be used"
+            " in a shared object; recompile with -fPIC"),
+          s->section->owner,
+          s->section,
+          h->root.root.root.string,
+          cris_elf_howto_table[s->r_type].name);
+
+       info->flags |= DF_TEXTREL;
+      }
 
   return TRUE;
 }