mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-24 12:23:31 +08:00
* 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:
@ -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>
|
2004-03-22 Alan Modra <amodra@bigpond.net.au>
|
||||||
|
|
||||||
* elf-bfd.h (RELOC_FOR_GLOBAL_SYMBOL): Add input_bfd, input_section
|
* elf-bfd.h (RELOC_FOR_GLOBAL_SYMBOL): Add input_bfd, input_section
|
||||||
|
@ -960,11 +960,25 @@ cris_elf_relocate_section (output_bfd, info, input_bfd, input_section,
|
|||||||
statically linking PIC code, or when using -Bsymbolic. Check
|
statically linking PIC code, or when using -Bsymbolic. Check
|
||||||
that we instead have a GOT entry as done for us by
|
that we instead have a GOT entry as done for us by
|
||||||
elf_cris_adjust_dynamic_symbol, and drop through into the
|
elf_cris_adjust_dynamic_symbol, and drop through into the
|
||||||
ordinary GOT cases. */
|
ordinary GOT cases. This must not happen for the
|
||||||
if (h != NULL && h->got.offset == (bfd_vma) -1)
|
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)
|
(*_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),
|
bfd_archive_filename (input_bfd),
|
||||||
cris_elf_howto_table[r_type].name,
|
cris_elf_howto_table[r_type].name,
|
||||||
symname[0] != '\0' ? symname : _("[whose name is lost]"),
|
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
|
if (!elf_hash_table (info)->dynamic_sections_created
|
||||||
|| (! info->shared
|
|| (! 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->shared
|
||||||
&& (info->symbolic || h->dynindx == -1)
|
&& (info->symbolic || h->dynindx == -1)
|
||||||
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
|
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
|
||||||
{
|
{
|
||||||
/* This wasn't checked above for ! info->shared, but
|
/* This wasn't checked above for ! info->shared, but
|
||||||
must hold there if we get here; the symbol must be
|
must hold there if we get here; the symbol must
|
||||||
defined in the regular program, or be undefweak. */
|
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
|
BFD_ASSERT (!elf_hash_table (info)->dynamic_sections_created
|
||||||
|| info->shared
|
|| info->shared
|
||||||
|| (h->elf_link_hash_flags
|
|| (h->elf_link_hash_flags
|
||||||
& ELF_LINK_HASH_DEF_REGULAR) != 0
|
& 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);
|
|| h->root.type == bfd_link_hash_undefweak);
|
||||||
|
|
||||||
/* This is actually a static link, or it is a
|
/* 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
|
/* For an ordinary program, we emit .got relocs only for symbols that
|
||||||
dynamic-symbols table for an ordinary program and are either defined
|
are in the dynamic-symbols table and are either defined by the
|
||||||
by the program or are undefined weak symbols. */
|
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
|
if (h->got.offset != (bfd_vma) -1
|
||||||
&& (info->shared
|
&& (info->shared
|
||||||
|| (h->dynindx != -1
|
|| (h->dynindx != -1
|
||||||
|
&& h->plt.offset == (bfd_vma) -1
|
||||||
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0
|
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0
|
||||||
&& h->root.type != bfd_link_hash_undefweak)))
|
&& 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);
|
r_symndx = ELF32_R_SYM (rel->r_info);
|
||||||
if (r_symndx < symtab_hdr->sh_info)
|
if (r_symndx < symtab_hdr->sh_info)
|
||||||
goto local_got_reloc;
|
goto local_got_reloc;
|
||||||
|
/* Fall through. */
|
||||||
case R_CRIS_32_PLT_GOTREL:
|
case R_CRIS_32_PLT_GOTREL:
|
||||||
/* FIXME: We don't garbage-collect away the .got section. */
|
/* FIXME: We don't garbage-collect away the .got section. */
|
||||||
if (local_got_refcounts != NULL)
|
if (local_got_refcounts != NULL)
|
||||||
local_got_refcounts[-1]--;
|
local_got_refcounts[-1]--;
|
||||||
/* Fall through. */
|
/* Fall through. */
|
||||||
|
|
||||||
case R_CRIS_8_PCREL:
|
case R_CRIS_8_PCREL:
|
||||||
case R_CRIS_16_PCREL:
|
case R_CRIS_16_PCREL:
|
||||||
case R_CRIS_32_PCREL:
|
case R_CRIS_32_PCREL:
|
||||||
@ -1929,16 +1952,22 @@ elf_cris_adjust_gotplt_to_got (h, p)
|
|||||||
want to do this:
|
want to do this:
|
||||||
|
|
||||||
- When all PLT references are GOTPLT references, and there are GOT
|
- 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
|
We want to make the PLT reference use the ordinary GOT entry rather
|
||||||
than a run-time dynamically resolved GOTPLT entry (since the GOT
|
than R_CRIS_JUMP_SLOT, a run-time dynamically resolved GOTPLT entry,
|
||||||
entry will have to be resolved at startup anyway).
|
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,
|
Though the latter case is handled when room for the PLT is allocated,
|
||||||
not here.
|
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
|
Note that this function is called before symbols are forced local by
|
||||||
version scripts. The differing cases are handled by
|
version scripts. The differing cases are handled by
|
||||||
elf_cris_hide_symbol. */
|
elf_cris_hide_symbol. */
|
||||||
@ -2045,9 +2074,13 @@ elf_cris_adjust_dynamic_symbol (info, h)
|
|||||||
info);
|
info);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If there are only GOT references and GOTPLT references to this
|
/* If we had a R_CRIS_GLOB_DAT that didn't have to point to a PLT;
|
||||||
PLT entry, get rid of the PLT. */
|
where a pointer-equivalent symbol was unimportant (i.e. more
|
||||||
if (! elf_cris_try_fold_plt_to_got ((struct elf_cris_link_hash_entry *)
|
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))
|
h, info))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
@ -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
|
/* 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
|
GOT field still has a reference count when we get here; it's
|
||||||
not yet changed to an offset. */
|
not yet changed to an offset. We can't do this for an
|
||||||
if (h->got.refcount > 0)
|
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;
|
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
|
/* 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,
|
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
|
(or rather, not defined by a DSO) then lose the reloc for the .got
|
||||||
.got (don't allocate room for it). */
|
(don't allocate room for it). Likewise for relocs for something
|
||||||
if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0)
|
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
|
if (h->root.got.refcount > 0
|
||||||
/* The size of this section is only valid and in sync with the
|
/* 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
|
introduce new problems. Of course we don't do this if we're
|
||||||
exporting all dynamic symbols. */
|
exporting all dynamic symbols. */
|
||||||
if (! info->export_dynamic
|
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;
|
h->root.dynindx = -1;
|
||||||
_bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
|
_bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
|
||||||
|
Reference in New Issue
Block a user