* elf64-ppc.c (get_opd_info): New function.
(adjust_opd_syms): Use get_opd_info. Define removed symbols as zero. (ppc64_elf_edit_opd): Use get_opd_info. Check that sym has a dot before calling get_fdh. Test fdh rather than h before dereferencing fdh. Mark removed symbols in opd_adjust. (ppc64_elf_tls_optimize): Don't bother with opd adjustment here. (ppc64_elf_relocate_section): Use get_opd_info, and handle removed opd symbols. (ppc64_elf_output_symbol_hook): Likewise.
This commit is contained in:
parent
ead80d2530
commit
4025353c27
@ -1,3 +1,15 @@
|
||||
2004-08-09 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* elf64-ppc.c (get_opd_info): New function.
|
||||
(adjust_opd_syms): Use get_opd_info. Define removed symbols as zero.
|
||||
(ppc64_elf_edit_opd): Use get_opd_info. Check that sym has a dot
|
||||
before calling get_fdh. Test fdh rather than h before dereferencing
|
||||
fdh. Mark removed symbols in opd_adjust.
|
||||
(ppc64_elf_tls_optimize): Don't bother with opd adjustment here.
|
||||
(ppc64_elf_relocate_section): Use get_opd_info, and handle removed
|
||||
opd symbols.
|
||||
(ppc64_elf_output_symbol_hook): Likewise.
|
||||
|
||||
2004-08-06 Paul Brook <paul@codesourcery.com>
|
||||
|
||||
* elfarm-nabi.c (elf32_arm_howto_table): Add new EABI relocations.
|
||||
|
@ -2492,6 +2492,16 @@ ppc64_elf_new_section_hook (bfd *abfd, asection *sec)
|
||||
|
||||
return _bfd_elf_new_section_hook (abfd, sec);
|
||||
}
|
||||
|
||||
static void *
|
||||
get_opd_info (asection * sec)
|
||||
{
|
||||
if (sec != NULL
|
||||
&& ppc64_elf_section_data (sec) != NULL
|
||||
&& ppc64_elf_section_data (sec)->opd.adjust != NULL)
|
||||
return ppc64_elf_section_data (sec)->opd.adjust;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* The following functions are specific to the ELF linker, while
|
||||
functions above are used generally. Those named ppc64_elf_* are
|
||||
@ -4935,11 +4945,19 @@ adjust_opd_syms (struct elf_link_hash_entry *h, void *inf ATTRIBUTE_UNUSED)
|
||||
return TRUE;
|
||||
|
||||
sym_sec = eh->elf.root.u.def.section;
|
||||
if (sym_sec != NULL
|
||||
&& elf_section_data (sym_sec) != NULL
|
||||
&& (opd_adjust = ppc64_elf_section_data (sym_sec)->opd.adjust) != NULL)
|
||||
opd_adjust = get_opd_info (sym_sec);
|
||||
if (opd_adjust != NULL)
|
||||
{
|
||||
eh->elf.root.u.def.value += opd_adjust[eh->elf.root.u.def.value / 24];
|
||||
long adjust = opd_adjust[eh->elf.root.u.def.value / 24];
|
||||
if (adjust == -1)
|
||||
{
|
||||
/* This entry has been deleted. */
|
||||
eh->elf.root.u.def.value = 0;
|
||||
eh->elf.root.u.def.section = &bfd_abs_section;
|
||||
}
|
||||
else
|
||||
eh->elf.root.u.def.value += adjust;
|
||||
eh->adjust_done = 1;
|
||||
}
|
||||
return TRUE;
|
||||
@ -4966,7 +4984,7 @@ ppc64_elf_edit_opd (bfd *obfd, struct bfd_link_info *info)
|
||||
struct elf_link_hash_entry **sym_hashes;
|
||||
bfd_vma offset;
|
||||
bfd_size_type amt;
|
||||
long *adjust;
|
||||
long *opd_adjust;
|
||||
bfd_boolean need_edit;
|
||||
|
||||
sec = bfd_get_section_by_name (ibfd, ".opd");
|
||||
@ -4974,15 +4992,15 @@ ppc64_elf_edit_opd (bfd *obfd, struct bfd_link_info *info)
|
||||
continue;
|
||||
|
||||
amt = sec->size * sizeof (long) / 24;
|
||||
adjust = ppc64_elf_section_data (sec)->opd.adjust;
|
||||
if (adjust == NULL)
|
||||
opd_adjust = get_opd_info (sec);
|
||||
if (opd_adjust == NULL)
|
||||
{
|
||||
/* Must be a ld -r link. ie. check_relocs hasn't been
|
||||
called. */
|
||||
adjust = bfd_zalloc (obfd, amt);
|
||||
ppc64_elf_section_data (sec)->opd.adjust = adjust;
|
||||
opd_adjust = bfd_zalloc (obfd, amt);
|
||||
ppc64_elf_section_data (sec)->opd.adjust = opd_adjust;
|
||||
}
|
||||
memset (adjust, 0, amt);
|
||||
memset (opd_adjust, 0, amt);
|
||||
|
||||
if (sec->output_section == bfd_abs_section_ptr)
|
||||
continue;
|
||||
@ -5134,7 +5152,8 @@ ppc64_elf_edit_opd (bfd *obfd, struct bfd_link_info *info)
|
||||
if (rel->r_offset == offset)
|
||||
{
|
||||
struct ppc_link_hash_entry *fdh = NULL;
|
||||
if (h != NULL)
|
||||
if (h != NULL
|
||||
&& h->root.root.string[0] == '.')
|
||||
fdh = get_fdh ((struct ppc_link_hash_entry *) h,
|
||||
ppc_hash_table (info));
|
||||
|
||||
@ -5142,19 +5161,20 @@ ppc64_elf_edit_opd (bfd *obfd, struct bfd_link_info *info)
|
||||
|| sym_sec->output_section == bfd_abs_section_ptr);
|
||||
if (skip)
|
||||
{
|
||||
if (h != NULL && sym_sec->owner == ibfd)
|
||||
if (fdh != NULL && sym_sec->owner == ibfd)
|
||||
{
|
||||
/* Arrange for the function descriptor sym
|
||||
to be dropped. */
|
||||
fdh->elf.root.u.def.value = 0;
|
||||
fdh->elf.root.u.def.section = sym_sec;
|
||||
}
|
||||
opd_adjust[rel->r_offset / 24] = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We'll be keeping this opd entry. */
|
||||
|
||||
if (h != NULL)
|
||||
if (fdh != NULL)
|
||||
{
|
||||
/* Redefine the function descriptor symbol to
|
||||
this location in the opd section. It is
|
||||
@ -5173,7 +5193,7 @@ ppc64_elf_edit_opd (bfd *obfd, struct bfd_link_info *info)
|
||||
for the function descriptor sym which we
|
||||
don't have at the moment. So keep an
|
||||
array of adjustments. */
|
||||
adjust[rel->r_offset / 24] = wptr - rptr;
|
||||
opd_adjust[rel->r_offset / 24] = wptr - rptr;
|
||||
|
||||
if (wptr != rptr)
|
||||
memcpy (wptr, rptr, 24);
|
||||
@ -5345,17 +5365,9 @@ ppc64_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
|
||||
value = h->root.u.def.value;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = sym->st_value;
|
||||
|
||||
if (elf_section_data (sym_sec) != NULL)
|
||||
{
|
||||
long *adjust;
|
||||
adjust = ppc64_elf_section_data (sym_sec)->opd.adjust;
|
||||
if (adjust != NULL)
|
||||
value += adjust[value / 24];
|
||||
}
|
||||
}
|
||||
/* Symbols referenced by TLS relocs must be of type
|
||||
STT_TLS. So no need for .opd local sym adjust. */
|
||||
value = sym->st_value;
|
||||
|
||||
ok_tprel = FALSE;
|
||||
is_local = FALSE;
|
||||
@ -7455,18 +7467,21 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
if (r_symndx < symtab_hdr->sh_info)
|
||||
{
|
||||
/* It's a local symbol. */
|
||||
long *opd_adjust;
|
||||
|
||||
sym = local_syms + r_symndx;
|
||||
sec = local_sections[r_symndx];
|
||||
sym_name = bfd_elf_local_sym_name (input_bfd, sym);
|
||||
sym_type = ELF64_ST_TYPE (sym->st_info);
|
||||
relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
|
||||
if (elf_section_data (sec) != NULL)
|
||||
opd_adjust = get_opd_info (sec);
|
||||
if (opd_adjust != NULL)
|
||||
{
|
||||
long *opd_sym_adjust;
|
||||
|
||||
opd_sym_adjust = ppc64_elf_section_data (sec)->opd.adjust;
|
||||
if (opd_sym_adjust != NULL)
|
||||
relocation += opd_sym_adjust[sym->st_value / 24];
|
||||
long adjust = opd_adjust[(sym->st_value + rel->r_addend) / 24];
|
||||
if (adjust == -1)
|
||||
relocation = 0;
|
||||
else
|
||||
relocation += adjust;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -8745,20 +8760,25 @@ ppc64_elf_output_symbol_hook (struct bfd_link_info *info,
|
||||
asection *input_sec,
|
||||
struct elf_link_hash_entry *h)
|
||||
{
|
||||
long *adjust;
|
||||
long *opd_adjust, adjust;
|
||||
bfd_vma value;
|
||||
|
||||
if (h != NULL
|
||||
|| input_sec == NULL
|
||||
|| ppc64_elf_section_data (input_sec) == NULL
|
||||
|| (adjust = ppc64_elf_section_data (input_sec)->opd.adjust) == NULL)
|
||||
if (h != NULL)
|
||||
return TRUE;
|
||||
|
||||
opd_adjust = get_opd_info (input_sec);
|
||||
if (opd_adjust == NULL)
|
||||
return TRUE;
|
||||
|
||||
value = elfsym->st_value - input_sec->output_offset;
|
||||
if (!info->relocatable)
|
||||
value -= input_sec->output_section->vma;
|
||||
|
||||
elfsym->st_value += adjust[value / 24];
|
||||
adjust = opd_adjust[value / 24];
|
||||
if (adjust == -1)
|
||||
elfsym->st_value = 0;
|
||||
else
|
||||
elfsym->st_value += adjust;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user