linux-mips
[Top] [All Lists]

[Patch v2]: Fix ld pr11138 FAILures on mips*.

To: binutils <binutils@sourceware.org>, Richard Sandiford <rdsandiford@googlemail.com>, Alan Modra <amodra@gmail.com>
Subject: [Patch v2]: Fix ld pr11138 FAILures on mips*.
From: David Daney <david.daney@cavium.com>
Date: Fri, 09 Dec 2011 12:31:14 -0800
Cc: Manuel Lauss <manuel.lauss@googlemail.com>, Debian MIPS <debian-mips@lists.debian.org>, linux-mips <linux-mips@linux-mips.org>
Sender: linux-mips-bounce@linux-mips.org
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.15) Gecko/20101027 Fedora/3.0.10-1.fc12 Thunderbird/3.0.10
As noted in from the first attempt at fixing this:

   The pr11138 testcase links an executable with a version script.  On
   mips64-linux the presence of a version script was causing the
   MIPS_RLD_MAP dynamic tag to be populated with a NULL value.  When
   such an executable was run ld.so would try to dereference this and
   receive SIGSEGV, thus killing the process.

   The root cause of this is that the mips linker synthesizes a
   special symbol "__RLD_MAP", and then sets MIPS_RLD_MAP to point to
   it.  When a version script is present, this symbol gets versioned
   along with all the rest, and when it is time to take its address,
   the symbol can no longer be found as it has had version information
   appended to its name.

   ...

   This problem has also been reported in the wild when linking the
   firefox executable.

This new patch, at Richard's suggestion, remembers the __RLD_MAP (which
also goes by several other names) symbol before it can get hidden or
renamed by the symbol versioning code.

Then when it comes time to calculate the DT_MIPS_RLD_MAP value, we can
get the required information from the now remembered symbol.

We can get rid of a big blob of code in
_bfd_mips_elf_finish_dynamic_symbol that is now unused.  Also the size
of the .rld_map section was not being set properly for ELF64 targets,
so I fixed that as well.

Tested on mips64-linux-gnu where it fixes the pr11138 testcase
failures.  Also tested by bootstrapping GCC with the patched binutils.

Not tested on IRIX6 which has slightly different handling of these
things, but I think the code 'looks plausible', so what could possibly
go wrong?

Comments?  or OK to commit?

2011-12-09  David Daney  <david.daney@cavium.com>

        * /elfxx-mips.c (mips_elf_link_hash_table.rld_value): Remove.
        (mips_elf_link_hash_table.rld_symbol): New field;
        (MIPS_ELF_RLD_MAP_SIZE): New macro.
        (_bfd_mips_elf_add_symbol_hook): Remember __rld_obj_head symbol
        in rld_symbol.
        (_bfd_mips_elf_create_dynamic_sections): Remember __rld_map symbol
        in rld_symbol.
        (_bfd_mips_elf_size_dynamic_sections): Set correct size for .rld_map.
        (_bfd_mips_elf_finish_dynamic_symbol): Remove .rld_map handling.
        (_bfd_mips_elf_finish_dynamic_sections): Use rld_symbol to
        calculate DT_MIPS_RLD_MAP value.
        (_bfd_mips_elf_link_hash_table_create): Initialize rld_symbol,
        quit initializing rld_value.

Attachment: dd.patch
Description: Text document

<Prev in Thread] Current Thread [Next in Thread>