* elf32-cris.c (cris_elf_plt_sym_val): Rewrite to work in presence

of merged .got and .got.plt entries.
This commit is contained in:
Hans-Peter Nilsson 2012-06-18 06:16:59 +00:00
parent 4b0296ce64
commit 51806b9750
2 changed files with 57 additions and 4 deletions

View File

@ -1,3 +1,8 @@
2012-06-18 Hans-Peter Nilsson <hp@axis.com>
* elf32-cris.c (cris_elf_plt_sym_val): Rewrite to work in presence
of merged .got and .got.plt entries.
2012-06-18 John Szakmeister <john@szakmeister.net>
* elf32-arm.c (elf32_arm_final_link_relocate): Correct return value.

View File

@ -2719,16 +2719,64 @@ cris_elf_gc_sweep_hook (bfd *abfd,
/* The elf_backend_plt_sym_val hook function. */
static bfd_vma
cris_elf_plt_sym_val (bfd_vma i, const asection *plt,
const arelent *rel ATTRIBUTE_UNUSED)
cris_elf_plt_sym_val (bfd_vma i ATTRIBUTE_UNUSED, const asection *plt,
const arelent *rel)
{
bfd_size_type plt_entry_size;
bfd_size_type pltoffs;
bfd *abfd = plt->owner;
/* Same for CRIS and CRIS v32; see elf_cris_(|pic_)plt_entry(|_v32)[]. */
bfd_size_type plt_entry_got_offset = 2;
bfd_size_type plt_sec_size;
bfd_size_type got_vma_for_dyn;
asection *got;
/* FIXME: the .got section should be readily available also when
we're not linking. */
if ((got = bfd_get_section_by_name (abfd, ".got")) == NULL)
return (bfd_vma) -1;
plt_sec_size = bfd_section_size (plt->owner, plt);
plt_entry_size
= (bfd_get_mach (plt->owner) == bfd_mach_cris_v32
= (bfd_get_mach (abfd) == bfd_mach_cris_v32
? PLT_ENTRY_SIZE_V32 : PLT_ENTRY_SIZE);
return plt->vma + (i + 1) * plt_entry_size;
/* Data in PLT is GOT-relative for DYN, but absolute for EXE. */
got_vma_for_dyn = (abfd->flags & EXEC_P) ? 0 : got->vma;
/* Because we can have merged GOT entries; a single .got entry for
both GOT and the PLT part of the GOT (.got.plt), the index of the
reloc in .rela.plt is not the same as the index in the PLT.
Instead, we have to hunt down the GOT offset in the PLT that
corresponds to that of this reloc. Unfortunately, we will only
be called for the .rela.plt relocs, so we'll miss synthetic
symbols for .plt entries with merged GOT entries. (FIXME:
fixable by providing our own bfd_elf32_get_synthetic_symtab.
Doesn't seem worthwile at time of this writing.) FIXME: we've
gone from O(1) to O(N) (N number of PLT entries) for finding each
PLT address. Shouldn't matter in practice though. */
for (pltoffs = plt_entry_size;
pltoffs < plt_sec_size;
pltoffs += plt_entry_size)
{
bfd_size_type got_offset;
bfd_byte gotoffs_raw[4];
if (!bfd_get_section_contents (abfd, (asection *) plt, gotoffs_raw,
pltoffs + plt_entry_got_offset,
sizeof (gotoffs_raw)))
return (bfd_vma) -1;
got_offset = bfd_get_32 (abfd, gotoffs_raw);
if (got_offset + got_vma_for_dyn == rel->address)
return plt->vma + pltoffs;
}
/* While it's tempting to BFD_ASSERT that we shouldn't get here,
that'd not be graceful behavior for invalid input. */
return (bfd_vma) -1;
}
/* Make sure we emit a GOT entry if the symbol was supposed to have a PLT