This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: PR20989, sparc GOT sequence optimization
- From: jose dot marchesi at oracle dot com (Jose E. Marchesi)
- To: Alan Modra <amodra at gmail dot com>
- Cc: binutils at sourceware dot org, Rainer Orth <ro at gcc dot gnu dot org>, "David S. Miller" <davem at davemloft dot net>
- Date: Mon, 02 Jan 2017 09:53:44 +0100
- Subject: Re: PR20989, sparc GOT sequence optimization
- Authentication-results: sourceware.org; auth=none
- References: <20161227030359.GE340@bubble.grove.modra.org>
Hi Alan.
This patch stops sparc ld doing the wrong thing when optimizing loads
from the GOT to a GOT pointer relative sequence. Tested by code
inspection and cross-build of binutils+testsuite as I don't have a
sparc system handy to do native regression testing. OK?
It would be easy to edit these code sequences to avoid the GOT load
for undefined weak hidden visibility syms by loading a zero inline,
but I'll leave that to the maintainers. Also, you might like to check
why the testcase in the PR didn't signal a relocation overflow..
Oh, and I strongly suspect the same bug exists in gold.
PR ld/20989
* elfxx-sparc.c (gdop_relative_offset_ok): New function.
(_bfd_sparc_elf_relocate_section): Use it to validate GOT
indirect to GOT pointer relative code edit.
diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c
index d7b2688..ca43c41 100644
--- a/bfd/elfxx-sparc.c
+++ b/bfd/elfxx-sparc.c
@@ -2927,6 +2927,33 @@ gdopoff (struct bfd_link_info *info, bfd_vma address)
return address - got_base;
}
+/* Return whether H is local and its ADDRESS is within 4G of
+ _GLOBAL_OFFSET_TABLE_ and thus the offset may be calculated by a
+ sethi, xor sequence. */
Generally speaking the address must be within {+-}2G of
_GLOBAL_OFFSET_TABLE_, i.e. there can be negative offsets.
I did an attempt recently to support negative offsets in GNU only to
find that we need some additional GCC support, but I will revisit it
soon.
Otherwise the fix looks good to me. I tested it in sparc64-linux-gnu
and sparcv9-linux-gnu targets. No regressions.
Thanks!