This is the mail archive of the
mailing list for the binutils project.
Re: invocation of mips_elf_multi_got can cause not enough GOT space for local GOT entries
Robert Schiele <email@example.com> writes:
> On Thu, Jan 10, 2013 at 10:48 AM, Robert Schiele <firstname.lastname@example.org> wrote:
>> On Thu, Jan 10, 2013 at 10:18 AM, Robert Schiele <email@example.com> wrote:
>>> The offending relocations are R_MIPS_GOT_PAGE relocations against
>>> .rodata.str1.8 sections.
>> And giving that one further thought, this section is SHF_MERGE |
>> SHF_STRINGS and thus it is kind of expected that from the merging it
>> could happen that the offsets of those relocations can change for a
>> different amount since other stuff could have been merged in between.
>> If that happens it is actually quite likely that they can cover more
>> pages than they initially did and thus the assumption mentioned above
>> that you can get an upper bound of pages affected by just summing up
>> the affected pages of the individual objects before is no longer true.
> This might for sure not be the smartest solution but at least it
> should fix it (and does in my case) if I just replace the
> g->local_gotno += (pages < g->page_gotno ? pages : g->page_gotno);
> with the conservative
> g->local_gotno += pages;
> Does anyone see a problem with that? Do you expect major penalties
> from this super conservative approach?
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.
It should be equivalent to reverting my patch.
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.