This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]