This is the mail archive of the
mailing list for the binutils project.
[0/20] Rework the MIPS GOT code
- From: Richard Sandiford <rdsandiford at googlemail dot com>
- To: binutils at sourceware dot org
- Date: Mon, 11 Feb 2013 17:19:29 +0000
- Subject: [0/20] Rework the MIPS GOT code
While looking at Robert's GOT overflow bug, I once again found the
MIPS GOT code pretty hard to work with. This patch series tries to
clean it up a little.
The main difficulty is that sometimes one mips_got_entry can represent
multiple GOT entries, and sometimes one GOT entry is represented by
multiple mips_got_entries. The former happens when there are IE and GD
references to the same TLS symbol. The latter happens because we create
separate mips_got_entry structures for every bfd that references a symbol;
the multigot code can then use these per-bfd entries to create per-bfd GOTs.
This in turn means that we have to have two ways of storing information
about GOT entries. Information about local GOT entries is stored in the
mips_got_entry itself. Information about the global part of the primary
GOT is stored in the symbol table. Information about the TLS part of
the primary GOT is stored in the symbol table if there are no secondary
GOTs, but in the mips_got_entry otherwise.
So the main aim of the series is to have one mips_got_entry per GOT entry
(although GD entries and LDM entries need to be two words long rather
than one). The idea is to make check_relocs create per-bfd GOTs from
the outset, with the new GOTs sharing mips_got_entry structures with
the "master" GOT. Whether this will lead to worse or better memory
usage in the single GOT case will depend on the input. We lose by having
an extra hash table per bfd, but we gain by having one mips_got_entry
for each symbol, rather than a separate mips_got_entry for every bfd
that references the symbol. I think it should be a clearer win in the
multigot case though.
A more minor problem, but one that directly affects the GOT overflow bug,
is that we count GOT entries in different places. We count local
entries while checking the relocs, but count the global ones during
size_dynamic_sections. The series makes us count everything in
All in all, this is a round-about way of not fixing Robert's bug,
but I hope to get to that soon. The plan there is to move the page
counting so that it too happens in size_dynamic_sections.
And sorry for spamming the list with a 20-patch series. Because this
code has been the source of a few bugs in the past, I thought it would
be better to do things in small steps.
FWIW, the overall change to bfd/elfxx-mips.c is:
1 file changed, 695 insertions(+), 983 deletions(-)
Tested by building a mips64el-linux-gnu sysroot with patched binutils
and running the GCC testsuite on the new sysroot. Also tested by
running the binutils testsuite for various MIPS targets.