* elf64-ppc.c (ppc64_elf_edit_toc): Account for dynamic relocs

that we no longer need.
This commit is contained in:
Alan Modra 2005-04-01 02:50:15 +00:00
parent 77623a344f
commit 3509047186
2 changed files with 106 additions and 0 deletions

View File

@ -1,3 +1,8 @@
2005-04-01 Alan Modra <amodra@bigpond.net.au>
* elf64-ppc.c (ppc64_elf_edit_toc): Account for dynamic relocs
that we no longer need.
2005-04-01 Alan Modra <amodra@bigpond.net.au>
* elf64-ppc.c (ppc64_elf_get_synthetic_symtab): Return -1 on errors

View File

@ -7056,6 +7056,107 @@ ppc64_elf_edit_toc (bfd *obfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
wrel->r_addend = rel->r_addend;
++wrel;
}
else
{
unsigned long r_symndx;
enum elf_ppc64_reloc_type r_type;
asection *sym_sec;
struct elf_link_hash_entry *h;
Elf_Internal_Sym *sym;
struct ppc_dyn_relocs *p;
struct ppc_dyn_relocs **head;
/* Can this reloc be dynamic?
This switch, and later tests here should be kept
in sync with the code in check_relocs. */
r_type = ELF64_R_TYPE (rel->r_info);
switch (r_type)
{
default:
continue;
case R_PPC64_TPREL16:
case R_PPC64_TPREL16_LO:
case R_PPC64_TPREL16_HI:
case R_PPC64_TPREL16_HA:
case R_PPC64_TPREL16_DS:
case R_PPC64_TPREL16_LO_DS:
case R_PPC64_TPREL16_HIGHER:
case R_PPC64_TPREL16_HIGHERA:
case R_PPC64_TPREL16_HIGHEST:
case R_PPC64_TPREL16_HIGHESTA:
if (!info->shared)
continue;
case R_PPC64_TPREL64:
case R_PPC64_DTPMOD64:
case R_PPC64_DTPREL64:
case R_PPC64_ADDR64:
case R_PPC64_REL30:
case R_PPC64_REL32:
case R_PPC64_REL64:
case R_PPC64_ADDR14:
case R_PPC64_ADDR14_BRNTAKEN:
case R_PPC64_ADDR14_BRTAKEN:
case R_PPC64_ADDR16:
case R_PPC64_ADDR16_DS:
case R_PPC64_ADDR16_HA:
case R_PPC64_ADDR16_HI:
case R_PPC64_ADDR16_HIGHER:
case R_PPC64_ADDR16_HIGHERA:
case R_PPC64_ADDR16_HIGHEST:
case R_PPC64_ADDR16_HIGHESTA:
case R_PPC64_ADDR16_LO:
case R_PPC64_ADDR16_LO_DS:
case R_PPC64_ADDR24:
case R_PPC64_ADDR32:
case R_PPC64_UADDR16:
case R_PPC64_UADDR32:
case R_PPC64_UADDR64:
case R_PPC64_TOC:
break;
}
r_symndx = ELF64_R_SYM (rel->r_info);
if (!get_sym_h (&h, &sym, &sym_sec, NULL, &local_syms,
r_symndx, ibfd))
goto error_ret;
if ((info->shared
&& (MUST_BE_DYN_RELOC (r_type)
|| (h != NULL
&& (!info->symbolic
|| h->root.type == bfd_link_hash_defweak
|| !h->def_regular))))
|| (ELIMINATE_COPY_RELOCS
&& !info->shared
&& h != NULL
&& (h->root.type == bfd_link_hash_defweak
|| !h->def_regular)))
;
else
continue;
if (h != NULL)
head = &((struct ppc_link_hash_entry *) h)->dyn_relocs;
else
{
if (sym_sec == NULL)
goto error_ret;
head = ((struct ppc_dyn_relocs **)
&elf_section_data (sym_sec)->local_dynrel);
}
for (p = *head; p != NULL; p = p->next)
if (p->sec == toc)
{
p->count -= 1;
if (!MUST_BE_DYN_RELOC (r_type))
p->pc_count -= 1;
break;
}
}
toc->reloc_count = wrel - relstart;
sz = elf_section_data (toc)->rel_hdr.sh_entsize;
elf_section_data (toc)->rel_hdr.sh_size = toc->reloc_count * sz;