This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Committed, CRIS: fix elf_cris_adjust_gotplt_to_got reinit (was: Re:elf backend hide_symbol bug)
On Tue, 7 Sep 2004, Alan Modra wrote:
> I just noted that in
> elf_cris_adjust_gotplt_to_got, called from elf_cris_hide_symbol, you do
>
> h->gotplt_refcount = -1
>
> and in cris_elf_check_relocs, you
>
> ((struct elf_cris_link_hash_entry *) h)->gotplt_refcount++;
Got it. Thanks Alan.
> So, to tickle the bug on cris you need some combination of input files
> that hides a symbol during the add_symbols phase of linking (visibility
> or symbol versioning) and later references the same symbol using a
> GOTPLT reloc.
Looking closer, the only *use* of h->gotplt_refcount (besides in
elf_cris_adjust_gotplt_to_got itself) is in
elf_cris_try_fold_plt_to_got, which is only called from
elf_cris_adjust_dynamic_symbol. That call only happens if the
symbol was (also) defined in a DSO being linked against.
Because it is defined in a linked non-DSO object too, the old
(dynamic) definition is ignored in elflink.c:_bfd_elf_merge_symbol.
The -1 in "h->gotplt_refcount = -1" above should have been 0
(that's the initialization value), but the value doesn't
actually matter after this point.
What probably *can* go bad is through repeated calls to
elf_cris_adjust_gotplt_to_got, if the exactness of got reference
counts matters. I'm still not sure. I can't think of a
situation where relocs are removed, as --gc-sections is ignored
when -shared. For an executable, I don't know at all.
I couldn't come up with a failing test-case, but I'm certainly
not sure of the safeness of the current (now previous)
situation. The obvious correction to make repeated calls to
elf_cris_adjust_gotplt_to_got work correctly seemed TRT.
bfd:
* elf32-cris.c (elf_cris_adjust_gotplt_to_got): Reset
h->gotplt_refcount to 0, not -1.
Index: elf32-cris.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-cris.c,v
retrieving revision 1.54
diff -u -p -r1.54 elf32-cris.c
--- elf32-cris.c 7 Sep 2004 18:33:22 -0000 1.54
+++ elf32-cris.c 7 Sep 2004 22:33:17 -0000
@@ -1916,7 +1916,7 @@ elf_cris_adjust_gotplt_to_got (h, p)
Probably not necessary at this stage, but keeping it accurate
helps avoiding surprises later. */
h->root.got.refcount += h->gotplt_refcount;
- h->gotplt_refcount = -1;
+ h->gotplt_refcount = 0;
}
else
{
@@ -1928,7 +1928,7 @@ elf_cris_adjust_gotplt_to_got (h, p)
/* Put an accurate refcount there. */
h->root.got.refcount = h->gotplt_refcount;
- h->gotplt_refcount = -1;
+ h->gotplt_refcount = 0;
/* We always have a .got and a .rela.got section if there were
GOTPLT relocs in input. */
brgds, H-P