This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Improve MIPS GOT_PAGE estimates
- From: Daniel Jacobowitz <drow at false dot org>
- To: binutils at sourceware dot org
- Date: Wed, 26 Mar 2008 12:13:36 -0400
- Subject: Improve MIPS GOT_PAGE estimates
One of our users reported GOT overflows when linking N64 code which
used %got_page. We tracked this to the new estimation function;
it is only called for local or forced-local symbols. That seems OK
at first, since otherwise %got_page decays to %got_disp for
overridable symbols - except that in check_relocs, we do not know
whether a symbol will be ultimately overridable or not.
This patch makes the heuristic a little more conservative. There's
room for further improvement (combining references to a single global
symbol from multiple object files), but they offer relatively little
value for a relatively large amount of work; so I left it at this.
Tested mips-linux, no regressions. OK to commit?
--
Daniel Jacobowitz
CodeSourcery
2008-03-26 Daniel Jacobowitz <dan@codesourcery.com>
* elfxx-mips.c (mips_elf_record_got_page_entry): Update comment.
(_bfd_mips_elf_check_relocs): Update comments. Always call
mips_elf_record_got_page_entry for R_MIPS_GOT_PAGE.
Index: elfxx-mips.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-mips.c,v
retrieving revision 1.227
diff -u -p -r1.227 elfxx-mips.c
--- elfxx-mips.c 27 Feb 2008 17:06:06 -0000 1.227
+++ elfxx-mips.c 20 Mar 2008 14:17:01 -0000
@@ -3007,8 +3007,11 @@ mips_elf_pages_for_range (const struct m
return (range->max_addend - range->min_addend + 0x1ffff) >> 16;
}
-/* Record that ABFD has a page relocation against symbol SYMNDX and that
- ADDEND is the addend for that relocation. G is the GOT information. */
+/* Record that ABFD has a page relocation against symbol SYMNDX and
+ that ADDEND is the addend for that relocation. G is the GOT
+ information. This function creates an upper bound on the number of
+ GOT slots required; no attempt is made to combine references to
+ non-overridable global symbols across multiple input files. */
static bfd_boolean
mips_elf_record_got_page_entry (bfd *abfd, long symndx, bfd_signed_vma addend,
@@ -6909,6 +6912,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, s
hmips = (struct mips_elf_link_hash_entry *)
hmips->root.root.u.i.link;
+ /* This symbol is definitely not overridable. */
if (hmips->root.def_regular
&& ! (info->shared && ! info->symbolic
&& ! hmips->root.forced_local))
@@ -6919,9 +6923,12 @@ _bfd_mips_elf_check_relocs (bfd *abfd, s
case R_MIPS_GOT16:
case R_MIPS_GOT_HI16:
case R_MIPS_GOT_LO16:
- if (!h)
+ if (!h || r_type == R_MIPS_GOT_PAGE)
{
- /* This relocation needs a page entry in the GOT. */
+ /* This relocation needs (or may need, if h != NULL) a
+ page entry in the GOT. For R_MIPS_GOT_PAGE we do not
+ know for sure until we know whether the symbol is
+ preemptible. */
if (mips_elf_rel_relocation_p (abfd, sec, relocs, rel))
{
if (!mips_elf_get_section_contents (abfd, sec, &contents))