* elf32-cris.c (cris_elf_relocate_section) <case R_CRIS_16_GOTPLT,

R_CRIS_16_GOTPLT>: Also error if there's no PLT for a symbol
	not defined by the executable, or defined in a DSO.
	<eliding run-time relocation of .got>: Initialize GOT entry for a
	function symbol or ELF_LINK_HASH_NEEDS_PLT statically in an
	executable.
	(cris_elf_gc_sweep_hook): Improve fallthrough marking.
	(elf_cris_try_fold_plt_to_got): Improve head comment.  Do not fold
	a PLT reloc to GOT for an executable.
	(elf_cris_adjust_dynamic_symbol): Only fold a .got.plt entry with
	.got for a DSO and explain why.
	(elf_cris_discard_excess_program_dynamics): Also lose GOT-relocs
	and unreferenced symbols for which a PLT is defined.  Adjust
	dynamic-symbol pruning correspondingly, to make sure we don't lose
	a dynamic symbol also defined by a DSO.
This commit is contained in:
Hans-Peter Nilsson
2004-03-22 04:08:39 +00:00
parent 2d4b84b0f5
commit e4a2175c7d
2 changed files with 82 additions and 25 deletions

View File

@ -1,3 +1,21 @@
2004-03-22 Hans-Peter Nilsson <hp@axis.com>
* elf32-cris.c (cris_elf_relocate_section) <case R_CRIS_16_GOTPLT,
R_CRIS_16_GOTPLT>: Also error if there's no PLT for a symbol
not defined by the executable, or defined in a DSO.
<eliding run-time relocation of .got>: Initialize GOT entry for a
function symbol or ELF_LINK_HASH_NEEDS_PLT statically in an
executable.
(cris_elf_gc_sweep_hook): Improve fallthrough marking.
(elf_cris_try_fold_plt_to_got): Improve head comment. Do not fold
a PLT reloc to GOT for an executable.
(elf_cris_adjust_dynamic_symbol): Only fold a .got.plt entry with
.got for a DSO and explain why.
(elf_cris_discard_excess_program_dynamics): Also lose GOT-relocs
and unreferenced symbols for which a PLT is defined. Adjust
dynamic-symbol pruning correspondingly, to make sure we don't lose
a dynamic symbol also defined by a DSO.
2004-03-22 Alan Modra <amodra@bigpond.net.au>
* elf-bfd.h (RELOC_FOR_GLOBAL_SYMBOL): Add input_bfd, input_section

View File

