This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: invocation of mips_elf_multi_got can cause not enough GOT space for local GOT entries
On Mon, Jan 14, 2013 at 2:47 PM, Richard Sandiford
<rdsandiford@googlemail.com> wrote:
> You'll need to do it consistently for all page_gotno tests
> (mips_elf_merge_got_with, mips_elf_merge_gots, mips_elf_multi_got and
> mips_elf_lay_out_got), otherwise you could end up merging GOTs based on
> the current estimate and lay them out using the conservative one, which
> could lead to overflow in the global region. But yeah, I think you'd
> be safe changing those four places, as a local hack to get round the bug.
So, with consistent you mean something like this?
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index 4036273..24716dc 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -4276,8 +4276,6 @@ mips_elf_merge_got_with (struct
mips_elf_bfd2got_hash *bfd2got,
/* Work out how many page entries we would need for the combined GOT. */
estimate = arg->max_pages;
- if (estimate >= from->page_gotno + to->page_gotno)
- estimate = from->page_gotno + to->page_gotno;
/* And conservatively estimate how many local and TLS entries
would be needed. */
@@ -4337,8 +4335,6 @@ mips_elf_merge_gots (void **bfd2got_, void *p)
/* Work out the number of page, local and TLS entries. */
estimate = arg->max_pages;
- if (estimate > g->page_gotno)
- estimate = g->page_gotno;
estimate += g->local_gotno + g->tls_gotno;
/* We place TLS GOT entries after both locals and globals. The globals
@@ -4687,7 +4683,7 @@ mips_elf_multi_got (bfd *abfd, struct bfd_link_info *info,
assign += htab->reserved_gotno;
g->assigned_gotno = assign;
g->local_gotno += assign;
- g->local_gotno += (pages < g->page_gotno ? pages : g->page_gotno);
+ g->local_gotno += pages;
assign = g->local_gotno + g->global_gotno + g->tls_gotno;
/* Take g out of the direct list, and push it onto the reversed
@@ -8918,11 +8914,6 @@ mips_elf_lay_out_got (bfd *output_bfd, struct
bfd_link_info *info)
sections. Is 5 enough? */
page_gotno = (loadable_size >> 16) + 5;
- /* Choose the smaller of the two estimates; both are intended to be
- conservative. */
- if (page_gotno > g->page_gotno)
- page_gotno = g->page_gotno;
-
g->local_gotno += page_gotno;
s->size += g->local_gotno * MIPS_ELF_GOT_SIZE (output_bfd);
s->size += g->global_gotno * MIPS_ELF_GOT_SIZE (output_bfd);
> FWIW, I experimented with one way of handling SEC_MERGE this weekend,
> but ran out time before I had something I was happy with. Hope to
> return to it again soon.
That sounds promising, thanks!
Robert