summaryrefslogtreecommitdiff
path: root/bfd/elf32-cris.c
diff options
context:
space:
mode:
authorHans-Peter Nilsson <hp@axis.com>2010-03-31 03:38:25 +0000
committerHans-Peter Nilsson <hp@axis.com>2010-03-31 03:38:25 +0000
commite8887bc925253187336a26dbaae1aa7aa441cfb8 (patch)
tree65047cb0ae22545c9798bf05ce9a8315ccfcbbf1 /bfd/elf32-cris.c
parentd05afe468f4371d8e95a6bc921054559f869fc5f (diff)
downloadbinutils-redhat-e8887bc925253187336a26dbaae1aa7aa441cfb8.tar.gz
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.
Diffstat (limited to 'bfd/elf32-cris.c')
-rw-r--r--bfd/elf32-cris.c71
1 files changed, 50 insertions, 21 deletions
diff --git a/bfd/elf32-cris.c b/bfd/elf32-cris.c
index 5fbaff6c88..83ef984a3e 100644
--- a/bfd/elf32-cris.c
+++ b/bfd/elf32-cris.c
@@ -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;
}