@ -960,11 +960,25 @@ cris_elf_relocate_section (output_bfd, info, input_bfd, input_section,
statically linking PIC code, or when using -Bsymbolic. Check
that we instead have a GOT entry as done for us by
elf_cris_adjust_dynamic_symbol, and drop through into the
ordinary GOT cases. */
if (h != NULL && h->got.offset == (bfd_vma) -1)
ordinary GOT cases. This must not happen for the
executable, because any reference it does to a function
that is satisfied by a DSO must generate a PLT. We assume
these call-specific relocs don't address non-functions. */
if (h != NULL
&& (h->got.offset == (bfd_vma) -1
|| (!info->shared
&& !((h->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR) != 0
|| ((h->elf_link_hash_flags
& ELF_LINK_HASH_DEF_DYNAMIC) == 0
&& h->root.type == bfd_link_hash_undefweak)))))
{
(*_bfd_error_handler)
(_("%s: No PLT nor GOT for relocation %s against symbol `%s' from %s section"),
((h->got.offset == (bfd_vma) -1)
? _("%s: No PLT nor GOT for relocation %s against\
symbol `%s' from %s section")
: _("%s: No PLT for relocation %s against\
symbol `%s' from %s section"),
bfd_archive_filename (input_bfd),
cris_elf_howto_table[r_type].name,
symname[0] != '\0' ? symname : _("[whose name is lost]"),
@ -996,18 +1010,25 @@ cris_elf_relocate_section (output_bfd, info, input_bfd, input_section,
if (!elf_hash_table (info)->dynamic_sections_created
|| (! info->shared
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))
&& ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
|| h->type == STT_FUNC
|| (h->elf_link_hash_flags
& ELF_LINK_HASH_NEEDS_PLT)))
|| (info->shared
&& (info->symbolic || h->dynindx == -1)
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
{
/* This wasn't checked above for ! info->shared, but
must hold there if we get here; the symbol must be
defined in the regular program, or be undefweak. */
must hold there if we get here; the symbol must
be defined in the regular program or be undefweak
or be a function or otherwise need a PLT. */
BFD_ASSERT (!elf_hash_table (info)->dynamic_sections_created
|| info->shared
|| (h->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR) != 0
|| h->type == STT_FUNC
|| (h->elf_link_hash_flags
& ELF_LINK_HASH_NEEDS_PLT)
|| h->root.type == bfd_link_hash_undefweak);
/* This is actually a static link, or it is a
@ -1511,12 +1532,15 @@ elf_cris_finish_dynamic_symbol (output_bfd, info, h, sym)
}
}
/* We don't emit .got relocs for symbols that aren't in the
dynamic-symbols table for an ordinary program and are either defined
by the program or are undefined weak symbols. */
/* For an ordinary program, we emit .got relocs only for symbols that
are in the dynamic-symbols table and are either defined by the
program or are undefined weak symbols, or are function symbols
where we do not output a PLT: the PLT reloc was output above and all
references to the function symbol are redirected to the PLT. */
if (h->got.offset != (bfd_vma) -1
&& (info->shared
|| (h->dynindx != -1
&& h->plt.offset == (bfd_vma) -1
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0
&& h->root.type != bfd_link_hash_undefweak)))
{
@ -1838,13 +1862,12 @@ cris_elf_gc_sweep_hook (abfd, info, sec, relocs)
r_symndx = ELF32_R_SYM (rel->r_info);
if (r_symndx < symtab_hdr->sh_info)
goto local_got_reloc;
/* Fall through. */
case R_CRIS_32_PLT_GOTREL:
/* FIXME: We don't garbage-collect away the .got section. */
if (local_got_refcounts != NULL)
local_got_refcounts[-1]--;
/* Fall through. */
case R_CRIS_8_PCREL:
case R_CRIS_16_PCREL:
case R_CRIS_32_PCREL:
@ -1929,16 +1952,22 @@ elf_cris_adjust_gotplt_to_got (h, p)
want to do this:
- When all PLT references are GOTPLT references, and there are GOT
references. We don't have to generate a PLT at all.
references, and this is not the executable. We don't have to
generate a PLT at all.
- When there are both (ordinary) PLT references and GOT references.
- When there are both (ordinary) PLT references and GOT references,
and this isn't the executable.
We want to make the PLT reference use the ordinary GOT entry rather
than a run-time dynamically resolved GOTPLT entry (since the GOT
entry will have to be resolved at startup anyway).
than R_CRIS_JUMP_SLOT, a run-time dynamically resolved GOTPLT entry,
since the GOT entry will have to be resolved at startup anyway.
Though the latter case is handled when room for the PLT is allocated,
not here.
By folding into the GOT, we may need a round-trip to a PLT in the
executable for calls, a loss in performance. Still, losing a
reloc is a win in size and at least in start-up time.
Note that this function is called before symbols are forced local by
version scripts. The differing cases are handled by
elf_cris_hide_symbol. */
@ -2045,10 +2074,14 @@ elf_cris_adjust_dynamic_symbol (info, h)
info);
}
/* If there are only GOT references and GOTPLT references to this
PLT entry, get rid of the PLT. */
if (! elf_cris_try_fold_plt_to_got ((struct elf_cris_link_hash_entry *)
h, info))
/* If we had a R_CRIS_GLOB_DAT that didn't have to point to a PLT;
where a pointer-equivalent symbol was unimportant (i.e. more
like R_CRIS_JUMP_SLOT after symbol evaluation) we could get rid
of the PLT. We can't for the executable, because the GOT
entries will point to the PLT there (and be constant). */
if (info->shared
&& !elf_cris_try_fold_plt_to_got ((struct elf_cris_link_hash_entry*)
h, info))
return FALSE;
/* GC or folding may have rendered this entry unused. */
@ -2086,8 +2119,11 @@ elf_cris_adjust_dynamic_symbol (info, h)
/* If there's already a GOT entry, use that, not a .got.plt. A
GOT field still has a reference count when we get here; it's
not yet changed to an offset. */
if (h->got.refcount > 0)
not yet changed to an offset. We can't do this for an
executable, because then the reloc associated with the PLT
would get a non-PLT reloc pointing to the PLT. FIXME: Move
this to elf_cris_try_fold_plt_to_got. */
if (info->shared && h->got.refcount > 0)
{
h->got.refcount += h->plt.refcount;
@ -2860,9 +2896,11 @@ elf_cris_discard_excess_program_dynamics (h, inf)
/* If we're not creating a shared library and have a symbol which is
referred to by .got references, but the symbol is defined locally,
(or rather, not not defined by a DSO) then lose the reloc for the
.got (don't allocate room for it). */
if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0)
(or rather, not defined by a DSO) then lose the reloc for the .got
(don't allocate room for it). Likewise for relocs for something
for which we create a PLT. */
if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0
|| h->root.plt.refcount > 0)
{
if (h->root.got.refcount > 0
/* The size of this section is only valid and in sync with the
@ -2888,7 +2926,8 @@ elf_cris_discard_excess_program_dynamics (h, inf)
introduce new problems. Of course we don't do this if we're
exporting all dynamic symbols. */
if (! info->export_dynamic
&& (h->root.elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0)
&& (h->root.elf_link_hash_flags
& (ELF_LINK_HASH_DEF_DYNAMIC|ELF_LINK_HASH_REF_DYNAMIC)) == 0)
{
h->root.dynindx = -1;
_bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,